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: update scc_profile_attachment parameters #5551

Merged
merged 1 commit into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 61 additions & 11 deletions ibm/service/scc/resource_ibm_scc_profile_attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ package scc
import (
"context"
"fmt"
"hash/crc32"
"log"
"strconv"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand Down Expand Up @@ -166,7 +169,7 @@ func ResourceIbmSccProfileAttachment() *schema.Resource {
Optional: true,
Description: "The profile parameters for the attachment.",
Elem: schemaAttachmentParameters(),
Set: hashAttachmentParameters,
Set: attachmentParametersSchemaSetFunc("assessment_id", "parameter_name", "parameter_display_name", "parameter_type", "parameter_value"),
},
"last_scan": {
Type: schema.TypeList,
Expand Down Expand Up @@ -236,13 +239,49 @@ func ResourceIbmSccProfileAttachmentValidator() *validate.ResourceValidator {

// hashAttachmentParameters will determine how to hash the AttachmentParameters schema.Resource
// It uses the 'assessment_id' in order to determine the difference.
func hashAttachmentParameters(v interface{}) int {
if v == nil {
return 0
func attachmentParametersSchemaSetFunc(keys ...string) schema.SchemaSetFunc {
return func(v interface{}) int {
var str strings.Builder

if m, ok := v.(map[string]interface{}); ok {
for _, key := range keys {
if v, ok := m[key]; ok {
switch v := v.(type) {
case bool:
str.WriteRune('-')
str.WriteString(strconv.FormatBool(v))
case int:
str.WriteRune('-')
str.WriteString(strconv.Itoa(v))
case string:
str.WriteRune('-')
str.WriteString(v)
case []interface{}:
str.WriteRune('-')
s := make([]string, len(v))
for i, v := range v {
s[i] = fmt.Sprint(v)
}
str.WriteString(fmt.Sprintf("[%s]", strings.Join(s, ",")))
}
}
}
}

return stringHashcode(str.String())
}
m := v.(map[string]interface{})
id := (m["assessment_id"]).(string)
return schema.HashString(id)
}

func stringHashcode(s string) int {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do have this common function already in
"github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns" please reuse it instead of duplicate

v := int(crc32.ChecksumIEEE([]byte(s)))
if v >= 0 {
return v
}
if -v >= 0 {
return -v
}
// v == MinInt
return 0
}

// schemaAttachmentParameters returns a *schema.Resource for AttachmentParameters
Expand Down Expand Up @@ -437,7 +476,9 @@ func resourceIbmSccProfileAttachmentRead(context context.Context, d *schema.Reso
}
}
if !core.IsNil(attachmentItem.AttachmentParameters) {
attachmentParameters := &schema.Set{F: hashAttachmentParameters}
attachmentParameters := &schema.Set{
F: attachmentParametersSchemaSetFunc("assessment_id", "parameter_name", "parameter_display_name", "parameter_type", "parameter_value"),
}
for _, attachmentParametersItem := range attachmentItem.AttachmentParameters {
attachmentParametersItemMap, err := resourceIbmSccProfileAttachmentAttachmentParameterPrototypeToMap(&attachmentParametersItem)
if err != nil {
Expand Down Expand Up @@ -549,9 +590,15 @@ func resourceIbmSccProfileAttachmentUpdate(context context.Context, d *schema.Re
if replaceProfileAttachmentOptions.Name == nil {
replaceProfileAttachmentOptions.SetName(d.Get("name").(string))
}
if replaceProfileAttachmentOptions.Status == nil {
replaceProfileAttachmentOptions.SetStatus(d.Get("status").(string))
}
if replaceProfileAttachmentOptions.Schedule == nil {
replaceProfileAttachmentOptions.SetSchedule(d.Get("schedule").(string))
}
if replaceProfileAttachmentOptions.Description == nil {
replaceProfileAttachmentOptions.SetDescription(d.Get("description").(string))
}
if replaceProfileAttachmentOptions.Notifications == nil {
notificationsItem := d.Get("notifications.0").(map[string]interface{})
updateNotifications, err := resourceIbmSccProfileAttachmentMapToAttachmentsNotificationsPrototype(notificationsItem)
Expand All @@ -560,6 +607,9 @@ func resourceIbmSccProfileAttachmentUpdate(context context.Context, d *schema.Re
}
replaceProfileAttachmentOptions.SetNotifications(updateNotifications)
}
if replaceProfileAttachmentOptions.Status == nil {
replaceProfileAttachmentOptions.SetSchedule(d.Get("status").(string))
}
if len(replaceProfileAttachmentOptions.Scope) == 0 {
scope := []securityandcompliancecenterapiv3.MultiCloudScope{}
for _, scopeItem := range d.Get("scope").([]interface{}) {
Expand Down Expand Up @@ -912,15 +962,15 @@ func resourceIbmSccProfileAttachmentAttachmentParameterPrototypeToMap(model *sec
if model.ParameterName != nil {
modelMap["parameter_name"] = flex.StringValue(model.ParameterName)
}
if model.ParameterValue != nil {
modelMap["parameter_value"] = flex.StringValue(model.ParameterValue)
}
if model.ParameterDisplayName != nil {
modelMap["parameter_display_name"] = flex.StringValue(model.ParameterDisplayName)
}
if model.ParameterType != nil {
modelMap["parameter_type"] = flex.StringValue(model.ParameterType)
}
if model.ParameterValue != nil {
modelMap["parameter_value"] = flex.StringValue(model.ParameterValue)
}
return modelMap, nil
}

Expand Down
56 changes: 43 additions & 13 deletions ibm/service/scc/resource_ibm_scc_profile_attachment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,40 @@ func TestAccIbmSccProfileAttachmentAllArgs(t *testing.T) {
},
resource.TestStep{
Config: testAccCheckIbmSccProfileAttachmentConfig(acc.SccInstanceID),
Check: resource.ComposeAggregateTestCheckFunc(),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckIbmSccProfileAttachmentExists("ibm_scc_profile_attachment.scc_profile_attachment_instance", conf),
resource.TestCheckResourceAttr(
"ibm_scc_profile_attachment.scc_profile_attachment_instance", "attachment_parameters.#", "5"),
),
},
resource.TestStep{
Config: testAccCheckIbmSccProfileAttachmentConfigChange(acc.SccInstanceID),
Check: resource.ComposeAggregateTestCheckFunc(),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckIbmSccProfileAttachmentExists("ibm_scc_profile_attachment.scc_profile_attachment_instance", conf),
// verify if all attachment_parameters are stored in the state
resource.TestCheckResourceAttr(
"ibm_scc_profile_attachment.scc_profile_attachment_instance", "attachment_parameters.#", "5"),
// verify the changes to rule-7c5f6385-67e4-4edf-bec8-c722558b2dec
resource.TestCheckResourceAttr(
"ibm_scc_profile_attachment.scc_profile_attachment_instance", "attachment_parameters.0.assessment_id", "rule-7c5f6385-67e4-4edf-bec8-c722558b2dec"),
resource.TestCheckResourceAttr(
"ibm_scc_profile_attachment.scc_profile_attachment_instance", "attachment_parameters.0.parameter_value", "23"),
// verify the changes to rule-9653d2c7-6290-4128-a5a3-65487ba40370
resource.TestCheckResourceAttr(
"ibm_scc_profile_attachment.scc_profile_attachment_instance", "attachment_parameters.1.assessment_id", "rule-9653d2c7-6290-4128-a5a3-65487ba40370"),
resource.TestCheckResourceAttr(
"ibm_scc_profile_attachment.scc_profile_attachment_instance", "attachment_parameters.1.parameter_value", "1234"),
// verify the changes to rule-e16fcfea-fe21-4d30-a721-423611481fea
resource.TestCheckResourceAttr(
"ibm_scc_profile_attachment.scc_profile_attachment_instance", "attachment_parameters.2.assessment_id", "rule-e16fcfea-fe21-4d30-a721-423611481fea"),
resource.TestCheckResourceAttr(
"ibm_scc_profile_attachment.scc_profile_attachment_instance", "attachment_parameters.2.parameter_value", "['1.2', '1.3']"),
// verify the changes to rule-f1e80ee7-88d5-4bf2-b42f-c863bb24601c
resource.TestCheckResourceAttr(
"ibm_scc_profile_attachment.scc_profile_attachment_instance", "attachment_parameters.3.assessment_id", "rule-f1e80ee7-88d5-4bf2-b42f-c863bb24601c"),
resource.TestCheckResourceAttr(
"ibm_scc_profile_attachment.scc_profile_attachment_instance", "attachment_parameters.3.parameter_value", "4000"),
),
},
resource.TestStep{
ResourceName: "ibm_scc_profile_attachment.scc_profile_attachment_instance",
Expand Down Expand Up @@ -138,7 +167,7 @@ func testAccCheckIbmSccProfileAttachmentConfigBasic(instanceID string) string {
}
}
schedule = "every_30_days"
status = "enabled"
status = "disabled"
notifications {
enabled = false
controls {
Expand Down Expand Up @@ -168,7 +197,7 @@ func testAccCheckIbmSccProfileAttachmentConfig(instanceID string) string {

resource "ibm_scc_profile_attachment" "scc_profile_attachment_instance" {
instance_id = "%s"
profile_id = local.scc_profiles_map["CIS IBM Cloud Foundations Benchmark"]
profile_id = local.scc_profiles_map["CIS IBM Cloud Foundations Benchmark v1.1.0"]
name = "profile_attachment_name"
description = "scc_profile_attachment_description"
scope {
Expand Down Expand Up @@ -235,6 +264,7 @@ func testAccCheckIbmSccProfileAttachmentConfig(instanceID string) string {
`, instanceID, instanceID)
}

// Returns a terraform change where the attachment_parameters are modified slightly.
func testAccCheckIbmSccProfileAttachmentConfigChange(instanceID string) string {
return fmt.Sprintf(`
locals {
Expand All @@ -253,7 +283,7 @@ func testAccCheckIbmSccProfileAttachmentConfigChange(instanceID string) string {

resource "ibm_scc_profile_attachment" "scc_profile_attachment_instance" {
instance_id = "%s"
profile_id = local.scc_profiles_map["CIS IBM Cloud Foundations Benchmark"]
profile_id = local.scc_profiles_map["CIS IBM Cloud Foundations Benchmark v1.1.0"]
name = "profile_attachment_name"
description = "scc_profile_attachment_description"
scope {
Expand Down Expand Up @@ -285,34 +315,34 @@ func testAccCheckIbmSccProfileAttachmentConfigChange(instanceID string) string {
parameter_type = "string_list"
}
attachment_parameters {
parameter_value = "22"
parameter_value = "8080"
assessment_id = "rule-f9137be8-2490-4afb-8cd5-a201cb167eb2"
assessment_type = "automated"
parameter_display_name = "Network ACL rule for allowed IPs to SSH port"
parameter_name = "ssh_port"
parameter_type = "numeric"
}
attachment_parameters {
parameter_value = "22"
parameter_value = "23"
assessment_id = "rule-7c5f6385-67e4-4edf-bec8-c722558b2dec"
assessment_type = "automated"
parameter_display_name = "Security group rule SSH allow port number"
parameter_name = "ssh_port"
parameter_type = "numeric"
}
attachment_parameters {
parameter_value = "3389"
assessment_id = "rule-9653d2c7-6290-4128-a5a3-65487ba40370"
parameter_value = "4000"
assessment_id = "rule-f1e80ee7-88d5-4bf2-b42f-c863bb24601c"
assessment_type = "automated"
parameter_display_name = "Security group rule RDP allow port number"
parameter_display_name = "Disallowed IPs for ingress to RDP port"
parameter_name = "rdp_port"
parameter_type = "numeric"
}
attachment_parameters {
parameter_value = "3389"
assessment_id = "rule-f1e80ee7-88d5-4bf2-b42f-c863bb24601c"
parameter_value = "1234"
assessment_id = "rule-9653d2c7-6290-4128-a5a3-65487ba40370"
assessment_type = "automated"
parameter_display_name = "Disallowed IPs for ingress to RDP port"
parameter_display_name = "Security group rule RDP allow port number"
parameter_name = "rdp_port"
parameter_type = "numeric"
}
Expand Down
Loading