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

azurerm_spring_cloud_gateway - support for the client_authentication property #22016

Merged
merged 4 commits into from
Jun 13, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
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
63 changes: 63 additions & 0 deletions internal/services/springcloud/spring_cloud_gateway_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,29 @@ func resourceSpringCloudGateway() *pluginsdk.Resource {
},
},

"client_auth": {
Type: pluginsdk.TypeList,
Optional: true,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"certificate_ids": {
Type: pluginsdk.TypeList,
Optional: true,
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeString,
ValidateFunc: validate.SpringCloudCertificateID,
},
},

"verification_enabled": {
Type: pluginsdk.TypeBool,
Optional: true,
},
},
},
},

"cors": {
Type: pluginsdk.TypeList,
Optional: true,
Expand Down Expand Up @@ -315,6 +338,7 @@ func resourceSpringCloudGatewayCreateUpdate(d *pluginsdk.ResourceData, meta inte

gatewayResource := appplatform.GatewayResource{
Properties: &appplatform.GatewayProperties{
ClientAuth: expandGatewayClientAuth(d.Get("client_auth").([]interface{})),
APIMetadataProperties: expandGatewayGatewayAPIMetadataProperties(d.Get("api_metadata").([]interface{})),
ApmTypes: expandGatewayGatewayApmTypes(d.Get("application_performance_monitoring_types").([]interface{})),
CorsProperties: expandGatewayGatewayCorsProperties(d.Get("cors").([]interface{})),
Expand Down Expand Up @@ -375,6 +399,9 @@ func resourceSpringCloudGatewayRead(d *pluginsdk.ResourceData, meta interface{})
if err := d.Set("application_performance_monitoring_types", flattenGatewayGatewayApmTypess(props.ApmTypes)); err != nil {
return fmt.Errorf("setting `application_performance_monitoring_types`: %+v", err)
}
if err := d.Set("client_auth", flattenGatewayClientAuth(props.ClientAuth)); err != nil {
return fmt.Errorf("setting `client_auth`: %+v", err)
}
if err := d.Set("cors", flattenGatewayGatewayCorsProperties(props.CorsProperties)); err != nil {
return fmt.Errorf("setting `cors`: %+v", err)
}
Expand Down Expand Up @@ -492,6 +519,21 @@ func expandGatewayGatewayEnvironmentVariables(env map[string]interface{}, secret
}
}

func expandGatewayClientAuth(input []interface{}) *appplatform.GatewayPropertiesClientAuth {
if len(input) == 0 {
return nil
}
v := input[0].(map[string]interface{})
verificationEnabled := appplatform.GatewayCertificateVerificationDisabled
if v["verification_enabled"].(bool) {
verificationEnabled = appplatform.GatewayCertificateVerificationEnabled
}
return &appplatform.GatewayPropertiesClientAuth{
Certificates: utils.ExpandStringSlice(v["certificate_ids"].([]interface{})),
CertificateVerification: verificationEnabled,
}
}

func flattenGatewayGatewayAPIMetadataProperties(input *appplatform.GatewayAPIMetadataProperties) []interface{} {
if input == nil {
return make([]interface{}, 0)
Expand Down Expand Up @@ -621,3 +663,24 @@ func flattenGatewayGatewayApmTypess(input *[]appplatform.ApmType) []interface{}
}
return out
}

func flattenGatewayClientAuth(input *appplatform.GatewayPropertiesClientAuth) []interface{} {
if input == nil || input.Certificates == nil || len(*input.Certificates) == 0 {
return make([]interface{}, 0)
}
certificateIds := make([]string, 0)
if input.Certificates != nil {
for _, v := range *input.Certificates {
certId, err := parse.SpringCloudCertificateIDInsensitively(v)
if err == nil {
certificateIds = append(certificateIds, certId.ID())
}
}
}
return []interface{}{
map[string]interface{}{
"certificate_ids": certificateIds,
"verification_enabled": input.CertificateVerification == appplatform.GatewayCertificateVerificationEnabled,
},
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,20 @@ func TestAccSpringCloudGateway_complete(t *testing.T) {
})
}

func TestAccSpringCloudGateway_clientAuth(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_spring_cloud_gateway", "test")
r := SpringCloudGatewayResource{}
data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.clientAuth(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccSpringCloudGateway_update(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_spring_cloud_gateway", "test")
clientId := os.Getenv("ARM_CLIENT_ID")
Expand Down Expand Up @@ -108,7 +122,12 @@ func (r SpringCloudGatewayResource) Exists(ctx context.Context, client *clients.
func (r SpringCloudGatewayResource) template(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
features {
key_vault {
purge_soft_delete_on_destroy = false
purge_soft_deleted_keys_on_destroy = false
}
}
}

resource "azurerm_resource_group" "test" {
Expand Down Expand Up @@ -204,3 +223,120 @@ resource "azurerm_spring_cloud_gateway" "test" {
}
`, template, clientId, clientSecret)
}

func (r SpringCloudGatewayResource) clientAuth(data acceptance.TestData) string {
template := r.template(data)
return fmt.Sprintf(`
%s

data "azurerm_client_config" "current" {
}

data "azuread_service_principal" "test" {
display_name = "Azure Spring Cloud Resource Provider"
}

resource "azurerm_key_vault" "test" {
name = "acctest-kv-%[2]d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"

access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id

secret_permissions = [
"Set",
]

certificate_permissions = [
"Create",
"Delete",
"Get",
"Purge",
"Update",
]
}

access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azuread_service_principal.test.object_id

secret_permissions = [
"Get",
"List",
]

certificate_permissions = [
"Get",
"List",
]
}
}

resource "azurerm_key_vault_certificate" "test" {
name = "acctest-cert-%[2]d"
key_vault_id = azurerm_key_vault.test.id

certificate_policy {
issuer_parameters {
name = "Self"
}

key_properties {
exportable = true
key_size = 2048
key_type = "RSA"
reuse_key = true
}

lifetime_action {
action {
action_type = "AutoRenew"
}

trigger {
days_before_expiry = 30
}
}

secret_properties {
content_type = "application/x-pkcs12"
}

x509_certificate_properties {
key_usage = [
"cRLSign",
"dataEncipherment",
"digitalSignature",
"keyAgreement",
"keyCertSign",
"keyEncipherment",
]

subject = "CN=contoso.com"
validity_in_months = 12
}
}
}

resource "azurerm_spring_cloud_certificate" "test" {
name = "acctest-scc-%[2]d"
resource_group_name = azurerm_spring_cloud_service.test.resource_group_name
service_name = azurerm_spring_cloud_service.test.name
key_vault_certificate_id = azurerm_key_vault_certificate.test.id
exclude_private_key = true
}

resource "azurerm_spring_cloud_gateway" "test" {
name = "default"
spring_cloud_service_id = azurerm_spring_cloud_service.test.id
client_auth {
certificate_ids = [azurerm_spring_cloud_certificate.test.id]
verification_enabled = true
}
}
`, template, data.RandomIntOfLength(10))
}
10 changes: 10 additions & 0 deletions website/docs/r/spring_cloud_gateway.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ The following arguments are supported:

* `application_performance_monitoring_types` - (Optional) Specifies a list of application performance monitoring types used in the Spring Cloud Gateway. The allowed values are `AppDynamics`, `ApplicationInsights`, `Dynatrace`, `ElasticAPM` and `NewRelic`.

* `client_auth` - (Optional) A `client_auth` block as defined below.
ms-henglu marked this conversation as resolved.
Show resolved Hide resolved

* `cors` - (Optional) A `cors` block as defined below.

* `environment_variables` - (Optional) Specifies the environment variables of the Spring Cloud Gateway as a map of key-value pairs. Changing this forces a new resource to be created.
Expand Down Expand Up @@ -116,6 +118,14 @@ A `api_metadata` block supports the following:

---

A `client_auth` block supports the following:

* `certificate_ids` - (Optional) Specifies the Spring Cloud Certificate IDs of the Spring Cloud Gateway.

* `verification_enabled` - (Optional) Specifies whether the client certificate verification is enabled.

---

A `cors` block supports the following:

* `credentials_allowed` - (Optional) is user credentials are supported on cross-site requests?
Expand Down