From 1421d4ce18f3fd871d61034aa702e75e60181af9 Mon Sep 17 00:00:00 2001 From: Paul Stack Date: Tue, 2 Feb 2016 19:48:09 -0500 Subject: [PATCH 1/3] provider/azurerm: Add `azurerm_dns_zone` resource This resource is the first which makes use of the new Riviera library (at https://github.com/jen20/riviera), so there is some additional set up work to add the provider to the client which gets passed among resources. --- builtin/providers/azurerm/config.go | 15 +++ builtin/providers/azurerm/provider.go | 1 + .../azurerm/resource_arm_dns_zone.go | 122 ++++++++++++++++++ .../azurerm/resource_arm_dns_zone_test.go | 89 +++++++++++++ .../azurerm/r/dns_zone.html.markdown | 41 ++++++ website/source/layouts/azurerm.erb | 11 ++ 6 files changed, 279 insertions(+) create mode 100644 builtin/providers/azurerm/resource_arm_dns_zone.go create mode 100644 builtin/providers/azurerm/resource_arm_dns_zone_test.go create mode 100644 website/source/docs/providers/azurerm/r/dns_zone.html.markdown diff --git a/builtin/providers/azurerm/config.go b/builtin/providers/azurerm/config.go index cbc3784b2..bc795ce2a 100644 --- a/builtin/providers/azurerm/config.go +++ b/builtin/providers/azurerm/config.go @@ -16,11 +16,14 @@ import ( "github.com/Azure/azure-sdk-for-go/arm/storage" mainStorage "github.com/Azure/azure-sdk-for-go/storage" "github.com/hashicorp/terraform/terraform" + riviera "github.com/jen20/riviera/azure" ) // ArmClient contains the handles to all the specific Azure Resource Manager // resource classes' respective clients. type ArmClient struct { + rivieraClient *riviera.Client + availSetClient compute.AvailabilitySetsClient usageOpsClient compute.UsageOperationsClient vmExtensionImageClient compute.VirtualMachineExtensionImagesClient @@ -110,6 +113,18 @@ func (c *Config) getArmClient() (*ArmClient, error) { // client declarations: client := ArmClient{} + rivieraClient, err := riviera.NewClient(&riviera.AzureResourceManagerCredentials{ + ClientID: c.ClientID, + ClientSecret: c.ClientSecret, + TenantID: c.TenantID, + SubscriptionID: c.SubscriptionID, + }) + if err != nil { + return nil, fmt.Errorf("Error creating Riviera client: %s", err) + } + + client.rivieraClient = rivieraClient + // NOTE: these declarations should be left separate for clarity should the // clients be wished to be configured with custom Responders/PollingModess etc... asc := compute.NewAvailabilitySetsClient(c.SubscriptionID) diff --git a/builtin/providers/azurerm/provider.go b/builtin/providers/azurerm/provider.go index 0f8733ec1..78850dfc5 100644 --- a/builtin/providers/azurerm/provider.go +++ b/builtin/providers/azurerm/provider.go @@ -60,6 +60,7 @@ func Provider() terraform.ResourceProvider { "azurerm_storage_container": resourceArmStorageContainer(), "azurerm_storage_blob": resourceArmStorageBlob(), "azurerm_storage_queue": resourceArmStorageQueue(), + "azurerm_dns_zone": resourceArmDnsZone(), }, ConfigureFunc: providerConfigure, } diff --git a/builtin/providers/azurerm/resource_arm_dns_zone.go b/builtin/providers/azurerm/resource_arm_dns_zone.go new file mode 100644 index 000000000..e12592bdb --- /dev/null +++ b/builtin/providers/azurerm/resource_arm_dns_zone.go @@ -0,0 +1,122 @@ +package azurerm + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/jen20/riviera/dns" +) + +func resourceArmDnsZone() *schema.Resource { + return &schema.Resource{ + Create: resourceArmDnsZoneCreate, + Read: resourceArmDnsZoneRead, + Update: resourceArmDnsZoneCreate, + Delete: resourceArmDnsZoneDelete, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "resource_group_name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "number_of_record_sets": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "max_number_of_record_sets": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + }, + } +} + +func resourceArmDnsZoneCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient) + rivieraClient := client.rivieraClient + + createRequest := rivieraClient.NewRequest() + createRequest.Command = &dns.CreateDNSZone{ + Name: d.Get("name").(string), + Location: "global", + ResourceGroupName: d.Get("resource_group_name").(string), + } + + createResponse, err := createRequest.Execute() + if err != nil { + return fmt.Errorf("Error creating DNS Zone: %s", err) + } else if !createResponse.IsSuccessful() { + return fmt.Errorf("Error creating DNS Zone: %s", createResponse.Error) + } + + readRequest := rivieraClient.NewRequest() + readRequest.Command = &dns.GetDNSZone{ + Name: d.Get("name").(string), + ResourceGroupName: d.Get("resource_group_name").(string), + } + + readResponse, err := readRequest.Execute() + if err != nil { + return fmt.Errorf("Error reading DNS Zone: %s", err) + } else if !readResponse.IsSuccessful() { + return fmt.Errorf("Error reading DNS Zone: %s", readResponse.Error) + } + + resp := readResponse.Parsed.(*dns.GetDNSZoneResponse) + d.SetId(*resp.ID) + + return resourceArmDnsZoneRead(d, meta) +} + +func resourceArmDnsZoneRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient) + rivieraClient := client.rivieraClient + + readRequest := rivieraClient.NewRequestForURI(d.Id()) + readRequest.Command = &dns.GetDNSZone{} + + readResponse, err := readRequest.Execute() + if err != nil { + return fmt.Errorf("Error reading DNS Zone: %s", err) + } else if !readResponse.IsSuccessful() { + log.Printf("[INFO] Error reading DNS Zone %q - removing from state", d.Id()) + d.SetId("") + return fmt.Errorf("Error reading DNS Zone: %s", readResponse.Error) + } + + resp := readResponse.Parsed.(*dns.GetDNSZoneResponse) + + d.Set("number_of_record_sets", resp.NumberOfRecordSets) + d.Set("max_number_of_record_sets", resp.MaxNumberOfRecordSets) + + return nil +} + +func resourceArmDnsZoneDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient) + rivieraClient := client.rivieraClient + + deleteRequest := rivieraClient.NewRequestForURI(d.Id()) + deleteRequest.Command = &dns.DeleteDNSZone{} + + deleteResponse, err := deleteRequest.Execute() + if err != nil { + return fmt.Errorf("Error deleting DNS Zone: %s", err) + } else if !deleteResponse.IsSuccessful() { + return fmt.Errorf("Error deleting DNS Zone: %s", deleteResponse.Error) + } + + return nil +} diff --git a/builtin/providers/azurerm/resource_arm_dns_zone_test.go b/builtin/providers/azurerm/resource_arm_dns_zone_test.go new file mode 100644 index 000000000..48f0c2e93 --- /dev/null +++ b/builtin/providers/azurerm/resource_arm_dns_zone_test.go @@ -0,0 +1,89 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/jen20/riviera/dns" +) + +func TestAccAzureRMDnsZone_basic(t *testing.T) { + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMDnsZone_basic, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMDnsZoneDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMDnsZoneExists("azurerm_dns_zone.test"), + ), + }, + }, + }) +} + +func testCheckAzureRMDnsZoneExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + conn := testAccProvider.Meta().(*ArmClient).rivieraClient + + readRequest := conn.NewRequestForURI(rs.Primary.ID) + readRequest.Command = &dns.GetDNSZone{} + + readResponse, err := readRequest.Execute() + if err != nil { + return fmt.Errorf("Bad: GetDNSZone: %s", err) + } else if !readResponse.IsSuccessful() { + return fmt.Errorf("Bad: GetDNSZone: %s", readResponse.Error) + } + + return nil + } +} + +func testCheckAzureRMDnsZoneDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).rivieraClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_dns_zone" { + continue + } + + readRequest := conn.NewRequestForURI(rs.Primary.ID) + readRequest.Command = &dns.GetDNSZone{} + + readResponse, err := readRequest.Execute() + if err != nil { + return fmt.Errorf("Bad: GetDNSZone: %s", err) + } + + if readResponse.IsSuccessful() { + return fmt.Errorf("Bad: DNS zone still exists: %s", readResponse.Error) + } + } + + return nil +} + +var testAccAzureRMDnsZone_basic = ` +resource "azurerm_resource_group" "test" { + name = "acctest_rg_%d" + location = "West US" +} +resource "azurerm_dns_zone" "test" { + name = "acctestzone%d.com" + resource_group_name = "${azurerm_resource_group.test.name}" +} +` diff --git a/website/source/docs/providers/azurerm/r/dns_zone.html.markdown b/website/source/docs/providers/azurerm/r/dns_zone.html.markdown new file mode 100644 index 000000000..81997faaf --- /dev/null +++ b/website/source/docs/providers/azurerm/r/dns_zone.html.markdown @@ -0,0 +1,41 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_dns_zone" +sidebar_current: "docs-azurerm-resource-dns-zone" +description: |- + Create a DNS Zone. +--- + +# azurerm\_dns\_zone + +Enables you to manage DNS zones within Azure DNS. These zones are hosted on Azure's name servers to which you can delegate the zone from the parent domain. + +## Example Usage + +``` +resource "azurerm_resource_group" "test" { + name = "acceptanceTestResourceGroup1" + location = "West US" +} +resource "azurerm_dns_zone" "test" { + name = "mydomain.com" + resource_group_name = "${azurerm_resource_group.test.name}" +} +``` +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the DNS Zone. Must be a valid domain name. + +* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The DNS Zone ID. +* `max_number_of_record_sets` - (Optional) Maximum number of Records in the zone. Defaults to `1000`. +* `number_of_record_sets` - (Optional) The number of records already in the zone. diff --git a/website/source/layouts/azurerm.erb b/website/source/layouts/azurerm.erb index 73e42e537..d34099280 100644 --- a/website/source/layouts/azurerm.erb +++ b/website/source/layouts/azurerm.erb @@ -30,6 +30,17 @@ + > + DNS Resources + + + > Network Resources