Skip to content

Commit

Permalink
New resource: azurerm_tenant_configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
neil-yechenwei committed May 8, 2021
1 parent 40d92ac commit 415baf2
Show file tree
Hide file tree
Showing 10 changed files with 472 additions and 3 deletions.
9 changes: 7 additions & 2 deletions azurerm/internal/services/portal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@ import (
)

type Client struct {
DashboardsClient *portal.DashboardsClient
DashboardsClient *portal.DashboardsClient
TenantConfigurationsClient *portal.TenantConfigurationsClient
}

func NewClient(o *common.ClientOptions) *Client {
dashboardsClient := portal.NewDashboardsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&dashboardsClient.Client, o.ResourceManagerAuthorizer)

tenantConfigurationsClient := portal.NewTenantConfigurationsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&tenantConfigurationsClient.Client, o.ResourceManagerAuthorizer)

return &Client{
DashboardsClient: &dashboardsClient,
DashboardsClient: &dashboardsClient,
TenantConfigurationsClient: &tenantConfigurationsClient,
}
}
53 changes: 53 additions & 0 deletions azurerm/internal/services/portal/parse/tenant_configuration.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"fmt"
"strings"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
)

type TenantConfigurationId struct {
Name string
}

func NewTenantConfigurationID(name string) TenantConfigurationId {
return TenantConfigurationId{
Name: name,
}
}

func (id TenantConfigurationId) String() string {
segments := []string{
fmt.Sprintf("Name %q", id.Name),
}
segmentsStr := strings.Join(segments, " / ")
return fmt.Sprintf("%s: (%s)", "Tenant Configuration", segmentsStr)
}

func (id TenantConfigurationId) ID() string {
fmtString := "/providers/Microsoft.Portal/tenantConfigurations/%s"
return fmt.Sprintf(fmtString, id.Name)
}

// TenantConfigurationID parses a TenantConfiguration ID into an TenantConfigurationId struct
func TenantConfigurationID(input string) (*TenantConfigurationId, error) {
id, err := azure.ParseAzureResourceID(input)
if err != nil {
return nil, err
}

resourceId := TenantConfigurationId{}

if resourceId.Name, err = id.PopSegment("tenantConfigurations"); err != nil {
return nil, err
}

if err := id.ValidateNoEmptySegments(input); err != nil {
return nil, err
}

return &resourceId, nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package parse

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"testing"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/resourceid"
)

var _ resourceid.Formatter = TenantConfigurationId{}

func TestTenantConfigurationIDFormatter(t *testing.T) {
actual := NewTenantConfigurationID("default").ID()
expected := "/providers/Microsoft.Portal/tenantConfigurations/default"
if actual != expected {
t.Fatalf("Expected %q but got %q", expected, actual)
}
}

func TestTenantConfigurationID(t *testing.T) {
testData := []struct {
Input string
Error bool
Expected *TenantConfigurationId
}{

{
// empty
Input: "",
Error: true,
},

{
// missing Name
Input: "/providers/Microsoft.Portal/",
Error: true,
},

{
// missing value for Name
Input: "/providers/Microsoft.Portal/tenantConfigurations/",
Error: true,
},

{
// valid
Input: "/providers/Microsoft.Portal/tenantConfigurations/default",
Expected: &TenantConfigurationId{
Name: "default",
},
},

{
// upper-cased
Input: "/PROVIDERS/MICROSOFT.PORTAL/TENANTCONFIGURATIONS/DEFAULT",
Error: true,
},
}

for _, v := range testData {
t.Logf("[DEBUG] Testing %q", v.Input)

actual, err := TenantConfigurationID(v.Input)
if err != nil {
if v.Error {
continue
}

t.Fatalf("Expect a value but got an error: %s", err)
}
if v.Error {
t.Fatal("Expect an error but didn't get one")
}

if actual.Name != v.Expected.Name {
t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package portal

import (
"fmt"
"time"

"github.com/Azure/azure-sdk-for-go/services/preview/portal/mgmt/2019-01-01-preview/portal"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/portal/parse"
azSchema "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/tf/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceTenantConfiguration() *schema.Resource {
return &schema.Resource{
Create: resourceTenantConfigurationCreateUpdate,
Read: resourceTenantConfigurationRead,
Update: resourceTenantConfigurationCreateUpdate,
Delete: resourceTenantConfigurationDelete,

Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(30 * time.Minute),
Read: schema.DefaultTimeout(5 * time.Minute),
Update: schema.DefaultTimeout(30 * time.Minute),
Delete: schema.DefaultTimeout(30 * time.Minute),
},

Importer: azSchema.ValidateResourceIDPriorToImport(func(id string) error {
_, err := parse.TenantConfigurationID(id)
return err
}),

Schema: map[string]*schema.Schema{
"enforce_private_markdown_storage": {
Type: schema.TypeBool,
Required: true,
},
},
}
}

func resourceTenantConfigurationCreateUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Portal.TenantConfigurationsClient
ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

id := parse.NewTenantConfigurationID("default")

if d.IsNewResource() {
existing, err := client.Get(ctx)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("checking for existing %s: %+v", id, err)
}
}

if !utils.ResponseWasNotFound(existing.Response) {
return tf.ImportAsExistsError("azurerm_tenant_configuration", id.ID())
}
}

