Skip to content

Commit

Permalink
Implement static credentials (#93)
Browse files Browse the repository at this point in the history
Implement static credentials

Description
Implement static users
Resolves: #74
Tests Performed
Acceptance tests
Running acceptance tests...
=== RUN   TestPlugin
=== RUN   TestPlugin/TestCloudLifecycle
=== RUN   TestPlugin/TestCloudLifecycle/WriteCloud
=== RUN   TestPlugin/TestCloudLifecycle/ReadCloud
=== RUN   TestPlugin/TestCloudLifecycle/ListClouds
=== RUN   TestPlugin/TestCloudLifecycle/ListClouds/method-LIST
=== PAUSE TestPlugin/TestCloudLifecycle/ListClouds/method-LIST
=== RUN   TestPlugin/TestCloudLifecycle/ListClouds/method-GET
=== PAUSE TestPlugin/TestCloudLifecycle/ListClouds/method-GET
=== CONT  TestPlugin/TestCloudLifecycle/ListClouds/method-LIST
=== CONT  TestPlugin/TestCloudLifecycle/ListClouds/method-GET
=== RUN   TestPlugin/TestCloudLifecycle/DeleteCloud
=== RUN   TestPlugin/TestCredsLifecycle
=== RUN   TestPlugin/TestCredsLifecycle/root_token
=== RUN   TestPlugin/TestCredsLifecycle/user_token
=== RUN   TestPlugin/TestCredsLifecycle/user_password
=== RUN   TestPlugin/TestCredsLifecycle/static_user_token
=== RUN   TestPlugin/TestCredsLifecycle/static_user_password
=== RUN   TestPlugin/TestInfo
=== RUN   TestPlugin/TestRoleLifecycle
    roles_test.go:53: Cloud with name `gev5efsque` was created
=== RUN   TestPlugin/TestRoleLifecycle/WriteRole
=== RUN   TestPlugin/TestRoleLifecycle/ReadRole
=== RUN   TestPlugin/TestRoleLifecycle/ListRoles
=== RUN   TestPlugin/TestRoleLifecycle/ListRoles/method-LIST
=== PAUSE TestPlugin/TestRoleLifecycle/ListRoles/method-LIST
=== RUN   TestPlugin/TestRoleLifecycle/ListRoles/method-GET
=== PAUSE TestPlugin/TestRoleLifecycle/ListRoles/method-GET
=== CONT  TestPlugin/TestRoleLifecycle/ListRoles/method-LIST
=== CONT  TestPlugin/TestRoleLifecycle/ListRoles/method-GET
=== RUN   TestPlugin/TestRoleLifecycle/DeleteRole
=== CONT  TestPlugin/TestRoleLifecycle
    plugin_test.go:337: Cloud with name `gev5efsque` has been removed
=== RUN   TestPlugin/TestRootRotate
    rotate_test.go:65: Cloud with name `default1` was created
    rotate_test.go:68: Cloud with name `t5n5` was created
    plugin_test.go:337: Cloud with name `t5n5` has been removed
    plugin_test.go:337: Cloud with name `default1` has been removed
--- PASS: TestPlugin (15.86s)
    --- PASS: TestPlugin/TestCloudLifecycle (0.41s)
        --- PASS: TestPlugin/TestCloudLifecycle/WriteCloud (0.40s)
        --- PASS: TestPlugin/TestCloudLifecycle/ReadCloud (0.00s)
        --- PASS: TestPlugin/TestCloudLifecycle/ListClouds (0.00s)
            --- PASS: TestPlugin/TestCloudLifecycle/ListClouds/method-LIST (0.00s)
            --- PASS: TestPlugin/TestCloudLifecycle/ListClouds/method-GET (0.00s)
        --- PASS: TestPlugin/TestCloudLifecycle/DeleteCloud (0.00s)
    --- PASS: TestPlugin/TestCredsLifecycle (9.36s)
        --- PASS: TestPlugin/TestCredsLifecycle/root_token (1.83s)
        --- PASS: TestPlugin/TestCredsLifecycle/user_token (2.23s)
        --- PASS: TestPlugin/TestCredsLifecycle/user_password (1.27s)
        --- PASS: TestPlugin/TestCredsLifecycle/static_user_token (2.11s)
        --- PASS: TestPlugin/TestCredsLifecycle/static_user_password (1.06s)
    --- PASS: TestPlugin/TestInfo (0.00s)
    --- PASS: TestPlugin/TestRoleLifecycle (0.02s)
        --- PASS: TestPlugin/TestRoleLifecycle/WriteRole (0.00s)
        --- PASS: TestPlugin/TestRoleLifecycle/ReadRole (0.00s)
        --- PASS: TestPlugin/TestRoleLifecycle/ListRoles (0.00s)
            --- PASS: TestPlugin/TestRoleLifecycle/ListRoles/method-GET (0.00s)
            --- PASS: TestPlugin/TestRoleLifecycle/ListRoles/method-LIST (0.00s)
        --- PASS: TestPlugin/TestRoleLifecycle/DeleteRole (0.00s)
    --- PASS: TestPlugin/TestRootRotate (4.87s)
PASS
ok      github.com/opentelekomcloud/vault-plugin-secrets-openstack/acceptance   15.863s

Unit tests
=== RUN   TestBackend_sharedCloud
--- PASS: TestBackend_sharedCloud (0.00s)
=== RUN   TestBackend_sharedCloud/existing
    --- PASS: TestBackend_sharedCloud/existing (0.00s)
=== RUN   TestBackend_sharedCloud/non-existing
    --- PASS: TestBackend_sharedCloud/non-existing (0.00s)
=== RUN   TestSharedCloud_client
--- PASS: TestSharedCloud_client (0.00s)
=== RUN   TestSharedCloud_client/existing-client
    --- PASS: TestSharedCloud_client/existing-client (0.00s)
=== RUN   TestSharedCloud_client/new-client
    --- PASS: TestSharedCloud_client/new-client (0.00s)
=== RUN   TestCloudCreate
--- PASS: TestCloudCreate (0.00s)
=== RUN   TestCloudCreate/EmptyConfig
    --- PASS: TestCloudCreate/EmptyConfig (0.00s)
=== RUN   TestCloudCreate/Create
    --- PASS: TestCloudCreate/Create (0.00s)
=== RUN   TestCloudCreate/Update
    --- PASS: TestCloudCreate/Update (0.00s)
=== RUN   TestCloudCreate/Read
    --- PASS: TestCloudCreate/Read (0.00s)
=== RUN   TestCloudCreate/Delete
    --- PASS: TestCloudCreate/Delete (0.00s)
=== RUN   TestCloudCreate/List
    --- PASS: TestCloudCreate/List (0.00s)
=== RUN   TestCredentialsRead_ok
--- PASS: TestCredentialsRead_ok (0.01s)
=== RUN   TestCredentialsRead_ok/root_token
    --- PASS: TestCredentialsRead_ok/root_token (0.00s)
=== RUN   TestCredentialsRead_ok/user_token
    --- PASS: TestCredentialsRead_ok/user_token (0.00s)
=== RUN   TestCredentialsRead_ok/user_password
    --- PASS: TestCredentialsRead_ok/user_password (0.00s)
=== RUN   TestCredentialsRead_ok/token_revoke
    --- PASS: TestCredentialsRead_ok/token_revoke (0.00s)
=== RUN   TestCredentialsRead_ok/user_password_revoke
    --- PASS: TestCredentialsRead_ok/user_password_revoke (0.00s)
=== RUN   TestCredentialsRead_error
--- PASS: TestCredentialsRead_error (0.00s)
=== RUN   TestCredentialsRead_error/read-fail
    --- PASS: TestCredentialsRead_error/read-fail (0.00s)
=== RUN   TestCredentialsRead_error/no-user-post
    --- PASS: TestCredentialsRead_error/no-user-post (0.00s)
=== RUN   TestCredentialsRead_error/no-users-token-post
    --- PASS: TestCredentialsRead_error/no-users-token-post (0.00s)
=== RUN   TestCredentialsRevoke_error
--- PASS: TestCredentialsRevoke_error (0.00s)
=== RUN   TestCredentialsRevoke_error/no-token-delete
    --- PASS: TestCredentialsRevoke_error/no-token-delete (0.00s)
=== RUN   TestCredentialsRevoke_error/no-user-delete
    --- PASS: TestCredentialsRevoke_error/no-user-delete (0.00s)
=== RUN   TestInfoRead
=== PAUSE TestInfoRead
=== CONT  TestInfoRead
--- PASS: TestInfoRead (0.00s)
=== RUN   TestRoleStoragePath
--- PASS: TestRoleStoragePath (0.00s)
=== RUN   TestRoleGet
=== PAUSE TestRoleGet
=== CONT  TestRoleGet
--- PASS: TestRoleGet (0.00s)
=== RUN   TestRoleGet/existing
=== PAUSE TestRoleGet/existing
=== CONT  TestRoleGet/existing
    --- PASS: TestRoleGet/existing (0.00s)
=== RUN   TestRoleGet/not-existing
=== PAUSE TestRoleGet/not-existing
=== CONT  TestRoleGet/not-existing
    --- PASS: TestRoleGet/not-existing (0.00s)
=== RUN   TestRoleGet/get-err
=== PAUSE TestRoleGet/get-err
=== CONT  TestRoleGet/get-err
    --- PASS: TestRoleGet/get-err (0.00s)
=== RUN   TestRoleExistence
=== PAUSE TestRoleExistence
=== CONT  TestRoleExistence
--- PASS: TestRoleExistence (0.00s)
=== RUN   TestRoleExistence/existing
=== PAUSE TestRoleExistence/existing
=== CONT  TestRoleExistence/existing
    --- PASS: TestRoleExistence/existing (0.00s)
=== RUN   TestRoleExistence/not-existing
=== PAUSE TestRoleExistence/not-existing
=== CONT  TestRoleExistence/not-existing
    --- PASS: TestRoleExistence/not-existing (0.00s)
=== RUN   TestRoleExistence/get-err
=== PAUSE TestRoleExistence/get-err
=== CONT  TestRoleExistence/get-err
    --- PASS: TestRoleExistence/get-err (0.00s)
=== RUN   TestRoleList
=== PAUSE TestRoleList
=== CONT  TestRoleList
--- PASS: TestRoleList (0.00s)
=== RUN   TestRoleList/ok
    --- PASS: TestRoleList/ok (0.00s)
=== RUN   TestRoleList/error
=== PAUSE TestRoleList/error
=== CONT  TestRoleList/error
    --- PASS: TestRoleList/error (0.00s)
=== RUN   TestRoleList/filter
=== PAUSE TestRoleList/filter
=== CONT  TestRoleList/filter
    --- PASS: TestRoleList/filter (0.00s)
=== RUN   TestRoleList/filter-get-err
=== PAUSE TestRoleList/filter-get-err
=== CONT  TestRoleList/filter-get-err
    --- PASS: TestRoleList/filter-get-err (0.00s)
=== RUN   TestRoleDelete
=== PAUSE TestRoleDelete
=== CONT  TestRoleDelete
--- PASS: TestRoleDelete (0.00s)
=== RUN   TestRoleDelete/existing
=== PAUSE TestRoleDelete/existing
=== CONT  TestRoleDelete/existing
    --- PASS: TestRoleDelete/existing (0.00s)
=== RUN   TestRoleDelete/not-existing
=== PAUSE TestRoleDelete/not-existing
=== CONT  TestRoleDelete/not-existing
    --- PASS: TestRoleDelete/not-existing (0.00s)
=== RUN   TestRoleDelete/error
=== PAUSE TestRoleDelete/error
=== CONT  TestRoleDelete/error
    --- PASS: TestRoleDelete/error (0.00s)
=== RUN   TestRoleDelete/error-get
=== PAUSE TestRoleDelete/error-get
=== CONT  TestRoleDelete/error-get
    --- PASS: TestRoleDelete/error-get (0.00s)
=== RUN   TestRoleCreate
=== PAUSE TestRoleCreate
=== CONT  TestRoleCreate
--- PASS: TestRoleCreate (0.01s)
=== RUN   TestRoleCreate/ok
    --- PASS: TestRoleCreate/ok (0.00s)
=== RUN   TestRoleCreate/ok/admin
=== PAUSE TestRoleCreate/ok/admin
=== CONT  TestRoleCreate/ok/admin
        --- PASS: TestRoleCreate/ok/admin (0.00s)
=== RUN   TestRoleCreate/ok/token
=== PAUSE TestRoleCreate/ok/token
=== CONT  TestRoleCreate/ok/token
        --- PASS: TestRoleCreate/ok/token (0.00s)
=== RUN   TestRoleCreate/ok/password
=== PAUSE TestRoleCreate/ok/password
=== CONT  TestRoleCreate/ok/password
        --- PASS: TestRoleCreate/ok/password (0.00s)
=== RUN   TestRoleCreate/ok/ttl
=== PAUSE TestRoleCreate/ok/ttl
=== CONT  TestRoleCreate/ok/ttl
        --- PASS: TestRoleCreate/ok/ttl (0.00s)
=== RUN   TestRoleCreate/ok/username
=== PAUSE TestRoleCreate/ok/username
=== CONT  TestRoleCreate/ok/username
        --- PASS: TestRoleCreate/ok/username (0.00s)
=== RUN   TestRoleCreate/ok/endpoint-override
=== PAUSE TestRoleCreate/ok/endpoint-override
=== CONT  TestRoleCreate/ok/endpoint-override
        --- PASS: TestRoleCreate/ok/endpoint-override (0.00s)
=== RUN   TestRoleCreate/error
    --- PASS: TestRoleCreate/error (0.00s)
=== RUN   TestRoleCreate/error/root-password
=== PAUSE TestRoleCreate/error/root-password
=== CONT  TestRoleCreate/error/root-password
        --- PASS: TestRoleCreate/error/root-password (0.00s)
=== RUN   TestRoleCreate/error/root-user-groups
=== PAUSE TestRoleCreate/error/root-user-groups
=== CONT  TestRoleCreate/error/root-user-groups
        --- PASS: TestRoleCreate/error/root-user-groups (0.00s)
=== RUN   TestRoleCreate/error/root-user-roles
=== PAUSE TestRoleCreate/error/root-user-roles
=== CONT  TestRoleCreate/error/root-user-roles
        --- PASS: TestRoleCreate/error/root-user-roles (0.00s)
=== RUN   TestRoleCreate/error/without-cloud
=== PAUSE TestRoleCreate/error/without-cloud
=== CONT  TestRoleCreate/error/without-cloud
        --- PASS: TestRoleCreate/error/without-cloud (0.00s)
=== RUN   TestRoleCreate/error/root-ttl
=== PAUSE TestRoleCreate/error/root-ttl
=== CONT  TestRoleCreate/error/root-ttl
        --- PASS: TestRoleCreate/error/root-ttl (0.00s)
=== RUN   TestRoleCreate/not-existing-cloud
=== PAUSE TestRoleCreate/not-existing-cloud
=== CONT  TestRoleCreate/not-existing-cloud
    --- PASS: TestRoleCreate/not-existing-cloud (0.00s)
=== RUN   TestRoleCreate/save-store-err
=== PAUSE TestRoleCreate/save-store-err
=== CONT  TestRoleCreate/save-store-err
    --- PASS: TestRoleCreate/save-store-err (0.00s)
=== RUN   TestRoleUpdate
=== PAUSE TestRoleUpdate
=== CONT  TestRoleUpdate
--- PASS: TestRoleUpdate (0.00s)
=== RUN   TestRoleUpdate/ok
    --- PASS: TestRoleUpdate/ok (0.00s)
=== RUN   TestRoleUpdate/not-existing
    --- PASS: TestRoleUpdate/not-existing (0.00s)
=== RUN   TestRotateRootCredentials_ok
--- PASS: TestRotateRootCredentials_ok (0.00s)
=== RUN   TestRotateRootCredentials_error
=== PAUSE TestRotateRootCredentials_error
=== CONT  TestRotateRootCredentials_error
--- PASS: TestRotateRootCredentials_error (0.01s)
=== RUN   TestRotateRootCredentials_error/read-fail
    --- PASS: TestRotateRootCredentials_error/read-fail (0.00s)
=== RUN   TestRotateRootCredentials_error/no-change
    --- PASS: TestRotateRootCredentials_error/no-change (0.00s)
=== RUN   TestRotateRootCredentials_error/no-post
    --- PASS: TestRotateRootCredentials_error/no-post (0.00s)
=== RUN   TestRotateRootCredentials_error/no-get
    --- PASS: TestRotateRootCredentials_error/no-get (0.00s)
PASS
ok  	github.com/opentelekomcloud/vault-plugin-secrets-openstack/openstack	(cached)
?   	github.com/opentelekomcloud/vault-plugin-secrets-openstack/openstack/fixtures	[no test files]

Process finished with the exit code 0

Reviewed-by: Anton Sidelnikov <None>
  • Loading branch information
lego963 authored Jun 30, 2022
1 parent 60e9d0f commit 296a798
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 32 deletions.
64 changes: 45 additions & 19 deletions acceptance/creds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,24 @@ import (
"net/http"
"testing"

"github.com/gophercloud/gophercloud/acceptance/tools"
"github.com/opentelekomcloud/vault-plugin-secrets-openstack/openstack"
"github.com/opentelekomcloud/vault-plugin-secrets-openstack/openstack/fixtures"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

type testCase struct {
Cloud string
Username string
ProjectID string
DomainID string
Root bool
SecretType string
UserRoles []string
Extensions map[string]interface{}
}

func (p *PluginTest) TestCredsLifecycle() {
t := p.T()

Expand All @@ -22,16 +34,6 @@ func (p *PluginTest) TestCredsLifecycle() {

_, aux := openstackClient(t)

type testCase struct {
Cloud string
ProjectID string
DomainID string
Root bool
SecretType string
UserRoles []string
Extensions map[string]interface{}
}

cases := map[string]testCase{
"root_token": {
Cloud: cloud.Name,
Expand Down Expand Up @@ -60,6 +62,29 @@ func (p *PluginTest) TestCredsLifecycle() {
"object_store_endpoint_override": "https://swift.example.com",
},
},
"static_user_token": {
Cloud: cloud.Name,
Username: tools.RandomString("vault-iam-", 3),
ProjectID: aux.ProjectID,
DomainID: aux.DomainID,
Root: false,
SecretType: "token",
UserRoles: []string{"member"},
Extensions: map[string]interface{}{
"identity_api_version": "3",
},
},
"static_user_password": {
Cloud: cloud.Name,
Username: tools.RandomString("vault-iam-", 3),
ProjectID: aux.ProjectID,
DomainID: aux.DomainID,
Root: false,
SecretType: "password",
Extensions: map[string]interface{}{
"object_store_endpoint_override": "https://swift.example.com",
},
},
}

for name, data := range cases {
Expand Down Expand Up @@ -88,7 +113,7 @@ func (p *PluginTest) TestCredsLifecycle() {
resp, err = p.vaultDo(
http.MethodPost,
roleURL(roleName),
cloudToRoleMap(data.Root, data.Cloud, data.ProjectID, data.DomainID, data.SecretType, data.UserRoles, data.Extensions),
cloudToRoleMap(data),
)
require.NoError(t, err)
assert.Equal(t, http.StatusNoContent, resp.StatusCode, readJSONResponse(t, resp))
Expand Down Expand Up @@ -152,14 +177,15 @@ func cloudToCloudMap(cloud *openstack.OsCloud) map[string]interface{} {
}
}

func cloudToRoleMap(root bool, cloud, projectID, domainID, secretType string, userRoles []string, extensions map[string]interface{}) map[string]interface{} {
func cloudToRoleMap(data testCase) map[string]interface{} {
return fixtures.SanitizedMap(map[string]interface{}{
"cloud": cloud,
"project_id": projectID,
"domain_id": domainID,
"root": root,
"secret_type": secretType,
"user_roles": userRoles,
"extensions": extensions,
"cloud": data.Cloud,
"username": data.Username,
"project_id": data.ProjectID,
"domain_id": data.DomainID,
"root": data.Root,
"secret_type": data.SecretType,
"user_roles": data.UserRoles,
"extensions": data.Extensions,
})
}
37 changes: 24 additions & 13 deletions openstack/path_creds.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,20 @@ func getRootCredentials(client *gophercloud.ServiceClient, opts *credsOpts) (*lo
return &logical.Response{Data: data, Secret: secret}, nil
}

func getTmpUserCredentials(client *gophercloud.ServiceClient, opts *credsOpts) (*logical.Response, error) {
func getUserCredentials(client *gophercloud.ServiceClient, opts *credsOpts) (*logical.Response, error) {
password, err := opts.PwdGenerator.Generate(context.Background())
if err != nil {
return nil, err
}

username, err := RandomTemporaryUsername(opts.UsernameTemplate, opts.Role)
if err != nil {
return logical.ErrorResponse("error generating username for temporary user: %s", err), nil
username := opts.Role.Username
static := true
if username == "" {
username, err = RandomTemporaryUsername(opts.UsernameTemplate, opts.Role)
if err != nil {
return logical.ErrorResponse("error generating username for temporary user: %s", err), nil
}
static = false
}

user, err := createUser(client, username, password, opts.Role)
Expand Down Expand Up @@ -182,6 +187,7 @@ func getTmpUserCredentials(client *gophercloud.ServiceClient, opts *credsOpts) (
"user_id": user.ID,
"cloud": opts.Config.Name,
"expires_at": token.ExpiresAt.String(),
"static": static,
}
case SecretPassword:
authResponse := &authResponseData{
Expand All @@ -202,6 +208,7 @@ func getTmpUserCredentials(client *gophercloud.ServiceClient, opts *credsOpts) (
"secret_type": backendSecretTypeUser,
"user_id": user.ID,
"cloud": opts.Config.Name,
"static": static,
}
default:
return nil, fmt.Errorf("invalid secret type: %s", r)
Expand All @@ -211,15 +218,19 @@ func getTmpUserCredentials(client *gophercloud.ServiceClient, opts *credsOpts) (
data[extensionKey] = extensionValue
}

secret := &logical.Secret{
InternalData: secretInternal,
}
if !static {
secret.LeaseOptions = logical.LeaseOptions{
TTL: opts.Role.TTL * time.Second,
IssueTime: time.Now(),
}
}

return &logical.Response{
Data: data,
Secret: &logical.Secret{
LeaseOptions: logical.LeaseOptions{
TTL: opts.Role.TTL * time.Second,
IssueTime: time.Now(),
},
InternalData: secretInternal,
},
Data: data,
Secret: secret,
}, nil
}

Expand Down Expand Up @@ -252,7 +263,7 @@ func (b *backend) pathCredsRead(ctx context.Context, r *logical.Request, d *fram
return getRootCredentials(client, opts)
}

return getTmpUserCredentials(client, opts)
return getUserCredentials(client, opts)
}

func (b *backend) tokenRevoke(ctx context.Context, r *logical.Request, d *framework.FieldData) (*logical.Response, error) {
Expand Down
13 changes: 13 additions & 0 deletions openstack/path_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ func (b *backend) pathRole() *framework.Path {
Description: "Specifies whenever to use the root user as a role actor.",
Default: false,
},
"username": {
Type: framework.TypeString,
Description: "Specifies the username of the static user.",
},
"ttl": {
Type: framework.TypeDurationSecond,
Description: "Specifies TTL value for the dynamically created users as a string duration with time suffix.",
Expand Down Expand Up @@ -158,6 +162,7 @@ type roleEntry struct {
SecretType secretType `json:"secret_type"`
UserGroups []string `json:"user_groups"`
UserRoles []string `json:"user_roles"`
Username string `json:"username"`
ProjectID string `json:"project_id"`
ProjectName string `json:"project_name"`
DomainID string `json:"domain_id"`
Expand Down Expand Up @@ -205,6 +210,7 @@ func roleToMap(src *roleEntry) map[string]interface{} {
"root": src.Root,
"ttl": src.TTL,
"secret_type": string(src.SecretType),
"username": src.Username,
"user_groups": src.UserGroups,
"user_roles": src.UserRoles,
"project_id": src.ProjectID,
Expand Down Expand Up @@ -319,6 +325,13 @@ func (b *backend) pathRoleUpdate(ctx context.Context, req *logical.Request, d *f
entry.UserRoles = roles.([]string)
}

if username, ok := d.GetOk("username"); ok {
if entry.Root {
return logical.ErrorResponse(errInvalidForRoot, "username"), nil
}
entry.Username = username.(string)
}

if err := saveRole(ctx, entry, req.Storage); err != nil {
return nil, err
}
Expand Down
13 changes: 13 additions & 0 deletions openstack/path_role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ func randomRoleName() string {
return tools.RandomString("k", 5) + "m"
}

func randomUsername() string {
return tools.RandomString("u", 5)
}

func expectedRoleData(cloudName string) (*roleEntry, map[string]interface{}) {
expTTL := time.Hour
expected := &roleEntry{
Expand All @@ -42,6 +46,7 @@ func expectedRoleData(cloudName string) (*roleEntry, map[string]interface{}) {
expectedMap := map[string]interface{}{
"cloud": expected.Cloud,
"ttl": expTTL,
"username": "",
"project_id": "",
"project_name": expected.ProjectName,
"domain_id": "",
Expand Down Expand Up @@ -349,6 +354,14 @@ func TestRoleCreate(t *testing.T) {
UserGroups: []string{"default", "testing"},
TTL: 24 * time.Hour,
},
"username": {
Name: randomRoleName(),
Cloud: cloudName,
ProjectName: randomRoleName(),
Username: randomUsername(),
SecretType: SecretToken,
UserGroups: []string{"default", "testing"},
},
"endpoint-override": {
Name: randomRoleName(),
Cloud: cloudName,
Expand Down

0 comments on commit 296a798

Please sign in to comment.