Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(IAM Policy Management): allow sourceServiceName to be optional for authorization policy #4804

Merged
merged 10 commits into from
Sep 27, 2023
42 changes: 26 additions & 16 deletions ibm/service/iampolicy/resource_ibm_iam_authorization_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@ func ResourceIBMIAMAuthorizationPolicy() *schema.Resource {
Type: schema.TypeString,
swcolley marked this conversation as resolved.
Show resolved Hide resolved
Optional: true,
Computed: true,
ExactlyOneOf: []string{"source_service_name", "subject_attributes"},
Description: "The source service name",
ForceNew: true,
AtLeastOneOf: []string{"source_service_name", "source_resource_group_id", "subject_attributes"},
Description: "The source service name",
},

"target_service_name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ExactlyOneOf: []string{"target_service_name", "resource_attributes"},
ForceNew: true,
AtLeastOneOf: []string{"target_service_name", "target_resource_type", "resource_attributes"},
Description: "The target service name",
},

Expand Down Expand Up @@ -126,7 +126,7 @@ func ResourceIBMIAMAuthorizationPolicy() *schema.Resource {
Computed: true,
ForceNew: true,
Description: "Set subject attributes.",
ConflictsWith: []string{"source_resource_instance_id", "source_resource_group_id", "source_resource_type", "source_service_account"},
ConflictsWith: []string{"source_service_name", "source_resource_instance_id", "source_resource_group_id", "source_resource_type", "source_service_account"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Expand All @@ -149,7 +149,7 @@ func ResourceIBMIAMAuthorizationPolicy() *schema.Resource {
Computed: true,
ForceNew: true,
Description: "Set resource attributes.",
ConflictsWith: []string{"target_resource_instance_id", "target_resource_group_id", "target_resource_type"},
ConflictsWith: []string{"target_service_name", "target_resource_instance_id", "target_resource_group_id", "target_resource_type"},
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Expand Down Expand Up @@ -249,13 +249,15 @@ func resourceIBMIAMAuthorizationPolicyCreate(d *schema.ResourceData, meta interf
}
} else {

sourceServiceName = d.Get("source_service_name").(string)
if name, ok := d.GetOk("source_service_name"); ok {
sourceServiceName = name.(string)

serviceNameSubjectAttribute := &iampolicymanagementv1.SubjectAttribute{
Name: core.StringPtr("serviceName"),
Value: &sourceServiceName,
serviceNameSubjectAttribute := &iampolicymanagementv1.SubjectAttribute{
Name: core.StringPtr("serviceName"),
Value: &sourceServiceName,
}
policySubject.Attributes = append(policySubject.Attributes, *serviceNameSubjectAttribute)
}
policySubject.Attributes = append(policySubject.Attributes, *serviceNameSubjectAttribute)

sourceServiceAccount := userDetails.UserAccount
if account, ok := d.GetOk("source_service_account"); ok {
Expand Down Expand Up @@ -304,6 +306,9 @@ func resourceIBMIAMAuthorizationPolicyCreate(d *schema.ResourceData, meta interf
if name == "serviceName" {
targetServiceName = value
}
if name == "resourceType" && targetServiceName == "" {
targetServiceName = "resource-controller"
}
at := iampolicymanagementv1.ResourceAttribute{
Name: &name,
Value: &value,
Expand All @@ -312,13 +317,15 @@ func resourceIBMIAMAuthorizationPolicyCreate(d *schema.ResourceData, meta interf
policyResource.Attributes = append(policyResource.Attributes, at)
}
} else {
targetServiceName = d.Get("target_service_name").(string)
serviceNameResourceAttribute := &iampolicymanagementv1.ResourceAttribute{
Name: core.StringPtr("serviceName"),
Value: core.StringPtr(targetServiceName),
Operator: core.StringPtr("stringEquals"),
if name, ok := d.GetOk("target_service_name"); ok {
targetServiceName = name.(string)
serviceNameResourceAttribute := &iampolicymanagementv1.ResourceAttribute{
Name: core.StringPtr("serviceName"),
Value: core.StringPtr(targetServiceName),
Operator: core.StringPtr("stringEquals"),
}
policyResource.Attributes = append(policyResource.Attributes, *serviceNameResourceAttribute)
}
policyResource.Attributes = append(policyResource.Attributes, *serviceNameResourceAttribute)

accountIDResourceAttribute := &iampolicymanagementv1.ResourceAttribute{
Name: core.StringPtr("accountId"),
Expand All @@ -342,6 +349,9 @@ func resourceIBMIAMAuthorizationPolicyCreate(d *schema.ResourceData, meta interf
Value: core.StringPtr(tType.(string)),
}
policyResource.Attributes = append(policyResource.Attributes, resourceTypeResourceAttribute)
if targetServiceName == "" {
targetServiceName = "resource-controller"
}
}

if tResGrpID, ok := d.GetOk("target_resource_group_id"); ok {
Expand Down
170 changes: 168 additions & 2 deletions ibm/service/iampolicy/resource_ibm_iam_authorization_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ func TestAccIBMIAMAuthorizationPolicy_ResourceType(t *testing.T) {
testAccCheckIBMIAMAuthorizationPolicyExists("ibm_iam_authorization_policy.policy", conf),
resource.TestCheckResourceAttr("ibm_iam_authorization_policy.policy", "source_service_name", "is"),
resource.TestCheckResourceAttr("ibm_iam_authorization_policy.policy", "source_resource_type", "load-balancer"),
resource.TestCheckResourceAttr("ibm_iam_authorization_policy.policy", "target_service_name", "cloudcerts"),
resource.TestCheckResourceAttr("ibm_iam_authorization_policy.policy", "target_service_name", "hs-crypto"),
),
},
},
Expand Down Expand Up @@ -154,6 +154,96 @@ func TestAccIBMIAMAuthorizationPolicy_ResourceAttributes(t *testing.T) {
})
}

func TestAccIBMIAMAuthorizationPolicy_SourceResourceGroupId(t *testing.T) {
var conf iampolicymanagementv1.PolicyTemplateMetaData
resourceName := "ibm_iam_authorization_policy.policy"
resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
CheckDestroy: testAccCheckIBMIAMAuthorizationPolicyDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckIBMIAMAuthorizationPolicySourceResourceGroupId(),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckIBMIAMAuthorizationPolicyExists("ibm_iam_authorization_policy.policy", conf),
resource.TestCheckResourceAttrSet("ibm_iam_authorization_policy.policy", "id"),
resource.TestCheckResourceAttr("ibm_iam_authorization_policy.policy", "source_service_name", ""),
resource.TestCheckResourceAttr("ibm_iam_authorization_policy.policy", "target_service_name", "cloud-object-storage"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"transaction_id"},
},
},
})
}

func TestAccIBMIAMAuthorizationPolicy_SourceResourceGroupId_ResourceAttributes(t *testing.T) {
var conf iampolicymanagementv1.PolicyTemplateMetaData

resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
CheckDestroy: testAccCheckIBMIAMAuthorizationPolicyDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckIBMIAMAuthorizationPolicySourceResourceGroupIdResourceAttributes(acc.Tg_cross_network_account_id, acc.Tg_cross_network_account_id),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckIBMIAMAuthorizationPolicyExists("ibm_iam_authorization_policy.policy", conf),
resource.TestCheckResourceAttrSet("ibm_iam_authorization_policy.policy", "id"),
resource.TestCheckResourceAttr("ibm_iam_authorization_policy.policy", "source_service_name", ""),
resource.TestCheckResourceAttr("ibm_iam_authorization_policy.policy", "target_service_name", "cloud-object-storage"),
),
},
},
})
}

