Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option in IoTHub to Enable Fallback Route #2764

Merged
merged 28 commits into from
Feb 22, 2019
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c901b63
Add option in IoTHub to Enable Fallback Route
BlueBasher Jan 25, 2019
e2097e6
Use correct syntax
BlueBasher Jan 25, 2019
ee5971f
Add missing comma
BlueBasher Jan 25, 2019
e76b2df
Ran goFmt
BlueBasher Jan 25, 2019
0a127d9
Use correct assignment
BlueBasher Jan 25, 2019
cd04f96
Use util methods
BlueBasher Jan 25, 2019
d36fbc3
Change fieldname to lowercase
BlueBasher Jan 25, 2019
897e65d
Added test and documentation
BlueBasher Jan 27, 2019
b9e4039
Option to change all values for the fallback route.
BlueBasher Jan 27, 2019
682f69c
Fix incorrect type
BlueBasher Jan 27, 2019
9016dcc
fallbackRoute elements should be optional
BlueBasher Jan 27, 2019
0a9bda2
Use single string for fallback route endpoint name.
BlueBasher Jan 27, 2019
641d5fd
Fix pointer indexing
BlueBasher Jan 27, 2019
2a20b2e
Fix pointer indexing
BlueBasher Jan 27, 2019
5c13bed
Updates based on review
BlueBasher Jan 29, 2019
48d0960
merge
BlueBasher Jan 29, 2019
4ba2e53
Fix merge error
BlueBasher Jan 29, 2019
848ef38
Add Condition to expandIoTHubFallbackRoute
BlueBasher Jan 29, 2019
8787f16
Fix invalid syntax for TestCheckResourceAttr
BlueBasher Jan 29, 2019
fd37921
Check if fallback_route has been supplied.
BlueBasher Jan 31, 2019
3046a14
Fix sytax error
BlueBasher Jan 31, 2019
9b281f2
Ran gofmt
BlueBasher Jan 31, 2019
7538300
read will now ignore default fallback route
katbyte Feb 19, 2019
a27985c
Merge branch 'master' into master-fallback
katbyte Feb 19, 2019
8ebf7f0
removed name, call update after create
katbyte Feb 19, 2019
74fa267
attempt to fix fallback
katbyte Feb 19, 2019
147464e
tidied up and fixed test
katbyte Feb 21, 2019
f264c60
git merge master -S
katbyte Feb 21, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 94 additions & 2 deletions azurerm/resource_arm_iothub.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,51 @@ func resourceArmIotHub() *schema.Resource {
},
},

"fallback_route": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
Default: "$fallback",
ValidateFunc: validation.StringLenBetween(0, 64),
BlueBasher marked this conversation as resolved.
Show resolved Hide resolved
},
"source": {
Type: schema.TypeString,
Optional: true,
Default: "DeviceMessages",
ValidateFunc: validation.StringInSlice([]string{
"DeviceJobLifecycleEvents",
"DeviceLifecycleEvents",
"DeviceMessages",
"Invalid",
"TwinChangeEvents",
}, false),
},
"condition": {
// The condition is a string value representing device-to-cloud message routes query expression
// https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-query-language#device-to-cloud-message-routes-query-expressions
Type: schema.TypeString,
Optional: true,
Default: "true",
},
"endpoint_name": {
Type: schema.TypeString,
Optional: true,
Default: "events",
ValidateFunc: validation.StringLenBetween(0, 64),
},
"enabled": {
Type: schema.TypeBool,
Optional: true,
},
},
},
},

"tags": tagsSchema(),
},
}
Expand Down Expand Up @@ -292,6 +337,7 @@ func resourceArmIotHubCreateUpdate(d *schema.ResourceData, meta interface{}) err
location := azureRMNormalizeLocation(d.Get("location").(string))
skuInfo := expandIoTHubSku(d)
tags := d.Get("tags").(map[string]interface{})
fallbackRoute := expandIoTHubFallbackRoute(d)

endpoints, err := expandIoTHubEndpoints(d, subscriptionID)
if err != nil {
Expand All @@ -306,8 +352,9 @@ func resourceArmIotHubCreateUpdate(d *schema.ResourceData, meta interface{}) err
Sku: skuInfo,
Properties: &devices.IotHubProperties{
Routing: &devices.RoutingProperties{
Endpoints: endpoints,
Routes: routes,
Endpoints: endpoints,
Routes: routes,
FallbackRoute: fallbackRoute,
},
},
Tags: expandTags(tags),
Expand Down Expand Up @@ -393,6 +440,11 @@ func resourceArmIotHubRead(d *schema.ResourceData, meta interface{}) error {
if err := d.Set("route", routes); err != nil {
return fmt.Errorf("Error setting `route` in IoTHub %q: %+v", name, err)
}

fallbackRoute := flattenIoTHubFallbackRoute(properties.Routing)
if err := d.Set("fallback_route", fallbackRoute); err != nil {
return fmt.Errorf("Error setting `fallbackRoute` in IoTHub %q: %+v", name, err)
}
}

d.Set("name", name)
Expand Down Expand Up @@ -573,6 +625,24 @@ func expandIoTHubEndpoints(d *schema.ResourceData, subscriptionId string) (*devi
}, nil
}

func expandIoTHubFallbackRoute(d *schema.ResourceData) *devices.FallbackRouteProperties {
fallbackRouteList := d.Get("fallback_route").([]interface{})
fallbackRouteMap := fallbackRouteList[0].(map[string]interface{})

name := fallbackRouteMap["name"].(string)
source := fallbackRouteMap["source"].(string)
endpointNames := make([]string, 0)
katbyte marked this conversation as resolved.
Show resolved Hide resolved
endpointNames = append(endpointNames, fallbackRouteMap["endpoint_name"].(string))
isEnabled := fallbackRouteMap["enabled"].(bool)

return &devices.FallbackRouteProperties{
Name: &name,
Source: &source,
EndpointNames: &endpointNames,
IsEnabled: &isEnabled,
}
}

