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 Data Source/Resource: azurerm_cdn_frontdoor_profile #17061

Merged
merged 7 commits into from
Jun 2, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
169 changes: 169 additions & 0 deletions internal/services/cdn/azuresdkhacks/cdn_frontdoor_route.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package azuresdkhacks

import (
"context"
"encoding/json"
"net/http"

"github.com/Azure/azure-sdk-for-go/services/cdn/mgmt/2021-06-01/cdn"
"github.com/Azure/go-autorest/autorest"
)

// NOTE: this workaround client exists to allow the removal of `cacheConfiguration` items during update

type CdnFrontDoorRoutesWorkaroundClient struct {
sdkClient *cdn.RoutesClient
}

func NewCdnFrontDoorRoutesWorkaroundClient(client *cdn.RoutesClient) CdnFrontDoorRoutesWorkaroundClient {
return CdnFrontDoorRoutesWorkaroundClient{
sdkClient: client,
}
}

func (c *CdnFrontDoorRoutesWorkaroundClient) Update(ctx context.Context, resourceGroupName string, profileName string, endpointName string, routeName string, routeUpdateProperties RouteUpdateParameters) (result cdn.RoutesUpdateFuture, err error) {
req, err := c.UpdatePreparer(ctx, resourceGroupName, profileName, endpointName, routeName, routeUpdateProperties)
if err != nil {
err = autorest.NewErrorWithError(err, "cdn.RoutesClient", "Update", nil, "Failure preparing request")
return
}

result, err = c.sdkClient.UpdateSender(req)
if err != nil {
err = autorest.NewErrorWithError(err, "cdn.RoutesClient", "Update", result.Response(), "Failure sending request")
return
}

return
}

// UpdatePreparer prepares the Update request.
func (client CdnFrontDoorRoutesWorkaroundClient) UpdatePreparer(ctx context.Context, resourceGroupName string, profileName string, endpointName string, routeName string, routeUpdateProperties RouteUpdateParameters) (*http.Request, error) {
pathParameters := map[string]interface{}{
"endpointName": autorest.Encode("path", endpointName),
"profileName": autorest.Encode("path", profileName),
"resourceGroupName": autorest.Encode("path", resourceGroupName),
"routeName": autorest.Encode("path", routeName),
"subscriptionId": autorest.Encode("path", client.sdkClient.SubscriptionID),
}

const APIVersion = "2021-06-01"
queryParameters := map[string]interface{}{
"api-version": APIVersion,
}

preparer := autorest.CreatePreparer(
autorest.AsContentType("application/json; charset=utf-8"),
autorest.AsPatch(),
autorest.WithBaseURL(client.sdkClient.BaseURI),
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Cdn/profiles/{profileName}/afdEndpoints/{endpointName}/routes/{routeName}", pathParameters),
autorest.WithJSON(routeUpdateProperties),
autorest.WithQueryParameters(queryParameters))
return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// RouteUpdateParameters the domain JSON object required for domain creation or update.
type RouteUpdateParameters struct {
*RouteUpdatePropertiesParameters `json:"properties,omitempty"`
}

// MarshalJSON is the custom marshaler for RouteUpdateParameters.
func (rup RouteUpdateParameters) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})
if rup.RouteUpdatePropertiesParameters != nil {
objectMap["properties"] = rup.RouteUpdatePropertiesParameters
}
return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for RouteUpdateParameters struct.
func (rup *RouteUpdateParameters) UnmarshalJSON(body []byte) error {
var m map[string]*json.RawMessage
err := json.Unmarshal(body, &m)
if err != nil {
return err
}
for k, v := range m {
switch k { // nolint gocritic
case "properties":
if v != nil {
var routeUpdatePropertiesParameters RouteUpdatePropertiesParameters
err = json.Unmarshal(*v, &routeUpdatePropertiesParameters)
if err != nil {
return err
}

rup.RouteUpdatePropertiesParameters = &routeUpdatePropertiesParameters
}
}
}

return nil
}

// RouteUpdatePropertiesParameters the JSON object that contains the properties of the domain to create.
type RouteUpdatePropertiesParameters struct {
// EndpointName - READ-ONLY; The name of the endpoint which holds the route.
EndpointName *string `json:"endpointName,omitempty"`
// CustomDomains - Domains referenced by this endpoint.
CustomDomains *[]cdn.ActivatedResourceReference `json:"customDomains,omitempty"`
// OriginGroup - A reference to the origin group.
OriginGroup *cdn.ResourceReference `json:"originGroup,omitempty"`
// OriginPath - A directory path on the origin that AzureFrontDoor can use to retrieve content from, e.g. contoso.cloudapp.net/originpath.
OriginPath *string `json:"originPath,omitempty"`
// RuleSets - rule sets referenced by this endpoint.
RuleSets *[]cdn.ResourceReference `json:"ruleSets,omitempty"`
// SupportedProtocols - List of supported protocols for this route.
SupportedProtocols *[]cdn.AFDEndpointProtocols `json:"supportedProtocols,omitempty"`
// PatternsToMatch - The route patterns of the rule.
PatternsToMatch *[]string `json:"patternsToMatch,omitempty"`
// CacheConfiguration - The caching configuration for this route. To disable caching, do not provide a cacheConfiguration object.
CacheConfiguration *cdn.AfdRouteCacheConfiguration `json:"cacheConfiguration,omitempty"`
// ForwardingProtocol - Protocol this rule will use when forwarding traffic to backends. Possible values include: 'ForwardingProtocolHTTPOnly', 'ForwardingProtocolHTTPSOnly', 'ForwardingProtocolMatchRequest'
ForwardingProtocol cdn.ForwardingProtocol `json:"forwardingProtocol,omitempty"`
// LinkToDefaultDomain - whether this route will be linked to the default endpoint domain. Possible values include: 'LinkToDefaultDomainEnabled', 'LinkToDefaultDomainDisabled'
LinkToDefaultDomain cdn.LinkToDefaultDomain `json:"linkToDefaultDomain,omitempty"`
// HTTPSRedirect - Whether to automatically redirect HTTP traffic to HTTPS traffic. Note that this is a easy way to set up this rule and it will be the first rule that gets executed. Possible values include: 'HTTPSRedirectEnabled', 'HTTPSRedirectDisabled'
HTTPSRedirect cdn.HTTPSRedirect `json:"httpsRedirect,omitempty"`
// EnabledState - Whether to enable use of this rule. Permitted values are 'Enabled' or 'Disabled'. Possible values include: 'EnabledStateEnabled', 'EnabledStateDisabled'
EnabledState cdn.EnabledState `json:"enabledState,omitempty"`
}

