func (c *listCredentialsCommand) Run(ctxt *cmd.Context) error { var credentials map[string]jujucloud.CloudCredential credentials, err := c.store.AllCredentials() if err != nil && !errors.IsNotFound(err) { return err } if c.cloudName != "" { for cloudName := range credentials { if cloudName != c.cloudName { delete(credentials, cloudName) } } } // Find local cloud names. personalClouds, err := c.personalClouds() if err != nil { return err } var personalCloudNames []string for name := range personalClouds { personalCloudNames = append(personalCloudNames, name) } displayCredentials := make(map[string]CloudCredential) var missingClouds []string for cloudName, cred := range credentials { if !c.showSecrets { if err := c.removeSecrets(cloudName, &cred); err != nil { if errors.IsNotValid(err) { missingClouds = append(missingClouds, cloudName) continue } return errors.Annotatef(err, "removing secrets from credentials for cloud %v", cloudName) } } displayCredential := CloudCredential{ DefaultCredential: cred.DefaultCredential, DefaultRegion: cred.DefaultRegion, } if len(cred.AuthCredentials) != 0 { displayCredential.Credentials = make(map[string]Credential, len(cred.AuthCredentials)) for credName, credDetails := range cred.AuthCredentials { displayCredential.Credentials[credName] = Credential{ string(credDetails.AuthType()), credDetails.Attributes(), credDetails.Revoked, credDetails.Label, } } } displayCredentials[cloudName] = displayCredential } if c.out.Name() == "tabular" && len(missingClouds) > 0 { fmt.Fprintf(ctxt.GetStdout(), "The following clouds have been removed and are omitted from the results to avoid leaking secrets.\n"+ "Run with --show-secrets to display these clouds' credentials: %v\n\n", strings.Join(missingClouds, ", ")) } return c.out.Write(ctxt, credentialsMap{displayCredentials}) }
func (s *ModelMigrationSuite) TestSpecValidation(c *gc.C) { tests := []struct { label string tweakSpec func(*state.ModelMigrationSpec) errorPattern string }{{ "empty InitiatedBy", func(spec *state.ModelMigrationSpec) { spec.InitiatedBy = "" }, "InitiatedBy not valid", }, { "invalid InitiatedBy", func(spec *state.ModelMigrationSpec) { spec.InitiatedBy = "!" }, "InitiatedBy not valid", }, { "TargetInfo is validated", func(spec *state.ModelMigrationSpec) { spec.TargetInfo.Password = "" }, "empty Password not valid", }} for _, test := range tests { c.Logf("---- %s -----------", test.label) // Set up spec. spec := s.stdSpec test.tweakSpec(&spec) // Check Validate directly. err := spec.Validate() c.Check(errors.IsNotValid(err), jc.IsTrue) c.Check(err, gc.ErrorMatches, test.errorPattern) // Ensure that CreateModelMigration rejects the bad spec too. mig, err := state.CreateModelMigration(s.State2, spec) c.Check(mig, gc.IsNil) c.Check(errors.IsNotValid(err), jc.IsTrue) c.Check(err, gc.ErrorMatches, test.errorPattern) } }
func verifyDownload(file *os.File, req Request) error { err := req.Verify(file) if err != nil { if errors.IsNotValid(err) { logger.Errorf("download of %s invalid: %v", req.URL, err) } return errors.Trace(err) } logger.Infof("download verified (%q)", req.URL) if _, err := file.Seek(0, os.SEEK_SET); err != nil { logger.Errorf("failed to seek to beginning of file: %v", err) return errors.Trace(err) } return nil }
// DownloadWithAlternates tries each of the provided requests until // one succeeds. If none succeed then the error from the most recent // attempt is returned. At least one request must be provided. func (dlr Downloader) DownloadWithAlternates(requests []Request, abort <-chan struct{}) (filename string, err error) { if len(requests) == 0 { return "", errors.New("no requests to try") } for _, req := range requests { filename, err = dlr.Download(req, abort) if errors.IsNotValid(err) { break } if err == nil { break } logger.Errorf("download request to %s failed: %v", req.URL, err) // Try the next one. } if err != nil { return "", errors.Trace(err) } return filename, nil }
// NewController creates an authenticated client to the MAAS API, and checks // the capabilities of the server. // // If the APIKey is not valid, a NotValid error is returned. // If the credentials are incorrect, a PermissionError is returned. func NewController(args ControllerArgs) (Controller, error) { // For now we don't need to test multiple versions. It is expected that at // some time in the future, we will try the most up to date version and then // work our way backwards. for _, apiVersion := range supportedAPIVersions { major, minor, err := version.ParseMajorMinor(apiVersion) // We should not get an error here. See the test. if err != nil { return nil, errors.Errorf("bad version defined in supported versions: %q", apiVersion) } client, err := NewAuthenticatedClient(args.BaseURL, args.APIKey, apiVersion) if err != nil { // If the credentials aren't valid, return now. if errors.IsNotValid(err) { return nil, errors.Trace(err) } // Any other error attempting to create the authenticated client // is an unexpected error and return now. return nil, NewUnexpectedError(err) } controllerVersion := version.Number{ Major: major, Minor: minor, } controller := &controller{client: client} // The controllerVersion returned from the function will include any patch version. controller.capabilities, controller.apiVersion, err = controller.readAPIVersion(controllerVersion) if err != nil { logger.Debugf("read version failed: %#v", err) continue } if err := controller.checkCreds(); err != nil { return nil, errors.Trace(err) } return controller, nil } return nil, NewUnsupportedVersionError("controller at %s does not support any of %s", args.BaseURL, supportedAPIVersions) }
func (s *TargetInfoSuite) TestValidation(c *gc.C) { tests := []struct { label string tweakInfo func(*migration.TargetInfo) errorPattern string }{{ "empty ControllerTag", func(info *migration.TargetInfo) { info.ControllerTag = names.NewControllerTag("fooo") }, "ControllerTag not valid", }, { "invalid ControllerTag", func(info *migration.TargetInfo) { info.ControllerTag = names.NewControllerTag("") }, "ControllerTag not valid", }, { "empty Addrs", func(info *migration.TargetInfo) { info.Addrs = []string{} }, "empty Addrs not valid", }, { "invalid Addrs", func(info *migration.TargetInfo) { info.Addrs = []string{"1.2.3.4:555", "abc"} }, `"abc" in Addrs not valid`, }, { "CACert", func(info *migration.TargetInfo) { info.CACert = "" }, "empty CACert not valid", }, { "AuthTag", func(info *migration.TargetInfo) { info.AuthTag = names.UserTag{} }, "empty AuthTag not valid", }, { "Password & Macaroons", func(info *migration.TargetInfo) { info.Password = "" info.Macaroons = nil }, "missing Password & Macaroons not valid", }, { "Success - empty Password", func(info *migration.TargetInfo) { info.Password = "" }, "", }, { "Success - empty Macaroons", func(info *migration.TargetInfo) { info.Macaroons = nil }, "", }, { "Success - all set", func(*migration.TargetInfo) {}, "", }} for _, test := range tests { c.Logf("---- %s -----------", test.label) info := makeValidTargetInfo(c) test.tweakInfo(&info) err := info.Validate() if test.errorPattern == "" { c.Check(err, jc.ErrorIsNil) } else { c.Check(errors.IsNotValid(err), jc.IsTrue) c.Check(err, gc.ErrorMatches, test.errorPattern) } } }
func (s *TargetInfoSuite) TestValidation(c *gc.C) { tests := []struct { label string tweakInfo func(*migration.TargetInfo) errorPattern string }{{ "empty ControllerTag", func(info *migration.TargetInfo) { info.ControllerTag = names.NewModelTag("fooo") }, "ControllerTag not valid", }, { "invalid ControllerTag", func(info *migration.TargetInfo) { info.ControllerTag = names.NewModelTag("") }, "ControllerTag not valid", }, { "empty Addrs", func(info *migration.TargetInfo) { info.Addrs = []string{} }, "empty Addrs not valid", }, { "invalid Addrs", func(info *migration.TargetInfo) { info.Addrs = []string{"1.2.3.4:555", "abc"} }, `"abc" in Addrs not valid`, }, { "CACert", func(info *migration.TargetInfo) { info.CACert = "" }, "empty CACert not valid", }, { "EntityTag", func(info *migration.TargetInfo) { info.EntityTag = names.NewMachineTag("") }, "empty EntityTag not valid", }, { "Password", func(info *migration.TargetInfo) { info.Password = "" }, "empty Password not valid", }, { "Success", func(*migration.TargetInfo) {}, "", }} modelTag := names.NewModelTag(utils.MustNewUUID().String()) for _, test := range tests { c.Logf("---- %s -----------", test.label) info := migration.TargetInfo{ ControllerTag: modelTag, Addrs: []string{"1.2.3.4:5555", "4.3.2.1:6666"}, CACert: "cert", EntityTag: names.NewUserTag("user"), Password: "******", } test.tweakInfo(&info) err := info.Validate() if test.errorPattern == "" { c.Check(err, jc.ErrorIsNil) } else { c.Check(errors.IsNotValid(err), jc.IsTrue) c.Check(err, gc.ErrorMatches, test.errorPattern) } } }