Skip to content

Commit

Permalink
Merge pull request #17061 from hashicorp/f/cdn-frontdoor-core
Browse files Browse the repository at this point in the history
New Data Source/Resource: `azurerm_cdn_frontdoor_profile`
  • Loading branch information
tombuildsstuff authored Jun 2, 2022
2 parents 170dca7 + 0f66652 commit eed353f
Show file tree
Hide file tree
Showing 62 changed files with 39,357 additions and 10 deletions.
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

0 comments on commit eed353f

Please sign in to comment.