Skip to content

Commit

Permalink
New Resource: azurerm_spring_cloud_connection and `azurerm_app_serv…
Browse files Browse the repository at this point in the history
…ice_connection` (#16907)

New Resource: `azurerm_spring_cloud_connection` and `azurerm_app_service_connection`
  • Loading branch information
jiaweitao001 authored Aug 30, 2022
1 parent 04e8fae commit 61db9d4
Show file tree
Hide file tree
Showing 77 changed files with 5,053 additions and 0 deletions.
1 change: 1 addition & 0 deletions .teamcity/components/generated/services.kt
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ var services = mapOf(
"servicefabric" to "Service Fabric",
"servicefabricmanaged" to "Service Fabric Managed Clusters",
"servicebus" to "ServiceBus",
"serviceconnector" to "ServiceConnector",
"signalr" to "SignalR",
"springcloud" to "Spring Cloud",
"storage" to "Storage",
Expand Down
3 changes: 3 additions & 0 deletions internal/clients/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ import (
securityCenter "github.com/hashicorp/terraform-provider-azurerm/internal/services/securitycenter/client"
sentinel "github.com/hashicorp/terraform-provider-azurerm/internal/services/sentinel/client"
serviceBus "github.com/hashicorp/terraform-provider-azurerm/internal/services/servicebus/client"
serviceConnector "github.com/hashicorp/terraform-provider-azurerm/internal/services/serviceconnector/client"
serviceFabric "github.com/hashicorp/terraform-provider-azurerm/internal/services/servicefabric/client"
serviceFabricManaged "github.com/hashicorp/terraform-provider-azurerm/internal/services/servicefabricmanaged/client"
signalr "github.com/hashicorp/terraform-provider-azurerm/internal/services/signalr/client"
Expand Down Expand Up @@ -213,6 +214,7 @@ type Client struct {
SecurityCenter *securityCenter.Client
Sentinel *sentinel.Client
ServiceBus *serviceBus.Client
ServiceConnector *serviceConnector.Client
ServiceFabric *serviceFabric.Client
ServiceFabricManaged *serviceFabricManaged.Client
SignalR *signalr.Client
Expand Down Expand Up @@ -329,6 +331,7 @@ func (client *Client) Build(ctx context.Context, o *common.ClientOptions) error
client.SecurityCenter = securityCenter.NewClient(o)
client.Sentinel = sentinel.NewClient(o)
client.ServiceBus = serviceBus.NewClient(o)
client.ServiceConnector = serviceConnector.NewClient(o)
client.ServiceFabric = serviceFabric.NewClient(o)
client.ServiceFabricManaged = serviceFabricManaged.NewClient(o)
client.SignalR = signalr.NewClient(o)
Expand Down
2 changes: 2 additions & 0 deletions internal/provider/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ import (
"github.com/hashicorp/terraform-provider-azurerm/internal/services/securitycenter"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/sentinel"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/servicebus"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/serviceconnector"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/servicefabric"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/servicefabricmanaged"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/signalr"
Expand Down Expand Up @@ -139,6 +140,7 @@ func SupportedTypedServices() []sdk.TypedServiceRegistration {
recoveryservices.Registration{},
resource.Registration{},
sentinel.Registration{},
serviceconnector.Registration{},
servicefabricmanaged.Registration{},
streamanalytics.Registration{},
web.Registration{},
Expand Down
25 changes: 25 additions & 0 deletions internal/services/serviceconnector/client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package client

import (
"github.com/hashicorp/go-azure-sdk/resource-manager/servicelinker/2022-05-01/links"
"github.com/hashicorp/go-azure-sdk/resource-manager/servicelinker/2022-05-01/servicelinker"
"github.com/hashicorp/terraform-provider-azurerm/internal/common"
)

type Client struct {
ServiceLinkerClient *servicelinker.ServicelinkerClient
LinksClient *links.LinksClient
}

func NewClient(o *common.ClientOptions) *Client {
serviceLinkerClient := servicelinker.NewServicelinkerClientWithBaseURI(o.ResourceManagerEndpoint)
o.ConfigureClient(&serviceLinkerClient.Client, o.ResourceManagerAuthorizer)

linksClient := links.NewLinksClientWithBaseURI(o.ResourceManagerEndpoint)
o.ConfigureClient(&linksClient.Client, o.ResourceManagerAuthorizer)

return &Client{
ServiceLinkerClient: &serviceLinkerClient,
LinksClient: &linksClient,
}
}
277 changes: 277 additions & 0 deletions internal/services/serviceconnector/helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
package serviceconnector

import (
"fmt"

"github.com/hashicorp/go-azure-sdk/resource-manager/servicelinker/2022-05-01/servicelinker"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"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 AuthInfoModel struct {
Type string `tfschema:"type"`
Name string `tfschema:"name"`
Secret string `tfschema:"secret"`
ClientId string `tfschema:"client_id"`
PrincipalId string `tfschema:"principal_id"`
SubscriptionId string `tfschema:"subscription_id"`
Certificate string `tfschema:"certificate"`
}

func authInfoSchema() *pluginsdk.Schema {
return &pluginsdk.Schema{
Type: pluginsdk.TypeList,
Required: true,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: pluginsdk.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
string(servicelinker.AuthTypeSecret),
string(servicelinker.AuthTypeServicePrincipalSecret),
string(servicelinker.AuthTypeServicePrincipalCertificate),
string(servicelinker.AuthTypeSystemAssignedIdentity),
string(servicelinker.AuthTypeUserAssignedIdentity),
}, false),
},

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

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

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

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

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

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

func expandServiceConnectorAuthInfo(input []AuthInfoModel) (servicelinker.AuthInfoBase, error) {
if len(input) == 0 {
return nil, fmt.Errorf("authentication should be defined")
}
v := input[0]

authType := servicelinker.AuthType(v.Type)
name := v.Name
secret := v.Secret
clientId := v.ClientId
subscriptionId := v.SubscriptionId
principalId := v.PrincipalId
certificate := v.Certificate

switch authType {
case servicelinker.AuthTypeSecret:
if clientId != "" {
return nil, fmt.Errorf("`client_id` cannot be set when `type` is set to `Secret`")
}
if subscriptionId != "" {
return nil, fmt.Errorf("`subscription_id` cannot be set when `type` is set to `Secret`")
}
if principalId != "" {
return nil, fmt.Errorf("`principal_id` cannot be set when `type` is set to `Secret`")
}
if certificate != "" {
return nil, fmt.Errorf("`certificate` cannot be set when `type` is set to `Secret`")
}
if name != "" && secret == "" {
return nil, fmt.Errorf("`name` cannot be set when `secret` is empty")
}
if name == "" && secret != "" {
return nil, fmt.Errorf("`secret` cannot be set when `name` is empty")
}
return servicelinker.SecretAuthInfo{
Name: utils.String(name),
SecretInfo: secret,
}, nil

case servicelinker.AuthTypeSystemAssignedIdentity:
if name != "" || secret != "" || clientId != "" || subscriptionId != "" || principalId != "" || certificate != "" {
return nil, fmt.Errorf("no other parameters should be set when `type` is set to `SystemIdentity`")
}
return servicelinker.SystemAssignedIdentityAuthInfo{}, nil

case servicelinker.AuthTypeServicePrincipalSecret:
if clientId == "" {
return nil, fmt.Errorf("`client_id` must be specified when `type` is set to `ServicePrincipal`")
}
if principalId == "" {
return nil, fmt.Errorf("`principal_id` must be specified when `type` is set to `ServicePrincipal`")
}
if secret == "" {
return nil, fmt.Errorf("`secret` must be specified when `type` is set to `ServicePrincipal`")
}
if subscriptionId != "" {
return nil, fmt.Errorf("`subscription_id` cannot be set when `type` is set to `ServicePrincipal`")
}
if name != "" {
return nil, fmt.Errorf("`name` cannot be set when `type` is set to `ServicePrincipal`")
}
if certificate != "" {
return nil, fmt.Errorf("`certificate` cannot be set when `type` is set to `ServicePrincipal`")
}
return servicelinker.ServicePrincipalSecretAuthInfo{
ClientId: clientId,
PrincipalId: principalId,
Secret: secret,
}, nil

case servicelinker.AuthTypeServicePrincipalCertificate:
if clientId == "" {
return nil, fmt.Errorf("`client_id` must be specified when `type` is set to `ServicePrincipalCertificate`")
}
if principalId == "" {
return nil, fmt.Errorf("`principal_id` must be specified when `type` is set to `ServicePrincipalCertificate`")
}
if certificate == "" {
return nil, fmt.Errorf("`certificate` must be specified when `type` is set to `ServicePrincipalCertificate`")
}
if subscriptionId != "" {
return nil, fmt.Errorf("`subscription_id` cannot be set when `type` is set to `ServicePrincipalCertificate`")
}
if name != "" {
return nil, fmt.Errorf("`name` cannot be set when `type` is set to `ServicePrincipalCertificate`")
}
if secret != "" {
return nil, fmt.Errorf("`secret` cannot be set when `type` is set to `ServicePrincipalCertificate`")
}
return servicelinker.ServicePrincipalCertificateAuthInfo{
Certificate: certificate,
ClientId: clientId,
PrincipalId: principalId,
}, nil

case servicelinker.AuthTypeUserAssignedIdentity:
if principalId != "" {
return nil, fmt.Errorf("`principal_id` cannot be set when `type` is set to `UserIdentity`")
}
if certificate != "" {
return nil, fmt.Errorf("`certificate` cannot be set when `type` is set to `UserIdentity`")
}
if name != "" {
return nil, fmt.Errorf("`name` cannot be set when `type` is set to `UserIdentity`")
}
if secret != "" {
return nil, fmt.Errorf("`secret` cannot be set when `type` is set to `UserIdentity`")
}
if clientId == "" && subscriptionId != "" {
return nil, fmt.Errorf("`subscription_id` cannot be set when `client_id` is empty")
}
if clientId != "" && subscriptionId == "" {
return nil, fmt.Errorf("`client_id` cannot be set when `subscription_id` is empty")
}
return servicelinker.UserAssignedIdentityAuthInfo{
ClientId: utils.String(clientId),
SubscriptionId: utils.String(subscriptionId),
}, nil
}

return nil, fmt.Errorf("unsupported authentication type %q", authType)
}

func flattenServiceConnectorAuthInfo(input servicelinker.AuthInfoBase) []AuthInfoModel {
var authType string
var name string
var secret string
var clientId string
var principalId string
var subscriptionId string
var certificate string

if value, ok := input.(servicelinker.SecretAuthInfo); ok {
authType = string(servicelinker.AuthTypeSecret)
if value.Name != nil {
name = *value.Name
}
secret = value.SecretInfo.(string)
}

if _, ok := input.(servicelinker.SystemAssignedIdentityAuthInfo); ok {
authType = string(servicelinker.AuthTypeSystemAssignedIdentity)
}

if value, ok := input.(servicelinker.UserAssignedIdentityAuthInfo); ok {
authType = string(servicelinker.AuthTypeUserAssignedIdentity)
if value.ClientId != nil {
clientId = *value.ClientId
}
if value.SubscriptionId != nil {
subscriptionId = *value.SubscriptionId
}
}

if value, ok := input.(servicelinker.ServicePrincipalSecretAuthInfo); ok {
authType = string(servicelinker.AuthTypeServicePrincipalSecret)
clientId = value.ClientId
principalId = value.PrincipalId
secret = value.Secret
}

if value, ok := input.(servicelinker.ServicePrincipalCertificateAuthInfo); ok {
authType = string(servicelinker.AuthTypeServicePrincipalCertificate)
certificate = value.Certificate
clientId = value.ClientId
principalId = value.PrincipalId
}

return []AuthInfoModel{
{
Type: authType,
Name: name,
Secret: secret,
ClientId: clientId,
PrincipalId: principalId,
SubscriptionId: subscriptionId,
Certificate: certificate,
},
}
}

//TODO: Only support Azure resource for now. Will include ConfluentBootstrapServer and ConfluentSchemaRegistry in the future.
func flattenTargetService(input servicelinker.TargetServiceBase) string {
var targetServiceId string

if value, ok := input.(servicelinker.AzureResource); ok {
if value.Id != nil {
targetServiceId = *value.Id
}
}

return targetServiceId
}
28 changes: 28 additions & 0 deletions internal/services/serviceconnector/registration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package serviceconnector

import (
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk"
)

type Registration struct{}

var _ sdk.TypedServiceRegistration = Registration{}

func (r Registration) WebsiteCategories() []string {
return []string{}
}

func (r Registration) DataSources() []sdk.DataSource {
return []sdk.DataSource{}
}

func (r Registration) Resources() []sdk.Resource {
return []sdk.Resource{
AppServiceConnectorResource{},
SpringCloudConnectorResource{},
}
}

func (r Registration) Name() string {
return "ServiceConnector"
}
Loading

0 comments on commit 61db9d4

Please sign in to comment.