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_automation_connection_type #17538

Merged
merged 5 commits into from
Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions internal/provider/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ func SupportedTypedServices() []sdk.TypedServiceRegistration {
appconfiguration.Registration{},
applicationinsights.Registration{},
appservice.Registration{},
automation.Registration{},
batch.Registration{},
bot.Registration{},
compute.Registration{},
Expand Down
211 changes: 211 additions & 0 deletions internal/services/automation/automation_connection_type_resource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
package automation

import (
"context"
"fmt"
"time"

"github.com/Azure/azure-sdk-for-go/services/preview/automation/mgmt/2020-01-13-preview/automation"
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-sdk/resource-manager/automation/2021-06-22/automationaccount"
"github.com/hashicorp/terraform-provider-azurerm/helpers/azure"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/automation/parse"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/automation/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

type FieldDefinition struct {
Name string `tfschema:"name"`
IsOptional bool `tfschema:"is_optional"`
IsEncrypted bool `tfschema:"is_encrypted"`
Type string `tfschema:"type"`
}

type AutomationConnectionTypeModel struct {
ResourceGrup string `json:"resource_grup" tfschema:"resource_group_name"`
AutomationAccountName string `json:"automation_account_name" tfschema:"automation_account_name"`
Name string `json:"name" tfschema:"name"`
IsGlobal bool `json:"is_global" tfschema:"is_global"`
FieldDefinitions []FieldDefinition `json:"field_definitions" tfschema:"field_definitions"`
}

type AutomationConnectionTypeResource struct{}

var _ sdk.Resource = (*AutomationConnectionTypeResource)(nil)

func (m AutomationConnectionTypeResource) Arguments() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
"resource_group_name": azure.SchemaResourceGroupName(),

"automation_account_name": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.AutomationAccount(),
},

"name": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.ConnectionTypeName,
},

"is_global": {
Type: pluginsdk.TypeBool,
Optional: true,
ForceNew: true,
},

"field_definitions": {
Type: pluginsdk.TypeList,
Required: true,
ForceNew: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Required: true,
},
"is_encrypted": {
Type: pluginsdk.TypeBool,
Optional: true,
},
"is_optional": {
Type: pluginsdk.TypeBool,
Optional: true,
},
"type": {
Type: pluginsdk.TypeString,
Required: true,
},
},
},
},
}
}

func (m AutomationConnectionTypeResource) Attributes() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{}
}

func (m AutomationConnectionTypeResource) ModelObject() interface{} {
return &AutomationConnectionTypeModel{}
}

func (m AutomationConnectionTypeResource) ResourceType() string {
return "azurerm_automation_connection_type"
}

func (m AutomationConnectionTypeResource) Create() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 30 * time.Minute,
Func: func(ctx context.Context, meta sdk.ResourceMetaData) error {
client := meta.Client.Automation.ConnectionTypeClient
connClient := meta.Client.Automation.AccountClient

var model AutomationConnectionTypeModel
if err := meta.Decode(&model); err != nil {
return err
}
subscriptionID := meta.Client.Account.SubscriptionId

accountID := automationaccount.NewAutomationAccountID(subscriptionID, model.ResourceGrup, model.AutomationAccountName)
account, err := connClient.Get(ctx, accountID)
if err != nil {
return fmt.Errorf("retrieving automation account %q: %+v", accountID, err)
}
if response.WasNotFound(account.HttpResponse) {
return fmt.Errorf("automation account %q was not found", accountID)
}

id := parse.NewConnectionTypeID(accountID.SubscriptionId, model.ResourceGrup, model.AutomationAccountName, model.Name)
existing, err := client.Get(ctx, id.ResourceGroup, model.AutomationAccountName, model.Name)
if !utils.ResponseWasNotFound(existing.Response) {
if err != nil {
return fmt.Errorf("retreiving %s: %v", id, err)
}
return meta.ResourceRequiresImport(m.ResourceType(), id)
}
param := automation.ConnectionTypeCreateOrUpdateParameters{
Name: utils.String(model.Name),
ConnectionTypeCreateOrUpdateProperties: &automation.ConnectionTypeCreateOrUpdateProperties{
IsGlobal: utils.Bool(model.IsGlobal),
FieldDefinitions: map[string]*automation.FieldDefinition{},
},
}
for _, field := range model.FieldDefinitions {
param.ConnectionTypeCreateOrUpdateProperties.FieldDefinitions[field.Name] = &automation.FieldDefinition{
IsEncrypted: utils.Bool(field.IsEncrypted),
IsOptional: utils.Bool(field.IsOptional),
Type: utils.String(field.Type),
}
}
_, err = client.CreateOrUpdate(ctx, id.ResourceGroup, id.AutomationAccountName, id.Name, param)
if err != nil {
return fmt.Errorf("creating %s: %v", id, err)
}

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

func (m AutomationConnectionTypeResource) Read() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 5 * time.Minute,
Func: func(ctx context.Context, meta sdk.ResourceMetaData) error {
id, err := parse.ConnectionTypeID(meta.ResourceData.Id())
if err != nil {
return err
}

client := meta.Client.Automation.ConnectionTypeClient
result, err := client.Get(ctx, id.ResourceGroup, id.AutomationAccountName, id.Name)
if err != nil {
return err
}

var output AutomationConnectionTypeModel
output.IsGlobal = utils.NormaliseNilableBool(result.IsGlobal)
output.Name = utils.NormalizeNilableString(result.Name)
output.AutomationAccountName = id.AutomationAccountName
output.ResourceGrup = id.ResourceGroup
for name, prop := range result.FieldDefinitions {
output.FieldDefinitions = append(output.FieldDefinitions, FieldDefinition{
Name: name,
Type: utils.NormalizeNilableString(prop.Type),
IsEncrypted: utils.NormaliseNilableBool(prop.IsEncrypted),
IsOptional: utils.NormaliseNilableBool(prop.IsOptional),
})
}

return meta.Encode(&output)
},
}
}

