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

New resource: azurerm_hci_cluster #9134

Merged
merged 19 commits into from
Dec 9, 2020
1 change: 1 addition & 0 deletions .teamcity/components/generated/services.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ var services = mapOf(
"attestation" to "Attestation",
"authorization" to "Authorization",
"automation" to "Automation",
"azurestackhci" to "Azure Stack HCI",
"batch" to "Batch",
"blueprints" to "Blueprints",
"bot" to "Bot",
Expand Down
3 changes: 3 additions & 0 deletions azurerm/internal/clients/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
attestation "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/attestation/client"
authorization "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/authorization/client"
automation "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/automation/client"
azureStackHCI "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/azurestackhci/client"
batch "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/batch/client"
blueprints "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/blueprints/client"
bot "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/bot/client"
Expand Down Expand Up @@ -106,6 +107,7 @@ type Client struct {
Attestation *attestation.Client
Authorization *authorization.Client
Automation *automation.Client
AzureStackHCI *azureStackHCI.Client
Batch *batch.Client
Blueprints *blueprints.Client
Bot *bot.Client
Expand Down Expand Up @@ -198,6 +200,7 @@ func (client *Client) Build(ctx context.Context, o *common.ClientOptions) error
client.Attestation = attestation.NewClient(o)
client.Authorization = authorization.NewClient(o)
client.Automation = automation.NewClient(o)
client.AzureStackHCI = azureStackHCI.NewClient(o)
client.Batch = batch.NewClient(o)
client.Blueprints = blueprints.NewClient(o)
client.Bot = bot.NewClient(o)
Expand Down
2 changes: 2 additions & 0 deletions azurerm/internal/provider/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/attestation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/authorization"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/automation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/azurestackhci"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/batch"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/blueprints"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/bot"
Expand Down Expand Up @@ -106,6 +107,7 @@ func SupportedUntypedServices() []sdk.UntypedServiceRegistration {
attestation.Registration{},
authorization.Registration{},
automation.Registration{},
azurestackhci.Registration{},
batch.Registration{},
blueprints.Registration{},
bot.Registration{},
Expand Down
19 changes: 19 additions & 0 deletions azurerm/internal/services/azurestackhci/client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package client

import (
"github.com/Azure/azure-sdk-for-go/services/azurestackhci/mgmt/2020-10-01/azurestackhci"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common"
)

type Client struct {
ClusterClient *azurestackhci.ClustersClient
}

func NewClient(o *common.ClientOptions) *Client {
clusterClient := azurestackhci.NewClustersClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&clusterClient.Client, o.ResourceManagerAuthorizer)

return &Client{
ClusterClient: &clusterClient,
}
}
183 changes: 183 additions & 0 deletions azurerm/internal/services/azurestackhci/hci_cluster_resource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
package azurestackhci

import (
"fmt"
"log"
"time"

"github.com/Azure/azure-sdk-for-go/services/azurestackhci/mgmt/2020-10-01/azurestackhci"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/location"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/azurestackhci/parse"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/azurestackhci/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tags"
azSchema "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceArmHCICluster() *schema.Resource {
return &schema.Resource{
Create: resourceArmHCIClusterCreate,
Read: resourceArmHCIClusterRead,
Update: resourceArmHCIClusterUpdate,
Delete: resourceArmHCIClusterDelete,

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(30 * time.Minute),
Read: schema.DefaultTimeout(5 * time.Minute),
Update: schema.DefaultTimeout(30 * time.Minute),
Delete: schema.DefaultTimeout(30 * time.Minute),
},

Importer: azSchema.ValidateResourceIDPriorToImport(func(id string) error {
_, err := parse.ClusterID(id)
return err
}),

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.ClusterName,
},

"resource_group_name": azure.SchemaResourceGroupName(),

"location": azure.SchemaLocation(),

"client_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.IsUUID,
},

"tenant_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't this statistically likely to be the current Tenant ID, so shouldn't this be Optional?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional (and Computed*) and ForceNew, actually - since this could be defaulted and overwritten

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

ValidateFunc: validation.IsUUID,
},

"tags": tags.Schema(),
},
}
}
func resourceArmHCIClusterCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).AzureStackHCI.ClusterClient
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d)
defer cancel()

name := d.Get("name").(string)
resourceGroup := d.Get("resource_group_name").(string)

id := parse.NewClusterID(subscriptionId, resourceGroup, name)

existing, err := client.Get(ctx, resourceGroup, name)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("checking for present of existing HCI Cluster %q (Resource Group %q): %+v", name, resourceGroup, err)
}
}

if existing.ID != nil && *existing.ID != "" {
return tf.ImportAsExistsError("azurerm_hci_cluster", *existing.ID)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be using the Resource ID formatter's ID here: id.ID("")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

}

cluster := azurestackhci.Cluster{
Location: utils.String(location.Normalize(d.Get("location").(string))),
ClusterProperties: &azurestackhci.ClusterProperties{
AadClientID: utils.String(d.Get("client_id").(string)),
AadTenantID: utils.String(d.Get("tenant_id").(string)),
},
Tags: tags.Expand(d.Get("tags").(map[string]interface{})),
}

if _, err := client.Create(ctx, resourceGroup, name, cluster); err != nil {
return fmt.Errorf("creating HCI Cluster %q (Resource Group %q): %+v", name, resourceGroup, err)
}

d.SetId(id.ID(""))

return resourceArmHCIClusterRead(d, meta)
}

func resourceArmHCIClusterRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).AzureStackHCI.ClusterClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := parse.ClusterID(d.Id())
if err != nil {
return err
}

resp, err := client.Get(ctx, id.ResourceGroup, id.Name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
log.Printf("[INFO] HCI Cluster %q does not exist - removing from state", d.Id())
d.SetId("")
return nil
}

return fmt.Errorf("retrieving HCI Cluster %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
}

d.Set("name", id.Name)
d.Set("resource_group_name", id.ResourceGroup)
d.Set("location", location.NormalizeNilable(resp.Location))

if props := resp.ClusterProperties; props != nil {
d.Set("client_id", props.AadClientID)
d.Set("tenant_id", props.AadTenantID)
}

return tags.FlattenAndSet(d, resp.Tags)
}

func resourceArmHCIClusterUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).AzureStackHCI.ClusterClient
ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := parse.ClusterID(d.Id())
if err != nil {
return err
}

cluster := azurestackhci.ClusterUpdate{}

if d.HasChange("tags") {
cluster.Tags = tags.Expand(d.Get("tags").(map[string]interface{}))
}

if _, err := client.Update(ctx, id.ResourceGroup, id.Name, cluster); err != nil {
return fmt.Errorf("updating HCI Cluster %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
}

return resourceArmHCIClusterRead(d, meta)
}

func resourceArmHCIClusterDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).AzureStackHCI.ClusterClient
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := parse.ClusterID(d.Id())
if err != nil {
return err
}

if _, err := client.Delete(ctx, id.ResourceGroup, id.Name); err != nil {
return fmt.Errorf("deleting HCI Cluster %q (Resource Group %q): %+v", id.Name, id.ResourceGroup, err)
}

return nil
}
Loading