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_data_factory_credential_user_managed_identity #24307

Merged
merged 25 commits into from
Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ require (
github.com/google/go-cmp v0.5.9
github.com/google/uuid v1.3.1
github.com/hashicorp/go-azure-helpers v0.65.0
github.com/hashicorp/go-azure-sdk v0.20231215.1114251
github.com/hashicorp/go-azure-sdk v0.20231220.1220246
github.com/hashicorp/go-hclog v1.5.0
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/go-uuid v1.0.3
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv
github.com/hashicorp/go-azure-helpers v0.12.0/go.mod h1:Zc3v4DNeX6PDdy7NljlYpnrdac1++qNW0I4U+ofGwpg=
github.com/hashicorp/go-azure-helpers v0.65.0 h1:aOZV7HcxvqAlnaWJ/Fhfu321dXLs++TyBIVelWOb/8w=
github.com/hashicorp/go-azure-helpers v0.65.0/go.mod h1:ELmZ65vzHJNTk6ml4jsPD+xq2gZb7t78D35s+XN02Kk=
github.com/hashicorp/go-azure-sdk v0.20231215.1114251 h1:SxPZYo5UrS1HcGOkTvz9k+ymHn4EFB3I1gbBiU3DksI=
github.com/hashicorp/go-azure-sdk v0.20231215.1114251/go.mod h1:69DSA+VMovHYJyQkRuUP3BCgwlEFrKvzeIHKi9m5xzY=
github.com/hashicorp/go-azure-sdk v0.20231220.1220246 h1:weUUUjjYMiz0rcgYhVPOr8wGutQQpWrE5RlboFddsyg=
github.com/hashicorp/go-azure-sdk v0.20231220.1220246/go.mod h1:69DSA+VMovHYJyQkRuUP3BCgwlEFrKvzeIHKi9m5xzY=
github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU=
github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
Expand Down
9 changes: 9 additions & 0 deletions internal/services/datafactory/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"

"github.com/Azure/azure-sdk-for-go/services/datafactory/mgmt/2018-06-01/datafactory" // nolint: staticcheck
"github.com/hashicorp/go-azure-sdk/resource-manager/datafactory/2018-06-01/credentials"
"github.com/hashicorp/go-azure-sdk/resource-manager/datafactory/2018-06-01/factories"
"github.com/hashicorp/go-azure-sdk/resource-manager/datafactory/2018-06-01/managedprivateendpoints"
"github.com/hashicorp/go-azure-sdk/resource-manager/datafactory/2018-06-01/managedvirtualnetworks"
Expand All @@ -15,6 +16,7 @@ import (

type Client struct {
Factories *factories.FactoriesClient
Credentials *credentials.CredentialsClient
ManagedPrivateEndpoints *managedprivateendpoints.ManagedPrivateEndpointsClient
ManagedVirtualNetworks *managedvirtualnetworks.ManagedVirtualNetworksClient

Expand All @@ -34,6 +36,12 @@ func NewClient(o *common.ClientOptions) (*Client, error) {
}
o.Configure(factoriesClient.Client, o.Authorizers.ResourceManager)

credentialsClient, err := credentials.NewCredentialsClientWithBaseURI(o.Environment.ResourceManager)
if err != nil {
return nil, fmt.Errorf("building Factories client: %+v", err)
}
o.Configure(credentialsClient.Client, o.Authorizers.ResourceManager)

managedPrivateEndpointsClient, err := managedprivateendpoints.NewManagedPrivateEndpointsClientWithBaseURI(o.Environment.ResourceManager)
if err != nil {
return nil, fmt.Errorf("building ManagedPrivateEndpoints client: %+v", err)
Expand Down Expand Up @@ -67,6 +75,7 @@ func NewClient(o *common.ClientOptions) (*Client, error) {

return &Client{
Factories: factoriesClient,
Credentials: credentialsClient,
ManagedPrivateEndpoints: managedPrivateEndpointsClient,
ManagedVirtualNetworks: managedVirtualNetworksClient,

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
package datafactory
bruceharrison1984 marked this conversation as resolved.
Show resolved Hide resolved

import (
"context"
"fmt"
"time"

"github.com/hashicorp/go-azure-helpers/resourcemanager/commonids"
"github.com/hashicorp/go-azure-sdk/resource-manager/datafactory/2018-06-01/credentials"
"github.com/hashicorp/go-azure-sdk/resource-manager/datafactory/2018-06-01/factories"
"github.com/hashicorp/terraform-provider-azurerm/helpers/tf"
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

type DataFactoryCredentialUserAssignedManagedIdentityResource struct{}

// user managed identities only have one type
const IDENTITY_TYPE = "ManagedIdentity"

var _ sdk.Resource = DataFactoryCredentialUserAssignedManagedIdentityResource{}
var _ sdk.ResourceWithUpdate = DataFactoryCredentialUserAssignedManagedIdentityResource{}

func (DataFactoryCredentialUserAssignedManagedIdentityResource) ResourceType() string {
return "azurerm_data_factory_credential_user_managed_identity"
}

type DataFactoryCredentialUserAssignedManagedIdentityResourceSchema struct {
Name string `tfschema:"name"`
DataFactoryId string `tfschema:"data_factory_id"`
IdentityId string `tfschema:"identity_id"`
Description string `tfschema:"description"`
Annotations []string `tfschema:"annotations"`
}

func (DataFactoryCredentialUserAssignedManagedIdentityResource) Arguments() map[string]*pluginsdk.Schema {
return map[string]*pluginsdk.Schema{
"name": {
Description: "The desired name of the credential resource",
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringIsNotEmpty,
},
"data_factory_id": {
Description: "The resource ID of the parent Data Factory",
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: factories.ValidateFactoryID,
},
"identity_id": {
Description: "The resource ID of the User Assigned Managed Identity",
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: commonids.ValidateUserAssignedIdentityID,
},
"description": {
Description: "(Optional) Short text description",
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: validation.StringIsNotEmpty,
},
"annotations": { // this property is not visible in the azure portal
Description: "(Optional) List of string annotations.",
Type: pluginsdk.TypeList,
Optional: true,
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeString,
},
},
}
}

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

func (DataFactoryCredentialUserAssignedManagedIdentityResource) ModelObject() interface{} {
return &DataFactoryCredentialUserAssignedManagedIdentityResourceSchema{}
}

func (DataFactoryCredentialUserAssignedManagedIdentityResource) IDValidationFunc() pluginsdk.SchemaValidateFunc {
return credentials.ValidateCredentialID
}

func (DataFactoryCredentialUserAssignedManagedIdentityResource) Read() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 5 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
d := metadata.ResourceData
client := metadata.Client.DataFactory.Credentials

credentialId, err := credentials.ParseCredentialID(d.Id())
if err != nil {
return err
}

var state DataFactoryCredentialUserAssignedManagedIdentityResourceSchema

existing, err := client.CredentialOperationsGet(ctx, *credentialId, credentials.CredentialOperationsGetOperationOptions{})
if err != nil {
if existing.HttpResponse.Status == "404" {
return fmt.Errorf("checking for presence of existing %s: %+v", d.Id(), err)
}
}

state.Name = credentialId.CredentialName

if existing.Model.Properties.Description != nil {
bruceharrison1984 marked this conversation as resolved.
Show resolved Hide resolved
state.Description = *existing.Model.Properties.Description
}

if existing.Model.Properties.TypeProperties.ResourceId != nil {
bruceharrison1984 marked this conversation as resolved.
Show resolved Hide resolved
state.IdentityId = *existing.Model.Properties.TypeProperties.ResourceId
}

state.DataFactoryId = factories.NewFactoryID(credentialId.SubscriptionId, credentialId.ResourceGroupName, credentialId.FactoryName).ID()
state.Annotations = flattenDataFactoryAnnotations(existing.Model.Properties.Annotations)

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

func (r DataFactoryCredentialUserAssignedManagedIdentityResource) Create() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 5 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
client := metadata.Client.DataFactory.Credentials

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

dataFactoryId, err := credentials.ParseFactoryID(data.DataFactoryId)
if err != nil {
return err
}

id := credentials.CredentialId{
SubscriptionId: dataFactoryId.SubscriptionId,
ResourceGroupName: dataFactoryId.ResourceGroupName,
FactoryName: dataFactoryId.FactoryName,
CredentialName: data.Name,
}

existing, err := client.CredentialOperationsGet(ctx, id, credentials.CredentialOperationsGetOperationOptions{})
if err != nil {
if existing.HttpResponse.Status == "404" {
bruceharrison1984 marked this conversation as resolved.
Show resolved Hide resolved
return fmt.Errorf("checking for presence of existing %s: %+v", id, err)
}
}
if existing.HttpResponse.Status == "404" {
bruceharrison1984 marked this conversation as resolved.
Show resolved Hide resolved
return tf.ImportAsExistsError("azurerm_data_factory_dataset_http", id.ID())
}

credential := credentials.ManagedIdentityCredentialResource{
Type: utils.String(IDENTITY_TYPE),
Properties: credentials.ManagedIdentityCredential{
TypeProperties: &credentials.ManagedIdentityTypeProperties{},
},
}

if len(data.Annotations) > 0 {
annotations := make([]interface{}, len(data.Annotations))
for i, v := range data.Annotations {
annotations[i] = v
}
credential.Properties.Annotations = &annotations
}

if data.Description != "" {
credential.Properties.Description = &data.Description
}

if data.IdentityId != "" {
bruceharrison1984 marked this conversation as resolved.
Show resolved Hide resolved
credential.Properties.TypeProperties.ResourceId = &data.IdentityId
}

_, err = client.CredentialOperationsCreateOrUpdate(ctx, id, credential, credentials.CredentialOperationsCreateOrUpdateOperationOptions{})
if err != nil {
return fmt.Errorf("creating %s: %+v", id, err)
}

metadata.SetID(id)

return nil
},
}
}

func (r DataFactoryCredentialUserAssignedManagedIdentityResource) Update() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 5 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
client := metadata.Client.DataFactory.Credentials
id, err := credentials.ParseCredentialID(metadata.ResourceData.Id())
if err != nil {
return err
}

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

existing, err := client.CredentialOperationsGet(ctx, *id, credentials.CredentialOperationsGetOperationOptions{})
if err != nil {
if existing.HttpResponse.Status == "404" {
bruceharrison1984 marked this conversation as resolved.
Show resolved Hide resolved
return fmt.Errorf("checking for presence of existing %s: %+v", id.ID(), err)
}
}

credential := credentials.ManagedIdentityCredentialResource{
bruceharrison1984 marked this conversation as resolved.
Show resolved Hide resolved
Type: existing.Model.Type,
Name: existing.Model.Name,
Id: existing.Model.Id,
Properties: credentials.ManagedIdentityCredential{
Annotations: existing.Model.Properties.Annotations,
Description: existing.Model.Properties.Description,
TypeProperties: &credentials.ManagedIdentityTypeProperties{
ResourceId: existing.Model.Properties.TypeProperties.ResourceId,
},
},
}

if metadata.ResourceData.HasChange("name") {
bruceharrison1984 marked this conversation as resolved.
Show resolved Hide resolved
credential.Name = &data.Name
}

if metadata.ResourceData.HasChange("identity_id") {
bruceharrison1984 marked this conversation as resolved.
Show resolved Hide resolved
credential.Properties.TypeProperties.ResourceId = &data.IdentityId
}

if metadata.ResourceData.HasChange("description") {
credential.Properties.Description = &data.Description
}

if metadata.ResourceData.HasChange("annotations") {
if len(data.Annotations) > 0 {
annotations := make([]interface{}, len(data.Annotations))
for i, v := range data.Annotations {
annotations[i] = v
}
credential.Properties.Annotations = &annotations
} else {
credential.Properties.Annotations = nil
}
}

_, err = client.CredentialOperationsCreateOrUpdate(ctx, *id, credential, credentials.CredentialOperationsCreateOrUpdateOperationOptions{})
if err != nil {
return fmt.Errorf("updating %s: %+v", id, err)
}

metadata.SetID(id)

return nil
},
}
}

func (DataFactoryCredentialUserAssignedManagedIdentityResource) Delete() sdk.ResourceFunc {
return sdk.ResourceFunc{
Timeout: 5 * time.Minute,
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error {
d := metadata.ResourceData
client := metadata.Client.DataFactory.Credentials

credentialId, err := credentials.ParseCredentialID(d.Id())
if err != nil {
return err
}

_, err = client.CredentialOperationsDelete(ctx, *credentialId)
if err != nil {
return err
}

return nil
},
}
}
Loading
Loading