Skip to content

Commit

Permalink
Merge branch 'storagemover/new_resource_storagemover_agent' of github…
Browse files Browse the repository at this point in the history
….com:sinbai/terraform-provider-azurerm into storagemover/new_resource_storagemover_agent
  • Loading branch information
sinbai committed Apr 20, 2023
2 parents 7df5646 + 574a8c2 commit d09b1f3
Show file tree
Hide file tree
Showing 24 changed files with 1,634 additions and 1 deletion.
9 changes: 9 additions & 0 deletions internal/services/storagemover/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ package client
import (
"fmt"

"github.com/hashicorp/go-azure-sdk/resource-manager/storagemover/2023-03-01/agents"
"github.com/hashicorp/go-azure-sdk/resource-manager/storagemover/2023-03-01/storagemovers"
"github.com/hashicorp/terraform-provider-azurerm/internal/common"
)

type Client struct {
StorageMoversClient *storagemovers.StorageMoversClient
AgentsClient *agents.AgentsClient
}

func NewClient(o *common.ClientOptions) (*Client, error) {
Expand All @@ -18,7 +20,14 @@ func NewClient(o *common.ClientOptions) (*Client, error) {
}
o.Configure(storageMoversClient.Client, o.Authorizers.ResourceManager)

agentsClient, err := agents.NewAgentsClientWithBaseURI(o.Environment.ResourceManager)
if err != nil {
return nil, fmt.Errorf("building agent client: %+v", err)
}
o.Configure(agentsClient.Client, o.Authorizers.ResourceManager)

return &Client{
StorageMoversClient: storageMoversClient,
AgentsClient: agentsClient,
}, nil
}
1 change: 1 addition & 0 deletions internal/services/storagemover/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ func (r Registration) DataSources() []sdk.DataSource {
func (r Registration) Resources() []sdk.Resource {
return []sdk.Resource{
StorageMoverResource{},
StorageMoverAgentResource{},
}
}
54 changes: 54 additions & 0 deletions internal/services/storagemover/scripts/install_arc.sh.tftpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/bin/bash

# Disable the Azure VM Guest Agent.
current_hostname=$(hostname)
sudo service walinuxagent stop
sudo waagent -deprovision -force
sudo rm -rf /var/lib/waagent
sudo hostnamectl set-hostname $current_hostname

# Block access to the Azure IMDS endpoint.
sudo ufw --force enable
sudo ufw deny out from any to 169.254.169.254
sudo ufw default allow incoming

# Add the service principal application ID and secret here
servicePrincipalClientId="${client_id}"
servicePrincipalSecret="${client_secret}"
cloud="AzureCloud"
tenantId="${tenant_id}"
subscriptionId="${subscription_id}"
resourceGroup="${resource_group_name}"
location="${location}"
authType="principal"
correlationId="${uuid}"
output="$(wget https://aka.ms/azcmagent -O ~/install_linux_azcmagent.sh 2>&1)"
if [ $? != 0 ]; then
read -d '' bodyData <<EOF
{
"operation": "onboarding",
"messageType": "DownloadScriptFailed",
"tenantId": "$tenantId",
"subscriptionId": "$subscriptionId",
"resourceGroup": "$resourceGroup",
"location": "$location",
"correlationId": "$correlationId",
"authType": "$authType",
"message": "$output"
}
EOF
wget -qO- --method=PUT --body-data="$bodyData" "https://gbl.his.arc.azure.com/log" &> /dev/null || true
fi
echo "$output"
sudo chmod +x ~/install_linux_azcmagent.sh
cd ~
./install_linux_azcmagent.sh
sudo azcmagent connect \
--service-principal-id "$servicePrincipalClientId" \
--service-principal-secret "$servicePrincipalSecret" \
--cloud "$cloud" \
--tenant-id "$tenantId" \
--subscription-id "$subscriptionId" \
--resource-group "$resourceGroup" \
--location "$location" \
--correlation-id "$correlationId"
225 changes: 225 additions & 0 deletions internal/services/storagemover/storage_mover_agent_resource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
package storagemover

import (
"context"
"fmt"
"time"

"github.com/hashicorp/go-azure-helpers/lang/pointer"

"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-sdk/resource-manager/storagemover/2023-03-01/agents"
"github.com/hashicorp/go-azure-sdk/resource-manager/storagemover/2023-03-01/storagemovers"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
computevalidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/compute/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
)

type StorageMoverAgentResourceModel struct {
Name string `tfschema:"name"`
StorageMoverId string `tfschema:"storage_mover_id"`
ArcVirtualMachineId string `tfschema:"arc_virtual_machine_id"`
ArcVmUuid string `tfschema:"arc_virtual_machine_uuid"`
Description string `tfschema:"description"`
}

type StorageMoverAgentResource struct{}

var _ sdk.ResourceWithUpdate = StorageMoverAgentResource{}

func (r StorageMoverAgentResource) ResourceType() string {
return "azurerm_storage_mover_agent"
}

func (r StorageMoverAgentResource) ModelObject() interface{} {
return &StorageMoverAgentResourceModel{}
}

func (r StorageMoverAgentResource) IDValidationFunc() pluginsdk.SchemaValidateFunc {
return agents.ValidateAgentID
}

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

"arc_virtual_machine_id": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: computevalidate.HybridMachineID,
},

"arc_virtual_machine_uuid": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.IsUUID,
},

"storage_mover_id": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: storagemovers.ValidateStorageMoverID,
},

"description": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: validation.StringIsNotEmpty,
},
}
}

func (r StorageMoverAgentResource) Attributes() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{}
}

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

client := metadata.Client.StorageMover.AgentsClient
storageMoverId, err := storagemovers.ParseStorageMoverID(model.StorageMoverId)
if err != nil {
return err
}

id := agents.NewAgentID(storageMoverId.SubscriptionId, storageMoverId.ResourceGroupName, storageMoverId.StorageMoverName, model.Name)

existing, err := client.Get(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)
}

properties := agents.Agent{
Properties: agents.AgentProperties{
ArcResourceId: model.ArcVirtualMachineId,
ArcVMUuid: model.ArcVmUuid,
},
}

if model.Description != "" {
properties.Properties.Description = &model.Description
}

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

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

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

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

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

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

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

if metadata.ResourceData.HasChange("description") {
properties.Properties.Description = &model.Description
}

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

return nil
},
}
}

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

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

resp, err := client.Get(ctx, *id)
if err != nil {
if response.WasNotFound(resp.HttpResponse) {
return metadata.MarkAsGone(id)
}
return fmt.Errorf("retrieving %s: %+v", *id, err)
}

state := StorageMoverAgentResourceModel{
Name: id.AgentName,
StorageMoverId: storagemovers.NewStorageMoverID(id.SubscriptionId, id.ResourceGroupName, id.StorageMoverName).ID(),
}

if model := resp.Model; model != nil {
state.ArcVmUuid = model.Properties.ArcVMUuid
state.ArcVirtualMachineId = model.Properties.ArcResourceId

state.Description = pointer.From(model.Properties.Description)
}

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

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

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

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

return nil
},
}
}
Loading

0 comments on commit d09b1f3

Please sign in to comment.