From 3088685bdffc3fe24a87cbadf5e7540085648470 Mon Sep 17 00:00:00 2001 From: kt Date: Mon, 13 Jan 2020 18:46:02 -0800 Subject: [PATCH] azurerm_devspace_controller: deprecate sku in favour of sku_name (#5379) partially addresses #1500 --- .../resource_arm_devspace_controller.go | 150 +++++++++++------- .../resource_arm_devspace_controller_test.go | 73 ++++++++- .../guides/2.0-upgrade-guide.html.markdown | 6 +- .../docs/r/devspace_controller.html.markdown | 15 +- 4 files changed, 170 insertions(+), 74 deletions(-) diff --git a/azurerm/internal/services/devspace/resource_arm_devspace_controller.go b/azurerm/internal/services/devspace/resource_arm_devspace_controller.go index 013ceef12878..fc25fa62da95 100644 --- a/azurerm/internal/services/devspace/resource_arm_devspace_controller.go +++ b/azurerm/internal/services/devspace/resource_arm_devspace_controller.go @@ -47,17 +47,30 @@ func resourceArmDevSpaceController() *schema.Resource { "resource_group_name": azure.SchemaResourceGroupName(), + "sku_name": { + Type: schema.TypeString, + Optional: true, // required in 2.0 + Computed: true, // remove in 2.0 + //ForceNew: true, // uncomment in 2.0 - this should be fine as there is only 1 valid value + ConflictsWith: []string{"sku"}, + ValidateFunc: validation.StringInSlice([]string{ + "S1", + }, false), + }, + "sku": { Type: schema.TypeList, - Required: true, - ForceNew: true, - MaxItems: 1, + Optional: true, + //ForceNew: true, // uncomment in 2.0 - this should be fine as there is only 1 valid value + Computed: true, + ConflictsWith: []string{"sku_name"}, + Deprecated: "This property has been deprecated in favour of the 'sku_name' property and will be removed in version 2.0 of the provider", + MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, Required: true, - ForceNew: true, ValidateFunc: validation.StringInSlice([]string{ "S1", }, false), @@ -65,7 +78,6 @@ func resourceArmDevSpaceController() *schema.Resource { "tier": { Type: schema.TypeString, Required: true, - ForceNew: true, ValidateFunc: validation.StringInSlice([]string{ string(devspaces.Standard), }, false), @@ -112,13 +124,13 @@ func resourceArmDevSpaceControllerCreate(d *schema.ResourceData, meta interface{ log.Printf("[INFO] preparing arguments for DevSpace Controller creation") name := d.Get("name").(string) - resGroup := d.Get("resource_group_name").(string) + resourceGroup := d.Get("resource_group_name").(string) if features.ShouldResourcesBeImported() && d.IsNewResource() { - existing, err := client.Get(ctx, resGroup, name) + existing, err := client.Get(ctx, resourceGroup, name) if err != nil { if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("Error checking for presence of existing DevSpace Controller %q (Resource Group %q): %s", name, resGroup, err) + return fmt.Errorf("Error checking for presence of existing DevSpace Controller %q (Resource Group %q): %s", name, resourceGroup, err) } } @@ -130,37 +142,72 @@ func resourceArmDevSpaceControllerCreate(d *schema.ResourceData, meta interface{ location := azure.NormalizeLocation(d.Get("location").(string)) t := d.Get("tags").(map[string]interface{}) - sku := expandDevSpaceControllerSku(d) - - tarCHResId := d.Get("target_container_host_resource_id").(string) - tarCHCredBase64 := d.Get("target_container_host_credentials_base64").(string) + var sku *devspaces.Sku + if b, ok := d.GetOk("sku_name"); ok { + var err error + sku, err = expandControllerSkuName(b.(string)) + if err != nil { + return fmt.Errorf("error expanding sku_name for DevSpace Controller %s (Resource Group %q): %v", name, resourceGroup, err) + } + } else if _, ok := d.GetOk("sku"); ok { + sku = expandDevSpaceControllerSku(d) + } else { + return fmt.Errorf("One of `sku` or `sku_name` must be set for DevSpace Controller %q (Resource Group %q)", name, resourceGroup) + } controller := devspaces.Controller{ Location: &location, - Tags: tags.Expand(t), Sku: sku, ControllerProperties: &devspaces.ControllerProperties{ - TargetContainerHostResourceID: &tarCHResId, - TargetContainerHostCredentialsBase64: &tarCHCredBase64, + TargetContainerHostResourceID: utils.String(d.Get("target_container_host_resource_id").(string)), + TargetContainerHostCredentialsBase64: utils.String(d.Get("target_container_host_credentials_base64").(string)), }, + Tags: tags.Expand(t), } - future, err := client.Create(ctx, resGroup, name, controller) + future, err := client.Create(ctx, resourceGroup, name, controller) if err != nil { - return fmt.Errorf("Error creating DevSpace Controller %q (Resource Group %q): %+v", name, resGroup, err) + return fmt.Errorf("Error creating DevSpace Controller %q (Resource Group %q): %+v", name, resourceGroup, err) } if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { - return fmt.Errorf("Error waiting for creation of DevSpace Controller %q (Resource Group %q): %+v", name, resGroup, err) + return fmt.Errorf("Error waiting for creation of DevSpace Controller %q (Resource Group %q): %+v", name, resourceGroup, err) } - result, err := client.Get(ctx, resGroup, name) + result, err := client.Get(ctx, resourceGroup, name) if err != nil { - return fmt.Errorf("Error retrieving DevSpace %q (Resource Group %q): %+v", name, resGroup, err) + return fmt.Errorf("Error retrieving DevSpace %q (Resource Group %q): %+v", name, resourceGroup, err) } if result.ID == nil { - return fmt.Errorf("Cannot read DevSpace Controller %q (Resource Group %q) ID", name, resGroup) + return fmt.Errorf("Cannot read DevSpace Controller %q (Resource Group %q) ID", name, resourceGroup) + } + d.SetId(*result.ID) + + return resourceArmDevSpaceControllerRead(d, meta) +} + +func resourceArmDevSpaceControllerUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).DevSpace.ControllersClient + ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) + defer cancel() + + log.Printf("[INFO] preparing arguments for DevSpace Controller updating") + + name := d.Get("name").(string) + resGroupName := d.Get("resource_group_name").(string) + + params := devspaces.ControllerUpdateParameters{ + Tags: tags.Expand(d.Get("tags").(map[string]interface{})), + } + + result, err := client.Update(ctx, resGroupName, name, params) + if err != nil { + return fmt.Errorf("Error updating DevSpace Controller %q (Resource Group %q): %+v", name, resGroupName, err) + } + + if result.ID == nil { + return fmt.Errorf("Cannot read DevSpace Controller %q (Resource Group %q) ID", name, resGroupName) } d.SetId(*result.ID) @@ -179,9 +226,9 @@ func resourceArmDevSpaceControllerRead(d *schema.ResourceData, meta interface{}) resGroupName := id.ResourceGroup name := id.Path["controllers"] - result, err := client.Get(ctx, resGroupName, name) + resp, err := client.Get(ctx, resGroupName, name) if err != nil { - if utils.ResponseWasNotFound(result.Response) { + if utils.ResponseWasNotFound(resp.Response) { log.Printf("[DEBUG] DevSpace Controller %q was not found in Resource Group %q - removing from state!", name, resGroupName) d.SetId("") return nil @@ -190,51 +237,27 @@ func resourceArmDevSpaceControllerRead(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error making Read request on DevSpace Controller %q (Resource Group %q): %+v", name, resGroupName, err) } - d.Set("name", result.Name) + d.Set("name", resp.Name) d.Set("resource_group_name", resGroupName) - if location := result.Location; location != nil { + if location := resp.Location; location != nil { d.Set("location", azure.NormalizeLocation(*location)) } - if err := d.Set("sku", flattenDevSpaceControllerSku(result.Sku)); err != nil { + if sku := resp.Sku; sku != nil { + d.Set("sku_name", sku.Name) + } + + if err := d.Set("sku", flattenDevSpaceControllerSku(resp.Sku)); err != nil { return fmt.Errorf("Error flattenning `sku`: %+v", err) } - if props := result.ControllerProperties; props != nil { + if props := resp.ControllerProperties; props != nil { d.Set("host_suffix", props.HostSuffix) d.Set("data_plane_fqdn", props.DataPlaneFqdn) d.Set("target_container_host_resource_id", props.TargetContainerHostResourceID) } - return tags.FlattenAndSet(d, result.Tags) -} - -func resourceArmDevSpaceControllerUpdate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*clients.Client).DevSpace.ControllersClient - ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) - defer cancel() - - log.Printf("[INFO] preparing arguments for DevSpace Controller updating") - - name := d.Get("name").(string) - resGroupName := d.Get("resource_group_name").(string) - t := d.Get("tags").(map[string]interface{}) - - params := devspaces.ControllerUpdateParameters{ - Tags: tags.Expand(t), - } - - result, err := client.Update(ctx, resGroupName, name, params) - if err != nil { - return fmt.Errorf("Error updating DevSpace Controller %q (Resource Group %q): %+v", name, resGroupName, err) - } - - if result.ID == nil { - return fmt.Errorf("Cannot read DevSpace Controller %q (Resource Group %q) ID", name, resGroupName) - } - d.SetId(*result.ID) - - return resourceArmDevSpaceControllerRead(d, meta) + return tags.FlattenAndSet(d, resp.Tags) } func resourceArmDevSpaceControllerDelete(d *schema.ResourceData, meta interface{}) error { @@ -261,6 +284,21 @@ func resourceArmDevSpaceControllerDelete(d *schema.ResourceData, meta interface{ return nil } +func expandControllerSkuName(skuName string) (*devspaces.Sku, error) { + var tier devspaces.SkuTier + switch skuName[0:1] { + case "S": + tier = devspaces.Standard + default: + return nil, fmt.Errorf("sku_name %s has unknown sku tier %s", skuName, skuName[0:1]) + } + + return &devspaces.Sku{ + Name: utils.String(skuName), + Tier: tier, + }, nil +} + func expandDevSpaceControllerSku(d *schema.ResourceData) *devspaces.Sku { if _, ok := d.GetOk("sku"); !ok { return nil diff --git a/azurerm/internal/services/devspace/tests/resource_arm_devspace_controller_test.go b/azurerm/internal/services/devspace/tests/resource_arm_devspace_controller_test.go index 9f359b181941..487d02f7cb23 100644 --- a/azurerm/internal/services/devspace/tests/resource_arm_devspace_controller_test.go +++ b/azurerm/internal/services/devspace/tests/resource_arm_devspace_controller_test.go @@ -36,6 +36,28 @@ func TestAccAzureRMDevSpaceController_basic(t *testing.T) { }) } +func TestAccAzureRMDevSpaceController_basicOldSku(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_devspace_controller", "test") + clientId := os.Getenv("ARM_CLIENT_ID") + clientSecret := os.Getenv("ARM_CLIENT_SECRET") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMDevSpaceControllerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMDevSpaceController_basicOldSku(data, clientId, clientSecret), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDevSpaceControllerExists(data.ResourceName), + resource.TestCheckResourceAttr(data.ResourceName, "sku.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "0"), + ), + }, + }, + }) +} + func TestAccAzureRMDevSpaceController_requiresImport(t *testing.T) { if !features.ShouldResourcesBeImported() { t.Skip("Skipping since resources aren't required to be imported") @@ -157,6 +179,51 @@ resource "azurerm_kubernetes_cluster" "test" { } } +resource "azurerm_devspace_controller" "test" { + name = "acctestdsc%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + target_container_host_resource_id = "${azurerm_kubernetes_cluster.test.id}" + target_container_host_credentials_base64 = "${base64encode(azurerm_kubernetes_cluster.test.kube_config_raw)}" + + sku_name = "S1" +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, clientId, clientSecret, data.RandomInteger) +} + +func testAccAzureRMDevSpaceController_basicOldSku(data acceptance.TestData, clientId string, clientSecret string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "%s" +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%d" + location = "${azurerm_resource_group.test.location}" + resource_group_name = "${azurerm_resource_group.test.name}" + dns_prefix = "acctestaks1" + + linux_profile { + admin_username = "acctestuser1" + + ssh_key { + key_data = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqaZoyiz1qbdOQ8xEf6uEu1cCwYowo5FHtsBhqLoDnnp7KUTEBN+L2NxRIfQ781rxV6Iq5jSav6b2Q8z5KiseOlvKA/RF2wqU0UPYqQviQhLmW6THTpmrv/YkUCuzxDpsH7DUDhZcwySLKVVe0Qm3+5N2Ta6UYH3lsDf9R9wTP2K/+vAnflKebuypNlmocIvakFWoZda18FOmsOoIVXQ8HWFNCuw9ZCunMSN62QGamCe3dL5cXlkgHYv7ekJE15IA9aOJcM7e90oeTqo+7HTcWfdu0qQqPWY5ujyMw/llas8tsXY85LFqRnr3gJ02bAscjc477+X+j/gkpFoN1QEmt terraform@demo.tld" + } + } + + agent_pool_profile { + name = "default" + count = "1" + vm_size = "Standard_DS2_v2" + } + + service_principal { + client_id = "%s" + client_secret = "%s" + } +} + resource "azurerm_devspace_controller" "test" { name = "acctestdsc%d" location = "${azurerm_resource_group.test.location}" @@ -183,11 +250,7 @@ resource "azurerm_devspace_controller" "import" { resource_group_name = "${azurerm_devspace_controller.test.resource_group_name}" target_container_host_resource_id = "${azurerm_kubernetes_cluster.test.id}" target_container_host_credentials_base64 = "${base64encode(azurerm_kubernetes_cluster.test.kube_config_raw)}" - - sku { - name = "S1" - tier = "Standard" - } + sku_name = "${base64encode(azurerm_kubernetes_cluster.test.sku_name)}" } `, template) } diff --git a/website/docs/guides/2.0-upgrade-guide.html.markdown b/website/docs/guides/2.0-upgrade-guide.html.markdown index 7e0fe818bcb5..0a62fb6d16d8 100644 --- a/website/docs/guides/2.0-upgrade-guide.html.markdown +++ b/website/docs/guides/2.0-upgrade-guide.html.markdown @@ -257,9 +257,13 @@ Azure Container Service (ACS) is being Deprecated in favour of Azure Kubernetes The deprecated `failover_policy` block will be removed. This has been replaced by the `geo_location` block. +### Resource: `azurerm_devspace_controller` + +The deprecated `sku` block has been replaced by the `sku_name` field and will be removed. + ### Resource: `azurerm_ddos_protection_plan` -The `azurerm_ddos_protection_planr` resource will be deprecated in favour of a new resources `azurerm_network_ddos_protection_plan`. +The `azurerm_ddos_protection_plan` resource will be deprecated in favour of a new resources `azurerm_network_ddos_protection_plan`. ### Resource: `azurerm_dns_mx_record` diff --git a/website/docs/r/devspace_controller.html.markdown b/website/docs/r/devspace_controller.html.markdown index 6a4391471c01..f4c9f8efb862 100644 --- a/website/docs/r/devspace_controller.html.markdown +++ b/website/docs/r/devspace_controller.html.markdown @@ -41,10 +41,7 @@ resource "azurerm_devspace_controller" "example" { location = azurerm_resource_group.example.location resource_group_name = azurerm_resource_group.example.name - sku { - name = "S1" - tier = "Standard" - } + sku_name = "S1" host_suffix = "suffix" target_container_host_resource_id = "${azurerm_kubernetes_cluster.example.id}" @@ -58,7 +55,7 @@ resource "azurerm_devspace_controller" "example" { ## Argument Reference -The following arguments are supported: +The following arguments are supported: * `name` - (Required) Specifies the name of the DevSpace Controller. Changing this forces a new resource to be created. @@ -66,7 +63,7 @@ The following arguments are supported: * `location` - (Required) Specifies the supported location where the DevSpace Controller should exist. Changing this forces a new resource to be created. -* `sku` - (Required) A `sku` block as documented below. Changing this forces a new resource to be created. +* `sku_name` - (Required) Specifies the SKU Name for this DevSpace Controller. Possible values are `S1`. * `target_container_host_resource_id` - (Required) The resource id of Azure Kubernetes Service cluster. Changing this forces a new resource to be created. @@ -74,12 +71,6 @@ The following arguments are supported: * `tags` - (Optional) A mapping of tags to assign to the resource. ---- - -A `sku` block supports the following: - -* `name` - (Required) The name of the SKU for DevSpace Controller. Currently the only supported value is `S1`. Changing this forces a new resource to be created. -* `tier` - (Required) The tier of the SKU for DevSpace Controller. Currently the only supported value is `Standard`. Changing this forces a new resource to be created. ## Attributes Reference