Example #1
0
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})
}
Example #2
0
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)
	}
}
Example #3
0
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
}
Example #4
0
// 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
}
Example #5
0
// 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)
}
Example #6
0
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)
		}
	}
}
Example #7
0
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)
		}
	}
}