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_api_management: introduction of the delegation block #20399

Merged
merged 12 commits into from
Feb 17, 2023
125 changes: 125 additions & 0 deletions internal/services/apimanagement/api_management_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,34 @@ func resourceApiManagementSchema() map[string]*pluginsdk.Schema {
},
},

"delegation": {
Type: pluginsdk.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"subscriptions_enabled": {
Type: pluginsdk.TypeBool,
Required: true,
},
"user_registration_enabled": {
Type: pluginsdk.TypeBool,
Required: true,
},
"url": {
Type: pluginsdk.TypeString,
Required: true,
},
"validation_key": {
Type: pluginsdk.TypeString,
Optional: true,
Sensitive: true,
},
},
},
},

"sign_up": {
Type: pluginsdk.TypeList,
Optional: true,
Expand Down Expand Up @@ -908,6 +936,18 @@ func resourceApiManagementServiceCreateUpdate(d *pluginsdk.ResourceData, meta in
}
}

delegationSettingsRaw := d.Get("delegation").([]interface{})
if sku.Name == apimanagement.SkuTypeConsumption && len(delegationSettingsRaw) > 0 {
return fmt.Errorf("`delegation` is not support for sku tier `Consumption`")
}
if sku.Name != apimanagement.SkuTypeConsumption {
delegationSettings := expandApiManagementDelegationSettings(delegationSettingsRaw)
delegationClient := meta.(*clients.Client).ApiManagement.DelegationSettingsClient
if _, err := delegationClient.CreateOrUpdate(ctx, id.ResourceGroup, id.ServiceName, delegationSettings, ""); err != nil {
return fmt.Errorf(" setting Delegation settings for %s: %+v", id, err)
}
}

