From 9b5c99ba2862d64b83580298e3b657d390376c06 Mon Sep 17 00:00:00 2001 From: aznashwan Date: Fri, 19 Jun 2015 19:52:36 +0300 Subject: [PATCH] Added affinity group resource. --- builtin/providers/azure/config.go | 5 + builtin/providers/azure/provider.go | 1 + .../azure/resource_azure_affinity_group.go | 168 ++++++++++++++++++ .../resource_azure_affinity_group_test.go | 121 +++++++++++++ .../azure/r/affinity_group.html.markdown | 42 +++++ website/source/layouts/azure.erb | 4 + 6 files changed, 341 insertions(+) create mode 100644 builtin/providers/azure/resource_azure_affinity_group.go create mode 100644 builtin/providers/azure/resource_azure_affinity_group_test.go create mode 100644 website/source/docs/providers/azure/r/affinity_group.html.markdown diff --git a/builtin/providers/azure/config.go b/builtin/providers/azure/config.go index 8e0e378df..fff31853d 100644 --- a/builtin/providers/azure/config.go +++ b/builtin/providers/azure/config.go @@ -6,6 +6,7 @@ import ( "sync" "github.com/Azure/azure-sdk-for-go/management" + "github.com/Azure/azure-sdk-for-go/management/affinitygroup" "github.com/Azure/azure-sdk-for-go/management/hostedservice" "github.com/Azure/azure-sdk-for-go/management/networksecuritygroup" "github.com/Azure/azure-sdk-for-go/management/osimage" @@ -31,6 +32,8 @@ type Config struct { type Client struct { mgmtClient management.Client + affinityGroupClient affinitygroup.AffinityGroupClient + hostedServiceClient hostedservice.HostedServiceClient secGroupClient networksecuritygroup.SecurityGroupClient @@ -107,6 +110,7 @@ func (c *Config) NewClientFromSettingsFile() (*Client, error) { return &Client{ mgmtClient: mc, + affinityGroupClient: affinitygroup.NewClient(mc), hostedServiceClient: hostedservice.NewClient(mc), secGroupClient: networksecuritygroup.NewClient(mc), osImageClient: osimage.NewClient(mc), @@ -130,6 +134,7 @@ func (c *Config) NewClient() (*Client, error) { return &Client{ mgmtClient: mc, + affinityGroupClient: affinitygroup.NewClient(mc), hostedServiceClient: hostedservice.NewClient(mc), secGroupClient: networksecuritygroup.NewClient(mc), osImageClient: osimage.NewClient(mc), diff --git a/builtin/providers/azure/provider.go b/builtin/providers/azure/provider.go index a6be93f5c..365488415 100644 --- a/builtin/providers/azure/provider.go +++ b/builtin/providers/azure/provider.go @@ -33,6 +33,7 @@ func Provider() terraform.ResourceProvider { ResourcesMap: map[string]*schema.Resource{ "azure_instance": resourceAzureInstance(), + "azure_affinity_group": resourceAzureAffinityGroup(), "azure_data_disk": resourceAzureDataDisk(), "azure_sql_database_server": resourceAzureSqlDatabaseServer(), "azure_sql_database_service": resourceAzureSqlDatabaseService(), diff --git a/builtin/providers/azure/resource_azure_affinity_group.go b/builtin/providers/azure/resource_azure_affinity_group.go new file mode 100644 index 000000000..5dd5bced4 --- /dev/null +++ b/builtin/providers/azure/resource_azure_affinity_group.go @@ -0,0 +1,168 @@ +package azure + +import ( + "fmt" + "log" + + "github.com/Azure/azure-sdk-for-go/management" + "github.com/Azure/azure-sdk-for-go/management/affinitygroup" + "github.com/hashicorp/terraform/helper/schema" +) + +// resourceAzureAffinityGroup returns the *schema.Resource associated to a +// resource affinity group on Azure. +func resourceAzureAffinityGroup() *schema.Resource { + return &schema.Resource{ + Create: resourceAzureAffinityGroupCreate, + Read: resourceAzureAffinityGroupRead, + Update: resourceAzureAffinityGroupUpdate, + Exists: resourceAzureAffinityGroupExists, + Delete: resourceAzureAffinityGroupDelete, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "location": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "label": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + }, + } +} + +// resourceAzureAffinityGroupCreate does all the necessary API calls to +// create an affinity group on Azure. +func resourceAzureAffinityGroupCreate(d *schema.ResourceData, meta interface{}) error { + affinityGroupClient := meta.(*Client).affinityGroupClient + + log.Println("[INFO] Begun creating Azure Affinity Group creation request.") + name := d.Get("name").(string) + params := affinitygroup.CreateAffinityGroupParams{ + Name: name, + Label: d.Get("label").(string), + Location: d.Get("location").(string), + } + + if desc, ok := d.GetOk("description"); ok { + params.Description = desc.(string) + } + + log.Println("[INFO] Sending Affinity Group creation request to Azure.") + err := affinityGroupClient.CreateAffinityGroup(params) + if err != nil { + return fmt.Errorf("Error issuing Azure Affinity Group creation: %s", err) + } + + d.SetId(name) + return nil +} + +// resourceAzureAffinityGroupRead does all the necessary API calls to +// read the state of the affinity group off Azure. +func resourceAzureAffinityGroupRead(d *schema.ResourceData, meta interface{}) error { + affinityGroupClient := meta.(*Client).affinityGroupClient + + log.Println("[INFO] Issuing Azure Affinity Group list request.") + affinityGroups, err := affinityGroupClient.ListAffinityGroups() + if err != nil { + return fmt.Errorf("Error obtaining Affinity Group list off Azure: %s", err) + } + + var found bool + name := d.Get("name").(string) + for _, group := range affinityGroups.AffinityGroups { + if group.Name == name { + found = true + d.Set("location", group.Location) + d.Set("label", group.Label) + d.Set("description", group.Description) + break + } + } + + if !found { + // it means the affinity group has been deleted in the meantime, so we + // must stop tracking it: + d.SetId("") + } + + return nil +} + +// resourceAzureAffinityGroupUpdate does all the necessary API calls to +// update the state of the affinity group on Azure. +func resourceAzureAffinityGroupUpdate(d *schema.ResourceData, meta interface{}) error { + affinityGroupClient := meta.(*Client).affinityGroupClient + + name := d.Get("name").(string) + clabel := d.HasChange("label") + cdesc := d.HasChange("description") + if clabel || cdesc { + log.Println("[INFO] Beginning Affinity Group update process.") + params := affinitygroup.UpdateAffinityGroupParams{} + + if clabel { + params.Label = d.Get("label").(string) + } + if cdesc { + params.Description = d.Get("description").(string) + } + + log.Println("[INFO] Sending Affinity Group update request to Azure.") + err := affinityGroupClient.UpdateAffinityGroup(name, params) + if err != nil { + return fmt.Errorf("Error updating Azure Affinity Group parameters: %s", err) + } + } + + return nil +} + +// resourceAzureAffinityGroupExists does all the necessary API calls to +// check for the existence of the affinity group on Azure. +func resourceAzureAffinityGroupExists(d *schema.ResourceData, meta interface{}) (bool, error) { + affinityGroupClient := meta.(*Client).affinityGroupClient + + log.Println("[INFO] Issuing Azure Affinity Group get request.") + name := d.Get("name").(string) + _, err := affinityGroupClient.GetAffinityGroup(name) + if err != nil { + if management.IsResourceNotFoundError(err) { + // it means that the affinity group has been deleted in the + // meantime, so we must untrack it from the schema: + d.SetId("") + return false, nil + } else { + return false, fmt.Errorf("Error getting Affinity Group off Azure: %s", err) + } + } + + return true, nil +} + +// resourceAzureAffinityGroupDelete does all the necessary API calls to +// delete the affinity group off Azure. +func resourceAzureAffinityGroupDelete(d *schema.ResourceData, meta interface{}) error { + affinityGroupClient := meta.(*Client).affinityGroupClient + + log.Println("[INFO] Sending Affinity Group deletion request to Azure.") + name := d.Get("name").(string) + err := affinityGroupClient.DeleteAffinityGroup(name) + if err != nil { + return fmt.Errorf("Error deleting Azure Affinity Group: %s", err) + } + + return nil +} diff --git a/builtin/providers/azure/resource_azure_affinity_group_test.go b/builtin/providers/azure/resource_azure_affinity_group_test.go new file mode 100644 index 000000000..1cc5211c4 --- /dev/null +++ b/builtin/providers/azure/resource_azure_affinity_group_test.go @@ -0,0 +1,121 @@ +package azure + +import ( + "fmt" + "testing" + + "github.com/Azure/azure-sdk-for-go/management" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAzureAffinityGroupBasic(t *testing.T) { + name := "azure_affinity_group.foo" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAzureAffinityGroupDestroyed, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAzureAffinityGroupConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckAzureAffinityGroupExists(name), + resource.TestCheckResourceAttr(name, "name", "terraform-testing-group"), + resource.TestCheckResourceAttr(name, "location", "West US"), + resource.TestCheckResourceAttr(name, "label", "A nice label."), + resource.TestCheckResourceAttr(name, "description", "A nice description."), + ), + }, + }, + }) +} + +func TestAccAzureAffinityGroupUpdate(t *testing.T) { + name := "azure_affinity_group.foo" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAzureAffinityGroupDestroyed, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccAzureAffinityGroupConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckAzureAffinityGroupExists(name), + resource.TestCheckResourceAttr(name, "name", "terraform-testing-group"), + resource.TestCheckResourceAttr(name, "location", "West US"), + resource.TestCheckResourceAttr(name, "label", "A nice label."), + resource.TestCheckResourceAttr(name, "description", "A nice description."), + ), + }, + resource.TestStep{ + Config: testAccAzureAffinityGroupUpdateConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckAzureAffinityGroupExists(name), + resource.TestCheckResourceAttr(name, "name", "terraform-testing-group"), + resource.TestCheckResourceAttr(name, "location", "West US"), + resource.TestCheckResourceAttr(name, "label", "An even nicer label."), + resource.TestCheckResourceAttr(name, "description", "An even nicer description."), + ), + }, + }, + }) +} + +func testAccCheckAzureAffinityGroupExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + resource, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Affinity Group resource %q doesn't exist.", name) + } + + if resource.Primary.ID == "" { + return fmt.Errorf("Affinity Group resource %q ID not set.", name) + } + + affinityGroupClient := testAccProvider.Meta().(*Client).affinityGroupClient + _, err := affinityGroupClient.GetAffinityGroup(resource.Primary.ID) + return err + } +} + +func testAccCheckAzureAffinityGroupDestroyed(s *terraform.State) error { + var err error + affinityGroupClient := testAccProvider.Meta().(*Client).affinityGroupClient + + for _, resource := range s.RootModule().Resources { + if resource.Type != "azure_affinity_group" { + continue + } + + if resource.Primary.ID == "" { + return fmt.Errorf("Affinity Group resource ID not set.") + } + + _, err = affinityGroupClient.GetAffinityGroup(resource.Primary.ID) + if !management.IsResourceNotFoundError(err) { + return err + } + } + + return nil +} + +const testAccAzureAffinityGroupConfig = ` +resource "azure_affinity_group" "foo" { + name = "terraform-testing-group" + location = "West US" + label = "A nice label." + description = "A nice description." +} +` + +const testAccAzureAffinityGroupUpdateConfig = ` +resource "azure_affinity_group" "foo" { + name = "terraform-testing-group" + location = "West US" + label = "An even nicer label." + description = "An even nicer description." +} +` diff --git a/website/source/docs/providers/azure/r/affinity_group.html.markdown b/website/source/docs/providers/azure/r/affinity_group.html.markdown new file mode 100644 index 000000000..906f73070 --- /dev/null +++ b/website/source/docs/providers/azure/r/affinity_group.html.markdown @@ -0,0 +1,42 @@ +--- +layout: "azure" +page_title: "Azure: azure_affinity_group" +sidebar_current: "docs-azure-affinity-group" +description: |- + Creates a new affinity group on Azure. +--- + +# azure\_affinity\_group + +Creates a new affinity group on Azure. + +## Example Usage + +``` +resource "azure_affinity_group" "terraform-main-group" { + name = "terraform-group" + location = "North Europe" + label = "tf-group-01" + description = "Affinity group created by Terraform." +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the affinity group. Must be unique on your + Azure subscription. + +* `location` - (Required) The location where the affinity group should be created. + For a list of all Azure locations, please consult [this link](http://azure.microsoft.com/en-us/regions/). + +* `label` - (Required) A label to be used for tracking purposes. + +* `description` - (Optional) A description for the affinity group. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The affinity group ID. Coincides with the given `name`. diff --git a/website/source/layouts/azure.erb b/website/source/layouts/azure.erb index 4fc096f0e..9525c45c9 100644 --- a/website/source/layouts/azure.erb +++ b/website/source/layouts/azure.erb @@ -13,6 +13,10 @@ > Resources