func TestAccIBMIAMAuthorizationPolicy_TargetResourceType(t *testing.T) {
var conf iampolicymanagementv1.PolicyTemplateMetaData

resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
CheckDestroy: testAccCheckIBMIAMAuthorizationPolicyDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckIBMIAMAuthorizationPolicyTargetResourceType(),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckIBMIAMAuthorizationPolicyExists("ibm_iam_authorization_policy.policy", conf),
resource.TestCheckResourceAttr("ibm_iam_authorization_policy.policy", "target_service_name", ""),
resource.TestCheckResourceAttr("ibm_iam_authorization_policy.policy", "source_service_name", "project"),
resource.TestCheckResourceAttr("ibm_iam_authorization_policy.policy", "target_resource_type", "resource-group"),
),
},
},
})
}

func TestAccIBMIAMAuthorizationPolicy_TargetResourceTypeAndResourceAttributes(t *testing.T) {
var conf iampolicymanagementv1.PolicyTemplateMetaData

resource.Test(t, resource.TestCase{
PreCheck: func() { acc.TestAccPreCheck(t) },
Providers: acc.TestAccProviders,
CheckDestroy: testAccCheckIBMIAMAuthorizationPolicyDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckIBMIAMAuthorizationPolicyResourceTypeAndResourceAttributes(acc.Tg_cross_network_account_id, acc.Tg_cross_network_account_id),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckIBMIAMAuthorizationPolicyExists("ibm_iam_authorization_policy.policy", conf),
resource.TestCheckResourceAttr("ibm_iam_authorization_policy.policy", "target_service_name", ""),
resource.TestCheckResourceAttr("ibm_iam_authorization_policy.policy", "source_service_name", "project"),
resource.TestCheckResourceAttr("ibm_iam_authorization_policy.policy", "target_resource_type", "resource-group"),
),
},
},
})
}

