From 475fd4decbc873d5abfca7966fc4dd58f43fb83d Mon Sep 17 00:00:00 2001 From: Peter McAtominey Date: Mon, 3 Oct 2016 11:22:18 +0100 Subject: [PATCH] provider/azurerm: add servicebus_subscription resource TF_ACC=1 go test ./builtin/providers/azurerm -v -run TestAccAzureRMServiceBusSubscription -timeout 120m === RUN TestAccAzureRMServiceBusSubscription_importBasic --- PASS: TestAccAzureRMServiceBusSubscription_importBasic (339.00s) === RUN TestAccAzureRMServiceBusSubscription_basic --- PASS: TestAccAzureRMServiceBusSubscription_basic (328.47s) === RUN TestAccAzureRMServiceBusSubscription_update --- PASS: TestAccAzureRMServiceBusSubscription_update (368.95s) === RUN TestAccAzureRMServiceBusSubscription_updateRequiresSession --- PASS: TestAccAzureRMServiceBusSubscription_updateRequiresSession (348.47s) PASS ok github.com/hashicorp/terraform/builtin/providers/azurerm 1384.966s --- builtin/providers/azurerm/config.go | 11 +- ...import_arm_servicebus_subscription_test.go | 33 +++ builtin/providers/azurerm/provider.go | 1 + .../resource_arm_servicebus_subscription.go | 212 ++++++++++++++++ ...source_arm_servicebus_subscription_test.go | 236 ++++++++++++++++++ .../r/servicebus_subscription.html.markdown | 107 ++++++++ website/source/layouts/azurerm.erb | 4 + 7 files changed, 602 insertions(+), 2 deletions(-) create mode 100644 builtin/providers/azurerm/import_arm_servicebus_subscription_test.go create mode 100644 builtin/providers/azurerm/resource_arm_servicebus_subscription.go create mode 100644 builtin/providers/azurerm/resource_arm_servicebus_subscription_test.go create mode 100644 website/source/docs/providers/azurerm/r/servicebus_subscription.html.markdown diff --git a/builtin/providers/azurerm/config.go b/builtin/providers/azurerm/config.go index 0fccb590b..e068f2738 100644 --- a/builtin/providers/azurerm/config.go +++ b/builtin/providers/azurerm/config.go @@ -68,8 +68,9 @@ type ArmClient struct { trafficManagerProfilesClient trafficmanager.ProfilesClient trafficManagerEndpointsClient trafficmanager.EndpointsClient - serviceBusNamespacesClient servicebus.NamespacesClient - serviceBusTopicsClient servicebus.TopicsClient + serviceBusNamespacesClient servicebus.NamespacesClient + serviceBusTopicsClient servicebus.TopicsClient + serviceBusSubscriptionsClient servicebus.SubscriptionsClient } func withRequestLogging() autorest.SendDecorator { @@ -359,6 +360,12 @@ func (c *Config) getArmClient() (*ArmClient, error) { sbtc.Sender = autorest.CreateSender(withRequestLogging()) client.serviceBusTopicsClient = sbtc + sbsc := servicebus.NewSubscriptionsClient(c.SubscriptionID) + setUserAgent(&sbsc.Client) + sbsc.Authorizer = spt + sbsc.Sender = autorest.CreateSender(withRequestLogging()) + client.serviceBusSubscriptionsClient = sbsc + return &client, nil } diff --git a/builtin/providers/azurerm/import_arm_servicebus_subscription_test.go b/builtin/providers/azurerm/import_arm_servicebus_subscription_test.go new file mode 100644 index 000000000..7b2ae9516 --- /dev/null +++ b/builtin/providers/azurerm/import_arm_servicebus_subscription_test.go @@ -0,0 +1,33 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccAzureRMServiceBusSubscription_importBasic(t *testing.T) { + resourceName := "azurerm_servicebus_subscription.test" + + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMServiceBusSubscription_basic, ri, ri, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMServiceBusSubscriptionDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: config, + }, + + resource.TestStep{ + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/builtin/providers/azurerm/provider.go b/builtin/providers/azurerm/provider.go index 4a3b3ac35..6558a721d 100644 --- a/builtin/providers/azurerm/provider.go +++ b/builtin/providers/azurerm/provider.go @@ -57,6 +57,7 @@ func Provider() terraform.ResourceProvider { "azurerm_route": resourceArmRoute(), "azurerm_route_table": resourceArmRouteTable(), "azurerm_servicebus_namespace": resourceArmServiceBusNamespace(), + "azurerm_servicebus_subscription": resourceArmServiceBusSubscription(), "azurerm_servicebus_topic": resourceArmServiceBusTopic(), "azurerm_storage_account": resourceArmStorageAccount(), "azurerm_storage_blob": resourceArmStorageBlob(), diff --git a/builtin/providers/azurerm/resource_arm_servicebus_subscription.go b/builtin/providers/azurerm/resource_arm_servicebus_subscription.go new file mode 100644 index 000000000..9c980e02a --- /dev/null +++ b/builtin/providers/azurerm/resource_arm_servicebus_subscription.go @@ -0,0 +1,212 @@ +package azurerm + +import ( + "fmt" + "log" + "net/http" + + "github.com/Azure/azure-sdk-for-go/arm/servicebus" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourceArmServiceBusSubscription() *schema.Resource { + return &schema.Resource{ + Create: resourceArmServiceBusSubscriptionCreate, + Read: resourceArmServiceBusSubscriptionRead, + Update: resourceArmServiceBusSubscriptionCreate, + Delete: resourceArmServiceBusSubscriptionDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "namespace_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "topic_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "location": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + StateFunc: azureRMNormalizeLocation, + }, + + "resource_group_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "auto_delete_on_idle": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "default_message_ttl": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "lock_duration": { + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + + "dead_lettering_on_filter_evaluation_exceptions": { + Type: schema.TypeBool, + Optional: true, + }, + + "dead_lettering_on_message_expiration": { + Type: schema.TypeBool, + Optional: true, + }, + + "enable_batched_operations": { + Type: schema.TypeBool, + Optional: true, + }, + + "max_delivery_count": { + Type: schema.TypeInt, + Required: true, + }, + + "requires_session": { + Type: schema.TypeBool, + Optional: true, + // cannot be modified + ForceNew: true, + }, + }, + } +} + +func resourceArmServiceBusSubscriptionCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).serviceBusSubscriptionsClient + log.Printf("[INFO] preparing arguments for Azure ARM ServiceBus Subscription creation.") + + name := d.Get("name").(string) + topicName := d.Get("topic_name").(string) + namespaceName := d.Get("namespace_name").(string) + location := d.Get("location").(string) + resGroup := d.Get("resource_group_name").(string) + + parameters := servicebus.SubscriptionCreateOrUpdateParameters{ + Location: &location, + Properties: &servicebus.SubscriptionProperties{}, + } + + if autoDeleteOnIdle := d.Get("auto_delete_on_idle").(string); autoDeleteOnIdle != "" { + parameters.Properties.AutoDeleteOnIdle = &autoDeleteOnIdle + } + + if lockDuration := d.Get("lock_duration").(string); lockDuration != "" { + parameters.Properties.LockDuration = &lockDuration + } + + deadLetteringFilterExceptions := d.Get("dead_lettering_on_filter_evaluation_exceptions").(bool) + deadLetteringExpiration := d.Get("dead_lettering_on_message_expiration").(bool) + enableBatchedOps := d.Get("enable_batched_operations").(bool) + maxDeliveryCount := int32(d.Get("max_delivery_count").(int)) + requiresSession := d.Get("requires_session").(bool) + + parameters.Properties.DeadLetteringOnFilterEvaluationExceptions = &deadLetteringFilterExceptions + parameters.Properties.DeadLetteringOnMessageExpiration = &deadLetteringExpiration + parameters.Properties.EnableBatchedOperations = &enableBatchedOps + parameters.Properties.MaxDeliveryCount = &maxDeliveryCount + parameters.Properties.RequiresSession = &requiresSession + + _, err := client.CreateOrUpdate(resGroup, namespaceName, topicName, name, parameters) + if err != nil { + return err + } + + read, err := client.Get(resGroup, namespaceName, topicName, name) + if err != nil { + return err + } + if read.ID == nil { + return fmt.Errorf("Cannot read ServiceBus Subscription %s (resource group %s) ID", name, resGroup) + } + + d.SetId(*read.ID) + + return resourceArmServiceBusSubscriptionRead(d, meta) +} + +func resourceArmServiceBusSubscriptionRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).serviceBusSubscriptionsClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + namespaceName := id.Path["namespaces"] + topicName := id.Path["topics"] + name := id.Path["subscriptions"] + + log.Printf("[INFO] subscriptionID: %s, args: %s, %s, %s, %s", d.Id(), resGroup, namespaceName, topicName, name) + + resp, err := client.Get(resGroup, namespaceName, topicName, name) + if err != nil { + return fmt.Errorf("Error making Read request on Azure ServiceBus Subscription %s: %s", name, err) + } + if resp.StatusCode == http.StatusNotFound { + d.SetId("") + return nil + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resGroup) + d.Set("namespace_name", namespaceName) + d.Set("topic_name", topicName) + d.Set("location", azureRMNormalizeLocation(*resp.Location)) + + props := resp.Properties + d.Set("auto_delete_on_idle", props.AutoDeleteOnIdle) + d.Set("default_message_ttl", props.DefaultMessageTimeToLive) + d.Set("lock_duration", props.LockDuration) + d.Set("dead_lettering_on_filter_evaluation_exceptions", props.DeadLetteringOnFilterEvaluationExceptions) + d.Set("dead_lettering_on_message_expiration", props.DeadLetteringOnMessageExpiration) + d.Set("enable_batched_operations", props.EnableBatchedOperations) + d.Set("max_delivery_count", int(*props.MaxDeliveryCount)) + d.Set("requires_session", props.RequiresSession) + + return nil +} + +func resourceArmServiceBusSubscriptionDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).serviceBusSubscriptionsClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + namespaceName := id.Path["namespaces"] + topicName := id.Path["topics"] + name := id.Path["subscriptions"] + + _, err = client.Delete(resGroup, namespaceName, topicName, name) + + return err +} diff --git a/builtin/providers/azurerm/resource_arm_servicebus_subscription_test.go b/builtin/providers/azurerm/resource_arm_servicebus_subscription_test.go new file mode 100644 index 000000000..98a4049db --- /dev/null +++ b/builtin/providers/azurerm/resource_arm_servicebus_subscription_test.go @@ -0,0 +1,236 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAzureRMServiceBusSubscription_basic(t *testing.T) { + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMServiceBusSubscription_basic, ri, ri, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMServiceBusTopicDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMServiceBusSubscriptionExists("azurerm_servicebus_subscription.test"), + ), + }, + }, + }) +} + +func TestAccAzureRMServiceBusSubscription_update(t *testing.T) { + ri := acctest.RandInt() + preConfig := fmt.Sprintf(testAccAzureRMServiceBusSubscription_basic, ri, ri, ri, ri) + postConfig := fmt.Sprintf(testAccAzureRMServiceBusSubscription_update, ri, ri, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMServiceBusTopicDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMServiceBusSubscriptionExists("azurerm_servicebus_subscription.test"), + ), + }, + resource.TestStep{ + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + "azurerm_servicebus_subscription.test", "enable_batched_operations", "true"), + ), + }, + }, + }) +} + +func TestAccAzureRMServiceBusSubscription_updateRequiresSession(t *testing.T) { + ri := acctest.RandInt() + preConfig := fmt.Sprintf(testAccAzureRMServiceBusSubscription_basic, ri, ri, ri, ri) + postConfig := fmt.Sprintf(testAccAzureRMServiceBusSubscription_updateRequiresSession, ri, ri, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMServiceBusTopicDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMServiceBusSubscriptionExists("azurerm_servicebus_subscription.test"), + ), + }, + resource.TestStep{ + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr( + "azurerm_servicebus_subscription.test", "requires_session", "true"), + ), + }, + }, + }) +} + +func testCheckAzureRMServiceBusSubscriptionDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).serviceBusSubscriptionsClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_servicebus_subscription" { + continue + } + + name := rs.Primary.Attributes["name"] + topicName := rs.Primary.Attributes["topic_name"] + namespaceName := rs.Primary.Attributes["namespace_name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.Get(resourceGroup, namespaceName, topicName, name) + if err != nil { + if resp.StatusCode == http.StatusNotFound { + return nil + } + return err + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("ServiceBus Subscription still exists:\n%#v", resp.Properties) + } + } + + return nil +} + +func testCheckAzureRMServiceBusSubscriptionExists(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) + } + + subscriptionName := rs.Primary.Attributes["name"] + topicName := rs.Primary.Attributes["topic_name"] + namespaceName := rs.Primary.Attributes["namespace_name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for subscription: %s", topicName) + } + + client := testAccProvider.Meta().(*ArmClient).serviceBusSubscriptionsClient + + resp, err := client.Get(resourceGroup, namespaceName, topicName, subscriptionName) + if err != nil { + return fmt.Errorf("Bad: Get on serviceBusSubscriptionsClient: %s", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Subscription %q (resource group: %q) does not exist", subscriptionName, resourceGroup) + } + + return nil + } +} + +var testAccAzureRMServiceBusSubscription_basic = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US" +} + +resource "azurerm_servicebus_namespace" "test" { + name = "acctestservicebusnamespace-%d" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "standard" +} + +resource "azurerm_servicebus_topic" "test" { + name = "acctestservicebustopic-%d" + location = "West US" + namespace_name = "${azurerm_servicebus_namespace.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_servicebus_subscription" "test" { + name = "acctestservicebussubscription-%d" + location = "West US" + namespace_name = "${azurerm_servicebus_namespace.test.name}" + topic_name = "${azurerm_servicebus_topic.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + max_delivery_count = 10 +} +` + +var testAccAzureRMServiceBusSubscription_update = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US" +} + +resource "azurerm_servicebus_namespace" "test" { + name = "acctestservicebusnamespace-%d" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "standard" +} + +resource "azurerm_servicebus_topic" "test" { + name = "acctestservicebustopic-%d" + location = "West US" + namespace_name = "${azurerm_servicebus_namespace.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_servicebus_subscription" "test" { + name = "acctestservicebussubscription-%d" + location = "West US" + namespace_name = "${azurerm_servicebus_namespace.test.name}" + topic_name = "${azurerm_servicebus_topic.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + max_delivery_count = 10 + enable_batched_operations = true +} +` + +var testAccAzureRMServiceBusSubscription_updateRequiresSession = ` +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US" +} + +resource "azurerm_servicebus_namespace" "test" { + name = "acctestservicebusnamespace-%d" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "standard" +} + +resource "azurerm_servicebus_topic" "test" { + name = "acctestservicebustopic-%d" + location = "West US" + namespace_name = "${azurerm_servicebus_namespace.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" +} + +resource "azurerm_servicebus_subscription" "test" { + name = "acctestservicebussubscription-%d" + location = "West US" + namespace_name = "${azurerm_servicebus_namespace.test.name}" + topic_name = "${azurerm_servicebus_topic.test.name}" + resource_group_name = "${azurerm_resource_group.test.name}" + max_delivery_count = 10 + requires_session = true +} +` diff --git a/website/source/docs/providers/azurerm/r/servicebus_subscription.html.markdown b/website/source/docs/providers/azurerm/r/servicebus_subscription.html.markdown new file mode 100644 index 000000000..cdac07f9d --- /dev/null +++ b/website/source/docs/providers/azurerm/r/servicebus_subscription.html.markdown @@ -0,0 +1,107 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_servicebus_subscription" +sidebar_current: "docs-azurerm-resource-servicebus-subscription" +description: |- + Create a ServiceBus Subscription. +--- + +# azurerm\_servicebus\_subscription + +Create a ServiceBus Subscription. + +## Example Usage + +``` +resource "azurerm_resource_group" "test" { + name = "resourceGroup1" + location = "West US" +} + +resource "azurerm_servicebus_namespace" "test" { + name = "acceptanceTestServiceBusNamespace" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + sku = "standard" + + tags { + environment = "Production" + } +} + +resource "azurerm_servicebus_topic" "test" { + name = "testTopic" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + namespace_name = "${azurerm_servicebus_namespace.test.name}" + + enable_partitioning = true +} + +resource "azurerm_servicebus_subscription" "test" { + name = "testSubscription" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + namespace_name = "${azurerm_servicebus_namespace.test.name}" + topic_name = "${azurerm_servicebus_topic.test.name}" + max_delivery_count = 1 +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the ServiceBus Subscription resource. + Changing this forces a new resource to be created. + +* `namespace_name` - (Required) The name of the ServiceBus Namespace to create + this Subscription in. Changing this forces a new resource to be created. + +* `topic_name` - (Required) The name of the ServiceBus Topic to create + this Subscription in. Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the supported Azure location where the resource exists. + Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to + create the namespace. Changing this forces a new resource to be created. + +* `max_delivery_count` - (Required) The maximum number of deliveries. + +* `auto_delete_on_idle` - (Optional) The idle interval after which the + Subscription is automatically deleted, minimum of 5 minutes. Provided in the + [TimeSpan](#timespan-format) format. + +* `default_message_ttl` - (Optional) The TTL of messages sent to this Subscription + if no TTL value is set on the message itself. Provided in the [TimeSpan](#timespan-format) + format. + +* `lock_duration` - (Optional) The lock duration for the subscription, maximum + supported value is 5 minutes. Defaults to 1 minute. + +* `dead_lettering_on_filter_evaluation_exceptions` - (Optional) Boolean flag which + controls whether the Subscription has dead letter support on Filter evaluation + exceptions. Defaults to false. + +* `dead_lettering_on_message_expiration` - (Optional) Boolean flag which controls + whether the Subscription has dead letter support when a message expires. Defaults + to false. + +* `enable_batched_operations` - (Optional) Boolean flag which controls whether the + Subscription supports batched operations. Defaults to false. + +* `requires_session` - (Optional) Boolean flag which controls whether this Subscription + supports the concept of a session. Defaults to false. Changing this forces a + new resource to be created. + +### TimeSpan Format + +Some arguments for this resource are required in the TimeSpan format which is +used to represent a lengh of time. The supported format is documented [here](https://msdn.microsoft.com/en-us/library/se73z7b9(v=vs.110).aspx#Anchor_2) + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ServiceBus Subscription ID. diff --git a/website/source/layouts/azurerm.erb b/website/source/layouts/azurerm.erb index 308011c83..28bf7b039 100644 --- a/website/source/layouts/azurerm.erb +++ b/website/source/layouts/azurerm.erb @@ -145,6 +145,10 @@ azurerm_servicebus_namespace + > + azurerm_servicebus_subscription + + > azurerm_servicebus_topic