policyClient := meta.(*clients.Client).ApiManagement.PolicyClient
policiesRaw := d.Get("policy").([]interface{})
policy, err := expandApiManagementPolicies(policiesRaw)
Expand Down Expand Up @@ -951,6 +991,7 @@ func resourceApiManagementServiceRead(d *pluginsdk.ResourceData, meta interface{
client := meta.(*clients.Client).ApiManagement.ServiceClient
signInClient := meta.(*clients.Client).ApiManagement.SignInClient
signUpClient := meta.(*clients.Client).ApiManagement.SignUpClient
delegationClient := meta.(*clients.Client).ApiManagement.DelegationSettingsClient
tenantAccessClient := meta.(*clients.Client).ApiManagement.TenantAccessClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()
Expand Down Expand Up @@ -1078,9 +1119,24 @@ func resourceApiManagementServiceRead(d *pluginsdk.ResourceData, meta interface{
if err := d.Set("sign_up", flattenApiManagementSignUpSettings(signUpSettings)); err != nil {
return fmt.Errorf("setting `sign_up`: %+v", err)
}

delegationSettings, err := delegationClient.Get(ctx, id.ResourceGroup, id.ServiceName)
if err != nil {
return fmt.Errorf("retrieving Delegation Settings for %s: %+v", *id, err)
}

delegationValidationKeyContract, err := delegationClient.ListSecrets(ctx, id.ResourceGroup, id.ServiceName)
if err != nil {
return fmt.Errorf("retrieving Delegation Validation Key for %s: %+v", *id, err)
}

if err := d.Set("delegation", flattenApiManagementDelegationSettings(delegationSettings, delegationValidationKeyContract)); err != nil {
return fmt.Errorf("setting `delegation`: %+v", err)
}
} else {
d.Set("sign_in", []interface{}{})
d.Set("sign_up", []interface{}{})
d.Set("delegation", []interface{}{})
}

if resp.Sku.Name != apimanagement.SkuTypeConsumption {
Expand Down Expand Up @@ -1808,6 +1864,75 @@ func flattenApiManagementSignInSettings(input apimanagement.PortalSigninSettings
}
}

func expandApiManagementDelegationSettings(input []interface{}) apimanagement.PortalDelegationSettings {
if len(input) == 0 {
return apimanagement.PortalDelegationSettings{
PortalDelegationSettingsProperties: &apimanagement.PortalDelegationSettingsProperties{
Subscriptions: &apimanagement.SubscriptionsDelegationSettingsProperties{
Enabled: utils.Bool(false),
},
UserRegistration: &apimanagement.RegistrationDelegationSettingsProperties{
Enabled: utils.Bool(false),
},
},
}
}

vs := input[0].(map[string]interface{})

props := apimanagement.PortalDelegationSettingsProperties{
UserRegistration: &apimanagement.RegistrationDelegationSettingsProperties{
Enabled: utils.Bool(vs["user_registration_enabled"].(bool)),
},
Subscriptions: &apimanagement.SubscriptionsDelegationSettingsProperties{
Enabled: utils.Bool(vs["subscriptions_enabled"].(bool)),
},
URL: utils.String(vs["url"].(string)),
}

validationKey := vs["validation_key"].(string)
if validationKey != "" {
props.ValidationKey = utils.String(validationKey)
}

return apimanagement.PortalDelegationSettings{
PortalDelegationSettingsProperties: &props,
}
}

func flattenApiManagementDelegationSettings(input apimanagement.PortalDelegationSettings, keyContract apimanagement.PortalSettingValidationKeyContract) []interface{} {
url := ""
subscriptionsEnabled := false
userRegistrationEnabled := false

if props := input.PortalDelegationSettingsProperties; props != nil {
if props.URL != nil {
url = *props.URL
}

if props.Subscriptions != nil && props.Subscriptions.Enabled != nil {
subscriptionsEnabled = *props.Subscriptions.Enabled
}

if props.UserRegistration != nil && props.UserRegistration.Enabled != nil {
userRegistrationEnabled = *props.UserRegistration.Enabled
}
}
validationKey := ""
if keyContract.ValidationKey != nil {
validationKey = *keyContract.ValidationKey
}

return []interface{}{
map[string]interface{}{
"url": url,
"subscriptions_enabled": subscriptionsEnabled,
"user_registration_enabled": userRegistrationEnabled,
"validation_key": validationKey,
},
}
}

func expandApiManagementSignUpSettings(input []interface{}) apimanagement.PortalSignupSettings {
if len(input) == 0 {
return apimanagement.PortalSignupSettings{
Expand Down
89 changes: 89 additions & 0 deletions internal/services/apimanagement/api_management_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,36 @@ func TestAccApiManagement_signInSignUpSettings(t *testing.T) {
})
}

func TestAccApiManagement_delegationSettings(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_api_management", "test")
r := ApiManagementResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.delegationSettings(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccApiManagement_delegationSettingsComplete(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_api_management", "test")
r := ApiManagementResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.delegationSettingsComplete(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccApiManagement_policy(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_api_management", "test")
r := ApiManagementResource{}
Expand Down Expand Up @@ -1117,6 +1147,65 @@ resource "azurerm_api_management" "test" {
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

func (ApiManagementResource) delegationSettings(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_api_management" "test" {
name = "acctestAM-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
publisher_name = "pub1"
publisher_email = "[email protected]"

sku_name = "Developer_1"

delegation {
url = "https://google.com"
subscriptions_enabled = false
user_registration_enabled = true
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

func (ApiManagementResource) delegationSettingsComplete(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "test" {
name = "acctestRG-%d"
location = "%s"
}

resource "azurerm_api_management" "test" {
name = "acctestAM-%d"
location = azurerm_resource_group.test.location
resource_group_name = azurerm_resource_group.test.name
publisher_name = "pub1"
publisher_email = "[email protected]"

sku_name = "Developer_1"

delegation {
url = "https://google.com"
validation_key = "aW50ZWdyYXRpb24mMjAyMzAzMTAxODMwJkxRaUxzcUVsaUpEaHJRK01YZkJYV3paUi9qdzZDSWMrazhjUXB0bVdyTGxKcVYrd0R4OXRqMGRzTWZXU3hmeGQ0a2V0WjcrcE44U0dJdDNsYUQ3Rk5BPT0="
subscriptions_enabled = true
user_registration_enabled = true
}
}
`, data.RandomInteger, data.Locations.Primary, data.RandomInteger)
}

func (ApiManagementResource) complete(data acceptance.TestData) string {
return fmt.Sprintf(`
provider "azurerm" {
Expand Down
5 changes: 5 additions & 0 deletions internal/services/apimanagement/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Client struct {
BackendClient *apimanagement.BackendClient
CacheClient *apimanagement.CacheClient
CertificatesClient *apimanagement.CertificateClient
DelegationSettingsClient *apimanagement.DelegationSettingsClient
DeletedServicesClient *apimanagement.DeletedServicesClient
DiagnosticClient *apimanagement.DiagnosticClient
EmailTemplateClient *apimanagement.EmailTemplateClient
Expand Down Expand Up @@ -93,6 +94,9 @@ func NewClient(o *common.ClientOptions) *Client {
diagnosticClient := apimanagement.NewDiagnosticClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&diagnosticClient.Client, o.ResourceManagerAuthorizer)

delegationSettingsClient := apimanagement.NewDelegationSettingsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&delegationSettingsClient.Client, o.ResourceManagerAuthorizer)

deletedServicesClient := apimanagement.NewDeletedServicesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&deletedServicesClient.Client, o.ResourceManagerAuthorizer)

Expand Down Expand Up @@ -188,6 +192,7 @@ func NewClient(o *common.ClientOptions) *Client {
BackendClient: &backendClient,
CacheClient: &cacheClient,
CertificatesClient: &certificatesClient,
DelegationSettingsClient: &delegationSettingsClient,
DeletedServicesClient: &deletedServicesClient,
DiagnosticClient: &diagnosticClient,
EmailTemplateClient: &emailTemplateClient,
Expand Down
14 changes: 14 additions & 0 deletions website/docs/r/api_management.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ The following arguments are supported:

* `client_certificate_enabled` - (Optional) Enforce a client certificate to be presented on each request to the gateway? This is only supported when SKU type is `Consumption`.

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

* `gateway_disabled` - (Optional) Disable the gateway in main region? This is only supported when `additional_location` is set.

* `min_api_version` - (Optional) The version which the control plane API calls to API Management service are limited with version equal to or newer than.
Expand Down Expand Up @@ -135,6 +137,18 @@ A `certificate` block supports the following:

---

A `delegation` block supports the following:

* `subscriptions_enabled` - (Required) Should subscription requests be delegated to an external url?

* `user_registration_enabled` - (Required) Should user registration requests be delegated to an external url?

* `url` - (Required) The delegation URL.

* `validation_key` - (Optional) A base64-encoded validation key to validate, that a request is coming from Azure API Management.

---

A `hostname_configuration` block supports the following:

* `management` - (Optional) One or more `management` blocks as documented below.
Expand Down