Skip to content

Commit

Permalink
New Resource: azurerm_management_lock
Browse files Browse the repository at this point in the history
Note: As the Subscription specific Locks will break other tests; these tests need to be run individually.
As such I've introduced the `TF_ACC_SUBSCRIPTION_PARALLEL_LOCK`  environment variable for this purpose.

Tests pass:

```
$ TF_ACC_SUBSCRIPTION_PARALLEL_LOCK=1 acctests azurerm TestAccAzureRMManagementLock_
=== RUN   TestAccAzureRMManagementLock_importResourceGroupReadOnlyBasic
--- PASS: TestAccAzureRMManagementLock_importResourceGroupReadOnlyBasic (61.52s)
=== RUN   TestAccAzureRMManagementLock_importResourceGroupReadOnlyComplete
--- PASS: TestAccAzureRMManagementLock_importResourceGroupReadOnlyComplete (58.75s)
=== RUN   TestAccAzureRMManagementLock_importResourceGroupCanNotDeleteBasic
--- PASS: TestAccAzureRMManagementLock_importResourceGroupCanNotDeleteBasic (53.38s)
=== RUN   TestAccAzureRMManagementLock_importResourceGroupCanNotDeleteComplete
--- PASS: TestAccAzureRMManagementLock_importResourceGroupCanNotDeleteComplete (46.87s)
=== RUN   TestAccAzureRMManagementLock_importPublicIPCanNotDeleteBasic
--- PASS: TestAccAzureRMManagementLock_importPublicIPCanNotDeleteBasic (80.46s)
=== RUN   TestAccAzureRMManagementLock_importPublicIPReadOnlyBasic
--- PASS: TestAccAzureRMManagementLock_importPublicIPReadOnlyBasic (68.53s)
=== RUN   TestAccAzureRMManagementLock_resourceGroupReadOnlyBasic
--- PASS: TestAccAzureRMManagementLock_resourceGroupReadOnlyBasic (61.24s)
=== RUN   TestAccAzureRMManagementLock_resourceGroupReadOnlyComplete
--- PASS: TestAccAzureRMManagementLock_resourceGroupReadOnlyComplete (64.10s)
=== RUN   TestAccAzureRMManagementLock_resourceGroupCanNotDeleteBasic
--- PASS: TestAccAzureRMManagementLock_resourceGroupCanNotDeleteBasic (72.49s)
=== RUN   TestAccAzureRMManagementLock_resourceGroupCanNotDeleteComplete
--- PASS: TestAccAzureRMManagementLock_resourceGroupCanNotDeleteComplete (113.71s)
=== RUN   TestAccAzureRMManagementLock_publicIPReadOnlyBasic
--- PASS: TestAccAzureRMManagementLock_publicIPReadOnlyBasic (64.05s)
=== RUN   TestAccAzureRMManagementLock_publicIPCanNotDeleteBasic
--- PASS: TestAccAzureRMManagementLock_publicIPCanNotDeleteBasic (94.53s)
=== RUN   TestAccAzureRMManagementLock_subscriptionReadOnlyBasic
--- PASS: TestAccAzureRMManagementLock_subscriptionReadOnlyBasic (17.98s)
=== RUN   TestAccAzureRMManagementLock_subscriptionCanNotDeleteBasic
--- PASS: TestAccAzureRMManagementLock_subscriptionCanNotDeleteBasic (15.20s)
PASS
ok      github.com/terraform-providers/terraform-provider-azurerm/azurerm    872.839s
```

Fixes #23
  • Loading branch information
tombuildsstuff committed Nov 18, 2017
1 parent 5b802d4 commit facd2a5
Show file tree
Hide file tree
Showing 7 changed files with 784 additions and 7 deletions.
13 changes: 13 additions & 0 deletions azurerm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/Azure/azure-sdk-for-go/arm/operationalinsights"
"github.com/Azure/azure-sdk-for-go/arm/postgresql"
"github.com/Azure/azure-sdk-for-go/arm/redis"
"github.com/Azure/azure-sdk-for-go/arm/resources/locks"
"github.com/Azure/azure-sdk-for-go/arm/resources/resources"
"github.com/Azure/azure-sdk-for-go/arm/resources/subscriptions"
"github.com/Azure/azure-sdk-for-go/arm/scheduler"
Expand Down Expand Up @@ -160,6 +161,9 @@ type ArmClient struct {
sqlElasticPoolsClient sql.ElasticPoolsClient
sqlFirewallRulesClient sql.FirewallRulesClient
sqlServersClient sql.ServersClient

// Resources
managementLocksClient locks.ManagementLocksClient
}