func expandIoTHubSku(d *schema.ResourceData) *devices.IotHubSkuInfo {
skuList := d.Get("sku").([]interface{})
skuMap := skuList[0].(map[string]interface{})
Expand Down Expand Up @@ -740,6 +810,28 @@ func flattenIoTHubRoute(input *devices.RoutingProperties) []interface{} {
return results
}

func flattenIoTHubFallbackRoute(input *devices.RoutingProperties) []interface{} {
output := make(map[string]interface{})

if input.FallbackRoute != nil {
BlueBasher marked this conversation as resolved.
Show resolved Hide resolved
if name := input.FallbackRoute.Name; name != nil {
output["name"] = *name
}
if condition := input.FallbackRoute.Condition; condition != nil {
output["condition"] = *condition
}
if endpointNames := input.FallbackRoute.EndpointNames; endpointNames != nil {
output["endpoint_name"] = (*endpointNames)[0]
}
if isEnabled := input.FallbackRoute.IsEnabled; isEnabled != nil {
output["enabled"] = *isEnabled
}
output["source"] = input.FallbackRoute.Source
BlueBasher marked this conversation as resolved.
Show resolved Hide resolved
}

return []interface{}{output}
}

func validateIoTHubEndpointName(v interface{}, _ string) (warnings []string, errors []error) {
value := v.(string)

Expand Down
56 changes: 56 additions & 0 deletions azurerm/resource_arm_iothub_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,30 @@ func TestAccAzureRMIotHub_customRoutes(t *testing.T) {
})
}

func TestAccAzureRMIotHub_fallbackRoute(t *testing.T) {
resourceName := "azurerm_iothub.test"
rInt := tf.AccRandTimeInt()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMIotHubDestroy,
Steps: []resource.TestStep{
{
Config: testAccAzureRMIotHub_fallbackRoute(rInt, testLocation()),
Check: resource.ComposeTestCheckFunc(
testCheckAzureRMIotHubExists(resourceName),
),
BlueBasher marked this conversation as resolved.
Show resolved Hide resolved
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testCheckAzureRMIotHubDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*ArmClient).iothubResourceClient
ctx := testAccProvider.Meta().(*ArmClient).StopContext
Expand Down Expand Up @@ -298,3 +322,35 @@ resource "azurerm_iothub" "test" {
}
`, rInt, location, rStr, rInt)
}

func testAccAzureRMIotHub_fallbackRoute(rInt int, location string) string {
return fmt.Sprintf(`
resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_iothub" "test" {
name = "acctestIoTHub-%d"
resource_group_name = "${azurerm_resource_group.test.name}"
location = "${azurerm_resource_group.test.location}"
BlueBasher marked this conversation as resolved.
Show resolved Hide resolved

sku {
name = "S1"
tier = "Standard"
capacity = "1"
}

fallback_route {
name = "fallback"
source = "DeviceMessages"
endpoint_name = "fallback"
enabled = true
}

tags {
"purpose" = "testing"
}
}
`, rInt, location, rInt)
}
26 changes: 23 additions & 3 deletions website/docs/r/iothub.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ resource "azurerm_storage_container" "test" {
}

resource "azurerm_iothub" "test" {
name = "test"
resource_group_name = "${azurerm_resource_group.test.name}"
location = "${azurerm_resource_group.test.location}"
name = "test"
BlueBasher marked this conversation as resolved.
Show resolved Hide resolved
resource_group_name = "${azurerm_resource_group.test.name}"
location = "${azurerm_resource_group.test.location}"

sku {
name = "S1"
Expand All @@ -63,6 +63,10 @@ resource "azurerm_iothub" "test" {
enabled = true
}

fallback_route {
enabled = true
}

tags {
"purpose" = "testing"
}
Expand All @@ -85,6 +89,8 @@ The following arguments are supported:

* `route` - (Optional) A `route` block as defined below.

* `fallback_route` - (Optional) A `fallback_route` block as defined below. If the fallback route is enabled, messages that don't match any of the supplied routes are automatically sent to this route. Defaults to messages/events.

* `tags` - (Optional) A mapping of tags to assign to the resource.

---
Expand Down Expand Up @@ -133,6 +139,20 @@ A `route` block supports the following:

* `enabled` - (Required) Used to specify whether a route is enabled.

---

A `fallback_route` block supports the following:

* `name` - (Optional) The name of the route. The name can only include alphanumeric characters, periods, underscores, hyphens, has a maximum length of 64 characters, and must be unique.
BlueBasher marked this conversation as resolved.
Show resolved Hide resolved

* `source` - (Optional) The source that the routing rule is to be applied to, such as `DeviceMessages`. Possible values include: `RoutingSourceInvalid`, `RoutingSourceDeviceMessages`, `RoutingSourceTwinChangeEvents`, `RoutingSourceDeviceLifecycleEvents`, `RoutingSourceDeviceJobLifecycleEvents`.

* `condition` - (Optional) The condition that is evaluated to apply the routing rule. If no condition is provided, it evaluates to true by default. For grammar, see: https://docs.microsoft.com/azure/iot-hub/iot-hub-devguide-query-language.

* `endpoint_name` - (Optional) The endpoint to which messages that satisfy the condition are routed. Currently only 1 endpoint is allowed.

* `enabled` - (Optional) Used to specify whether the fallback route is enabled.

## Attributes Reference

The following attributes are exported:
Expand Down