Skip to content

Commit

Permalink
New resources: azurerm_iothub_device_update_account `azurerm_iothub…
Browse files Browse the repository at this point in the history
…_device_update_instance`
  • Loading branch information
myc2h6o committed Oct 17, 2022
1 parent eebab07 commit 2f3f508
Show file tree
Hide file tree
Showing 63 changed files with 4,552 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .teamcity/components/settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ var serviceTestConfigurationOverrides = mapOf(
// HSM has low quota and potentially slow recycle time, Only run on Mondays
"hsm" to testConfiguration(parallelism = 1, daysOfWeek = "1"),

// IoT Hub Device Update is only available in certain locations
"iothub" to testConfiguration(locationOverride = LocationConfiguration("northeurope", "eastus2", "westus2", false)),

// IoT Central is only available in certain locations
"iotcentral" to testConfiguration(locationOverride = LocationConfiguration("westeurope", "southeastasia", "eastus2", false)),

Expand Down
1 change: 1 addition & 0 deletions internal/provider/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ func SupportedTypedServices() []sdk.TypedServiceRegistration {
domainservices.Registration{},
eventhub.Registration{},
fluidrelay.Registration{},
iothub.Registration{},
iotcentral.Registration{},
keyvault.Registration{},
loadbalancer.Registration{},
Expand Down
6 changes: 6 additions & 0 deletions internal/services/iothub/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import (
"github.com/Azure/azure-sdk-for-go/services/iothub/mgmt/2021-07-02/devices"
"github.com/hashicorp/go-azure-sdk/resource-manager/deviceprovisioningservices/2022-02-05/dpscertificate"
"github.com/hashicorp/go-azure-sdk/resource-manager/deviceprovisioningservices/2022-02-05/iotdpsresource"
"github.com/hashicorp/go-azure-sdk/resource-manager/deviceupdate/2022-10-01/deviceupdates"
"github.com/hashicorp/terraform-provider-azurerm/internal/common"
)

type Client struct {
ResourceClient *devices.IotHubResourceClient
IotHubCertificateClient *devices.CertificatesClient
DeviceUpdatesClient *deviceupdates.DeviceupdatesClient
DPSResourceClient *iotdpsresource.IotDpsResourceClient
DPSCertificateClient *dpscertificate.DpsCertificateClient
}
Expand All @@ -21,6 +23,9 @@ func NewClient(o *common.ClientOptions) *Client {
IotHubCertificateClient := devices.NewCertificatesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&IotHubCertificateClient.Client, o.ResourceManagerAuthorizer)

DeviceUpdatesClient := deviceupdates.NewDeviceupdatesClientWithBaseURI(o.ResourceManagerEndpoint)
o.ConfigureClient(&DeviceUpdatesClient.Client, o.ResourceManagerAuthorizer)

DPSResourceClient := iotdpsresource.NewIotDpsResourceClientWithBaseURI(o.ResourceManagerEndpoint)
o.ConfigureClient(&DPSResourceClient.Client, o.ResourceManagerAuthorizer)

Expand All @@ -30,6 +35,7 @@ func NewClient(o *common.ClientOptions) *Client {
return &Client{
ResourceClient: &ResourceClient,
IotHubCertificateClient: &IotHubCertificateClient,
DeviceUpdatesClient: &DeviceUpdatesClient,
DPSResourceClient: &DPSResourceClient,
DPSCertificateClient: &DPSCertificateClient,
}
Expand Down
284 changes: 284 additions & 0 deletions internal/services/iothub/iothub_device_update_account_resource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
package iothub

import (
"context"
"fmt"
"time"

"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
"github.com/hashicorp/go-azure-helpers/resourcemanager/identity"
"github.com/hashicorp/go-azure-helpers/resourcemanager/location"
"github.com/hashicorp/go-azure-sdk/resource-manager/deviceupdate/2022-10-01/deviceupdates"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/iothub/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
)

type IotHubDeviceUpdateAccountResource struct{}

var (
_ sdk.ResourceWithUpdate = IotHubDeviceUpdateAccountResource{}
)

type IotHubDeviceUpdateAccountModel struct {
Name string `tfschema:"name"`
ResourceGroupName string `tfschema:"resource_group_name"`
Location string `tfschema:"location"`
HostName string `tfschema:"host_name"`
PublicNetworkAccess deviceupdates.PublicNetworkAccess `tfschema:"public_network_access"`
Sku deviceupdates.SKU `tfschema:"sku"`
Tags map[string]string `tfschema:"tags"`
}

func (r IotHubDeviceUpdateAccountResource) Arguments() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.IotHubDeviceUpdateAccountName,
},

"resource_group_name": commonschema.ResourceGroupName(),

"location": commonschema.Location(),

"identity": commonschema.SystemAssignedUserAssignedIdentityOptional(),

"public_network_access": {
Type: pluginsdk.TypeString,
Optional: true,
Default: deviceupdates.PublicNetworkAccessEnabled,
ValidateFunc: validation.StringInSlice([]string{
string(deviceupdates.PublicNetworkAccessEnabled),
string(deviceupdates.PublicNetworkAccessDisabled),
}, false),
},

"sku": {
Type: pluginsdk.TypeString,
Optional: true,
Default: deviceupdates.SKUStandard,
ValidateFunc: validation.StringInSlice([]string{
string(deviceupdates.SKUFree),
string(deviceupdates.SKUStandard),
}, false),
},

"tags": commonschema.Tags(),
}
}

func (r IotHubDeviceUpdateAccountResource) Attributes() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
"host_name": {
Type: pluginsdk.TypeString,
Computed: true,
},
}
}