tenantConfiguration := portal.Configuration{
ConfigurationProperties: &portal.ConfigurationProperties{
EnforcePrivateMarkdownStorage: utils.Bool(d.Get("enforce_private_markdown_storage").(bool)),
},
}

if _, err := client.Create(ctx, tenantConfiguration); err != nil {
return fmt.Errorf("creating/updating %s: %+v", id, err)
}

d.SetId(id.ID())

return resourceTenantConfigurationRead(d, meta)
}

func resourceTenantConfigurationRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Portal.TenantConfigurationsClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := parse.TenantConfigurationID(d.Id())
if err != nil {
return err
}

resp, err := client.Get(ctx)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
d.SetId("")
return nil
}
return fmt.Errorf("retrieving %s: %+v", *id, err)
}

if props := resp.ConfigurationProperties; props != nil {
d.Set("enforce_private_markdown_storage", props.EnforcePrivateMarkdownStorage)
}

return nil
}

func resourceTenantConfigurationDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Portal.TenantConfigurationsClient
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := parse.TenantConfigurationID(d.Id())
if err != nil {
return err
}

if _, err := client.Delete(ctx); err != nil {
return fmt.Errorf("deleting %s: %+v", *id, err)
}

return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package portal_test

import (
"context"
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance/check"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/portal/parse"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

type PortalTenantConfigurationResource struct{}

func TestAccPortalTenantConfiguration_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_tenant_configuration", "test")
r := PortalTenantConfigurationResource{}
data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.basic(),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep(),
})
}

func TestAccPortalTenantConfiguration_requiresImport(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_tenant_configuration", "test")
r := PortalTenantConfigurationResource{}
data.ResourceTest(t, r, []resource.TestStep{
{
Config: r.basic(),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.RequiresImportErrorStep(r.requiresImport),
})
}

func (r PortalTenantConfigurationResource) Exists(ctx context.Context, client *clients.Client, state *terraform.InstanceState) (*bool, error) {
id, err := parse.TenantConfigurationID(state.ID)
if err != nil {
return nil, err
}

resp, err := client.Portal.TenantConfigurationsClient.Get(ctx)
if err != nil {
return nil, fmt.Errorf("retrieving %s: %v", id.String(), err)
}

return utils.Bool(resp.ConfigurationProperties != nil), nil
}

func (r PortalTenantConfigurationResource) basic() string {
return fmt.Sprintf(`
provider "azurerm" {
features {}
}
resource "azurerm_tenant_configuration" "test" {
enforce_private_markdown_storage = true
}
`)
}

func (r PortalTenantConfigurationResource) requiresImport(data acceptance.TestData) string {
return fmt.Sprintf(`
%s
resource "azurerm_portal_tenant_configuration" "import" {
enforce_private_markdown_storage = azurerm_portal_tenant_configuration.test.enforce_private_markdown_storage
}
`, r.basic())
}
3 changes: 2 additions & 1 deletion azurerm/internal/services/portal/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func (r Registration) SupportedDataSources() map[string]*schema.Resource {
// SupportedResources returns the supported Resources supported by this Service
func (r Registration) SupportedResources() map[string]*schema.Resource {
return map[string]*schema.Resource{
"azurerm_dashboard": resourceDashboard(),
"azurerm_dashboard": resourceDashboard(),
"azurerm_tenant_configuration": resourceTenantConfiguration(),
}
}
1 change: 1 addition & 0 deletions azurerm/internal/services/portal/resourceids.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
package portal

//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=Dashboard -id=/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/group1/providers/Microsoft.Portal/dashboards/dashboard1
//go:generate go run ../../tools/generator-resource-id/main.go -path=./ -name=TenantConfiguration -id=/providers/Microsoft.Portal/tenantConfigurations/default
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package validate

// NOTE: this file is generated via 'go:generate' - manual changes will be overwritten

import (
"fmt"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/portal/parse"
)

func TenantConfigurationID(input interface{}, key string) (warnings []string, errors []error) {
v, ok := input.(string)
if !ok {
errors = append(errors, fmt.Errorf("expected %q to be a string", key))
return
}

if _, err := parse.TenantConfigurationID(v); err != nil {
errors = append(errors, err)
}

return
}
Loading

0 comments on commit 415baf2

Please sign in to comment.