Skip to content

Commit

Permalink
Enhance - azurerm_api_management_api - support contact, license (
Browse files Browse the repository at this point in the history
…#18472)

Co-authored-by: xuzhang3 <Zhangxu894765>
  • Loading branch information
xuzhang3 authored Oct 12, 2022
1 parent 0625970 commit 3c3d494
Show file tree
Hide file tree
Showing 5 changed files with 294 additions and 0 deletions.
139 changes: 139 additions & 0 deletions internal/services/apimanagement/api_management_api_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,32 @@ func resourceApiManagementApi() *pluginsdk.Resource {
}, false),
},

"contact": {
Type: pluginsdk.TypeList,
Optional: true,
MinItems: 1,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"email": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: validate.EmailAddress,
},
"name": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: validation.StringIsNotEmpty,
},
"url": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: validation.IsURLWithHTTPorHTTPS,
},
},
},
},

"description": {
Type: pluginsdk.TypeString,
Optional: true,
Expand Down Expand Up @@ -158,6 +184,27 @@ func resourceApiManagementApi() *pluginsdk.Resource {
},
},

"license": {
Type: pluginsdk.TypeList,
Optional: true,
MinItems: 1,
MaxItems: 1,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: validation.StringIsNotEmpty,
},
"url": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: validation.IsURLWithHTTPorHTTPS,
},
},
},
},