// MarshalJSON is the custom marshaler for RouteUpdatePropertiesParameters.
func (rupp RouteUpdatePropertiesParameters) MarshalJSON() ([]byte, error) {
objectMap := make(map[string]interface{})

objectMap["customDomains"] = rupp.CustomDomains

if rupp.OriginGroup != nil {
objectMap["originGroup"] = rupp.OriginGroup
}
if rupp.OriginPath != nil {
objectMap["originPath"] = rupp.OriginPath
}
if rupp.RuleSets != nil {
objectMap["ruleSets"] = rupp.RuleSets
}
if rupp.SupportedProtocols != nil {
objectMap["supportedProtocols"] = rupp.SupportedProtocols
}
if rupp.PatternsToMatch != nil {
objectMap["patternsToMatch"] = rupp.PatternsToMatch
}

objectMap["cacheConfiguration"] = rupp.CacheConfiguration

if rupp.ForwardingProtocol != "" {
objectMap["forwardingProtocol"] = rupp.ForwardingProtocol
}
if rupp.LinkToDefaultDomain != "" {
objectMap["linkToDefaultDomain"] = rupp.LinkToDefaultDomain
}
if rupp.HTTPSRedirect != "" {
objectMap["httpsRedirect"] = rupp.HTTPSRedirect
}
if rupp.EnabledState != "" {
objectMap["enabledState"] = rupp.EnabledState
}
return json.Marshal(objectMap)
}
92 changes: 92 additions & 0 deletions internal/services/cdn/cdn_frontdoor_profile_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package cdn

import (
"fmt"
"time"

"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/cdn/parse"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/cdn/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/tags"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/timeouts"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

func dataSourceCdnFrontDoorProfile() *pluginsdk.Resource {
return &pluginsdk.Resource{
Read: dataSourceCdnFrontDoorProfileRead,

Timeouts: &pluginsdk.ResourceTimeout{
Read: pluginsdk.DefaultTimeout(5 * time.Minute),
},

Schema: map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validate.FrontDoorName,
},

"resource_group_name": commonschema.ResourceGroupNameForDataSource(),

"response_timeout_seconds": {
Type: pluginsdk.TypeInt,
Computed: true,
},

"sku_name": {
Type: pluginsdk.TypeString,
Computed: true,
},

"tags": commonschema.TagsDataSource(),

"resource_guid": {
Type: pluginsdk.TypeString,
Computed: true,
},
},
}
}

func dataSourceCdnFrontDoorProfileRead(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Cdn.FrontDoorProfileClient
subscriptionId := meta.(*clients.Client).Account.SubscriptionId
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

id := parse.NewFrontDoorProfileID(subscriptionId, d.Get("resource_group_name").(string), d.Get("name").(string))
resp, err := client.Get(ctx, id.ResourceGroup, id.ProfileName)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("%s was not found", id)
}
return fmt.Errorf("retrieving %s: %+v", id, err)
}

d.SetId(id.ID())
d.Set("name", id.ProfileName)
d.Set("resource_group_name", id.ResourceGroup)

if props := resp.ProfileProperties; props != nil {
d.Set("response_timeout_seconds", props.OriginResponseTimeoutSeconds)

// whilst this is returned in the API as FrontDoorID other resources refer to
// this as the Resource GUID, so we will for consistency
d.Set("resource_guid", props.FrontDoorID)
}

skuName := ""
if resp.Sku != nil {
skuName = string(resp.Sku.Name)
}
d.Set("sku_name", skuName)

if err := tags.FlattenAndSet(d, resp.Tags); err != nil {
return err
}

return nil
}
36 changes: 36 additions & 0 deletions internal/services/cdn/cdn_frontdoor_profile_data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package cdn_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check"
)

type CdnFrontDoorProfileDataSource struct{}

func TestAccCdnFrontDoorProfileDataSource_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_cdn_frontdoor_profile", "test")
d := CdnFrontDoorProfileDataSource{}

data.DataSourceTest(t, []acceptance.TestStep{
{
Config: d.basic(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("sku_name").HasValue("Premium_AzureFrontDoor"),
),
},
})
}

func (CdnFrontDoorProfileDataSource) basic(data acceptance.TestData) string {
return fmt.Sprintf(`
%s

data "azurerm_cdn_frontdoor_profile" "test" {
name = azurerm_cdn_frontdoor_profile.test.name
resource_group_name = azurerm_cdn_frontdoor_profile.test.resource_group_name
}
`, CdnFrontDoorProfileResource{}.complete(data))
}
Loading