func withRequestLogging() autorest.SendDecorator {
Expand Down Expand Up @@ -656,6 +660,7 @@ func (c *Config) getArmClient() (*ArmClient, error) {
client.registerDisks(endpoint, c.SubscriptionID, auth, sender)
client.registerKeyVaultClients(endpoint, c.SubscriptionID, auth, keyVaultAuth, sender)
client.registerRedisClients(endpoint, c.SubscriptionID, auth, sender)
client.registerResourcesClients(endpoint, c.SubscriptionID, auth, sender)

return &client, nil
}
Expand Down Expand Up @@ -805,6 +810,14 @@ func (c *ArmClient) registerRedisClients(endpoint, subscriptionId string, auth a
c.redisPatchSchedulesClient = patchSchedulesClient
}

func (c *ArmClient) registerResourcesClients(endpoint, subscriptionId string, auth autorest.Authorizer, sender autorest.Sender) {
locksClient := locks.NewManagementLocksClientWithBaseURI(endpoint, subscriptionId)
setUserAgent(&locksClient.Client)
locksClient.Authorizer = auth
locksClient.Sender = sender
c.managementLocksClient = locksClient
}

func (armClient *ArmClient) getKeyForStorageAccount(resourceGroupName, storageAccountName string) (string, bool, error) {
accountKeys, err := armClient.storageServiceClient.ListKeys(resourceGroupName, storageAccountName)
if accountKeys.StatusCode == http.StatusNotFound {
Expand Down
134 changes: 134 additions & 0 deletions azurerm/import_arm_management_lock_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package azurerm

import (
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)

func TestAccAzureRMManagementLock_importResourceGroupReadOnlyBasic(t *testing.T) {
ri := acctest.RandInt()
config := testAccAzureRMManagementLock_resourceGroupReadOnlyBasic(ri, testLocation())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMManagementLockDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: "azurerm_management_lock.test",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAzureRMManagementLock_importResourceGroupReadOnlyComplete(t *testing.T) {
ri := acctest.RandInt()
config := testAccAzureRMManagementLock_resourceGroupReadOnlyComplete(ri, testLocation())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMManagementLockDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: "azurerm_management_lock.test",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAzureRMManagementLock_importResourceGroupCanNotDeleteBasic(t *testing.T) {
ri := acctest.RandInt()
config := testAccAzureRMManagementLock_resourceGroupCanNotDeleteBasic(ri, testLocation())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMManagementLockDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: "azurerm_management_lock.test",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAzureRMManagementLock_importResourceGroupCanNotDeleteComplete(t *testing.T) {
ri := acctest.RandInt()
config := testAccAzureRMManagementLock_resourceGroupCanNotDeleteComplete(ri, testLocation())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMManagementLockDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: "azurerm_management_lock.test",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAzureRMManagementLock_importPublicIPCanNotDeleteBasic(t *testing.T) {
ri := acctest.RandInt()
config := testAccAzureRMManagementLock_publicIPCanNotDeleteBasic(ri, testLocation())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMManagementLockDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: "azurerm_management_lock.test",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAzureRMManagementLock_importPublicIPReadOnlyBasic(t *testing.T) {
ri := acctest.RandInt()
config := testAccAzureRMManagementLock_publicIPReadOnlyBasic(ri, testLocation())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMManagementLockDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: "azurerm_management_lock.test",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
1 change: 1 addition & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_local_network_gateway": resourceArmLocalNetworkGateway(),
"azurerm_log_analytics_workspace": resourceArmLogAnalyticsWorkspace(),
"azurerm_managed_disk": resourceArmManagedDisk(),
"azurerm_management_lock": resourceArmManagementLock(),
"azurerm_mysql_configuration": resourceArmMySQLConfiguration(),
"azurerm_mysql_database": resourceArmMySqlDatabase(),
"azurerm_mysql_firewall_rule": resourceArmMySqlFirewallRule(),
Expand Down
155 changes: 155 additions & 0 deletions azurerm/resource_arm_management_lock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package azurerm

import (
"fmt"
"log"
"strings"

"github.com/Azure/azure-sdk-for-go/arm/resources/locks"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceArmManagementLock() *schema.Resource {
return &schema.Resource{
Create: resourceArmManagementLockCreateUpdate,
Read: resourceArmManagementLockRead,
Delete: resourceArmManagementLockDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
// TODO: validation
// The lock name can be a maximum of 260 characters.
// It cannot contain <, > %, &, :, \, ?, /, or any control characters.
},

"scope": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},

"lock_level": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{
string(locks.CanNotDelete),
string(locks.ReadOnly),
}, false),
},

"notes": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
ValidateFunc: validation.StringLenBetween(0, 512),
},
},
}
}

func resourceArmManagementLockCreateUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).managementLocksClient
log.Printf("[INFO] preparing arguments for AzureRM Management Lock creation.")

name := d.Get("name").(string)
scope := d.Get("scope").(string)
lockLevel := d.Get("lock_level").(string)
notes := d.Get("notes").(string)

lock := locks.ManagementLockObject{
ManagementLockProperties: &locks.ManagementLockProperties{
Level: locks.LockLevel(lockLevel),
Notes: utils.String(notes),
},
}

_, err := client.CreateOrUpdateByScope(scope, name, lock)
if err != nil {
return err
}

read, err := client.GetByScope(scope, name)
if err != nil {
return err
}

if read.ID == nil {
return fmt.Errorf("Cannot read ID of AzureRM Management Lock %q (Scope %q)", name, scope)
}

d.SetId(*read.ID)
return resourceArmManagementLockRead(d, meta)
}

func resourceArmManagementLockRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).managementLocksClient

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

resp, err := client.GetByScope(id.Scope, id.Name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
d.SetId("")
return nil
}
return fmt.Errorf("Error making Read request on AzureRM Management Lock %q (Scope %q): %+v", id.Name, id.Scope, err)
}

d.Set("name", resp.Name)
d.Set("scope", id.Scope)

if props := resp.ManagementLockProperties; props != nil {
d.Set("lock_level", string(props.Level))
d.Set("notes", props.Notes)
}

return nil
}

func resourceArmManagementLockDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).managementLocksClient

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

resp, err := client.DeleteByScope(id.Scope, id.Name)
if err != nil {
if utils.ResponseWasNotFound(resp) {
return nil
}

return fmt.Errorf("Error issuing AzureRM delete request for Management Lock %q (Scope %q): %+v", id.Name, id.Scope, err)
}

return nil
}

type AzureManagementLockId struct {
Scope string
Name string
}

func parseAzureRMLockId(id string) (*AzureManagementLockId, error) {
segments := strings.Split(id, "/providers/Microsoft.Authorization/locks/")
scope := segments[0]
name := segments[1]
lockId := AzureManagementLockId{
Scope: scope,
Name: name,
}
return &lockId, nil
}
Loading

0 comments on commit facd2a5

Please sign in to comment.