"service_url": {
Type: pluginsdk.TypeString,
Optional: true,
Expand Down Expand Up @@ -191,6 +238,12 @@ func resourceApiManagementApi() *pluginsdk.Resource {
Default: true,
},

"terms_of_service_url": {
Type: pluginsdk.TypeString,
Optional: true,
ValidateFunc: validation.IsURLWithHTTPorHTTPS,
},

"source_api_id": {
Type: pluginsdk.TypeString,
Optional: true,
Expand Down Expand Up @@ -413,6 +466,12 @@ func resourceApiManagementApiCreateUpdate(d *pluginsdk.ResourceData, meta interf
openIDAuthorizationSettings := expandApiManagementOpenIDAuthenticationSettingsContract(openIDAuthorizationSettingsRaw)
authenticationSettings.Openid = openIDAuthorizationSettings

contactInfoRaw := d.Get("contact").([]interface{})
contactInfo := expandApiManagementApiContact(contactInfoRaw)

licenseInfoRaw := d.Get("license").([]interface{})
licenseInfo := expandApiManagementApiLicense(licenseInfoRaw)

params := apimanagement.APICreateOrUpdateParameter{
APICreateOrUpdateProperties: &apimanagement.APICreateOrUpdateProperties{
APIType: apiType,
Expand All @@ -427,6 +486,8 @@ func resourceApiManagementApiCreateUpdate(d *pluginsdk.ResourceData, meta interf
AuthenticationSettings: authenticationSettings,
APIRevisionDescription: utils.String(d.Get("revision_description").(string)),
APIVersionDescription: utils.String(d.Get("version_description").(string)),
Contact: contactInfo,
License: licenseInfo,
},
}

Expand All @@ -442,6 +503,10 @@ func resourceApiManagementApiCreateUpdate(d *pluginsdk.ResourceData, meta interf
params.APICreateOrUpdateProperties.APIVersionSetID = utils.String(versionSetId)
}

if v, ok := d.GetOk("terms_of_service_url"); ok {
params.APICreateOrUpdateProperties.TermsOfServiceURL = utils.String(v.(string))
}

future, err := client.CreateOrUpdate(ctx, id.ResourceGroup, id.ServiceName, apiId, params, "")
if err != nil {
return fmt.Errorf("creating/updating %s: %+v", id, err)
Expand Down Expand Up @@ -508,6 +573,7 @@ func resourceApiManagementApiRead(d *pluginsdk.ResourceData, meta interface{}) e
d.Set("version_set_id", props.APIVersionSetID)
d.Set("revision_description", props.APIRevisionDescription)
d.Set("version_description", props.APIVersionDescription)
d.Set("terms_of_service_url", props.TermsOfServiceURL)

if err := d.Set("protocols", flattenApiManagementApiProtocols(props.Protocols)); err != nil {
return fmt.Errorf("setting `protocols`: %s", err)
Expand All @@ -524,6 +590,14 @@ func resourceApiManagementApiRead(d *pluginsdk.ResourceData, meta interface{}) e
if err := d.Set("openid_authentication", flattenApiManagementOpenIDAuthentication(props.AuthenticationSettings.Openid)); err != nil {
return fmt.Errorf("setting `openid_authentication`: %+v", err)
}

if err := d.Set("contact", flattenApiManagementApiContact(props.Contact)); err != nil {
return fmt.Errorf("setting `contact`: %+v", err)
}

if err := d.Set("license", flattenApiManagementApiLicense(props.License)); err != nil {
return fmt.Errorf("setting `license`: %+v", err)
}
}

return nil
Expand Down Expand Up @@ -694,3 +768,68 @@ func flattenApiManagementOpenIDAuthentication(input *apimanagement.OpenIDAuthent

return []interface{}{result}
}

func expandApiManagementApiContact(input []interface{}) *apimanagement.APIContactInformation {
if len(input) == 0 {
return nil
}

v := input[0].(map[string]interface{})
return &apimanagement.APIContactInformation{
Email: utils.String(v["email"].(string)),
Name: utils.String(v["name"].(string)),
URL: utils.String(v["url"].(string)),
}
}

func flattenApiManagementApiContact(contact *apimanagement.APIContactInformation) []interface{} {
if contact == nil {
return make([]interface{}, 0)
}

result := make(map[string]interface{})

if contact.Email != nil {
result["email"] = *contact.Email
}

if contact.Name != nil {
result["name"] = *contact.Name
}

if contact.URL != nil {
result["url"] = *contact.URL
}

return []interface{}{result}
}

func expandApiManagementApiLicense(input []interface{}) *apimanagement.APILicenseInformation {
if len(input) == 0 {
return nil
}

v := input[0].(map[string]interface{})
return &apimanagement.APILicenseInformation{
Name: utils.String(v["name"].(string)),
URL: utils.String(v["url"].(string)),
}
}

func flattenApiManagementApiLicense(license *apimanagement.APILicenseInformation) []interface{} {
if license == nil {
return make([]interface{}, 0)
}

result := make(map[string]interface{})

if license.Name != nil {
result["name"] = *license.Name
}

if license.URL != nil {
result["url"] = *license.URL
}

return []interface{}{result}
}
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,21 @@ func TestAccApiManagementApi_createRevisionFromExistingRevision(t *testing.T) {
})
}

func TestAccApiManagementApi_contact(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_api_management_api", "test")
r := ApiManagementApiResource{}

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

func (ApiManagementApiResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
id, err := parse.ApiID(state.ID)
if err != nil {
Expand Down Expand Up @@ -610,6 +625,19 @@ resource "azurerm_api_management_api" "test" {
header = "X-Butter-Robot-API-Key"
query = "location"
}
contact {
email = "test@test.com"
name = "test"
url = "https://example:8080"
}
license {
name = "test-license"
url = "https://example:8080/license"
}
terms_of_service_url = "https://example:8080/service"
}
`, r.template(data, SkuNameConsumption), data.RandomInteger)
}
Expand Down Expand Up @@ -779,10 +807,51 @@ resource "azurerm_api_management_api" "revision" {
revision = "18"
source_api_id = "${azurerm_api_management_api.test.id};rev=3"
revision_description = "Creating a Revision of an existing API"
contact {
email = "test@test.com"
name = "test"
url = "https://example:8080"
}
license {
name = "test-license"
url = "https://example:8080/license"
}
terms_of_service_url = "https://example:8080/service"
}
`, r.complete(data), data.RandomInteger)
}

func (r ApiManagementApiResource) contact(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_api_management_api" "test" {
name = "acctestapi-%d"
resource_group_name = azurerm_resource_group.test.name
api_management_name = azurerm_api_management.test.name
display_name = "api1"
path = "api1"
protocols = ["https"]
revision = "1"
contact {
email = "test@test.com"
name = "test"
url = "https://example:8080"
}
license {
name = "test-license"
url = "https://example:8080/license"
}
terms_of_service_url = "https://example:8080/service"
}
`, r.template(data, SkuNameConsumption), data.RandomInteger)
}

func (ApiManagementApiResource) template(data acceptance.TestData, skuName string) string {
return fmt.Sprintf(`
provider "azurerm" {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package validate

import (
"fmt"
"regexp"
)

func EmailAddress(v interface{}, k string) (warnings []string, errors []error) {
value := v.(string)

if matched := regexp.MustCompile(`^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$`).Match([]byte(value)); !matched {
errors = append(errors, fmt.Errorf("test: %s, %q is not an valida email address", k, v))
}
return warnings, errors
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package validate

import "testing"

func TestEmailAddress(t *testing.T) {
testData := []struct {
Value string
Error bool
}{
{
Value: "a",
Error: true,
},
{
Value: "abc",
Error: true,
},
{
Value: "123",
Error: true,
},
{
Value: "test.com",
Error: true,
},
{
Value: "test@.com",
Error: true,
},
{
Value: "test.com",
Error: true,
},
{
Value: "test@test.com",
Error: false,
},
}
for _, v := range testData {
t.Logf("[DEBUG] Testing %q", v.Value)

_, err := EmailAddress(v.Value, "unit test")
if err != nil && !v.Error {
t.Fatalf("Expected pass but got an error: %s", err)
}
}
}
Loading

0 comments on commit 3c3d494

Please sign in to comment.