Skip to content

Commit

Permalink
Add New Resource & Data Source: azurerm_netapp_volume (#4933)
Browse files Browse the repository at this point in the history
This PR is code implement for issue #3936

Fixes #3936
  • Loading branch information
Neil Ye authored and katbyte committed Dec 18, 2019
1 parent 65cdd3d commit 2ebd225
Show file tree
Hide file tree
Showing 18 changed files with 1,441 additions and 6 deletions.
110 changes: 110 additions & 0 deletions azurerm/data_source_netapp_volume.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package azurerm

import (
"fmt"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
aznetapp "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/netapp"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func dataSourceArmNetAppVolume() *schema.Resource {
return &schema.Resource{
Read: dataSourceArmNetAppVolumeRead,

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

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ValidateFunc: aznetapp.ValidateNetAppPoolName,
},

"resource_group_name": azure.SchemaResourceGroupNameForDataSource(),

"location": azure.SchemaLocationForDataSource(),

"account_name": {
Type: schema.TypeString,
Required: true,
ValidateFunc: aznetapp.ValidateNetAppAccountName,
},

"pool_name": {
Type: schema.TypeString,
Required: true,
ValidateFunc: aznetapp.ValidateNetAppPoolName,
},

"volume_path": {
Type: schema.TypeString,
Computed: true,
},

"service_level": {
Type: schema.TypeString,
Computed: true,
},

"subnet_id": {
Type: schema.TypeString,
Computed: true,
},

"storage_quota_in_gb": {
Type: schema.TypeInt,
Computed: true,
},
},
}
}

func dataSourceArmNetAppVolumeRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).NetApp.VolumeClient
ctx, cancel := timeouts.ForRead(meta.(*ArmClient).StopContext, d)
defer cancel()

name := d.Get("name").(string)
accountName := d.Get("account_name").(string)
poolName := d.Get("pool_name").(string)
resourceGroup := d.Get("resource_group_name").(string)

resp, err := client.Get(ctx, resourceGroup, accountName, poolName, name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Error: NetApp Volume %q (Resource Group %q) was not found", name, resourceGroup)
}
return fmt.Errorf("Error reading NetApp Volume %q (Resource Group %q): %+v", name, resourceGroup, err)
}

if resp.ID == nil || *resp.ID == "" {
return fmt.Errorf("Error retrieving NetApp Volume %q (Resource Group %q): ID was nil or empty", name, resourceGroup)
}

d.SetId(*resp.ID)

d.Set("name", name)
d.Set("resource_group_name", resourceGroup)
d.Set("account_name", accountName)
d.Set("pool_name", poolName)
if location := resp.Location; location != nil {
d.Set("location", azure.NormalizeLocation(*location))
}
if props := resp.VolumeProperties; props != nil {
d.Set("volume_path", props.CreationToken)
d.Set("service_level", props.ServiceLevel)
d.Set("subnet_id", props.SubnetID)

if props.UsageThreshold != nil {
d.Set("storage_quota_in_gb", *props.UsageThreshold/1073741824)
}
}

return nil
}
45 changes: 45 additions & 0 deletions azurerm/data_source_netapp_volume_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package azurerm

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
)

func TestAccDataSourceAzureRMNetAppVolume_basic(t *testing.T) {
dataSourceName := "data.azurerm_netapp_volume.test"
ri := tf.AccRandTimeInt()
location := testLocation()

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceNetAppVolume_basic(ri, location),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(dataSourceName, "volume_path"),
resource.TestCheckResourceAttrSet(dataSourceName, "service_level"),
resource.TestCheckResourceAttrSet(dataSourceName, "subnet_id"),
resource.TestCheckResourceAttrSet(dataSourceName, "storage_quota_in_gb"),
),
},
},
})
}

func testAccDataSourceNetAppVolume_basic(rInt int, location string) string {
config := testAccAzureRMNetAppVolume_basic(rInt, location)
return fmt.Sprintf(`
%s
data "azurerm_netapp_volume" "test" {
resource_group_name = "${azurerm_netapp_volume.test.resource_group_name}"
account_name = "${azurerm_netapp_volume.test.account_name}"
pool_name = "${azurerm_netapp_volume.test.pool_name}"
name = "${azurerm_netapp_volume.test.name}"
}
`, config)
}
5 changes: 5 additions & 0 deletions azurerm/internal/services/netapp/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
type Client struct {
AccountClient *netapp.AccountsClient
PoolClient *netapp.PoolsClient
VolumeClient *netapp.VolumesClient
}

func NewClient(o *common.ClientOptions) *Client {
Expand All @@ -17,8 +18,12 @@ func NewClient(o *common.ClientOptions) *Client {
poolClient := netapp.NewPoolsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&poolClient.Client, o.ResourceManagerAuthorizer)

volumeClient := netapp.NewVolumesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&volumeClient.Client, o.ResourceManagerAuthorizer)

return &Client{
AccountClient: &accountClient,
PoolClient: &poolClient,
VolumeClient: &volumeClient,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,23 @@ func ValidateNetAppPoolName(v interface{}, k string) (warnings []string, errors

return warnings, errors
}

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

if !regexp.MustCompile(`^[a-zA-Z][-_\da-zA-Z]{0,63}$`).MatchString(value) {
errors = append(errors, fmt.Errorf("%q must be between 1 and 64 characters in length and start with letters and contains only letters, numbers, underscore or hyphens.", k))
}

return warnings, errors
}

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

