-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
provider/aws: Added Cognito Identity Pool Roles Association
- Loading branch information
Showing
8 changed files
with
1,195 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
307 changes: 307 additions & 0 deletions
307
builtin/providers/aws/resource_aws_cognito_identity_pool_roles_attachment.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,307 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"bytes" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/aws/awserr" | ||
"github.com/aws/aws-sdk-go/service/cognitoidentity" | ||
"github.com/hashicorp/terraform/helper/hashcode" | ||
"github.com/hashicorp/terraform/helper/resource" | ||
"github.com/hashicorp/terraform/helper/schema" | ||
) | ||
|
||
func resourceAwsCognitoIdentityPoolRolesAttachment() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceAwsCognitoIdentityPoolRolesAttachmentCreate, | ||
Read: resourceAwsCognitoIdentityPoolRolesAttachmentRead, | ||
Update: resourceAwsCognitoIdentityPoolRolesAttachmentUpdate, | ||
Delete: resourceAwsCognitoIdentityPoolRolesAttachmentDelete, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"identity_pool_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"role_mappings": { | ||
Type: schema.TypeList, | ||
Optional: true, | ||
MaxItems: 1, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"role_mapping": { | ||
Type: schema.TypeSet, | ||
Required: true, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"key": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
}, | ||
"value": { | ||
Type: schema.TypeSet, | ||
MaxItems: 1, | ||
Required: true, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"ambiguous_role_resolution": { | ||
Type: schema.TypeString, | ||
ValidateFunc: validateCognitoRoleMappingsAmbiguousRoleResolution, | ||
Optional: true, // Required if Type equals Token or Rules. | ||
}, | ||
"rules_configuration": { | ||
Type: schema.TypeSet, | ||
MaxItems: 1, | ||
Optional: true, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"rules": { | ||
Type: schema.TypeList, | ||
Required: true, | ||
MaxItems: 25, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"claim": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ValidateFunc: validateCognitoRoleMappingsRulesClaim, | ||
}, | ||
"match_type": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ValidateFunc: validateCognitoRoleMappingsRulesMatchType, | ||
}, | ||
"role_arn": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ValidateFunc: validateArn, | ||
}, | ||
"value": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ValidateFunc: validateCognitoRoleMappingsRulesValue, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
"type": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ValidateFunc: validateCognitoRoleMappingsType, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
|
||
"roles": { | ||
Type: schema.TypeMap, | ||
Required: true, | ||
ForceNew: true, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"authenticated": { | ||
Type: schema.TypeString, | ||
ValidateFunc: validateArn, | ||
Optional: true, // Required if unauthenticated isn't defined. | ||
}, | ||
"unauthenticated": { | ||
Type: schema.TypeString, | ||
ValidateFunc: validateArn, | ||
Optional: true, // Required if authenticated isn't defined. | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsCognitoIdentityPoolRolesAttachmentCreate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).cognitoconn | ||
log.Print("[DEBUG] Creating Cognito Identity Pool Roles Association") | ||
|
||
// Validates role keys to be either authenticated or unauthenticated, | ||
// since ValidateFunc validates only the value not the key. | ||
if errors := validateCognitoRoles(d.Get("roles").(map[string]interface{}), "roles"); len(errors) > 0 { | ||
return fmt.Errorf("Error validating Roles: %v", errors) | ||
} | ||
|
||
params := &cognitoidentity.SetIdentityPoolRolesInput{ | ||
IdentityPoolId: aws.String(d.Get("identity_pool_id").(string)), | ||
Roles: expandCognitoIdentityPoolRoles(d.Get("roles").(map[string]interface{})), | ||
} | ||
|
||
if v, ok := d.GetOk("role_mappings"); ok { | ||
rms := v.([]interface{})[0].(map[string]interface{}) | ||
errors := validateRoleMappings(rms["role_mapping"].(*schema.Set).List()) | ||
|
||
if len(errors) > 0 { | ||
return fmt.Errorf("Error validating ambiguous role resolution: %v", errors) | ||
} | ||
|
||
params.RoleMappings = expandCognitoIdentityPoolRoleMappingsAttachment(v.([]interface{})) | ||
} | ||
|
||
_, err := conn.SetIdentityPoolRoles(params) | ||
if err != nil { | ||
return fmt.Errorf("Error creating Cognito Identity Pool Roles Association: %s", err) | ||
} | ||
|
||
d.SetId(d.Get("identity_pool_id").(string)) | ||
|
||
return resourceAwsCognitoIdentityPoolRolesAttachmentRead(d, meta) | ||
} | ||
|
||
func resourceAwsCognitoIdentityPoolRolesAttachmentRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).cognitoconn | ||
log.Printf("[DEBUG] Reading Cognito Identity Pool Roles Association: %s", d.Id()) | ||
|
||
ip, err := conn.GetIdentityPoolRoles(&cognitoidentity.GetIdentityPoolRolesInput{ | ||
IdentityPoolId: aws.String(d.Get("identity_pool_id").(string)), | ||
}) | ||
if err != nil { | ||
if awsErr, ok := err.(awserr.Error); ok && awsErr.Code() == "ResourceNotFoundException" { | ||
d.SetId("") | ||
return nil | ||
} | ||
return err | ||
} | ||
|
||
if err := d.Set("roles", flattenCognitoIdentityPoolRoles(ip.Roles)); err != nil { | ||
return fmt.Errorf("[DEBUG] Error setting roles error: %#v", err) | ||
} | ||
|
||
if err := d.Set("role_mappings", flattenCognitoIdentityPoolRoleMappingsAttachment(ip.RoleMappings)); err != nil { | ||
return fmt.Errorf("[DEBUG] Error setting role mappings error: %#v", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func resourceAwsCognitoIdentityPoolRolesAttachmentUpdate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).cognitoconn | ||
log.Printf("[DEBUG] Updating Cognito Identity Pool Roles Association: %s", d.Id()) | ||
|
||
// Validates role keys to be either authenticated or unauthenticated, | ||
// since ValidateFunc validates only the value not the key. | ||
if errors := validateCognitoRoles(d.Get("roles").(map[string]interface{}), "roles"); len(errors) > 0 { | ||
return fmt.Errorf("Error validating Roles: %v", errors) | ||
} | ||
|
||
params := &cognitoidentity.SetIdentityPoolRolesInput{ | ||
IdentityPoolId: aws.String(d.Get("identity_pool_id").(string)), | ||
Roles: expandCognitoIdentityPoolRoles(d.Get("roles").(map[string]interface{})), | ||
} | ||
|
||
if d.HasChange("role_mappings") { | ||
v, ok := d.GetOk("role_mappings") | ||
var mappings []interface{} | ||
|
||
if ok { | ||
rms := v.([]interface{})[0].(map[string]interface{}) | ||
errors := validateRoleMappings(rms["role_mapping"].(*schema.Set).List()) | ||
|
||
if len(errors) > 0 { | ||
return fmt.Errorf("Error validating ambiguous role resolution: %v", errors) | ||
} | ||
mappings = v.([]interface{}) | ||
} else { | ||
mappings = []interface{}{} | ||
} | ||
|
||
params.RoleMappings = expandCognitoIdentityPoolRoleMappingsAttachment(mappings) | ||
} | ||
|
||
_, err := conn.SetIdentityPoolRoles(params) | ||
if err != nil { | ||
return fmt.Errorf("Error updating Cognito Identity Pool Roles Association: %s", err) | ||
} | ||
|
||
d.SetId(d.Get("identity_pool_id").(string)) | ||
|
||
return resourceAwsCognitoIdentityPoolRolesAttachmentRead(d, meta) | ||
} | ||
|
||
func resourceAwsCognitoIdentityPoolRolesAttachmentDelete(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).cognitoconn | ||
log.Printf("[DEBUG] Deleting Cognito Identity Pool Roles Association: %s", d.Id()) | ||
|
||
return resource.Retry(5*time.Minute, func() *resource.RetryError { | ||
_, err := conn.SetIdentityPoolRoles(&cognitoidentity.SetIdentityPoolRolesInput{ | ||
IdentityPoolId: aws.String(d.Get("identity_pool_id").(string)), | ||
Roles: expandCognitoIdentityPoolRoles(make(map[string]interface{})), | ||
RoleMappings: expandCognitoIdentityPoolRoleMappingsAttachment([]interface{}{}), | ||
}) | ||
|
||
if err == nil { | ||
return nil | ||
} | ||
|
||
return resource.NonRetryableError(err) | ||
}) | ||
} | ||
|
||
// Validating that each role_mapping ambiguous_role_resolution | ||
// is defined when "type" equals Token or Rules. | ||
func validateRoleMappings(roleMappings []interface{}) []error { | ||
errors := make([]error, 0) | ||
|
||
for _, r := range roleMappings { | ||
rm := r.(map[string]interface{}) | ||
roleMapping := rm["value"].(*schema.Set).List() | ||
|
||
if err := validateCognitoRoleMappingsAmbiguousRoleResolutionAgainstType(roleMapping[0].(map[string]interface{})); len(err) > 0 { | ||
errors = append(errors, fmt.Errorf("Role Mapping %q: %v", rm["key"].(string), err)) | ||
} | ||
} | ||
|
||
return errors | ||
} | ||
|
||
func cognitoRoleMappingHash(v interface{}) int { | ||
var buf bytes.Buffer | ||
m := v.(map[string]interface{}) | ||
buf.WriteString(fmt.Sprintf("%s-", m["key"].(string))) | ||
|
||
return hashcode.String(buf.String()) | ||
} | ||
|
||
func cognitoRoleMappingValueHash(v interface{}) int { | ||
var buf bytes.Buffer | ||
m := v.(map[string]interface{}) | ||
buf.WriteString(fmt.Sprintf("%s-", m["type"].(string))) | ||
if d, ok := m["ambiguous_role_resolution"]; ok { | ||
buf.WriteString(fmt.Sprintf("%s-", d.(string))) | ||
} | ||
|
||
return hashcode.String(buf.String()) | ||
} | ||
|
||
func cognitoRoleMappingRulesConfigurationHash(v interface{}) int { | ||
var buf bytes.Buffer | ||
m := v.(map[string]interface{}) | ||
for _, rule := range m["rules"].([]interface{}) { | ||
r := rule.(map[string]interface{}) | ||
buf.WriteString(fmt.Sprintf("%s-", r["claim"].(string))) | ||
buf.WriteString(fmt.Sprintf("%s-", r["match_type"].(string))) | ||
buf.WriteString(fmt.Sprintf("%s-", r["role_arn"].(string))) | ||
buf.WriteString(fmt.Sprintf("%s-", r["value"].(string))) | ||
} | ||
|
||
return hashcode.String(buf.String()) | ||
} |
Oops, something went wrong.