func (m AutomationConnectionTypeResource) Delete() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 10 * time.Minute,
Func: func(ctx context.Context, meta sdk.ResourceMetaData) error {
id, err := parse.ConnectionTypeID(meta.ResourceData.Id())
if err != nil {
return err
}

client := meta.Client.Automation.ConnectionTypeClient
if _, err = client.Delete(ctx, id.ResourceGroup, id.AutomationAccountName, id.Name); err != nil {
return fmt.Errorf("deleting %s: %v", id, err)
}
return nil
},
}
}

func (m AutomationConnectionTypeResource) IDValidationFunc() pluginsdk.SchemaValidateFunc {
return validate.ConnectionTypeID
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package automation_test

import (
"context"
"fmt"
"testing"

"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/automation"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/automation/parse"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

type AutomationConnectionTypeResource struct{}

func (a AutomationConnectionTypeResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
id, err := parse.ConnectionTypeID(state.ID)
if err != nil {
return nil, err
}
resp, err := client.Automation.ConnectionTypeClient.Get(ctx, id.ResourceGroup, id.AutomationAccountName, id.Name)
if err != nil {
return nil, fmt.Errorf("retrieving Automation Connection Type %s: %+v", id, err)
}
return utils.Bool(resp.ConnectionTypeProperties != nil), nil
}

func (a AutomationConnectionTypeResource) template(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-auto-%[1]d"
location = "%[2]s"
}

resource "azurerm_automation_account" "test" {
name = "acctest-%[1]d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
sku_name = "Basic"
}
`, data.RandomInteger, data.Locations.Primary)
}

func (a AutomationConnectionTypeResource) basic(data acceptance.TestData) string {
return fmt.Sprintf(`


%s

resource "azurerm_automation_connection_type" "test" {
name = "acctest-%[2]d"
resource_group_name = azurerm_resource_group.test.name
automation_account_name = azurerm_automation_account.test.name
is_global = false
field_definitions {
name = "my_def"
type = "string"
}
}
`, a.template(data), data.RandomInteger)
}

func TestAccAutomationConnectionType_basic(t *testing.T) {
data := acceptance.BuildTestData(t, automation.AutomationConnectionTypeResource{}.ResourceType(), "test")
r := AutomationConnectionTypeResource{}
data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.basic(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
check.That(data.ResourceName).Key("is_global").HasValue("false"),
),
},
data.ImportStep(),
})
}
75 changes: 75 additions & 0 deletions internal/services/automation/parse/connection_type.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"fmt"
"strings"

"github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids"
)

type ConnectionTypeId struct {
SubscriptionId string
ResourceGroup string
AutomationAccountName string
Name string
}

func NewConnectionTypeID(subscriptionId, resourceGroup, automationAccountName, name string) ConnectionTypeId {
return ConnectionTypeId{
SubscriptionId: subscriptionId,
ResourceGroup: resourceGroup,
AutomationAccountName: automationAccountName,
Name: name,
}
}

func (id ConnectionTypeId) String() string {
segments := []string{
fmt.Sprintf("Name %q", id.Name),
fmt.Sprintf("Automation Account Name %q", id.AutomationAccountName),
fmt.Sprintf("Resource Group %q", id.ResourceGroup),
}
segmentsStr := strings.Join(segments, " / ")
return fmt.Sprintf("%s: (%s)", "Connection Type", segmentsStr)
}

func (id ConnectionTypeId) ID() string {
fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Automation/automationAccounts/%s/connectionTypes/%s"
return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroup, id.AutomationAccountName, id.Name)
}

// ConnectionTypeID parses a ConnectionType ID into an ConnectionTypeId struct
func ConnectionTypeID(input string) (*ConnectionTypeId, error) {
id, err := resourceids.ParseAzureResourceID(input)
if err != nil {
return nil, err
}

resourceId := ConnectionTypeId{
SubscriptionId: id.SubscriptionID,
ResourceGroup: id.ResourceGroup,
}

if resourceId.SubscriptionId == "" {
return nil, fmt.Errorf("ID was missing the 'subscriptions' element")
}

if resourceId.ResourceGroup == "" {
return nil, fmt.Errorf("ID was missing the 'resourceGroups' element")
}

if resourceId.AutomationAccountName, err = id.PopSegment("automationAccounts"); err != nil {
return nil, err
}
if resourceId.Name, err = id.PopSegment("connectionTypes"); err != nil {
return nil, err
}

if err := id.ValidateNoEmptySegments(input); err != nil {
return nil, err
}

return &resourceId, nil
}
Loading