if !regexp.MustCompile(`^[a-zA-Z][-\da-zA-Z]{0,79}$`).MatchString(value) {
errors = append(errors, fmt.Errorf("%q must be between 1 and 80 characters in length and start with letters and contains only letters, numbers or hyphens.", k))
}

return warnings, errors
}
139 changes: 139 additions & 0 deletions azurerm/internal/services/netapp/validation_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package netapp

import "testing"

func TestValidateNetAppVolumeName(t *testing.T) {
testData := []struct {
input string
expected bool
}{
{
// empty
input: "",
expected: false,
},
{
// basic example
input: "hello",
expected: true,
},
{
// can't start with an underscore
input: "_hello",
expected: false,
},
{
// can't end with a dash
input: "hello-",
expected: true,
},
{
// can't contain an exclamation mark
input: "hello!",
expected: false,
},
{
// dash in the middle
input: "malcolm-in-the-middle",
expected: true,
},
{
// can't end with a period
input: "hello.",
expected: false,
},
{
// 63 chars
input: "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk",
expected: true,
},
{
// 64 chars
input: "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkj",
expected: true,
},
{
// 65 chars
input: "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkja",
expected: false,
},
}

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

_, errors := ValidateNetAppVolumeName(v.input, "name")
actual := len(errors) == 0
if v.expected != actual {
t.Fatalf("Expected %t but got %t", v.expected, actual)
}
}
}

func TestValidateNetAppVolumeVolumePath(t *testing.T) {
testData := []struct {
input string
expected bool
}{
{
// empty
input: "",
expected: false,
},
{
// basic example
input: "hello",
expected: true,
},
{
// can't start with an underscore
input: "_hello",
expected: false,
},
{
// can't end with a dash
input: "hello-",
expected: true,
},
{
// can't contain an exclamation mark
input: "hello!",
expected: false,
},
{
// dash in the middle
input: "malcolm-in-the-middle",
expected: true,
},
{
// can't end with a period
input: "hello.",
expected: false,
},
{
// 79 chars
input: "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijabcdefgheysudciac",
expected: true,
},
{
// 80 chars
input: "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkasbdjdssardwyupac",
expected: true,
},
{
// 81 chars
input: "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkjspoiuytrewqasdfac",
expected: false,
},
}

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

_, errors := ValidateNetAppVolumeVolumePath(v.input, "volume_path")
actual := len(errors) == 0
if v.expected != actual {
t.Fatalf("Expected %t but got %t", v.expected, actual)
}
}
}
2 changes: 2 additions & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_nat_gateway": dataSourceArmNatGateway(),
"azurerm_netapp_account": dataSourceArmNetAppAccount(),
"azurerm_netapp_pool": dataSourceArmNetAppPool(),
"azurerm_netapp_volume": dataSourceArmNetAppVolume(),
"azurerm_network_ddos_protection_plan": dataSourceNetworkDDoSProtectionPlan(),
"azurerm_network_interface": dataSourceArmNetworkInterface(),
"azurerm_network_security_group": dataSourceArmNetworkSecurityGroup(),
Expand Down Expand Up @@ -387,6 +388,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_network_watcher": resourceArmNetworkWatcher(),
"azurerm_netapp_account": resourceArmNetAppAccount(),
"azurerm_netapp_pool": resourceArmNetAppPool(),
"azurerm_netapp_volume": resourceArmNetAppVolume(),
"azurerm_notification_hub_authorization_rule": resourceArmNotificationHubAuthorizationRule(),
"azurerm_notification_hub_namespace": resourceArmNotificationHubNamespace(),
"azurerm_notification_hub": resourceArmNotificationHub(),
Expand Down
1 change: 0 additions & 1 deletion azurerm/resource_arm_netapp_account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ resource "azurerm_netapp_account" "import" {
location = "${azurerm_netapp_account.test.location}"
resource_group_name = "${azurerm_netapp_account.test.name}"
}
}
`, testAccAzureRMNetAppAccount_basicConfig(rInt, location))
}

Expand Down
1 change: 1 addition & 0 deletions azurerm/resource_arm_netapp_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func resourceArmNetAppPool() *schema.Resource {
"account_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: aznetapp.ValidateNetAppAccountName,
},

Expand Down
4 changes: 2 additions & 2 deletions azurerm/resource_arm_netapp_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ resource "azurerm_netapp_pool" "test" {
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
service_level = "Premium"
size_in_tb = "4"
size_in_tb = 4
}
`, rInt, location, rInt, rInt)
}
Expand Down Expand Up @@ -236,7 +236,7 @@ resource "azurerm_netapp_pool" "test" {
location = "${azurerm_resource_group.test.location}"
resource_group_name = "${azurerm_resource_group.test.name}"
service_level = "Standard"
size_in_tb = "15"
size_in_tb = 15
}
`, rInt, location, rInt, rInt)
}
Loading

0 comments on commit 2ebd225

Please sign in to comment.