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

Add New Resource & Data Source: azurerm_netapp_volume #4933

Merged
merged 13 commits into from Dec 18, 2019
110 changes: 110 additions & 0 deletions azurerm/data_source_netapp_volume.go
@@ -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)
neil-yechenwei marked this conversation as resolved.
Show resolved Hide resolved

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)
}
katbyte marked this conversation as resolved.
Show resolved Hide resolved
}

return nil
}
45 changes: 45 additions & 0 deletions azurerm/data_source_netapp_volume_test.go
@@ -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
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,
}
}
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
@@ -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
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 @@ -382,6 +383,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
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
Expand Up @@ -52,6 +52,7 @@ func resourceArmNetAppPool() *schema.Resource {
"account_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
katbyte marked this conversation as resolved.
Show resolved Hide resolved
ValidateFunc: aznetapp.ValidateNetAppAccountName,
},

Expand Down
4 changes: 2 additions & 2 deletions azurerm/resource_arm_netapp_pool_test.go
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)
}