Exemplo n.º 1
0
func (s *credentialsSuite) TestFinalizeCredentialFilePath(c *gc.C) {
	dir := c.MkDir()
	filename := filepath.Join(dir, "filename")
	err := ioutil.WriteFile(filename, []byte{}, 0600)
	c.Assert(err, jc.ErrorIsNil)

	cred := cloud.NewCredential(
		cloud.JSONFileAuthType,
		map[string]string{
			"file": filename,
		},
	)
	schema := cloud.CredentialSchema{{
		"file", cloud.CredentialAttr{FilePath: true},
	}}

	readFile := func(path string) ([]byte, error) {
		c.Assert(path, gc.Equals, filename)
		return []byte("file-contents"), nil
	}

	newCred, err := cloud.FinalizeCredential(cred, map[cloud.AuthType]cloud.CredentialSchema{
		cloud.JSONFileAuthType: schema,
	}, readFile)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(newCred.Attributes(), jc.DeepEquals, map[string]string{
		"file": "file-contents",
	})
}
Exemplo n.º 2
0
func (s *credentialsSuite) TestFinalizeCredentialMandatoryFieldFromFile(c *gc.C) {
	cred := cloud.NewCredential(
		cloud.UserPassAuthType,
		map[string]string{
			"key-file": "path",
		},
	)
	schema := cloud.CredentialSchema{{
		"key",
		cloud.CredentialAttr{
			Description: "key credential",
			Optional:    false,
			FileAttr:    "key-file",
		},
	}}
	readFile := func(s string) ([]byte, error) {
		c.Assert(s, gc.Equals, "path")
		return []byte("file-value"), nil
	}
	newCred, err := cloud.FinalizeCredential(cred, map[cloud.AuthType]cloud.CredentialSchema{
		cloud.UserPassAuthType: schema,
	}, readFile)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(newCred.Attributes(), jc.DeepEquals, map[string]string{
		"key": "file-value",
	})
}
Exemplo n.º 3
0
func (s *credentialsSuite) TestFinalizeCredentialNotSupported(c *gc.C) {
	cred := cloud.NewCredential(
		cloud.OAuth2AuthType,
		map[string]string{},
	)
	_, err := cloud.FinalizeCredential(
		cred, map[cloud.AuthType]cloud.CredentialSchema{}, readFileNotSupported,
	)
	c.Assert(err, jc.Satisfies, errors.IsNotSupported)
	c.Assert(err, gc.ErrorMatches, `auth-type "oauth2" not supported`)
}
Exemplo n.º 4
0
func (s *credentialsSuite) TestFinalizeCredentialRelativeFilePath(c *gc.C) {
	cred := cloud.NewCredential(
		cloud.JSONFileAuthType,
		map[string]string{
			"file": "file",
		},
	)
	schema := cloud.CredentialSchema{{
		"file", cloud.CredentialAttr{FilePath: true},
	}}
	_, err := cloud.FinalizeCredential(cred, map[cloud.AuthType]cloud.CredentialSchema{
		cloud.JSONFileAuthType: schema,
	}, nil)
	c.Assert(err, gc.ErrorMatches, "file path must be an absolute path: file")
}
Exemplo n.º 5
0
func (s *credentialsSuite) TestFinalizeCredentialInvalidFilePath(c *gc.C) {
	cred := cloud.NewCredential(
		cloud.JSONFileAuthType,
		map[string]string{
			"file": filepath.Join(c.MkDir(), "somefile"),
		},
	)
	schema := cloud.CredentialSchema{{
		"file", cloud.CredentialAttr{FilePath: true},
	}}
	_, err := cloud.FinalizeCredential(cred, map[cloud.AuthType]cloud.CredentialSchema{
		cloud.JSONFileAuthType: schema,
	}, nil)
	c.Assert(err, gc.ErrorMatches, "invalid file path: .*")
}
Exemplo n.º 6
0
func (s *credentialsSuite) TestFinalizeCredentialInvalid(c *gc.C) {
	cred := cloud.NewCredential(
		cloud.UserPassAuthType,
		map[string]string{},
	)
	schema := cloud.CredentialSchema{{
		"key",
		cloud.CredentialAttr{
			Description: "key credential",
			Hidden:      true,
		},
	}}
	_, err := cloud.FinalizeCredential(cred, map[cloud.AuthType]cloud.CredentialSchema{
		cloud.UserPassAuthType: schema,
	}, readFileNotSupported)
	c.Assert(err, gc.ErrorMatches, "key: expected string, got nothing")
}
Exemplo n.º 7
0
func (s *credentialsSuite) TestFinalizeCredentialMandatoryFieldMissing(c *gc.C) {
	cred := cloud.NewCredential(
		cloud.UserPassAuthType,
		map[string]string{
			"password": "******",
			"domain":   "domain",
		},
	)
	schema := cloud.CredentialSchema{
		{"username", cloud.CredentialAttr{Optional: false}},
		{"password", cloud.CredentialAttr{Hidden: true}},
		{"domain", cloud.CredentialAttr{}},
	}
	_, err := cloud.FinalizeCredential(cred, map[cloud.AuthType]cloud.CredentialSchema{
		cloud.UserPassAuthType: schema,
	}, nil)
	c.Assert(err, gc.ErrorMatches, "username: expected string, got nothing")
}
Exemplo n.º 8
0
func (s *credentialsSuite) TestFinalizeCredentialFileAttrNeither(c *gc.C) {
	cred := cloud.NewCredential(
		cloud.UserPassAuthType,
		map[string]string{},
	)
	schema := cloud.CredentialSchema{{
		"key",
		cloud.CredentialAttr{
			Description: "key credential",
			Hidden:      true,
			FileAttr:    "key-file",
		},
	}}
	_, err := cloud.FinalizeCredential(cred, map[cloud.AuthType]cloud.CredentialSchema{
		cloud.UserPassAuthType: schema,
	}, readFileNotSupported)
	c.Assert(err, gc.ErrorMatches, `either "key" or "key-file" must be specified`)
}
Exemplo n.º 9
0
func (s *credentialsSuite) TestFinalizeCredentialInvalidChoice(c *gc.C) {
	cred := cloud.NewCredential(
		cloud.UserPassAuthType,
		map[string]string{
			"username":  "******",
			"password":  "******",
			"algorithm": "foo",
		},
	)
	schema := cloud.CredentialSchema{
		{"username", cloud.CredentialAttr{Optional: false}},
		{"password", cloud.CredentialAttr{Hidden: true}},
		{"algorithm", cloud.CredentialAttr{Options: []interface{}{"bar", "foobar"}}},
	}
	_, err := cloud.FinalizeCredential(cred, map[cloud.AuthType]cloud.CredentialSchema{
		cloud.UserPassAuthType: schema,
	}, nil)
	c.Assert(err, gc.ErrorMatches, regexp.QuoteMeta(`algorithm: expected one of [bar foobar], got "foo"`))
}
Exemplo n.º 10
0
func (s *credentialsSuite) TestFinalizeCredential(c *gc.C) {
	cred := cloud.NewCredential(
		cloud.UserPassAuthType,
		map[string]string{
			"key": "value",
		},
	)
	schema := cloud.CredentialSchema{{
		"key",
		cloud.CredentialAttr{
			Description: "key credential",
			Hidden:      true,
		},
	}}
	_, err := cloud.FinalizeCredential(cred, map[cloud.AuthType]cloud.CredentialSchema{
		cloud.UserPassAuthType: schema,
	}, readFileNotSupported)
	c.Assert(err, jc.ErrorIsNil)
}
Exemplo n.º 11
0
func (s *credentialsSuite) TestFinalizeCredentialExtraField(c *gc.C) {
	cred := cloud.NewCredential(
		cloud.UserPassAuthType,
		map[string]string{
			"username":   "******",
			"password":   "******",
			"domain":     "domain",
			"access-key": "access-key",
		},
	)
	schema := cloud.CredentialSchema{
		{"username", cloud.CredentialAttr{Optional: false}},
		{"password", cloud.CredentialAttr{Hidden: true}},
		{"domain", cloud.CredentialAttr{}},
	}
	_, err := cloud.FinalizeCredential(cred, map[cloud.AuthType]cloud.CredentialSchema{
		cloud.UserPassAuthType: schema,
	}, nil)
	c.Assert(err, gc.ErrorMatches, regexp.QuoteMeta(`unknown key "access-key" (value "access-key")`))
}
Exemplo n.º 12
0
// GetCredentials returns a curated set of credential values for a given cloud.
// The credential key values are read from the credentials store and the provider
// finalises the values to resolve things like json files.
// If region is not specified, the default credential region is used.
func GetCredentials(
	store jujuclient.CredentialGetter, region, credentialName, cloudName, cloudType string,
) (_ *cloud.Credential, chosenCredentialName, regionName string, _ error) {

	credential, credentialName, defaultRegion, err := credentialByName(
		store, cloudName, credentialName,
	)
	if err != nil {
		return nil, "", "", errors.Trace(err)
	}

	regionName = region
	if regionName == "" {
		regionName = defaultRegion
	}

	readFile := func(f string) ([]byte, error) {
		f, err := utils.NormalizePath(f)
		if err != nil {
			return nil, errors.Trace(err)
		}
		return ioutil.ReadFile(f)
	}

	// Finalize credential against schemas supported by the provider.
	provider, err := environs.Provider(cloudType)
	if err != nil {
		return nil, "", "", errors.Trace(err)
	}

	credential, err = cloud.FinalizeCredential(
		*credential, provider.CredentialSchemas(), readFile,
	)
	if err != nil {
		return nil, "", "", errors.Annotatef(
			err, "validating %q credential for cloud %q",
			credentialName, cloudName,
		)
	}
	return credential, credentialName, regionName, nil
}
Exemplo n.º 13
0
func (s *credentialsSuite) TestFinalizeCredentialFileAttrBoth(c *gc.C) {
	cred := cloud.NewCredential(
		cloud.UserPassAuthType,
		map[string]string{
			"key":      "value",
			"key-file": "path",
		},
	)
	schema := cloud.CredentialSchema{{
		"key",
		cloud.CredentialAttr{
			Description: "key credential",
			Hidden:      true,
			FileAttr:    "key-file",
		},
	}}
	_, err := cloud.FinalizeCredential(cred, map[cloud.AuthType]cloud.CredentialSchema{
		cloud.UserPassAuthType: schema,
	}, readFileNotSupported)
	c.Assert(err, gc.ErrorMatches, `specifying both "key" and "key-file" not valid`)
}
Exemplo n.º 14
0
func (s *credentialsSuite) TestFinalizeCredentialFileEmpty(c *gc.C) {
	cred := cloud.NewCredential(
		cloud.UserPassAuthType,
		map[string]string{
			"key-file": "path",
		},
	)
	schema := cloud.CredentialSchema{{
		"key",
		cloud.CredentialAttr{
			Description: "key credential",
			Hidden:      true,
			FileAttr:    "key-file",
		},
	}}
	readFile := func(string) ([]byte, error) {
		return nil, nil
	}
	_, err := cloud.FinalizeCredential(cred, map[cloud.AuthType]cloud.CredentialSchema{
		cloud.UserPassAuthType: schema,
	}, readFile)
	c.Assert(err, gc.ErrorMatches, `empty file for "key" not valid`)
}
Exemplo n.º 15
0
// GetCredentials returns a curated set of credential values for a given cloud.
// The credential key values are read from the credentials store and the provider
// finalises the values to resolve things like json files.
// If region is not specified, the default credential region is used.
func GetCredentials(
	ctx *cmd.Context,
	store jujuclient.CredentialGetter,
	args GetCredentialsParams,
) (_ *cloud.Credential, chosenCredentialName, regionName string, _ error) {

	credential, credentialName, defaultRegion, err := credentialByName(
		store, args.CloudName, args.CredentialName,
	)
	if err != nil {
		return nil, "", "", errors.Trace(err)
	}

	regionName = args.CloudRegion
	if regionName == "" {
		regionName = defaultRegion
		if regionName == "" && len(args.Cloud.Regions) > 0 {
			// No region was specified, use the first region
			// in the list.
			regionName = args.Cloud.Regions[0].Name
		}
	}

	cloudEndpoint := args.Cloud.Endpoint
	cloudIdentityEndpoint := args.Cloud.IdentityEndpoint
	if regionName != "" {
		region, err := cloud.RegionByName(args.Cloud.Regions, regionName)
		if err != nil {
			return nil, "", "", errors.Trace(err)
		}
		cloudEndpoint = region.Endpoint
		cloudIdentityEndpoint = region.IdentityEndpoint
	}

	readFile := func(f string) ([]byte, error) {
		f, err := utils.NormalizePath(f)
		if err != nil {
			return nil, errors.Trace(err)
		}
		return ioutil.ReadFile(f)
	}

	// Finalize credential against schemas supported by the provider.
	provider, err := environs.Provider(args.Cloud.Type)
	if err != nil {
		return nil, "", "", errors.Trace(err)
	}

	credential, err = cloud.FinalizeCredential(
		*credential, provider.CredentialSchemas(), readFile,
	)
	if err != nil {
		return nil, "", "", errors.Annotatef(
			err, "finalizing %q credential for cloud %q",
			credentialName, args.CloudName,
		)
	}

	credential, err = provider.FinalizeCredential(
		ctx, environs.FinalizeCredentialParams{
			Credential:            *credential,
			CloudEndpoint:         cloudEndpoint,
			CloudIdentityEndpoint: cloudIdentityEndpoint,
		},
	)
	if err != nil {
		return nil, "", "", errors.Annotatef(
			err, "finalizing %q credential for cloud %q",
			credentialName, args.CloudName,
		)
	}

	return credential, credentialName, regionName, nil
}