diff --git a/ecl/import_ecl_mlb_certificate_v1_mock_test.go b/ecl/import_ecl_mlb_certificate_v1_mock_test.go new file mode 100644 index 00000000..f81d9928 --- /dev/null +++ b/ecl/import_ecl_mlb_certificate_v1_mock_test.go @@ -0,0 +1,44 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1CertificateImport(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "certificates", "/v1.0/certificates", testMockMLBV1CertificatesCreate) + mc.Register(t, "certificates", "/v1.0/certificates/497f6eca-6276-4993-bfeb-53cbbbba6f08/files", testMockMLBV1CertificatesUploadFileCaCert) + mc.Register(t, "certificates", "/v1.0/certificates/497f6eca-6276-4993-bfeb-53cbbbba6f08/files", testMockMLBV1CertificatesUploadFileSslCert) + mc.Register(t, "certificates", "/v1.0/certificates/497f6eca-6276-4993-bfeb-53cbbbba6f08/files", testMockMLBV1CertificatesUploadFileSslKey) + mc.Register(t, "certificates", "/v1.0/certificates/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1CertificatesShowAfterCreate) + mc.Register(t, "certificates", "/v1.0/certificates/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1CertificatesDelete) + mc.Register(t, "certificates", "/v1.0/certificates/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1CertificatesShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1Certificate, + }, + { + ResourceName: "ecl_mlb_certificate_v1.certificate", + ImportState: true, + ImportStateVerify: true, + ImportStateVerifyIgnore: []string{"ca_cert", "ssl_cert", "ssl_key"}, + }, + }, + }) +} diff --git a/ecl/import_ecl_mlb_health_monitor_v1_mock_test.go b/ecl/import_ecl_mlb_health_monitor_v1_mock_test.go new file mode 100644 index 00000000..fa8981ef --- /dev/null +++ b/ecl/import_ecl_mlb_health_monitor_v1_mock_test.go @@ -0,0 +1,40 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1HealthMonitorImport(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "health_monitors", "/v1.0/health_monitors", testMockMLBV1HealthMonitorsCreate) + mc.Register(t, "health_monitors", "/v1.0/health_monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1HealthMonitorsShowAfterCreate) + mc.Register(t, "health_monitors", "/v1.0/health_monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1HealthMonitorsDelete) + mc.Register(t, "health_monitors", "/v1.0/health_monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1HealthMonitorsShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1HealthMonitor, + }, + { + ResourceName: "ecl_mlb_health_monitor_v1.health_monitor", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/ecl/import_ecl_mlb_listener_v1_mock_test.go b/ecl/import_ecl_mlb_listener_v1_mock_test.go new file mode 100644 index 00000000..575214c9 --- /dev/null +++ b/ecl/import_ecl_mlb_listener_v1_mock_test.go @@ -0,0 +1,40 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1ListenerImport(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "listeners", "/v1.0/listeners", testMockMLBV1ListenersCreate) + mc.Register(t, "listeners", "/v1.0/listeners/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1ListenersShowAfterCreate) + mc.Register(t, "listeners", "/v1.0/listeners/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1ListenersDelete) + mc.Register(t, "listeners", "/v1.0/listeners/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1ListenersShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1Listener, + }, + { + ResourceName: "ecl_mlb_listener_v1.listener", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/ecl/import_ecl_mlb_load_balancer_v1_mock_test.go b/ecl/import_ecl_mlb_load_balancer_v1_mock_test.go new file mode 100644 index 00000000..f023b52e --- /dev/null +++ b/ecl/import_ecl_mlb_load_balancer_v1_mock_test.go @@ -0,0 +1,40 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1LoadBalancerImport(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "load_balancers", "/v1.0/load_balancers", testMockMLBV1LoadBalancersCreate) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowAfterCreate) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersDelete) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1LoadBalancer, + }, + { + ResourceName: "ecl_mlb_load_balancer_v1.load_balancer", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/ecl/import_ecl_mlb_policy_v1_mock_test.go b/ecl/import_ecl_mlb_policy_v1_mock_test.go new file mode 100644 index 00000000..3ebe4889 --- /dev/null +++ b/ecl/import_ecl_mlb_policy_v1_mock_test.go @@ -0,0 +1,40 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1PolicyImport(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "policies", "/v1.0/policies", testMockMLBV1PoliciesCreate) + mc.Register(t, "policies", "/v1.0/policies/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1PoliciesShowAfterCreate) + mc.Register(t, "policies", "/v1.0/policies/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1PoliciesDelete) + mc.Register(t, "policies", "/v1.0/policies/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1PoliciesShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1Policy, + }, + { + ResourceName: "ecl_mlb_policy_v1.policy", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/ecl/import_ecl_mlb_route_v1_mock_test.go b/ecl/import_ecl_mlb_route_v1_mock_test.go new file mode 100644 index 00000000..37a576b5 --- /dev/null +++ b/ecl/import_ecl_mlb_route_v1_mock_test.go @@ -0,0 +1,40 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1RouteImport(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "routes", "/v1.0/routes", testMockMLBV1RoutesCreate) + mc.Register(t, "routes", "/v1.0/routes/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RoutesShowAfterCreate) + mc.Register(t, "routes", "/v1.0/routes/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RoutesDelete) + mc.Register(t, "routes", "/v1.0/routes/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RoutesShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1Route, + }, + { + ResourceName: "ecl_mlb_route_v1.route", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/ecl/import_ecl_mlb_rule_v1_mock_test.go b/ecl/import_ecl_mlb_rule_v1_mock_test.go new file mode 100644 index 00000000..43e3ad06 --- /dev/null +++ b/ecl/import_ecl_mlb_rule_v1_mock_test.go @@ -0,0 +1,40 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1RuleImport(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "rules", "/v1.0/rules", testMockMLBV1RulesCreate) + mc.Register(t, "rules", "/v1.0/rules/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RulesShowAfterCreate) + mc.Register(t, "rules", "/v1.0/rules/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RulesDelete) + mc.Register(t, "rules", "/v1.0/rules/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RulesShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1Rule, + }, + { + ResourceName: "ecl_mlb_rule_v1.rule", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/ecl/import_ecl_mlb_target_group_v1_mock_test.go b/ecl/import_ecl_mlb_target_group_v1_mock_test.go new file mode 100644 index 00000000..478d7410 --- /dev/null +++ b/ecl/import_ecl_mlb_target_group_v1_mock_test.go @@ -0,0 +1,40 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1TargetGroupImport(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "target_groups", "/v1.0/target_groups", testMockMLBV1TargetGroupsCreate) + mc.Register(t, "target_groups", "/v1.0/target_groups/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1TargetGroupsShowAfterCreate) + mc.Register(t, "target_groups", "/v1.0/target_groups/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1TargetGroupsDelete) + mc.Register(t, "target_groups", "/v1.0/target_groups/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1TargetGroupsShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1TargetGroup, + }, + { + ResourceName: "ecl_mlb_target_group_v1.target_group", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/ecl/provider.go b/ecl/provider.go index 6af46f9d..a54a69a3 100644 --- a/ecl/provider.go +++ b/ecl/provider.go @@ -232,6 +232,15 @@ func Provider() terraform.ResourceProvider { "ecl_imagestorages_image_v2": resourceImageStoragesImageV2(), "ecl_imagestorages_member_accepter_v2": resourceImageStoragesMemberAccepterV2(), "ecl_imagestorages_member_v2": resourceImageStoragesMemberV2(), + "ecl_mlb_certificate_v1": resourceMLBCertificateV1(), + "ecl_mlb_health_monitor_v1": resourceMLBHealthMonitorV1(), + "ecl_mlb_listener_v1": resourceMLBListenerV1(), + "ecl_mlb_load_balancer_v1": resourceMLBLoadBalancerV1(), + "ecl_mlb_load_balancer_action_v1": resourceMLBLoadBalancerActionV1(), + "ecl_mlb_policy_v1": resourceMLBPolicyV1(), + "ecl_mlb_route_v1": resourceMLBRouteV1(), + "ecl_mlb_rule_v1": resourceMLBRuleV1(), + "ecl_mlb_target_group_v1": resourceMLBTargetGroupV1(), "ecl_network_common_function_gateway_v2": resourceNetworkCommonFunctionGatewayV2(), "ecl_network_gateway_interface_v2": resourceNetworkGatewayInterfaceV2(), "ecl_network_internet_gateway_v2": resourceNetworkInternetGatewayV2(), diff --git a/ecl/resource_ecl_mlb_certificate_v1.go b/ecl/resource_ecl_mlb_certificate_v1.go new file mode 100644 index 00000000..3c57bf02 --- /dev/null +++ b/ecl/resource_ecl_mlb_certificate_v1.go @@ -0,0 +1,187 @@ +package ecl + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates" +) + +func certificateFileSchemaForResource() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeMap, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "content": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + }, + }, + } +} + +func resourceMLBCertificateV1() *schema.Resource { + var result *schema.Resource + + result = &schema.Resource{ + Create: resourceMLBCertificateV1Create, + Read: reourceMLBCertificateV1Read, + Update: resourceMLBCertificateV1Update, + Delete: resourceMLBCertificateV1Delete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "tags": &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + }, + "tenant_id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + "ca_cert": certificateFileSchemaForResource(), + "ssl_cert": certificateFileSchemaForResource(), + "ssl_key": certificateFileSchemaForResource(), + }, + } + + return result +} + +func resourceMLBCertificateV1Create(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + createOpts := certificates.CreateOpts{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + Tags: d.Get("tags").(map[string]interface{}), + } + + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Creating ECL managed load balancer certificate with options %+v", createOpts) + + certificate, err := certificates.Create(managedLoadBalancerClient, createOpts).Extract() + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer certificate with options %+v: %s", createOpts, err) + } + + d.SetId(certificate.ID) + log.Printf("[INFO] ECL managed load balancer certificate ID: %s", certificate.ID) + + for _, fileType := range []string{"ca_cert", "ssl_cert", "ssl_key"} { + file := d.Get(fileType).(map[string]interface{}) + uploadFileOpts := certificates.UploadFileOpts{ + Type: fileType, + Content: file["content"].(string), + } + + log.Printf("[DEBUG] Uploading ECL managed load balancer certificate file (%s) with options %+v", d.Id(), uploadFileOpts) + + err = certificates.UploadFile(managedLoadBalancerClient, certificate.ID, uploadFileOpts).ExtractErr() + if err != nil { + return fmt.Errorf("Error uploading ECL managed load balancer certificate file (%s) with options %+v: %s", d.Id(), uploadFileOpts, err) + } + } + + return reourceMLBCertificateV1Read(d, meta) +} + +func reourceMLBCertificateV1Read(d *schema.ResourceData, meta interface{}) error { + var certificate certificates.Certificate + + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + err = certificates.Show(managedLoadBalancerClient, d.Id()).ExtractInto(&certificate) + if err != nil { + return CheckDeleted(d, err, "certificate") + } + + log.Printf("[DEBUG] Retrieved ECL managed load balancer certificate (%s): %+v", d.Id(), certificate) + + d.Set("name", certificate.Name) + d.Set("description", certificate.Description) + d.Set("tags", certificate.Tags) + d.Set("tenant_id", certificate.TenantID) + + return nil +} + +func resourceMLBCertificateV1Update(d *schema.ResourceData, meta interface{}) error { + var isUpdated bool + var updateOpts certificates.UpdateOpts + + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + if d.HasChange("name") { + isUpdated = true + name := d.Get("name").(string) + updateOpts.Name = &name + } + + if d.HasChange("description") { + isUpdated = true + description := d.Get("description").(string) + updateOpts.Description = &description + } + + if d.HasChange("tags") { + isUpdated = true + tags := d.Get("tags").(map[string]interface{}) + updateOpts.Tags = &tags + } + + if isUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer certificate (%s) with options %+v", d.Id(), updateOpts) + + _, err := certificates.Update(managedLoadBalancerClient, d.Id(), updateOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer certificate (%s) with options %+v: %s", d.Id(), updateOpts, err) + } + } + + return reourceMLBCertificateV1Read(d, meta) +} + +func resourceMLBCertificateV1Delete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Deleting ECL managed load balancer certificate (%s)", d.Id()) + + err = certificates.Delete(managedLoadBalancerClient, d.Id()).ExtractErr() + if err != nil { + return fmt.Errorf("Error deleting ECL managed load balancer certificate: %s", err) + } + + return nil +} diff --git a/ecl/resource_ecl_mlb_certificate_v1_mock_test.go b/ecl/resource_ecl_mlb_certificate_v1_mock_test.go new file mode 100644 index 00000000..30b658b4 --- /dev/null +++ b/ecl/resource_ecl_mlb_certificate_v1_mock_test.go @@ -0,0 +1,276 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1CertificateResource(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "certificates", "/v1.0/certificates", testMockMLBV1CertificatesCreate) + mc.Register(t, "certificates", "/v1.0/certificates/497f6eca-6276-4993-bfeb-53cbbbba6f08/files", testMockMLBV1CertificatesUploadFileCaCert) + mc.Register(t, "certificates", "/v1.0/certificates/497f6eca-6276-4993-bfeb-53cbbbba6f08/files", testMockMLBV1CertificatesUploadFileSslCert) + mc.Register(t, "certificates", "/v1.0/certificates/497f6eca-6276-4993-bfeb-53cbbbba6f08/files", testMockMLBV1CertificatesUploadFileSslKey) + mc.Register(t, "certificates", "/v1.0/certificates/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1CertificatesShowAfterCreate) + mc.Register(t, "certificates", "/v1.0/certificates/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1CertificatesUpdate) + mc.Register(t, "certificates", "/v1.0/certificates/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1CertificatesShowAfterUpdate) + mc.Register(t, "certificates", "/v1.0/certificates/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1CertificatesDelete) + mc.Register(t, "certificates", "/v1.0/certificates/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1CertificatesShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1Certificate, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_certificate_v1.certificate", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_certificate_v1.certificate", "name", "certificate"), + resource.TestCheckResourceAttr("ecl_mlb_certificate_v1.certificate", "description", "description"), + resource.TestCheckResourceAttr("ecl_mlb_certificate_v1.certificate", "tags.key", "value"), + resource.TestCheckResourceAttr("ecl_mlb_certificate_v1.certificate", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + resource.TestCheckResourceAttrSet("ecl_mlb_certificate_v1.certificate", "ca_cert.content"), + resource.TestCheckResourceAttrSet("ecl_mlb_certificate_v1.certificate", "ssl_cert.content"), + resource.TestCheckResourceAttrSet("ecl_mlb_certificate_v1.certificate", "ssl_key.content"), + ), + }, + { + Config: testAccMLBV1CertificateUpdate, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_certificate_v1.certificate", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_certificate_v1.certificate", "name", "certificate-update"), + resource.TestCheckResourceAttr("ecl_mlb_certificate_v1.certificate", "description", "description-update"), + resource.TestCheckResourceAttr("ecl_mlb_certificate_v1.certificate", "tags.key-update", "value-update"), + resource.TestCheckResourceAttr("ecl_mlb_certificate_v1.certificate", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + resource.TestCheckResourceAttrSet("ecl_mlb_certificate_v1.certificate", "ca_cert.content"), + resource.TestCheckResourceAttrSet("ecl_mlb_certificate_v1.certificate", "ssl_cert.content"), + resource.TestCheckResourceAttrSet("ecl_mlb_certificate_v1.certificate", "ssl_key.content"), + ), + }, + }, + }) +} + +var testAccMLBV1Certificate = fmt.Sprintf(` +resource "ecl_mlb_certificate_v1" "certificate" { + name = "certificate" + description = "description" + tags = { + key = "value" + } + ca_cert = { + content = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEKMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMwo0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1CjY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1NjcKODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OQpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCCkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0QKRUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRgpHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdICklKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUoKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTApNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OCk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1AKUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUgpTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUClVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVYKV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWApZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaCmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWIKY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZAplZmdoaWprbG1ub3BxcnN0dXZ3eHl6VjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlCmZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==" + } + ssl_cert = { + content = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEKMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMwo0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1CjY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1NjcKODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OQpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCCkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0QKRUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRgpHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdICklKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUoKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTApNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OCk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1AKUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUgpTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUClVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVYKV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWApZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaCmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWIKY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZAplZmdoaWprbG1ub3BxcnN0dXZ3eHl6VjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlCmZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==" + } + ssl_key = { + content = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEKMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMwo0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1CjY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1NjcKODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OQpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCCkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0QKRUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRgpHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdICklKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUoKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTApNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OCk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1AKUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUgpTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUClVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVYKV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWApZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaCmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWIKY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZAplZmdoaWprbG1ub3BxcnN0dXZ3eHl6VjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlCmZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==" + } +} +`) + +var testAccMLBV1CertificateUpdate = fmt.Sprintf(` +resource "ecl_mlb_certificate_v1" "certificate" { + name = "certificate-update" + description = "description-update" + tags = { + key-update = "value-update" + } + ca_cert = { + content = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEKMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMwo0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1CjY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1NjcKODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OQpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCCkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0QKRUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRgpHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdICklKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUoKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTApNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OCk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1AKUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUgpTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUClVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVYKV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWApZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaCmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWIKY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZAplZmdoaWprbG1ub3BxcnN0dXZ3eHl6VjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlCmZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==" + } + ssl_cert = { + content = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEKMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMwo0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1CjY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1NjcKODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OQpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCCkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0QKRUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRgpHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdICklKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUoKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTApNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OCk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1AKUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUgpTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUClVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVYKV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWApZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaCmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWIKY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZAplZmdoaWprbG1ub3BxcnN0dXZ3eHl6VjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlCmZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==" + } + ssl_key = { + content = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEKMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMwo0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1CjY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1NjcKODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OQpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCCkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0QKRUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRgpHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdICklKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUoKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTApNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OCk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1AKUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUgpTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUClVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVYKV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWApZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaCmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWIKY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZAplZmdoaWprbG1ub3BxcnN0dXZ3eHl6VjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlCmZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==" + } +} +`) + +var testMockMLBV1CertificatesCreate = fmt.Sprintf(` +request: + method: POST + body: > + {"certificate":{"description":"description","name":"certificate","tags":{"key":"value"}}} +response: + code: 200 + body: > + { + "certificate": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "certificate", + "description": "description", + "tags": { + "key": "value" + }, + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "ca_cert": { + "status": "NOT_UPLOADED" + }, + "ssl_cert": { + "status": "NOT_UPLOADED" + }, + "ssl_key": { + "status": "NOT_UPLOADED" + } + } + } +newStatus: Created +`) + +var testMockMLBV1CertificatesShowAfterCreate = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "certificate": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "certificate", + "description": "description", + "tags": { + "key": "value" + }, + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "ca_cert": { + "status": "UPLOADED" + }, + "ssl_cert": { + "status": "UPLOADED" + }, + "ssl_key": { + "status": "UPLOADED" + } + } + } +expectedStatus: + - Created +`) + +var testMockMLBV1CertificatesShowAfterUpdate = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "certificate": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "certificate-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "ca_cert": { + "status": "UPLOADED" + }, + "ssl_cert": { + "status": "UPLOADED" + }, + "ssl_key": { + "status": "UPLOADED" + } + } + } +expectedStatus: + - Updated +`) + +var testMockMLBV1CertificatesShowAfterDelete = fmt.Sprintf(` +request: + method: GET +response: + code: 404 +expectedStatus: + - Deleted +`) + +var testMockMLBV1CertificatesUpdate = fmt.Sprintf(` +request: + method: PATCH + body: > + {"certificate":{"description":"description-update","name":"certificate-update","tags":{"key-update":"value-update"}}} +response: + code: 200 + body: > + { + "certificate": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "certificate-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "ca_cert": { + "status": "UPLOADED" + }, + "ssl_cert": { + "status": "UPLOADED" + }, + "ssl_key": { + "status": "UPLOADED" + } + } + } +newStatus: Updated +`) + +var testMockMLBV1CertificatesDelete = fmt.Sprintf(` +request: + method: DELETE +response: + code: 204 +expectedStatus: + - Created + - Updated +newStatus: Deleted +`) + +var testMockMLBV1CertificatesUploadFileCaCert = fmt.Sprintf(` +request: + method: POST + body: > + {"content":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEKMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMwo0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1CjY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1NjcKODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OQpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCCkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0QKRUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRgpHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdICklKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUoKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTApNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OCk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1AKUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUgpTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUClVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVYKV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWApZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaCmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWIKY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZAplZmdoaWprbG1ub3BxcnN0dXZ3eHl6VjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlCmZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==","type":"ca_cert"} +response: + code: 204 +expectedStatus: + - Created +`) + +var testMockMLBV1CertificatesUploadFileSslCert = fmt.Sprintf(` +request: + method: POST + body: > + {"content":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEKMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMwo0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1CjY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1NjcKODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OQpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCCkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0QKRUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRgpHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdICklKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUoKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTApNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OCk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1AKUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUgpTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUClVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVYKV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWApZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaCmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWIKY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZAplZmdoaWprbG1ub3BxcnN0dXZ3eHl6VjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlCmZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==","type":"ssl_cert"} +response: + code: 204 +expectedStatus: + - Created +`) + +var testMockMLBV1CertificatesUploadFileSslKey = fmt.Sprintf(` +request: + method: POST + body: > + {"content":"LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEKMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMwo0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1CjY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1NjcKODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OQpBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCCkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0QKRUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRgpHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdICklKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUoKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTApNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OCk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1AKUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUgpTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUClVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVYKV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWApZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaCmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWIKY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZAplZmdoaWprbG1ub3BxcnN0dXZ3eHl6VjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlCmZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMgotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==","type":"ssl_key"} +response: + code: 204 +expectedStatus: + - Created +`) diff --git a/ecl/resource_ecl_mlb_health_monitor_v1.go b/ecl/resource_ecl_mlb_health_monitor_v1.go new file mode 100644 index 00000000..edd569be --- /dev/null +++ b/ecl/resource_ecl_mlb_health_monitor_v1.go @@ -0,0 +1,363 @@ +package ecl + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/nttcom/eclcloud/v2" + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors" +) + +func resourceMLBHealthMonitorV1() *schema.Resource { + var result *schema.Resource + + result = &schema.Resource{ + Create: resourceMLBHealthMonitorV1Create, + Read: resourceMLBHealthMonitorV1Read, + Update: resourceMLBHealthMonitorV1Update, + Delete: resourceMLBHealthMonitorV1Delete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "tags": &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + }, + "port": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + }, + "protocol": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "interval": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + }, + "retry": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + }, + "timeout": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + }, + "path": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "http_status_code": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "load_balancer_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "tenant_id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + }, + } + + return result +} + +func resourceMLBHealthMonitorV1Create(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + createOpts := health_monitors.CreateOpts{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + Tags: d.Get("tags").(map[string]interface{}), + Port: d.Get("port").(int), + Protocol: d.Get("protocol").(string), + Interval: d.Get("interval").(int), + Retry: d.Get("retry").(int), + Timeout: d.Get("timeout").(int), + Path: d.Get("path").(string), + HttpStatusCode: d.Get("http_status_code").(string), + LoadBalancerID: d.Get("load_balancer_id").(string), + } + + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Creating ECL managed load balancer health monitor with options %+v", createOpts) + + healthMonitor, err := health_monitors.Create(managedLoadBalancerClient, createOpts).Extract() + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer health monitor with options %+v: %s", createOpts, err) + } + + d.SetId(healthMonitor.ID) + log.Printf("[INFO] ECL managed load balancer health monitor ID: %s", healthMonitor.ID) + + return resourceMLBHealthMonitorV1Read(d, meta) +} + +func resourceMLBHealthMonitorV1Show(d *schema.ResourceData, client *eclcloud.ServiceClient, changes bool) (*health_monitors.HealthMonitor, error) { + var healthMonitor health_monitors.HealthMonitor + + showOpts := health_monitors.ShowOpts{Changes: changes} + err := health_monitors.Show(client, d.Id(), showOpts).ExtractInto(&healthMonitor) + if err != nil { + return nil, fmt.Errorf("Unable to retrieve ECL managed load balancer health monitor (%s): %s", d.Id(), err) + } + + return &healthMonitor, nil +} + +func resourceMLBHealthMonitorV1Read(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + healthMonitor, err := resourceMLBHealthMonitorV1Show(d, managedLoadBalancerClient, true) + if err != nil { + return CheckDeleted(d, err, "health_monitor") + } + + log.Printf("[DEBUG] Retrieved ECL managed load balancer health monitor (%s): %+v", d.Id(), healthMonitor) + + if healthMonitor.ConfigurationStatus == "ACTIVE" { + d.Set("port", healthMonitor.Port) + d.Set("protocol", healthMonitor.Protocol) + d.Set("interval", healthMonitor.Interval) + d.Set("retry", healthMonitor.Retry) + d.Set("timeout", healthMonitor.Timeout) + d.Set("path", healthMonitor.Path) + d.Set("http_status_code", healthMonitor.HttpStatusCode) + } else if healthMonitor.ConfigurationStatus == "CREATE_STAGED" { + d.Set("port", healthMonitor.Staged.Port) + d.Set("protocol", healthMonitor.Staged.Protocol) + d.Set("interval", healthMonitor.Staged.Interval) + d.Set("retry", healthMonitor.Staged.Retry) + d.Set("timeout", healthMonitor.Staged.Timeout) + d.Set("path", healthMonitor.Staged.Path) + d.Set("http_status_code", healthMonitor.Staged.HttpStatusCode) + } else if healthMonitor.ConfigurationStatus == "UPDATE_STAGED" { + d.Set("port", ternary(healthMonitor.Staged.Port == 0, healthMonitor.Port, healthMonitor.Staged.Port)) + d.Set("protocol", ternary(healthMonitor.Staged.Protocol == "", healthMonitor.Protocol, healthMonitor.Staged.Protocol)) + d.Set("interval", ternary(healthMonitor.Staged.Interval == 0, healthMonitor.Interval, healthMonitor.Staged.Interval)) + d.Set("retry", ternary(healthMonitor.Staged.Retry == 0, healthMonitor.Retry, healthMonitor.Staged.Retry)) + d.Set("timeout", ternary(healthMonitor.Staged.Timeout == 0, healthMonitor.Timeout, healthMonitor.Staged.Timeout)) + d.Set("path", ternary(healthMonitor.Staged.Path == "", healthMonitor.Path, healthMonitor.Staged.Path)) + d.Set("http_status_code", ternary(healthMonitor.Staged.HttpStatusCode == "", healthMonitor.HttpStatusCode, healthMonitor.Staged.HttpStatusCode)) + } else if healthMonitor.ConfigurationStatus == "DELETE_STAGED" { + d.SetId("") + return nil + } + + d.Set("name", healthMonitor.Name) + d.Set("description", healthMonitor.Description) + d.Set("tags", healthMonitor.Tags) + d.Set("load_balancer_id", healthMonitor.LoadBalancerID) + d.Set("tenant_id", healthMonitor.TenantID) + + return nil +} + +func resourceMLBHealthMonitorV1Update(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Start updating attributes of ECL managed load balancer health monitor ...") + + err = resourceMLBHealthMonitorV1UpdateAttributes(d, managedLoadBalancerClient) + if err != nil { + return fmt.Errorf("Error in updating attributes of ECL managed load balancer health monitor: %s", err) + } + + log.Printf("[DEBUG] Start updating configurations of ECL managed load balancer health monitor ...") + + err = resourceMLBHealthMonitorV1UpdateConfigurations(d, managedLoadBalancerClient) + if err != nil { + return fmt.Errorf("Error in updating configurations of ECL managed load balancer health monitor: %s", err) + } + + return resourceMLBHealthMonitorV1Read(d, meta) +} + +func resourceMLBHealthMonitorV1UpdateAttributes(d *schema.ResourceData, client *eclcloud.ServiceClient) error { + var isAttributesUpdated bool + var updateOpts health_monitors.UpdateOpts + + if d.HasChange("name") { + isAttributesUpdated = true + name := d.Get("name").(string) + updateOpts.Name = &name + } + + if d.HasChange("description") { + isAttributesUpdated = true + description := d.Get("description").(string) + updateOpts.Description = &description + } + + if d.HasChange("tags") { + isAttributesUpdated = true + tags := d.Get("tags").(map[string]interface{}) + updateOpts.Tags = &tags + } + + if isAttributesUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer health monitor attributes (%s) with options %+v", d.Id(), updateOpts) + + _, err := health_monitors.Update(client, d.Id(), updateOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer health monitor attributes (%s) with options %+v: %s", d.Id(), updateOpts, err) + } + } + + return nil +} + +func resourceMLBHealthMonitorV1UpdateConfigurations(d *schema.ResourceData, client *eclcloud.ServiceClient) error { + var isConfigurationsUpdated bool + + healthMonitor, err := resourceMLBHealthMonitorV1Show(d, client, false) + if err != nil { + return err + } + + if healthMonitor.ConfigurationStatus == "ACTIVE" { + var createStagedOpts health_monitors.CreateStagedOpts + + if d.HasChange("port") { + isConfigurationsUpdated = true + createStagedOpts.Port = d.Get("port").(int) + } + + if d.HasChange("protocol") { + isConfigurationsUpdated = true + createStagedOpts.Protocol = d.Get("protocol").(string) + } + + if d.HasChange("interval") { + isConfigurationsUpdated = true + createStagedOpts.Interval = d.Get("interval").(int) + } + + if d.HasChange("retry") { + isConfigurationsUpdated = true + createStagedOpts.Retry = d.Get("retry").(int) + } + + if d.HasChange("timeout") { + isConfigurationsUpdated = true + createStagedOpts.Timeout = d.Get("timeout").(int) + } + + if d.HasChange("path") { + isConfigurationsUpdated = true + createStagedOpts.Path = d.Get("path").(string) + } + + if d.HasChange("http_status_code") { + isConfigurationsUpdated = true + createStagedOpts.HttpStatusCode = d.Get("http_status_code").(string) + } + + if isConfigurationsUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer health monitor configurations (%s) with options %+v", d.Id(), createStagedOpts) + + _, err := health_monitors.CreateStaged(client, d.Id(), createStagedOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer health monitor configurations (%s) with options %+v: %s", d.Id(), createStagedOpts, err) + } + } + } else { + var updateStagedOpts health_monitors.UpdateStagedOpts + + if d.HasChange("port") { + isConfigurationsUpdated = true + port := d.Get("port").(int) + updateStagedOpts.Port = &port + } + + if d.HasChange("protocol") { + isConfigurationsUpdated = true + protocol := d.Get("protocol").(string) + updateStagedOpts.Protocol = &protocol + } + + if d.HasChange("interval") { + isConfigurationsUpdated = true + interval := d.Get("interval").(int) + updateStagedOpts.Interval = &interval + } + + if d.HasChange("retry") { + isConfigurationsUpdated = true + retry := d.Get("retry").(int) + updateStagedOpts.Retry = &retry + } + + if d.HasChange("timeout") { + isConfigurationsUpdated = true + timeout := d.Get("timeout").(int) + updateStagedOpts.Timeout = &timeout + } + + if d.HasChange("path") { + isConfigurationsUpdated = true + path := d.Get("path").(string) + updateStagedOpts.Path = &path + } + + if d.HasChange("http_status_code") { + isConfigurationsUpdated = true + httpStatusCode := d.Get("http_status_code").(string) + updateStagedOpts.HttpStatusCode = &httpStatusCode + } + + if isConfigurationsUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer health monitor configurations (%s) with options %+v", d.Id(), updateStagedOpts) + + _, err := health_monitors.UpdateStaged(client, d.Id(), updateStagedOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer health monitor configurations (%s) with options %+v: %s", d.Id(), updateStagedOpts, err) + } + } + } + + return nil +} + +func resourceMLBHealthMonitorV1Delete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Deleting ECL managed load balancer health monitor: %s", d.Id()) + + err = health_monitors.Delete(managedLoadBalancerClient, d.Id()).ExtractErr() + if err != nil { + return fmt.Errorf("Error deleting ECL managed load balancer health monitor: %s", err) + } + + return nil +} diff --git a/ecl/resource_ecl_mlb_health_monitor_v1_mock_test.go b/ecl/resource_ecl_mlb_health_monitor_v1_mock_test.go new file mode 100644 index 00000000..62e9d555 --- /dev/null +++ b/ecl/resource_ecl_mlb_health_monitor_v1_mock_test.go @@ -0,0 +1,565 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1HealthMonitorResource(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "health_monitors", "/v1.0/health_monitors", testMockMLBV1HealthMonitorsCreate) + mc.Register(t, "health_monitors", "/v1.0/health_monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1HealthMonitorsShowAfterCreate) + mc.Register(t, "health_monitors", "/v1.0/health_monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1HealthMonitorsUpdateAttributes) + mc.Register(t, "health_monitors", "/v1.0/health_monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1HealthMonitorsShowBeforeUpdateConfigurations) + mc.Register(t, "health_monitors", "/v1.0/health_monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08/staged", testMockMLBV1HealthMonitorsUpdateConfigurations) + mc.Register(t, "health_monitors", "/v1.0/health_monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1HealthMonitorsShowAfterUpdateConfigurations) + // Staged configurations of the load balancer and related resources are applied here + mc.Register(t, "health_monitors", "/v1.0/health_monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1HealthMonitorsShowAfterApplyConfigurations) + mc.Register(t, "health_monitors", "/v1.0/health_monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1HealthMonitorsShowBeforeCreateConfigurations) + mc.Register(t, "health_monitors", "/v1.0/health_monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08/staged", testMockMLBV1HealthMonitorsCreateConfigurations) + mc.Register(t, "health_monitors", "/v1.0/health_monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1HealthMonitorsShowAfterCreateConfigurations) + mc.Register(t, "health_monitors", "/v1.0/health_monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1HealthMonitorsDelete) + mc.Register(t, "health_monitors", "/v1.0/health_monitors/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1HealthMonitorsShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1HealthMonitor, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "name", "health_monitor"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "description", "description"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "tags.key", "value"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "port", "80"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "protocol", "http"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "interval", "5"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "retry", "3"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "timeout", "5"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "path", "/health"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "http_status_code", "200-299"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + ), + }, + { + Config: testAccMLBV1HealthMonitorUpdateBeforeApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "name", "health_monitor-update"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "description", "description-update"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "tags.key-update", "value-update"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "port", "0"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "protocol", "icmp"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "interval", "5"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "retry", "3"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "timeout", "5"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "path", ""), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "http_status_code", ""), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + ), + }, + { + Config: testAccMLBV1HealthMonitorUpdateAfterApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "name", "health_monitor-update"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "description", "description-update"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "tags.key-update", "value-update"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "port", "80"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "protocol", "http"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "interval", "5"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "retry", "3"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "timeout", "5"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "path", "/health"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "http_status_code", "200-299"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_health_monitor_v1.health_monitor", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + ), + }, + }, + }) +} + +var testAccMLBV1HealthMonitor = fmt.Sprintf(` +resource "ecl_mlb_health_monitor_v1" "health_monitor" { + name = "health_monitor" + description = "description" + tags = { + key = "value" + } + port = 80 + protocol = "http" + interval = 5 + retry = 3 + timeout = 5 + path = "/health" + http_status_code = "200-299" + load_balancer_id = "67fea379-cff0-4191-9175-de7d6941a040" +} +`) + +var testAccMLBV1HealthMonitorUpdateBeforeApplyConfigurations = fmt.Sprintf(` +resource "ecl_mlb_health_monitor_v1" "health_monitor" { + name = "health_monitor-update" + description = "description-update" + tags = { + key-update = "value-update" + } + port = 0 + protocol = "icmp" + interval = 5 + retry = 3 + timeout = 5 + path = "" + http_status_code = "" + load_balancer_id = "67fea379-cff0-4191-9175-de7d6941a040" +} +`) + +var testAccMLBV1HealthMonitorUpdateAfterApplyConfigurations = fmt.Sprintf(` +resource "ecl_mlb_health_monitor_v1" "health_monitor" { + name = "health_monitor-update" + description = "description-update" + tags = { + key-update = "value-update" + } + port = 80 + protocol = "http" + interval = 5 + retry = 3 + timeout = 5 + path = "/health" + http_status_code = "200-299" + load_balancer_id = "67fea379-cff0-4191-9175-de7d6941a040" +} +`) + +var testMockMLBV1HealthMonitorsCreate = fmt.Sprintf(` +request: + method: POST + body: > + {"health_monitor":{"description":"description","http_status_code":"200-299","interval":5,"load_balancer_id":"67fea379-cff0-4191-9175-de7d6941a040","name":"health_monitor","path":"/health","port":80,"protocol":"http","retry":3,"tags":{"key":"value"},"timeout":5}} +response: + code: 200 + body: > + { + "health_monitor": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "health_monitor", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "port": null, + "protocol": null, + "interval": null, + "retry": null, + "timeout": null, + "path": null, + "http_status_code": null + } + } +newStatus: Created +`) + +var testMockMLBV1HealthMonitorsShowAfterCreate = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "health_monitor": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "health_monitor", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "port": null, + "protocol": null, + "interval": null, + "retry": null, + "timeout": null, + "path": null, + "http_status_code": null, + "current": null, + "staged": { + "port": 80, + "protocol": "http", + "interval": 5, + "retry": 3, + "timeout": 5, + "path": "/health", + "http_status_code": "200-299" + } + } + } +expectedStatus: + - Created +`) + +var testMockMLBV1HealthMonitorsShowBeforeUpdateConfigurations = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "health_monitor": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "health_monitor-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "port": null, + "protocol": null, + "interval": null, + "retry": null, + "timeout": null, + "path": null, + "http_status_code": null + } + } +expectedStatus: + - AttributesUpdated +`) + +var testMockMLBV1HealthMonitorsShowAfterUpdateConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "health_monitor": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "health_monitor-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "port": null, + "protocol": null, + "interval": null, + "retry": null, + "timeout": null, + "path": null, + "http_status_code": null, + "current": null, + "staged": { + "port": 0, + "protocol": "icmp", + "interval": 5, + "retry": 3, + "timeout": 5, + "path": "", + "http_status_code": "" + } + } + } +expectedStatus: + - ConfigurationsUpdatedBeforeApply +newStatus: ConfigurationsApplied +`) + +var testMockMLBV1HealthMonitorsShowAfterApplyConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "health_monitor": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "health_monitor-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "ACTIVE", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "port": 0, + "protocol": "icmp", + "interval": 5, + "retry": 3, + "timeout": 5, + "path": "", + "http_status_code": "", + "current": { + "port": 0, + "protocol": "icmp", + "interval": 5, + "retry": 3, + "timeout": 5, + "path": "", + "http_status_code": "" + }, + "staged": null + } + } +expectedStatus: + - ConfigurationsApplied +`) + +var testMockMLBV1HealthMonitorsShowBeforeCreateConfigurations = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "health_monitor": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "health_monitor-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "ACTIVE", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "port": 0, + "protocol": "icmp", + "interval": 5, + "retry": 3, + "timeout": 5, + "path": "", + "http_status_code": "" + } + } +expectedStatus: + - ConfigurationsApplied +`) + +var testMockMLBV1HealthMonitorsShowAfterCreateConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "health_monitor": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "health_monitor-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "UPDATE_STAGED", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "port": 0, + "protocol": "icmp", + "interval": 5, + "retry": 3, + "timeout": 5, + "path": "", + "http_status_code": "", + "current": { + "port": 0, + "protocol": "icmp", + "interval": 5, + "retry": 3, + "timeout": 5, + "path": "", + "http_status_code": "" + }, + "staged": { + "port": 80, + "protocol": "http", + "interval": null, + "retry": null, + "timeout": null, + "path": "/health", + "http_status_code": "200-299" + } + } + } +expectedStatus: + - ConfigurationsUpdatedAfterApply +`) + +var testMockMLBV1HealthMonitorsShowAfterDelete = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "health_monitor": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "health_monitor-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "DELETE_STAGED", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "port": 0, + "protocol": "icmp", + "interval": 5, + "retry": 3, + "timeout": 5, + "path": "", + "http_status_code": "", + "current": { + "port": 0, + "protocol": "icmp", + "interval": 5, + "retry": 3, + "timeout": 5, + "path": "", + "http_status_code": "" + }, + "staged": null + } + } +expectedStatus: + - Deleted +`) + +var testMockMLBV1HealthMonitorsUpdateAttributes = fmt.Sprintf(` +request: + method: PATCH + body: > + {"health_monitor":{"description":"description-update","name":"health_monitor-update","tags":{"key-update":"value-update"}}} +response: + code: 200 + body: > + { + "health_monitor": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "health_monitor-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "port": null, + "protocol": null, + "interval": null, + "retry": null, + "timeout": null, + "path": null, + "http_status_code": null + } + } +expectedStatus: + - Created +newStatus: AttributesUpdated +`) + +var testMockMLBV1HealthMonitorsCreateConfigurations = fmt.Sprintf(` +request: + method: POST + body: > + {"health_monitor":{"http_status_code":"200-299","path":"/health","port":80,"protocol":"http"}} +response: + code: 200 + body: > + { + "health_monitor": { + "port": 80, + "protocol": "http", + "interval": null, + "retry": null, + "timeout": null, + "path": "/health", + "http_status_code": "200-299" + } + } +expectedStatus: + - ConfigurationsApplied +newStatus: ConfigurationsUpdatedAfterApply +`) + +var testMockMLBV1HealthMonitorsUpdateConfigurations = fmt.Sprintf(` +request: + method: PATCH + body: > + {"health_monitor":{"http_status_code":"","path":"","port":0,"protocol":"icmp"}} +response: + code: 200 + body: > + { + "health_monitor": { + "port": 0, + "protocol": "icmp", + "interval": 5, + "retry": 3, + "timeout": 5, + "path": "", + "http_status_code": "" + } + } +expectedStatus: + - AttributesUpdated +newStatus: ConfigurationsUpdatedBeforeApply +`) + +var testMockMLBV1HealthMonitorsDelete = fmt.Sprintf(` +request: + method: DELETE +response: + code: 204 +expectedStatus: + - Created + - ConfigurationsUpdatedAfterApply +newStatus: Deleted +`) diff --git a/ecl/resource_ecl_mlb_listener_v1.go b/ecl/resource_ecl_mlb_listener_v1.go new file mode 100644 index 00000000..57800b35 --- /dev/null +++ b/ecl/resource_ecl_mlb_listener_v1.go @@ -0,0 +1,287 @@ +package ecl + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/nttcom/eclcloud/v2" + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners" +) + +func resourceMLBListenerV1() *schema.Resource { + var result *schema.Resource + + result = &schema.Resource{ + Create: resourceMLBListenerV1Create, + Read: resourceMLBListenerV1Read, + Update: resourceMLBListenerV1Update, + Delete: resourceMLBListenerV1Delete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "tags": &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + }, + "ip_address": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "port": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + }, + "protocol": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "load_balancer_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "tenant_id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + }, + } + + return result +} + +func resourceMLBListenerV1Create(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + createOpts := listeners.CreateOpts{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + Tags: d.Get("tags").(map[string]interface{}), + IPAddress: d.Get("ip_address").(string), + Port: d.Get("port").(int), + Protocol: d.Get("protocol").(string), + LoadBalancerID: d.Get("load_balancer_id").(string), + } + + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Creating ECL managed load balancer listener with options %+v", createOpts) + + listener, err := listeners.Create(managedLoadBalancerClient, createOpts).Extract() + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer listener with options %+v: %s", createOpts, err) + } + + d.SetId(listener.ID) + log.Printf("[INFO] ECL managed load balancer listener ID: %s", listener.ID) + + return resourceMLBListenerV1Read(d, meta) +} + +func resourceMLBListenerV1Show(d *schema.ResourceData, client *eclcloud.ServiceClient, changes bool) (*listeners.Listener, error) { + var listener listeners.Listener + + showOpts := listeners.ShowOpts{Changes: changes} + err := listeners.Show(client, d.Id(), showOpts).ExtractInto(&listener) + if err != nil { + return nil, fmt.Errorf("Unable to retrieve ECL managed load balancer listener (%s): %s", d.Id(), err) + } + + return &listener, nil +} + +func resourceMLBListenerV1Read(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + listener, err := resourceMLBListenerV1Show(d, managedLoadBalancerClient, true) + if err != nil { + return CheckDeleted(d, err, "listener") + } + + log.Printf("[DEBUG] Retrieved ECL managed load balancer listener (%s): %+v", d.Id(), listener) + + if listener.ConfigurationStatus == "ACTIVE" { + d.Set("ip_address", listener.IPAddress) + d.Set("port", listener.Port) + d.Set("protocol", listener.Protocol) + } else if listener.ConfigurationStatus == "CREATE_STAGED" { + d.Set("ip_address", listener.Staged.IPAddress) + d.Set("port", listener.Staged.Port) + d.Set("protocol", listener.Staged.Protocol) + } else if listener.ConfigurationStatus == "UPDATE_STAGED" { + d.Set("ip_address", ternary(listener.Staged.IPAddress == "", listener.IPAddress, listener.Staged.IPAddress)) + d.Set("port", ternary(listener.Staged.Port == 0, listener.Port, listener.Staged.Port)) + d.Set("protocol", ternary(listener.Staged.Protocol == "", listener.Protocol, listener.Staged.Protocol)) + } else if listener.ConfigurationStatus == "DELETE_STAGED" { + d.SetId("") + return nil + } + + d.Set("name", listener.Name) + d.Set("description", listener.Description) + d.Set("tags", listener.Tags) + d.Set("load_balancer_id", listener.LoadBalancerID) + d.Set("tenant_id", listener.TenantID) + + return nil +} + +func resourceMLBListenerV1Update(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Start updating attributes of ECL managed load balancer listener ...") + + err = resourceMLBListenerV1UpdateAttributes(d, managedLoadBalancerClient) + if err != nil { + return fmt.Errorf("Error in updating attributes of ECL managed load balancer listener: %s", err) + } + + log.Printf("[DEBUG] Start updating configurations of ECL managed load balancer listener ...") + + err = resourceMLBListenerV1UpdateConfigurations(d, managedLoadBalancerClient) + if err != nil { + return fmt.Errorf("Error in updating configurations of ECL managed load balancer listener: %s", err) + } + + return resourceMLBListenerV1Read(d, meta) +} + +func resourceMLBListenerV1UpdateAttributes(d *schema.ResourceData, client *eclcloud.ServiceClient) error { + var isAttributesUpdated bool + var updateOpts listeners.UpdateOpts + + if d.HasChange("name") { + isAttributesUpdated = true + name := d.Get("name").(string) + updateOpts.Name = &name + } + + if d.HasChange("description") { + isAttributesUpdated = true + description := d.Get("description").(string) + updateOpts.Description = &description + } + + if d.HasChange("tags") { + isAttributesUpdated = true + tags := d.Get("tags").(map[string]interface{}) + updateOpts.Tags = &tags + } + + if isAttributesUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer listener attributes (%s) with options %+v", d.Id(), updateOpts) + + _, err := listeners.Update(client, d.Id(), updateOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer listener attributes (%s) with options %+v: %s", d.Id(), updateOpts, err) + } + } + + return nil +} + +func resourceMLBListenerV1UpdateConfigurations(d *schema.ResourceData, client *eclcloud.ServiceClient) error { + var isConfigurationsUpdated bool + + listener, err := resourceMLBListenerV1Show(d, client, false) + if err != nil { + return err + } + + if listener.ConfigurationStatus == "ACTIVE" { + var createStagedOpts listeners.CreateStagedOpts + + if d.HasChange("ip_address") { + isConfigurationsUpdated = true + createStagedOpts.IPAddress = d.Get("ip_address").(string) + } + + if d.HasChange("port") { + isConfigurationsUpdated = true + createStagedOpts.Port = d.Get("port").(int) + } + + if d.HasChange("protocol") { + isConfigurationsUpdated = true + createStagedOpts.Protocol = d.Get("protocol").(string) + } + + if isConfigurationsUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer listener configurations (%s) with options %+v", d.Id(), createStagedOpts) + + _, err := listeners.CreateStaged(client, d.Id(), createStagedOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer listener configurations (%s) with options %+v: %s", d.Id(), createStagedOpts, err) + } + } + } else { + var updateStagedOpts listeners.UpdateStagedOpts + + if d.HasChange("ip_address") { + isConfigurationsUpdated = true + ipAddress := d.Get("ip_address").(string) + updateStagedOpts.IPAddress = &ipAddress + } + + if d.HasChange("port") { + isConfigurationsUpdated = true + port := d.Get("port").(int) + updateStagedOpts.Port = &port + } + + if d.HasChange("protocol") { + isConfigurationsUpdated = true + protocol := d.Get("protocol").(string) + updateStagedOpts.Protocol = &protocol + } + + if isConfigurationsUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer listener configurations (%s) with options %+v", d.Id(), updateStagedOpts) + + _, err := listeners.UpdateStaged(client, d.Id(), updateStagedOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer listener configurations (%s) with options %+v: %s", d.Id(), updateStagedOpts, err) + } + } + } + + return nil +} + +func resourceMLBListenerV1Delete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Deleting ECL managed load balancer listener: %s", d.Id()) + + err = listeners.Delete(managedLoadBalancerClient, d.Id()).ExtractErr() + if err != nil { + return fmt.Errorf("Error deleting ECL managed load balancer listener: %s", err) + } + + return nil +} diff --git a/ecl/resource_ecl_mlb_listener_v1_mock_test.go b/ecl/resource_ecl_mlb_listener_v1_mock_test.go new file mode 100644 index 00000000..a26db67c --- /dev/null +++ b/ecl/resource_ecl_mlb_listener_v1_mock_test.go @@ -0,0 +1,473 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1ListenerResource(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "listeners", "/v1.0/listeners", testMockMLBV1ListenersCreate) + mc.Register(t, "listeners", "/v1.0/listeners/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1ListenersShowAfterCreate) + mc.Register(t, "listeners", "/v1.0/listeners/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1ListenersUpdateAttributes) + mc.Register(t, "listeners", "/v1.0/listeners/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1ListenersShowBeforeUpdateConfigurations) + mc.Register(t, "listeners", "/v1.0/listeners/497f6eca-6276-4993-bfeb-53cbbbba6f08/staged", testMockMLBV1ListenersUpdateConfigurations) + mc.Register(t, "listeners", "/v1.0/listeners/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1ListenersShowAfterUpdateConfigurations) + // Staged configurations of the load balancer and related resources are applied here + mc.Register(t, "listeners", "/v1.0/listeners/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1ListenersShowAfterApplyConfigurations) + mc.Register(t, "listeners", "/v1.0/listeners/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1ListenersShowBeforeCreateConfigurations) + mc.Register(t, "listeners", "/v1.0/listeners/497f6eca-6276-4993-bfeb-53cbbbba6f08/staged", testMockMLBV1ListenersCreateConfigurations) + mc.Register(t, "listeners", "/v1.0/listeners/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1ListenersShowAfterCreateConfigurations) + mc.Register(t, "listeners", "/v1.0/listeners/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1ListenersDelete) + mc.Register(t, "listeners", "/v1.0/listeners/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1ListenersShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1Listener, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "name", "listener"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "description", "description"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "tags.key", "value"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "ip_address", "10.0.0.1"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "port", "80"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "protocol", "http"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + ), + }, + { + Config: testAccMLBV1ListenerUpdateBeforeApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "name", "listener-update"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "description", "description-update"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "tags.key-update", "value-update"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "ip_address", "10.0.0.1"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "port", "443"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "protocol", "https"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + ), + }, + { + Config: testAccMLBV1ListenerUpdateAfterApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "name", "listener-update"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "description", "description-update"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "tags.key-update", "value-update"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "ip_address", "10.0.0.1"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "port", "80"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "protocol", "http"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_listener_v1.listener", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + ), + }, + }, + }) +} + +var testAccMLBV1Listener = fmt.Sprintf(` +resource "ecl_mlb_listener_v1" "listener" { + name = "listener" + description = "description" + tags = { + key = "value" + } + ip_address = "10.0.0.1" + port = 80 + protocol = "http" + load_balancer_id = "67fea379-cff0-4191-9175-de7d6941a040" +} +`) + +var testAccMLBV1ListenerUpdateBeforeApplyConfigurations = fmt.Sprintf(` +resource "ecl_mlb_listener_v1" "listener" { + name = "listener-update" + description = "description-update" + tags = { + key-update = "value-update" + } + ip_address = "10.0.0.1" + port = 443 + protocol = "https" + load_balancer_id = "67fea379-cff0-4191-9175-de7d6941a040" +} +`) + +var testAccMLBV1ListenerUpdateAfterApplyConfigurations = fmt.Sprintf(` +resource "ecl_mlb_listener_v1" "listener" { + name = "listener-update" + description = "description-update" + tags = { + key-update = "value-update" + } + ip_address = "10.0.0.1" + port = 80 + protocol = "http" + load_balancer_id = "67fea379-cff0-4191-9175-de7d6941a040" +} +`) + +var testMockMLBV1ListenersCreate = fmt.Sprintf(` +request: + method: POST + body: > + {"listener":{"description":"description","ip_address":"10.0.0.1","load_balancer_id":"67fea379-cff0-4191-9175-de7d6941a040","name":"listener","port":80,"protocol":"http","tags":{"key":"value"}}} +response: + code: 200 + body: > + { + "listener": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "listener", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "ip_address": null, + "port": null, + "protocol": null + } + } +newStatus: Created +`) + +var testMockMLBV1ListenersShowAfterCreate = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "listener": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "listener", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "ip_address": null, + "port": null, + "protocol": null, + "current": null, + "staged": { + "ip_address": "10.0.0.1", + "port": 80, + "protocol": "http" + } + } + } +expectedStatus: + - Created +`) + +var testMockMLBV1ListenersShowBeforeUpdateConfigurations = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "listener": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "listener-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "ip_address": null, + "port": null, + "protocol": null + } + } +expectedStatus: + - AttributesUpdated +`) + +var testMockMLBV1ListenersShowAfterUpdateConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "listener": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "listener-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "ip_address": null, + "port": null, + "protocol": null, + "current": null, + "staged": { + "ip_address": "10.0.0.1", + "port": 443, + "protocol": "https" + } + } + } +expectedStatus: + - ConfigurationsUpdatedBeforeApply +newStatus: ConfigurationsApplied +`) + +var testMockMLBV1ListenersShowAfterApplyConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "listener": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "listener-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "ACTIVE", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "ip_address": "10.0.0.1", + "port": 443, + "protocol": "https", + "current": { + "ip_address": "10.0.0.1", + "port": 443, + "protocol": "https" + }, + "staged": null + } + } +expectedStatus: + - ConfigurationsApplied +`) + +var testMockMLBV1ListenersShowBeforeCreateConfigurations = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "listener": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "listener-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "ACTIVE", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "ip_address": "10.0.0.1", + "port": 443, + "protocol": "https" + } + } +expectedStatus: + - ConfigurationsApplied +`) + +var testMockMLBV1ListenersShowAfterCreateConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "listener": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "listener-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "UPDATE_STAGED", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "ip_address": "10.0.0.1", + "port": 443, + "protocol": "https", + "current": { + "ip_address": "10.0.0.1", + "port": 443, + "protocol": "https" + }, + "staged": { + "ip_address": null, + "port": 80, + "protocol": "http" + } + } + } +expectedStatus: + - ConfigurationsUpdatedAfterApply +`) + +var testMockMLBV1ListenersShowAfterDelete = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "listener": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "listener-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "DELETE_STAGED", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "ip_address": "10.0.0.1", + "port": 443, + "protocol": "https", + "current": { + "ip_address": "10.0.0.1", + "port": 443, + "protocol": "https" + }, + "staged": null + } + } +expectedStatus: + - Deleted +`) + +var testMockMLBV1ListenersUpdateAttributes = fmt.Sprintf(` +request: + method: PATCH + body: > + {"listener":{"description":"description-update","name":"listener-update","tags":{"key-update":"value-update"}}} +response: + code: 200 + body: > + { + "listener": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "listener-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "ip_address": null, + "port": null, + "protocol": null + } + } +expectedStatus: + - Created +newStatus: AttributesUpdated +`) + +var testMockMLBV1ListenersCreateConfigurations = fmt.Sprintf(` +request: + method: POST + body: > + {"listener":{"port":80,"protocol":"http"}} +response: + code: 200 + body: > + { + "listener": { + "ip_address": null, + "port": 80, + "protocol": "http" + } + } +expectedStatus: + - ConfigurationsApplied +newStatus: ConfigurationsUpdatedAfterApply +`) + +var testMockMLBV1ListenersUpdateConfigurations = fmt.Sprintf(` +request: + method: PATCH + body: > + {"listener":{"port":443,"protocol":"https"}} +response: + code: 200 + body: > + { + "listener": { + "ip_address": "10.0.0.1", + "port": 443, + "protocol": "https" + } + } +expectedStatus: + - AttributesUpdated +newStatus: ConfigurationsUpdatedBeforeApply +`) + +var testMockMLBV1ListenersDelete = fmt.Sprintf(` +request: + method: DELETE +response: + code: 204 +expectedStatus: + - Created + - ConfigurationsUpdatedAfterApply +newStatus: Deleted +`) diff --git a/ecl/resource_ecl_mlb_load_balancer_action_v1.go b/ecl/resource_ecl_mlb_load_balancer_action_v1.go new file mode 100644 index 00000000..6abae666 --- /dev/null +++ b/ecl/resource_ecl_mlb_load_balancer_action_v1.go @@ -0,0 +1,355 @@ +package ecl + +import ( + "fmt" + "log" + "time" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + "github.com/nttcom/eclcloud/v2" + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors" + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners" + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers" + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies" + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes" + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules" + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates" + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups" +) + +func resourceMLBLoadBalancerActionV1() *schema.Resource { + var result *schema.Resource + + result = &schema.Resource{ + Create: resourceMLBLoadBalancerActionV1Perform, + Read: resourceMLBLoadBalancerActionV1Read, + Update: resourceMLBLoadBalancerActionV1Perform, + Delete: resourceMLBLoadBalancerActionV1Delete, + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(1 * time.Hour), + Update: schema.DefaultTimeout(1 * time.Hour), + }, + Schema: map[string]*schema.Schema{ + "load_balancer_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "apply_configurations": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + }, + "system_update": &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "system_update_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + }, + } + + return result +} + +func resourceMLBLoadBalancerActionV1CheckApplyConfigurationsRequired(d *schema.ResourceData, client *eclcloud.ServiceClient) (bool, error) { + loadBalancer, err := resourceMLBLoadBalancerActionV1ShowLoadBalancer(d, client) + if err != nil { + return false, err + } + + if loadBalancer.ConfigurationStatus != "ACTIVE" { + log.Printf("[DEBUG] configuration_status (%s) of load balancer (%s) is not ACTIVE", loadBalancer.ConfigurationStatus, loadBalancer.ID) + return true, nil + } + + healthMonitors, err := resourceMLBLoadBalancerActionV1ListHealthMonitors(d, client) + if err != nil { + return false, err + } + + for _, healthMonitor := range *healthMonitors { + if healthMonitor.ConfigurationStatus != "ACTIVE" { + log.Printf("[DEBUG] configuration_status (%s) of health monitor (%s) is not ACTIVE", healthMonitor.ConfigurationStatus, healthMonitor.ID) + return true, nil + } + } + + listeners, err := resourceMLBLoadBalancerActionV1ListListeners(d, client) + if err != nil { + return false, err + } + + for _, listener := range *listeners { + if listener.ConfigurationStatus != "ACTIVE" { + log.Printf("[DEBUG] configuration_status (%s) of listener (%s) is not ACTIVE", listener.ConfigurationStatus, listener.ID) + return true, nil + } + } + + policies, err := resourceMLBLoadBalancerActionV1ListPolicies(d, client) + if err != nil { + return false, err + } + + for _, policy := range *policies { + if policy.ConfigurationStatus != "ACTIVE" { + log.Printf("[DEBUG] configuration_status (%s) of policy (%s) is not ACTIVE", policy.ConfigurationStatus, policy.ID) + return true, nil + } + } + + routes, err := resourceMLBLoadBalancerActionV1ListRoutes(d, client) + if err != nil { + return false, err + } + + for _, route := range *routes { + if route.ConfigurationStatus != "ACTIVE" { + log.Printf("[DEBUG] configuration_status (%s) of route (%s) is not ACTIVE", route.ConfigurationStatus, route.ID) + return true, nil + } + } + + rules, err := resourceMLBLoadBalancerActionV1ListRules(d, client) + if err != nil { + return false, err + } + + for _, rule := range *rules { + if rule.ConfigurationStatus != "ACTIVE" { + log.Printf("[DEBUG] configuration_status (%s) of rule (%s) is not ACTIVE", rule.ConfigurationStatus, rule.ID) + return true, nil + } + } + + targetGroups, err := resourceMLBLoadBalancerActionV1ListTargetGroups(d, client) + if err != nil { + return false, err + } + + for _, targetGroup := range *targetGroups { + if targetGroup.ConfigurationStatus != "ACTIVE" { + log.Printf("[DEBUG] configuration_status (%s) of target group (%s) is not ACTIVE", targetGroup.ConfigurationStatus, targetGroup.ID) + return true, nil + } + } + + return false, nil +} + +func resourceMLBLoadBalancerActionV1CheckSystemUpdateRequired(d *schema.ResourceData, client *eclcloud.ServiceClient) (bool, error) { + var systemUpdate system_updates.SystemUpdate + + loadBalancer, err := resourceMLBLoadBalancerActionV1ShowLoadBalancer(d, client) + if err != nil { + return false, err + } + + systemUpdateID := d.Get("system_update").(map[string]interface{})["system_update_id"].(string) + err = system_updates.Show(client, systemUpdateID).ExtractInto(&systemUpdate) + if err != nil { + return false, fmt.Errorf("Unable to retrieve ECL managed load balancer system update (%s): %s", systemUpdateID, err) + } + + if loadBalancer.Revision == systemUpdate.NextRevision { + log.Printf("[DEBUG] next_revision (%d) of system update (%s) matches with revision (%d) of load balancer (%s)", systemUpdate.NextRevision, systemUpdate.ID, loadBalancer.Revision, loadBalancer.ID) + return false, nil + } else if loadBalancer.Revision != systemUpdate.CurrentRevision { + return false, fmt.Errorf("current_revision (%d) of system update (%s) does not match with revision (%d) of load balancer (%s)", systemUpdate.CurrentRevision, systemUpdate.ID, loadBalancer.Revision, loadBalancer.ID) + } + + return true, nil +} + +func resourceMLBLoadBalancerActionV1Perform(d *schema.ResourceData, meta interface{}) error { + var isApplyConfigurationsRequired, isSystemUpdateRequired bool + + loadBalancerID := d.Get("load_balancer_id").(string) + + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + actionOpts := load_balancers.ActionOpts{} + if d.Get("apply_configurations").(bool) { + isApplyConfigurationsRequired, err = resourceMLBLoadBalancerActionV1CheckApplyConfigurationsRequired(d, managedLoadBalancerClient) + if err != nil { + return err + } + if isApplyConfigurationsRequired { + actionOpts.ApplyConfigurations = true + } + } + if len(d.Get("system_update").(map[string]interface{})) != 0 { + isSystemUpdateRequired, err = resourceMLBLoadBalancerActionV1CheckSystemUpdateRequired(d, managedLoadBalancerClient) + if err != nil { + return err + } + if isSystemUpdateRequired { + systemUpdate := load_balancers.ActionOptsSystemUpdate{ + SystemUpdateID: d.Get("system_update").(map[string]interface{})["system_update_id"].(string), + } + actionOpts.SystemUpdate = &systemUpdate + } + } + + if isApplyConfigurationsRequired || isSystemUpdateRequired { + log.Printf("[DEBUG] Performing action on ECL managed load balancer load balancer (%s) with options %+v", loadBalancerID, actionOpts) + + err = load_balancers.Action(managedLoadBalancerClient, loadBalancerID, actionOpts).ExtractErr() + if err != nil { + return fmt.Errorf("Error performing action on ECL managed load balancer load balancer (%s) with options %+v: %s", loadBalancerID, actionOpts, err) + } + + stateChangeConf := &resource.StateChangeConf{ + Pending: []string{"PROCESSING"}, + Target: []string{"COMPLETE"}, + Refresh: resourceMLBLoadBalancerActionV1WaitForComplete(managedLoadBalancerClient, loadBalancerID), + Timeout: d.Timeout(schema.TimeoutCreate), + Delay: 5 * time.Second, + PollInterval: 30 * time.Second, + MinTimeout: 10 * time.Second, + } + + _, err = stateChangeConf.WaitForState() + if err != nil { + return fmt.Errorf("Error waiting for ECL managed load balancer load balancer (%s) to become COMPLETE: %s", loadBalancerID, err) + } + } else { + log.Printf("[DEBUG] No action required on ECL managed load balancer load balancer (%s)", loadBalancerID) + } + + d.SetId(loadBalancerID) + + return resourceMLBLoadBalancerActionV1Read(d, meta) +} + +func resourceMLBLoadBalancerActionV1WaitForComplete(client *eclcloud.ServiceClient, loadBalancerID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + loadBalancer, err := load_balancers.Show(client, loadBalancerID, load_balancers.ShowOpts{}).Extract() + if err != nil { + return nil, "", err + } + + return loadBalancer, loadBalancer.OperationStatus, nil + } +} + +func resourceMLBLoadBalancerActionV1ShowLoadBalancer(d *schema.ResourceData, client *eclcloud.ServiceClient) (*load_balancers.LoadBalancer, error) { + var loadBalancer load_balancers.LoadBalancer + + loadBalancerID := d.Get("load_balancer_id").(string) + err := load_balancers.Show(client, loadBalancerID, load_balancers.ShowOpts{}).ExtractInto(&loadBalancer) + if err != nil { + return nil, fmt.Errorf("Unable to retrieve ECL managed load balancer load balancer (%s): %s", loadBalancerID, err) + } + + return &loadBalancer, nil +} + +func resourceMLBLoadBalancerActionV1ListHealthMonitors(d *schema.ResourceData, client *eclcloud.ServiceClient) (*[]health_monitors.HealthMonitor, error) { + listOpts := health_monitors.ListOpts{LoadBalancerID: d.Get("load_balancer_id").(string)} + pages, err := health_monitors.List(client, listOpts).AllPages() + if err != nil { + return nil, err + } + + healthMonitors, err := health_monitors.ExtractHealthMonitors(pages) + if err != nil { + return nil, fmt.Errorf("Unable to retrieve ECL managed load balancer health monitors with options %+v: %s", listOpts, err) + } + + return &healthMonitors, nil +} + +func resourceMLBLoadBalancerActionV1ListListeners(d *schema.ResourceData, client *eclcloud.ServiceClient) (*[]listeners.Listener, error) { + listOpts := listeners.ListOpts{LoadBalancerID: d.Get("load_balancer_id").(string)} + pages, err := listeners.List(client, listOpts).AllPages() + if err != nil { + return nil, err + } + + listeners, err := listeners.ExtractListeners(pages) + if err != nil { + return nil, fmt.Errorf("Unable to retrieve ECL managed load balancer listeners with options %+v: %s", listOpts, err) + } + + return &listeners, nil +} + +func resourceMLBLoadBalancerActionV1ListPolicies(d *schema.ResourceData, client *eclcloud.ServiceClient) (*[]policies.Policy, error) { + listOpts := policies.ListOpts{LoadBalancerID: d.Get("load_balancer_id").(string)} + pages, err := policies.List(client, listOpts).AllPages() + if err != nil { + return nil, err + } + + policies, err := policies.ExtractPolicies(pages) + if err != nil { + return nil, fmt.Errorf("Unable to retrieve ECL managed load balancer policies with options %+v: %s", listOpts, err) + } + + return &policies, nil +} + +func resourceMLBLoadBalancerActionV1ListRoutes(d *schema.ResourceData, client *eclcloud.ServiceClient) (*[]routes.Route, error) { + listOpts := routes.ListOpts{LoadBalancerID: d.Get("load_balancer_id").(string)} + pages, err := routes.List(client, listOpts).AllPages() + if err != nil { + return nil, err + } + + routes, err := routes.ExtractRoutes(pages) + if err != nil { + return nil, fmt.Errorf("Unable to retrieve ECL managed load balancer routes with options %+v: %s", listOpts, err) + } + + return &routes, nil +} + +func resourceMLBLoadBalancerActionV1ListRules(d *schema.ResourceData, client *eclcloud.ServiceClient) (*[]rules.Rule, error) { + listOpts := rules.ListOpts{LoadBalancerID: d.Get("load_balancer_id").(string)} + pages, err := rules.List(client, listOpts).AllPages() + if err != nil { + return nil, err + } + + rules, err := rules.ExtractRules(pages) + if err != nil { + return nil, fmt.Errorf("Unable to retrieve ECL managed load balancer rules with options %+v: %s", listOpts, err) + } + + return &rules, nil +} + +func resourceMLBLoadBalancerActionV1ListTargetGroups(d *schema.ResourceData, client *eclcloud.ServiceClient) (*[]target_groups.TargetGroup, error) { + listOpts := target_groups.ListOpts{LoadBalancerID: d.Get("load_balancer_id").(string)} + pages, err := target_groups.List(client, listOpts).AllPages() + if err != nil { + return nil, err + } + + targetGroups, err := target_groups.ExtractTargetGroups(pages) + if err != nil { + return nil, fmt.Errorf("Unable to retrieve ECL managed load balancer target groups with options %+v: %s", listOpts, err) + } + + return &targetGroups, nil +} + +func resourceMLBLoadBalancerActionV1Read(d *schema.ResourceData, meta interface{}) error { + return nil +} + +func resourceMLBLoadBalancerActionV1Delete(d *schema.ResourceData, meta interface{}) error { + return nil +} diff --git a/ecl/resource_ecl_mlb_load_balancer_action_v1_mock_test.go b/ecl/resource_ecl_mlb_load_balancer_action_v1_mock_test.go new file mode 100644 index 00000000..d6b0c790 --- /dev/null +++ b/ecl/resource_ecl_mlb_load_balancer_action_v1_mock_test.go @@ -0,0 +1,511 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1LoadBalancerActionResource_ApplyConfigurations(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowBeforeActionCreateStaged) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08/action", testMockMLBV1LoadBalancersActionApplyConfigurations) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowAfterActionProcessing) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowAfterActionCompleted) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1LoadBalancerActionApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "load_balancer_id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "apply_configurations", "true"), + resource.TestCheckNoResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "system_update"), + ), + }, + }, + }) +} + +func TestMockedAccMLBV1LoadBalancerActionResource_SystemUpdate(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowBeforeActionCreateStaged) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08/action", testMockMLBV1LoadBalancersActionSystemUpdate) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowAfterActionProcessing) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowAfterActionCompleted) + mc.Register(t, "system_updates", "/v1.0/system_updates/31746df7-92f9-4b5e-ad05-59f6684a54eb", testMockMLBV1SystemUpdatesShow) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1LoadBalancerActionSystemUpdate, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "load_balancer_id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "system_update.system_update_id", "31746df7-92f9-4b5e-ad05-59f6684a54eb"), + resource.TestCheckNoResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "apply_configurations"), + ), + }, + }, + }) +} + +func TestMockedAccMLBV1LoadBalancerActionResource_ApplyConfigurationsAndSystemUpdate(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowBeforeActionCreateStaged) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08/action", testMockMLBV1LoadBalancersActionApplyConfigurationsAndSystemUpdate) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowAfterActionProcessing) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowAfterActionCompleted) + mc.Register(t, "system_updates", "/v1.0/system_updates/31746df7-92f9-4b5e-ad05-59f6684a54eb", testMockMLBV1SystemUpdatesShow) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1LoadBalancerActionApplyConfigurationsAndSystemUpdate, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "load_balancer_id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "apply_configurations", "true"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "system_update.system_update_id", "31746df7-92f9-4b5e-ad05-59f6684a54eb"), + ), + }, + }, + }) +} + +func TestMockedAccMLBV1LoadBalancerActionResource_NoApplyConfigurations(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowBeforeActionActive) + mc.Register(t, "health_monitors", "/v1.0/health_monitors", testMockMLBV1HealthMonitorsListEmpty) + mc.Register(t, "listeners", "/v1.0/listeners", testMockMLBV1ListenersListEmpty) + mc.Register(t, "policies", "/v1.0/policies", testMockMLBV1PoliciesListEmpty) + mc.Register(t, "routes", "/v1.0/routes", testMockMLBV1RoutesListEmpty) + mc.Register(t, "rules", "/v1.0/rules", testMockMLBV1RulesListEmpty) + mc.Register(t, "target_groups", "/v1.0/target_groups", testMockMLBV1TargetGroupsListEmpty) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1LoadBalancerActionApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "load_balancer_id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "apply_configurations", "true"), + resource.TestCheckNoResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "system_update"), + ), + }, + }, + }) +} + +func TestMockedAccMLBV1LoadBalancerActionResource_NoSystemUpdate(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowBeforeActionActive) + mc.Register(t, "system_updates", "/v1.0/system_updates/31746df7-92f9-4b5e-ad05-59f6684a54eb", testMockMLBV1SystemUpdatesShow) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1LoadBalancerActionSystemUpdate, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "load_balancer_id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "system_update.system_update_id", "31746df7-92f9-4b5e-ad05-59f6684a54eb"), + resource.TestCheckNoResourceAttr("ecl_mlb_load_balancer_action_v1.load_balancer_action", "apply_configurations"), + ), + }, + }, + }) +} + +var testAccMLBV1LoadBalancerActionApplyConfigurations = fmt.Sprintf(` +resource "ecl_mlb_load_balancer_action_v1" "load_balancer_action" { + load_balancer_id = "497f6eca-6276-4993-bfeb-53cbbbba6f08" + apply_configurations = true +} +`) + +var testAccMLBV1LoadBalancerActionSystemUpdate = fmt.Sprintf(` +resource "ecl_mlb_load_balancer_action_v1" "load_balancer_action" { + load_balancer_id = "497f6eca-6276-4993-bfeb-53cbbbba6f08" + system_update = { + system_update_id = "31746df7-92f9-4b5e-ad05-59f6684a54eb" + } +} +`) + +var testAccMLBV1LoadBalancerActionApplyConfigurationsAndSystemUpdate = fmt.Sprintf(` +resource "ecl_mlb_load_balancer_action_v1" "load_balancer_action" { + load_balancer_id = "497f6eca-6276-4993-bfeb-53cbbbba6f08" + apply_configurations = true + system_update = { + system_update_id = "31746df7-92f9-4b5e-ad05-59f6684a54eb" + } +} +`) + +var testMockMLBV1LoadBalancersShowBeforeActionCreateStaged = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "load_balancer": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "load_balancer", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "monitoring_status": "INITIAL", + "operation_status": "NONE", + "primary_availability_zone": null, + "secondary_availability_zone": null, + "active_availability_zone": "UNDEFINED", + "revision": 1, + "plan_id": "00713021-9aea-41da-9a88-87760c08fa72", + "plan_name": "50M_HA_4IF", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "syslog_servers": null, + "interfaces": null + } + } +expectedStatus: + - ~ +`) + +var testMockMLBV1LoadBalancersShowBeforeActionActive = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "load_balancer": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "load_balancer", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "ACTIVE", + "monitoring_status": "ACTIVE", + "operation_status": "COMPLETE", + "primary_availability_zone": "zone1_groupa", + "secondary_availability_zone": "zone1_groupb", + "active_availability_zone": "zone1_groupa", + "revision": 2, + "plan_id": "00713021-9aea-41da-9a88-87760c08fa72", + "plan_name": "50M_HA_4IF", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "syslog_servers": [ + { + "ip_address": "192.168.0.6", + "port": 514, + "protocol": "udp" + } + ], + "interfaces": [ + { + "network_id": "d6797cf4-42b9-4cad-8591-9dd91c3f0fc3", + "virtual_ip_address": "192.168.0.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.0.2" + }, + { + "ip_address": "192.168.0.3" + }, + { + "ip_address": "192.168.0.4" + }, + { + "ip_address": "192.168.0.5" + } + ] + } + ] + } + } +expectedStatus: + - ~ +`) + +var testMockMLBV1LoadBalancersShowAfterActionProcessing = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "load_balancer": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "load_balancer", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "monitoring_status": "INITIAL", + "operation_status": "PROCESSING", + "primary_availability_zone": null, + "secondary_availability_zone": null, + "active_availability_zone": "UNDEFINED", + "revision": 1, + "plan_id": "00713021-9aea-41da-9a88-87760c08fa72", + "plan_name": "50M_HA_4IF", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "syslog_servers": null, + "interfaces": null + } + } +expectedStatus: + - Performed +counter: + max: 3 +`) + +var testMockMLBV1LoadBalancersShowAfterActionCompleted = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "load_balancer": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "load_balancer", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "ACTIVE", + "monitoring_status": "ACTIVE", + "operation_status": "COMPLETE", + "primary_availability_zone": "zone1_groupa", + "secondary_availability_zone": "zone1_groupb", + "active_availability_zone": "zone1_groupa", + "revision": 2, + "plan_id": "00713021-9aea-41da-9a88-87760c08fa72", + "plan_name": "50M_HA_4IF", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "syslog_servers": [ + { + "ip_address": "192.168.0.6", + "port": 514, + "protocol": "udp" + } + ], + "interfaces": [ + { + "network_id": "d6797cf4-42b9-4cad-8591-9dd91c3f0fc3", + "virtual_ip_address": "192.168.0.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.0.2" + }, + { + "ip_address": "192.168.0.3" + }, + { + "ip_address": "192.168.0.4" + }, + { + "ip_address": "192.168.0.5" + } + ] + } + ] + } + } +expectedStatus: + - Performed +counter: + min: 4 +`) + +var testMockMLBV1LoadBalancersActionApplyConfigurations = fmt.Sprintf(` +request: + method: POST + body: > + {"apply-configurations":null} +response: + code: 204 +newStatus: Performed +`) + +var testMockMLBV1LoadBalancersActionSystemUpdate = fmt.Sprintf(` +request: + method: POST + body: > + {"system-update":{"system_update_id":"31746df7-92f9-4b5e-ad05-59f6684a54eb"}} +response: + code: 204 +newStatus: Performed +`) + +var testMockMLBV1LoadBalancersActionApplyConfigurationsAndSystemUpdate = fmt.Sprintf(` +request: + method: POST + body: > + {"apply-configurations":null,"system-update":{"system_update_id":"31746df7-92f9-4b5e-ad05-59f6684a54eb"}} +response: + code: 204 +newStatus: Performed +`) + +var testMockMLBV1SystemUpdatesShow = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "system_update": { + "id": "31746df7-92f9-4b5e-ad05-59f6684a54eb", + "name": "security_update_202210", + "description": "description", + "href": "https://sdpf.ntt.com/news/2022100301/", + "publish_datetime": "2022-10-03 00:00:00", + "limit_datetime": "2022-10-11 12:59:59", + "current_revision": 1, + "next_revision": 2, + "applicable": true + } + } +`) + +var testMockMLBV1HealthMonitorsListEmpty = fmt.Sprintf(` +request: + method: GET + query: + load_balancer_id: + - 497f6eca-6276-4993-bfeb-53cbbbba6f08 +response: + code: 200 + body: > + { + "health_monitors": [] + } +`) + +var testMockMLBV1ListenersListEmpty = fmt.Sprintf(` +request: + method: GET + query: + load_balancer_id: + - 497f6eca-6276-4993-bfeb-53cbbbba6f08 +response: + code: 200 + body: > + { + "listeners": [] + } +`) + +var testMockMLBV1PoliciesListEmpty = fmt.Sprintf(` +request: + method: GET + query: + load_balancer_id: + - 497f6eca-6276-4993-bfeb-53cbbbba6f08 +response: + code: 200 + body: > + { + "policies": [] + } +`) + +var testMockMLBV1RoutesListEmpty = fmt.Sprintf(` +request: + method: GET + query: + load_balancer_id: + - 497f6eca-6276-4993-bfeb-53cbbbba6f08 +response: + code: 200 + body: > + { + "routes": [] + } +`) + +var testMockMLBV1RulesListEmpty = fmt.Sprintf(` +request: + method: GET + query: + load_balancer_id: + - 497f6eca-6276-4993-bfeb-53cbbbba6f08 +response: + code: 200 + body: > + { + "rules": [] + } +`) + +var testMockMLBV1TargetGroupsListEmpty = fmt.Sprintf(` +request: + method: GET + query: + load_balancer_id: + - 497f6eca-6276-4993-bfeb-53cbbbba6f08 +response: + code: 200 + body: > + { + "target_groups": [] + } +`) diff --git a/ecl/resource_ecl_mlb_load_balancer_v1.go b/ecl/resource_ecl_mlb_load_balancer_v1.go new file mode 100644 index 00000000..91c6fe51 --- /dev/null +++ b/ecl/resource_ecl_mlb_load_balancer_v1.go @@ -0,0 +1,474 @@ +package ecl + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + + "github.com/nttcom/eclcloud/v2" + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers" +) + +func reservedFixedIPsSchemaForResource() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Required: true, + MinItems: 4, + MaxItems: 4, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip_address": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + }, + }, + } +} + +func interfacesSchemaForResource() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Required: true, + MinItems: 1, + MaxItems: 7, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "network_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "virtual_ip_address": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "reserved_fixed_ips": reservedFixedIPsSchemaForResource(), + }, + }, + } +} + +func syslogServersSchemaForResource() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + MaxItems: 2, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip_address": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "port": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + }, + "protocol": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + }, + }, + } +} + +func resourceMLBLoadBalancerV1() *schema.Resource { + var result *schema.Resource + + result = &schema.Resource{ + Create: resourceMLBLoadBalancerV1Create, + Read: resourceMLBLoadBalancerV1Read, + Update: resourceMLBLoadBalancerV1Update, + Delete: resourceMLBLoadBalancerV1Delete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "tags": &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + }, + "plan_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "tenant_id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + "syslog_servers": syslogServersSchemaForResource(), + "interfaces": interfacesSchemaForResource(), + }, + } + + return result +} + +func resourceMLBLoadBalancerV1Create(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + createOpts := load_balancers.CreateOpts{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + Tags: d.Get("tags").(map[string]interface{}), + PlanID: d.Get("plan_id").(string), + } + + syslogServers := make([]load_balancers.CreateOptsSyslogServer, len(d.Get("syslog_servers").([]interface{}))) + for i, syslogServer := range d.Get("syslog_servers").([]interface{}) { + syslogServers[i] = load_balancers.CreateOptsSyslogServer{ + IPAddress: syslogServer.(map[string]interface{})["ip_address"].(string), + Port: syslogServer.(map[string]interface{})["port"].(int), + Protocol: syslogServer.(map[string]interface{})["protocol"].(string), + } + } + createOpts.SyslogServers = &syslogServers + + interfaces := make([]load_balancers.CreateOptsInterface, len(d.Get("interfaces").([]interface{}))) + for i, interfaceV := range d.Get("interfaces").([]interface{}) { + reservedFixedIPs := make([]load_balancers.CreateOptsReservedFixedIP, len(interfaceV.(map[string]interface{})["reserved_fixed_ips"].([]interface{}))) + for j, reservedFixedIP := range interfaceV.(map[string]interface{})["reserved_fixed_ips"].([]interface{}) { + reservedFixedIPs[j] = load_balancers.CreateOptsReservedFixedIP{ + IPAddress: reservedFixedIP.(map[string]interface{})["ip_address"].(string), + } + } + + interfaces[i] = load_balancers.CreateOptsInterface{ + NetworkID: interfaceV.(map[string]interface{})["network_id"].(string), + VirtualIPAddress: interfaceV.(map[string]interface{})["virtual_ip_address"].(string), + ReservedFixedIPs: &reservedFixedIPs, + } + } + createOpts.Interfaces = &interfaces + + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Creating ECL managed load balancer load balancer with options %+v", createOpts) + + loadBalancer, err := load_balancers.Create(managedLoadBalancerClient, createOpts).Extract() + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer load balancer with options %+v: %s", createOpts, err) + } + + d.SetId(loadBalancer.ID) + log.Printf("[INFO] ECL managed load balancer load balancer ID: %s", loadBalancer.ID) + + return resourceMLBLoadBalancerV1Read(d, meta) +} + +func resourceMLBLoadBalancerV1Show(d *schema.ResourceData, client *eclcloud.ServiceClient, changes bool) (*load_balancers.LoadBalancer, error) { + var loadBalancer load_balancers.LoadBalancer + + showOpts := load_balancers.ShowOpts{Changes: changes} + err := load_balancers.Show(client, d.Id(), showOpts).ExtractInto(&loadBalancer) + if err != nil { + return nil, fmt.Errorf("Unable to retrieve ECL managed load balancer load balancer (%s): %s", d.Id(), err) + } + + return &loadBalancer, nil +} + +func resourceMLBLoadBalancerV1Read(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + loadBalancer, err := resourceMLBLoadBalancerV1Show(d, managedLoadBalancerClient, true) + if err != nil { + return CheckDeleted(d, err, "load_balancer") + } + + log.Printf("[DEBUG] Retrieved ECL managed load balancer load balancer (%s): %+v", d.Id(), loadBalancer) + + if loadBalancer.ConfigurationStatus == "ACTIVE" || (loadBalancer.ConfigurationStatus == "UPDATE_STAGED" && loadBalancer.Staged.SyslogServers == nil) { + syslogServers := make([]interface{}, len(loadBalancer.SyslogServers)) + for i, syslogServer := range loadBalancer.SyslogServers { + syslogServers[i] = map[string]interface{}{ + "ip_address": syslogServer.IPAddress, + "port": syslogServer.Port, + "protocol": syslogServer.Protocol, + } + } + + d.Set("syslog_servers", syslogServers) + } else if loadBalancer.ConfigurationStatus == "CREATE_STAGED" || (loadBalancer.ConfigurationStatus == "UPDATE_STAGED" && loadBalancer.Staged.SyslogServers != nil) { + syslogServers := make([]interface{}, len(loadBalancer.Staged.SyslogServers)) + for i, syslogServer := range loadBalancer.Staged.SyslogServers { + syslogServers[i] = map[string]interface{}{ + "ip_address": syslogServer.IPAddress, + "port": syslogServer.Port, + "protocol": syslogServer.Protocol, + } + } + + d.Set("syslog_servers", syslogServers) + } + + if loadBalancer.ConfigurationStatus == "ACTIVE" || (loadBalancer.ConfigurationStatus == "UPDATE_STAGED" && loadBalancer.Staged.Interfaces == nil) { + reservedFixedIPs := make([]interface{}, len(loadBalancer.Interfaces)) + for i, interfaceV := range loadBalancer.Interfaces { + results := make([]interface{}, len(interfaceV.ReservedFixedIPs)) + for j, reservedFixedIP := range interfaceV.ReservedFixedIPs { + results[j] = map[string]interface{}{ + "ip_address": reservedFixedIP.IPAddress, + } + } + reservedFixedIPs[i] = results + } + + interfaces := make([]interface{}, len(loadBalancer.Interfaces)) + for i, interfaceV := range loadBalancer.Interfaces { + interfaces[i] = map[string]interface{}{ + "network_id": interfaceV.NetworkID, + "virtual_ip_address": interfaceV.VirtualIPAddress, + "reserved_fixed_ips": reservedFixedIPs[i], + } + } + + d.Set("interfaces", interfaces) + } else if loadBalancer.ConfigurationStatus == "CREATE_STAGED" || (loadBalancer.ConfigurationStatus == "UPDATE_STAGED" && loadBalancer.Staged.Interfaces != nil) { + reservedFixedIPs := make([]interface{}, len(loadBalancer.Staged.Interfaces)) + for i, interfaceV := range loadBalancer.Staged.Interfaces { + results := make([]interface{}, len(interfaceV.ReservedFixedIPs)) + for j, reservedFixedIP := range interfaceV.ReservedFixedIPs { + results[j] = map[string]interface{}{ + "ip_address": reservedFixedIP.IPAddress, + } + } + reservedFixedIPs[i] = results + } + + interfaces := make([]interface{}, len(loadBalancer.Staged.Interfaces)) + for i, interfaceV := range loadBalancer.Staged.Interfaces { + interfaces[i] = map[string]interface{}{ + "network_id": interfaceV.NetworkID, + "virtual_ip_address": interfaceV.VirtualIPAddress, + "reserved_fixed_ips": reservedFixedIPs[i], + } + } + + d.Set("interfaces", interfaces) + } + + d.Set("name", loadBalancer.Name) + d.Set("description", loadBalancer.Description) + d.Set("tags", loadBalancer.Tags) + d.Set("plan_id", loadBalancer.PlanID) + d.Set("tenant_id", loadBalancer.TenantID) + + return nil +} + +func resourceMLBLoadBalancerV1Update(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Start updating attributes of ECL managed load balancer load balancer ...") + + err = resourceMLBLoadBalancerV1UpdateAttributes(d, managedLoadBalancerClient) + if err != nil { + return fmt.Errorf("Error in updating attributes of ECL managed load balancer load balancer: %s", err) + } + + log.Printf("[DEBUG] Start updating configurations of ECL managed load balancer load balancer ...") + + err = resourceMLBLoadBalancerV1UpdateConfigurations(d, managedLoadBalancerClient) + if err != nil { + return fmt.Errorf("Error in updating configurations of ECL managed load balancer load balancer: %s", err) + } + + return resourceMLBLoadBalancerV1Read(d, meta) +} + +func resourceMLBLoadBalancerV1UpdateAttributes(d *schema.ResourceData, client *eclcloud.ServiceClient) error { + var isAttributesUpdated bool + var updateOpts load_balancers.UpdateOpts + + if d.HasChange("name") { + isAttributesUpdated = true + name := d.Get("name").(string) + updateOpts.Name = &name + } + + if d.HasChange("description") { + isAttributesUpdated = true + description := d.Get("description").(string) + updateOpts.Description = &description + } + + if d.HasChange("tags") { + isAttributesUpdated = true + tags := d.Get("tags").(map[string]interface{}) + updateOpts.Tags = &tags + } + + if isAttributesUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer load balancer attributes (%s) with options %+v", d.Id(), updateOpts) + + _, err := load_balancers.Update(client, d.Id(), updateOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer load balancer attributes (%s) with options %+v: %s", d.Id(), updateOpts, err) + } + } + + return nil +} + +func resourceMLBLoadBalancerV1UpdateConfigurations(d *schema.ResourceData, client *eclcloud.ServiceClient) error { + var isConfigurationsUpdated bool + + loadBalancer, err := resourceMLBLoadBalancerV1Show(d, client, false) + if err != nil { + return err + } + + if loadBalancer.ConfigurationStatus == "ACTIVE" { + syslogServers := make([]load_balancers.CreateStagedOptsSyslogServer, len(d.Get("syslog_servers").([]interface{}))) + reservedFixedIPs := make([][]load_balancers.CreateStagedOptsReservedFixedIP, len(d.Get("interfaces").([]interface{}))) + interfaces := make([]load_balancers.CreateStagedOptsInterface, len(d.Get("interfaces").([]interface{}))) + + if d.HasChange("syslog_servers") { + isConfigurationsUpdated = true + + for i, syslogServer := range d.Get("syslog_servers").([]interface{}) { + syslogServers[i] = load_balancers.CreateStagedOptsSyslogServer{ + IPAddress: syslogServer.(map[string]interface{})["ip_address"].(string), + Port: syslogServer.(map[string]interface{})["port"].(int), + Protocol: syslogServer.(map[string]interface{})["protocol"].(string), + } + } + } + + if d.HasChange("interfaces") { + isConfigurationsUpdated = true + + for i, interfaceV := range d.Get("interfaces").([]interface{}) { + results := make([]load_balancers.CreateStagedOptsReservedFixedIP, len(interfaceV.(map[string]interface{})["reserved_fixed_ips"].([]interface{}))) + for j, reservedFixedIP := range interfaceV.(map[string]interface{})["reserved_fixed_ips"].([]interface{}) { + results[j] = load_balancers.CreateStagedOptsReservedFixedIP{ + IPAddress: reservedFixedIP.(map[string]interface{})["ip_address"].(string), + } + } + reservedFixedIPs[i] = results + } + + for i, interfaceV := range d.Get("interfaces").([]interface{}) { + interfaces[i] = load_balancers.CreateStagedOptsInterface{ + NetworkID: interfaceV.(map[string]interface{})["network_id"].(string), + VirtualIPAddress: interfaceV.(map[string]interface{})["virtual_ip_address"].(string), + ReservedFixedIPs: &reservedFixedIPs[i], + } + } + } + + if isConfigurationsUpdated { + createStagedOpts := load_balancers.CreateStagedOpts{ + SyslogServers: &syslogServers, + Interfaces: &interfaces, + } + + log.Printf("[DEBUG] Updating ECL managed load balancer load balancer configurations (%s) with options %+v", d.Id(), createStagedOpts) + + _, err := load_balancers.CreateStaged(client, d.Id(), createStagedOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer load balancer configurations (%s) with options %+v: %s", d.Id(), createStagedOpts, err) + } + } + } else { + syslogServers := make([]load_balancers.UpdateStagedOptsSyslogServer, len(d.Get("syslog_servers").([]interface{}))) + reservedFixedIPs := make([][]load_balancers.UpdateStagedOptsReservedFixedIP, len(d.Get("interfaces").([]interface{}))) + interfaces := make([]load_balancers.UpdateStagedOptsInterface, len(d.Get("interfaces").([]interface{}))) + + if d.HasChange("syslog_servers") { + isConfigurationsUpdated = true + + for i, syslogServer := range d.Get("syslog_servers").([]interface{}) { + result := load_balancers.UpdateStagedOptsSyslogServer{} + ipAddress := syslogServer.(map[string]interface{})["ip_address"].(string) + port := syslogServer.(map[string]interface{})["port"].(int) + protocol := syslogServer.(map[string]interface{})["protocol"].(string) + result.IPAddress = &ipAddress + result.Port = &port + result.Protocol = &protocol + syslogServers[i] = result + } + } + + if d.HasChange("interfaces") { + isConfigurationsUpdated = true + + for i, interfaceV := range d.Get("interfaces").([]interface{}) { + results := make([]load_balancers.UpdateStagedOptsReservedFixedIP, len(interfaceV.(map[string]interface{})["reserved_fixed_ips"].([]interface{}))) + for j, reservedFixedIP := range interfaceV.(map[string]interface{})["reserved_fixed_ips"].([]interface{}) { + ipAddress := reservedFixedIP.(map[string]interface{})["ip_address"].(string) + results[j] = load_balancers.UpdateStagedOptsReservedFixedIP{ + IPAddress: &ipAddress, + } + } + reservedFixedIPs[i] = results + } + + for i, interfaceV := range d.Get("interfaces").([]interface{}) { + networkID := interfaceV.(map[string]interface{})["network_id"].(string) + virtualIPAddress := interfaceV.(map[string]interface{})["virtual_ip_address"].(string) + interfaces[i] = load_balancers.UpdateStagedOptsInterface{ + NetworkID: &networkID, + VirtualIPAddress: &virtualIPAddress, + ReservedFixedIPs: &reservedFixedIPs[i], + } + } + } + + if isConfigurationsUpdated { + updateStagedOpts := load_balancers.UpdateStagedOpts{ + SyslogServers: &syslogServers, + Interfaces: &interfaces, + } + + log.Printf("[DEBUG] Updating ECL managed load balancer load balancer configurations (%s) with options %+v", d.Id(), updateStagedOpts) + + _, err := load_balancers.UpdateStaged(client, d.Id(), updateStagedOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer load balancer configurations (%s) with options %+v: %s", d.Id(), updateStagedOpts, err) + } + } + } + + return nil +} + +func resourceMLBLoadBalancerV1Delete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Deleting ECL managed load balancer load balancer: %s", d.Id()) + + err = load_balancers.Delete(managedLoadBalancerClient, d.Id()).ExtractErr() + if err != nil { + return fmt.Errorf("Error deleting ECL managed load balancer load balancer: %s", err) + } + + return nil +} diff --git a/ecl/resource_ecl_mlb_load_balancer_v1_mock_test.go b/ecl/resource_ecl_mlb_load_balancer_v1_mock_test.go new file mode 100644 index 00000000..3b5e8cfc --- /dev/null +++ b/ecl/resource_ecl_mlb_load_balancer_v1_mock_test.go @@ -0,0 +1,992 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1LoadBalancerResource(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "load_balancers", "/v1.0/load_balancers", testMockMLBV1LoadBalancersCreate) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowAfterCreate) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersUpdateAttributes) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowBeforeUpdateConfigurations) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08/staged", testMockMLBV1LoadBalancersUpdateConfigurations) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowAfterUpdateConfigurations) + // Staged configurations of the load balancer and related resources are applied here + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowAfterApplyConfigurations) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowBeforeCreateConfigurations) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08/staged", testMockMLBV1LoadBalancersCreateConfigurations) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowAfterCreateConfigurations) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersDelete) + mc.Register(t, "load_balancers", "/v1.0/load_balancers/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1LoadBalancersShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1LoadBalancer, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "name", "load_balancer"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "description", "description"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "tags.key", "value"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "plan_id", "00713021-9aea-41da-9a88-87760c08fa72"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "syslog_servers.0.ip_address", "192.168.0.6"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "syslog_servers.0.port", "514"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "syslog_servers.0.protocol", "udp"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.network_id", "d6797cf4-42b9-4cad-8591-9dd91c3f0fc3"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.virtual_ip_address", "192.168.0.1"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.reserved_fixed_ips.0.ip_address", "192.168.0.2"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.reserved_fixed_ips.1.ip_address", "192.168.0.3"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.reserved_fixed_ips.2.ip_address", "192.168.0.4"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.reserved_fixed_ips.3.ip_address", "192.168.0.5"), + ), + }, + { + Config: testAccMLBV1LoadBalancerUpdateBeforeApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "name", "load_balancer-update"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "description", "description-update"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "tags.key-update", "value-update"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "plan_id", "00713021-9aea-41da-9a88-87760c08fa72"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "syslog_servers.0.ip_address", "192.168.0.6"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "syslog_servers.0.port", "514"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "syslog_servers.0.protocol", "udp"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "syslog_servers.1.ip_address", "192.168.1.6"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "syslog_servers.1.port", "514"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "syslog_servers.1.protocol", "udp"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.network_id", "d6797cf4-42b9-4cad-8591-9dd91c3f0fc3"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.virtual_ip_address", "192.168.0.1"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.reserved_fixed_ips.0.ip_address", "192.168.0.2"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.reserved_fixed_ips.1.ip_address", "192.168.0.3"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.reserved_fixed_ips.2.ip_address", "192.168.0.4"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.reserved_fixed_ips.3.ip_address", "192.168.0.5"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.1.network_id", "58e6d72b-f5e7-4b83-b306-06989ff78a84"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.1.virtual_ip_address", "192.168.1.1"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.1.reserved_fixed_ips.0.ip_address", "192.168.1.2"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.1.reserved_fixed_ips.1.ip_address", "192.168.1.3"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.1.reserved_fixed_ips.2.ip_address", "192.168.1.4"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.1.reserved_fixed_ips.3.ip_address", "192.168.1.5"), + ), + }, + { + Config: testAccMLBV1LoadBalancerUpdateAfterApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "name", "load_balancer-update"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "description", "description-update"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "tags.key-update", "value-update"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "plan_id", "00713021-9aea-41da-9a88-87760c08fa72"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "syslog_servers.0.ip_address", "192.168.1.6"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "syslog_servers.0.port", "514"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "syslog_servers.0.protocol", "udp"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.network_id", "58e6d72b-f5e7-4b83-b306-06989ff78a84"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.virtual_ip_address", "192.168.1.1"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.reserved_fixed_ips.0.ip_address", "192.168.1.2"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.reserved_fixed_ips.1.ip_address", "192.168.1.3"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.reserved_fixed_ips.2.ip_address", "192.168.1.4"), + resource.TestCheckResourceAttr("ecl_mlb_load_balancer_v1.load_balancer", "interfaces.0.reserved_fixed_ips.3.ip_address", "192.168.1.5"), + ), + }, + }, + }) +} + +var testAccMLBV1LoadBalancer = fmt.Sprintf(` +resource "ecl_mlb_load_balancer_v1" "load_balancer" { + name = "load_balancer" + description = "description" + tags = { + key = "value" + } + plan_id = "00713021-9aea-41da-9a88-87760c08fa72" + syslog_servers { + ip_address = "192.168.0.6" + port = 514 + protocol = "udp" + } + interfaces { + network_id = "d6797cf4-42b9-4cad-8591-9dd91c3f0fc3" + virtual_ip_address = "192.168.0.1" + reserved_fixed_ips { + ip_address = "192.168.0.2" + } + reserved_fixed_ips { + ip_address = "192.168.0.3" + } + reserved_fixed_ips { + ip_address = "192.168.0.4" + } + reserved_fixed_ips { + ip_address = "192.168.0.5" + } + } +} +`) + +var testAccMLBV1LoadBalancerUpdateBeforeApplyConfigurations = fmt.Sprintf(` +resource "ecl_mlb_load_balancer_v1" "load_balancer" { + name = "load_balancer-update" + description = "description-update" + tags = { + key-update = "value-update" + } + plan_id = "00713021-9aea-41da-9a88-87760c08fa72" + syslog_servers { + ip_address = "192.168.0.6" + port = 514 + protocol = "udp" + } + syslog_servers { + ip_address = "192.168.1.6" + port = 514 + protocol = "udp" + } + interfaces { + network_id = "d6797cf4-42b9-4cad-8591-9dd91c3f0fc3" + virtual_ip_address = "192.168.0.1" + reserved_fixed_ips { + ip_address = "192.168.0.2" + } + reserved_fixed_ips { + ip_address = "192.168.0.3" + } + reserved_fixed_ips { + ip_address = "192.168.0.4" + } + reserved_fixed_ips { + ip_address = "192.168.0.5" + } + } + interfaces { + network_id = "58e6d72b-f5e7-4b83-b306-06989ff78a84" + virtual_ip_address = "192.168.1.1" + reserved_fixed_ips { + ip_address = "192.168.1.2" + } + reserved_fixed_ips { + ip_address = "192.168.1.3" + } + reserved_fixed_ips { + ip_address = "192.168.1.4" + } + reserved_fixed_ips { + ip_address = "192.168.1.5" + } + } +} +`) + +var testAccMLBV1LoadBalancerUpdateAfterApplyConfigurations = fmt.Sprintf(` +resource "ecl_mlb_load_balancer_v1" "load_balancer" { + name = "load_balancer-update" + description = "description-update" + tags = { + key-update = "value-update" + } + plan_id = "00713021-9aea-41da-9a88-87760c08fa72" + syslog_servers { + ip_address = "192.168.1.6" + port = 514 + protocol = "udp" + } + interfaces { + network_id = "58e6d72b-f5e7-4b83-b306-06989ff78a84" + virtual_ip_address = "192.168.1.1" + reserved_fixed_ips { + ip_address = "192.168.1.2" + } + reserved_fixed_ips { + ip_address = "192.168.1.3" + } + reserved_fixed_ips { + ip_address = "192.168.1.4" + } + reserved_fixed_ips { + ip_address = "192.168.1.5" + } + } +} +`) + +var testMockMLBV1LoadBalancersCreate = fmt.Sprintf(` +request: + method: POST + body: > + {"load_balancer":{"description":"description","interfaces":[{"network_id":"d6797cf4-42b9-4cad-8591-9dd91c3f0fc3","reserved_fixed_ips":[{"ip_address":"192.168.0.2"},{"ip_address":"192.168.0.3"},{"ip_address":"192.168.0.4"},{"ip_address":"192.168.0.5"}],"virtual_ip_address":"192.168.0.1"}],"name":"load_balancer","plan_id":"00713021-9aea-41da-9a88-87760c08fa72","syslog_servers":[{"ip_address":"192.168.0.6","port":514,"protocol":"udp"}],"tags":{"key":"value"}}} +response: + code: 200 + body: > + { + "load_balancer": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "load_balancer", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "monitoring_status": "INITIAL", + "operation_status": "NONE", + "primary_availability_zone": null, + "secondary_availability_zone": null, + "active_availability_zone": "UNDEFINED", + "revision": 1, + "plan_id": "00713021-9aea-41da-9a88-87760c08fa72", + "plan_name": "50M_HA_4IF", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "syslog_servers": null, + "interfaces": null + } + } +newStatus: Created +`) + +var testMockMLBV1LoadBalancersShowAfterCreate = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "load_balancer": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "load_balancer", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "monitoring_status": "INITIAL", + "operation_status": "NONE", + "primary_availability_zone": null, + "secondary_availability_zone": null, + "active_availability_zone": "UNDEFINED", + "revision": 1, + "plan_id": "00713021-9aea-41da-9a88-87760c08fa72", + "plan_name": "50M_HA_4IF", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "syslog_servers": null, + "interfaces": null, + "current": null, + "staged": { + "syslog_servers": [ + { + "ip_address": "192.168.0.6", + "port": 514, + "protocol": "udp" + } + ], + "interfaces": [ + { + "network_id": "d6797cf4-42b9-4cad-8591-9dd91c3f0fc3", + "virtual_ip_address": "192.168.0.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.0.2" + }, + { + "ip_address": "192.168.0.3" + }, + { + "ip_address": "192.168.0.4" + }, + { + "ip_address": "192.168.0.5" + } + ] + } + ] + } + } + } +expectedStatus: + - Created +`) + +var testMockMLBV1LoadBalancersShowBeforeUpdateConfigurations = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "load_balancer": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "load_balancer-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "monitoring_status": "INITIAL", + "operation_status": "NONE", + "primary_availability_zone": null, + "secondary_availability_zone": null, + "active_availability_zone": "UNDEFINED", + "revision": 1, + "plan_id": "00713021-9aea-41da-9a88-87760c08fa72", + "plan_name": "50M_HA_4IF", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "syslog_servers": null, + "interfaces": null + } + } +expectedStatus: + - AttributesUpdated +`) + +var testMockMLBV1LoadBalancersShowAfterUpdateConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "load_balancer": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "load_balancer-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "monitoring_status": "INITIAL", + "operation_status": "NONE", + "primary_availability_zone": null, + "secondary_availability_zone": null, + "active_availability_zone": "UNDEFINED", + "revision": 1, + "plan_id": "00713021-9aea-41da-9a88-87760c08fa72", + "plan_name": "50M_HA_4IF", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "syslog_servers": null, + "interfaces": null, + "current": null, + "staged": { + "syslog_servers": [ + { + "ip_address": "192.168.0.6", + "port": 514, + "protocol": "udp" + }, + { + "ip_address": "192.168.1.6", + "port": 514, + "protocol": "udp" + } + ], + "interfaces": [ + { + "network_id": "d6797cf4-42b9-4cad-8591-9dd91c3f0fc3", + "virtual_ip_address": "192.168.0.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.0.2" + }, + { + "ip_address": "192.168.0.3" + }, + { + "ip_address": "192.168.0.4" + }, + { + "ip_address": "192.168.0.5" + } + ] + }, + { + "network_id": "58e6d72b-f5e7-4b83-b306-06989ff78a84", + "virtual_ip_address": "192.168.1.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.1.2" + }, + { + "ip_address": "192.168.1.3" + }, + { + "ip_address": "192.168.1.4" + }, + { + "ip_address": "192.168.1.5" + } + ] + } + ] + } + } + } +expectedStatus: + - ConfigurationsUpdatedBeforeApply +newStatus: ConfigurationsApplied +`) + +var testMockMLBV1LoadBalancersShowAfterApplyConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "load_balancer": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "load_balancer-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "ACTIVE", + "monitoring_status": "ACTIVE", + "operation_status": "COMPLETE", + "primary_availability_zone": "zone1_groupa", + "secondary_availability_zone": "zone1_groupb", + "active_availability_zone": "zone1_groupa", + "revision": 1, + "plan_id": "00713021-9aea-41da-9a88-87760c08fa72", + "plan_name": "50M_HA_4IF", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "syslog_servers": [ + { + "ip_address": "192.168.0.6", + "port": 514, + "protocol": "udp" + }, + { + "ip_address": "192.168.1.6", + "port": 514, + "protocol": "udp" + } + ], + "interfaces": [ + { + "network_id": "d6797cf4-42b9-4cad-8591-9dd91c3f0fc3", + "virtual_ip_address": "192.168.0.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.0.2" + }, + { + "ip_address": "192.168.0.3" + }, + { + "ip_address": "192.168.0.4" + }, + { + "ip_address": "192.168.0.5" + } + ] + }, + { + "network_id": "58e6d72b-f5e7-4b83-b306-06989ff78a84", + "virtual_ip_address": "192.168.1.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.1.2" + }, + { + "ip_address": "192.168.1.3" + }, + { + "ip_address": "192.168.1.4" + }, + { + "ip_address": "192.168.1.5" + } + ] + } + ], + "current": { + "syslog_servers": [ + { + "ip_address": "192.168.0.6", + "port": 514, + "protocol": "udp" + }, + { + "ip_address": "192.168.1.6", + "port": 514, + "protocol": "udp" + } + ], + "interfaces": [ + { + "network_id": "d6797cf4-42b9-4cad-8591-9dd91c3f0fc3", + "virtual_ip_address": "192.168.0.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.0.2" + }, + { + "ip_address": "192.168.0.3" + }, + { + "ip_address": "192.168.0.4" + }, + { + "ip_address": "192.168.0.5" + } + ] + }, + { + "network_id": "58e6d72b-f5e7-4b83-b306-06989ff78a84", + "virtual_ip_address": "192.168.1.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.1.2" + }, + { + "ip_address": "192.168.1.3" + }, + { + "ip_address": "192.168.1.4" + }, + { + "ip_address": "192.168.1.5" + } + ] + } + ] + }, + "staged": null + } + } +expectedStatus: + - ConfigurationsApplied +`) + +var testMockMLBV1LoadBalancersShowBeforeCreateConfigurations = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "load_balancer": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "load_balancer-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "ACTIVE", + "monitoring_status": "ACTIVE", + "operation_status": "COMPLETE", + "primary_availability_zone": "zone1_groupa", + "secondary_availability_zone": "zone1_groupb", + "active_availability_zone": "zone1_groupa", + "revision": 1, + "plan_id": "00713021-9aea-41da-9a88-87760c08fa72", + "plan_name": "50M_HA_4IF", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "syslog_servers": [ + { + "ip_address": "192.168.0.6", + "port": 514, + "protocol": "udp" + }, + { + "ip_address": "192.168.1.6", + "port": 514, + "protocol": "udp" + } + ], + "interfaces": [ + { + "network_id": "d6797cf4-42b9-4cad-8591-9dd91c3f0fc3", + "virtual_ip_address": "192.168.0.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.0.2" + }, + { + "ip_address": "192.168.0.3" + }, + { + "ip_address": "192.168.0.4" + }, + { + "ip_address": "192.168.0.5" + } + ] + }, + { + "network_id": "58e6d72b-f5e7-4b83-b306-06989ff78a84", + "virtual_ip_address": "192.168.1.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.1.2" + }, + { + "ip_address": "192.168.1.3" + }, + { + "ip_address": "192.168.1.4" + }, + { + "ip_address": "192.168.1.5" + } + ] + } + ] + } + } +expectedStatus: + - ConfigurationsApplied +`) + +var testMockMLBV1LoadBalancersShowAfterCreateConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "load_balancer": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "load_balancer-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "UPDATE_STAGED", + "monitoring_status": "ACTIVE", + "operation_status": "COMPLETE", + "primary_availability_zone": "zone1_groupa", + "secondary_availability_zone": "zone1_groupb", + "active_availability_zone": "zone1_groupa", + "revision": 1, + "plan_id": "00713021-9aea-41da-9a88-87760c08fa72", + "plan_name": "50M_HA_4IF", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "syslog_servers": [ + { + "ip_address": "192.168.0.6", + "port": 514, + "protocol": "udp" + }, + { + "ip_address": "192.168.1.6", + "port": 514, + "protocol": "udp" + } + ], + "interfaces": [ + { + "network_id": "d6797cf4-42b9-4cad-8591-9dd91c3f0fc3", + "virtual_ip_address": "192.168.0.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.0.2" + }, + { + "ip_address": "192.168.0.3" + }, + { + "ip_address": "192.168.0.4" + }, + { + "ip_address": "192.168.0.5" + } + ] + }, + { + "network_id": "58e6d72b-f5e7-4b83-b306-06989ff78a84", + "virtual_ip_address": "192.168.1.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.1.2" + }, + { + "ip_address": "192.168.1.3" + }, + { + "ip_address": "192.168.1.4" + }, + { + "ip_address": "192.168.1.5" + } + ] + } + ], + "current": { + "syslog_servers": [ + { + "ip_address": "192.168.0.6", + "port": 514, + "protocol": "udp" + }, + { + "ip_address": "192.168.1.6", + "port": 514, + "protocol": "udp" + } + ], + "interfaces": [ + { + "network_id": "d6797cf4-42b9-4cad-8591-9dd91c3f0fc3", + "virtual_ip_address": "192.168.0.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.0.2" + }, + { + "ip_address": "192.168.0.3" + }, + { + "ip_address": "192.168.0.4" + }, + { + "ip_address": "192.168.0.5" + } + ] + }, + { + "network_id": "58e6d72b-f5e7-4b83-b306-06989ff78a84", + "virtual_ip_address": "192.168.1.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.1.2" + }, + { + "ip_address": "192.168.1.3" + }, + { + "ip_address": "192.168.1.4" + }, + { + "ip_address": "192.168.1.5" + } + ] + } + ] + }, + "staged": { + "syslog_servers": [ + { + "ip_address": "192.168.1.6", + "port": 514, + "protocol": "udp" + } + ], + "interfaces": [ + { + "network_id": "58e6d72b-f5e7-4b83-b306-06989ff78a84", + "virtual_ip_address": "192.168.1.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.1.2" + }, + { + "ip_address": "192.168.1.3" + }, + { + "ip_address": "192.168.1.4" + }, + { + "ip_address": "192.168.1.5" + } + ] + } + ] + } + } + } +expectedStatus: + - ConfigurationsUpdatedAfterApply +`) + +var testMockMLBV1LoadBalancersShowAfterDelete = fmt.Sprintf(` +request: + method: GET +response: + code: 404 +expectedStatus: + - Deleted +`) + +var testMockMLBV1LoadBalancersUpdateAttributes = fmt.Sprintf(` +request: + method: PATCH + body: > + {"load_balancer":{"description":"description-update","name":"load_balancer-update","tags":{"key-update":"value-update"}}} +response: + code: 200 + body: > + { + "load_balancer": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "load_balancer-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "monitoring_status": "INITIAL", + "operation_status": "NONE", + "primary_availability_zone": null, + "secondary_availability_zone": null, + "active_availability_zone": "UNDEFINED", + "revision": 1, + "plan_id": "00713021-9aea-41da-9a88-87760c08fa72", + "plan_name": "50M_HA_4IF", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "syslog_servers": null, + "interfaces": null + } + } +expectedStatus: + - Created +newStatus: AttributesUpdated +`) + +var testMockMLBV1LoadBalancersCreateConfigurations = fmt.Sprintf(` +request: + method: POST + body: > + {"load_balancer":{"interfaces":[{"network_id":"58e6d72b-f5e7-4b83-b306-06989ff78a84","reserved_fixed_ips":[{"ip_address":"192.168.1.2"},{"ip_address":"192.168.1.3"},{"ip_address":"192.168.1.4"},{"ip_address":"192.168.1.5"}],"virtual_ip_address":"192.168.1.1"}],"syslog_servers":[{"ip_address":"192.168.1.6","port":514,"protocol":"udp"}]}} +response: + code: 200 + body: > + { + "load_balancer": { + "syslog_servers": [ + { + "ip_address": "192.168.1.6", + "port": 514, + "protocol": "udp" + } + ], + "interfaces": [ + { + "network_id": "58e6d72b-f5e7-4b83-b306-06989ff78a84", + "virtual_ip_address": "192.168.1.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.1.2" + }, + { + "ip_address": "192.168.1.3" + }, + { + "ip_address": "192.168.1.4" + }, + { + "ip_address": "192.168.1.5" + } + ] + } + ] + } + } +expectedStatus: + - ConfigurationsApplied +newStatus: ConfigurationsUpdatedAfterApply +`) + +var testMockMLBV1LoadBalancersUpdateConfigurations = fmt.Sprintf(` +request: + method: PATCH + body: > + {"load_balancer":{"interfaces":[{"network_id":"d6797cf4-42b9-4cad-8591-9dd91c3f0fc3","reserved_fixed_ips":[{"ip_address":"192.168.0.2"},{"ip_address":"192.168.0.3"},{"ip_address":"192.168.0.4"},{"ip_address":"192.168.0.5"}],"virtual_ip_address":"192.168.0.1"},{"network_id":"58e6d72b-f5e7-4b83-b306-06989ff78a84","reserved_fixed_ips":[{"ip_address":"192.168.1.2"},{"ip_address":"192.168.1.3"},{"ip_address":"192.168.1.4"},{"ip_address":"192.168.1.5"}],"virtual_ip_address":"192.168.1.1"}],"syslog_servers":[{"ip_address":"192.168.0.6","port":514,"protocol":"udp"},{"ip_address":"192.168.1.6","port":514,"protocol":"udp"}]}} +response: + code: 200 + body: > + { + "load_balancer": { + "syslog_servers": [ + { + "ip_address": "192.168.0.6", + "port": 514, + "protocol": "udp" + }, + { + "ip_address": "192.168.1.6", + "port": 514, + "protocol": "udp" + } + ], + "interfaces": [ + { + "network_id": "d6797cf4-42b9-4cad-8591-9dd91c3f0fc3", + "virtual_ip_address": "192.168.0.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.0.2" + }, + { + "ip_address": "192.168.0.3" + }, + { + "ip_address": "192.168.0.4" + }, + { + "ip_address": "192.168.0.5" + } + ] + }, + { + "network_id": "58e6d72b-f5e7-4b83-b306-06989ff78a84", + "virtual_ip_address": "192.168.1.1", + "reserved_fixed_ips": [ + { + "ip_address": "192.168.1.2" + }, + { + "ip_address": "192.168.1.3" + }, + { + "ip_address": "192.168.1.4" + }, + { + "ip_address": "192.168.1.5" + } + ] + } + ] + } + } +expectedStatus: + - AttributesUpdated +newStatus: ConfigurationsUpdatedBeforeApply +`) + +var testMockMLBV1LoadBalancersDelete = fmt.Sprintf(` +request: + method: DELETE +response: + code: 204 +expectedStatus: + - Created + - ConfigurationsUpdatedAfterApply +newStatus: Deleted +`) diff --git a/ecl/resource_ecl_mlb_policy_v1.go b/ecl/resource_ecl_mlb_policy_v1.go new file mode 100644 index 00000000..aceb37c9 --- /dev/null +++ b/ecl/resource_ecl_mlb_policy_v1.go @@ -0,0 +1,418 @@ +package ecl + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/nttcom/eclcloud/v2" + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies" +) + +func resourceMLBPolicyV1() *schema.Resource { + var result *schema.Resource + + result = &schema.Resource{ + Create: resourceMLBPolicyV1Create, + Read: resourceMLBPolicyV1Read, + Update: resourceMLBPolicyV1Update, + Delete: resourceMLBPolicyV1Delete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "tags": &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + }, + "algorithm": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "persistence": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "idle_timeout": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + }, + "sorry_page_url": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "source_nat": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "certificate_id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "health_monitor_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "listener_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "default_target_group_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "tls_policy_id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "load_balancer_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "tenant_id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + }, + } + + return result +} + +func resourceMLBPolicyV1Create(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + createOpts := policies.CreateOpts{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + Tags: d.Get("tags").(map[string]interface{}), + Algorithm: d.Get("algorithm").(string), + Persistence: d.Get("persistence").(string), + IdleTimeout: d.Get("idle_timeout").(int), + SorryPageUrl: d.Get("sorry_page_url").(string), + SourceNat: d.Get("source_nat").(string), + CertificateID: d.Get("certificate_id").(string), + HealthMonitorID: d.Get("health_monitor_id").(string), + ListenerID: d.Get("listener_id").(string), + DefaultTargetGroupID: d.Get("default_target_group_id").(string), + TLSPolicyID: d.Get("tls_policy_id").(string), + LoadBalancerID: d.Get("load_balancer_id").(string), + } + + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Creating ECL managed load balancer policy with options %+v", createOpts) + + policy, err := policies.Create(managedLoadBalancerClient, createOpts).Extract() + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer policy with options %+v: %s", createOpts, err) + } + + d.SetId(policy.ID) + log.Printf("[INFO] ECL managed load balancer policy ID: %s", policy.ID) + + return resourceMLBPolicyV1Read(d, meta) +} + +func resourceMLBPolicyV1Show(d *schema.ResourceData, client *eclcloud.ServiceClient, changes bool) (*policies.Policy, error) { + var policy policies.Policy + + showOpts := policies.ShowOpts{Changes: changes} + err := policies.Show(client, d.Id(), showOpts).ExtractInto(&policy) + if err != nil { + return nil, fmt.Errorf("Unable to retrieve ECL managed load balancer policy (%s): %s", d.Id(), err) + } + + return &policy, nil +} + +func resourceMLBPolicyV1Read(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + policy, err := resourceMLBPolicyV1Show(d, managedLoadBalancerClient, true) + if err != nil { + return CheckDeleted(d, err, "policy") + } + + if policy.ConfigurationStatus == "ACTIVE" { + d.Set("algorithm", policy.Algorithm) + d.Set("persistence", policy.Persistence) + d.Set("idle_timeout", policy.IdleTimeout) + d.Set("sorry_page_url", policy.SorryPageUrl) + d.Set("source_nat", policy.SourceNat) + d.Set("certificate_id", policy.CertificateID) + d.Set("health_monitor_id", policy.HealthMonitorID) + d.Set("listener_id", policy.ListenerID) + d.Set("default_target_group_id", policy.DefaultTargetGroupID) + d.Set("tls_policy_id", policy.TLSPolicyID) + } else if policy.ConfigurationStatus == "CREATE_STAGED" { + d.Set("algorithm", policy.Staged.Algorithm) + d.Set("persistence", policy.Staged.Persistence) + d.Set("idle_timeout", policy.Staged.IdleTimeout) + d.Set("sorry_page_url", policy.Staged.SorryPageUrl) + d.Set("source_nat", policy.Staged.SourceNat) + d.Set("certificate_id", policy.Staged.CertificateID) + d.Set("health_monitor_id", policy.Staged.HealthMonitorID) + d.Set("listener_id", policy.Staged.ListenerID) + d.Set("default_target_group_id", policy.Staged.DefaultTargetGroupID) + d.Set("tls_policy_id", policy.Staged.TLSPolicyID) + } else if policy.ConfigurationStatus == "UPDATE_STAGED" { + d.Set("algorithm", ternary(policy.Staged.Algorithm == "", policy.Algorithm, policy.Staged.Algorithm)) + d.Set("persistence", ternary(policy.Staged.Persistence == "", policy.Persistence, policy.Staged.Persistence)) + d.Set("idle_timeout", ternary(policy.Staged.IdleTimeout == 0, policy.IdleTimeout, policy.Staged.IdleTimeout)) + d.Set("sorry_page_url", ternary(policy.Staged.SorryPageUrl == "", policy.SorryPageUrl, policy.Staged.SorryPageUrl)) + d.Set("source_nat", ternary(policy.Staged.SourceNat == "", policy.SourceNat, policy.Staged.SourceNat)) + d.Set("certificate_id", ternary(policy.Staged.CertificateID == "", policy.CertificateID, policy.Staged.CertificateID)) + d.Set("health_monitor_id", ternary(policy.Staged.HealthMonitorID == "", policy.HealthMonitorID, policy.Staged.HealthMonitorID)) + d.Set("listener_id", ternary(policy.Staged.ListenerID == "", policy.ListenerID, policy.Staged.ListenerID)) + d.Set("default_target_group_id", ternary(policy.Staged.DefaultTargetGroupID == "", policy.DefaultTargetGroupID, policy.Staged.DefaultTargetGroupID)) + d.Set("tls_policy_id", ternary(policy.Staged.TLSPolicyID == "", policy.TLSPolicyID, policy.Staged.TLSPolicyID)) + } else if policy.ConfigurationStatus == "DELETE_STAGED" { + d.SetId("") + return nil + } + + d.Set("name", policy.Name) + d.Set("description", policy.Description) + d.Set("tags", policy.Tags) + d.Set("load_balancer_id", policy.LoadBalancerID) + d.Set("tenant_id", policy.TenantID) + + return nil +} + +func resourceMLBPolicyV1Update(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Start updating attributes of ECL managed load balancer policy ...") + + err = resourceMLBPolicyV1UpdateAttributes(d, managedLoadBalancerClient) + if err != nil { + return fmt.Errorf("Error in updating attributes of ECL managed load balancer policy: %s", err) + } + + log.Printf("[DEBUG] Start updating configurations of ECL managed load balancer policy ...") + + err = resourceMLBPolicyV1UpdateConfigurations(d, managedLoadBalancerClient) + if err != nil { + return fmt.Errorf("Error in updating configurations of ECL managed load balancer policy: %s", err) + } + + return resourceMLBPolicyV1Read(d, meta) +} + +func resourceMLBPolicyV1UpdateAttributes(d *schema.ResourceData, client *eclcloud.ServiceClient) error { + var isAttributesUpdated bool + var updateOpts policies.UpdateOpts + + if d.HasChange("name") { + isAttributesUpdated = true + name := d.Get("name").(string) + updateOpts.Name = &name + } + + if d.HasChange("description") { + isAttributesUpdated = true + description := d.Get("description").(string) + updateOpts.Description = &description + } + + if d.HasChange("tags") { + isAttributesUpdated = true + tags := d.Get("tags").(map[string]interface{}) + updateOpts.Tags = &tags + } + + if isAttributesUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer policy attributes (%s) with options %+v", d.Id(), updateOpts) + + _, err := policies.Update(client, d.Id(), updateOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer policy attributes (%s) with options %+v: %s", d.Id(), updateOpts, err) + } + } + + return nil +} + +func resourceMLBPolicyV1UpdateConfigurations(d *schema.ResourceData, client *eclcloud.ServiceClient) error { + var isConfigurationsUpdated bool + + policy, err := resourceMLBPolicyV1Show(d, client, false) + if err != nil { + return err + } + + if policy.ConfigurationStatus == "ACTIVE" { + var createStagedOpts policies.CreateStagedOpts + + if d.HasChange("algorithm") { + isConfigurationsUpdated = true + createStagedOpts.Algorithm = d.Get("algorithm").(string) + } + + if d.HasChange("persistence") { + isConfigurationsUpdated = true + createStagedOpts.Persistence = d.Get("persistence").(string) + } + + if d.HasChange("idle_timeout") { + isConfigurationsUpdated = true + createStagedOpts.IdleTimeout = d.Get("idle_timeout").(int) + } + + if d.HasChange("sorry_page_url") { + isConfigurationsUpdated = true + createStagedOpts.SorryPageUrl = d.Get("sorry_page_url").(string) + } + + if d.HasChange("source_nat") { + isConfigurationsUpdated = true + createStagedOpts.SourceNat = d.Get("source_nat").(string) + } + + if d.HasChange("certificate_id") { + isConfigurationsUpdated = true + createStagedOpts.CertificateID = d.Get("certificate_id").(string) + } + + if d.HasChange("health_monitor_id") { + isConfigurationsUpdated = true + createStagedOpts.HealthMonitorID = d.Get("health_monitor_id").(string) + } + + if d.HasChange("listener_id") { + isConfigurationsUpdated = true + createStagedOpts.ListenerID = d.Get("listener_id").(string) + } + + if d.HasChange("default_target_group_id") { + isConfigurationsUpdated = true + createStagedOpts.DefaultTargetGroupID = d.Get("default_target_group_id").(string) + } + + if d.HasChange("tls_policy_id") { + isConfigurationsUpdated = true + createStagedOpts.TLSPolicyID = d.Get("tls_policy_id").(string) + } + + if isConfigurationsUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer policy configurations (%s) with options %+v", d.Id(), createStagedOpts) + + _, err := policies.CreateStaged(client, d.Id(), createStagedOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer policy configurations (%s) with options %+v: %s", d.Id(), createStagedOpts, err) + } + } + } else { + var updateStagedOpts policies.UpdateStagedOpts + + if d.HasChange("algorithm") { + isConfigurationsUpdated = true + algorithm := d.Get("algorithm").(string) + updateStagedOpts.Algorithm = &algorithm + } + + if d.HasChange("persistence") { + isConfigurationsUpdated = true + persistence := d.Get("persistence").(string) + updateStagedOpts.Persistence = &persistence + } + + if d.HasChange("idle_timeout") { + isConfigurationsUpdated = true + idleTimeout := d.Get("idle_timeout").(int) + updateStagedOpts.IdleTimeout = &idleTimeout + } + + if d.HasChange("sorry_page_url") { + isConfigurationsUpdated = true + sorryPageUrl := d.Get("sorry_page_url").(string) + updateStagedOpts.SorryPageUrl = &sorryPageUrl + } + + if d.HasChange("source_nat") { + isConfigurationsUpdated = true + sourceNat := d.Get("source_nat").(string) + updateStagedOpts.SourceNat = &sourceNat + } + + if d.HasChange("certificate_id") { + isConfigurationsUpdated = true + certificateID := d.Get("certificate_id").(string) + updateStagedOpts.CertificateID = &certificateID + } + + if d.HasChange("health_monitor_id") { + isConfigurationsUpdated = true + healthMonitorID := d.Get("health_monitor_id").(string) + updateStagedOpts.HealthMonitorID = &healthMonitorID + } + + if d.HasChange("listener_id") { + isConfigurationsUpdated = true + listenerID := d.Get("listener_id").(string) + updateStagedOpts.ListenerID = &listenerID + } + + if d.HasChange("default_target_group_id") { + isConfigurationsUpdated = true + defaultTargetGroupID := d.Get("default_target_group_id").(string) + updateStagedOpts.DefaultTargetGroupID = &defaultTargetGroupID + } + + if d.HasChange("tls_policy_id") { + isConfigurationsUpdated = true + tlsPolicyID := d.Get("tls_policy_id").(string) + updateStagedOpts.TLSPolicyID = &tlsPolicyID + } + + if isConfigurationsUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer policy configurations (%s) with options %+v", d.Id(), updateStagedOpts) + + _, err := policies.UpdateStaged(client, d.Id(), updateStagedOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer policy configurations (%s) with options %+v: %s", d.Id(), updateStagedOpts, err) + } + } + } + + return nil +} + +func resourceMLBPolicyV1Delete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Deleting ECL managed load balancer policy: %s", d.Id()) + + err = policies.Delete(managedLoadBalancerClient, d.Id()).ExtractErr() + if err != nil { + return fmt.Errorf("Error deleting ECL managed load balancer policy: %s", err) + } + + return nil +} diff --git a/ecl/resource_ecl_mlb_policy_v1_mock_test.go b/ecl/resource_ecl_mlb_policy_v1_mock_test.go new file mode 100644 index 00000000..9456cc43 --- /dev/null +++ b/ecl/resource_ecl_mlb_policy_v1_mock_test.go @@ -0,0 +1,634 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1PolicyResource(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "policies", "/v1.0/policies", testMockMLBV1PoliciesCreate) + mc.Register(t, "policies", "/v1.0/policies/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1PoliciesShowAfterCreate) + mc.Register(t, "policies", "/v1.0/policies/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1PoliciesUpdateAttributes) + mc.Register(t, "policies", "/v1.0/policies/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1PoliciesShowBeforeUpdateConfigurations) + mc.Register(t, "policies", "/v1.0/policies/497f6eca-6276-4993-bfeb-53cbbbba6f08/staged", testMockMLBV1PoliciesUpdateConfigurations) + mc.Register(t, "policies", "/v1.0/policies/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1PoliciesShowAfterUpdateConfigurations) + // Staged configurations of the load balancer and related resources are applied here + mc.Register(t, "policies", "/v1.0/policies/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1PoliciesShowAfterApplyConfigurations) + mc.Register(t, "policies", "/v1.0/policies/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1PoliciesShowBeforeCreateConfigurations) + mc.Register(t, "policies", "/v1.0/policies/497f6eca-6276-4993-bfeb-53cbbbba6f08/staged", testMockMLBV1PoliciesCreateConfigurations) + mc.Register(t, "policies", "/v1.0/policies/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1PoliciesShowAfterCreateConfigurations) + mc.Register(t, "policies", "/v1.0/policies/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1PoliciesDelete) + mc.Register(t, "policies", "/v1.0/policies/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1PoliciesShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1Policy, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "name", "policy"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "description", "description"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "tags.key", "value"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "algorithm", "round-robin"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "persistence", "cookie"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "idle_timeout", "600"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "sorry_page_url", "https://example.com/sorry"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "source_nat", "enable"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "certificate_id", "f57a98fe-d63e-4048-93a0-51fe163f30d7"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "health_monitor_id", "dd7a96d6-4e66-4666-baca-a8555f0c472c"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "listener_id", "68633f4f-f52a-402f-8572-b8173418904f"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "default_target_group_id", "a44c4072-ed90-4b50-a33a-6b38fb10c7db"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "tls_policy_id", "4ba79662-f2a1-41a4-a3d9-595799bbcd86"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + ), + }, + { + Config: testAccMLBV1PolicyUpdateBeforeApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "name", "policy-update"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "description", "description-update"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "tags.key-update", "value-update"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "algorithm", "least-connection"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "persistence", "source-ip"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "idle_timeout", "120"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "sorry_page_url", ""), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "source_nat", "disable"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "certificate_id", ""), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "health_monitor_id", "dd7a96d6-4e66-4666-baca-a8555f0c472c"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "listener_id", "68633f4f-f52a-402f-8572-b8173418904f"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "default_target_group_id", "a44c4072-ed90-4b50-a33a-6b38fb10c7db"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "tls_policy_id", ""), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + ), + }, + { + Config: testAccMLBV1PolicyUpdateAfterApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "name", "policy-update"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "description", "description-update"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "tags.key-update", "value-update"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "algorithm", "round-robin"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "persistence", "cookie"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "idle_timeout", "600"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "sorry_page_url", "https://example.com/sorry"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "source_nat", "enable"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "certificate_id", "f57a98fe-d63e-4048-93a0-51fe163f30d7"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "health_monitor_id", "dd7a96d6-4e66-4666-baca-a8555f0c472c"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "listener_id", "68633f4f-f52a-402f-8572-b8173418904f"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "default_target_group_id", "a44c4072-ed90-4b50-a33a-6b38fb10c7db"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "tls_policy_id", "4ba79662-f2a1-41a4-a3d9-595799bbcd86"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_policy_v1.policy", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + ), + }, + }, + }) +} + +var testAccMLBV1Policy = fmt.Sprintf(` +resource "ecl_mlb_policy_v1" "policy" { + name = "policy" + description = "description" + tags = { + key = "value" + } + algorithm = "round-robin" + persistence = "cookie" + idle_timeout = 600 + sorry_page_url = "https://example.com/sorry" + source_nat = "enable" + certificate_id = "f57a98fe-d63e-4048-93a0-51fe163f30d7" + health_monitor_id = "dd7a96d6-4e66-4666-baca-a8555f0c472c" + listener_id = "68633f4f-f52a-402f-8572-b8173418904f" + default_target_group_id = "a44c4072-ed90-4b50-a33a-6b38fb10c7db" + tls_policy_id = "4ba79662-f2a1-41a4-a3d9-595799bbcd86" + load_balancer_id = "67fea379-cff0-4191-9175-de7d6941a040" +} +`) + +var testAccMLBV1PolicyUpdateBeforeApplyConfigurations = fmt.Sprintf(` +resource "ecl_mlb_policy_v1" "policy" { + name = "policy-update" + description = "description-update" + tags = { + key-update = "value-update" + } + algorithm = "least-connection" + persistence = "source-ip" + idle_timeout = 120 + sorry_page_url = "" + source_nat = "disable" + certificate_id = "" + health_monitor_id = "dd7a96d6-4e66-4666-baca-a8555f0c472c" + listener_id = "68633f4f-f52a-402f-8572-b8173418904f" + default_target_group_id = "a44c4072-ed90-4b50-a33a-6b38fb10c7db" + tls_policy_id = "" + load_balancer_id = "67fea379-cff0-4191-9175-de7d6941a040" +} +`) + +var testAccMLBV1PolicyUpdateAfterApplyConfigurations = fmt.Sprintf(` +resource "ecl_mlb_policy_v1" "policy" { + name = "policy-update" + description = "description-update" + tags = { + key-update = "value-update" + } + algorithm = "round-robin" + persistence = "cookie" + idle_timeout = 600 + sorry_page_url = "https://example.com/sorry" + source_nat = "enable" + certificate_id = "f57a98fe-d63e-4048-93a0-51fe163f30d7" + health_monitor_id = "dd7a96d6-4e66-4666-baca-a8555f0c472c" + listener_id = "68633f4f-f52a-402f-8572-b8173418904f" + default_target_group_id = "a44c4072-ed90-4b50-a33a-6b38fb10c7db" + tls_policy_id = "4ba79662-f2a1-41a4-a3d9-595799bbcd86" + load_balancer_id = "67fea379-cff0-4191-9175-de7d6941a040" +} +`) + +var testMockMLBV1PoliciesCreate = fmt.Sprintf(` +request: + method: POST + body: > + {"policy":{"algorithm":"round-robin","certificate_id":"f57a98fe-d63e-4048-93a0-51fe163f30d7","default_target_group_id":"a44c4072-ed90-4b50-a33a-6b38fb10c7db","description":"description","health_monitor_id":"dd7a96d6-4e66-4666-baca-a8555f0c472c","idle_timeout":600,"listener_id":"68633f4f-f52a-402f-8572-b8173418904f","load_balancer_id":"67fea379-cff0-4191-9175-de7d6941a040","name":"policy","persistence":"cookie","sorry_page_url":"https://example.com/sorry","source_nat":"enable","tags":{"key":"value"},"tls_policy_id":"4ba79662-f2a1-41a4-a3d9-595799bbcd86"}} +response: + code: 200 + body: > + { + "policy": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "policy", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "algorithm": null, + "persistence": null, + "idle_timeout": null, + "sorry_page_url": null, + "source_nat": null, + "certificate_id": null, + "health_monitor_id": null, + "listener_id": null, + "default_target_group_id": null, + "tls_policy_id": null + } + } +newStatus: Created +`) + +var testMockMLBV1PoliciesShowAfterCreate = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "policy": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "policy", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "algorithm": null, + "persistence": null, + "idle_timeout": null, + "sorry_page_url": null, + "source_nat": null, + "certificate_id": null, + "health_monitor_id": null, + "listener_id": null, + "default_target_group_id": null, + "tls_policy_id": null, + "current": null, + "staged": { + "algorithm": "round-robin", + "persistence": "cookie", + "idle_timeout": 600, + "sorry_page_url": "https://example.com/sorry", + "source_nat": "enable", + "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", + "health_monitor_id": "dd7a96d6-4e66-4666-baca-a8555f0c472c", + "listener_id": "68633f4f-f52a-402f-8572-b8173418904f", + "default_target_group_id": "a44c4072-ed90-4b50-a33a-6b38fb10c7db", + "tls_policy_id": "4ba79662-f2a1-41a4-a3d9-595799bbcd86" + } + } + } +expectedStatus: + - Created +`) + +var testMockMLBV1PoliciesShowBeforeUpdateConfigurations = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "policy": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "policy-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "algorithm": null, + "persistence": null, + "idle_timeout": null, + "sorry_page_url": null, + "source_nat": null, + "certificate_id": null, + "health_monitor_id": null, + "listener_id": null, + "default_target_group_id": null, + "tls_policy_id": null + } + } +expectedStatus: + - AttributesUpdated +`) + +var testMockMLBV1PoliciesShowAfterUpdateConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "policy": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "policy-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "algorithm": null, + "persistence": null, + "idle_timeout": null, + "sorry_page_url": null, + "source_nat": null, + "certificate_id": null, + "health_monitor_id": null, + "listener_id": null, + "default_target_group_id": null, + "tls_policy_id": null, + "current": null, + "staged": { + "algorithm": "least-connection", + "persistence": "source-ip", + "idle_timeout": 120, + "sorry_page_url": "", + "source_nat": "disable", + "certificate_id": "", + "health_monitor_id": "dd7a96d6-4e66-4666-baca-a8555f0c472c", + "listener_id": "68633f4f-f52a-402f-8572-b8173418904f", + "default_target_group_id": "a44c4072-ed90-4b50-a33a-6b38fb10c7db", + "tls_policy_id": "" + } + } + } +expectedStatus: + - ConfigurationsUpdatedBeforeApply +newStatus: ConfigurationsApplied +`) + +var testMockMLBV1PoliciesShowAfterApplyConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "policy": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "policy-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "ACTIVE", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "algorithm": "least-connection", + "persistence": "source-ip", + "idle_timeout": 120, + "sorry_page_url": "", + "source_nat": "disable", + "certificate_id": "", + "health_monitor_id": "dd7a96d6-4e66-4666-baca-a8555f0c472c", + "listener_id": "68633f4f-f52a-402f-8572-b8173418904f", + "default_target_group_id": "a44c4072-ed90-4b50-a33a-6b38fb10c7db", + "tls_policy_id": "", + "current": { + "algorithm": "least-connection", + "persistence": "source-ip", + "idle_timeout": 120, + "sorry_page_url": "", + "source_nat": "disable", + "certificate_id": "", + "health_monitor_id": "dd7a96d6-4e66-4666-baca-a8555f0c472c", + "listener_id": "68633f4f-f52a-402f-8572-b8173418904f", + "default_target_group_id": "a44c4072-ed90-4b50-a33a-6b38fb10c7db", + "tls_policy_id": "" + }, + "staged": null + } + } +expectedStatus: + - ConfigurationsApplied +`) + +var testMockMLBV1PoliciesShowBeforeCreateConfigurations = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "policy": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "policy-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "ACTIVE", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "algorithm": "least-connection", + "persistence": "source-ip", + "idle_timeout": 120, + "sorry_page_url": "", + "source_nat": "disable", + "certificate_id": "", + "health_monitor_id": "dd7a96d6-4e66-4666-baca-a8555f0c472c", + "listener_id": "68633f4f-f52a-402f-8572-b8173418904f", + "default_target_group_id": "a44c4072-ed90-4b50-a33a-6b38fb10c7db", + "tls_policy_id": "" + } + } +expectedStatus: + - ConfigurationsApplied +`) + +var testMockMLBV1PoliciesShowAfterCreateConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "policy": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "policy-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "UPDATE_STAGED", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "algorithm": "least-connection", + "persistence": "source-ip", + "idle_timeout": 120, + "sorry_page_url": "", + "source_nat": "disable", + "certificate_id": "", + "health_monitor_id": "dd7a96d6-4e66-4666-baca-a8555f0c472c", + "listener_id": "68633f4f-f52a-402f-8572-b8173418904f", + "default_target_group_id": "a44c4072-ed90-4b50-a33a-6b38fb10c7db", + "tls_policy_id": "", + "current": { + "algorithm": "least-connection", + "persistence": "source-ip", + "idle_timeout": 120, + "sorry_page_url": "", + "source_nat": "disable", + "certificate_id": "", + "health_monitor_id": "dd7a96d6-4e66-4666-baca-a8555f0c472c", + "listener_id": "68633f4f-f52a-402f-8572-b8173418904f", + "default_target_group_id": "a44c4072-ed90-4b50-a33a-6b38fb10c7db", + "tls_policy_id": "" + }, + "staged": { + "algorithm": "round-robin", + "persistence": "cookie", + "idle_timeout": 600, + "sorry_page_url": "https://example.com/sorry", + "source_nat": "enable", + "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", + "health_monitor_id": null, + "listener_id": null, + "default_target_group_id": null, + "tls_policy_id": "4ba79662-f2a1-41a4-a3d9-595799bbcd86" + } + } + } +expectedStatus: + - ConfigurationsUpdatedAfterApply +`) + +var testMockMLBV1PoliciesShowAfterDelete = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "policy": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "policy-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "DELETE_STAGED", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "algorithm": "least-connection", + "persistence": "source-ip", + "idle_timeout": 120, + "sorry_page_url": "", + "source_nat": "disable", + "certificate_id": "", + "health_monitor_id": "dd7a96d6-4e66-4666-baca-a8555f0c472c", + "listener_id": "68633f4f-f52a-402f-8572-b8173418904f", + "default_target_group_id": "a44c4072-ed90-4b50-a33a-6b38fb10c7db", + "tls_policy_id": "", + "current": { + "algorithm": "least-connection", + "persistence": "source-ip", + "idle_timeout": 120, + "sorry_page_url": "", + "source_nat": "disable", + "certificate_id": "", + "health_monitor_id": "dd7a96d6-4e66-4666-baca-a8555f0c472c", + "listener_id": "68633f4f-f52a-402f-8572-b8173418904f", + "default_target_group_id": "a44c4072-ed90-4b50-a33a-6b38fb10c7db", + "tls_policy_id": "" + }, + "staged": null + } + } +expectedStatus: + - Deleted +`) + +var testMockMLBV1PoliciesUpdateAttributes = fmt.Sprintf(` +request: + method: PATCH + body: > + {"policy":{"description":"description-update","name":"policy-update","tags":{"key-update":"value-update"}}} +response: + code: 200 + body: > + { + "policy": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "policy-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "algorithm": null, + "persistence": null, + "idle_timeout": null, + "sorry_page_url": null, + "source_nat": null, + "certificate_id": null, + "health_monitor_id": null, + "listener_id": null, + "default_target_group_id": null, + "tls_policy_id": null + } + } +expectedStatus: + - Created +newStatus: AttributesUpdated +`) + +var testMockMLBV1PoliciesCreateConfigurations = fmt.Sprintf(` +request: + method: POST + body: > + {"policy":{"algorithm":"round-robin","certificate_id":"f57a98fe-d63e-4048-93a0-51fe163f30d7","idle_timeout":600,"persistence":"cookie","sorry_page_url":"https://example.com/sorry","source_nat":"enable","tls_policy_id":"4ba79662-f2a1-41a4-a3d9-595799bbcd86"}} +response: + code: 200 + body: > + { + "policy": { + "algorithm": "round-robin", + "persistence": "cookie", + "idle_timeout": 600, + "sorry_page_url": "https://example.com/sorry", + "source_nat": "enable", + "certificate_id": "f57a98fe-d63e-4048-93a0-51fe163f30d7", + "health_monitor_id": null, + "listener_id": null, + "default_target_group_id": null, + "tls_policy_id": "4ba79662-f2a1-41a4-a3d9-595799bbcd86" + } + } +expectedStatus: + - ConfigurationsApplied +newStatus: ConfigurationsUpdatedAfterApply +`) + +var testMockMLBV1PoliciesUpdateConfigurations = fmt.Sprintf(` +request: + method: PATCH + body: > + {"policy":{"algorithm":"least-connection","certificate_id":"","idle_timeout":120,"persistence":"source-ip","sorry_page_url":"","source_nat":"disable","tls_policy_id":""}} +response: + code: 200 + body: > + { + "policy": { + "algorithm": "least-connection", + "persistence": "source-ip", + "idle_timeout": 120, + "sorry_page_url": "", + "source_nat": "disable", + "certificate_id": "", + "health_monitor_id": "dd7a96d6-4e66-4666-baca-a8555f0c472c", + "listener_id": "68633f4f-f52a-402f-8572-b8173418904f", + "default_target_group_id": "a44c4072-ed90-4b50-a33a-6b38fb10c7db", + "tls_policy_id": "" + } + } +expectedStatus: + - AttributesUpdated +newStatus: ConfigurationsUpdatedBeforeApply +`) + +var testMockMLBV1PoliciesDelete = fmt.Sprintf(` +request: + method: DELETE +response: + code: 204 +expectedStatus: + - Created + - ConfigurationsUpdatedAfterApply +newStatus: Deleted +`) diff --git a/ecl/resource_ecl_mlb_route_v1.go b/ecl/resource_ecl_mlb_route_v1.go new file mode 100644 index 00000000..84d8b7df --- /dev/null +++ b/ecl/resource_ecl_mlb_route_v1.go @@ -0,0 +1,254 @@ +package ecl + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/nttcom/eclcloud/v2" + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes" +) + +func resourceMLBRouteV1() *schema.Resource { + var result *schema.Resource + + result = &schema.Resource{ + Create: resourceMLBRouteV1Create, + Read: resourceMLBRouteV1Read, + Update: resourceMLBRouteV1Update, + Delete: resourceMLBRouteV1Delete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "tags": &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + }, + "destination_cidr": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "next_hop_ip_address": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "load_balancer_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "tenant_id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + }, + } + + return result +} + +func resourceMLBRouteV1Create(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + createOpts := routes.CreateOpts{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + Tags: d.Get("tags").(map[string]interface{}), + DestinationCidr: d.Get("destination_cidr").(string), + NextHopIPAddress: d.Get("next_hop_ip_address").(string), + LoadBalancerID: d.Get("load_balancer_id").(string), + } + + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Creating ECL managed load balancer route with options %+v", createOpts) + + route, err := routes.Create(managedLoadBalancerClient, createOpts).Extract() + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer route with options %+v: %s", createOpts, err) + } + + d.SetId(route.ID) + log.Printf("[INFO] ECL managed load balancer route ID: %s", route.ID) + + return resourceMLBRouteV1Read(d, meta) +} + +func resourceMLBRouteV1Show(d *schema.ResourceData, client *eclcloud.ServiceClient, changes bool) (*routes.Route, error) { + var route routes.Route + + showOpts := routes.ShowOpts{Changes: changes} + err := routes.Show(client, d.Id(), showOpts).ExtractInto(&route) + if err != nil { + return nil, fmt.Errorf("Unable to retrieve ECL managed load balancer route (%s): %s", d.Id(), err) + } + + return &route, nil +} + +func resourceMLBRouteV1Read(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + route, err := resourceMLBRouteV1Show(d, managedLoadBalancerClient, true) + if err != nil { + return CheckDeleted(d, err, "route") + } + + if route.ConfigurationStatus == "ACTIVE" { + d.Set("next_hop_ip_address", route.NextHopIPAddress) + } else if route.ConfigurationStatus == "CREATE_STAGED" { + d.Set("next_hop_ip_address", route.Staged.NextHopIPAddress) + } else if route.ConfigurationStatus == "UPDATE_STAGED" { + d.Set("next_hop_ip_address", ternary(route.Staged.NextHopIPAddress == "", route.NextHopIPAddress, route.Staged.NextHopIPAddress)) + } else if route.ConfigurationStatus == "DELETE_STAGED" { + d.SetId("") + return nil + } + + d.Set("name", route.Name) + d.Set("description", route.Description) + d.Set("tags", route.Tags) + d.Set("destination_cidr", route.DestinationCidr) + d.Set("load_balancer_id", route.LoadBalancerID) + d.Set("tenant_id", route.TenantID) + + return nil +} + +func resourceMLBRouteV1Update(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Start updating attributes of ECL managed load balancer route ...") + + err = resourceMLBRouteV1UpdateAttributes(d, managedLoadBalancerClient) + if err != nil { + return fmt.Errorf("Error in updating attributes of ECL managed load balancer route: %s", err) + } + + log.Printf("[DEBUG] Start updating configurations of ECL managed load balancer route ...") + + err = resourceMLBRouteV1UpdateConfigurations(d, managedLoadBalancerClient) + if err != nil { + return fmt.Errorf("Error in updating configurations of ECL managed load balancer route: %s", err) + } + + return resourceMLBRouteV1Read(d, meta) +} + +func resourceMLBRouteV1UpdateAttributes(d *schema.ResourceData, client *eclcloud.ServiceClient) error { + var isAttributesUpdated bool + var updateOpts routes.UpdateOpts + + if d.HasChange("name") { + isAttributesUpdated = true + name := d.Get("name").(string) + updateOpts.Name = &name + } + + if d.HasChange("description") { + isAttributesUpdated = true + description := d.Get("description").(string) + updateOpts.Description = &description + } + + if d.HasChange("tags") { + isAttributesUpdated = true + tags := d.Get("tags").(map[string]interface{}) + updateOpts.Tags = &tags + } + + if isAttributesUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer route attributes (%s) with options %+v", d.Id(), updateOpts) + + _, err := routes.Update(client, d.Id(), updateOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer route attributes (%s) with options %+v: %s", d.Id(), updateOpts, err) + } + } + + return nil +} + +func resourceMLBRouteV1UpdateConfigurations(d *schema.ResourceData, client *eclcloud.ServiceClient) error { + var isConfigurationsUpdated bool + + route, err := resourceMLBRouteV1Show(d, client, false) + if err != nil { + return err + } + + if route.ConfigurationStatus == "ACTIVE" { + var createStagedOpts routes.CreateStagedOpts + + if d.HasChange("next_hop_ip_address") { + isConfigurationsUpdated = true + createStagedOpts.NextHopIPAddress = d.Get("next_hop_ip_address").(string) + } + + if isConfigurationsUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer route configurations (%s) with options %+v", d.Id(), createStagedOpts) + + _, err := routes.CreateStaged(client, d.Id(), createStagedOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer route configurations (%s) with options %+v: %s", d.Id(), createStagedOpts, err) + } + } + } else { + var updateStagedOpts routes.UpdateStagedOpts + + if d.HasChange("next_hop_ip_address") { + isConfigurationsUpdated = true + nextHopIPAddress := d.Get("next_hop_ip_address").(string) + updateStagedOpts.NextHopIPAddress = &nextHopIPAddress + } + + if isConfigurationsUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer route configurations (%s) with options %+v", d.Id(), updateStagedOpts) + + _, err := routes.UpdateStaged(client, d.Id(), updateStagedOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer route configurations (%s) with options %+v: %s", d.Id(), updateStagedOpts, err) + } + } + } + + return nil +} + +func resourceMLBRouteV1Delete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Deleting ECL managed load balancer route: %s", d.Id()) + + err = routes.Delete(managedLoadBalancerClient, d.Id()).ExtractErr() + if err != nil { + return fmt.Errorf("Error deleting ECL managed load balancer route: %s", err) + } + + return nil +} diff --git a/ecl/resource_ecl_mlb_route_v1_mock_test.go b/ecl/resource_ecl_mlb_route_v1_mock_test.go new file mode 100644 index 00000000..425ae9f9 --- /dev/null +++ b/ecl/resource_ecl_mlb_route_v1_mock_test.go @@ -0,0 +1,442 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1RouteResource(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "routes", "/v1.0/routes", testMockMLBV1RoutesCreate) + mc.Register(t, "routes", "/v1.0/routes/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RoutesShowAfterCreate) + mc.Register(t, "routes", "/v1.0/routes/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RoutesUpdateAttributes) + mc.Register(t, "routes", "/v1.0/routes/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RoutesShowBeforeUpdateConfigurations) + mc.Register(t, "routes", "/v1.0/routes/497f6eca-6276-4993-bfeb-53cbbbba6f08/staged", testMockMLBV1RoutesUpdateConfigurations) + mc.Register(t, "routes", "/v1.0/routes/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RoutesShowAfterUpdateConfigurations) + // Staged configurations of the load balancer and related resources are applied here + mc.Register(t, "routes", "/v1.0/routes/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RoutesShowAfterApplyConfigurations) + mc.Register(t, "routes", "/v1.0/routes/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RoutesShowBeforeCreateConfigurations) + mc.Register(t, "routes", "/v1.0/routes/497f6eca-6276-4993-bfeb-53cbbbba6f08/staged", testMockMLBV1RoutesCreateConfigurations) + mc.Register(t, "routes", "/v1.0/routes/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RoutesShowAfterCreateConfigurations) + mc.Register(t, "routes", "/v1.0/routes/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RoutesDelete) + mc.Register(t, "routes", "/v1.0/routes/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RoutesShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1Route, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "name", "route"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "description", "description"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "tags.key", "value"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "destination_cidr", "172.16.0.0/24"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "next_hop_ip_address", "192.168.0.254"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + ), + }, + { + Config: testAccMLBV1RouteUpdateBeforeApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "name", "route-update"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "description", "description-update"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "tags.key-update", "value-update"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "destination_cidr", "172.16.0.0/24"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "next_hop_ip_address", "192.168.1.254"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + ), + }, + { + Config: testAccMLBV1RouteUpdateAfterApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "name", "route-update"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "description", "description-update"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "tags.key-update", "value-update"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "destination_cidr", "172.16.0.0/24"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "next_hop_ip_address", "192.168.0.254"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_route_v1.route", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + ), + }, + }, + }) +} + +var testAccMLBV1Route = fmt.Sprintf(` +resource "ecl_mlb_route_v1" "route" { + name = "route" + description = "description" + tags = { + key = "value" + } + destination_cidr = "172.16.0.0/24" + next_hop_ip_address = "192.168.0.254" + load_balancer_id = "67fea379-cff0-4191-9175-de7d6941a040" +} +`) + +var testAccMLBV1RouteUpdateBeforeApplyConfigurations = fmt.Sprintf(` +resource "ecl_mlb_route_v1" "route" { + name = "route-update" + description = "description-update" + tags = { + key-update = "value-update" + } + destination_cidr = "172.16.0.0/24" + next_hop_ip_address = "192.168.1.254" + load_balancer_id = "67fea379-cff0-4191-9175-de7d6941a040" +} +`) + +var testAccMLBV1RouteUpdateAfterApplyConfigurations = fmt.Sprintf(` +resource "ecl_mlb_route_v1" "route" { + name = "route-update" + description = "description-update" + tags = { + key-update = "value-update" + } + destination_cidr = "172.16.0.0/24" + next_hop_ip_address = "192.168.0.254" + load_balancer_id = "67fea379-cff0-4191-9175-de7d6941a040" +} +`) + +var testMockMLBV1RoutesCreate = fmt.Sprintf(` +request: + method: POST + body: > + {"route":{"description":"description","destination_cidr":"172.16.0.0/24","load_balancer_id":"67fea379-cff0-4191-9175-de7d6941a040","name":"route","next_hop_ip_address":"192.168.0.254","tags":{"key":"value"}}} +response: + code: 200 + body: > + { + "route": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "route", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "destination_cidr": "172.16.0.0/24", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "next_hop_ip_address": null + } + } +newStatus: Created +`) + +var testMockMLBV1RoutesShowAfterCreate = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "route": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "route", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "destination_cidr": "172.16.0.0/24", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "next_hop_ip_address": null, + "current": null, + "staged": { + "next_hop_ip_address": "192.168.0.254" + } + } + } +expectedStatus: + - Created +`) + +var testMockMLBV1RoutesShowBeforeUpdateConfigurations = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "route": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "route-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "destination_cidr": "172.16.0.0/24", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "next_hop_ip_address": null + } + } +expectedStatus: + - AttributesUpdated +`) + +var testMockMLBV1RoutesShowAfterUpdateConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "route": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "route-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "destination_cidr": "172.16.0.0/24", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "next_hop_ip_address": null, + "current": null, + "staged": { + "next_hop_ip_address": "192.168.1.254" + } + } + } +expectedStatus: + - ConfigurationsUpdatedBeforeApply +newStatus: ConfigurationsApplied +`) + +var testMockMLBV1RoutesShowAfterApplyConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "route": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "route-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "ACTIVE", + "operation_status": "COMPLETE", + "destination_cidr": "172.16.0.0/24", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "next_hop_ip_address": "192.168.1.254", + "current": { + "next_hop_ip_address": "192.168.1.254" + }, + "staged": null + } + } +expectedStatus: + - ConfigurationsApplied +`) + +var testMockMLBV1RoutesShowBeforeCreateConfigurations = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "route": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "route-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "ACTIVE", + "operation_status": "COMPLETE", + "destination_cidr": "172.16.0.0/24", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "next_hop_ip_address": "192.168.1.254" + } + } +expectedStatus: + - ConfigurationsApplied +`) + +var testMockMLBV1RoutesShowAfterCreateConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "route": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "route-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "UPDATE_STAGED", + "operation_status": "COMPLETE", + "destination_cidr": "172.16.0.0/24", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "next_hop_ip_address": "192.168.1.254", + "current": { + "next_hop_ip_address": "192.168.1.254" + }, + "staged": { + "next_hop_ip_address": "192.168.0.254" + } + } + } +expectedStatus: + - ConfigurationsUpdatedAfterApply +`) + +var testMockMLBV1RoutesShowAfterDelete = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "route": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "route-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "DELETE_STAGED", + "operation_status": "COMPLETE", + "destination_cidr": "172.16.0.0/24", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "next_hop_ip_address": "192.168.1.254", + "current": { + "next_hop_ip_address": "192.168.1.254" + }, + "staged": null + } + } +expectedStatus: + - Deleted +`) + +var testMockMLBV1RoutesUpdateAttributes = fmt.Sprintf(` +request: + method: PATCH + body: > + {"route":{"description":"description-update","name":"route-update","tags":{"key-update":"value-update"}}} +response: + code: 200 + body: > + { + "route": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "route-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "destination_cidr": "172.16.0.0/24", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "next_hop_ip_address": null + } + } +expectedStatus: + - Created +newStatus: AttributesUpdated +`) + +var testMockMLBV1RoutesCreateConfigurations = fmt.Sprintf(` +request: + method: POST + body: > + {"route":{"next_hop_ip_address":"192.168.0.254"}} +response: + code: 200 + body: > + { + "route": { + "next_hop_ip_address": "192.168.0.254" + } + } +expectedStatus: + - ConfigurationsApplied +newStatus: ConfigurationsUpdatedAfterApply +`) + +var testMockMLBV1RoutesUpdateConfigurations = fmt.Sprintf(` +request: + method: PATCH + body: > + {"route":{"next_hop_ip_address":"192.168.1.254"}} +response: + code: 200 + body: > + { + "route": { + "next_hop_ip_address": "192.168.1.254" + } + } +expectedStatus: + - AttributesUpdated +newStatus: ConfigurationsUpdatedBeforeApply +`) + +var testMockMLBV1RoutesDelete = fmt.Sprintf(` +request: + method: DELETE +response: + code: 204 +expectedStatus: + - Created + - ConfigurationsUpdatedAfterApply +newStatus: Deleted +`) diff --git a/ecl/resource_ecl_mlb_rule_v1.go b/ecl/resource_ecl_mlb_rule_v1.go new file mode 100644 index 00000000..8fb8f9c6 --- /dev/null +++ b/ecl/resource_ecl_mlb_rule_v1.go @@ -0,0 +1,332 @@ +package ecl + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/nttcom/eclcloud/v2" + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules" +) + +func conditionsSchemaForResource() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Required: true, + MinItems: 1, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "path_patterns": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + } +} + +func resourceMLBRuleV1() *schema.Resource { + var result *schema.Resource + + result = &schema.Resource{ + Create: resourceMLBRuleV1Create, + Read: resourceMLBRuleV1Read, + Update: resourceMLBRuleV1Update, + Delete: resourceMLBRuleV1Delete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "tags": &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + }, + "priority": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + }, + "target_group_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "policy_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "load_balancer_id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "tenant_id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "conditions": conditionsSchemaForResource(), + }, + } + + return result +} + +func resourceMLBRuleV1Create(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + createOpts := rules.CreateOpts{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + Tags: d.Get("tags").(map[string]interface{}), + Priority: d.Get("priority").(int), + TargetGroupID: d.Get("target_group_id").(string), + PolicyID: d.Get("policy_id").(string), + } + + pathPatterns := make([]string, len(d.Get("conditions").([]interface{})[0].(map[string]interface{})["path_patterns"].([]interface{}))) + for i, pathPattern := range d.Get("conditions").([]interface{})[0].(map[string]interface{})["path_patterns"].([]interface{}) { + pathPatterns[i] = pathPattern.(string) + } + + condition := rules.CreateOptsCondition{ + PathPatterns: pathPatterns, + } + createOpts.Conditions = &condition + + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Creating ECL managed load balancer rule with options %+v", createOpts) + + rule, err := rules.Create(managedLoadBalancerClient, createOpts).Extract() + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer rule with options %+v: %s", createOpts, err) + } + + d.SetId(rule.ID) + log.Printf("[INFO] ECL managed load balancer rule ID: %s", rule.ID) + + return resourceMLBRuleV1Read(d, meta) +} + +func resourceMLBRuleV1Show(d *schema.ResourceData, client *eclcloud.ServiceClient, changes bool) (*rules.Rule, error) { + var rule rules.Rule + + showOpts := rules.ShowOpts{Changes: changes} + err := rules.Show(client, d.Id(), showOpts).ExtractInto(&rule) + if err != nil { + return nil, fmt.Errorf("Unable to retrieve ECL managed load balancer rule (%s): %s", d.Id(), err) + } + + return &rule, nil +} + +func resourceMLBRuleV1Read(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + rule, err := resourceMLBRuleV1Show(d, managedLoadBalancerClient, true) + if err != nil { + return CheckDeleted(d, err, "rule") + } + + log.Printf("[DEBUG] Retrieved ECL managed load balancer rule (%s): %+v", d.Id(), rule) + + conditions := make(map[string]interface{}) + + if rule.ConfigurationStatus == "ACTIVE" { + d.Set("priority", rule.Priority) + d.Set("target_group_id", rule.TargetGroupID) + conditions["path_patterns"] = rule.Conditions.PathPatterns + } else if rule.ConfigurationStatus == "CREATE_STAGED" { + d.Set("priority", rule.Staged.Priority) + d.Set("target_group_id", rule.Staged.TargetGroupID) + conditions["path_patterns"] = rule.Staged.Conditions.PathPatterns + } else if rule.ConfigurationStatus == "UPDATE_STAGED" { + d.Set("priority", ternary(rule.Staged.Priority == 0, rule.Priority, rule.Staged.Priority)) + d.Set("target_group_id", ternary(rule.Staged.TargetGroupID == "", rule.TargetGroupID, rule.Staged.TargetGroupID)) + conditions["path_patterns"] = ternary(rule.Staged.Conditions.PathPatterns == nil, rule.Conditions.PathPatterns, rule.Staged.Conditions.PathPatterns) + } else if rule.ConfigurationStatus == "DELETE_STAGED" { + d.SetId("") + return nil + } + + d.Set("name", rule.Name) + d.Set("description", rule.Description) + d.Set("tags", rule.Tags) + d.Set("policy_id", rule.PolicyID) + d.Set("load_balancer_id", rule.LoadBalancerID) + d.Set("tenant_id", rule.TenantID) + d.Set("conditions", []interface{}{conditions}) + + return nil +} + +func resourceMLBRuleV1Update(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Start updating attributes of ECL managed load balancer rule ...") + + err = resourceMLBRuleV1UpdateAttributes(d, managedLoadBalancerClient) + if err != nil { + return fmt.Errorf("Error in updating attributes of ECL managed load balancer rule: %s", err) + } + + log.Printf("[DEBUG] Start updating configurations of ECL managed load balancer rule ...") + + err = resourceMLBRuleV1UpdateConfigurations(d, managedLoadBalancerClient) + if err != nil { + return fmt.Errorf("Error in updating configurations of ECL managed load balancer rule: %s", err) + } + + return resourceMLBRuleV1Read(d, meta) +} + +func resourceMLBRuleV1UpdateAttributes(d *schema.ResourceData, client *eclcloud.ServiceClient) error { + var isAttributesUpdated bool + var updateOpts rules.UpdateOpts + + if d.HasChange("name") { + isAttributesUpdated = true + name := d.Get("name").(string) + updateOpts.Name = &name + } + + if d.HasChange("description") { + isAttributesUpdated = true + description := d.Get("description").(string) + updateOpts.Description = &description + } + + if d.HasChange("tags") { + isAttributesUpdated = true + tags := d.Get("tags").(map[string]interface{}) + updateOpts.Tags = &tags + } + + if isAttributesUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer rule attributes (%s) with options %+v", d.Id(), updateOpts) + + _, err := rules.Update(client, d.Id(), updateOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer rule attributes (%s) with options %+v: %s", d.Id(), updateOpts, err) + } + } + + return nil +} + +func resourceMLBRuleV1UpdateConfigurations(d *schema.ResourceData, client *eclcloud.ServiceClient) error { + var isConfigurationsUpdated bool + + pathPatterns := make([]string, len(d.Get("conditions").([]interface{})[0].(map[string]interface{})["path_patterns"].([]interface{}))) + for i, pathPattern := range d.Get("conditions").([]interface{})[0].(map[string]interface{})["path_patterns"].([]interface{}) { + pathPatterns[i] = pathPattern.(string) + } + + rule, err := resourceMLBRuleV1Show(d, client, false) + if err != nil { + return err + } + + if rule.ConfigurationStatus == "ACTIVE" { + var createStagedOpts rules.CreateStagedOpts + + if d.HasChange("priority") { + isConfigurationsUpdated = true + createStagedOpts.Priority = d.Get("priority").(int) + } + + if d.HasChange("target_group_id") { + isConfigurationsUpdated = true + createStagedOpts.TargetGroupID = d.Get("target_group_id").(string) + } + + if d.HasChange("conditions") { + isConfigurationsUpdated = true + condition := rules.CreateStagedOptsCondition{ + PathPatterns: pathPatterns, + } + createStagedOpts.Conditions = &condition + } + + if isConfigurationsUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer rule configurations (%s) with options %+v", d.Id(), createStagedOpts) + + _, err := rules.CreateStaged(client, d.Id(), createStagedOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer rule configurations (%s) with options %+v: %s", d.Id(), createStagedOpts, err) + } + } + } else { + var updateStagedOpts rules.UpdateStagedOpts + + if d.HasChange("priority") { + isConfigurationsUpdated = true + priority := d.Get("priority").(int) + updateStagedOpts.Priority = &priority + } + + if d.HasChange("target_group_id") { + isConfigurationsUpdated = true + targetGroupID := d.Get("target_group_id").(string) + updateStagedOpts.TargetGroupID = &targetGroupID + } + + if d.HasChange("conditions") { + isConfigurationsUpdated = true + condition := rules.UpdateStagedOptsCondition{ + PathPatterns: &pathPatterns, + } + updateStagedOpts.Conditions = &condition + } + + if isConfigurationsUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer rule configurations (%s) with options %+v", d.Id(), updateStagedOpts) + + _, err := rules.UpdateStaged(client, d.Id(), updateStagedOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer rule configurations (%s) with options %+v: %s", d.Id(), updateStagedOpts, err) + } + } + } + + return nil +} + +func resourceMLBRuleV1Delete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Deleting ECL managed load balancer rule: %s", d.Id()) + + err = rules.Delete(managedLoadBalancerClient, d.Id()).ExtractErr() + if err != nil { + return fmt.Errorf("Error deleting ECL managed load balancer rule: %s", err) + } + + return nil +} diff --git a/ecl/resource_ecl_mlb_rule_v1_mock_test.go b/ecl/resource_ecl_mlb_rule_v1_mock_test.go new file mode 100644 index 00000000..61945104 --- /dev/null +++ b/ecl/resource_ecl_mlb_rule_v1_mock_test.go @@ -0,0 +1,516 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1RuleResource(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "rules", "/v1.0/rules", testMockMLBV1RulesCreate) + mc.Register(t, "rules", "/v1.0/rules/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RulesShowAfterCreate) + mc.Register(t, "rules", "/v1.0/rules/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RulesUpdateAttributes) + mc.Register(t, "rules", "/v1.0/rules/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RulesShowBeforeUpdateConfigurations) + mc.Register(t, "rules", "/v1.0/rules/497f6eca-6276-4993-bfeb-53cbbbba6f08/staged", testMockMLBV1RulesUpdateConfigurations) + mc.Register(t, "rules", "/v1.0/rules/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RulesShowAfterUpdateConfigurations) + // Staged configurations of the load balancer and related resources are applied here + mc.Register(t, "rules", "/v1.0/rules/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RulesShowAfterApplyConfigurations) + mc.Register(t, "rules", "/v1.0/rules/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RulesShowBeforeCreateConfigurations) + mc.Register(t, "rules", "/v1.0/rules/497f6eca-6276-4993-bfeb-53cbbbba6f08/staged", testMockMLBV1RulesCreateConfigurations) + mc.Register(t, "rules", "/v1.0/rules/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RulesShowAfterCreateConfigurations) + mc.Register(t, "rules", "/v1.0/rules/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RulesDelete) + mc.Register(t, "rules", "/v1.0/rules/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1RulesShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1Rule, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "name", "rule"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "description", "description"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "tags.key", "value"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "priority", "1"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "target_group_id", "29527a3c-9e5d-48b7-868f-6442c7d21a95"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "policy_id", "fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "conditions.0.path_patterns.0", "^/statics/"), + ), + }, + { + Config: testAccMLBV1RuleUpdateBeforeApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "name", "rule-update"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "description", "description-update"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "tags.key-update", "value-update"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "priority", "1"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "target_group_id", "29527a3c-9e5d-48b7-868f-6442c7d21a95"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "policy_id", "fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "conditions.0.path_patterns.0", "^/statics/"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "conditions.0.path_patterns.1", "^/assets/"), + ), + }, + { + Config: testAccMLBV1RuleUpdateAfterApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "name", "rule-update"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "description", "description-update"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "tags.key-update", "value-update"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "priority", "1"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "target_group_id", "29527a3c-9e5d-48b7-868f-6442c7d21a95"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "policy_id", "fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + resource.TestCheckResourceAttr("ecl_mlb_rule_v1.rule", "conditions.0.path_patterns.0", "^/assets/"), + ), + }, + }, + }) +} + +var testAccMLBV1Rule = fmt.Sprintf(` +resource "ecl_mlb_rule_v1" "rule" { + name = "rule" + description = "description" + tags = { + key = "value" + } + priority = 1 + target_group_id = "29527a3c-9e5d-48b7-868f-6442c7d21a95" + policy_id = "fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4" + conditions { + path_patterns = ["^/statics/"] + } +} +`) + +var testAccMLBV1RuleUpdateBeforeApplyConfigurations = fmt.Sprintf(` +resource "ecl_mlb_rule_v1" "rule" { + name = "rule-update" + description = "description-update" + tags = { + key-update = "value-update" + } + priority = 1 + target_group_id = "29527a3c-9e5d-48b7-868f-6442c7d21a95" + policy_id = "fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4" + conditions { + path_patterns = ["^/statics/", "^/assets/"] + } +} +`) + +var testAccMLBV1RuleUpdateAfterApplyConfigurations = fmt.Sprintf(` +resource "ecl_mlb_rule_v1" "rule" { + name = "rule-update" + description = "description-update" + tags = { + key-update = "value-update" + } + priority = 1 + target_group_id = "29527a3c-9e5d-48b7-868f-6442c7d21a95" + policy_id = "fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4" + conditions { + path_patterns = ["^/assets/"] + } +} +`) + +var testMockMLBV1RulesCreate = fmt.Sprintf(` +request: + method: POST + body: > + {"rule":{"conditions":{"path_patterns":["^/statics/"]},"description":"description","name":"rule","policy_id":"fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4","priority":1,"tags":{"key":"value"},"target_group_id":"29527a3c-9e5d-48b7-868f-6442c7d21a95"}} +response: + code: 200 + body: > + { + "rule": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "rule", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "policy_id": "fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "priority": null, + "target_group_id": null, + "conditions": null + } + } +newStatus: Created +`) + +var testMockMLBV1RulesShowAfterCreate = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "rule": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "rule", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "policy_id": "fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "priority": null, + "target_group_id": null, + "conditions": null, + "current": null, + "staged": { + "priority": 1, + "target_group_id": "29527a3c-9e5d-48b7-868f-6442c7d21a95", + "conditions": { + "path_patterns": ["^/statics/"] + } + } + } + } +expectedStatus: + - Created +`) + +var testMockMLBV1RulesShowBeforeUpdateConfigurations = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "rule": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "rule-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "policy_id": "fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "priority": null, + "target_group_id": null, + "conditions": null + } + } +expectedStatus: + - AttributesUpdated +`) + +var testMockMLBV1RulesShowAfterUpdateConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "rule": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "rule-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "policy_id": "fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "priority": null, + "target_group_id": null, + "conditions": null, + "current": null, + "staged": { + "priority": 1, + "target_group_id": "29527a3c-9e5d-48b7-868f-6442c7d21a95", + "conditions": { + "path_patterns": ["^/statics/", "^/assets/"] + } + } + } + } +expectedStatus: + - ConfigurationsUpdatedBeforeApply +newStatus: ConfigurationsApplied +`) + +var testMockMLBV1RulesShowAfterApplyConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "rule": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "rule-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "ACTIVE", + "operation_status": "COMPLETE", + "policy_id": "fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "priority": 1, + "target_group_id": "29527a3c-9e5d-48b7-868f-6442c7d21a95", + "conditions": { + "path_patterns": ["^/statics/", "^/assets/"] + }, + "current": { + "priority": 1, + "target_group_id": "29527a3c-9e5d-48b7-868f-6442c7d21a95", + "conditions": { + "path_patterns": ["^/statics/", "^/assets/"] + } + }, + "staged": null + } + } +expectedStatus: + - ConfigurationsApplied +`) + +var testMockMLBV1RulesShowBeforeCreateConfigurations = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "rule": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "rule-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "ACTIVE", + "operation_status": "COMPLETE", + "policy_id": "fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "priority": 1, + "target_group_id": "29527a3c-9e5d-48b7-868f-6442c7d21a95", + "conditions": { + "path_patterns": ["^/statics/", "^/assets/"] + } + } + } +expectedStatus: + - ConfigurationsApplied +`) + +var testMockMLBV1RulesShowAfterCreateConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "rule": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "rule-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "UPDATE_STAGED", + "operation_status": "COMPLETE", + "policy_id": "fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "priority": 1, + "target_group_id": "29527a3c-9e5d-48b7-868f-6442c7d21a95", + "conditions": { + "path_patterns": ["^/statics/", "^/assets/"] + }, + "current": { + "priority": 1, + "target_group_id": "29527a3c-9e5d-48b7-868f-6442c7d21a95", + "conditions": { + "path_patterns": ["^/statics/", "^/assets/"] + } + }, + "staged": { + "priority": null, + "target_group_id": null, + "conditions": { + "path_patterns": ["^/assets/"] + } + } + } + } +expectedStatus: + - ConfigurationsUpdatedAfterApply +`) + +var testMockMLBV1RulesShowAfterDelete = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "rule": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "rule-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "DELETE_STAGED", + "operation_status": "COMPLETE", + "policy_id": "fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "priority": 1, + "target_group_id": "29527a3c-9e5d-48b7-868f-6442c7d21a95", + "conditions": { + "path_patterns": ["^/statics/", "^/assets/"] + }, + "current": { + "priority": 1, + "target_group_id": "29527a3c-9e5d-48b7-868f-6442c7d21a95", + "conditions": { + "path_patterns": ["^/statics/", "^/assets/"] + } + }, + "staged": null + } + } +expectedStatus: + - Deleted +`) + +var testMockMLBV1RulesUpdateAttributes = fmt.Sprintf(` +request: + method: PATCH + body: > + {"rule":{"description":"description-update","name":"rule-update","tags":{"key-update":"value-update"}}} +response: + code: 200 + body: > + { + "rule": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "rule-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "policy_id": "fcb520e5-858d-4f9f-bc6c-7bd225fe7cf4", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "priority": null, + "target_group_id": null, + "conditions": null + } + } +expectedStatus: + - Created +newStatus: AttributesUpdated +`) + +var testMockMLBV1RulesCreateConfigurations = fmt.Sprintf(` +request: + method: POST + body: > + {"rule":{"conditions":{"path_patterns":["^/assets/"]}}} +response: + code: 200 + body: > + { + "rule": { + "priority": null, + "target_group_id": null, + "conditions": { + "path_patterns": ["^/assets/"] + } + } + } +expectedStatus: + - ConfigurationsApplied +newStatus: ConfigurationsUpdatedAfterApply +`) + +var testMockMLBV1RulesUpdateConfigurations = fmt.Sprintf(` +request: + method: PATCH + body: > + {"rule":{"conditions":{"path_patterns":["^/statics/","^/assets/"]}}} +response: + code: 200 + body: > + { + "rule": { + "priority": 1, + "target_group_id": "29527a3c-9e5d-48b7-868f-6442c7d21a95", + "conditions": { + "path_patterns": ["^/statics/", "^/assets/"] + } + } + } +expectedStatus: + - AttributesUpdated +newStatus: ConfigurationsUpdatedBeforeApply +`) + +var testMockMLBV1RulesDelete = fmt.Sprintf(` +request: + method: DELETE +response: + code: 204 +expectedStatus: + - Created + - ConfigurationsUpdatedAfterApply +newStatus: Deleted +`) diff --git a/ecl/resource_ecl_mlb_target_group_v1.go b/ecl/resource_ecl_mlb_target_group_v1.go new file mode 100644 index 00000000..dfe5bb0a --- /dev/null +++ b/ecl/resource_ecl_mlb_target_group_v1.go @@ -0,0 +1,315 @@ +package ecl + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/nttcom/eclcloud/v2" + "github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups" +) + +func membersSchemaForResource() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Required: true, + MinItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip_address": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "port": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + }, + "weight": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + }, + }, + }, + } +} + +func resourceMLBTargetGroupV1() *schema.Resource { + var result *schema.Resource + + result = &schema.Resource{ + Read: resourceMLBTargetGroupV1Read, + Create: resourceMLBTargetGroupV1Create, + Update: resourceMLBTargetGroupV1Update, + Delete: resourceMLBTargetGroupV1Delete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "tags": &schema.Schema{ + Type: schema.TypeMap, + Optional: true, + }, + "load_balancer_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "tenant_id": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "members": membersSchemaForResource(), + }, + } + + return result +} + +func resourceMLBTargetGroupV1Create(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + createOpts := target_groups.CreateOpts{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + Tags: d.Get("tags").(map[string]interface{}), + LoadBalancerID: d.Get("load_balancer_id").(string), + } + + members := make([]target_groups.CreateOptsMember, len(d.Get("members").([]interface{}))) + for i, member := range d.Get("members").([]interface{}) { + members[i] = target_groups.CreateOptsMember{ + IPAddress: member.(map[string]interface{})["ip_address"].(string), + Port: member.(map[string]interface{})["port"].(int), + Weight: member.(map[string]interface{})["weight"].(int), + } + } + createOpts.Members = &members + + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Creating ECL managed load balancer target group with options %+v", createOpts) + + rule, err := target_groups.Create(managedLoadBalancerClient, createOpts).Extract() + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer target group with options %+v: %s", createOpts, err) + } + + d.SetId(rule.ID) + log.Printf("[INFO] ECL managed load balancer target group ID: %s", rule.ID) + + return resourceMLBTargetGroupV1Read(d, meta) +} + +func resourceMLBTargetGroupV1Show(d *schema.ResourceData, client *eclcloud.ServiceClient, changes bool) (*target_groups.TargetGroup, error) { + var targetGroup target_groups.TargetGroup + + showOpts := target_groups.ShowOpts{Changes: changes} + err := target_groups.Show(client, d.Id(), showOpts).ExtractInto(&targetGroup) + if err != nil { + return nil, fmt.Errorf("Unable to retrieve ECL managed load balancer target group (%s): %s", d.Id(), err) + } + + return &targetGroup, nil +} + +func resourceMLBTargetGroupV1Read(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + targetGroup, err := resourceMLBTargetGroupV1Show(d, managedLoadBalancerClient, true) + if err != nil { + return CheckDeleted(d, err, "target_group") + } + + log.Printf("[DEBUG] Retrieved ECL managed load balancer target group (%s): %+v", d.Id(), targetGroup) + + if targetGroup.ConfigurationStatus == "ACTIVE" || (targetGroup.ConfigurationStatus == "UPDATE_STAGED" && targetGroup.Members == nil) { + members := make([]interface{}, len(targetGroup.Members)) + for i, member := range targetGroup.Members { + members[i] = map[string]interface{}{ + "ip_address": member.IPAddress, + "port": member.Port, + "weight": member.Weight, + } + } + + d.Set("members", members) + } else if targetGroup.ConfigurationStatus == "CREATE_STAGED" || (targetGroup.ConfigurationStatus == "UPDATE_STAGED" && targetGroup.Members != nil) { + members := make([]interface{}, len(targetGroup.Staged.Members)) + for i, member := range targetGroup.Staged.Members { + members[i] = map[string]interface{}{ + "ip_address": member.IPAddress, + "port": member.Port, + "weight": member.Weight, + } + } + + d.Set("members", members) + } else if targetGroup.ConfigurationStatus == "DELETE_STAGED" { + d.SetId("") + return nil + } + + d.Set("name", targetGroup.Name) + d.Set("description", targetGroup.Description) + d.Set("tags", targetGroup.Tags) + d.Set("load_balancer_id", targetGroup.LoadBalancerID) + d.Set("tenant_id", targetGroup.TenantID) + + return nil +} + +func resourceMLBTargetGroupV1Update(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Start updating attributes of ECL managed load balancer target group ...") + + err = resourceMLBTargetGroupV1UpdateAttributes(d, managedLoadBalancerClient) + if err != nil { + return fmt.Errorf("Error in updating attributes of ECL managed load balancer target group: %s", err) + } + + log.Printf("[DEBUG] Start updating configurations of ECL managed load balancer target group ...") + + err = resourceMLBTargetGroupV1UpdateConfigurations(d, managedLoadBalancerClient) + if err != nil { + return fmt.Errorf("Error in updating configurations of ECL managed load balancer target group: %s", err) + } + + return resourceMLBTargetGroupV1Read(d, meta) +} + +func resourceMLBTargetGroupV1UpdateAttributes(d *schema.ResourceData, client *eclcloud.ServiceClient) error { + var isAttributesUpdated bool + var updateOpts target_groups.UpdateOpts + + if d.HasChange("name") { + isAttributesUpdated = true + name := d.Get("name").(string) + updateOpts.Name = &name + } + + if d.HasChange("description") { + isAttributesUpdated = true + description := d.Get("description").(string) + updateOpts.Description = &description + } + + if d.HasChange("tags") { + isAttributesUpdated = true + tags := d.Get("tags").(map[string]interface{}) + updateOpts.Tags = &tags + } + + if isAttributesUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer target group attributes (%s) with options %+v", d.Id(), updateOpts) + + _, err := target_groups.Update(client, d.Id(), updateOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer target group attributes (%s) with options %+v: %s", d.Id(), updateOpts, err) + } + } + + return nil +} + +func resourceMLBTargetGroupV1UpdateConfigurations(d *schema.ResourceData, client *eclcloud.ServiceClient) error { + var isConfigurationsUpdated bool + + targetGroup, err := resourceMLBTargetGroupV1Show(d, client, false) + if err != nil { + return err + } + + if targetGroup.ConfigurationStatus == "ACTIVE" { + var createStagedOpts target_groups.CreateStagedOpts + + if d.HasChange("members") { + isConfigurationsUpdated = true + + members := make([]target_groups.CreateStagedOptsMember, len(d.Get("members").([]interface{}))) + for i, member := range d.Get("members").([]interface{}) { + members[i] = target_groups.CreateStagedOptsMember{ + IPAddress: member.(map[string]interface{})["ip_address"].(string), + Port: member.(map[string]interface{})["port"].(int), + Weight: member.(map[string]interface{})["weight"].(int), + } + } + createStagedOpts.Members = &members + } + + if isConfigurationsUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer target group configurations (%s) with options %+v", d.Id(), createStagedOpts) + + _, err := target_groups.CreateStaged(client, d.Id(), createStagedOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer target group configurations (%s) with options %+v: %s", d.Id(), createStagedOpts, err) + } + } + } else { + var updateStagedOpts target_groups.UpdateStagedOpts + + if d.HasChange("members") { + isConfigurationsUpdated = true + + members := make([]target_groups.UpdateStagedOptsMember, len(d.Get("members").([]interface{}))) + for i, member := range d.Get("members").([]interface{}) { + ipAddress := member.(map[string]interface{})["ip_address"].(string) + port := member.(map[string]interface{})["port"].(int) + weight := member.(map[string]interface{})["weight"].(int) + members[i] = target_groups.UpdateStagedOptsMember{ + IPAddress: &ipAddress, + Port: &port, + Weight: &weight, + } + } + updateStagedOpts.Members = &members + } + + if isConfigurationsUpdated { + log.Printf("[DEBUG] Updating ECL managed load balancer target group configurations (%s) with options %+v", d.Id(), updateStagedOpts) + + _, err := target_groups.UpdateStaged(client, d.Id(), updateStagedOpts).Extract() + if err != nil { + return fmt.Errorf("Error updating ECL managed load balancer target group configurations (%s) with options %+v: %s", d.Id(), updateStagedOpts, err) + } + } + } + + return nil +} + +func resourceMLBTargetGroupV1Delete(d *schema.ResourceData, meta interface{}) error { + config := meta.(*Config) + managedLoadBalancerClient, err := config.managedLoadBalancerV1Client(GetRegion(d, config)) + if err != nil { + return fmt.Errorf("Error creating ECL managed load balancer client: %s", err) + } + + log.Printf("[DEBUG] Deleting ECL managed load balancer target group: %s", d.Id()) + + err = target_groups.Delete(managedLoadBalancerClient, d.Id()).ExtractErr() + if err != nil { + return fmt.Errorf("Error deleting ECL managed load balancer target group: %s", err) + } + + return nil +} diff --git a/ecl/resource_ecl_mlb_target_group_v1_mock_test.go b/ecl/resource_ecl_mlb_target_group_v1_mock_test.go new file mode 100644 index 00000000..ab7f6b40 --- /dev/null +++ b/ecl/resource_ecl_mlb_target_group_v1_mock_test.go @@ -0,0 +1,570 @@ +package ecl + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + + "github.com/nttcom/terraform-provider-ecl/ecl/testhelper/mock" +) + +func TestMockedAccMLBV1TargetGroupResource(t *testing.T) { + mc := mock.NewMockController() + defer mc.TerminateMockControllerSafety() + + postKeystone := fmt.Sprintf(fakeKeystonePostTmpl, mc.Endpoint(), OS_REGION_NAME) + + mc.Register(t, "keystone", "/v3/auth/tokens", postKeystone) + mc.Register(t, "target_groups", "/v1.0/target_groups", testMockMLBV1TargetGroupsCreate) + mc.Register(t, "target_groups", "/v1.0/target_groups/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1TargetGroupsShowAfterCreate) + mc.Register(t, "target_groups", "/v1.0/target_groups/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1TargetGroupsUpdateAttributes) + mc.Register(t, "target_groups", "/v1.0/target_groups/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1TargetGroupsShowBeforeUpdateConfigurations) + mc.Register(t, "target_groups", "/v1.0/target_groups/497f6eca-6276-4993-bfeb-53cbbbba6f08/staged", testMockMLBV1TargetGroupsUpdateConfigurations) + mc.Register(t, "target_groups", "/v1.0/target_groups/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1TargetGroupsShowAfterUpdateConfigurations) + // Staged configurations of the load balancer and related resources are applied here + mc.Register(t, "target_groups", "/v1.0/target_groups/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1TargetGroupsShowAfterApplyConfigurations) + mc.Register(t, "target_groups", "/v1.0/target_groups/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1TargetGroupsShowBeforeCreateConfigurations) + mc.Register(t, "target_groups", "/v1.0/target_groups/497f6eca-6276-4993-bfeb-53cbbbba6f08/staged", testMockMLBV1TargetGroupsCreateConfigurations) + mc.Register(t, "target_groups", "/v1.0/target_groups/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1TargetGroupsShowAfterCreateConfigurations) + mc.Register(t, "target_groups", "/v1.0/target_groups/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1TargetGroupsDelete) + mc.Register(t, "target_groups", "/v1.0/target_groups/497f6eca-6276-4993-bfeb-53cbbbba6f08", testMockMLBV1TargetGroupsShowAfterDelete) + + mc.StartServer(t) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccMLBV1TargetGroup, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "name", "target_group"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "description", "description"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "tags.key", "value"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "members.0.ip_address", "192.168.0.7"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "members.0.port", "80"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "members.0.weight", "1"), + ), + }, + { + Config: testAccMLBV1TargetGroupUpdateBeforeApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "name", "target_group-update"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "description", "description-update"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "tags.key-update", "value-update"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "members.0.ip_address", "192.168.0.7"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "members.0.port", "80"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "members.0.weight", "1"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "members.1.ip_address", "192.168.0.8"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "members.1.port", "80"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "members.1.weight", "1"), + ), + }, + { + Config: testAccMLBV1TargetGroupUpdateAfterApplyConfigurations, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "id", "497f6eca-6276-4993-bfeb-53cbbbba6f08"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "name", "target_group-update"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "description", "description-update"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "tags.key-update", "value-update"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "load_balancer_id", "67fea379-cff0-4191-9175-de7d6941a040"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "tenant_id", "34f5c98ef430457ba81292637d0c6fd0"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "members.0.ip_address", "192.168.0.8"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "members.0.port", "80"), + resource.TestCheckResourceAttr("ecl_mlb_target_group_v1.target_group", "members.0.weight", "1"), + ), + }, + }, + }) +} + +var testAccMLBV1TargetGroup = fmt.Sprintf(` +resource "ecl_mlb_target_group_v1" "target_group" { + name = "target_group" + description = "description" + tags = { + key = "value" + } + load_balancer_id = "67fea379-cff0-4191-9175-de7d6941a040" + members { + ip_address = "192.168.0.7" + port = 80 + weight = 1 + } +} +`) + +var testAccMLBV1TargetGroupUpdateBeforeApplyConfigurations = fmt.Sprintf(` +resource "ecl_mlb_target_group_v1" "target_group" { + name = "target_group-update" + description = "description-update" + tags = { + key-update = "value-update" + } + load_balancer_id = "67fea379-cff0-4191-9175-de7d6941a040" + members { + ip_address = "192.168.0.7" + port = 80 + weight = 1 + } + members { + ip_address = "192.168.0.8" + port = 80 + weight = 1 + } +} +`) + +var testAccMLBV1TargetGroupUpdateAfterApplyConfigurations = fmt.Sprintf(` +resource "ecl_mlb_target_group_v1" "target_group" { + name = "target_group-update" + description = "description-update" + tags = { + key-update = "value-update" + } + load_balancer_id = "67fea379-cff0-4191-9175-de7d6941a040" + members { + ip_address = "192.168.0.8" + port = 80 + weight = 1 + } +} +`) + +var testMockMLBV1TargetGroupsCreate = fmt.Sprintf(` +request: + method: POST + body: > + {"target_group":{"description":"description","load_balancer_id":"67fea379-cff0-4191-9175-de7d6941a040","members":[{"ip_address":"192.168.0.7","port":80,"weight":1}],"name":"target_group","tags":{"key":"value"}}} +response: + code: 200 + body: > + { + "target_group": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "target_group", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "members": null + } + } +newStatus: Created +`) + +var testMockMLBV1TargetGroupsShowAfterCreate = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "target_group": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "target_group", + "description": "description", + "tags": { + "key": "value" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "members": null, + "current": null, + "staged": { + "members": [ + { + "ip_address": "192.168.0.7", + "port": 80, + "weight": 1 + } + ] + } + } + } +expectedStatus: + - Created +`) + +var testMockMLBV1TargetGroupsShowBeforeUpdateConfigurations = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "target_group": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "target_group-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "members": null + } + } +expectedStatus: + - AttributesUpdated +`) + +var testMockMLBV1TargetGroupsShowAfterUpdateConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "target_group": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "target_group-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "members": null, + "current": null, + "staged": { + "members": [ + { + "ip_address": "192.168.0.7", + "port": 80, + "weight": 1 + }, + { + "ip_address": "192.168.0.8", + "port": 80, + "weight": 1 + } + ] + } + } + } +expectedStatus: + - ConfigurationsUpdatedBeforeApply +newStatus: ConfigurationsApplied +`) + +var testMockMLBV1TargetGroupsShowAfterApplyConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "target_group": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "target_group-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "ACTIVE", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "members": [ + { + "ip_address": "192.168.0.7", + "port": 80, + "weight": 1 + }, + { + "ip_address": "192.168.0.8", + "port": 80, + "weight": 1 + } + ], + "current": { + "members": [ + { + "ip_address": "192.168.0.7", + "port": 80, + "weight": 1 + }, + { + "ip_address": "192.168.0.8", + "port": 80, + "weight": 1 + } + ] + }, + "staged": null + } + } +expectedStatus: + - ConfigurationsApplied +`) + +var testMockMLBV1TargetGroupsShowBeforeCreateConfigurations = fmt.Sprintf(` +request: + method: GET +response: + code: 200 + body: > + { + "target_group": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "target_group-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "ACTIVE", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "members": [ + { + "ip_address": "192.168.0.7", + "port": 80, + "weight": 1 + }, + { + "ip_address": "192.168.0.8", + "port": 80, + "weight": 1 + } + ] + } + } +expectedStatus: + - ConfigurationsApplied +`) + +var testMockMLBV1TargetGroupsShowAfterCreateConfigurations = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "target_group": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "target_group-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "UPDATE_STAGED", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "members": [ + { + "ip_address": "192.168.0.7", + "port": 80, + "weight": 1 + }, + { + "ip_address": "192.168.0.8", + "port": 80, + "weight": 1 + } + ], + "current": { + "members": [ + { + "ip_address": "192.168.0.7", + "port": 80, + "weight": 1 + }, + { + "ip_address": "192.168.0.8", + "port": 80, + "weight": 1 + } + ] + }, + "staged": { + "members": [ + { + "ip_address": "192.168.0.8", + "port": 80, + "weight": 1 + } + ] + } + } + } +expectedStatus: + - ConfigurationsUpdatedAfterApply +`) + +var testMockMLBV1TargetGroupsShowAfterDelete = fmt.Sprintf(` +request: + method: GET + query: + changes: + - true +response: + code: 200 + body: > + { + "target_group": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "target_group-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "DELETE_STAGED", + "operation_status": "COMPLETE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "members": [ + { + "ip_address": "192.168.0.7", + "port": 80, + "weight": 1 + }, + { + "ip_address": "192.168.0.8", + "port": 80, + "weight": 1 + } + ], + "current": { + "members": [ + { + "ip_address": "192.168.0.7", + "port": 80, + "weight": 1 + }, + { + "ip_address": "192.168.0.8", + "port": 80, + "weight": 1 + } + ] + }, + "staged": null + } + } +expectedStatus: + - Deleted +`) + +var testMockMLBV1TargetGroupsUpdateAttributes = fmt.Sprintf(` +request: + method: PATCH + body: > + {"target_group":{"description":"description-update","name":"target_group-update","tags":{"key-update":"value-update"}}} +response: + code: 200 + body: > + { + "target_group": { + "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08", + "name": "target_group-update", + "description": "description-update", + "tags": { + "key-update": "value-update" + }, + "configuration_status": "CREATE_STAGED", + "operation_status": "NONE", + "load_balancer_id": "67fea379-cff0-4191-9175-de7d6941a040", + "tenant_id": "34f5c98ef430457ba81292637d0c6fd0", + "members": null + } + } +expectedStatus: + - Created +newStatus: AttributesUpdated +`) + +var testMockMLBV1TargetGroupsCreateConfigurations = fmt.Sprintf(` +request: + method: POST + body: > + {"target_group":{"members":[{"ip_address":"192.168.0.8","port":80,"weight":1}]}} +response: + code: 200 + body: > + { + "target_group": { + "members": [ + { + "ip_address": "192.168.0.8", + "port": 80, + "weight": 1 + } + ] + } + } +expectedStatus: + - ConfigurationsApplied +newStatus: ConfigurationsUpdatedAfterApply +`) + +var testMockMLBV1TargetGroupsUpdateConfigurations = fmt.Sprintf(` +request: + method: PATCH + body: > + {"target_group":{"members":[{"ip_address":"192.168.0.7","port":80,"weight":1},{"ip_address":"192.168.0.8","port":80,"weight":1}]}} +response: + code: 200 + body: > + { + "target_group": { + "members": [ + { + "ip_address": "192.168.0.7", + "port": 80, + "weight": 1 + }, + { + "ip_address": "192.168.0.8", + "port": 80, + "weight": 1 + } + ] + } + } +expectedStatus: + - AttributesUpdated +newStatus: ConfigurationsUpdatedBeforeApply +`) + +var testMockMLBV1TargetGroupsDelete = fmt.Sprintf(` +request: + method: DELETE +response: + code: 204 +expectedStatus: + - Created + - ConfigurationsUpdatedAfterApply +newStatus: Deleted +`) diff --git a/ecl/testhelper/mock/mock.go b/ecl/testhelper/mock/mock.go index 66c8191e..021069b9 100644 --- a/ecl/testhelper/mock/mock.go +++ b/ecl/testhelper/mock/mock.go @@ -8,6 +8,7 @@ import ( "net/url" "os" "reflect" + "strings" "testing" "gopkg.in/yaml.v2" @@ -131,15 +132,7 @@ func (mc MockController) setupHandler(t *testing.T, path string, mocks []Mock) { } } - if v.Request.Body != "" && v.Request.Body != string(body) { - continue - } - - if v.Request.Method != r.Method { - continue - } - - if v.Request.Body != "" && v.Request.Body != string(body) { + if v.Request.Body != "" && strings.TrimSpace(v.Request.Body) != strings.TrimSpace(string(body)) { continue } diff --git a/ecl/util.go b/ecl/util.go index 8c2a19d0..db2bb8d9 100644 --- a/ecl/util.go +++ b/ecl/util.go @@ -246,3 +246,11 @@ func getTags(d *schema.ResourceData, tagName string) (map[string]string, error) } return tags, nil } + +func ternary(condition bool, ifOutput interface{}, elseOutput interface{}) interface{} { + if condition { + return ifOutput + } + + return elseOutput +} diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/doc.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/doc.go index a0cd9ff6..02633bcd 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/doc.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/doc.go @@ -1,6 +1,4 @@ /* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb - Package certificates contains functionality for working with ECL Managed Load Balancer resources. Example to list certificates diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/requests.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/requests.go index ff6d055a..dd5946c1 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/requests.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/requests.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package certificates import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/results.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/results.go index 5e1a11a8..2d3170ab 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/results.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/results.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package certificates import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/urls.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/urls.go index e2e21a4c..874706b4 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/urls.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/certificates/urls.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package certificates import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/doc.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/doc.go index b7cfae6f..8fb714ce 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/doc.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/doc.go @@ -1,6 +1,4 @@ /* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb - Package health_monitors contains functionality for working with ECL Managed Load Balancer resources. Example to list health monitors diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/requests.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/requests.go index 39a33dae..1992ae73 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/requests.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/requests.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package health_monitors import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/results.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/results.go index 12af174e..fc1b20fb 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/results.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/results.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package health_monitors import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/urls.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/urls.go index 106294e7..c3a2c6fa 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/urls.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/health_monitors/urls.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package health_monitors import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/doc.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/doc.go index 3ac6c464..7682c620 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/doc.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/doc.go @@ -1,6 +1,4 @@ /* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb - Package listeners contains functionality for working with ECL Managed Load Balancer resources. Example to list listeners diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/requests.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/requests.go index 7be82b07..17201f33 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/requests.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/requests.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package listeners import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/results.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/results.go index 9ac1068f..5fa0657b 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/results.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/results.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package listeners import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/urls.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/urls.go index c2aeed04..6e3e4ca7 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/urls.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/listeners/urls.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package listeners import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/doc.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/doc.go index 5c143775..2d40e690 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/doc.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/doc.go @@ -1,6 +1,4 @@ /* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb - Package load_balancers contains functionality for working with ECL Managed Load Balancer resources. Example to list load balancers @@ -117,20 +115,43 @@ Example to delete a load balancer Example to perform apply-configurations action on a load balancer + actionOpts := load_balancers.ActionOpts{ + ApplyConfigurations: true, + } + id := "497f6eca-6276-4993-bfeb-53cbbbba6f08" - err := load_balancers.ApplyConfigurations(managedLoadBalancerClient, id).ExtractErr() + err := load_balancers.Action(cli, id, actionOpts).ExtractErr() if err != nil { panic(err) } Example to perform system-update action on a load balancer - systemUpdateOpts := load_balancers.SystemUpdateOpts{ + systemUpdate := load_balancers.ActionOptsSystemUpdate{ + SystemUpdateID: "31746df7-92f9-4b5e-ad05-59f6684a54eb", + } + actionOpts := load_balancers.ActionOpts{ + SystemUpdate: &systemUpdate, + } + + id := "497f6eca-6276-4993-bfeb-53cbbbba6f08" + err := load_balancers.Action(cli, id, actionOpts).ExtractErr() + if err != nil { + panic(err) + } + +Example to perform apply-configurations and system-update action on a load balancer + + systemUpdate := load_balancers.ActionOptsSystemUpdate{ SystemUpdateID: "31746df7-92f9-4b5e-ad05-59f6684a54eb", } + actionOpts := load_balancers.ActionOpts{ + ApplyConfigurations: true, + SystemUpdate: &systemUpdate, + } id := "497f6eca-6276-4993-bfeb-53cbbbba6f08" - err := load_balancers.SystemUpdate(managedLoadBalancerClient, id, systemUpdateOpts).ExtractErr() + err := load_balancers.Action(cli, id, actionOpts).ExtractErr() if err != nil { panic(err) } diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/requests.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/requests.go index 0c70e378..4fefa09b 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/requests.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/requests.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package load_balancers import ( @@ -302,36 +299,48 @@ func Delete(c *eclcloud.ServiceClient, id string) (r DeleteResult) { Action Load Balancer */ -// ApplyConfigurations performs action on a existing load balancer. -func ApplyConfigurations(c *eclcloud.ServiceClient, id string) (r ActionResult) { - b := map[string]interface{}{"apply-configurations": nil} - _, r.Err = c.Post(actionURL(c, id), b, nil, &eclcloud.RequestOpts{ - OkCodes: []int{204}, - }) +// ActionOptsSystemUpdate represents system-update information in the load balancer action. +type ActionOptsSystemUpdate struct { - return + // - ID of the system update that will be applied to the load balancer + SystemUpdateID string `json:"system_update_id"` } -// SystemUpdateOpts represents options used to perform action on a existing load balancer. -type SystemUpdateOpts struct { +// ActionOpts represents options used to perform action on a existing load balancer. +type ActionOpts struct { - // - ID of the system update that will be applied to the load balancer - SystemUpdateID string `json:"system_update_id"` + // - Added or changed configurations of the load balancer and related resources will be applied + ApplyConfigurations bool `json:"apply-configurations,omitempty"` + + // - Apply the system update to the load balancer + SystemUpdate *ActionOptsSystemUpdate `json:"system-update,omitempty"` } -// ToLoadBalancerSystemUpdateMap builds a request body from SystemUpdateOpts. -func (opts SystemUpdateOpts) ToLoadBalancerSystemUpdateMap() (map[string]interface{}, error) { - return eclcloud.BuildRequestBody(opts, "system-update") +// ToLoadBalancerActionMap builds a request body from ActionOpts. +func (opts ActionOpts) ToLoadBalancerActionMap() (map[string]interface{}, error) { + optsMap := make(map[string]interface{}) + + if opts.ApplyConfigurations { + optsMap["apply-configurations"] = nil + } + + if opts.SystemUpdate != nil { + optsMap["system-update"] = map[string]interface{}{ + "system_update_id": opts.SystemUpdate.SystemUpdateID, + } + } + + return optsMap, nil } -// SystemUpdateOptsBuilder allows extensions to add additional parameters to the SystemUpdate request. -type SystemUpdateOptsBuilder interface { - ToLoadBalancerSystemUpdateMap() (map[string]interface{}, error) +// ActionOptsBuilder allows extensions to add additional parameters to the Action request. +type ActionOptsBuilder interface { + ToLoadBalancerActionMap() (map[string]interface{}, error) } -// SystemUpdate accepts a SystemUpdateOpts struct and performs action on a existing load balancer using the values provided. -func SystemUpdate(c *eclcloud.ServiceClient, id string, opts SystemUpdateOptsBuilder) (r ActionResult) { - b, err := opts.ToLoadBalancerSystemUpdateMap() +// Action accepts a ActionOpts struct and performs action on a existing load balancer using the values provided. +func Action(c *eclcloud.ServiceClient, id string, opts ActionOptsBuilder) (r ActionResult) { + b, err := opts.ToLoadBalancerActionMap() if err != nil { r.Err = err diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/results.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/results.go index e3679b71..aa34a4e0 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/results.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/results.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package load_balancers import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/urls.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/urls.go index 8a12ce13..361bd432 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/urls.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/load_balancers/urls.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package load_balancers import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/doc.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/doc.go index 4527fd76..6eb28a66 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/doc.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/doc.go @@ -1,6 +1,4 @@ /* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb - Package operations contains functionality for working with ECL Managed Load Balancer resources. Example to list operations diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/requests.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/requests.go index c93f0d6c..2c148550 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/requests.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/requests.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package operations import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/results.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/results.go index 2865c018..0d509086 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/results.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/results.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package operations import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/urls.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/urls.go index 5cdeb28c..36c8f39b 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/urls.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/operations/urls.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package operations import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/doc.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/doc.go index 0a3d9a45..c5710fbb 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/doc.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/doc.go @@ -1,6 +1,4 @@ /* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb - Package plans contains functionality for working with ECL Managed Load Balancer resources. Example to list plans diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/requests.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/requests.go index ef8191f0..4f4bf320 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/requests.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/requests.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package plans import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/results.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/results.go index 12645e1a..e1b6345f 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/results.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/results.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package plans import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/urls.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/urls.go index 2845e326..13c565e3 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/urls.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/plans/urls.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package plans import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/doc.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/doc.go index 28e6272b..a804c5df 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/doc.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/doc.go @@ -1,6 +1,4 @@ /* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb - Package policies contains functionality for working with ECL Managed Load Balancer resources. Example to list policies diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/requests.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/requests.go index a8e1634c..1c610983 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/requests.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/requests.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package policies import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/results.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/results.go index 7a345db6..d7c8ca0e 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/results.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/results.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package policies import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/urls.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/urls.go index e5196a3b..d169d788 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/urls.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/policies/urls.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package policies import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/doc.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/doc.go index 19f98e07..e6a5a70a 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/doc.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/doc.go @@ -1,6 +1,4 @@ /* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb - Package routes contains functionality for working with ECL Managed Load Balancer resources. Example to list routes diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/requests.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/requests.go index 9a54be12..c2c746ae 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/requests.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/requests.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package routes import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/results.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/results.go index 1629b39b..13e5be2f 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/results.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/results.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package routes import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/urls.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/urls.go index 0892a491..1f3fc6b5 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/urls.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/routes/urls.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package routes import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/doc.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/doc.go index 2ecbb9c3..1356c598 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/doc.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/doc.go @@ -1,6 +1,4 @@ /* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb - Package rules contains functionality for working with ECL Managed Load Balancer resources. Example to list rules diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/requests.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/requests.go index 3da2422b..d465080a 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/requests.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/requests.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package rules import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/results.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/results.go index e151343a..2dddb178 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/results.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/results.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package rules import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/urls.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/urls.go index a85f9277..dfc1edb8 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/urls.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/rules/urls.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package rules import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/doc.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/doc.go index f055e0ce..19bf8c20 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/doc.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/doc.go @@ -1,6 +1,4 @@ /* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb - Package system_updates contains functionality for working with ECL Managed Load Balancer resources. Example to list system updates diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/requests.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/requests.go index 9c7174eb..caea0bf2 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/requests.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/requests.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package system_updates import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/results.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/results.go index fc8d7c1e..d6ca5d2e 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/results.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/results.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package system_updates import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/urls.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/urls.go index 9cd40756..ea52a045 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/urls.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/system_updates/urls.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package system_updates import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/doc.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/doc.go index de5ceabc..bc9f5262 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/doc.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/doc.go @@ -1,6 +1,4 @@ /* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb - Package target_groups contains functionality for working with ECL Managed Load Balancer resources. Example to list target groups diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/requests.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/requests.go index 42871956..3ae6ecd2 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/requests.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/requests.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package target_groups import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/results.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/results.go index 1c964c4e..421b4dfc 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/results.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/results.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package target_groups import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/urls.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/urls.go index 8776912f..a93301c2 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/urls.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/target_groups/urls.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package target_groups import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/doc.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/doc.go index 8ba1a3f1..f861a872 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/doc.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/doc.go @@ -1,6 +1,4 @@ /* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb - Package tls_policies contains functionality for working with ECL Managed Load Balancer resources. Example to list tls policies diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/requests.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/requests.go index 95a31252..35fb2756 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/requests.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/requests.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package tls_policies import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/results.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/results.go index 2ccd1c5a..6ef0c358 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/results.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/results.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package tls_policies import ( diff --git a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/urls.go b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/urls.go index 05890ced..1b557517 100644 --- a/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/urls.go +++ b/vendor/github.com/nttcom/eclcloud/v2/ecl/managed_load_balancer/v1/tls_policies/urls.go @@ -1,6 +1,3 @@ -/* -Generated by https://github.com/tamac-io/openapi-to-eclcloud-rb -*/ package tls_policies import (