From 7dcf231d8edb2ae90f05e317709e1971d8abf1a8 Mon Sep 17 00:00:00 2001 From: nitrocode Date: Mon, 23 Aug 2021 11:01:55 -0400 Subject: [PATCH 01/17] mq_broker: rm auto_minor_version_upgrade ForceNew --- internal/service/mq/broker.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/service/mq/broker.go b/internal/service/mq/broker.go index 27c87daab861..f6de5ec8a93a 100644 --- a/internal/service/mq/broker.go +++ b/internal/service/mq/broker.go @@ -56,7 +56,6 @@ func ResourceBroker() *schema.Resource { Type: schema.TypeBool, Optional: true, Default: false, - ForceNew: true, }, "broker_name": { Type: schema.TypeString, From 7cf3894757908d58a6da02358b84779637faa9e7 Mon Sep 17 00:00:00 2001 From: nitrocode Date: Mon, 23 Aug 2021 11:42:54 -0400 Subject: [PATCH 02/17] mq_broker: rm host_instance_type ForceNew --- internal/service/mq/broker.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/service/mq/broker.go b/internal/service/mq/broker.go index f6de5ec8a93a..c298f2d4d68f 100644 --- a/internal/service/mq/broker.go +++ b/internal/service/mq/broker.go @@ -126,7 +126,6 @@ func ResourceBroker() *schema.Resource { "host_instance_type": { Type: schema.TypeString, Required: true, - ForceNew: true, }, "instances": { Type: schema.TypeList, From 2d95034a04e65727d915b292757c63f012911caf Mon Sep 17 00:00:00 2001 From: nitrocode Date: Thu, 26 Aug 2021 20:10:28 -0400 Subject: [PATCH 03/17] Add hasChange for each --- internal/service/mq/broker.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/internal/service/mq/broker.go b/internal/service/mq/broker.go index c298f2d4d68f..15c77060afce 100644 --- a/internal/service/mq/broker.go +++ b/internal/service/mq/broker.go @@ -565,6 +565,26 @@ func resourceBrokerUpdate(d *schema.ResourceData, meta interface{}) error { } } + if d.HasChange("host_instance_type") { + _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ + BrokerId: aws.String(d.Id()), + HostInstanceType: aws.String(d.Get("host_instance_type")), + }) + if err != nil { + return fmt.Errorf("error updating MQ Broker (%s) host instance type: %w", d.Id(), err) + } + } + + if d.HasChange("auto_minor_version_upgrade") { + _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ + BrokerId: aws.String(d.Id()), + AutoMinorVersionUpgrade: aws.String(d.Get("auto_minor_version_upgrade")), + }) + if err != nil { + return fmt.Errorf("error updating MQ Broker (%s) auto minor version upgrade: %w", d.Id(), err) + } + } + return nil } From 3a5f052e8a1aeb376fe33c4c8c9fa647772c20a3 Mon Sep 17 00:00:00 2001 From: nitrocode Date: Thu, 26 Aug 2021 20:11:32 -0400 Subject: [PATCH 04/17] Fix bool --- internal/service/mq/broker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/mq/broker.go b/internal/service/mq/broker.go index 15c77060afce..c5b46d60ce85 100644 --- a/internal/service/mq/broker.go +++ b/internal/service/mq/broker.go @@ -578,7 +578,7 @@ func resourceBrokerUpdate(d *schema.ResourceData, meta interface{}) error { if d.HasChange("auto_minor_version_upgrade") { _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ BrokerId: aws.String(d.Id()), - AutoMinorVersionUpgrade: aws.String(d.Get("auto_minor_version_upgrade")), + AutoMinorVersionUpgrade: aws.Bool(d.Get("auto_minor_version_upgrade").(bool)), }) if err != nil { return fmt.Errorf("error updating MQ Broker (%s) auto minor version upgrade: %w", d.Id(), err) From 0f2fc54439c4902b66dd61925e89f7cee932fc0b Mon Sep 17 00:00:00 2001 From: nitrocode Date: Wed, 20 Oct 2021 10:36:30 -0500 Subject: [PATCH 05/17] Update resource_aws_mq_broker.go --- internal/service/mq/broker.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/internal/service/mq/broker.go b/internal/service/mq/broker.go index c5b46d60ce85..2269f047deda 100644 --- a/internal/service/mq/broker.go +++ b/internal/service/mq/broker.go @@ -1,3 +1,4 @@ +<<<<<<< HEAD:internal/service/mq/broker.go package mq import ( @@ -1087,3 +1088,6 @@ func expandMQLDAPServerMetadata(tfList []interface{}) *mq.LdapServerMetadataInpu return apiObject } +======= + +>>>>>>> ceb21bc040 (Update resource_aws_mq_broker.go):aws/resource_aws_mq_broker.go From 48d54ccbf5afad3eca76639dd8747a88fb4502d3 Mon Sep 17 00:00:00 2001 From: nitrocode Date: Wed, 20 Oct 2021 10:36:56 -0500 Subject: [PATCH 06/17] Update resource_aws_mq_broker.go --- aws/resource_aws_mq_broker.go | 1087 +++++++++++++++++++++++++++++++++ 1 file changed, 1087 insertions(+) create mode 100644 aws/resource_aws_mq_broker.go diff --git a/aws/resource_aws_mq_broker.go b/aws/resource_aws_mq_broker.go new file mode 100644 index 000000000000..bd9d66b16629 --- /dev/null +++ b/aws/resource_aws_mq_broker.go @@ -0,0 +1,1087 @@ +package aws + +import ( + "bytes" + "context" + "errors" + "fmt" + "log" + "reflect" + "strconv" + "strings" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/mq" + "github.com/hashicorp/aws-sdk-go-base/tfawserr" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/mitchellh/copystructure" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/experimental/nullable" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/hashcode" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" + "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/mq/waiter" +) + +func resourceAwsMqBroker() *schema.Resource { + return &schema.Resource{ + Create: resourceAwsMqBrokerCreate, + Read: resourceAwsMqBrokerRead, + Update: resourceAwsMqBrokerUpdate, + Delete: resourceAwsMqBrokerDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "apply_immediately": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "arn": { + Type: schema.TypeString, + Computed: true, + }, + "authentication_strategy": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice(mq.AuthenticationStrategy_Values(), true), + }, + "auto_minor_version_upgrade": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "broker_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "configuration": { + Type: schema.TypeList, + Optional: true, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "revision": { + Type: schema.TypeInt, + Optional: true, + Computed: true, + }, + }, + }, + }, + "deployment_mode": { + Type: schema.TypeString, + Optional: true, + Default: mq.DeploymentModeSingleInstance, + ForceNew: true, + ValidateFunc: validation.StringInSlice(mq.DeploymentMode_Values(), true), + }, + "encryption_options": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + MaxItems: 1, + DiffSuppressFunc: suppressMissingOptionalConfigurationBlock, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "kms_key_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validateArn, + }, + "use_aws_owned_key": { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Default: true, + }, + }, + }, + }, + "engine_type": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice(mq.EngineType_Values(), true), + }, + "engine_version": { + Type: schema.TypeString, + Required: true, + }, + "host_instance_type": { + Type: schema.TypeString, + Required: true, + }, + "instances": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "console_url": { + Type: schema.TypeString, + Computed: true, + }, + "endpoints": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "ldap_server_metadata": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "hosts": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "role_base": { + Type: schema.TypeString, + Optional: true, + }, + "role_name": { + Type: schema.TypeString, + Optional: true, + }, + "role_search_matching": { + Type: schema.TypeString, + Optional: true, + }, + "role_search_subtree": { + Type: schema.TypeBool, + Optional: true, + }, + "service_account_password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + }, + "service_account_username": { + Type: schema.TypeString, + Optional: true, + }, + "user_base": { + Type: schema.TypeString, + Optional: true, + }, + "user_role_name": { + Type: schema.TypeString, + Optional: true, + }, + "user_search_matching": { + Type: schema.TypeString, + Optional: true, + }, + "user_search_subtree": { + Type: schema.TypeBool, + Optional: true, + }, + }, + }, + }, + "logs": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + // Ignore missing configuration block + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == "1" && new == "0" { + return true + } + return false + }, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "general": { + Type: schema.TypeBool, + Optional: true, + }, + "audit": { + Type: nullable.TypeNullableBool, + Optional: true, + ValidateFunc: nullable.ValidateTypeStringNullableBool, + DiffSuppressFunc: nullable.DiffSuppressNullableBoolFalseAsNull, + }, + }, + }, + }, + "maintenance_window_start_time": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Computed: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "day_of_week": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice(mq.DayOfWeek_Values(), true), + }, + "time_of_day": { + Type: schema.TypeString, + Required: true, + }, + "time_zone": { + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + "publicly_accessible": { + Type: schema.TypeBool, + Optional: true, + Default: false, + ForceNew: true, + }, + "security_groups": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + }, + "storage_type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ValidateFunc: validation.StringInSlice(mq.BrokerStorageType_Values(), true), + }, + "subnet_ids": { + Type: schema.TypeSet, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + Computed: true, + ForceNew: true, + }, + "tags": tagsSchema(), + "tags_all": tagsSchemaComputed(), + "user": { + Type: schema.TypeSet, + Required: true, + Set: resourceAwsMqUserHash, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + // AWS currently does not support updating the RabbitMQ users beyond resource creation. + // User list is not returned back after creation. + // Updates to users can only be in the RabbitMQ UI. + if v := d.Get("engine_type").(string); strings.EqualFold(v, mq.EngineTypeRabbitmq) && d.Get("arn").(string) != "" { + return true + } + + return false + }, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "console_access": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "groups": { + Type: schema.TypeSet, + MaxItems: 20, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringLenBetween(2, 100), + }, + Optional: true, + }, + "password": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + ValidateFunc: validateMqBrokerPassword, + }, + "username": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringLenBetween(2, 100), + }, + }, + }, + }, + }, + + CustomizeDiff: customdiff.All( + SetTagsDiff, + func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error { + if strings.EqualFold(diff.Get("engine_type").(string), mq.EngineTypeRabbitmq) { + if v, ok := diff.GetOk("logs.0.audit"); ok { + if v, _, _ := nullable.Bool(v.(string)).Value(); v { + return errors.New("logs.audit: Can not be configured when engine is RabbitMQ") + } + } + } + + return nil + }, + ), + } +} + +func resourceAwsMqBrokerCreate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).mqconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) + + name := d.Get("broker_name").(string) + engineType := d.Get("engine_type").(string) + requestId := resource.PrefixedUniqueId(fmt.Sprintf("tf-%s", name)) + input := mq.CreateBrokerRequest{ + AutoMinorVersionUpgrade: aws.Bool(d.Get("auto_minor_version_upgrade").(bool)), + BrokerName: aws.String(name), + CreatorRequestId: aws.String(requestId), + EngineType: aws.String(engineType), + EngineVersion: aws.String(d.Get("engine_version").(string)), + HostInstanceType: aws.String(d.Get("host_instance_type").(string)), + PubliclyAccessible: aws.Bool(d.Get("publicly_accessible").(bool)), + Users: expandMqUsers(d.Get("user").(*schema.Set).List()), + } + + if v, ok := d.GetOk("authentication_strategy"); ok { + input.AuthenticationStrategy = aws.String(v.(string)) + } + if v, ok := d.GetOk("configuration"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.Configuration = expandMqConfigurationId(v.([]interface{})) + } + if v, ok := d.GetOk("deployment_mode"); ok { + input.DeploymentMode = aws.String(v.(string)) + } + if v, ok := d.GetOk("encryption_options"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.EncryptionOptions = expandMqEncryptionOptions(d.Get("encryption_options").([]interface{})) + } + if v, ok := d.GetOk("logs"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.Logs = expandMqLogs(engineType, v.([]interface{})) + } + if v, ok := d.GetOk("ldap_server_metadata"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.LdapServerMetadata = expandMQLDAPServerMetadata(v.([]interface{})) + } + if v, ok := d.GetOk("maintenance_window_start_time"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { + input.MaintenanceWindowStartTime = expandMqWeeklyStartTime(v.([]interface{})) + } + if v, ok := d.GetOk("security_groups"); ok && v.(*schema.Set).Len() > 0 { + input.SecurityGroups = expandStringSet(v.(*schema.Set)) + } + if v, ok := d.GetOk("storage_type"); ok { + input.StorageType = aws.String(v.(string)) + } + if v, ok := d.GetOk("subnet_ids"); ok { + input.SubnetIds = expandStringSet(v.(*schema.Set)) + } + if len(tags) > 0 { + input.Tags = tags.IgnoreAws().MqTags() + } + + log.Printf("[INFO] Creating MQ Broker: %s", input) + out, err := conn.CreateBroker(&input) + if err != nil { + return err + } + + d.SetId(aws.StringValue(out.BrokerId)) + d.Set("arn", out.BrokerArn) + + if _, err := waiter.BrokerCreated(conn, d.Id()); err != nil { + return fmt.Errorf("error waiting for MQ Broker (%s) creation: %w", d.Id(), err) + } + + return resourceAwsMqBrokerRead(d, meta) +} + +func resourceAwsMqBrokerRead(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).mqconn + defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig + ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig + + output, err := conn.DescribeBroker(&mq.DescribeBrokerInput{ + BrokerId: aws.String(d.Id()), + }) + + if !d.IsNewResource() && (tfawserr.ErrCodeEquals(err, mq.ErrCodeNotFoundException) || tfawserr.ErrCodeEquals(err, mq.ErrCodeForbiddenException)) { + log.Printf("[WARN] MQ broker (%s) not found, removing from state", d.Id()) + d.SetId("") + return nil + } + + if err != nil { + return fmt.Errorf("error reading MQ broker (%s): %w", d.Id(), err) + } + + if output == nil { + return fmt.Errorf("empty response while reading MQ broker (%s)", d.Id()) + } + + d.Set("arn", output.BrokerArn) + d.Set("authentication_strategy", output.AuthenticationStrategy) + d.Set("auto_minor_version_upgrade", output.AutoMinorVersionUpgrade) + d.Set("broker_name", output.BrokerName) + d.Set("deployment_mode", output.DeploymentMode) + d.Set("engine_type", output.EngineType) + d.Set("engine_version", output.EngineVersion) + d.Set("host_instance_type", output.HostInstanceType) + d.Set("instances", flattenMqBrokerInstances(output.BrokerInstances)) + d.Set("publicly_accessible", output.PubliclyAccessible) + d.Set("security_groups", aws.StringValueSlice(output.SecurityGroups)) + d.Set("storage_type", output.StorageType) + d.Set("subnet_ids", aws.StringValueSlice(output.SubnetIds)) + + if err := d.Set("configuration", flattenMqConfiguration(output.Configurations)); err != nil { + return fmt.Errorf("error setting configuration: %w", err) + } + + if err := d.Set("encryption_options", flattenMqEncryptionOptions(output.EncryptionOptions)); err != nil { + return fmt.Errorf("error setting encryption_options: %w", err) + } + + var password string + if v, ok := d.GetOk("ldap_server_metadata.0.service_account_password"); ok { + password = v.(string) + } + + if err := d.Set("ldap_server_metadata", flattenMQLDAPServerMetadata(output.LdapServerMetadata, password)); err != nil { + return fmt.Errorf("error setting ldap_server_metadata: %w", err) + } + + if err := d.Set("logs", flattenMqLogs(output.Logs)); err != nil { + return fmt.Errorf("error setting logs: %w", err) + } + + if err := d.Set("maintenance_window_start_time", flattenMqWeeklyStartTime(output.MaintenanceWindowStartTime)); err != nil { + return fmt.Errorf("error setting maintenance_window_start_time: %w", err) + } + + rawUsers, err := expandMqUsersForBroker(conn, d.Id(), output.Users) + + if err != nil { + return fmt.Errorf("error retrieving user info for MQ broker (%s): %w", d.Id(), err) + } + + if err := d.Set("user", flattenMqUsers(rawUsers, d.Get("user").(*schema.Set).List())); err != nil { + return fmt.Errorf("error setting user: %w", err) + } + + tags := keyvaluetags.MqKeyValueTags(output.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) + + //lintignore:AWSR002 + if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { + return fmt.Errorf("error setting tags: %w", err) + } + + if err := d.Set("tags_all", tags.Map()); err != nil { + return fmt.Errorf("error setting tags_all: %w", err) + } + + return nil +} + +func resourceAwsMqBrokerUpdate(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).mqconn + + requiresReboot := false + + if d.HasChange("security_groups") { + _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ + BrokerId: aws.String(d.Id()), + SecurityGroups: expandStringSet(d.Get("security_groups").(*schema.Set)), + }) + if err != nil { + return fmt.Errorf("error updating MQ Broker (%s) security groups: %w", d.Id(), err) + } + } + + if d.HasChanges("configuration", "logs", "engine_version") { + engineType := d.Get("engine_type").(string) + _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ + BrokerId: aws.String(d.Id()), + Configuration: expandMqConfigurationId(d.Get("configuration").([]interface{})), + Logs: expandMqLogs(engineType, d.Get("logs").([]interface{})), + EngineVersion: aws.String(d.Get("engine_version").(string)), + }) + if err != nil { + return fmt.Errorf("error updating MQ Broker (%s) configuration: %w", d.Id(), err) + } + requiresReboot = true + } + + if d.HasChange("user") { + o, n := d.GetChange("user") + var err error + // d.HasChange("user") always reports a change when running resourceAwsMqBrokerUpdate + // updateAwsMqBrokerUsers needs to be called to know if changes to user are actually made + var usersUpdated bool + usersUpdated, err = updateAwsMqBrokerUsers(conn, d.Id(), + o.(*schema.Set).List(), n.(*schema.Set).List()) + if err != nil { + return fmt.Errorf("error updating MQ Broker (%s) user: %w", d.Id(), err) + } + + if usersUpdated { + requiresReboot = true + } + } + + if d.Get("apply_immediately").(bool) && requiresReboot { + _, err := conn.RebootBroker(&mq.RebootBrokerInput{ + BrokerId: aws.String(d.Id()), + }) + if err != nil { + return fmt.Errorf("error rebooting MQ Broker (%s): %w", d.Id(), err) + } + + if _, err := waiter.BrokerRebooted(conn, d.Id()); err != nil { + return fmt.Errorf("error waiting for MQ Broker (%s) reboot: %w", d.Id(), err) + } + } + + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") + + if err := keyvaluetags.MqUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { + return fmt.Errorf("error updating MQ Broker (%s) tags: %w", d.Get("arn").(string), err) + } + } + + if d.HasChange("host_instance_type") { + _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ + BrokerId: aws.String(d.Id()), + HostInstanceType: aws.String(d.Get("host_instance_type")), + }) + if err != nil { + return fmt.Errorf("error updating MQ Broker (%s) host instance type: %w", d.Id(), err) + } + } + + if d.HasChange("auto_minor_version_upgrade") { + _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ + BrokerId: aws.String(d.Id()), + AutoMinorVersionUpgrade: aws.Bool(d.Get("auto_minor_version_upgrade").(bool)), + }) + if err != nil { + return fmt.Errorf("error updating MQ Broker (%s) auto minor version upgrade: %w", d.Id(), err) + } + } + + return nil +} + +func resourceAwsMqBrokerDelete(d *schema.ResourceData, meta interface{}) error { + conn := meta.(*AWSClient).mqconn + + log.Printf("[INFO] Deleting MQ Broker: %s", d.Id()) + _, err := conn.DeleteBroker(&mq.DeleteBrokerInput{ + BrokerId: aws.String(d.Id()), + }) + if err != nil { + return err + } + + if _, err := waiter.BrokerDeleted(conn, d.Id()); err != nil { + return fmt.Errorf("error waiting for MQ Broker (%s) deletion: %w", d.Id(), err) + } + + return nil +} + +func resourceAwsMqUserHash(v interface{}) int { + var buf bytes.Buffer + + m := v.(map[string]interface{}) + if ca, ok := m["console_access"]; ok { + buf.WriteString(fmt.Sprintf("%t-", ca.(bool))) + } else { + buf.WriteString("false-") + } + if g, ok := m["groups"]; ok { + buf.WriteString(fmt.Sprintf("%v-", g.(*schema.Set).List())) + } + if p, ok := m["password"]; ok { + buf.WriteString(fmt.Sprintf("%s-", p.(string))) + } + buf.WriteString(fmt.Sprintf("%s-", m["username"].(string))) + + return hashcode.String(buf.String()) +} + +func updateAwsMqBrokerUsers(conn *mq.MQ, bId string, oldUsers, newUsers []interface{}) (bool, error) { + // If there are any user creates/deletes/updates, updatedUsers will be set to true + updatedUsers := false + + createL, deleteL, updateL, err := diffAwsMqBrokerUsers(bId, oldUsers, newUsers) + if err != nil { + return updatedUsers, err + } + + for _, c := range createL { + _, err := conn.CreateUser(c) + updatedUsers = true + if err != nil { + return updatedUsers, err + } + } + for _, d := range deleteL { + _, err := conn.DeleteUser(d) + updatedUsers = true + if err != nil { + return updatedUsers, err + } + } + for _, u := range updateL { + _, err := conn.UpdateUser(u) + updatedUsers = true + if err != nil { + return updatedUsers, err + } + } + + return updatedUsers, nil +} + +func diffAwsMqBrokerUsers(bId string, oldUsers, newUsers []interface{}) ( + cr []*mq.CreateUserRequest, di []*mq.DeleteUserInput, ur []*mq.UpdateUserRequest, e error) { + + existingUsers := make(map[string]interface{}) + for _, ou := range oldUsers { + u := ou.(map[string]interface{}) + username := u["username"].(string) + // Convert Set to slice to allow easier comparison + if g, ok := u["groups"]; ok { + groups := g.(*schema.Set).List() + u["groups"] = groups + } + + existingUsers[username] = u + } + + for _, nu := range newUsers { + // Still need access to the original map + // because Set contents doesn't get copied + // Likely related to https://github.com/mitchellh/copystructure/issues/17 + nuOriginal := nu.(map[string]interface{}) + + // Create a mutable copy + newUser, err := copystructure.Copy(nu) + if err != nil { + return cr, di, ur, err + } + + newUserMap := newUser.(map[string]interface{}) + username := newUserMap["username"].(string) + + // Convert Set to slice to allow easier comparison + var ng []interface{} + if g, ok := nuOriginal["groups"]; ok { + ng = g.(*schema.Set).List() + newUserMap["groups"] = ng + } + + if eu, ok := existingUsers[username]; ok { + + existingUserMap := eu.(map[string]interface{}) + + if !reflect.DeepEqual(existingUserMap, newUserMap) { + ur = append(ur, &mq.UpdateUserRequest{ + BrokerId: aws.String(bId), + ConsoleAccess: aws.Bool(newUserMap["console_access"].(bool)), + Groups: expandStringList(ng), + Password: aws.String(newUserMap["password"].(string)), + Username: aws.String(username), + }) + } + + // Delete after processing, so we know what's left for deletion + delete(existingUsers, username) + } else { + cur := &mq.CreateUserRequest{ + BrokerId: aws.String(bId), + ConsoleAccess: aws.Bool(newUserMap["console_access"].(bool)), + Password: aws.String(newUserMap["password"].(string)), + Username: aws.String(username), + } + if len(ng) > 0 { + cur.Groups = expandStringList(ng) + } + cr = append(cr, cur) + } + } + + for username := range existingUsers { + di = append(di, &mq.DeleteUserInput{ + BrokerId: aws.String(bId), + Username: aws.String(username), + }) + } + + return cr, di, ur, nil +} + +func expandMqEncryptionOptions(l []interface{}) *mq.EncryptionOptions { + if len(l) == 0 || l[0] == nil { + return nil + } + + m := l[0].(map[string]interface{}) + + encryptionOptions := &mq.EncryptionOptions{ + UseAwsOwnedKey: aws.Bool(m["use_aws_owned_key"].(bool)), + } + + if v, ok := m["kms_key_id"].(string); ok && v != "" { + encryptionOptions.KmsKeyId = aws.String(v) + } + + return encryptionOptions +} + +func flattenMqEncryptionOptions(encryptionOptions *mq.EncryptionOptions) []interface{} { + if encryptionOptions == nil { + return []interface{}{} + } + + m := map[string]interface{}{ + "kms_key_id": aws.StringValue(encryptionOptions.KmsKeyId), + "use_aws_owned_key": aws.BoolValue(encryptionOptions.UseAwsOwnedKey), + } + + return []interface{}{m} +} + +func validateMqBrokerPassword(v interface{}, k string) (ws []string, errors []error) { + min := 12 + max := 250 + value := v.(string) + unique := make(map[string]bool) + + for _, v := range value { + if _, ok := unique[string(v)]; ok { + continue + } + if string(v) == "," { + errors = append(errors, fmt.Errorf("%q must not contain commas", k)) + } + unique[string(v)] = true + } + if len(unique) < 4 { + errors = append(errors, fmt.Errorf("%q must contain at least 4 unique characters", k)) + } + if len(value) < min || len(value) > max { + errors = append(errors, fmt.Errorf( + "%q must be %d to %d characters long. provided string length: %d", k, min, max, len(value))) + } + return +} + +func expandMqUsers(cfg []interface{}) []*mq.User { + users := make([]*mq.User, len(cfg)) + for i, m := range cfg { + u := m.(map[string]interface{}) + user := mq.User{ + Username: aws.String(u["username"].(string)), + Password: aws.String(u["password"].(string)), + } + if v, ok := u["console_access"]; ok { + user.ConsoleAccess = aws.Bool(v.(bool)) + } + if v, ok := u["groups"]; ok { + user.Groups = expandStringSet(v.(*schema.Set)) + } + users[i] = &user + } + return users +} + +func expandMqUsersForBroker(conn *mq.MQ, brokerId string, input []*mq.UserSummary) ([]*mq.User, error) { + var rawUsers []*mq.User + + for _, u := range input { + if u == nil { + continue + } + + uOut, err := conn.DescribeUser(&mq.DescribeUserInput{ + BrokerId: aws.String(brokerId), + Username: u.Username, + }) + + if err != nil { + return nil, err + } + + user := &mq.User{ + ConsoleAccess: uOut.ConsoleAccess, + Groups: uOut.Groups, + Username: uOut.Username, + } + + rawUsers = append(rawUsers, user) + } + + return rawUsers, nil +} + +// We use cfgdUsers to get & set the password +func flattenMqUsers(users []*mq.User, cfgUsers []interface{}) *schema.Set { + existingPairs := make(map[string]string) + for _, u := range cfgUsers { + user := u.(map[string]interface{}) + username := user["username"].(string) + existingPairs[username] = user["password"].(string) + } + + out := make([]interface{}, 0) + for _, u := range users { + m := map[string]interface{}{ + "username": aws.StringValue(u.Username), + } + password := "" + if p, ok := existingPairs[aws.StringValue(u.Username)]; ok { + password = p + } + if password != "" { + m["password"] = password + } + if u.ConsoleAccess != nil { + m["console_access"] = aws.BoolValue(u.ConsoleAccess) + } + if len(u.Groups) > 0 { + m["groups"] = flattenStringSet(u.Groups) + } + out = append(out, m) + } + return schema.NewSet(resourceAwsMqUserHash, out) +} + +func expandMqWeeklyStartTime(cfg []interface{}) *mq.WeeklyStartTime { + if len(cfg) < 1 { + return nil + } + + m := cfg[0].(map[string]interface{}) + return &mq.WeeklyStartTime{ + DayOfWeek: aws.String(m["day_of_week"].(string)), + TimeOfDay: aws.String(m["time_of_day"].(string)), + TimeZone: aws.String(m["time_zone"].(string)), + } +} + +func flattenMqWeeklyStartTime(wst *mq.WeeklyStartTime) []interface{} { + if wst == nil { + return []interface{}{} + } + m := make(map[string]interface{}) + if wst.DayOfWeek != nil { + m["day_of_week"] = *wst.DayOfWeek + } + if wst.TimeOfDay != nil { + m["time_of_day"] = *wst.TimeOfDay + } + if wst.TimeZone != nil { + m["time_zone"] = *wst.TimeZone + } + return []interface{}{m} +} + +func expandMqConfigurationId(cfg []interface{}) *mq.ConfigurationId { + if len(cfg) < 1 { + return nil + } + + m := cfg[0].(map[string]interface{}) + out := mq.ConfigurationId{ + Id: aws.String(m["id"].(string)), + } + if v, ok := m["revision"].(int); ok && v > 0 { + out.Revision = aws.Int64(int64(v)) + } + + return &out +} + +func flattenMqConfiguration(config *mq.Configurations) []interface{} { + if config == nil || config.Current == nil { + return []interface{}{} + } + + m := map[string]interface{}{ + "id": aws.StringValue(config.Current.Id), + "revision": aws.Int64Value(config.Current.Revision), + } + + return []interface{}{m} +} + +func flattenMqBrokerInstances(instances []*mq.BrokerInstance) []interface{} { + if len(instances) == 0 { + return []interface{}{} + } + l := make([]interface{}, len(instances)) + for i, instance := range instances { + m := make(map[string]interface{}) + if instance.ConsoleURL != nil { + m["console_url"] = aws.StringValue(instance.ConsoleURL) + } + if len(instance.Endpoints) > 0 { + m["endpoints"] = aws.StringValueSlice(instance.Endpoints) + } + if instance.IpAddress != nil { + m["ip_address"] = aws.StringValue(instance.IpAddress) + } + l[i] = m + } + + return l +} + +func flattenMqLogs(logs *mq.LogsSummary) []interface{} { + if logs == nil { + return []interface{}{} + } + + m := map[string]interface{}{} + + if logs.General != nil { + m["general"] = aws.BoolValue(logs.General) + } + + if logs.Audit != nil { + m["audit"] = strconv.FormatBool(aws.BoolValue(logs.Audit)) + } + + return []interface{}{m} +} + +func expandMqLogs(engineType string, l []interface{}) *mq.Logs { + if len(l) == 0 || l[0] == nil { + return nil + } + + m := l[0].(map[string]interface{}) + + logs := &mq.Logs{} + + if v, ok := m["general"]; ok { + logs.General = aws.Bool(v.(bool)) + } + + // When the engine type is "RabbitMQ", the parameter audit cannot be set at all. + if v, ok := m["audit"]; ok { + if v, null, _ := nullable.Bool(v.(string)).Value(); !null { + if !strings.EqualFold(engineType, mq.EngineTypeRabbitmq) { + logs.Audit = aws.Bool(v) + } + } + } + + return logs +} + +func flattenMQLDAPServerMetadata(apiObject *mq.LdapServerMetadataOutput, password string) []interface{} { + if apiObject == nil { + return nil + } + + tfMap := map[string]interface{}{} + + if v := apiObject.Hosts; v != nil { + tfMap["hosts"] = aws.StringValueSlice(v) + } + if v := apiObject.RoleBase; v != nil { + tfMap["role_base"] = aws.StringValue(v) + } + if v := apiObject.RoleName; v != nil { + tfMap["role_name"] = aws.StringValue(v) + } + if v := apiObject.RoleSearchMatching; v != nil { + tfMap["role_search_matching"] = aws.StringValue(v) + } + if v := apiObject.RoleSearchSubtree; v != nil { + tfMap["role_search_subtree"] = aws.BoolValue(v) + } + if password != "" { + tfMap["service_account_password"] = password + } + if v := apiObject.ServiceAccountUsername; v != nil { + tfMap["service_account_username"] = aws.StringValue(v) + } + if v := apiObject.UserBase; v != nil { + tfMap["user_base"] = aws.StringValue(v) + } + if v := apiObject.UserRoleName; v != nil { + tfMap["user_role_name"] = aws.StringValue(v) + } + if v := apiObject.UserSearchMatching; v != nil { + tfMap["user_search_matching"] = aws.StringValue(v) + } + if v := apiObject.UserSearchSubtree; v != nil { + tfMap["user_search_subtree"] = aws.BoolValue(v) + } + + return []interface{}{tfMap} +} + +func expandMQLDAPServerMetadata(tfList []interface{}) *mq.LdapServerMetadataInput { + if len(tfList) == 0 || tfList[0] == nil { + return nil + } + + apiObject := &mq.LdapServerMetadataInput{} + + tfMap := tfList[0].(map[string]interface{}) + + if v, ok := tfMap["hosts"]; ok && len(v.([]interface{})) > 0 { + apiObject.Hosts = expandStringList(v.([]interface{})) + } + if v, ok := tfMap["role_base"].(string); ok && v != "" { + apiObject.RoleBase = aws.String(v) + } + if v, ok := tfMap["role_name"].(string); ok && v != "" { + apiObject.RoleName = aws.String(v) + } + if v, ok := tfMap["role_search_matching"].(string); ok && v != "" { + apiObject.RoleSearchMatching = aws.String(v) + } + if v, ok := tfMap["role_search_subtree"].(bool); ok { + apiObject.RoleSearchSubtree = aws.Bool(v) + } + if v, ok := tfMap["service_account_password"].(string); ok && v != "" { + apiObject.ServiceAccountPassword = aws.String(v) + } + if v, ok := tfMap["service_account_username"].(string); ok && v != "" { + apiObject.ServiceAccountUsername = aws.String(v) + } + if v, ok := tfMap["user_base"].(string); ok && v != "" { + apiObject.UserBase = aws.String(v) + } + if v, ok := tfMap["user_role_name"].(string); ok && v != "" { + apiObject.UserRoleName = aws.String(v) + } + if v, ok := tfMap["user_search_matching"].(string); ok && v != "" { + apiObject.UserSearchMatching = aws.String(v) + } + if v, ok := tfMap["user_search_subtree"].(bool); ok { + apiObject.UserSearchSubtree = aws.Bool(v) + } + + return apiObject +} From 936c4f69c3cb180bc302a35b3741436ebdd3e5c6 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Feb 2022 16:25:53 -0500 Subject: [PATCH 07/17] Rebase, fix merge --- aws/resource_aws_mq_broker.go | 1087 --------------------------------- 1 file changed, 1087 deletions(-) delete mode 100644 aws/resource_aws_mq_broker.go diff --git a/aws/resource_aws_mq_broker.go b/aws/resource_aws_mq_broker.go deleted file mode 100644 index bd9d66b16629..000000000000 --- a/aws/resource_aws_mq_broker.go +++ /dev/null @@ -1,1087 +0,0 @@ -package aws - -import ( - "bytes" - "context" - "errors" - "fmt" - "log" - "reflect" - "strconv" - "strings" - - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/mq" - "github.com/hashicorp/aws-sdk-go-base/tfawserr" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - "github.com/mitchellh/copystructure" - "github.com/terraform-providers/terraform-provider-aws/aws/internal/experimental/nullable" - "github.com/terraform-providers/terraform-provider-aws/aws/internal/hashcode" - "github.com/terraform-providers/terraform-provider-aws/aws/internal/keyvaluetags" - "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/mq/waiter" -) - -func resourceAwsMqBroker() *schema.Resource { - return &schema.Resource{ - Create: resourceAwsMqBrokerCreate, - Read: resourceAwsMqBrokerRead, - Update: resourceAwsMqBrokerUpdate, - Delete: resourceAwsMqBrokerDelete, - Importer: &schema.ResourceImporter{ - State: schema.ImportStatePassthrough, - }, - - Schema: map[string]*schema.Schema{ - "apply_immediately": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "arn": { - Type: schema.TypeString, - Computed: true, - }, - "authentication_strategy": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: validation.StringInSlice(mq.AuthenticationStrategy_Values(), true), - }, - "auto_minor_version_upgrade": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "broker_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "configuration": { - Type: schema.TypeList, - Optional: true, - Computed: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "revision": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - }, - }, - }, - "deployment_mode": { - Type: schema.TypeString, - Optional: true, - Default: mq.DeploymentModeSingleInstance, - ForceNew: true, - ValidateFunc: validation.StringInSlice(mq.DeploymentMode_Values(), true), - }, - "encryption_options": { - Type: schema.TypeList, - Optional: true, - ForceNew: true, - MaxItems: 1, - DiffSuppressFunc: suppressMissingOptionalConfigurationBlock, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "kms_key_id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ValidateFunc: validateArn, - }, - "use_aws_owned_key": { - Type: schema.TypeBool, - Optional: true, - ForceNew: true, - Default: true, - }, - }, - }, - }, - "engine_type": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringInSlice(mq.EngineType_Values(), true), - }, - "engine_version": { - Type: schema.TypeString, - Required: true, - }, - "host_instance_type": { - Type: schema.TypeString, - Required: true, - }, - "instances": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "console_url": { - Type: schema.TypeString, - Computed: true, - }, - "endpoints": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "ip_address": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "ldap_server_metadata": { - Type: schema.TypeList, - Optional: true, - ForceNew: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "hosts": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "role_base": { - Type: schema.TypeString, - Optional: true, - }, - "role_name": { - Type: schema.TypeString, - Optional: true, - }, - "role_search_matching": { - Type: schema.TypeString, - Optional: true, - }, - "role_search_subtree": { - Type: schema.TypeBool, - Optional: true, - }, - "service_account_password": { - Type: schema.TypeString, - Optional: true, - Sensitive: true, - }, - "service_account_username": { - Type: schema.TypeString, - Optional: true, - }, - "user_base": { - Type: schema.TypeString, - Optional: true, - }, - "user_role_name": { - Type: schema.TypeString, - Optional: true, - }, - "user_search_matching": { - Type: schema.TypeString, - Optional: true, - }, - "user_search_subtree": { - Type: schema.TypeBool, - Optional: true, - }, - }, - }, - }, - "logs": { - Type: schema.TypeList, - Optional: true, - MaxItems: 1, - // Ignore missing configuration block - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - if old == "1" && new == "0" { - return true - } - return false - }, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "general": { - Type: schema.TypeBool, - Optional: true, - }, - "audit": { - Type: nullable.TypeNullableBool, - Optional: true, - ValidateFunc: nullable.ValidateTypeStringNullableBool, - DiffSuppressFunc: nullable.DiffSuppressNullableBoolFalseAsNull, - }, - }, - }, - }, - "maintenance_window_start_time": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Computed: true, - ForceNew: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "day_of_week": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice(mq.DayOfWeek_Values(), true), - }, - "time_of_day": { - Type: schema.TypeString, - Required: true, - }, - "time_zone": { - Type: schema.TypeString, - Required: true, - }, - }, - }, - }, - "publicly_accessible": { - Type: schema.TypeBool, - Optional: true, - Default: false, - ForceNew: true, - }, - "security_groups": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Optional: true, - }, - "storage_type": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ValidateFunc: validation.StringInSlice(mq.BrokerStorageType_Values(), true), - }, - "subnet_ids": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Optional: true, - Computed: true, - ForceNew: true, - }, - "tags": tagsSchema(), - "tags_all": tagsSchemaComputed(), - "user": { - Type: schema.TypeSet, - Required: true, - Set: resourceAwsMqUserHash, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - // AWS currently does not support updating the RabbitMQ users beyond resource creation. - // User list is not returned back after creation. - // Updates to users can only be in the RabbitMQ UI. - if v := d.Get("engine_type").(string); strings.EqualFold(v, mq.EngineTypeRabbitmq) && d.Get("arn").(string) != "" { - return true - } - - return false - }, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "console_access": { - Type: schema.TypeBool, - Optional: true, - Default: false, - }, - "groups": { - Type: schema.TypeSet, - MaxItems: 20, - Elem: &schema.Schema{ - Type: schema.TypeString, - ValidateFunc: validation.StringLenBetween(2, 100), - }, - Optional: true, - }, - "password": { - Type: schema.TypeString, - Required: true, - Sensitive: true, - ValidateFunc: validateMqBrokerPassword, - }, - "username": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringLenBetween(2, 100), - }, - }, - }, - }, - }, - - CustomizeDiff: customdiff.All( - SetTagsDiff, - func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error { - if strings.EqualFold(diff.Get("engine_type").(string), mq.EngineTypeRabbitmq) { - if v, ok := diff.GetOk("logs.0.audit"); ok { - if v, _, _ := nullable.Bool(v.(string)).Value(); v { - return errors.New("logs.audit: Can not be configured when engine is RabbitMQ") - } - } - } - - return nil - }, - ), - } -} - -func resourceAwsMqBrokerCreate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).mqconn - defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig - tags := defaultTagsConfig.MergeTags(keyvaluetags.New(d.Get("tags").(map[string]interface{}))) - - name := d.Get("broker_name").(string) - engineType := d.Get("engine_type").(string) - requestId := resource.PrefixedUniqueId(fmt.Sprintf("tf-%s", name)) - input := mq.CreateBrokerRequest{ - AutoMinorVersionUpgrade: aws.Bool(d.Get("auto_minor_version_upgrade").(bool)), - BrokerName: aws.String(name), - CreatorRequestId: aws.String(requestId), - EngineType: aws.String(engineType), - EngineVersion: aws.String(d.Get("engine_version").(string)), - HostInstanceType: aws.String(d.Get("host_instance_type").(string)), - PubliclyAccessible: aws.Bool(d.Get("publicly_accessible").(bool)), - Users: expandMqUsers(d.Get("user").(*schema.Set).List()), - } - - if v, ok := d.GetOk("authentication_strategy"); ok { - input.AuthenticationStrategy = aws.String(v.(string)) - } - if v, ok := d.GetOk("configuration"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - input.Configuration = expandMqConfigurationId(v.([]interface{})) - } - if v, ok := d.GetOk("deployment_mode"); ok { - input.DeploymentMode = aws.String(v.(string)) - } - if v, ok := d.GetOk("encryption_options"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - input.EncryptionOptions = expandMqEncryptionOptions(d.Get("encryption_options").([]interface{})) - } - if v, ok := d.GetOk("logs"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - input.Logs = expandMqLogs(engineType, v.([]interface{})) - } - if v, ok := d.GetOk("ldap_server_metadata"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - input.LdapServerMetadata = expandMQLDAPServerMetadata(v.([]interface{})) - } - if v, ok := d.GetOk("maintenance_window_start_time"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - input.MaintenanceWindowStartTime = expandMqWeeklyStartTime(v.([]interface{})) - } - if v, ok := d.GetOk("security_groups"); ok && v.(*schema.Set).Len() > 0 { - input.SecurityGroups = expandStringSet(v.(*schema.Set)) - } - if v, ok := d.GetOk("storage_type"); ok { - input.StorageType = aws.String(v.(string)) - } - if v, ok := d.GetOk("subnet_ids"); ok { - input.SubnetIds = expandStringSet(v.(*schema.Set)) - } - if len(tags) > 0 { - input.Tags = tags.IgnoreAws().MqTags() - } - - log.Printf("[INFO] Creating MQ Broker: %s", input) - out, err := conn.CreateBroker(&input) - if err != nil { - return err - } - - d.SetId(aws.StringValue(out.BrokerId)) - d.Set("arn", out.BrokerArn) - - if _, err := waiter.BrokerCreated(conn, d.Id()); err != nil { - return fmt.Errorf("error waiting for MQ Broker (%s) creation: %w", d.Id(), err) - } - - return resourceAwsMqBrokerRead(d, meta) -} - -func resourceAwsMqBrokerRead(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).mqconn - defaultTagsConfig := meta.(*AWSClient).DefaultTagsConfig - ignoreTagsConfig := meta.(*AWSClient).IgnoreTagsConfig - - output, err := conn.DescribeBroker(&mq.DescribeBrokerInput{ - BrokerId: aws.String(d.Id()), - }) - - if !d.IsNewResource() && (tfawserr.ErrCodeEquals(err, mq.ErrCodeNotFoundException) || tfawserr.ErrCodeEquals(err, mq.ErrCodeForbiddenException)) { - log.Printf("[WARN] MQ broker (%s) not found, removing from state", d.Id()) - d.SetId("") - return nil - } - - if err != nil { - return fmt.Errorf("error reading MQ broker (%s): %w", d.Id(), err) - } - - if output == nil { - return fmt.Errorf("empty response while reading MQ broker (%s)", d.Id()) - } - - d.Set("arn", output.BrokerArn) - d.Set("authentication_strategy", output.AuthenticationStrategy) - d.Set("auto_minor_version_upgrade", output.AutoMinorVersionUpgrade) - d.Set("broker_name", output.BrokerName) - d.Set("deployment_mode", output.DeploymentMode) - d.Set("engine_type", output.EngineType) - d.Set("engine_version", output.EngineVersion) - d.Set("host_instance_type", output.HostInstanceType) - d.Set("instances", flattenMqBrokerInstances(output.BrokerInstances)) - d.Set("publicly_accessible", output.PubliclyAccessible) - d.Set("security_groups", aws.StringValueSlice(output.SecurityGroups)) - d.Set("storage_type", output.StorageType) - d.Set("subnet_ids", aws.StringValueSlice(output.SubnetIds)) - - if err := d.Set("configuration", flattenMqConfiguration(output.Configurations)); err != nil { - return fmt.Errorf("error setting configuration: %w", err) - } - - if err := d.Set("encryption_options", flattenMqEncryptionOptions(output.EncryptionOptions)); err != nil { - return fmt.Errorf("error setting encryption_options: %w", err) - } - - var password string - if v, ok := d.GetOk("ldap_server_metadata.0.service_account_password"); ok { - password = v.(string) - } - - if err := d.Set("ldap_server_metadata", flattenMQLDAPServerMetadata(output.LdapServerMetadata, password)); err != nil { - return fmt.Errorf("error setting ldap_server_metadata: %w", err) - } - - if err := d.Set("logs", flattenMqLogs(output.Logs)); err != nil { - return fmt.Errorf("error setting logs: %w", err) - } - - if err := d.Set("maintenance_window_start_time", flattenMqWeeklyStartTime(output.MaintenanceWindowStartTime)); err != nil { - return fmt.Errorf("error setting maintenance_window_start_time: %w", err) - } - - rawUsers, err := expandMqUsersForBroker(conn, d.Id(), output.Users) - - if err != nil { - return fmt.Errorf("error retrieving user info for MQ broker (%s): %w", d.Id(), err) - } - - if err := d.Set("user", flattenMqUsers(rawUsers, d.Get("user").(*schema.Set).List())); err != nil { - return fmt.Errorf("error setting user: %w", err) - } - - tags := keyvaluetags.MqKeyValueTags(output.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig) - - //lintignore:AWSR002 - if err := d.Set("tags", tags.RemoveDefaultConfig(defaultTagsConfig).Map()); err != nil { - return fmt.Errorf("error setting tags: %w", err) - } - - if err := d.Set("tags_all", tags.Map()); err != nil { - return fmt.Errorf("error setting tags_all: %w", err) - } - - return nil -} - -func resourceAwsMqBrokerUpdate(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).mqconn - - requiresReboot := false - - if d.HasChange("security_groups") { - _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ - BrokerId: aws.String(d.Id()), - SecurityGroups: expandStringSet(d.Get("security_groups").(*schema.Set)), - }) - if err != nil { - return fmt.Errorf("error updating MQ Broker (%s) security groups: %w", d.Id(), err) - } - } - - if d.HasChanges("configuration", "logs", "engine_version") { - engineType := d.Get("engine_type").(string) - _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ - BrokerId: aws.String(d.Id()), - Configuration: expandMqConfigurationId(d.Get("configuration").([]interface{})), - Logs: expandMqLogs(engineType, d.Get("logs").([]interface{})), - EngineVersion: aws.String(d.Get("engine_version").(string)), - }) - if err != nil { - return fmt.Errorf("error updating MQ Broker (%s) configuration: %w", d.Id(), err) - } - requiresReboot = true - } - - if d.HasChange("user") { - o, n := d.GetChange("user") - var err error - // d.HasChange("user") always reports a change when running resourceAwsMqBrokerUpdate - // updateAwsMqBrokerUsers needs to be called to know if changes to user are actually made - var usersUpdated bool - usersUpdated, err = updateAwsMqBrokerUsers(conn, d.Id(), - o.(*schema.Set).List(), n.(*schema.Set).List()) - if err != nil { - return fmt.Errorf("error updating MQ Broker (%s) user: %w", d.Id(), err) - } - - if usersUpdated { - requiresReboot = true - } - } - - if d.Get("apply_immediately").(bool) && requiresReboot { - _, err := conn.RebootBroker(&mq.RebootBrokerInput{ - BrokerId: aws.String(d.Id()), - }) - if err != nil { - return fmt.Errorf("error rebooting MQ Broker (%s): %w", d.Id(), err) - } - - if _, err := waiter.BrokerRebooted(conn, d.Id()); err != nil { - return fmt.Errorf("error waiting for MQ Broker (%s) reboot: %w", d.Id(), err) - } - } - - if d.HasChange("tags_all") { - o, n := d.GetChange("tags_all") - - if err := keyvaluetags.MqUpdateTags(conn, d.Get("arn").(string), o, n); err != nil { - return fmt.Errorf("error updating MQ Broker (%s) tags: %w", d.Get("arn").(string), err) - } - } - - if d.HasChange("host_instance_type") { - _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ - BrokerId: aws.String(d.Id()), - HostInstanceType: aws.String(d.Get("host_instance_type")), - }) - if err != nil { - return fmt.Errorf("error updating MQ Broker (%s) host instance type: %w", d.Id(), err) - } - } - - if d.HasChange("auto_minor_version_upgrade") { - _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ - BrokerId: aws.String(d.Id()), - AutoMinorVersionUpgrade: aws.Bool(d.Get("auto_minor_version_upgrade").(bool)), - }) - if err != nil { - return fmt.Errorf("error updating MQ Broker (%s) auto minor version upgrade: %w", d.Id(), err) - } - } - - return nil -} - -func resourceAwsMqBrokerDelete(d *schema.ResourceData, meta interface{}) error { - conn := meta.(*AWSClient).mqconn - - log.Printf("[INFO] Deleting MQ Broker: %s", d.Id()) - _, err := conn.DeleteBroker(&mq.DeleteBrokerInput{ - BrokerId: aws.String(d.Id()), - }) - if err != nil { - return err - } - - if _, err := waiter.BrokerDeleted(conn, d.Id()); err != nil { - return fmt.Errorf("error waiting for MQ Broker (%s) deletion: %w", d.Id(), err) - } - - return nil -} - -func resourceAwsMqUserHash(v interface{}) int { - var buf bytes.Buffer - - m := v.(map[string]interface{}) - if ca, ok := m["console_access"]; ok { - buf.WriteString(fmt.Sprintf("%t-", ca.(bool))) - } else { - buf.WriteString("false-") - } - if g, ok := m["groups"]; ok { - buf.WriteString(fmt.Sprintf("%v-", g.(*schema.Set).List())) - } - if p, ok := m["password"]; ok { - buf.WriteString(fmt.Sprintf("%s-", p.(string))) - } - buf.WriteString(fmt.Sprintf("%s-", m["username"].(string))) - - return hashcode.String(buf.String()) -} - -func updateAwsMqBrokerUsers(conn *mq.MQ, bId string, oldUsers, newUsers []interface{}) (bool, error) { - // If there are any user creates/deletes/updates, updatedUsers will be set to true - updatedUsers := false - - createL, deleteL, updateL, err := diffAwsMqBrokerUsers(bId, oldUsers, newUsers) - if err != nil { - return updatedUsers, err - } - - for _, c := range createL { - _, err := conn.CreateUser(c) - updatedUsers = true - if err != nil { - return updatedUsers, err - } - } - for _, d := range deleteL { - _, err := conn.DeleteUser(d) - updatedUsers = true - if err != nil { - return updatedUsers, err - } - } - for _, u := range updateL { - _, err := conn.UpdateUser(u) - updatedUsers = true - if err != nil { - return updatedUsers, err - } - } - - return updatedUsers, nil -} - -func diffAwsMqBrokerUsers(bId string, oldUsers, newUsers []interface{}) ( - cr []*mq.CreateUserRequest, di []*mq.DeleteUserInput, ur []*mq.UpdateUserRequest, e error) { - - existingUsers := make(map[string]interface{}) - for _, ou := range oldUsers { - u := ou.(map[string]interface{}) - username := u["username"].(string) - // Convert Set to slice to allow easier comparison - if g, ok := u["groups"]; ok { - groups := g.(*schema.Set).List() - u["groups"] = groups - } - - existingUsers[username] = u - } - - for _, nu := range newUsers { - // Still need access to the original map - // because Set contents doesn't get copied - // Likely related to https://github.com/mitchellh/copystructure/issues/17 - nuOriginal := nu.(map[string]interface{}) - - // Create a mutable copy - newUser, err := copystructure.Copy(nu) - if err != nil { - return cr, di, ur, err - } - - newUserMap := newUser.(map[string]interface{}) - username := newUserMap["username"].(string) - - // Convert Set to slice to allow easier comparison - var ng []interface{} - if g, ok := nuOriginal["groups"]; ok { - ng = g.(*schema.Set).List() - newUserMap["groups"] = ng - } - - if eu, ok := existingUsers[username]; ok { - - existingUserMap := eu.(map[string]interface{}) - - if !reflect.DeepEqual(existingUserMap, newUserMap) { - ur = append(ur, &mq.UpdateUserRequest{ - BrokerId: aws.String(bId), - ConsoleAccess: aws.Bool(newUserMap["console_access"].(bool)), - Groups: expandStringList(ng), - Password: aws.String(newUserMap["password"].(string)), - Username: aws.String(username), - }) - } - - // Delete after processing, so we know what's left for deletion - delete(existingUsers, username) - } else { - cur := &mq.CreateUserRequest{ - BrokerId: aws.String(bId), - ConsoleAccess: aws.Bool(newUserMap["console_access"].(bool)), - Password: aws.String(newUserMap["password"].(string)), - Username: aws.String(username), - } - if len(ng) > 0 { - cur.Groups = expandStringList(ng) - } - cr = append(cr, cur) - } - } - - for username := range existingUsers { - di = append(di, &mq.DeleteUserInput{ - BrokerId: aws.String(bId), - Username: aws.String(username), - }) - } - - return cr, di, ur, nil -} - -func expandMqEncryptionOptions(l []interface{}) *mq.EncryptionOptions { - if len(l) == 0 || l[0] == nil { - return nil - } - - m := l[0].(map[string]interface{}) - - encryptionOptions := &mq.EncryptionOptions{ - UseAwsOwnedKey: aws.Bool(m["use_aws_owned_key"].(bool)), - } - - if v, ok := m["kms_key_id"].(string); ok && v != "" { - encryptionOptions.KmsKeyId = aws.String(v) - } - - return encryptionOptions -} - -func flattenMqEncryptionOptions(encryptionOptions *mq.EncryptionOptions) []interface{} { - if encryptionOptions == nil { - return []interface{}{} - } - - m := map[string]interface{}{ - "kms_key_id": aws.StringValue(encryptionOptions.KmsKeyId), - "use_aws_owned_key": aws.BoolValue(encryptionOptions.UseAwsOwnedKey), - } - - return []interface{}{m} -} - -func validateMqBrokerPassword(v interface{}, k string) (ws []string, errors []error) { - min := 12 - max := 250 - value := v.(string) - unique := make(map[string]bool) - - for _, v := range value { - if _, ok := unique[string(v)]; ok { - continue - } - if string(v) == "," { - errors = append(errors, fmt.Errorf("%q must not contain commas", k)) - } - unique[string(v)] = true - } - if len(unique) < 4 { - errors = append(errors, fmt.Errorf("%q must contain at least 4 unique characters", k)) - } - if len(value) < min || len(value) > max { - errors = append(errors, fmt.Errorf( - "%q must be %d to %d characters long. provided string length: %d", k, min, max, len(value))) - } - return -} - -func expandMqUsers(cfg []interface{}) []*mq.User { - users := make([]*mq.User, len(cfg)) - for i, m := range cfg { - u := m.(map[string]interface{}) - user := mq.User{ - Username: aws.String(u["username"].(string)), - Password: aws.String(u["password"].(string)), - } - if v, ok := u["console_access"]; ok { - user.ConsoleAccess = aws.Bool(v.(bool)) - } - if v, ok := u["groups"]; ok { - user.Groups = expandStringSet(v.(*schema.Set)) - } - users[i] = &user - } - return users -} - -func expandMqUsersForBroker(conn *mq.MQ, brokerId string, input []*mq.UserSummary) ([]*mq.User, error) { - var rawUsers []*mq.User - - for _, u := range input { - if u == nil { - continue - } - - uOut, err := conn.DescribeUser(&mq.DescribeUserInput{ - BrokerId: aws.String(brokerId), - Username: u.Username, - }) - - if err != nil { - return nil, err - } - - user := &mq.User{ - ConsoleAccess: uOut.ConsoleAccess, - Groups: uOut.Groups, - Username: uOut.Username, - } - - rawUsers = append(rawUsers, user) - } - - return rawUsers, nil -} - -// We use cfgdUsers to get & set the password -func flattenMqUsers(users []*mq.User, cfgUsers []interface{}) *schema.Set { - existingPairs := make(map[string]string) - for _, u := range cfgUsers { - user := u.(map[string]interface{}) - username := user["username"].(string) - existingPairs[username] = user["password"].(string) - } - - out := make([]interface{}, 0) - for _, u := range users { - m := map[string]interface{}{ - "username": aws.StringValue(u.Username), - } - password := "" - if p, ok := existingPairs[aws.StringValue(u.Username)]; ok { - password = p - } - if password != "" { - m["password"] = password - } - if u.ConsoleAccess != nil { - m["console_access"] = aws.BoolValue(u.ConsoleAccess) - } - if len(u.Groups) > 0 { - m["groups"] = flattenStringSet(u.Groups) - } - out = append(out, m) - } - return schema.NewSet(resourceAwsMqUserHash, out) -} - -func expandMqWeeklyStartTime(cfg []interface{}) *mq.WeeklyStartTime { - if len(cfg) < 1 { - return nil - } - - m := cfg[0].(map[string]interface{}) - return &mq.WeeklyStartTime{ - DayOfWeek: aws.String(m["day_of_week"].(string)), - TimeOfDay: aws.String(m["time_of_day"].(string)), - TimeZone: aws.String(m["time_zone"].(string)), - } -} - -func flattenMqWeeklyStartTime(wst *mq.WeeklyStartTime) []interface{} { - if wst == nil { - return []interface{}{} - } - m := make(map[string]interface{}) - if wst.DayOfWeek != nil { - m["day_of_week"] = *wst.DayOfWeek - } - if wst.TimeOfDay != nil { - m["time_of_day"] = *wst.TimeOfDay - } - if wst.TimeZone != nil { - m["time_zone"] = *wst.TimeZone - } - return []interface{}{m} -} - -func expandMqConfigurationId(cfg []interface{}) *mq.ConfigurationId { - if len(cfg) < 1 { - return nil - } - - m := cfg[0].(map[string]interface{}) - out := mq.ConfigurationId{ - Id: aws.String(m["id"].(string)), - } - if v, ok := m["revision"].(int); ok && v > 0 { - out.Revision = aws.Int64(int64(v)) - } - - return &out -} - -func flattenMqConfiguration(config *mq.Configurations) []interface{} { - if config == nil || config.Current == nil { - return []interface{}{} - } - - m := map[string]interface{}{ - "id": aws.StringValue(config.Current.Id), - "revision": aws.Int64Value(config.Current.Revision), - } - - return []interface{}{m} -} - -func flattenMqBrokerInstances(instances []*mq.BrokerInstance) []interface{} { - if len(instances) == 0 { - return []interface{}{} - } - l := make([]interface{}, len(instances)) - for i, instance := range instances { - m := make(map[string]interface{}) - if instance.ConsoleURL != nil { - m["console_url"] = aws.StringValue(instance.ConsoleURL) - } - if len(instance.Endpoints) > 0 { - m["endpoints"] = aws.StringValueSlice(instance.Endpoints) - } - if instance.IpAddress != nil { - m["ip_address"] = aws.StringValue(instance.IpAddress) - } - l[i] = m - } - - return l -} - -func flattenMqLogs(logs *mq.LogsSummary) []interface{} { - if logs == nil { - return []interface{}{} - } - - m := map[string]interface{}{} - - if logs.General != nil { - m["general"] = aws.BoolValue(logs.General) - } - - if logs.Audit != nil { - m["audit"] = strconv.FormatBool(aws.BoolValue(logs.Audit)) - } - - return []interface{}{m} -} - -func expandMqLogs(engineType string, l []interface{}) *mq.Logs { - if len(l) == 0 || l[0] == nil { - return nil - } - - m := l[0].(map[string]interface{}) - - logs := &mq.Logs{} - - if v, ok := m["general"]; ok { - logs.General = aws.Bool(v.(bool)) - } - - // When the engine type is "RabbitMQ", the parameter audit cannot be set at all. - if v, ok := m["audit"]; ok { - if v, null, _ := nullable.Bool(v.(string)).Value(); !null { - if !strings.EqualFold(engineType, mq.EngineTypeRabbitmq) { - logs.Audit = aws.Bool(v) - } - } - } - - return logs -} - -func flattenMQLDAPServerMetadata(apiObject *mq.LdapServerMetadataOutput, password string) []interface{} { - if apiObject == nil { - return nil - } - - tfMap := map[string]interface{}{} - - if v := apiObject.Hosts; v != nil { - tfMap["hosts"] = aws.StringValueSlice(v) - } - if v := apiObject.RoleBase; v != nil { - tfMap["role_base"] = aws.StringValue(v) - } - if v := apiObject.RoleName; v != nil { - tfMap["role_name"] = aws.StringValue(v) - } - if v := apiObject.RoleSearchMatching; v != nil { - tfMap["role_search_matching"] = aws.StringValue(v) - } - if v := apiObject.RoleSearchSubtree; v != nil { - tfMap["role_search_subtree"] = aws.BoolValue(v) - } - if password != "" { - tfMap["service_account_password"] = password - } - if v := apiObject.ServiceAccountUsername; v != nil { - tfMap["service_account_username"] = aws.StringValue(v) - } - if v := apiObject.UserBase; v != nil { - tfMap["user_base"] = aws.StringValue(v) - } - if v := apiObject.UserRoleName; v != nil { - tfMap["user_role_name"] = aws.StringValue(v) - } - if v := apiObject.UserSearchMatching; v != nil { - tfMap["user_search_matching"] = aws.StringValue(v) - } - if v := apiObject.UserSearchSubtree; v != nil { - tfMap["user_search_subtree"] = aws.BoolValue(v) - } - - return []interface{}{tfMap} -} - -func expandMQLDAPServerMetadata(tfList []interface{}) *mq.LdapServerMetadataInput { - if len(tfList) == 0 || tfList[0] == nil { - return nil - } - - apiObject := &mq.LdapServerMetadataInput{} - - tfMap := tfList[0].(map[string]interface{}) - - if v, ok := tfMap["hosts"]; ok && len(v.([]interface{})) > 0 { - apiObject.Hosts = expandStringList(v.([]interface{})) - } - if v, ok := tfMap["role_base"].(string); ok && v != "" { - apiObject.RoleBase = aws.String(v) - } - if v, ok := tfMap["role_name"].(string); ok && v != "" { - apiObject.RoleName = aws.String(v) - } - if v, ok := tfMap["role_search_matching"].(string); ok && v != "" { - apiObject.RoleSearchMatching = aws.String(v) - } - if v, ok := tfMap["role_search_subtree"].(bool); ok { - apiObject.RoleSearchSubtree = aws.Bool(v) - } - if v, ok := tfMap["service_account_password"].(string); ok && v != "" { - apiObject.ServiceAccountPassword = aws.String(v) - } - if v, ok := tfMap["service_account_username"].(string); ok && v != "" { - apiObject.ServiceAccountUsername = aws.String(v) - } - if v, ok := tfMap["user_base"].(string); ok && v != "" { - apiObject.UserBase = aws.String(v) - } - if v, ok := tfMap["user_role_name"].(string); ok && v != "" { - apiObject.UserRoleName = aws.String(v) - } - if v, ok := tfMap["user_search_matching"].(string); ok && v != "" { - apiObject.UserSearchMatching = aws.String(v) - } - if v, ok := tfMap["user_search_subtree"].(bool); ok { - apiObject.UserSearchSubtree = aws.Bool(v) - } - - return apiObject -} From d58aa666a0018f8684dbd2115284648361967c7d Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Feb 2022 16:31:18 -0500 Subject: [PATCH 08/17] Fix merge --- internal/service/mq/broker.go | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/internal/service/mq/broker.go b/internal/service/mq/broker.go index 2269f047deda..b992a58664d7 100644 --- a/internal/service/mq/broker.go +++ b/internal/service/mq/broker.go @@ -1,4 +1,3 @@ -<<<<<<< HEAD:internal/service/mq/broker.go package mq import ( @@ -558,14 +557,6 @@ func resourceBrokerUpdate(d *schema.ResourceData, meta interface{}) error { } } - if d.HasChange("tags_all") { - o, n := d.GetChange("tags_all") - - if err := UpdateTags(conn, d.Get("arn").(string), o, n); err != nil { - return fmt.Errorf("error updating MQ Broker (%s) tags: %w", d.Get("arn").(string), err) - } - } - if d.HasChange("host_instance_type") { _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ BrokerId: aws.String(d.Id()), @@ -586,6 +577,14 @@ func resourceBrokerUpdate(d *schema.ResourceData, meta interface{}) error { } } + if d.HasChange("tags_all") { + o, n := d.GetChange("tags_all") + + if err := UpdateTags(conn, d.Get("arn").(string), o, n); err != nil { + return fmt.Errorf("error updating MQ Broker (%s) tags: %w", d.Get("arn").(string), err) + } + } + return nil } @@ -1088,6 +1087,3 @@ func expandMQLDAPServerMetadata(tfList []interface{}) *mq.LdapServerMetadataInpu return apiObject } -======= - ->>>>>>> ceb21bc040 (Update resource_aws_mq_broker.go):aws/resource_aws_mq_broker.go From d961173a00f1d0e9fb78e072cf306a53e76df453 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Feb 2022 16:46:26 -0500 Subject: [PATCH 09/17] Fix type --- internal/service/mq/broker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/service/mq/broker.go b/internal/service/mq/broker.go index b992a58664d7..8d698944110c 100644 --- a/internal/service/mq/broker.go +++ b/internal/service/mq/broker.go @@ -560,7 +560,7 @@ func resourceBrokerUpdate(d *schema.ResourceData, meta interface{}) error { if d.HasChange("host_instance_type") { _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ BrokerId: aws.String(d.Id()), - HostInstanceType: aws.String(d.Get("host_instance_type")), + HostInstanceType: aws.String(d.Get("host_instance_type").(string)), }) if err != nil { return fmt.Errorf("error updating MQ Broker (%s) host instance type: %w", d.Id(), err) From 9c55ab2c4dce0d950e5cbb67c9332c1767b29819 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Feb 2022 17:14:58 -0500 Subject: [PATCH 10/17] Update versions for GovCloud --- internal/service/mq/broker_test.go | 212 +++++++++++++++-------------- 1 file changed, 109 insertions(+), 103 deletions(-) diff --git a/internal/service/mq/broker_test.go b/internal/service/mq/broker_test.go index 6adefa647b15..e84b7f0b1efd 100644 --- a/internal/service/mq/broker_test.go +++ b/internal/service/mq/broker_test.go @@ -188,6 +188,12 @@ func TestDiffUsers(t *testing.T) { } } +const ( + testAccBrokerVersionNewer = "5.16.3" // before changing, check b/c must be valid on GovCloud + testAccBrokerVersionOlder = "5.15.12" // before changing, check b/c must be valid on GovCloud + testAccRabbitMQVersion = "3.8.6" // before changing, check b/c must be valid on GovCloud +) + func TestAccMQBroker_basic(t *testing.T) { var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) @@ -204,7 +210,7 @@ func TestAccMQBroker_basic(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccMqBrokerConfig(rName), + Config: testAccBrokerConfig(rName, testAccBrokerVersionNewer), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "auto_minor_version_upgrade", "false"), @@ -277,7 +283,7 @@ func TestAccMQBroker_throughputOptimized(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccMqBrokerEBSConfig(rName), + Config: testAccBrokerEBSConfig(rName, testAccBrokerVersionNewer), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "auto_minor_version_upgrade", "false"), @@ -356,7 +362,7 @@ func TestAccMQBroker_allFieldsDefaultVPC(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccMqBrokerConfig_allFieldsDefaultVpc(rName, rName, cfgBodyBefore), + Config: testAccBrokerConfig_allFieldsDefaultVpc(rName, testAccBrokerVersionNewer, rName, cfgBodyBefore), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "auto_minor_version_upgrade", "true"), @@ -427,7 +433,7 @@ func TestAccMQBroker_allFieldsDefaultVPC(t *testing.T) { }, { // Update configuration in-place - Config: testAccMqBrokerConfig_allFieldsDefaultVpc(rName, rName, cfgBodyAfter), + Config: testAccBrokerConfig_allFieldsDefaultVpc(rName, testAccBrokerVersionNewer, rName, cfgBodyAfter), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "broker_name", rName), @@ -438,7 +444,7 @@ func TestAccMQBroker_allFieldsDefaultVPC(t *testing.T) { }, { // Replace configuration - Config: testAccMqBrokerConfig_allFieldsDefaultVpc(rName, rNameUpdated, cfgBodyAfter), + Config: testAccBrokerConfig_allFieldsDefaultVpc(rName, testAccBrokerVersionNewer, rNameUpdated, cfgBodyAfter), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "broker_name", rName), @@ -480,7 +486,7 @@ func TestAccMQBroker_allFieldsCustomVPC(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccMqBrokerConfig_allFieldsCustomVpc(rName, rName, cfgBodyBefore), + Config: testAccBrokerConfig_allFieldsCustomVpc(rName, testAccBrokerVersionNewer, rName, cfgBodyBefore), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "auto_minor_version_upgrade", "true"), @@ -551,7 +557,7 @@ func TestAccMQBroker_allFieldsCustomVPC(t *testing.T) { }, { // Update configuration in-place - Config: testAccMqBrokerConfig_allFieldsCustomVpc(rName, rName, cfgBodyAfter), + Config: testAccBrokerConfig_allFieldsCustomVpc(rName, testAccBrokerVersionNewer, rName, cfgBodyAfter), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "broker_name", rName), @@ -562,7 +568,7 @@ func TestAccMQBroker_allFieldsCustomVPC(t *testing.T) { }, { // Replace configuration - Config: testAccMqBrokerConfig_allFieldsCustomVpc(rName, rNameUpdated, cfgBodyAfter), + Config: testAccBrokerConfig_allFieldsCustomVpc(rName, testAccBrokerVersionNewer, rNameUpdated, cfgBodyAfter), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "broker_name", rName), @@ -592,7 +598,7 @@ func TestAccMQBroker_EncryptionOptions_kmsKeyID(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccMqBrokerConfigEncryptionOptionsKmsKeyId(rName), + Config: testAccBrokerConfigEncryptionOptionsKmsKeyId(rName, testAccBrokerVersionNewer), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "encryption_options.#", "1"), @@ -626,7 +632,7 @@ func TestAccMQBroker_EncryptionOptionsUseAwsOwnedKey_disabled(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccBrokerEncryptionOptionsUseAWSOwnedKeyConfig(rName, false), + Config: testAccBrokerEncryptionOptionsUseAWSOwnedKeyConfig(rName, testAccBrokerVersionNewer, false), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "encryption_options.#", "1"), @@ -659,7 +665,7 @@ func TestAccMQBroker_EncryptionOptionsUseAwsOwnedKey_enabled(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccBrokerEncryptionOptionsUseAWSOwnedKeyConfig(rName, true), + Config: testAccBrokerEncryptionOptionsUseAWSOwnedKeyConfig(rName, testAccBrokerVersionNewer, true), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "encryption_options.#", "1"), @@ -692,7 +698,7 @@ func TestAccMQBroker_updateUsers(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccMqBrokerConfig_updateUsers1(rName), + Config: testAccBrokerConfig_updateUsers1(rName, testAccBrokerVersionNewer), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "user.#", "1"), @@ -712,7 +718,7 @@ func TestAccMQBroker_updateUsers(t *testing.T) { }, // Adding new user + modify existing { - Config: testAccMqBrokerConfig_updateUsers2(rName), + Config: testAccBrokerConfig_updateUsers2(rName, testAccBrokerVersionNewer), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "user.#", "2"), @@ -732,7 +738,7 @@ func TestAccMQBroker_updateUsers(t *testing.T) { }, // Deleting user + modify existing { - Config: testAccMqBrokerConfig_updateUsers3(rName), + Config: testAccBrokerConfig_updateUsers3(rName, testAccBrokerVersionNewer), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "user.#", "1"), @@ -765,7 +771,7 @@ func TestAccMQBroker_tags(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccMqBrokerConfigTags1(rName, "key1", "value1"), + Config: testAccBrokerConfigTags1(rName, testAccBrokerVersionNewer, "key1", "value1"), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), @@ -779,7 +785,7 @@ func TestAccMQBroker_tags(t *testing.T) { ImportStateVerifyIgnore: []string{"apply_immediately", "user"}, }, { - Config: testAccMqBrokerConfigTags2(rName, "key1", "value1updated", "key2", "value2"), + Config: testAccBrokerConfigTags2(rName, testAccBrokerVersionNewer, "key1", "value1updated", "key2", "value2"), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "tags.%", "2"), @@ -788,7 +794,7 @@ func TestAccMQBroker_tags(t *testing.T) { ), }, { - Config: testAccMqBrokerConfigTags1(rName, "key2", "value2"), + Config: testAccBrokerConfigTags1(rName, testAccBrokerVersionNewer, "key2", "value2"), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "tags.%", "1"), @@ -815,7 +821,7 @@ func TestAccMQBroker_updateSecurityGroup(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccMqBrokerConfig(rName), + Config: testAccBrokerConfig(rName, testAccBrokerVersionNewer), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "security_groups.#", "1"), @@ -828,7 +834,7 @@ func TestAccMQBroker_updateSecurityGroup(t *testing.T) { ImportStateVerifyIgnore: []string{"apply_immediately", "user"}, }, { - Config: testAccMqBrokerConfig_updateSecurityGroups(rName), + Config: testAccBrokerConfig_updateSecurityGroups(rName, testAccBrokerVersionNewer), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "security_groups.#", "2"), @@ -837,7 +843,7 @@ func TestAccMQBroker_updateSecurityGroup(t *testing.T) { // Trigger a reboot and ensure the password change was applied // User hashcode can be retrieved by calling resourceUserHash { - Config: testAccMqBrokerConfig_updateUsersSecurityGroups(rName), + Config: testAccBrokerConfig_updateUsersSecurityGroups(rName, testAccBrokerVersionNewer), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "security_groups.#", "1"), @@ -868,10 +874,10 @@ func TestAccMQBroker_updateEngineVersion(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccMqBrokerConfig(rName), + Config: testAccBrokerConfig(rName, testAccBrokerVersionOlder), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.15.0"), + resource.TestCheckResourceAttr(resourceName, "engine_version", testAccBrokerVersionOlder), ), }, { @@ -881,10 +887,10 @@ func TestAccMQBroker_updateEngineVersion(t *testing.T) { ImportStateVerifyIgnore: []string{"apply_immediately", "user"}, }, { - Config: testAccMqBrokerEngineVersionUpdateConfig(rName), + Config: testAccBrokerEngineVersionUpdateConfig(rName, testAccBrokerVersionNewer), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.15.9"), + resource.TestCheckResourceAttr(resourceName, "engine_version", testAccBrokerVersionNewer), ), }, }, @@ -907,7 +913,7 @@ func TestAccMQBroker_disappears(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccMqBrokerConfig(rName), + Config: testAccBrokerConfig(rName, testAccBrokerVersionNewer), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), acctest.CheckResourceDisappears(acctest.Provider, tfmq.ResourceBroker(), resourceName), @@ -934,12 +940,12 @@ func TestAccMQBroker_rabbitMQ(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccMqBrokerConfigRabbit(rName), + Config: testAccBrokerConfigRabbit(rName, testAccRabbitMQVersion), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "configuration.#", "0"), resource.TestCheckResourceAttr(resourceName, "engine_type", "RabbitMQ"), - resource.TestCheckResourceAttr(resourceName, "engine_version", "3.8.6"), + resource.TestCheckResourceAttr(resourceName, "engine_version", testAccRabbitMQVersion), resource.TestCheckResourceAttr(resourceName, "host_instance_type", "mq.t3.micro"), resource.TestCheckResourceAttr(resourceName, "instances.#", "1"), resource.TestCheckResourceAttr(resourceName, "instances.0.endpoints.#", "1"), @@ -975,12 +981,12 @@ func TestAccMQBroker_RabbitMQ_logs(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccMqBrokerConfigRabbitLogs(rName), + Config: testAccBrokerConfigRabbitLogs(rName, testAccRabbitMQVersion), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "configuration.#", "0"), resource.TestCheckResourceAttr(resourceName, "engine_type", "RabbitMQ"), - resource.TestCheckResourceAttr(resourceName, "engine_version", "3.8.6"), + resource.TestCheckResourceAttr(resourceName, "engine_version", testAccRabbitMQVersion), resource.TestCheckResourceAttr(resourceName, "host_instance_type", "mq.t3.micro"), resource.TestCheckResourceAttr(resourceName, "instances.#", "1"), resource.TestCheckResourceAttr(resourceName, "instances.0.endpoints.#", "1"), @@ -1016,13 +1022,13 @@ func TestAccMQBroker_RabbitMQValidation_auditLog(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccMqBrokerConfigRabbitAuditLog(rName, true), + Config: testAccBrokerConfigRabbitAuditLog(rName, testAccRabbitMQVersion, true), ExpectError: regexp.MustCompile(`logs.audit: Can not be configured when engine is RabbitMQ`), }, { // Special case: allow explicitly setting logs.0.audit to false, // though the AWS API does not accept the parameter. - Config: testAccMqBrokerConfigRabbitAuditLog(rName, false), + Config: testAccBrokerConfigRabbitAuditLog(rName, testAccRabbitMQVersion, false), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "logs.#", "1"), @@ -1050,7 +1056,7 @@ func TestAccMQBroker_clusterRabbitMQ(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccRabbitMqClusterBrokerConfig(rName), + Config: testAccRabbitClusterBrokerConfig(rName, testAccRabbitMQVersion), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "auto_minor_version_upgrade", "false"), @@ -1059,7 +1065,7 @@ func TestAccMQBroker_clusterRabbitMQ(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "encryption_options.#", "1"), resource.TestCheckResourceAttr(resourceName, "encryption_options.0.use_aws_owned_key", "true"), resource.TestCheckResourceAttr(resourceName, "engine_type", "RabbitMQ"), - resource.TestCheckResourceAttr(resourceName, "engine_version", "3.8.6"), + resource.TestCheckResourceAttr(resourceName, "engine_version", testAccRabbitMQVersion), resource.TestCheckResourceAttr(resourceName, "host_instance_type", "mq.m5.large"), resource.TestCheckResourceAttr(resourceName, "maintenance_window_start_time.#", "1"), resource.TestCheckResourceAttrSet(resourceName, "maintenance_window_start_time.0.day_of_week"), @@ -1112,7 +1118,7 @@ func TestAccMQBroker_ldap(t *testing.T) { CheckDestroy: testAccCheckBrokerDestroy, Steps: []resource.TestStep{ { - Config: testAccMqBrokerConfig_ldap(rName, "anyusername"), + Config: testAccBrokerConfig_ldap(rName, testAccBrokerVersionNewer, "anyusername"), Check: resource.ComposeTestCheckFunc( testAccCheckBrokerExists(resourceName, &broker), resource.TestCheckResourceAttr(resourceName, "auto_minor_version_upgrade", "false"), @@ -1204,7 +1210,7 @@ func testAccPreCheck(t *testing.T) { } } -func testAccMqBrokerConfig(rName string) string { +func testAccBrokerConfig(rName, version string) string { return fmt.Sprintf(` resource "aws_security_group" "test" { name = %[1]q @@ -1213,7 +1219,7 @@ resource "aws_security_group" "test" { resource "aws_mq_broker" "test" { broker_name = %[1]q engine_type = "ActiveMQ" - engine_version = "5.15.0" + engine_version = %[2]q host_instance_type = "mq.t2.micro" security_groups = [aws_security_group.test.id] authentication_strategy = "simple" @@ -1228,10 +1234,10 @@ resource "aws_mq_broker" "test" { password = "TestTest1234" } } -`, rName) +`, rName, version) } -func testAccMqBrokerEBSConfig(rName string) string { +func testAccBrokerEBSConfig(rName, version string) string { return fmt.Sprintf(` resource "aws_security_group" "test" { name = %[1]q @@ -1240,7 +1246,7 @@ resource "aws_security_group" "test" { resource "aws_mq_broker" "test" { broker_name = %[1]q engine_type = "ActiveMQ" - engine_version = "5.15.9" + engine_version = %[2]q # "5.15.9" storage_type = "ebs" host_instance_type = "mq.m5.large" security_groups = [aws_security_group.test.id] @@ -1254,10 +1260,10 @@ resource "aws_mq_broker" "test" { password = "TestTest1234" } } -`, rName) +`, rName, version) } -func testAccMqBrokerEngineVersionUpdateConfig(rName string) string { +func testAccBrokerEngineVersionUpdateConfig(rName, version string) string { return fmt.Sprintf(` resource "aws_security_group" "test" { name = %[1]q @@ -1267,7 +1273,7 @@ resource "aws_mq_broker" "test" { broker_name = %[1]q apply_immediately = true engine_type = "ActiveMQ" - engine_version = "5.15.9" + engine_version = %[2]q # "5.15.9" host_instance_type = "mq.t2.micro" security_groups = [aws_security_group.test.id] @@ -1280,10 +1286,10 @@ resource "aws_mq_broker" "test" { password = "TestTest1234" } } -`, rName) +`, rName, version) } -func testAccMqBrokerConfig_allFieldsDefaultVpc(rName, cfgName, cfgBody string) string { +func testAccBrokerConfig_allFieldsDefaultVpc(rName, version, cfgName, cfgBody string) string { return fmt.Sprintf(` resource "aws_security_group" "mq1" { name = %[1]q @@ -1294,12 +1300,12 @@ resource "aws_security_group" "mq2" { } resource "aws_mq_configuration" "test" { - name = %[2]q + name = %[3]q engine_type = "ActiveMQ" - engine_version = "5.15.0" + engine_version = %[2]q data = < Date: Mon, 7 Feb 2022 17:20:40 -0500 Subject: [PATCH 11/17] Fix tests --- internal/service/mq/broker_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/service/mq/broker_test.go b/internal/service/mq/broker_test.go index e84b7f0b1efd..92f7ff04a69a 100644 --- a/internal/service/mq/broker_test.go +++ b/internal/service/mq/broker_test.go @@ -223,7 +223,7 @@ func TestAccMQBroker_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "encryption_options.#", "1"), resource.TestCheckResourceAttr(resourceName, "encryption_options.0.use_aws_owned_key", "true"), resource.TestCheckResourceAttr(resourceName, "engine_type", "ActiveMQ"), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.15.0"), + resource.TestCheckResourceAttr(resourceName, "engine_version", testAccBrokerVersionNewer), resource.TestCheckResourceAttr(resourceName, "host_instance_type", "mq.t2.micro"), resource.TestCheckResourceAttr(resourceName, "maintenance_window_start_time.#", "1"), resource.TestCheckResourceAttrSet(resourceName, "maintenance_window_start_time.0.day_of_week"), @@ -295,7 +295,7 @@ func TestAccMQBroker_throughputOptimized(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "encryption_options.#", "1"), resource.TestCheckResourceAttr(resourceName, "encryption_options.0.use_aws_owned_key", "true"), resource.TestCheckResourceAttr(resourceName, "engine_type", "ActiveMQ"), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.15.9"), + resource.TestCheckResourceAttr(resourceName, "engine_version", testAccBrokerVersionNewer), resource.TestCheckResourceAttr(resourceName, "storage_type", "ebs"), resource.TestCheckResourceAttr(resourceName, "host_instance_type", "mq.m5.large"), resource.TestCheckResourceAttr(resourceName, "maintenance_window_start_time.#", "1"), @@ -372,7 +372,7 @@ func TestAccMQBroker_allFieldsDefaultVPC(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "configuration.0.revision", "2"), resource.TestCheckResourceAttr(resourceName, "deployment_mode", "ACTIVE_STANDBY_MULTI_AZ"), resource.TestCheckResourceAttr(resourceName, "engine_type", "ActiveMQ"), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.15.0"), + resource.TestCheckResourceAttr(resourceName, "engine_version", testAccBrokerVersionNewer), resource.TestCheckResourceAttr(resourceName, "storage_type", "efs"), resource.TestCheckResourceAttr(resourceName, "host_instance_type", "mq.t2.micro"), resource.TestCheckResourceAttr(resourceName, "maintenance_window_start_time.#", "1"), @@ -496,7 +496,7 @@ func TestAccMQBroker_allFieldsCustomVPC(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "configuration.0.revision", "2"), resource.TestCheckResourceAttr(resourceName, "deployment_mode", "ACTIVE_STANDBY_MULTI_AZ"), resource.TestCheckResourceAttr(resourceName, "engine_type", "ActiveMQ"), - resource.TestCheckResourceAttr(resourceName, "engine_version", "5.15.0"), + resource.TestCheckResourceAttr(resourceName, "engine_version", testAccBrokerVersionNewer), resource.TestCheckResourceAttr(resourceName, "storage_type", "efs"), resource.TestCheckResourceAttr(resourceName, "host_instance_type", "mq.t2.micro"), resource.TestCheckResourceAttr(resourceName, "maintenance_window_start_time.#", "1"), @@ -1246,7 +1246,7 @@ resource "aws_security_group" "test" { resource "aws_mq_broker" "test" { broker_name = %[1]q engine_type = "ActiveMQ" - engine_version = %[2]q # "5.15.9" + engine_version = %[2]q storage_type = "ebs" host_instance_type = "mq.m5.large" security_groups = [aws_security_group.test.id] @@ -1273,7 +1273,7 @@ resource "aws_mq_broker" "test" { broker_name = %[1]q apply_immediately = true engine_type = "ActiveMQ" - engine_version = %[2]q # "5.15.9" + engine_version = %[2]q host_instance_type = "mq.t2.micro" security_groups = [aws_security_group.test.id] From 22767fbc31feaa5e623d81d09bd7eec17b8563ca Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Feb 2022 17:26:57 -0500 Subject: [PATCH 12/17] Add long guards --- .../service/mq/broker_data_source_test.go | 4 ++ internal/service/mq/broker_test.go | 68 +++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/internal/service/mq/broker_data_source_test.go b/internal/service/mq/broker_data_source_test.go index 7506043b065a..330e71479b4b 100644 --- a/internal/service/mq/broker_data_source_test.go +++ b/internal/service/mq/broker_data_source_test.go @@ -11,6 +11,10 @@ import ( ) func TestAccMQBrokerDataSource_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mq_broker.test" diff --git a/internal/service/mq/broker_test.go b/internal/service/mq/broker_test.go index 92f7ff04a69a..29fdeabbbf0b 100644 --- a/internal/service/mq/broker_test.go +++ b/internal/service/mq/broker_test.go @@ -195,6 +195,10 @@ const ( ) func TestAccMQBroker_basic(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mq_broker.test" @@ -268,6 +272,10 @@ func TestAccMQBroker_basic(t *testing.T) { } func TestAccMQBroker_throughputOptimized(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mq_broker.test" @@ -334,6 +342,10 @@ func TestAccMQBroker_throughputOptimized(t *testing.T) { } func TestAccMQBroker_allFieldsDefaultVPC(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) rNameUpdated := sdkacctest.RandomWithPrefix("tf-acc-test-updated") @@ -458,6 +470,10 @@ func TestAccMQBroker_allFieldsDefaultVPC(t *testing.T) { } func TestAccMQBroker_allFieldsCustomVPC(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) rNameUpdated := sdkacctest.RandomWithPrefix("tf-acc-test-updated") @@ -582,6 +598,10 @@ func TestAccMQBroker_allFieldsCustomVPC(t *testing.T) { } func TestAccMQBroker_EncryptionOptions_kmsKeyID(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) kmsKeyResourceName := "aws_kms_key.test" @@ -617,6 +637,10 @@ func TestAccMQBroker_EncryptionOptions_kmsKeyID(t *testing.T) { } func TestAccMQBroker_EncryptionOptionsUseAwsOwnedKey_disabled(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mq_broker.test" @@ -650,6 +674,10 @@ func TestAccMQBroker_EncryptionOptionsUseAwsOwnedKey_disabled(t *testing.T) { } func TestAccMQBroker_EncryptionOptionsUseAwsOwnedKey_enabled(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mq_broker.test" @@ -683,6 +711,10 @@ func TestAccMQBroker_EncryptionOptionsUseAwsOwnedKey_enabled(t *testing.T) { } func TestAccMQBroker_updateUsers(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mq_broker.test" @@ -756,6 +788,10 @@ func TestAccMQBroker_updateUsers(t *testing.T) { } func TestAccMQBroker_tags(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mq_broker.test" @@ -806,6 +842,10 @@ func TestAccMQBroker_tags(t *testing.T) { } func TestAccMQBroker_updateSecurityGroup(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mq_broker.test" @@ -859,6 +899,10 @@ func TestAccMQBroker_updateSecurityGroup(t *testing.T) { } func TestAccMQBroker_updateEngineVersion(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mq_broker.test" @@ -898,6 +942,10 @@ func TestAccMQBroker_updateEngineVersion(t *testing.T) { } func TestAccMQBroker_disappears(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mq_broker.test" @@ -925,6 +973,10 @@ func TestAccMQBroker_disappears(t *testing.T) { } func TestAccMQBroker_rabbitMQ(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mq_broker.test" @@ -966,6 +1018,10 @@ func TestAccMQBroker_rabbitMQ(t *testing.T) { } func TestAccMQBroker_RabbitMQ_logs(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mq_broker.test" @@ -1007,6 +1063,10 @@ func TestAccMQBroker_RabbitMQ_logs(t *testing.T) { } func TestAccMQBroker_RabbitMQValidation_auditLog(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mq_broker.test" @@ -1041,6 +1101,10 @@ func TestAccMQBroker_RabbitMQValidation_auditLog(t *testing.T) { } func TestAccMQBroker_clusterRabbitMQ(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mq_broker.test" @@ -1103,6 +1167,10 @@ func TestAccMQBroker_clusterRabbitMQ(t *testing.T) { } func TestAccMQBroker_ldap(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + var broker mq.DescribeBrokerResponse rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) resourceName := "aws_mq_broker.test" From c64226824a320d2f6f8f68e55789b1fe0a6f3733 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Feb 2022 18:14:12 -0500 Subject: [PATCH 13/17] Add changelog --- .changelog/20661.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/20661.txt diff --git a/.changelog/20661.txt b/.changelog/20661.txt new file mode 100644 index 000000000000..32e71688fe62 --- /dev/null +++ b/.changelog/20661.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_mq_broker: `auto_minor_version_upgrade` and `host_instance_type` can be changed without recreating broker +``` \ No newline at end of file From 468df3617cd2335c14fc60d5e6be747f991ad8b4 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Feb 2022 18:43:56 -0500 Subject: [PATCH 14/17] Clean up names --- internal/service/mq/broker.go | 78 +++++++++++++++++------------------ 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/internal/service/mq/broker.go b/internal/service/mq/broker.go index 8d698944110c..379b2ac0d8f4 100644 --- a/internal/service/mq/broker.go +++ b/internal/service/mq/broker.go @@ -359,29 +359,29 @@ func resourceBrokerCreate(d *schema.ResourceData, meta interface{}) error { EngineVersion: aws.String(d.Get("engine_version").(string)), HostInstanceType: aws.String(d.Get("host_instance_type").(string)), PubliclyAccessible: aws.Bool(d.Get("publicly_accessible").(bool)), - Users: expandMqUsers(d.Get("user").(*schema.Set).List()), + Users: expandUsers(d.Get("user").(*schema.Set).List()), } if v, ok := d.GetOk("authentication_strategy"); ok { input.AuthenticationStrategy = aws.String(v.(string)) } if v, ok := d.GetOk("configuration"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - input.Configuration = expandMqConfigurationId(v.([]interface{})) + input.Configuration = expandConfigurationId(v.([]interface{})) } if v, ok := d.GetOk("deployment_mode"); ok { input.DeploymentMode = aws.String(v.(string)) } if v, ok := d.GetOk("encryption_options"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - input.EncryptionOptions = expandMqEncryptionOptions(d.Get("encryption_options").([]interface{})) + input.EncryptionOptions = expandEncryptionOptions(d.Get("encryption_options").([]interface{})) } if v, ok := d.GetOk("logs"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - input.Logs = expandMqLogs(engineType, v.([]interface{})) + input.Logs = expandLogs(engineType, v.([]interface{})) } if v, ok := d.GetOk("ldap_server_metadata"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { input.LdapServerMetadata = expandMQLDAPServerMetadata(v.([]interface{})) } if v, ok := d.GetOk("maintenance_window_start_time"); ok && len(v.([]interface{})) > 0 && v.([]interface{})[0] != nil { - input.MaintenanceWindowStartTime = expandMqWeeklyStartTime(v.([]interface{})) + input.MaintenanceWindowStartTime = expandWeeklyStartTime(v.([]interface{})) } if v, ok := d.GetOk("security_groups"); ok && v.(*schema.Set).Len() > 0 { input.SecurityGroups = flex.ExpandStringSet(v.(*schema.Set)) @@ -443,17 +443,17 @@ func resourceBrokerRead(d *schema.ResourceData, meta interface{}) error { d.Set("engine_type", output.EngineType) d.Set("engine_version", output.EngineVersion) d.Set("host_instance_type", output.HostInstanceType) - d.Set("instances", flattenMqBrokerInstances(output.BrokerInstances)) + d.Set("instances", flattenBrokerInstances(output.BrokerInstances)) d.Set("publicly_accessible", output.PubliclyAccessible) d.Set("security_groups", aws.StringValueSlice(output.SecurityGroups)) d.Set("storage_type", output.StorageType) d.Set("subnet_ids", aws.StringValueSlice(output.SubnetIds)) - if err := d.Set("configuration", flattenMqConfiguration(output.Configurations)); err != nil { + if err := d.Set("configuration", flattenConfiguration(output.Configurations)); err != nil { return fmt.Errorf("error setting configuration: %w", err) } - if err := d.Set("encryption_options", flattenMqEncryptionOptions(output.EncryptionOptions)); err != nil { + if err := d.Set("encryption_options", flattenEncryptionOptions(output.EncryptionOptions)); err != nil { return fmt.Errorf("error setting encryption_options: %w", err) } @@ -466,21 +466,21 @@ func resourceBrokerRead(d *schema.ResourceData, meta interface{}) error { return fmt.Errorf("error setting ldap_server_metadata: %w", err) } - if err := d.Set("logs", flattenMqLogs(output.Logs)); err != nil { + if err := d.Set("logs", flattenLogs(output.Logs)); err != nil { return fmt.Errorf("error setting logs: %w", err) } - if err := d.Set("maintenance_window_start_time", flattenMqWeeklyStartTime(output.MaintenanceWindowStartTime)); err != nil { + if err := d.Set("maintenance_window_start_time", flattenWeeklyStartTime(output.MaintenanceWindowStartTime)); err != nil { return fmt.Errorf("error setting maintenance_window_start_time: %w", err) } - rawUsers, err := expandMqUsersForBroker(conn, d.Id(), output.Users) + rawUsers, err := expandUsersForBroker(conn, d.Id(), output.Users) if err != nil { return fmt.Errorf("error retrieving user info for MQ broker (%s): %w", d.Id(), err) } - if err := d.Set("user", flattenMqUsers(rawUsers, d.Get("user").(*schema.Set).List())); err != nil { + if err := d.Set("user", flattenUsers(rawUsers, d.Get("user").(*schema.Set).List())); err != nil { return fmt.Errorf("error setting user: %w", err) } @@ -517,8 +517,8 @@ func resourceBrokerUpdate(d *schema.ResourceData, meta interface{}) error { engineType := d.Get("engine_type").(string) _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ BrokerId: aws.String(d.Id()), - Configuration: expandMqConfigurationId(d.Get("configuration").([]interface{})), - Logs: expandMqLogs(engineType, d.Get("logs").([]interface{})), + Configuration: expandConfigurationId(d.Get("configuration").([]interface{})), + Logs: expandLogs(engineType, d.Get("logs").([]interface{})), EngineVersion: aws.String(d.Get("engine_version").(string)), }) if err != nil { @@ -544,19 +544,6 @@ func resourceBrokerUpdate(d *schema.ResourceData, meta interface{}) error { } } - if d.Get("apply_immediately").(bool) && requiresReboot { - _, err := conn.RebootBroker(&mq.RebootBrokerInput{ - BrokerId: aws.String(d.Id()), - }) - if err != nil { - return fmt.Errorf("error rebooting MQ Broker (%s): %w", d.Id(), err) - } - - if _, err := WaitBrokerRebooted(conn, d.Id()); err != nil { - return fmt.Errorf("error waiting for MQ Broker (%s) reboot: %w", d.Id(), err) - } - } - if d.HasChange("host_instance_type") { _, err := conn.UpdateBroker(&mq.UpdateBrokerRequest{ BrokerId: aws.String(d.Id()), @@ -577,6 +564,19 @@ func resourceBrokerUpdate(d *schema.ResourceData, meta interface{}) error { } } + if d.Get("apply_immediately").(bool) && requiresReboot { + _, err := conn.RebootBroker(&mq.RebootBrokerInput{ + BrokerId: aws.String(d.Id()), + }) + if err != nil { + return fmt.Errorf("error rebooting MQ Broker (%s): %w", d.Id(), err) + } + + if _, err := WaitBrokerRebooted(conn, d.Id()); err != nil { + return fmt.Errorf("error waiting for MQ Broker (%s) reboot: %w", d.Id(), err) + } + } + if d.HasChange("tags_all") { o, n := d.GetChange("tags_all") @@ -738,7 +738,7 @@ func DiffBrokerUsers(bId string, oldUsers, newUsers []interface{}) ( return cr, di, ur, nil } -func expandMqEncryptionOptions(l []interface{}) *mq.EncryptionOptions { +func expandEncryptionOptions(l []interface{}) *mq.EncryptionOptions { if len(l) == 0 || l[0] == nil { return nil } @@ -756,7 +756,7 @@ func expandMqEncryptionOptions(l []interface{}) *mq.EncryptionOptions { return encryptionOptions } -func flattenMqEncryptionOptions(encryptionOptions *mq.EncryptionOptions) []interface{} { +func flattenEncryptionOptions(encryptionOptions *mq.EncryptionOptions) []interface{} { if encryptionOptions == nil { return []interface{}{} } @@ -794,7 +794,7 @@ func ValidBrokerPassword(v interface{}, k string) (ws []string, errors []error) return } -func expandMqUsers(cfg []interface{}) []*mq.User { +func expandUsers(cfg []interface{}) []*mq.User { users := make([]*mq.User, len(cfg)) for i, m := range cfg { u := m.(map[string]interface{}) @@ -813,7 +813,7 @@ func expandMqUsers(cfg []interface{}) []*mq.User { return users } -func expandMqUsersForBroker(conn *mq.MQ, brokerId string, input []*mq.UserSummary) ([]*mq.User, error) { +func expandUsersForBroker(conn *mq.MQ, brokerId string, input []*mq.UserSummary) ([]*mq.User, error) { var rawUsers []*mq.User for _, u := range input { @@ -843,7 +843,7 @@ func expandMqUsersForBroker(conn *mq.MQ, brokerId string, input []*mq.UserSummar } // We use cfgdUsers to get & set the password -func flattenMqUsers(users []*mq.User, cfgUsers []interface{}) *schema.Set { +func flattenUsers(users []*mq.User, cfgUsers []interface{}) *schema.Set { existingPairs := make(map[string]string) for _, u := range cfgUsers { user := u.(map[string]interface{}) @@ -874,7 +874,7 @@ func flattenMqUsers(users []*mq.User, cfgUsers []interface{}) *schema.Set { return schema.NewSet(resourceUserHash, out) } -func expandMqWeeklyStartTime(cfg []interface{}) *mq.WeeklyStartTime { +func expandWeeklyStartTime(cfg []interface{}) *mq.WeeklyStartTime { if len(cfg) < 1 { return nil } @@ -887,7 +887,7 @@ func expandMqWeeklyStartTime(cfg []interface{}) *mq.WeeklyStartTime { } } -func flattenMqWeeklyStartTime(wst *mq.WeeklyStartTime) []interface{} { +func flattenWeeklyStartTime(wst *mq.WeeklyStartTime) []interface{} { if wst == nil { return []interface{}{} } @@ -904,7 +904,7 @@ func flattenMqWeeklyStartTime(wst *mq.WeeklyStartTime) []interface{} { return []interface{}{m} } -func expandMqConfigurationId(cfg []interface{}) *mq.ConfigurationId { +func expandConfigurationId(cfg []interface{}) *mq.ConfigurationId { if len(cfg) < 1 { return nil } @@ -920,7 +920,7 @@ func expandMqConfigurationId(cfg []interface{}) *mq.ConfigurationId { return &out } -func flattenMqConfiguration(config *mq.Configurations) []interface{} { +func flattenConfiguration(config *mq.Configurations) []interface{} { if config == nil || config.Current == nil { return []interface{}{} } @@ -933,7 +933,7 @@ func flattenMqConfiguration(config *mq.Configurations) []interface{} { return []interface{}{m} } -func flattenMqBrokerInstances(instances []*mq.BrokerInstance) []interface{} { +func flattenBrokerInstances(instances []*mq.BrokerInstance) []interface{} { if len(instances) == 0 { return []interface{}{} } @@ -955,7 +955,7 @@ func flattenMqBrokerInstances(instances []*mq.BrokerInstance) []interface{} { return l } -func flattenMqLogs(logs *mq.LogsSummary) []interface{} { +func flattenLogs(logs *mq.LogsSummary) []interface{} { if logs == nil { return []interface{}{} } @@ -973,7 +973,7 @@ func flattenMqLogs(logs *mq.LogsSummary) []interface{} { return []interface{}{m} } -func expandMqLogs(engineType string, l []interface{}) *mq.Logs { +func expandLogs(engineType string, l []interface{}) *mq.Logs { if len(l) == 0 || l[0] == nil { return nil } From 7e18fdf0bf81bd29c885536fee834d68c5d0b379 Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Feb 2022 18:46:12 -0500 Subject: [PATCH 15/17] Clean up names --- internal/service/mq/broker.go | 4 ++-- internal/service/mq/broker_data_source.go | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/internal/service/mq/broker.go b/internal/service/mq/broker.go index 379b2ac0d8f4..501623da729e 100644 --- a/internal/service/mq/broker.go +++ b/internal/service/mq/broker.go @@ -462,7 +462,7 @@ func resourceBrokerRead(d *schema.ResourceData, meta interface{}) error { password = v.(string) } - if err := d.Set("ldap_server_metadata", flattenMQLDAPServerMetadata(output.LdapServerMetadata, password)); err != nil { + if err := d.Set("ldap_server_metadata", flattenLDAPServerMetadata(output.LdapServerMetadata, password)); err != nil { return fmt.Errorf("error setting ldap_server_metadata: %w", err) } @@ -998,7 +998,7 @@ func expandLogs(engineType string, l []interface{}) *mq.Logs { return logs } -func flattenMQLDAPServerMetadata(apiObject *mq.LdapServerMetadataOutput, password string) []interface{} { +func flattenLDAPServerMetadata(apiObject *mq.LdapServerMetadataOutput, password string) []interface{} { if apiObject == nil { return nil } diff --git a/internal/service/mq/broker_data_source.go b/internal/service/mq/broker_data_source.go index 8fe80688a65f..51061179aeea 100644 --- a/internal/service/mq/broker_data_source.go +++ b/internal/service/mq/broker_data_source.go @@ -309,17 +309,17 @@ func dataSourcemqBrokerRead(d *schema.ResourceData, meta interface{}) error { d.Set("engine_type", output.EngineType) d.Set("engine_version", output.EngineVersion) d.Set("host_instance_type", output.HostInstanceType) - d.Set("instances", flattenMqBrokerInstances(output.BrokerInstances)) + d.Set("instances", flattenBrokerInstances(output.BrokerInstances)) d.Set("publicly_accessible", output.PubliclyAccessible) d.Set("security_groups", aws.StringValueSlice(output.SecurityGroups)) d.Set("storage_type", output.StorageType) d.Set("subnet_ids", aws.StringValueSlice(output.SubnetIds)) - if err := d.Set("configuration", flattenMqConfiguration(output.Configurations)); err != nil { + if err := d.Set("configuration", flattenConfiguration(output.Configurations)); err != nil { return fmt.Errorf("error setting configuration: %w", err) } - if err := d.Set("encryption_options", flattenMqEncryptionOptions(output.EncryptionOptions)); err != nil { + if err := d.Set("encryption_options", flattenEncryptionOptions(output.EncryptionOptions)); err != nil { return fmt.Errorf("error setting encryption_options: %w", err) } @@ -328,25 +328,25 @@ func dataSourcemqBrokerRead(d *schema.ResourceData, meta interface{}) error { password = v.(string) } - if err := d.Set("ldap_server_metadata", flattenMQLDAPServerMetadata(output.LdapServerMetadata, password)); err != nil { + if err := d.Set("ldap_server_metadata", flattenLDAPServerMetadata(output.LdapServerMetadata, password)); err != nil { return fmt.Errorf("error setting ldap_server_metadata: %w", err) } - if err := d.Set("logs", flattenMqLogs(output.Logs)); err != nil { + if err := d.Set("logs", flattenLogs(output.Logs)); err != nil { return fmt.Errorf("error setting logs: %w", err) } - if err := d.Set("maintenance_window_start_time", flattenMqWeeklyStartTime(output.MaintenanceWindowStartTime)); err != nil { + if err := d.Set("maintenance_window_start_time", flattenWeeklyStartTime(output.MaintenanceWindowStartTime)); err != nil { return fmt.Errorf("error setting maintenance_window_start_time: %w", err) } - rawUsers, err := expandMqUsersForBroker(conn, brokerId, output.Users) + rawUsers, err := expandUsersForBroker(conn, brokerId, output.Users) if err != nil { return fmt.Errorf("error retrieving user info for MQ broker (%s): %w", brokerId, err) } - if err := d.Set("user", flattenMqUsers(rawUsers, d.Get("user").(*schema.Set).List())); err != nil { + if err := d.Set("user", flattenUsers(rawUsers, d.Get("user").(*schema.Set).List())); err != nil { return fmt.Errorf("error setting user: %w", err) } From d3526b1467a0897753893f7c317927e78ab60d9e Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Feb 2022 18:54:14 -0500 Subject: [PATCH 16/17] Get reboot in the right place --- internal/service/mq/broker.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/internal/service/mq/broker.go b/internal/service/mq/broker.go index 501623da729e..98caf5946437 100644 --- a/internal/service/mq/broker.go +++ b/internal/service/mq/broker.go @@ -549,9 +549,12 @@ func resourceBrokerUpdate(d *schema.ResourceData, meta interface{}) error { BrokerId: aws.String(d.Id()), HostInstanceType: aws.String(d.Get("host_instance_type").(string)), }) + if err != nil { return fmt.Errorf("error updating MQ Broker (%s) host instance type: %w", d.Id(), err) } + + requiresReboot = true } if d.HasChange("auto_minor_version_upgrade") { @@ -559,9 +562,12 @@ func resourceBrokerUpdate(d *schema.ResourceData, meta interface{}) error { BrokerId: aws.String(d.Id()), AutoMinorVersionUpgrade: aws.Bool(d.Get("auto_minor_version_upgrade").(bool)), }) + if err != nil { return fmt.Errorf("error updating MQ Broker (%s) auto minor version upgrade: %w", d.Id(), err) } + + requiresReboot = true } if d.Get("apply_immediately").(bool) && requiresReboot { From c5e6477cc2b8dbcd50e310594d4dd81e80a9746a Mon Sep 17 00:00:00 2001 From: Dirk Avery Date: Mon, 7 Feb 2022 19:25:46 -0500 Subject: [PATCH 17/17] Add instance type update test --- internal/service/mq/broker_test.go | 96 ++++++++++++++++++++++++++---- 1 file changed, 85 insertions(+), 11 deletions(-) diff --git a/internal/service/mq/broker_test.go b/internal/service/mq/broker_test.go index 29fdeabbbf0b..d48c35c127f7 100644 --- a/internal/service/mq/broker_test.go +++ b/internal/service/mq/broker_test.go @@ -341,7 +341,7 @@ func TestAccMQBroker_throughputOptimized(t *testing.T) { }) } -func TestAccMQBroker_allFieldsDefaultVPC(t *testing.T) { +func TestAccMQBroker_AllFields_defaultVPC(t *testing.T) { if testing.Short() { t.Skip("skipping long-running test in short mode") } @@ -469,7 +469,7 @@ func TestAccMQBroker_allFieldsDefaultVPC(t *testing.T) { }) } -func TestAccMQBroker_allFieldsCustomVPC(t *testing.T) { +func TestAccMQBroker_AllFields_customVPC(t *testing.T) { if testing.Short() { t.Skip("skipping long-running test in short mode") } @@ -636,7 +636,7 @@ func TestAccMQBroker_EncryptionOptions_kmsKeyID(t *testing.T) { }) } -func TestAccMQBroker_EncryptionOptionsUseAwsOwnedKey_disabled(t *testing.T) { +func TestAccMQBroker_EncryptionOptions_awsOwnedKeyDisabled(t *testing.T) { if testing.Short() { t.Skip("skipping long-running test in short mode") } @@ -673,7 +673,7 @@ func TestAccMQBroker_EncryptionOptionsUseAwsOwnedKey_disabled(t *testing.T) { }) } -func TestAccMQBroker_EncryptionOptionsUseAwsOwnedKey_enabled(t *testing.T) { +func TestAccMQBroker_EncryptionOptions_awsOwnedKeyEnabled(t *testing.T) { if testing.Short() { t.Skip("skipping long-running test in short mode") } @@ -710,7 +710,7 @@ func TestAccMQBroker_EncryptionOptionsUseAwsOwnedKey_enabled(t *testing.T) { }) } -func TestAccMQBroker_updateUsers(t *testing.T) { +func TestAccMQBroker_Update_users(t *testing.T) { if testing.Short() { t.Skip("skipping long-running test in short mode") } @@ -787,7 +787,7 @@ func TestAccMQBroker_updateUsers(t *testing.T) { }) } -func TestAccMQBroker_tags(t *testing.T) { +func TestAccMQBroker_Update_tags(t *testing.T) { if testing.Short() { t.Skip("skipping long-running test in short mode") } @@ -841,7 +841,7 @@ func TestAccMQBroker_tags(t *testing.T) { }) } -func TestAccMQBroker_updateSecurityGroup(t *testing.T) { +func TestAccMQBroker_Update_securityGroup(t *testing.T) { if testing.Short() { t.Skip("skipping long-running test in short mode") } @@ -898,7 +898,7 @@ func TestAccMQBroker_updateSecurityGroup(t *testing.T) { }) } -func TestAccMQBroker_updateEngineVersion(t *testing.T) { +func TestAccMQBroker_Update_engineVersion(t *testing.T) { if testing.Short() { t.Skip("skipping long-running test in short mode") } @@ -941,6 +941,44 @@ func TestAccMQBroker_updateEngineVersion(t *testing.T) { }) } +func TestAccMQBroker_Update_hostInstanceType(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var broker1, broker2 mq.DescribeBrokerResponse + rName := sdkacctest.RandomWithPrefix(acctest.ResourcePrefix) + resourceName := "aws_mq_broker.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + acctest.PreCheck(t) + acctest.PreCheckPartitionHasService(mq.EndpointsID, t) + testAccPreCheck(t) + }, + ErrorCheck: acctest.ErrorCheck(t, mq.EndpointsID), + Providers: acctest.Providers, + CheckDestroy: testAccCheckBrokerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccBrokerConfigInstanceType(rName, testAccBrokerVersionNewer, "mq.t2.micro"), + Check: resource.ComposeTestCheckFunc( + testAccCheckBrokerExists(resourceName, &broker1), + resource.TestCheckResourceAttr(resourceName, "host_instance_type", "mq.t2.micro"), + ), + }, + { + Config: testAccBrokerConfigInstanceType(rName, testAccBrokerVersionNewer, "mq.t3.micro"), + Check: resource.ComposeTestCheckFunc( + testAccCheckBrokerExists(resourceName, &broker2), + testAccCheckBrokerNotRecreated(&broker1, &broker2), + resource.TestCheckResourceAttr(resourceName, "host_instance_type", "mq.t3.micro"), + ), + }, + }, + }) +} + func TestAccMQBroker_disappears(t *testing.T) { if testing.Short() { t.Skip("skipping long-running test in short mode") @@ -972,7 +1010,7 @@ func TestAccMQBroker_disappears(t *testing.T) { }) } -func TestAccMQBroker_rabbitMQ(t *testing.T) { +func TestAccMQBroker_RabbitMQ_basic(t *testing.T) { if testing.Short() { t.Skip("skipping long-running test in short mode") } @@ -1062,7 +1100,7 @@ func TestAccMQBroker_RabbitMQ_logs(t *testing.T) { }) } -func TestAccMQBroker_RabbitMQValidation_auditLog(t *testing.T) { +func TestAccMQBroker_RabbitMQ_validationAuditLog(t *testing.T) { if testing.Short() { t.Skip("skipping long-running test in short mode") } @@ -1100,7 +1138,7 @@ func TestAccMQBroker_RabbitMQValidation_auditLog(t *testing.T) { }) } -func TestAccMQBroker_clusterRabbitMQ(t *testing.T) { +func TestAccMQBroker_RabbitMQ_cluster(t *testing.T) { if testing.Short() { t.Skip("skipping long-running test in short mode") } @@ -1278,6 +1316,16 @@ func testAccPreCheck(t *testing.T) { } } +func testAccCheckBrokerNotRecreated(before, after *mq.DescribeBrokerResponse) resource.TestCheckFunc { + return func(s *terraform.State) error { + if before, after := aws.StringValue(before.BrokerId), aws.StringValue(after.BrokerId); before != after { + return fmt.Errorf("MQ Broker (%s/%s) recreated", before, after) + } + + return nil + } +} + func testAccBrokerConfig(rName, version string) string { return fmt.Sprintf(` resource "aws_security_group" "test" { @@ -1935,3 +1983,29 @@ resource "aws_mq_broker" "test" { } `, rName, version, ldapUsername) } + +func testAccBrokerConfigInstanceType(rName, version, instanceType string) string { + return fmt.Sprintf(` +resource "aws_security_group" "test" { + name = %[1]q +} + +resource "aws_mq_broker" "test" { + broker_name = %[1]q + apply_immediately = true + engine_type = "ActiveMQ" + engine_version = %[2]q + host_instance_type = %[3]q + security_groups = [aws_security_group.test.id] + + logs { + general = true + } + + user { + username = "Test" + password = "TestTest1234" + } +} +`, rName, version, instanceType) +}