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

Iot hub networks #772

Merged
merged 5 commits into from
Jan 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
67 changes: 67 additions & 0 deletions docs/resources/iot_network.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
layout: "scaleway"
page_title: "Scaleway: scaleway_iot_network"
description: |-
Manages Scaleway IoT Networks.
---

# scaleway_iot_network

-> **Note:** This terraform resource is currently in beta and might include breaking change in future releases.

Creates and manages Scaleway IoT Networks. For more information, see the following:

- [API documentation](https://developers.scaleway.com/en/products/iot/api).
- [Product documentation](https://www.scaleway.com/en/docs/scaleway-iothub-networks/)

For more step-by-step instructions on how to setup the networks on the external providers backends, you can follow these guides:

- [Configuring the Sigfox backend](https://www.scaleway.com/en/docs/scaleway-iothub-networks/#-Configuring-the-Sigfox-backend)
- [Using the Rest Network](https://www.scaleway.com/en/docs/scaleway-iothub-networks/#-Using-the-Rest-Network)

## Examples

```hcl
resource "scaleway_iot_network" "main" {
name = "main"
hub_id = scaleway_iot_hub.main.id
type = "sigfox"
}
resource "scaleway_iot_hub" "main" {
name = "main"
product_plan = "plan_shared"
}
```

## Arguments Reference

~> **Important:** Updates to any value will recreate the IoT Route.

The following arguments are supported:

- `name` - (Required) The name of the IoT Network you want to create (e.g. `my-net`).

- `hub_id` - (Required) The hub ID to which the Network will be attached to.

- `type` - (Required) The network type to create (e.g. `sigfox`).

- `topic_prefix` - (Optional) The prefix that will be prepended to all topics for this Network.

## Attributes Reference

In addition to all arguments above, the following attributes are exported:

- `id` - The ID of the Network.
- `region` - (Defaults to [provider](../index.md#region) `region`) The [region](../guides/regions_and_zones.md#regions) in which the Network is attached to.
- `created_at` - The date and time the Network was created.
- `endpoint` - The endpoint to use when interacting with the network.
- `secret` - The endpoint key to keep secret.

## Import

IoT Networks can be imported using the `{region}/{id}`, e.g.

```bash
$ terraform import scaleway_iot_network.net01 fr-par/11111111-1111-1111-1111-111111111111
```

1 change: 1 addition & 0 deletions scaleway/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ func Provider(config *ProviderConfig) plugin.ProviderFunc {
"scaleway_iot_hub": resourceScalewayIotHub(),
"scaleway_iot_device": resourceScalewayIotDevice(),
"scaleway_iot_route": resourceScalewayIotRoute(),
"scaleway_iot_network": resourceScalewayIotNetwork(),
"scaleway_k8s_cluster": resourceScalewayK8SCluster(),
"scaleway_k8s_pool": resourceScalewayK8SPool(),
"scaleway_lb": resourceScalewayLb(),
Expand Down
7 changes: 4 additions & 3 deletions scaleway/resource_iot_device.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ func resourceScalewayIotDevice() *schema.Resource {
SchemaVersion: 0,
Schema: map[string]*schema.Schema{
"hub_id": {
Type: schema.TypeString,
Required: true,
Description: "The ID of the hub on which this device will be created",
Type: schema.TypeString,
Required: true,
Description: "The ID of the hub on which this device will be created",
DiffSuppressFunc: diffSuppressFuncLocality,
},
"name": {
Type: schema.TypeString,
Expand Down
158 changes: 158 additions & 0 deletions scaleway/resource_iot_network.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package scaleway

import (
"context"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
iot "github.com/scaleway/scaleway-sdk-go/api/iot/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
)

func resourceScalewayIotNetwork() *schema.Resource {
return &schema.Resource{
CreateContext: resourceScalewayIotNetworkCreate,
ReadContext: resourceScalewayIotNetworkRead,
DeleteContext: resourceScalewayIotNetworkDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
SchemaVersion: 0,
Schema: map[string]*schema.Schema{
"hub_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "The ID of the hub on which this network will be created",
DiffSuppressFunc: diffSuppressFuncLocality,
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "The name of the network",
},
"type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "The type of the network",
ValidateFunc: validation.StringInSlice([]string{
iot.NetworkNetworkTypeSigfox.String(),
iot.NetworkNetworkTypeRest.String(),
}, false),
},
"topic_prefix": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Description: "The prefix that will be prepended to all topics for this Network",
},
// Computed elements
"created_at": {
Type: schema.TypeString,
Computed: true,
Description: "The date and time of the creation of the network",
},
"endpoint": {
Type: schema.TypeString,
Computed: true,
Description: "The endpoint to use when interacting with the network",
},
"secret": {
Type: schema.TypeString,
Computed: true,
Description: "The endpoint key to keep secret",
Sensitive: true,
},
},
}
}

func resourceScalewayIotNetworkCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
iotAPI, region, err := iotAPIWithRegion(d, meta)
if err != nil {
return diag.FromErr(err)
}

////
// Create network
////

req := &iot.CreateNetworkRequest{
Region: region,
Name: expandOrGenerateString(d.Get("name"), "network"),
Type: iot.NetworkNetworkType(d.Get("type").(string)),
HubID: expandID(d.Get("hub_id")),
}

if topicPrefix, ok := d.GetOk("topic_prefix"); ok {
req.TopicPrefix = topicPrefix.(string)
}

res, err := iotAPI.CreateNetwork(req, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

d.SetId(newRegionalIDString(region, res.Network.ID))

// Secret key cannot be retreived later
_ = d.Set("secret", res.Secret)

return resourceScalewayIotNetworkRead(ctx, d, meta)
}

func resourceScalewayIotNetworkRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
iotAPI, region, networkID, err := iotAPIWithRegionAndID(m, d.Id())
if err != nil {
return diag.FromErr(err)
}

////
// Read Network
////
network, err := iotAPI.GetNetwork(&iot.GetNetworkRequest{
Region: region,
NetworkID: networkID,
}, scw.WithContext(ctx))
if err != nil {
if is404Error(err) {
d.SetId("")
return nil
}
return diag.FromErr(err)
}

_ = d.Set("name", network.Name)
_ = d.Set("type", network.Type.String())
_ = d.Set("endpoint", network.Endpoint)
_ = d.Set("hub_id", newRegionalID(region, network.HubID).String())
_ = d.Set("created_at", network.CreatedAt.String())
_ = d.Set("topic_prefix", network.TopicPrefix)

return nil
}

func resourceScalewayIotNetworkDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
iotAPI, region, networkID, err := iotAPIWithRegionAndID(m, d.Id())
if err != nil {
return diag.FromErr(err)
}

////
// Delete Network
////
err = iotAPI.DeleteNetwork(&iot.DeleteNetworkRequest{
Region: region,
NetworkID: networkID,
}, scw.WithContext(ctx))
if err != nil {
if !is404Error(err) {
return diag.FromErr(err)
}
}

return nil
}
121 changes: 121 additions & 0 deletions scaleway/resource_iot_network_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package scaleway

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
iot "github.com/scaleway/scaleway-sdk-go/api/iot/v1"
)

func TestAccScalewayIotNetwork_Minimal(t *testing.T) {
tt := NewTestTools(t)
defer tt.Cleanup()
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: tt.ProviderFactories,
// Destruction is done via the hub destruction.
CheckDestroy: testAccCheckScalewayIotHubDestroy(tt),
Steps: []resource.TestStep{
{
Config: `
resource "scaleway_iot_network" "default" {
name = "default"
hub_id = scaleway_iot_hub.minimal.id
type = "sigfox"
}
resource "scaleway_iot_hub" "minimal" {
name = "minimal"
product_plan = "plan_shared"
}
`,
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayIotHubExists(tt, "scaleway_iot_hub.minimal"),
testAccCheckScalewayIotNetworkExists(tt, "scaleway_iot_network.default"),
resource.TestCheckResourceAttrSet("scaleway_iot_network.default", "id"),
resource.TestCheckResourceAttrSet("scaleway_iot_network.default", "hub_id"),
resource.TestCheckResourceAttr("scaleway_iot_network.default", "name", "default"),
resource.TestCheckResourceAttr("scaleway_iot_network.default", "type", "sigfox"),
resource.TestCheckResourceAttrSet("scaleway_iot_network.default", "endpoint"),
resource.TestCheckResourceAttrSet("scaleway_iot_network.default", "secret"),
resource.TestCheckResourceAttrSet("scaleway_iot_network.default", "created_at"),
),
},
{
Config: `
resource "scaleway_iot_network" "default" {
name = "default"
hub_id = scaleway_iot_hub.minimal.id
type = "rest"
}
resource "scaleway_iot_hub" "minimal" {
name = "minimal"
product_plan = "plan_shared"
}
`,
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayIotHubExists(tt, "scaleway_iot_hub.minimal"),
testAccCheckScalewayIotNetworkExists(tt, "scaleway_iot_network.default"),
resource.TestCheckResourceAttrSet("scaleway_iot_network.default", "id"),
resource.TestCheckResourceAttrSet("scaleway_iot_network.default", "hub_id"),
resource.TestCheckResourceAttr("scaleway_iot_network.default", "name", "default"),
resource.TestCheckResourceAttr("scaleway_iot_network.default", "type", "rest"),
resource.TestCheckResourceAttrSet("scaleway_iot_network.default", "endpoint"),
resource.TestCheckResourceAttrSet("scaleway_iot_network.default", "secret"),
resource.TestCheckResourceAttrSet("scaleway_iot_network.default", "created_at"),
),
},
{
Config: `
resource "scaleway_iot_network" "default" {
name = "default"
hub_id = scaleway_iot_hub.minimal.id
type = "rest"
topic_prefix = "foo/bar"
}
resource "scaleway_iot_hub" "minimal" {
name = "minimal"
product_plan = "plan_shared"
}
`,
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayIotHubExists(tt, "scaleway_iot_hub.minimal"),
testAccCheckScalewayIotNetworkExists(tt, "scaleway_iot_network.default"),
resource.TestCheckResourceAttrSet("scaleway_iot_network.default", "id"),
resource.TestCheckResourceAttrSet("scaleway_iot_network.default", "hub_id"),
resource.TestCheckResourceAttr("scaleway_iot_network.default", "name", "default"),
resource.TestCheckResourceAttr("scaleway_iot_network.default", "type", "rest"),
resource.TestCheckResourceAttr("scaleway_iot_network.default", "topic_prefix", "foo/bar"),
resource.TestCheckResourceAttrSet("scaleway_iot_network.default", "endpoint"),
resource.TestCheckResourceAttrSet("scaleway_iot_network.default", "secret"),
resource.TestCheckResourceAttrSet("scaleway_iot_network.default", "created_at"),
),
},
},
})
}

func testAccCheckScalewayIotNetworkExists(tt *TestTools, n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("resource not found: %s", n)
}

iotAPI, region, networkID, err := iotAPIWithRegionAndID(tt.Meta, rs.Primary.ID)
if err != nil {
return err
}

_, err = iotAPI.GetNetwork(&iot.GetNetworkRequest{
Region: region,
NetworkID: networkID,
})
if err != nil {
return err
}

return nil
}
}
Loading