From 4226473df8960e1f165432ee0b619e152483fdd1 Mon Sep 17 00:00:00 2001 From: Sean Nixon Date: Mon, 25 May 2020 00:29:42 -0500 Subject: [PATCH] New resource: azurerm_dev_test_global_shutdown_schedule (#5536) This resource enables the "Auto-shutdown" functionality of regular ARM-based VMs. It's basically a hack of the Dev Test Labs schedules resource known as a "Global Schedule" in the API docs. The API looks like it would support multiple types of schedules and timings, but in reality based on testing only "ComputeVMShutdownTask" schedules are supported and only with a daily recurrence. The API also seems to require a specific naming standard of the resource of "shutdown-computevm-{{VM Name}}". Anything else results in a 400 Bad Request. Because of these restrictions, for ease of use, I opted to create a resource specifically for shutdown schedules that essentially maps to the "Auto-shutdown" blade in the Portal. If in the future, if additional types of schedules like Auto-starts are supported, my thought is new resources could be created or a more general resource could be created to support multiple types. I'm very open to feedback on resource naming and overall approach. References: Feature Announcement azure.microsoft.com/en-us/blog/announcing-auto-shutdown-for-vms-using-azure-resource-manager API Docs docs.microsoft.com/en-us/rest/api/dtl/globalschedules Example Usage Forum Post social.msdn.microsoft.com/Forums/en-US/25a02403-dba9-4bcb-bdcc-1f4afcba5b65/powershell-script-to-autoshutdown-azure-virtual-machine?forum=WAVirtualMachinesforWindows --- .teamcity/components/generated/services.kt | 1 + .../services/devtestlabs/client/client.go | 25 +- ...st_global_vm_shutdown_schedule_resource.go | 296 ++++++++++++++++++ ...obal_vm_shutdown_schedule_resource_test.go | 289 +++++++++++++++++ .../dev_test_lab_data_source_test.go | 2 +- .../{tests => }/dev_test_lab_resource_test.go | 40 +-- .../dev_test_lab_schedule_resource_test.go | 50 +-- ...est_linux_virtual_machine_resource_test.go | 74 ++--- .../dev_test_policy_resource_test.go | 40 +-- ...v_test_virtual_network_data_source_test.go | 2 +- .../dev_test_virtual_network_resource_test.go | 40 +-- ...t_windows_virtual_machine_resource_test.go | 62 ++-- .../devtestlabs/parse/global_schedule.go | 33 ++ .../devtestlabs/parse/global_schedule_test.go | 61 ++++ .../parse/global_schedule_virtual_machine.go | 33 ++ .../global_schedule_virtual_machine_test.go | 61 ++++ .../services/devtestlabs/registration.go | 13 +- .../devtestlabs/validate/global_schedule.go | 22 ++ .../validate/global_schedule_test.go | 40 +++ .../global_schedule_virtual_machine.go | 22 ++ .../global_schedule_virtual_machine_test.go | 40 +++ website/azurerm.erb | 4 + ..._global_vm_shutdown_schedule.html.markdown | 133 ++++++++ .../docs/r/dev_test_schedule.html.markdown | 16 +- .../docs/r/storage_table_entity.html.markdown | 2 +- 25 files changed, 1221 insertions(+), 180 deletions(-) create mode 100644 azurerm/internal/services/devtestlabs/dev_test_global_vm_shutdown_schedule_resource.go create mode 100644 azurerm/internal/services/devtestlabs/dev_test_global_vm_shutdown_schedule_resource_test.go rename azurerm/internal/services/devtestlabs/{tests => }/dev_test_lab_data_source_test.go (99%) rename azurerm/internal/services/devtestlabs/{tests => }/dev_test_lab_resource_test.go (79%) rename azurerm/internal/services/devtestlabs/{tests => }/dev_test_lab_schedule_resource_test.go (85%) rename azurerm/internal/services/devtestlabs/{tests => }/dev_test_linux_virtual_machine_resource_test.go (80%) rename azurerm/internal/services/devtestlabs/{tests => }/dev_test_policy_resource_test.go (81%) rename azurerm/internal/services/devtestlabs/{tests => }/dev_test_virtual_network_data_source_test.go (99%) rename azurerm/internal/services/devtestlabs/{tests => }/dev_test_virtual_network_resource_test.go (82%) rename azurerm/internal/services/devtestlabs/{tests => }/dev_test_windows_virtual_machine_resource_test.go (80%) create mode 100644 azurerm/internal/services/devtestlabs/parse/global_schedule.go create mode 100644 azurerm/internal/services/devtestlabs/parse/global_schedule_test.go create mode 100644 azurerm/internal/services/devtestlabs/parse/global_schedule_virtual_machine.go create mode 100644 azurerm/internal/services/devtestlabs/parse/global_schedule_virtual_machine_test.go create mode 100644 azurerm/internal/services/devtestlabs/validate/global_schedule.go create mode 100644 azurerm/internal/services/devtestlabs/validate/global_schedule_test.go create mode 100644 azurerm/internal/services/devtestlabs/validate/global_schedule_virtual_machine.go create mode 100644 azurerm/internal/services/devtestlabs/validate/global_schedule_virtual_machine_test.go create mode 100644 website/docs/r/dev_test_global_vm_shutdown_schedule.html.markdown diff --git a/.teamcity/components/generated/services.kt b/.teamcity/components/generated/services.kt index 1f98d158e478..227160c1904b 100644 --- a/.teamcity/components/generated/services.kt +++ b/.teamcity/components/generated/services.kt @@ -70,6 +70,7 @@ var services = mapOf( "storage" to "Storage", "streamanalytics" to "Stream Analytics", "subscription" to "Subscription", + "iottimeseriesinsights" to "Time Series Insights", "trafficmanager" to "Traffic Manager", "web" to "Web" ) \ No newline at end of file diff --git a/azurerm/internal/services/devtestlabs/client/client.go b/azurerm/internal/services/devtestlabs/client/client.go index 869818017b94..bcf61e99d341 100644 --- a/azurerm/internal/services/devtestlabs/client/client.go +++ b/azurerm/internal/services/devtestlabs/client/client.go @@ -6,11 +6,12 @@ import ( ) type Client struct { - LabsClient *dtl.LabsClient - LabSchedulesClient *dtl.SchedulesClient - PoliciesClient *dtl.PoliciesClient - VirtualMachinesClient *dtl.VirtualMachinesClient - VirtualNetworksClient *dtl.VirtualNetworksClient + GlobalLabSchedulesClient *dtl.GlobalSchedulesClient + LabsClient *dtl.LabsClient + LabSchedulesClient *dtl.SchedulesClient + PoliciesClient *dtl.PoliciesClient + VirtualMachinesClient *dtl.VirtualMachinesClient + VirtualNetworksClient *dtl.VirtualNetworksClient } func NewClient(o *common.ClientOptions) *Client { @@ -29,11 +30,15 @@ func NewClient(o *common.ClientOptions) *Client { LabSchedulesClient := dtl.NewSchedulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&LabSchedulesClient.Client, o.ResourceManagerAuthorizer) + GlobalLabSchedulesClient := dtl.NewGlobalSchedulesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) + o.ConfigureClient(&GlobalLabSchedulesClient.Client, o.ResourceManagerAuthorizer) + return &Client{ - LabsClient: &LabsClient, - LabSchedulesClient: &LabSchedulesClient, - PoliciesClient: &PoliciesClient, - VirtualMachinesClient: &VirtualMachinesClient, - VirtualNetworksClient: &VirtualNetworksClient, + GlobalLabSchedulesClient: &GlobalLabSchedulesClient, + LabsClient: &LabsClient, + LabSchedulesClient: &LabSchedulesClient, + PoliciesClient: &PoliciesClient, + VirtualMachinesClient: &VirtualMachinesClient, + VirtualNetworksClient: &VirtualNetworksClient, } } diff --git a/azurerm/internal/services/devtestlabs/dev_test_global_vm_shutdown_schedule_resource.go b/azurerm/internal/services/devtestlabs/dev_test_global_vm_shutdown_schedule_resource.go new file mode 100644 index 000000000000..0fec54df6ef4 --- /dev/null +++ b/azurerm/internal/services/devtestlabs/dev_test_global_vm_shutdown_schedule_resource.go @@ -0,0 +1,296 @@ +package devtestlabs + +import ( + "fmt" + "regexp" + "time" + + "github.com/Azure/azure-sdk-for-go/services/devtestlabs/mgmt/2016-05-15/dtl" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/devtestlabs/parse" + devtestValidate "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/devtestlabs/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags" + azSchema "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/schema" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmDevTestLabGlobalVMShutdownSchedule() *schema.Resource { + return &schema.Resource{ + Create: resourceArmDevTestLabGlobalVMShutdownScheduleCreateUpdate, + Read: resourceArmDevTestLabGlobalVMShutdownScheduleRead, + Update: resourceArmDevTestLabGlobalVMShutdownScheduleCreateUpdate, + Delete: resourceArmDevTestLabGlobalVMShutdownScheduleDelete, + Importer: azSchema.ValidateResourceIDPriorToImport(func(id string) error { + _, err := parse.GlobalScheduleID(id) + return err + }), + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Read: schema.DefaultTimeout(5 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "location": azure.SchemaLocation(), + + "virtual_machine_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: devtestValidate.GlobalScheduleVirtualMachineID, + }, + + "enabled": { + Type: schema.TypeBool, + Optional: true, + Default: true, + }, + + "daily_recurrence_time": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile("^(0[0-9]|1[0-9]|2[0-3]|[0-9])[0-5][0-9]$"), + "Time of day must match the format HHmm where HH is 00-23 and mm is 00-59", + ), + }, + + "timezone": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validate.VirtualMachineTimeZoneCaseInsensitive(), + }, + + "notification_settings": { + Type: schema.TypeList, + Required: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enabled": { + Type: schema.TypeBool, + Required: true, + }, + "time_in_minutes": { + Type: schema.TypeInt, + Optional: true, + Default: 30, + ValidateFunc: validation.IntBetween(15, 120), + }, + "webhook_url": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, + + "tags": tags.Schema(), + }, + } +} + +func resourceArmDevTestLabGlobalVMShutdownScheduleCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).DevTestLabs.GlobalLabSchedulesClient + ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d) + defer cancel() + + vmID := d.Get("virtual_machine_id").(string) + id, err := parse.GlobalScheduleVirtualMachineID(vmID) + if err != nil { + return err + } + + // Can't find any official documentation on this, but the API returns a 400 for any other name. + // The best example I could find is here: https://social.msdn.microsoft.com/Forums/en-US/25a02403-dba9-4bcb-bdcc-1f4afcba5b65/powershell-script-to-autoshutdown-azure-virtual-machine?forum=WAVirtualMachinesforWindows + name := "shutdown-computevm-" + id.Name + + if features.ShouldResourcesBeImported() && d.IsNewResource() { + existing, err := client.Get(ctx, id.ResourceGroup, name, "") + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Schedule %q (Resource Group %q): %s", name, id.ResourceGroup, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_dev_test_global_vm_shutdown_schedule", *existing.ID) + } + } + + location := azure.NormalizeLocation(d.Get("location").(string)) + taskType := "ComputeVmShutdownTask" + + schedule := dtl.Schedule{ + Location: &location, + ScheduleProperties: &dtl.ScheduleProperties{ + TargetResourceID: &vmID, + TaskType: &taskType, + }, + Tags: tags.Expand(d.Get("tags").(map[string]interface{})), + } + + if d.Get("enabled").(bool) { + schedule.ScheduleProperties.Status = dtl.EnableStatusEnabled + } else { + schedule.ScheduleProperties.Status = dtl.EnableStatusDisabled + } + + if timeZoneId := d.Get("timezone").(string); timeZoneId != "" { + schedule.ScheduleProperties.TimeZoneID = &timeZoneId + } + + if v, ok := d.GetOk("daily_recurrence_time"); ok { + dailyRecurrence := expandArmDevTestLabGlobalVMShutdownScheduleRecurrenceDaily(v) + schedule.DailyRecurrence = dailyRecurrence + } + + if _, ok := d.GetOk("notification_settings"); ok { + notificationSettings := expandArmDevTestLabGlobalVMShutdownScheduleNotificationSettings(d) + schedule.NotificationSettings = notificationSettings + } + + if _, err := client.CreateOrUpdate(ctx, id.ResourceGroup, name, schedule); err != nil { + return err + } + + read, err := client.Get(ctx, id.ResourceGroup, name, "") + if err != nil { + return err + } + + if read.ID == nil { + return fmt.Errorf("Cannot read Dev Test Global Schedule %s (resource group %s) ID", name, id.ResourceGroup) + } + + d.SetId(*read.ID) + + return resourceArmDevTestLabGlobalVMShutdownScheduleRead(d, meta) +} + +func resourceArmDevTestLabGlobalVMShutdownScheduleRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).DevTestLabs.GlobalLabSchedulesClient + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.GlobalScheduleID(d.Id()) + if err != nil { + return err + } + + resp, err := client.Get(ctx, id.ResourceGroup, id.Name, "") + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + d.SetId("") + return nil + } + return fmt.Errorf("Error making Read request on Dev Test Global Schedule %s: %s", id.Name, err) + } + + if location := resp.Location; location != nil { + d.Set("location", azure.NormalizeLocation(*location)) + } + + if props := resp.ScheduleProperties; props != nil { + d.Set("virtual_machine_id", props.TargetResourceID) + d.Set("timezone", props.TimeZoneID) + d.Set("enabled", props.Status == dtl.EnableStatusEnabled) + + if err := d.Set("daily_recurrence_time", flattenArmDevTestLabGlobalVMShutdownScheduleRecurrenceDaily(props.DailyRecurrence)); err != nil { + return fmt.Errorf("Error setting `dailyRecurrence`: %#v", err) + } + + if err := d.Set("notification_settings", flattenArmDevTestLabGlobalVMShutdownScheduleNotificationSettings(props.NotificationSettings)); err != nil { + return fmt.Errorf("Error setting `notificationSettings`: %#v", err) + } + } + + return tags.FlattenAndSet(d, resp.Tags) +} + +func resourceArmDevTestLabGlobalVMShutdownScheduleDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).DevTestLabs.GlobalLabSchedulesClient + ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.GlobalScheduleID(d.Id()) + if err != nil { + return err + } + + if _, err := client.Delete(ctx, id.ResourceGroup, id.Name); err != nil { + return err + } + + return nil +} + +func expandArmDevTestLabGlobalVMShutdownScheduleRecurrenceDaily(dailyTime interface{}) *dtl.DayDetails { + time := dailyTime.(string) + return &dtl.DayDetails{ + Time: &time, + } +} + +func flattenArmDevTestLabGlobalVMShutdownScheduleRecurrenceDaily(dailyRecurrence *dtl.DayDetails) interface{} { + if dailyRecurrence == nil { + return nil + } + + var result string + if dailyRecurrence.Time != nil { + result = *dailyRecurrence.Time + } + + return result +} + +func expandArmDevTestLabGlobalVMShutdownScheduleNotificationSettings(d *schema.ResourceData) *dtl.NotificationSettings { + notificationSettingsConfigs := d.Get("notification_settings").([]interface{}) + notificationSettingsConfig := notificationSettingsConfigs[0].(map[string]interface{}) + webhookUrl := notificationSettingsConfig["webhook_url"].(string) + timeInMinutes := int32(notificationSettingsConfig["time_in_minutes"].(int)) + + var notificationStatus dtl.NotificationStatus + if notificationSettingsConfig["enabled"].(bool) { + notificationStatus = dtl.NotificationStatusEnabled + } else { + notificationStatus = dtl.NotificationStatusDisabled + } + + return &dtl.NotificationSettings{ + WebhookURL: &webhookUrl, + TimeInMinutes: &timeInMinutes, + Status: notificationStatus, + } +} + +func flattenArmDevTestLabGlobalVMShutdownScheduleNotificationSettings(notificationSettings *dtl.NotificationSettings) []interface{} { + if notificationSettings == nil { + return []interface{}{} + } + + result := make(map[string]interface{}) + + if notificationSettings.WebhookURL != nil { + result["webhook_url"] = *notificationSettings.WebhookURL + } + + if notificationSettings.TimeInMinutes != nil { + result["time_in_minutes"] = *notificationSettings.TimeInMinutes + } + + result["enabled"] = notificationSettings.Status == dtl.NotificationStatusEnabled + + return []interface{}{result} +} diff --git a/azurerm/internal/services/devtestlabs/dev_test_global_vm_shutdown_schedule_resource_test.go b/azurerm/internal/services/devtestlabs/dev_test_global_vm_shutdown_schedule_resource_test.go new file mode 100644 index 000000000000..50c623609568 --- /dev/null +++ b/azurerm/internal/services/devtestlabs/dev_test_global_vm_shutdown_schedule_resource_test.go @@ -0,0 +1,289 @@ +package devtestlabs_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/devtestlabs/parse" +) + +func TestAccDevTestLabGlobalVMShutdownSchedule_autoShutdownBasic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_dev_test_global_vm_shutdown_schedule", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckDevTestLabGlobalVMShutdownScheduleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDevTestLabGlobalVMShutdownSchedule_autoShutdownBasic(data), + Check: resource.ComposeTestCheckFunc( + testCheckDevTestLabGlobalVMShutdownScheduleExists(data.ResourceName), + resource.TestCheckResourceAttr(data.ResourceName, "enabled", "true"), + resource.TestCheckResourceAttr(data.ResourceName, "timezone", "Pacific Standard Time"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.0.enabled", "false"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.0.time_in_minutes", "30"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.0.webhook_url", ""), + resource.TestCheckResourceAttr(data.ResourceName, "daily_recurrence_time", "0100"), + resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "tags.environment", "Production"), + ), + }, + data.ImportStep(), + }, + }) +} + +func TestAccDevTestLabGlobalVMShutdownSchedule_autoShutdownComplete(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_dev_test_global_vm_shutdown_schedule", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckDevTestLabGlobalVMShutdownScheduleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDevTestLabGlobalVMShutdownSchedule_autoShutdownComplete(data), + Check: resource.ComposeTestCheckFunc( + testCheckDevTestLabGlobalVMShutdownScheduleExists(data.ResourceName), + resource.TestCheckResourceAttr(data.ResourceName, "enabled", "false"), + resource.TestCheckResourceAttr(data.ResourceName, "timezone", "Central Standard Time"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.0.time_in_minutes", "15"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.0.webhook_url", "https://www.bing.com/2/4"), + resource.TestCheckResourceAttr(data.ResourceName, "daily_recurrence_time", "1100"), + resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "tags.Environment", "Production"), + ), + }, + data.ImportStep(), + }, + }) +} + +func TestAccDevTestLabGlobalVMShutdownSchedule_autoShutdownUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_dev_test_global_vm_shutdown_schedule", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckDevTestLabGlobalVMShutdownScheduleDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDevTestLabGlobalVMShutdownSchedule_autoShutdownBasic(data), + Check: resource.ComposeTestCheckFunc( + testCheckDevTestLabGlobalVMShutdownScheduleExists(data.ResourceName), + resource.TestCheckResourceAttr(data.ResourceName, "enabled", "true"), + resource.TestCheckResourceAttr(data.ResourceName, "timezone", "Pacific Standard Time"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.0.enabled", "false"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.0.time_in_minutes", "30"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.0.webhook_url", ""), + resource.TestCheckResourceAttr(data.ResourceName, "daily_recurrence_time", "0100"), + resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "tags.environment", "Production"), + ), + }, + data.ImportStep(), + { + Config: testAccDevTestLabGlobalVMShutdownSchedule_autoShutdownComplete(data), + Check: resource.ComposeTestCheckFunc( + testCheckDevTestLabGlobalVMShutdownScheduleExists(data.ResourceName), + resource.TestCheckResourceAttr(data.ResourceName, "enabled", "false"), + resource.TestCheckResourceAttr(data.ResourceName, "timezone", "Central Standard Time"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.#", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.0.enabled", "true"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.0.time_in_minutes", "15"), + resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.0.webhook_url", "https://www.bing.com/2/4"), + resource.TestCheckResourceAttr(data.ResourceName, "daily_recurrence_time", "1100"), + resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "1"), + resource.TestCheckResourceAttr(data.ResourceName, "tags.Environment", "Production"), + ), + }, + }, + }) +} + +func testCheckDevTestLabGlobalVMShutdownScheduleExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %s", resourceName) + } + + targetResourceID := rs.Primary.Attributes["virtual_machine_id"] + exists, err := testCheckDevTestLabGlobalVMShutdownScheduleExistsInternal(targetResourceID) + + if err != nil { + return fmt.Errorf("Error checking if item has been created: %s", err) + } + if !exists { + return fmt.Errorf("Bad: Dev Test Lab Global Schedule %q does not exist", targetResourceID) + } + + return nil + } +} + +func testCheckDevTestLabGlobalVMShutdownScheduleDestroy(s *terraform.State) error { + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_dev_test_global_vm_shutdown_schedule" { + continue + } + + targetResourceID := rs.Primary.Attributes["virtual_machine_id"] + exists, err := testCheckDevTestLabGlobalVMShutdownScheduleExistsInternal(targetResourceID) + + if err != nil { + return fmt.Errorf("Error checking if item has been destroyed: %s", err) + } + if exists { + return fmt.Errorf("Bad: Dev Test Lab Global Schedule %q still exists", targetResourceID) + } + } + + return nil +} + +func testCheckDevTestLabGlobalVMShutdownScheduleExistsInternal(vmID string) (bool, error) { + client := acceptance.AzureProvider.Meta().(*clients.Client).DevTestLabs.GlobalLabSchedulesClient + ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext + + vm, err := parse.GlobalScheduleVirtualMachineID(vmID) + if err != nil { + return false, fmt.Errorf("Bad: Failed to parse ID (id: %s): %+v", vmID, err) + } + + vmName := vm.Name + name := "shutdown-computevm-" + vmName // Auto-shutdown schedule must use this naming format for Compute VMs + resourceGroup := vm.ResourceGroup + + resp, err := client.Get(ctx, resourceGroup, name, "") + if err != nil { + if resp.Response.IsHTTPStatus(404) { + return false, nil + } + return false, fmt.Errorf("Bad: Get on devTestLabsGlobalSchedules client (id: %s): %+v", vmID, err) + } + + return true, nil +} + +func testAccDevTestLabGlobalVMShutdownSchedule_template(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-dtl-%d" + location = "%s" +} + +resource "azurerm_virtual_network" "test" { + name = "acctestVN-%d" + address_space = ["10.0.0.0/16"] + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name +} + +resource "azurerm_subnet" "test" { + name = "acctestSN-%d" + resource_group_name = azurerm_resource_group.test.name + virtual_network_name = azurerm_virtual_network.test.name + address_prefix = "10.0.2.0/24" +} + +resource "azurerm_network_interface" "test" { + name = "acctestNIC-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + + ip_configuration { + name = "testconfiguration1" + subnet_id = azurerm_subnet.test.id + private_ip_address_allocation = "Dynamic" + } +} + +resource "azurerm_linux_virtual_machine" "test" { + name = "acctestVM-%d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + network_interface_ids = [azurerm_network_interface.test.id] + size = "Standard_B2s" + + admin_username = "testadmin" + admin_password = "Password1234!" + disable_password_authentication = false + + source_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "18.04-LTS" + version = "latest" + } + + os_disk { + name = "myosdisk-%d" + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + } +} +`, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger, data.RandomInteger) +} + +func testAccDevTestLabGlobalVMShutdownSchedule_autoShutdownBasic(data acceptance.TestData) string { + template := testAccDevTestLabGlobalVMShutdownSchedule_template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_dev_test_global_vm_shutdown_schedule" "test" { + location = azurerm_resource_group.test.location + virtual_machine_id = azurerm_linux_virtual_machine.test.id + daily_recurrence_time = "0100" + timezone = "Pacific Standard Time" + + notification_settings { + enabled = false + } + + tags = { + environment = "Production" + } +} +`, template) +} + +func testAccDevTestLabGlobalVMShutdownSchedule_autoShutdownComplete(data acceptance.TestData) string { + template := testAccDevTestLabGlobalVMShutdownSchedule_template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_dev_test_global_vm_shutdown_schedule" "test" { + location = azurerm_resource_group.test.location + virtual_machine_id = azurerm_linux_virtual_machine.test.id + enabled = false + + daily_recurrence_time = "1100" + timezone = "Central Standard Time" + + notification_settings { + time_in_minutes = 15 + webhook_url = "https://www.bing.com/2/4" + enabled = true + } + + tags = { + Environment = "Production" + } +} + +`, template) +} diff --git a/azurerm/internal/services/devtestlabs/tests/dev_test_lab_data_source_test.go b/azurerm/internal/services/devtestlabs/dev_test_lab_data_source_test.go similarity index 99% rename from azurerm/internal/services/devtestlabs/tests/dev_test_lab_data_source_test.go rename to azurerm/internal/services/devtestlabs/dev_test_lab_data_source_test.go index 4a37fda3ac5e..8e56635af02d 100644 --- a/azurerm/internal/services/devtestlabs/tests/dev_test_lab_data_source_test.go +++ b/azurerm/internal/services/devtestlabs/dev_test_lab_data_source_test.go @@ -1,4 +1,4 @@ -package tests +package devtestlabs_test import ( "fmt" diff --git a/azurerm/internal/services/devtestlabs/tests/dev_test_lab_resource_test.go b/azurerm/internal/services/devtestlabs/dev_test_lab_resource_test.go similarity index 79% rename from azurerm/internal/services/devtestlabs/tests/dev_test_lab_resource_test.go rename to azurerm/internal/services/devtestlabs/dev_test_lab_resource_test.go index 186ec0872a0c..2435bf6068fb 100644 --- a/azurerm/internal/services/devtestlabs/tests/dev_test_lab_resource_test.go +++ b/azurerm/internal/services/devtestlabs/dev_test_lab_resource_test.go @@ -1,4 +1,4 @@ -package tests +package devtestlabs_test import ( "fmt" @@ -11,18 +11,18 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" ) -func TestAccAzureRMDevTestLab_basic(t *testing.T) { +func TestAccDevTestLab_basic(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_lab", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestLabDestroy, + CheckDestroy: testCheckDevTestLabDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestLab_basic(data), + Config: testAccDevTestLab_basic(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestLabExists(data.ResourceName), + testCheckDevTestLabExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "storage_type", "Premium"), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "0"), ), @@ -32,40 +32,40 @@ func TestAccAzureRMDevTestLab_basic(t *testing.T) { }) } -func TestAccAzureRMDevTestLab_requiresImport(t *testing.T) { +func TestAccDevTestLab_requiresImport(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_lab", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestLabDestroy, + CheckDestroy: testCheckDevTestLabDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestLab_basic(data), + Config: testAccDevTestLab_basic(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestLabExists(data.ResourceName), + testCheckDevTestLabExists(data.ResourceName), ), }, { - Config: testAccAzureRMDevTestLab_requiresImport(data), + Config: testAccDevTestLab_requiresImport(data), ExpectError: acceptance.RequiresImportError("azurerm_dev_test_lab"), }, }, }) } -func TestAccAzureRMDevTestLab_complete(t *testing.T) { +func TestAccDevTestLab_complete(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_lab", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestLabDestroy, + CheckDestroy: testCheckDevTestLabDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestLab_complete(data), + Config: testAccDevTestLab_complete(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestLabExists(data.ResourceName), + testCheckDevTestLabExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "storage_type", "Standard"), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "1"), resource.TestCheckResourceAttr(data.ResourceName, "tags.Hello", "World"), @@ -76,7 +76,7 @@ func TestAccAzureRMDevTestLab_complete(t *testing.T) { }) } -func testCheckAzureRMDevTestLabExists(resourceName string) resource.TestCheckFunc { +func testCheckDevTestLabExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acceptance.AzureProvider.Meta().(*clients.Client).DevTestLabs.LabsClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext @@ -106,7 +106,7 @@ func testCheckAzureRMDevTestLabExists(resourceName string) resource.TestCheckFun } } -func testCheckAzureRMDevTestLabDestroy(s *terraform.State) error { +func testCheckDevTestLabDestroy(s *terraform.State) error { conn := acceptance.AzureProvider.Meta().(*clients.Client).DevTestLabs.LabsClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext @@ -134,7 +134,7 @@ func testCheckAzureRMDevTestLabDestroy(s *terraform.State) error { return nil } -func testAccAzureRMDevTestLab_basic(data acceptance.TestData) string { +func testAccDevTestLab_basic(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { features {} @@ -153,8 +153,8 @@ resource "azurerm_dev_test_lab" "test" { `, data.RandomInteger, data.Locations.Primary, data.RandomInteger) } -func testAccAzureRMDevTestLab_requiresImport(data acceptance.TestData) string { - template := testAccAzureRMDevTestLab_basic(data) +func testAccDevTestLab_requiresImport(data acceptance.TestData) string { + template := testAccDevTestLab_basic(data) return fmt.Sprintf(` %s @@ -166,7 +166,7 @@ resource "azurerm_dev_test_lab" "import" { `, template) } -func testAccAzureRMDevTestLab_complete(data acceptance.TestData) string { +func testAccDevTestLab_complete(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { features {} diff --git a/azurerm/internal/services/devtestlabs/tests/dev_test_lab_schedule_resource_test.go b/azurerm/internal/services/devtestlabs/dev_test_lab_schedule_resource_test.go similarity index 85% rename from azurerm/internal/services/devtestlabs/tests/dev_test_lab_schedule_resource_test.go rename to azurerm/internal/services/devtestlabs/dev_test_lab_schedule_resource_test.go index 870db269ba88..ca1553ea83e1 100644 --- a/azurerm/internal/services/devtestlabs/tests/dev_test_lab_schedule_resource_test.go +++ b/azurerm/internal/services/devtestlabs/dev_test_lab_schedule_resource_test.go @@ -1,4 +1,4 @@ -package tests +package devtestlabs_test import ( "fmt" @@ -11,18 +11,18 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" ) -func TestAccAzureRMDevTestLabSchedule_autoShutdownBasic(t *testing.T) { +func TestAccDevTestLabSchedule_autoShutdownBasic(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_schedule", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestLabScheduleDestroy, + CheckDestroy: testCheckDevTestLabScheduleDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestLabSchedule_autoShutdownBasic(data), + Config: testAccDevTestLabSchedule_autoShutdownBasic(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestLabScheduleExists(data.ResourceName), + testCheckDevTestLabScheduleExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "status", "Disabled"), resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.#", "1"), resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.0.status", "Disabled"), @@ -32,9 +32,9 @@ func TestAccAzureRMDevTestLabSchedule_autoShutdownBasic(t *testing.T) { }, data.ImportStep(), { - Config: testAccAzureRMDevTestLabSchedule_autoShutdownBasicUpdate(data), + Config: testAccDevTestLabSchedule_autoShutdownBasicUpdate(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestLabScheduleExists(data.ResourceName), + testCheckDevTestLabScheduleExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "status", "Enabled"), resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.#", "1"), resource.TestCheckResourceAttr(data.ResourceName, "notification_settings.0.status", "Enabled"), @@ -48,18 +48,18 @@ func TestAccAzureRMDevTestLabSchedule_autoShutdownBasic(t *testing.T) { }) } -func TestAccAzureRMDevTestLabSchedule_autoStartupBasic(t *testing.T) { +func TestAccDevTestLabSchedule_autoStartupBasic(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_schedule", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestLabScheduleDestroy, + CheckDestroy: testCheckDevTestLabScheduleDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestLabSchedule_autoStartupBasic(data), + Config: testAccDevTestLabSchedule_autoStartupBasic(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestLabScheduleExists(data.ResourceName), + testCheckDevTestLabScheduleExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "status", "Disabled"), resource.TestCheckResourceAttr(data.ResourceName, "weekly_recurrence.#", "1"), resource.TestCheckResourceAttr(data.ResourceName, "weekly_recurrence.0.time", "1100"), @@ -69,9 +69,9 @@ func TestAccAzureRMDevTestLabSchedule_autoStartupBasic(t *testing.T) { }, data.ImportStep("task_type"), { - Config: testAccAzureRMDevTestLabSchedule_autoStartupBasicUpdate(data), + Config: testAccDevTestLabSchedule_autoStartupBasicUpdate(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestLabScheduleExists(data.ResourceName), + testCheckDevTestLabScheduleExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "status", "Enabled"), resource.TestCheckResourceAttr(data.ResourceName, "weekly_recurrence.#", "1"), resource.TestCheckResourceAttr(data.ResourceName, "weekly_recurrence.0.time", "1000"), @@ -83,27 +83,27 @@ func TestAccAzureRMDevTestLabSchedule_autoStartupBasic(t *testing.T) { }) } -func TestAccAzureRMDevTestLabSchedule_concurrent(t *testing.T) { +func TestAccDevTestLabSchedule_concurrent(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_schedule", "test") secondResourceName := "azurerm_dev_test_schedule.test2" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestLabScheduleDestroy, + CheckDestroy: testCheckDevTestLabScheduleDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestLabSchedule_concurrent(data), + Config: testAccDevTestLabSchedule_concurrent(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestLabScheduleExists(data.ResourceName), - testCheckAzureRMDevTestLabScheduleExists(secondResourceName), + testCheckDevTestLabScheduleExists(data.ResourceName), + testCheckDevTestLabScheduleExists(secondResourceName), ), }, }, }) } -func testCheckAzureRMDevTestLabScheduleExists(resourceName string) resource.TestCheckFunc { +func testCheckDevTestLabScheduleExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { client := acceptance.AzureProvider.Meta().(*clients.Client).DevTestLabs.LabSchedulesClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext @@ -130,7 +130,7 @@ func testCheckAzureRMDevTestLabScheduleExists(resourceName string) resource.Test } } -func testCheckAzureRMDevTestLabScheduleDestroy(s *terraform.State) error { +func testCheckDevTestLabScheduleDestroy(s *terraform.State) error { client := acceptance.AzureProvider.Meta().(*clients.Client).DevTestLabs.LabSchedulesClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext @@ -157,7 +157,7 @@ func testCheckAzureRMDevTestLabScheduleDestroy(s *terraform.State) error { return nil } -func testAccAzureRMDevTestLabSchedule_autoShutdownBasic(data acceptance.TestData) string { +func testAccDevTestLabSchedule_autoShutdownBasic(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { features {} @@ -194,7 +194,7 @@ resource "azurerm_dev_test_schedule" "test" { `, data.RandomInteger, data.Locations.Primary, data.RandomInteger) } -func testAccAzureRMDevTestLabSchedule_autoShutdownBasicUpdate(data acceptance.TestData) string { +func testAccDevTestLabSchedule_autoShutdownBasicUpdate(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { features {} @@ -234,7 +234,7 @@ resource "azurerm_dev_test_schedule" "test" { `, data.RandomInteger, data.Locations.Primary, data.RandomInteger) } -func testAccAzureRMDevTestLabSchedule_autoStartupBasic(data acceptance.TestData) string { +func testAccDevTestLabSchedule_autoStartupBasic(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { features {} @@ -274,7 +274,7 @@ resource "azurerm_dev_test_schedule" "test" { `, data.RandomInteger, data.Locations.Primary, data.RandomInteger) } -func testAccAzureRMDevTestLabSchedule_autoStartupBasicUpdate(data acceptance.TestData) string { +func testAccDevTestLabSchedule_autoStartupBasicUpdate(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { features {} @@ -316,7 +316,7 @@ resource "azurerm_dev_test_schedule" "test" { `, data.RandomInteger, data.Locations.Primary, data.RandomInteger) } -func testAccAzureRMDevTestLabSchedule_concurrent(data acceptance.TestData) string { +func testAccDevTestLabSchedule_concurrent(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { features {} diff --git a/azurerm/internal/services/devtestlabs/tests/dev_test_linux_virtual_machine_resource_test.go b/azurerm/internal/services/devtestlabs/dev_test_linux_virtual_machine_resource_test.go similarity index 80% rename from azurerm/internal/services/devtestlabs/tests/dev_test_linux_virtual_machine_resource_test.go rename to azurerm/internal/services/devtestlabs/dev_test_linux_virtual_machine_resource_test.go index 3cd4b44f0b7a..1bbaef6c895f 100644 --- a/azurerm/internal/services/devtestlabs/tests/dev_test_linux_virtual_machine_resource_test.go +++ b/azurerm/internal/services/devtestlabs/dev_test_linux_virtual_machine_resource_test.go @@ -1,4 +1,4 @@ -package tests +package devtestlabs_test import ( "fmt" @@ -11,18 +11,18 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" ) -func TestAccAzureRMDevTestLinuxVirtualMachine_basic(t *testing.T) { +func TestAccDevTestLinuxVirtualMachine_basic(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_linux_virtual_machine", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestLinuxVirtualMachineDestroy, + CheckDestroy: testCheckDevTestLinuxVirtualMachineDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestLinuxVirtualMachine_basic(data), + Config: testAccDevTestLinuxVirtualMachine_basic(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestLinuxVirtualMachineExists(data.ResourceName), + testCheckDevTestLinuxVirtualMachineExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "gallery_image_reference.0.publisher", "Canonical"), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "0"), ), @@ -37,40 +37,40 @@ func TestAccAzureRMDevTestLinuxVirtualMachine_basic(t *testing.T) { }) } -func TestAccAzureRMDevTestLinuxVirtualMachine_requiresImport(t *testing.T) { +func TestAccDevTestLinuxVirtualMachine_requiresImport(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_linux_virtual_machine", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestLinuxVirtualMachineDestroy, + CheckDestroy: testCheckDevTestLinuxVirtualMachineDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestLinuxVirtualMachine_basic(data), + Config: testAccDevTestLinuxVirtualMachine_basic(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestLinuxVirtualMachineExists(data.ResourceName), + testCheckDevTestLinuxVirtualMachineExists(data.ResourceName), ), }, { - Config: testAccAzureRMDevTestLinuxVirtualMachine_requiresImport(data), + Config: testAccDevTestLinuxVirtualMachine_requiresImport(data), ExpectError: acceptance.RequiresImportError("azurerm_dev_test_lab_linux_virtual_machine"), }, }, }) } -func TestAccAzureRMDevTestLinuxVirtualMachine_basicSSH(t *testing.T) { +func TestAccDevTestLinuxVirtualMachine_basicSSH(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_linux_virtual_machine", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestLinuxVirtualMachineDestroy, + CheckDestroy: testCheckDevTestLinuxVirtualMachineDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestLinuxVirtualMachine_basicSSH(data), + Config: testAccDevTestLinuxVirtualMachine_basicSSH(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestLinuxVirtualMachineExists(data.ResourceName), + testCheckDevTestLinuxVirtualMachineExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "gallery_image_reference.0.publisher", "Canonical"), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "0"), ), @@ -86,18 +86,18 @@ func TestAccAzureRMDevTestLinuxVirtualMachine_basicSSH(t *testing.T) { }) } -func TestAccAzureRMDevTestLinuxVirtualMachine_inboundNatRules(t *testing.T) { +func TestAccDevTestLinuxVirtualMachine_inboundNatRules(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_linux_virtual_machine", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestLinuxVirtualMachineDestroy, + CheckDestroy: testCheckDevTestLinuxVirtualMachineDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestLinuxVirtualMachine_inboundNatRules(data), + Config: testAccDevTestLinuxVirtualMachine_inboundNatRules(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestLinuxVirtualMachineExists(data.ResourceName), + testCheckDevTestLinuxVirtualMachineExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "disallow_public_ip_address", "true"), resource.TestCheckResourceAttr(data.ResourceName, "gallery_image_reference.0.publisher", "Canonical"), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "1"), @@ -115,27 +115,27 @@ func TestAccAzureRMDevTestLinuxVirtualMachine_inboundNatRules(t *testing.T) { }) } -func TestAccAzureRMDevTestLinuxVirtualMachine_updateStorage(t *testing.T) { +func TestAccDevTestLinuxVirtualMachine_updateStorage(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_linux_virtual_machine", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestLinuxVirtualMachineDestroy, + CheckDestroy: testCheckDevTestLinuxVirtualMachineDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestLinuxVirtualMachine_storage(data, "Standard"), + Config: testAccDevTestLinuxVirtualMachine_storage(data, "Standard"), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestLinuxVirtualMachineExists(data.ResourceName), + testCheckDevTestLinuxVirtualMachineExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "gallery_image_reference.0.publisher", "Canonical"), resource.TestCheckResourceAttr(data.ResourceName, "storage_type", "Standard"), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "0"), ), }, { - Config: testAccAzureRMDevTestLinuxVirtualMachine_storage(data, "Premium"), + Config: testAccDevTestLinuxVirtualMachine_storage(data, "Premium"), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestLinuxVirtualMachineExists(data.ResourceName), + testCheckDevTestLinuxVirtualMachineExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "gallery_image_reference.0.publisher", "Canonical"), resource.TestCheckResourceAttr(data.ResourceName, "storage_type", "Premium"), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "0"), @@ -145,7 +145,7 @@ func TestAccAzureRMDevTestLinuxVirtualMachine_updateStorage(t *testing.T) { }) } -func testCheckAzureRMDevTestLinuxVirtualMachineExists(resourceName string) resource.TestCheckFunc { +func testCheckDevTestLinuxVirtualMachineExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acceptance.AzureProvider.Meta().(*clients.Client).DevTestLabs.VirtualMachinesClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext @@ -173,7 +173,7 @@ func testCheckAzureRMDevTestLinuxVirtualMachineExists(resourceName string) resou } } -func testCheckAzureRMDevTestLinuxVirtualMachineDestroy(s *terraform.State) error { +func testCheckDevTestLinuxVirtualMachineDestroy(s *terraform.State) error { conn := acceptance.AzureProvider.Meta().(*clients.Client).DevTestLabs.VirtualMachinesClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext @@ -202,8 +202,8 @@ func testCheckAzureRMDevTestLinuxVirtualMachineDestroy(s *terraform.State) error return nil } -func testAccAzureRMDevTestLinuxVirtualMachine_basic(data acceptance.TestData) string { - template := testAccAzureRMDevTestLinuxVirtualMachine_template(data) +func testAccDevTestLinuxVirtualMachine_basic(data acceptance.TestData) string { + template := testAccDevTestLinuxVirtualMachine_template(data) return fmt.Sprintf(` %s @@ -229,8 +229,8 @@ resource "azurerm_dev_test_linux_virtual_machine" "test" { `, template, data.RandomInteger) } -func testAccAzureRMDevTestLinuxVirtualMachine_requiresImport(data acceptance.TestData) string { - template := testAccAzureRMDevTestLinuxVirtualMachine_basic(data) +func testAccDevTestLinuxVirtualMachine_requiresImport(data acceptance.TestData) string { + template := testAccDevTestLinuxVirtualMachine_basic(data) return fmt.Sprintf(` %s @@ -256,8 +256,8 @@ resource "azurerm_dev_test_linux_virtual_machine" "import" { `, template) } -func testAccAzureRMDevTestLinuxVirtualMachine_basicSSH(data acceptance.TestData) string { - template := testAccAzureRMDevTestLinuxVirtualMachine_template(data) +func testAccDevTestLinuxVirtualMachine_basicSSH(data acceptance.TestData) string { + template := testAccDevTestLinuxVirtualMachine_template(data) return fmt.Sprintf(` %s @@ -283,8 +283,8 @@ resource "azurerm_dev_test_linux_virtual_machine" "test" { `, template, data.RandomInteger) } -func testAccAzureRMDevTestLinuxVirtualMachine_inboundNatRules(data acceptance.TestData) string { - template := testAccAzureRMDevTestLinuxVirtualMachine_template(data) +func testAccDevTestLinuxVirtualMachine_inboundNatRules(data acceptance.TestData) string { + template := testAccDevTestLinuxVirtualMachine_template(data) return fmt.Sprintf(` %s @@ -325,8 +325,8 @@ resource "azurerm_dev_test_linux_virtual_machine" "test" { `, template, data.RandomInteger) } -func testAccAzureRMDevTestLinuxVirtualMachine_storage(data acceptance.TestData, storageType string) string { - template := testAccAzureRMDevTestLinuxVirtualMachine_template(data) +func testAccDevTestLinuxVirtualMachine_storage(data acceptance.TestData, storageType string) string { + template := testAccDevTestLinuxVirtualMachine_template(data) return fmt.Sprintf(` %s @@ -352,7 +352,7 @@ resource "azurerm_dev_test_linux_virtual_machine" "test" { `, template, data.RandomInteger, storageType) } -func testAccAzureRMDevTestLinuxVirtualMachine_template(data acceptance.TestData) string { +func testAccDevTestLinuxVirtualMachine_template(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { features {} diff --git a/azurerm/internal/services/devtestlabs/tests/dev_test_policy_resource_test.go b/azurerm/internal/services/devtestlabs/dev_test_policy_resource_test.go similarity index 81% rename from azurerm/internal/services/devtestlabs/tests/dev_test_policy_resource_test.go rename to azurerm/internal/services/devtestlabs/dev_test_policy_resource_test.go index 2655194c4257..6a73ce2460f6 100644 --- a/azurerm/internal/services/devtestlabs/tests/dev_test_policy_resource_test.go +++ b/azurerm/internal/services/devtestlabs/dev_test_policy_resource_test.go @@ -1,4 +1,4 @@ -package tests +package devtestlabs_test import ( "fmt" @@ -11,18 +11,18 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" ) -func TestAccAzureRMDevTestPolicy_basic(t *testing.T) { +func TestAccDevTestPolicy_basic(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_policy", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestPolicyDestroy, + CheckDestroy: testCheckDevTestPolicyDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestPolicy_basic(data), + Config: testAccDevTestPolicy_basic(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestPolicyExists(data.ResourceName), + testCheckDevTestPolicyExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "0"), ), }, @@ -31,41 +31,41 @@ func TestAccAzureRMDevTestPolicy_basic(t *testing.T) { }) } -func TestAccAzureRMDevTestPolicy_requiresImport(t *testing.T) { +func TestAccDevTestPolicy_requiresImport(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_policy", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestPolicyDestroy, + CheckDestroy: testCheckDevTestPolicyDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestPolicy_basic(data), + Config: testAccDevTestPolicy_basic(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestPolicyExists(data.ResourceName), + testCheckDevTestPolicyExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "0"), ), }, { - Config: testAccAzureRMDevTestPolicy_requiresImport(data), + Config: testAccDevTestPolicy_requiresImport(data), ExpectError: acceptance.RequiresImportError("azurerm_dev_test_policy"), }, }, }) } -func TestAccAzureRMDevTestPolicy_complete(t *testing.T) { +func TestAccDevTestPolicy_complete(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_policy", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestPolicyDestroy, + CheckDestroy: testCheckDevTestPolicyDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestPolicy_complete(data), + Config: testAccDevTestPolicy_complete(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestPolicyExists(data.ResourceName), + testCheckDevTestPolicyExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "1"), resource.TestCheckResourceAttr(data.ResourceName, "tags.Acceptance", "Test"), ), @@ -75,7 +75,7 @@ func TestAccAzureRMDevTestPolicy_complete(t *testing.T) { }) } -func testCheckAzureRMDevTestPolicyExists(resourceName string) resource.TestCheckFunc { +func testCheckDevTestPolicyExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acceptance.AzureProvider.Meta().(*clients.Client).DevTestLabs.PoliciesClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext @@ -104,7 +104,7 @@ func testCheckAzureRMDevTestPolicyExists(resourceName string) resource.TestCheck } } -func testCheckAzureRMDevTestPolicyDestroy(s *terraform.State) error { +func testCheckDevTestPolicyDestroy(s *terraform.State) error { conn := acceptance.AzureProvider.Meta().(*clients.Client).DevTestLabs.PoliciesClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext @@ -134,7 +134,7 @@ func testCheckAzureRMDevTestPolicyDestroy(s *terraform.State) error { return nil } -func testAccAzureRMDevTestPolicy_basic(data acceptance.TestData) string { +func testAccDevTestPolicy_basic(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { features {} @@ -162,8 +162,8 @@ resource "azurerm_dev_test_policy" "test" { `, data.RandomInteger, data.Locations.Primary, data.RandomInteger) } -func testAccAzureRMDevTestPolicy_requiresImport(data acceptance.TestData) string { - template := testAccAzureRMDevTestPolicy_basic(data) +func testAccDevTestPolicy_requiresImport(data acceptance.TestData) string { + template := testAccDevTestPolicy_basic(data) return fmt.Sprintf(` %s @@ -178,7 +178,7 @@ resource "azurerm_dev_test_policy" "import" { `, template) } -func testAccAzureRMDevTestPolicy_complete(data acceptance.TestData) string { +func testAccDevTestPolicy_complete(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { features {} diff --git a/azurerm/internal/services/devtestlabs/tests/dev_test_virtual_network_data_source_test.go b/azurerm/internal/services/devtestlabs/dev_test_virtual_network_data_source_test.go similarity index 99% rename from azurerm/internal/services/devtestlabs/tests/dev_test_virtual_network_data_source_test.go rename to azurerm/internal/services/devtestlabs/dev_test_virtual_network_data_source_test.go index af8cfb7380a3..3aeb82efa6b3 100644 --- a/azurerm/internal/services/devtestlabs/tests/dev_test_virtual_network_data_source_test.go +++ b/azurerm/internal/services/devtestlabs/dev_test_virtual_network_data_source_test.go @@ -1,4 +1,4 @@ -package tests +package devtestlabs_test import ( "fmt" diff --git a/azurerm/internal/services/devtestlabs/tests/dev_test_virtual_network_resource_test.go b/azurerm/internal/services/devtestlabs/dev_test_virtual_network_resource_test.go similarity index 82% rename from azurerm/internal/services/devtestlabs/tests/dev_test_virtual_network_resource_test.go rename to azurerm/internal/services/devtestlabs/dev_test_virtual_network_resource_test.go index 5af1814a9c23..70671ebaefc7 100644 --- a/azurerm/internal/services/devtestlabs/tests/dev_test_virtual_network_resource_test.go +++ b/azurerm/internal/services/devtestlabs/dev_test_virtual_network_resource_test.go @@ -1,4 +1,4 @@ -package tests +package devtestlabs_test import ( "fmt" @@ -40,18 +40,18 @@ func TestValidateDevTestVirtualNetworkName(t *testing.T) { } } -func TestAccAzureRMDevTestVirtualNetwork_basic(t *testing.T) { +func TestAccDevTestVirtualNetwork_basic(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_virtual_network", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestVirtualNetworkDestroy, + CheckDestroy: testCheckDevTestVirtualNetworkDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestVirtualNetwork_basic(data), + Config: testAccDevTestVirtualNetwork_basic(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestVirtualNetworkExists(data.ResourceName), + testCheckDevTestVirtualNetworkExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "0"), ), }, @@ -60,41 +60,41 @@ func TestAccAzureRMDevTestVirtualNetwork_basic(t *testing.T) { }) } -func TestAccAzureRMDevTestVirtualNetwork_requiresImport(t *testing.T) { +func TestAccDevTestVirtualNetwork_requiresImport(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_virtual_network", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestVirtualNetworkDestroy, + CheckDestroy: testCheckDevTestVirtualNetworkDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestVirtualNetwork_basic(data), + Config: testAccDevTestVirtualNetwork_basic(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestVirtualNetworkExists(data.ResourceName), + testCheckDevTestVirtualNetworkExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "0"), ), }, { - Config: testAccAzureRMDevTestVirtualNetwork_requiresImport(data), + Config: testAccDevTestVirtualNetwork_requiresImport(data), ExpectError: acceptance.RequiresImportError("azurerm_dev_test_virtual_network"), }, }, }) } -func TestAccAzureRMDevTestVirtualNetwork_subnet(t *testing.T) { +func TestAccDevTestVirtualNetwork_subnet(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_virtual_network", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestVirtualNetworkDestroy, + CheckDestroy: testCheckDevTestVirtualNetworkDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestVirtualNetwork_subnets(data), + Config: testAccDevTestVirtualNetwork_subnets(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestVirtualNetworkExists(data.ResourceName), + testCheckDevTestVirtualNetworkExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "subnet.#", "1"), resource.TestCheckResourceAttr(data.ResourceName, "subnet.0.use_public_ip_address", "Deny"), resource.TestCheckResourceAttr(data.ResourceName, "subnet.0.use_in_virtual_machine_creation", "Allow"), @@ -106,7 +106,7 @@ func TestAccAzureRMDevTestVirtualNetwork_subnet(t *testing.T) { }) } -func testCheckAzureRMDevTestVirtualNetworkExists(resourceName string) resource.TestCheckFunc { +func testCheckDevTestVirtualNetworkExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acceptance.AzureProvider.Meta().(*clients.Client).DevTestLabs.VirtualNetworksClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext @@ -134,7 +134,7 @@ func testCheckAzureRMDevTestVirtualNetworkExists(resourceName string) resource.T } } -func testCheckAzureRMDevTestVirtualNetworkDestroy(s *terraform.State) error { +func testCheckDevTestVirtualNetworkDestroy(s *terraform.State) error { conn := acceptance.AzureProvider.Meta().(*clients.Client).DevTestLabs.VirtualNetworksClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext @@ -163,7 +163,7 @@ func testCheckAzureRMDevTestVirtualNetworkDestroy(s *terraform.State) error { return nil } -func testAccAzureRMDevTestVirtualNetwork_basic(data acceptance.TestData) string { +func testAccDevTestVirtualNetwork_basic(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { features {} @@ -188,8 +188,8 @@ resource "azurerm_dev_test_virtual_network" "test" { `, data.RandomInteger, data.Locations.Primary, data.RandomInteger, data.RandomInteger) } -func testAccAzureRMDevTestVirtualNetwork_requiresImport(data acceptance.TestData) string { - template := testAccAzureRMDevTestVirtualNetwork_basic(data) +func testAccDevTestVirtualNetwork_requiresImport(data acceptance.TestData) string { + template := testAccDevTestVirtualNetwork_basic(data) return fmt.Sprintf(` %s @@ -201,7 +201,7 @@ resource "azurerm_dev_test_virtual_network" "import" { `, template) } -func testAccAzureRMDevTestVirtualNetwork_subnets(data acceptance.TestData) string { +func testAccDevTestVirtualNetwork_subnets(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { features {} diff --git a/azurerm/internal/services/devtestlabs/tests/dev_test_windows_virtual_machine_resource_test.go b/azurerm/internal/services/devtestlabs/dev_test_windows_virtual_machine_resource_test.go similarity index 80% rename from azurerm/internal/services/devtestlabs/tests/dev_test_windows_virtual_machine_resource_test.go rename to azurerm/internal/services/devtestlabs/dev_test_windows_virtual_machine_resource_test.go index 050402418146..8156f3fc6b8f 100644 --- a/azurerm/internal/services/devtestlabs/tests/dev_test_windows_virtual_machine_resource_test.go +++ b/azurerm/internal/services/devtestlabs/dev_test_windows_virtual_machine_resource_test.go @@ -1,4 +1,4 @@ -package tests +package devtestlabs_test import ( "fmt" @@ -11,18 +11,18 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" ) -func TestAccAzureRMDevTestVirtualMachine_basic(t *testing.T) { +func TestAccDevTestVirtualMachine_basic(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_windows_virtual_machine", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestWindowsVirtualMachineDestroy, + CheckDestroy: testCheckDevTestWindowsVirtualMachineDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestWindowsVirtualMachine_basic(data), + Config: testAccDevTestWindowsVirtualMachine_basic(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestWindowsVirtualMachineExists(data.ResourceName), + testCheckDevTestWindowsVirtualMachineExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "gallery_image_reference.0.publisher", "MicrosoftWindowsServer"), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "0"), ), @@ -37,40 +37,40 @@ func TestAccAzureRMDevTestVirtualMachine_basic(t *testing.T) { }) } -func TestAccAzureRMDevTestVirtualMachine_requiresImport(t *testing.T) { +func TestAccDevTestVirtualMachine_requiresImport(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_windows_virtual_machine", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestWindowsVirtualMachineDestroy, + CheckDestroy: testCheckDevTestWindowsVirtualMachineDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestWindowsVirtualMachine_basic(data), + Config: testAccDevTestWindowsVirtualMachine_basic(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestWindowsVirtualMachineExists(data.ResourceName), + testCheckDevTestWindowsVirtualMachineExists(data.ResourceName), ), }, { - Config: testAccAzureRMDevTestWindowsVirtualMachine_requiresImport(data), + Config: testAccDevTestWindowsVirtualMachine_requiresImport(data), ExpectError: acceptance.RequiresImportError("azurerm_dev_test_windows_virtual_machine"), }, }, }) } -func TestAccAzureRMDevTestWindowsVirtualMachine_inboundNatRules(t *testing.T) { +func TestAccDevTestWindowsVirtualMachine_inboundNatRules(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_windows_virtual_machine", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestWindowsVirtualMachineDestroy, + CheckDestroy: testCheckDevTestWindowsVirtualMachineDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestWindowsVirtualMachine_inboundNatRules(data), + Config: testAccDevTestWindowsVirtualMachine_inboundNatRules(data), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestWindowsVirtualMachineExists(data.ResourceName), + testCheckDevTestWindowsVirtualMachineExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "disallow_public_ip_address", "true"), resource.TestCheckResourceAttr(data.ResourceName, "gallery_image_reference.0.publisher", "MicrosoftWindowsServer"), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "1"), @@ -88,27 +88,27 @@ func TestAccAzureRMDevTestWindowsVirtualMachine_inboundNatRules(t *testing.T) { }) } -func TestAccAzureRMDevTestWindowsVirtualMachine_updateStorage(t *testing.T) { +func TestAccDevTestWindowsVirtualMachine_updateStorage(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_dev_test_windows_virtual_machine", "test") resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { acceptance.PreCheck(t) }, Providers: acceptance.SupportedProviders, - CheckDestroy: testCheckAzureRMDevTestWindowsVirtualMachineDestroy, + CheckDestroy: testCheckDevTestWindowsVirtualMachineDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMDevTestWindowsVirtualMachine_storage(data, "Standard"), + Config: testAccDevTestWindowsVirtualMachine_storage(data, "Standard"), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestWindowsVirtualMachineExists(data.ResourceName), + testCheckDevTestWindowsVirtualMachineExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "gallery_image_reference.0.publisher", "MicrosoftWindowsServer"), resource.TestCheckResourceAttr(data.ResourceName, "storage_type", "Standard"), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "0"), ), }, { - Config: testAccAzureRMDevTestWindowsVirtualMachine_storage(data, "Premium"), + Config: testAccDevTestWindowsVirtualMachine_storage(data, "Premium"), Check: resource.ComposeTestCheckFunc( - testCheckAzureRMDevTestWindowsVirtualMachineExists(data.ResourceName), + testCheckDevTestWindowsVirtualMachineExists(data.ResourceName), resource.TestCheckResourceAttr(data.ResourceName, "gallery_image_reference.0.publisher", "MicrosoftWindowsServer"), resource.TestCheckResourceAttr(data.ResourceName, "storage_type", "Premium"), resource.TestCheckResourceAttr(data.ResourceName, "tags.%", "0"), @@ -118,7 +118,7 @@ func TestAccAzureRMDevTestWindowsVirtualMachine_updateStorage(t *testing.T) { }) } -func testCheckAzureRMDevTestWindowsVirtualMachineExists(resourceName string) resource.TestCheckFunc { +func testCheckDevTestWindowsVirtualMachineExists(resourceName string) resource.TestCheckFunc { return func(s *terraform.State) error { conn := acceptance.AzureProvider.Meta().(*clients.Client).DevTestLabs.VirtualMachinesClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext @@ -146,7 +146,7 @@ func testCheckAzureRMDevTestWindowsVirtualMachineExists(resourceName string) res } } -func testCheckAzureRMDevTestWindowsVirtualMachineDestroy(s *terraform.State) error { +func testCheckDevTestWindowsVirtualMachineDestroy(s *terraform.State) error { conn := acceptance.AzureProvider.Meta().(*clients.Client).DevTestLabs.VirtualMachinesClient ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext @@ -175,8 +175,8 @@ func testCheckAzureRMDevTestWindowsVirtualMachineDestroy(s *terraform.State) err return nil } -func testAccAzureRMDevTestWindowsVirtualMachine_basic(data acceptance.TestData) string { - template := testAccAzureRMDevTestWindowsVirtualMachine_template(data) +func testAccDevTestWindowsVirtualMachine_basic(data acceptance.TestData) string { + template := testAccDevTestWindowsVirtualMachine_template(data) return fmt.Sprintf(` %s @@ -202,8 +202,8 @@ resource "azurerm_dev_test_windows_virtual_machine" "test" { `, template, data.RandomInteger%1000000) } -func testAccAzureRMDevTestWindowsVirtualMachine_requiresImport(data acceptance.TestData) string { - template := testAccAzureRMDevTestWindowsVirtualMachine_basic(data) +func testAccDevTestWindowsVirtualMachine_requiresImport(data acceptance.TestData) string { + template := testAccDevTestWindowsVirtualMachine_basic(data) return fmt.Sprintf(` %s @@ -229,8 +229,8 @@ resource "azurerm_dev_test_windows_virtual_machine" "import" { `, template) } -func testAccAzureRMDevTestWindowsVirtualMachine_inboundNatRules(data acceptance.TestData) string { - template := testAccAzureRMDevTestWindowsVirtualMachine_template(data) +func testAccDevTestWindowsVirtualMachine_inboundNatRules(data acceptance.TestData) string { + template := testAccDevTestWindowsVirtualMachine_template(data) return fmt.Sprintf(` %s @@ -271,8 +271,8 @@ resource "azurerm_dev_test_windows_virtual_machine" "test" { `, template, data.RandomInteger%1000000) } -func testAccAzureRMDevTestWindowsVirtualMachine_storage(data acceptance.TestData, storageType string) string { - template := testAccAzureRMDevTestWindowsVirtualMachine_template(data) +func testAccDevTestWindowsVirtualMachine_storage(data acceptance.TestData, storageType string) string { + template := testAccDevTestWindowsVirtualMachine_template(data) return fmt.Sprintf(` %s @@ -298,7 +298,7 @@ resource "azurerm_dev_test_windows_virtual_machine" "test" { `, template, data.RandomInteger%1000000, storageType) } -func testAccAzureRMDevTestWindowsVirtualMachine_template(data acceptance.TestData) string { +func testAccDevTestWindowsVirtualMachine_template(data acceptance.TestData) string { return fmt.Sprintf(` provider "azurerm" { features {} diff --git a/azurerm/internal/services/devtestlabs/parse/global_schedule.go b/azurerm/internal/services/devtestlabs/parse/global_schedule.go new file mode 100644 index 000000000000..82c85fb2008e --- /dev/null +++ b/azurerm/internal/services/devtestlabs/parse/global_schedule.go @@ -0,0 +1,33 @@ +package parse + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" +) + +type GlobalScheduleId struct { + ResourceGroup string + Name string +} + +func GlobalScheduleID(input string) (*GlobalScheduleId, error) { + id, err := azure.ParseAzureResourceID(input) + if err != nil { + return nil, fmt.Errorf("[ERROR] Unable to parse Global Schedule ID %q: %+v", input, err) + } + + service := GlobalScheduleId{ + ResourceGroup: id.ResourceGroup, + } + + if service.Name, err = id.PopSegment("schedules"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &service, nil +} diff --git a/azurerm/internal/services/devtestlabs/parse/global_schedule_test.go b/azurerm/internal/services/devtestlabs/parse/global_schedule_test.go new file mode 100644 index 000000000000..f892b91ae5d8 --- /dev/null +++ b/azurerm/internal/services/devtestlabs/parse/global_schedule_test.go @@ -0,0 +1,61 @@ +package parse + +import "testing" + +func TestGlobalSchedule(t *testing.T) { + testData := []struct { + Name string + Input string + Expected *GlobalScheduleId + }{ + { + Name: "Empty", + Input: "", + Expected: nil, + }, + { + Name: "No DevTest Lab segment", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myGroup1/", + Expected: nil, + }, + { + Name: "No schedule name", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myGroup1/providers/Microsoft.DevTestLab/schedules/", + Expected: nil, + }, + { + Name: "Case incorrect in path element", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myGroup1/providers/Microsoft.DevTestLab/Schedules/schedule1", + Expected: nil, + }, + { + Name: "Valid", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myGroup1/providers/Microsoft.DevTestLab/schedules/schedule1", + Expected: &GlobalScheduleId{ + ResourceGroup: "myGroup1", + Name: "schedule1", + }, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Name) + + actual, err := GlobalScheduleID(v.Input) + if err != nil { + if v.Expected == nil { + continue + } + + t.Fatalf("Expected a value but got an error: %s", err) + } + + if actual.Name != v.Expected.Name { + t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name) + } + + if actual.ResourceGroup != v.Expected.ResourceGroup { + t.Fatalf("Expected %q but got %q for ResourceGroup", v.Expected.ResourceGroup, actual.ResourceGroup) + } + } +} diff --git a/azurerm/internal/services/devtestlabs/parse/global_schedule_virtual_machine.go b/azurerm/internal/services/devtestlabs/parse/global_schedule_virtual_machine.go new file mode 100644 index 000000000000..b77a4b2930dc --- /dev/null +++ b/azurerm/internal/services/devtestlabs/parse/global_schedule_virtual_machine.go @@ -0,0 +1,33 @@ +package parse + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" +) + +type GlobalScheduleVirtualMachineId struct { + ResourceGroup string + Name string +} + +func GlobalScheduleVirtualMachineID(input string) (*GlobalScheduleVirtualMachineId, error) { + id, err := azure.ParseAzureResourceID(input) + if err != nil { + return nil, fmt.Errorf("[ERROR] Unable to parse Virtual Machine ID %q: %+v", input, err) + } + + service := GlobalScheduleVirtualMachineId{ + ResourceGroup: id.ResourceGroup, + } + + if service.Name, err = id.PopSegment("virtualMachines"); err != nil { + return nil, err + } + + if err := id.ValidateNoEmptySegments(input); err != nil { + return nil, err + } + + return &service, nil +} diff --git a/azurerm/internal/services/devtestlabs/parse/global_schedule_virtual_machine_test.go b/azurerm/internal/services/devtestlabs/parse/global_schedule_virtual_machine_test.go new file mode 100644 index 000000000000..6d0ef73f4c09 --- /dev/null +++ b/azurerm/internal/services/devtestlabs/parse/global_schedule_virtual_machine_test.go @@ -0,0 +1,61 @@ +package parse + +import "testing" + +func TestGlobalScheduleVirtualMachine(t *testing.T) { + testData := []struct { + Name string + Input string + Expected *GlobalScheduleVirtualMachineId + }{ + { + Name: "Empty", + Input: "", + Expected: nil, + }, + { + Name: "No virtual machine segment", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myGroup1/", + Expected: nil, + }, + { + Name: "No virtual machine name", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myGroup1/providers/microsoft.compute/virtualMachines/", + Expected: nil, + }, + { + Name: "Case incorrect in path element", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myGroup1/providers/microsoft.compute/VirtualMachines/machine1", + Expected: nil, + }, + { + Name: "Valid", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myGroup1/providers/microsoft.compute/virtualMachines/machine1", + Expected: &GlobalScheduleVirtualMachineId{ + ResourceGroup: "myGroup1", + Name: "machine1", + }, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q", v.Name) + + actual, err := GlobalScheduleVirtualMachineID(v.Input) + if err != nil { + if v.Expected == nil { + continue + } + + t.Fatalf("Expected a value but got an error: %s", err) + } + + if actual.Name != v.Expected.Name { + t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name) + } + + if actual.ResourceGroup != v.Expected.ResourceGroup { + t.Fatalf("Expected %q but got %q for ResourceGroup", v.Expected.ResourceGroup, actual.ResourceGroup) + } + } +} diff --git a/azurerm/internal/services/devtestlabs/registration.go b/azurerm/internal/services/devtestlabs/registration.go index 607fa7bc4d9f..b6a1865944eb 100644 --- a/azurerm/internal/services/devtestlabs/registration.go +++ b/azurerm/internal/services/devtestlabs/registration.go @@ -28,10 +28,11 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource { // SupportedResources returns the supported Resources supported by this Service func (r Registration) SupportedResources() map[string]*schema.Resource { return map[string]*schema.Resource{ - "azurerm_dev_test_lab": resourceArmDevTestLab(), - "azurerm_dev_test_schedule": resourceArmDevTestLabSchedules(), - "azurerm_dev_test_linux_virtual_machine": resourceArmDevTestLinuxVirtualMachine(), - "azurerm_dev_test_policy": resourceArmDevTestPolicy(), - "azurerm_dev_test_virtual_network": resourceArmDevTestVirtualNetwork(), - "azurerm_dev_test_windows_virtual_machine": resourceArmDevTestWindowsVirtualMachine()} + "azurerm_dev_test_global_vm_shutdown_schedule": resourceArmDevTestLabGlobalVMShutdownSchedule(), + "azurerm_dev_test_lab": resourceArmDevTestLab(), + "azurerm_dev_test_schedule": resourceArmDevTestLabSchedules(), + "azurerm_dev_test_linux_virtual_machine": resourceArmDevTestLinuxVirtualMachine(), + "azurerm_dev_test_policy": resourceArmDevTestPolicy(), + "azurerm_dev_test_virtual_network": resourceArmDevTestVirtualNetwork(), + "azurerm_dev_test_windows_virtual_machine": resourceArmDevTestWindowsVirtualMachine()} } diff --git a/azurerm/internal/services/devtestlabs/validate/global_schedule.go b/azurerm/internal/services/devtestlabs/validate/global_schedule.go new file mode 100644 index 000000000000..06299e03ebde --- /dev/null +++ b/azurerm/internal/services/devtestlabs/validate/global_schedule.go @@ -0,0 +1,22 @@ +package validate + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/devtestlabs/parse" +) + +func GlobalScheduleID(i interface{}, k string) (warnings []string, errors []error) { + v, ok := i.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %q to be string", k)) + return + } + + if _, err := parse.GlobalScheduleID(v); err != nil { + errors = append(errors, fmt.Errorf("Can not parse %q as a resource id: %v", k, err)) + return + } + + return warnings, errors +} diff --git a/azurerm/internal/services/devtestlabs/validate/global_schedule_test.go b/azurerm/internal/services/devtestlabs/validate/global_schedule_test.go new file mode 100644 index 000000000000..17dde18cd8c0 --- /dev/null +++ b/azurerm/internal/services/devtestlabs/validate/global_schedule_test.go @@ -0,0 +1,40 @@ +package validate + +import "testing" + +func TestGlobalScheduleID(t *testing.T) { + cases := []struct { + ID string + Valid bool + }{ + { + ID: "", + Valid: false, + }, + { + ID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/", + Valid: false, + }, + { + ID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/Microsoft.DevTestLab/schedules/", + Valid: false, + }, + { + ID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myGroup1/providers/Microsoft.DevTestLab/Schedules/schedule1", + Valid: false, + }, + { + ID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myGroup1/providers/Microsoft.DevTestLab/schedules/schedule1", + Valid: true, + }, + } + for _, tc := range cases { + t.Logf("[DEBUG] Testing Value %s", tc.ID) + _, errors := GlobalScheduleID(tc.ID, "test") + valid := len(errors) == 0 + + if tc.Valid != valid { + t.Fatalf("Expected %t but got %t", tc.Valid, valid) + } + } +} diff --git a/azurerm/internal/services/devtestlabs/validate/global_schedule_virtual_machine.go b/azurerm/internal/services/devtestlabs/validate/global_schedule_virtual_machine.go new file mode 100644 index 000000000000..a4bc05537244 --- /dev/null +++ b/azurerm/internal/services/devtestlabs/validate/global_schedule_virtual_machine.go @@ -0,0 +1,22 @@ +package validate + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/devtestlabs/parse" +) + +func GlobalScheduleVirtualMachineID(i interface{}, k string) (warnings []string, errors []error) { + v, ok := i.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %q to be string", k)) + return + } + + if _, err := parse.GlobalScheduleVirtualMachineID(v); err != nil { + errors = append(errors, fmt.Errorf("Can not parse %q as a resource id: %v", k, err)) + return + } + + return warnings, errors +} diff --git a/azurerm/internal/services/devtestlabs/validate/global_schedule_virtual_machine_test.go b/azurerm/internal/services/devtestlabs/validate/global_schedule_virtual_machine_test.go new file mode 100644 index 000000000000..347317fad2de --- /dev/null +++ b/azurerm/internal/services/devtestlabs/validate/global_schedule_virtual_machine_test.go @@ -0,0 +1,40 @@ +package validate + +import "testing" + +func TestGlobalScheduleVirtualMachineID(t *testing.T) { + cases := []struct { + ID string + Valid bool + }{ + { + ID: "", + Valid: false, + }, + { + ID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/", + Valid: false, + }, + { + ID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/mygroup1/providers/microsoft.compute/virtualMachines/", + Valid: false, + }, + { + ID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myGroup1/providers/microsoft.compute/VirtualMachines/machine1", + Valid: false, + }, + { + ID: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myGroup1/providers/microsoft.compute/virtualMachines/machine1", + Valid: true, + }, + } + for _, tc := range cases { + t.Logf("[DEBUG] Testing Value %s", tc.ID) + _, errors := GlobalScheduleVirtualMachineID(tc.ID, "test") + valid := len(errors) == 0 + + if tc.Valid != valid { + t.Fatalf("Expected %t but got %t", tc.Valid, valid) + } + } +} diff --git a/website/azurerm.erb b/website/azurerm.erb index b8d309844bd7..4687af9a6655 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -1456,6 +1456,10 @@
  • Dev Test Resources