func (r IotHubDeviceUpdateAccountResource) ResourceType() string {
return "azurerm_iothub_device_update_account"
}

func (r IotHubDeviceUpdateAccountResource) ModelObject() interface{} {
return &IotHubDeviceUpdateInstanceModel{}
}

func (r IotHubDeviceUpdateAccountResource) IDValidationFunc() pluginsdk.SchemaValidateFunc {
return deviceupdates.ValidateAccountID
}

func (r IotHubDeviceUpdateAccountResource) Create() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 30 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
var model IotHubDeviceUpdateAccountModel
if err := metadata.Decode(&model); err != nil {
return fmt.Errorf("decoding: %+v", err)
}

client := metadata.Client.IoTHub.DeviceUpdatesClient
subscriptionId := metadata.Client.Account.SubscriptionId
id := deviceupdates.NewAccountID(subscriptionId, model.ResourceGroupName, model.Name)
existing, err := client.AccountsGet(ctx, id)
if err != nil && !response.WasNotFound(existing.HttpResponse) {
return fmt.Errorf("checking for existing %s: %+v", id, err)
}

if !response.WasNotFound(existing.HttpResponse) {
return metadata.ResourceRequiresImport(r.ResourceType(), id)
}

identityValue, err := identity.ExpandLegacySystemAndUserAssignedMap(metadata.ResourceData.Get("identity").([]interface{}))
if err != nil {
return fmt.Errorf("expanding `identity`: %+v", err)
}

input := &deviceupdates.Account{
Location: location.Normalize(model.Location),
Identity: identityValue,
Properties: &deviceupdates.AccountProperties{
PublicNetworkAccess: &model.PublicNetworkAccess,
Sku: &model.Sku,
},
Tags: &model.Tags,
}

if err := client.AccountsCreateThenPoll(ctx, id, *input); err != nil {
return fmt.Errorf("creating %s: %+v", id, err)
}

metadata.SetID(id)
return nil
},
}
}

func (r IotHubDeviceUpdateAccountResource) Read() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 5 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
client := metadata.Client.IoTHub.DeviceUpdatesClient

id, err := deviceupdates.ParseAccountID(metadata.ResourceData.Id())
if err != nil {
return err
}

resp, err := client.AccountsGet(ctx, *id)
if err != nil {
if response.WasNotFound(resp.HttpResponse) {
return metadata.MarkAsGone(id)
}

return fmt.Errorf("retrieving %s: %+v", *id, err)
}

model := resp.Model
if model == nil {
return fmt.Errorf("retrieving %s: model was nil", id)
}

state := IotHubDeviceUpdateAccountModel{
Name: id.AccountName,
ResourceGroupName: id.ResourceGroupName,
Location: location.Normalize(model.Location),
}

identityValue, err := identity.FlattenLegacySystemAndUserAssignedMap(model.Identity)
if err != nil {
return fmt.Errorf("flattening `identity`: %+v", err)
}

if err := metadata.ResourceData.Set("identity", identityValue); err != nil {
return fmt.Errorf("setting `identity`: %+v", err)
}

if properties := model.Properties; properties != nil {
if properties.HostName != nil {
state.HostName = *properties.HostName
}

if properties.PublicNetworkAccess != nil {
state.PublicNetworkAccess = *properties.PublicNetworkAccess
}

if properties.Sku != nil {
state.Sku = *properties.Sku
}
}
if model.Tags != nil {
state.Tags = *model.Tags
}

return metadata.Encode(&state)
},
}
}

func (r IotHubDeviceUpdateAccountResource) Update() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 30 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
client := metadata.Client.IoTHub.DeviceUpdatesClient

id, err := deviceupdates.ParseAccountID(metadata.ResourceData.Id())
if err != nil {
return err
}

var model IotHubDeviceUpdateAccountModel
if err := metadata.Decode(&model); err != nil {
return fmt.Errorf("decoding: %+v", err)
}

resp, err := client.AccountsGet(ctx, *id)
if err != nil {
return fmt.Errorf("retrieving %s: %+v", *id, err)
}

existing := resp.Model
if existing == nil {
return fmt.Errorf("retrieving %s: properties was nil", id)
}

if existing.Properties == nil {
existing.Properties = &deviceupdates.AccountProperties{}
}

if metadata.ResourceData.HasChange("identity") {
identityValue, err := identity.ExpandLegacySystemAndUserAssignedMap(metadata.ResourceData.Get("identity").([]interface{}))
if err != nil {
return fmt.Errorf("expanding `identity`: %+v", err)
}
existing.Identity = identityValue
}

if metadata.ResourceData.HasChange("public_network_access") {
existing.Properties.PublicNetworkAccess = &model.PublicNetworkAccess
}

if metadata.ResourceData.HasChange("sku") {
existing.Properties.Sku = &model.Sku
}

if metadata.ResourceData.HasChange("tags") {
existing.Tags = &model.Tags
}

existing.Properties.HostName = nil
existing.Properties.Locations = nil
existing.SystemData = nil

if err := client.AccountsCreateThenPoll(ctx, *id, *existing); err != nil {
return fmt.Errorf("updating %s: %+v", *id, err)
}

return nil
},
}
}

func (r IotHubDeviceUpdateAccountResource) Delete() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 30 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
client := metadata.Client.IoTHub.DeviceUpdatesClient

id, err := deviceupdates.ParseAccountID(metadata.ResourceData.Id())
if err != nil {
return err
}

if err := client.AccountsDeleteThenPoll(ctx, *id); err != nil {
return fmt.Errorf("deleting %s: %+v", id, err)
}

return nil
},
}
}
Loading

0 comments on commit 2f3f508

Please sign in to comment.