Skip to content

Commit

Permalink
Identity V3: Add application credential resource
Browse files Browse the repository at this point in the history
  • Loading branch information
kayrus committed Feb 7, 2019
1 parent 427c6b3 commit d45bf77
Show file tree
Hide file tree
Showing 11 changed files with 765 additions and 1 deletion.
2 changes: 1 addition & 1 deletion openstack/data_source_openstack_identity_auth_scope_v3.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ func dataSourceIdentityAuthScopeV3Read(d *schema.ResourceData, meta interface{})
}

d.Set("user_name", user.Name)
d.Set("user_id", user.Name)
d.Set("user_id", user.ID)
d.Set("user_domain_name", user.Domain.Name)
d.Set("user_domain_id", user.Domain.ID)

Expand Down
21 changes: 21 additions & 0 deletions openstack/identity_application_credential_v3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package openstack

import (
"github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/applicationcredentials"
)

func flattenIdentityApplicationCredentialRolesV3(roles []applicationcredentials.Role) []string {
var res []string
for _, role := range roles {
res = append(res, role.Name)
}
return res
}

func expandIdentityApplicationCredentialRolesV3(roles []interface{}) []applicationcredentials.Role {
var res []applicationcredentials.Role
for _, role := range roles {
res = append(res, applicationcredentials.Role{Name: role.(string)})
}
return res
}
43 changes: 43 additions & 0 deletions openstack/identity_application_credential_v3_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package openstack

import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/applicationcredentials"
)

func TestFlattenIdentityApplicationCredentialRolesV3(t *testing.T) {
role1 := applicationcredentials.Role{
ID: "123",
Name: "foo",
}
role2 := applicationcredentials.Role{
ID: "321",
Name: "bar",
}

roles := []applicationcredentials.Role{role1, role2}

expected := []string{"foo", "bar"}

actual := flattenIdentityApplicationCredentialRolesV3(roles)
assert.Equal(t, expected, actual)
}

func TestExpandIdentityApplicationCredentialRolesV3(t *testing.T) {
role1 := applicationcredentials.Role{
Name: "foo",
}
role2 := applicationcredentials.Role{
Name: "bar",
}

roles := []interface{}{role1.Name, role2.Name}

expected := []applicationcredentials.Role{role1, role2}

actual := expandIdentityApplicationCredentialRolesV3(roles)
assert.Equal(t, expected, actual)
}
1 change: 1 addition & 0 deletions openstack/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ func Provider() terraform.ResourceProvider {
"openstack_identity_role_v3": resourceIdentityRoleV3(),
"openstack_identity_role_assignment_v3": resourceIdentityRoleAssignmentV3(),
"openstack_identity_user_v3": resourceIdentityUserV3(),
"openstack_identity_application_credential_v3": resourceIdentityApplicationCredentialV3(),
"openstack_images_image_v2": resourceImagesImageV2(),
"openstack_lb_member_v1": resourceLBMemberV1(),
"openstack_lb_monitor_v1": resourceLBMonitorV1(),
Expand Down
190 changes: 190 additions & 0 deletions openstack/resource_openstack_identity_application_credential_v3.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
package openstack

import (
"fmt"
"log"
"time"

"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack/identity/v3/extensions/applicationcredentials"
"github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
)

func resourceIdentityApplicationCredentialV3() *schema.Resource {
return &schema.Resource{
Create: resourceIdentityApplicationCredentialV3Create,
Read: resourceIdentityApplicationCredentialV3Read,
Delete: resourceIdentityApplicationCredentialV3Delete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"region": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},

"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"description": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},

"unrestricted": {
Type: schema.TypeBool,
Optional: true,
Default: false,
ForceNew: true,
},

"secret": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Sensitive: true,
ForceNew: true,
},

"project_id": {
Type: schema.TypeString,
Computed: true,
ForceNew: true,
},

"roles": {
Type: schema.TypeList,
Optional: true,
Computed: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
},

"expires_at": {Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.ValidateRFC3339TimeString,
},
},
}
}

func resourceIdentityApplicationCredentialV3Create(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
identityClient, err := config.identityV3Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating OpenStack identity client: %s", err)
}

token := tokens.Get(identityClient, config.OsClient.TokenID)
if token.Err != nil {
return token.Err
}

user, err := token.ExtractUser()
if err != nil {
return err
}

createOpts := applicationcredentials.CreateOpts{
Name: d.Get("name").(string),
Description: d.Get("description").(string),
Unrestricted: d.Get("unrestricted").(bool),
Roles: expandIdentityApplicationCredentialRolesV3(d.Get("roles").([]interface{})),
ExpiresAt: d.Get("expires_at").(string),
}

log.Printf("[DEBUG] openstack_identity_application_credential_v3 create options: %#v", createOpts)

createOpts.Secret = d.Get("secret").(string)

applicationCredential, err := applicationcredentials.Create(identityClient, user.ID, createOpts).Extract()
if err != nil {
if v, ok := err.(gophercloud.ErrDefault404); ok {
return fmt.Errorf("Error creating openstack_identity_application_credential_v3: %s", v.ErrUnexpectedResponseCode.Body)
}
return fmt.Errorf("Error creating openstack_identity_application_credential_v3: %s", err)
}

d.SetId(applicationCredential.ID)

// Secret is returned only once
d.Set("secret", applicationCredential.Secret)

return resourceIdentityApplicationCredentialV3Read(d, meta)
}

func resourceIdentityApplicationCredentialV3Read(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
identityClient, err := config.identityV3Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating OpenStack identity client: %s", err)
}

token := tokens.Get(identityClient, config.OsClient.TokenID)
if token.Err != nil {
return token.Err
}

user, err := token.ExtractUser()
if err != nil {
return err
}

applicationCredential, err := applicationcredentials.Get(identityClient, user.ID, d.Id()).Extract()
if err != nil {
return CheckDeleted(d, err, "Error retrieving openstack_identity_application_credential_v3")
}

log.Printf("[DEBUG] Retrieved openstack_identity_application_credential_v3 %s: %#v", d.Id(), applicationCredential)

d.Set("name", applicationCredential.Name)
d.Set("description", applicationCredential.Description)
d.Set("unrestricted", applicationCredential.Unrestricted)
d.Set("roles", flattenIdentityApplicationCredentialRolesV3(applicationCredential.Roles))
d.Set("project_id", applicationCredential.ProjectID)
d.Set("region", GetRegion(d, config))

if applicationCredential.ExpiresAt == (time.Time{}) {
d.Set("expires_at", "")
} else {
d.Set("expires_at", applicationCredential.ExpiresAt.UTC().Format(time.RFC3339))
}

return nil
}

func resourceIdentityApplicationCredentialV3Delete(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
identityClient, err := config.identityV3Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating OpenStack identity client: %s", err)
}

token := tokens.Get(identityClient, config.OsClient.TokenID)
if token.Err != nil {
return token.Err
}

user, err := token.ExtractUser()
if err != nil {
return err
}

err = applicationcredentials.Delete(identityClient, user.ID, d.Id()).ExtractErr()
if err != nil {
return CheckDeleted(d, err, "Error deleting openstack_identity_application_credential_v3")
}

return nil
}
Loading

0 comments on commit d45bf77

Please sign in to comment.