func TestAccIBMIAMAuthorizationPolicy_With_Transaction_id(t *testing.T) {
var conf iampolicymanagementv1.PolicyTemplateMetaData

Expand Down Expand Up @@ -274,7 +364,7 @@ func testAccCheckIBMIAMAuthorizationPolicyResourceType() string {
resource "ibm_iam_authorization_policy" "policy" {
source_service_name = "is"
source_resource_type = "load-balancer"
target_service_name = "cloudcerts"
target_service_name = "hs-crypto"
roles = ["Reader"]
}
`
Expand Down Expand Up @@ -368,3 +458,79 @@ func testAccCheckIBMIAMAuthorizationPolicyTransactionId() string {
}
`
}

func testAccCheckIBMIAMAuthorizationPolicySourceResourceGroupId() string {
return fmt.Sprintf(`
resource "ibm_iam_authorization_policy" "policy" {
source_resource_group_id = "123-456-abc-def"
target_service_name = "cloud-object-storage"
roles = ["Reader"]
}

`)
}

func testAccCheckIBMIAMAuthorizationPolicySourceResourceGroupIdResourceAttributes(sAccountID, tAccountID string) string {

return fmt.Sprintf(`

resource "ibm_iam_authorization_policy" "policy" {
roles = ["Reader"]
subject_attributes {
name = "accountId"
value = "%s"
}
subject_attributes {
name = "resourceGroupId"
value = "def-abc-456-123"
}

resource_attributes {
name = "serviceName"
value = "cloud-object-storage"
}
resource_attributes {
name = "accountId"
value = "%s"
}
}
`, sAccountID, tAccountID)
}

func testAccCheckIBMIAMAuthorizationPolicyTargetResourceType() string {
return `
resource "ibm_iam_authorization_policy" "policy" {
source_service_name = "project"
target_resource_type = "resource-group"
roles = ["Viewer"]
}
`
}

func testAccCheckIBMIAMAuthorizationPolicyResourceTypeAndResourceAttributes(sAccountID, tAccountID string) string {

return fmt.Sprintf(`

resource "ibm_iam_authorization_policy" "policy" {
roles = ["Viewer"]
subject_attributes {
name = "accountId"
value = "%s"
}
subject_attributes {
name = "serviceName"
value = "project"
}

resource_attributes {
name = "resourceType"
value = "resource-group"
}
resource_attributes {
name = "accountId"
value = "%s"
}

}
`, sAccountID, tAccountID)
}
4 changes: 2 additions & 2 deletions website/docs/d/iam_authorization_policies.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ In addition to all argument reference list, you can access the following attribu

Nested scheme for `resources`:
- `source_service_account` - (Optional, Forces new resource, string) The account GUID of source service.
- `source_service_name` - (Required, Forces new resource, string) The source service name.
- `target_service_name` - (Required, Forces new resource, string) The target service name.
- `source_service_name` - (Optional, Forces new resource, string) The source service name.
- `target_service_name` - (Optional, Forces new resource, string) The target service name.
- `source_resource_instance_id` - (Optional, Forces new resource, string) The source resource instance id.
- `target_resource_instance_id` - (Optional, Forces new resource, string) The target resource instance id.
- `source_resource_type` - (Optional, Forces new resource, string) The resource type of source service.
Expand Down