Skip to content

Commit

Permalink
Add new resource for NetApp Account (#4416)
Browse files Browse the repository at this point in the history
fixes #4417
  • Loading branch information
Neil Ye authored and katbyte committed Nov 15, 2019
1 parent 6f2fef5 commit 2ccff85
Show file tree
Hide file tree
Showing 22 changed files with 4,714 additions and 0 deletions.
3 changes: 3 additions & 0 deletions azurerm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import (
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/msi"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/mssql"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/mysql"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/netapp"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/network"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/notificationhub"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/policy"
Expand Down Expand Up @@ -126,6 +127,7 @@ type ArmClient struct {
Msi *msi.Client
Mssql *mssql.Client
Mysql *mysql.Client
Netapp *netapp.Client
Network *network.Client
NotificationHubs *notificationhub.Client
Policy *policy.Client
Expand Down Expand Up @@ -262,6 +264,7 @@ func getArmClient(authConfig *authentication.Config, skipProviderRegistration bo
client.Msi = msi.BuildClient(o)
client.Mysql = mysql.BuildClient(o)
client.ManagementGroups = managementgroup.BuildClient(o)
client.Netapp = netapp.BuildClient(o)
client.Network = network.BuildClient(o)
client.NotificationHubs = notificationhub.BuildClient(o)
client.Policy = policy.BuildClient(o)
Expand Down
60 changes: 60 additions & 0 deletions azurerm/data_source_netapp_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package azurerm

import (
"fmt"
"regexp"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func dataSourceArmNetAppAccount() *schema.Resource {
return &schema.Resource{
Read: dataSourceArmNetAppAccountRead,

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringMatch(
regexp.MustCompile(`(^[\da-zA-Z])([-\da-zA-Z]{1,62})([\da-zA-Z]$)`),
`The name must be between 3 and 64 characters in length and begin with a letter or number, end with a letter or number and may contain only letters, numbers or hyphens.`,
),
},

"resource_group_name": azure.SchemaResourceGroupNameForDataSource(),

"location": azure.SchemaLocationForDataSource(),

// Handles tags being interface{} until https://github.com/Azure/azure-rest-api-specs/issues/7447 is fixed
},
}
}

func dataSourceArmNetAppAccountRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).Netapp.AccountClient
ctx := meta.(*ArmClient).StopContext

name := d.Get("name").(string)
resourceGroup := d.Get("resource_group_name").(string)

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

d.SetId(*resp.ID)

d.Set("name", resp.Name)
d.Set("resource_group_name", resourceGroup)
if location := resp.Location; location != nil {
d.Set("location", azure.NormalizeLocation(*location))
}

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

import (
"fmt"
"testing"

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

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

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceNetAppAccount_basicConfig(ri, location),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(dataSourceName, "resource_group_name"),
resource.TestCheckResourceAttrSet(dataSourceName, "name"),
),
},
},
})
}

func testAccDataSourceNetAppAccount_basicConfig(rInt int, location string) string {
config := testAccAzureRMNetAppAccount_basicConfig(rInt, location)
return fmt.Sprintf(`
%s
data "azurerm_netapp_account" "test" {
resource_group_name = "${azurerm_netapp_account.test.resource_group_name}"
name = "${azurerm_netapp_account.test.name}"
}
`, config)
}
19 changes: 19 additions & 0 deletions azurerm/internal/services/netapp/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package netapp

import (
"github.com/Azure/azure-sdk-for-go/services/netapp/mgmt/2019-06-01/netapp"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common"
)

type Client struct {
AccountClient *netapp.AccountsClient
}

func BuildClient(o *common.ClientOptions) *Client {
accountClient := netapp.NewAccountsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&accountClient.Client, o.ResourceManagerAuthorizer)

return &Client{
AccountClient: &accountClient,
}
}
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_monitor_diagnostic_categories": dataSourceArmMonitorDiagnosticCategories(),
"azurerm_monitor_log_profile": dataSourceArmMonitorLogProfile(),
"azurerm_mssql_elasticpool": dataSourceArmMsSqlElasticpool(),
"azurerm_netapp_account": dataSourceArmNetAppAccount(),
"azurerm_network_ddos_protection_plan": dataSourceNetworkDDoSProtectionPlan(),
"azurerm_network_interface": dataSourceArmNetworkInterface(),
"azurerm_network_security_group": dataSourceArmNetworkSecurityGroup(),
Expand Down Expand Up @@ -365,6 +366,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_network_security_group": resourceArmNetworkSecurityGroup(),
"azurerm_network_security_rule": resourceArmNetworkSecurityRule(),
"azurerm_network_watcher": resourceArmNetworkWatcher(),
"azurerm_netapp_account": resourceArmNetAppAccount(),
"azurerm_notification_hub_authorization_rule": resourceArmNotificationHubAuthorizationRule(),
"azurerm_notification_hub_namespace": resourceArmNotificationHubNamespace(),
"azurerm_notification_hub": resourceArmNotificationHub(),
Expand Down
222 changes: 222 additions & 0 deletions azurerm/resource_arm_netapp_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
package azurerm

import (
"fmt"
"log"
"regexp"
"strings"

"github.com/Azure/azure-sdk-for-go/services/netapp/mgmt/2019-06-01/netapp"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/response"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/features"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceArmNetAppAccount() *schema.Resource {
return &schema.Resource{
Create: resourceArmNetAppAccountCreateUpdate,
Read: resourceArmNetAppAccountRead,
Update: resourceArmNetAppAccountCreateUpdate,
Delete: resourceArmNetAppAccountDelete,

Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringMatch(
regexp.MustCompile(`(^[\da-zA-Z])([-\da-zA-Z]{1,62})([\da-zA-Z]$)`),
`The name must be between 3 and 64 characters in length and begin with a letter or number, end with a letter or number and may contain only letters, numbers or hyphens.`,
),
},

"resource_group_name": azure.SchemaResourceGroupName(),

"location": azure.SchemaLocation(),

"active_directory": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"dns_servers": {
Type: schema.TypeList,
Required: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validate.IPv4Address,
},
},
"domain": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringMatch(
regexp.MustCompile(`^[(\da-zA-Z)\.]{1,255}$`),
`The domain name must end with a letter or number before dot and start with a letter or number after dot and can not be longer than 255 characters in length.`,
),
},
"smb_server_name": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringMatch(
regexp.MustCompile(`^[\da-zA-Z]{1,10}$`),
`The smb server name can not be longer than 10 characters in length.`,
),
},
"username": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validate.NoEmptyStrings,
},
"password": {
Type: schema.TypeString,
Required: true,
Sensitive: true,
ValidateFunc: validate.NoEmptyStrings,
},
"organizational_unit": {
Type: schema.TypeString,
Optional: true,
},
},
},
},

// Handles tags being interface{} until https://github.com/Azure/azure-rest-api-specs/issues/7447 is fixed
},
}
}

func resourceArmNetAppAccountCreateUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).Netapp.AccountClient
ctx := meta.(*ArmClient).StopContext

name := d.Get("name").(string)
resourceGroup := d.Get("resource_group_name").(string)

if features.ShouldResourcesBeImported() && d.IsNewResource() {
existing, err := client.Get(ctx, resourceGroup, name)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("Error checking for present of existing NetApp Account %q (Resource Group %q): %+v", name, resourceGroup, err)
}
}
if existing.ID != nil && *existing.ID != "" {
return tf.ImportAsExistsError("azurerm_netapp_account", *existing.ID)
}
}

location := azure.NormalizeLocation(d.Get("location").(string))
activeDirectories := d.Get("active_directory").([]interface{})

accountParameters := netapp.Account{
Location: utils.String(location),
AccountProperties: &netapp.AccountProperties{
ActiveDirectories: expandArmNetAppActiveDirectories(activeDirectories),
},
}

future, err := client.CreateOrUpdate(ctx, accountParameters, resourceGroup, name)
if err != nil {
return fmt.Errorf("Error creating NetApp Account %q (Resource Group %q): %+v", name, resourceGroup, err)
}
if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("Error waiting for creation of NetApp Account %q (Resource Group %q): %+v", name, resourceGroup, err)
}

resp, err := client.Get(ctx, resourceGroup, name)
if err != nil {
return fmt.Errorf("Error retrieving NetApp Account %q (Resource Group %q): %+v", name, resourceGroup, err)
}
if resp.ID == nil {
return fmt.Errorf("Cannot read NetApp Account %q (Resource Group %q) ID", name, resourceGroup)
}
d.SetId(*resp.ID)

return resourceArmNetAppAccountRead(d, meta)
}

func resourceArmNetAppAccountRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).Netapp.AccountClient
ctx := meta.(*ArmClient).StopContext

id, err := azure.ParseAzureResourceID(d.Id())
if err != nil {
return err
}
resourceGroup := id.ResourceGroup
name := id.Path["netAppAccounts"]

resp, err := client.Get(ctx, resourceGroup, name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
log.Printf("[INFO] NetApp Accounts %q does not exist - removing from state", d.Id())
d.SetId("")
return nil
}
return fmt.Errorf("Error reading NetApp Accounts %q (Resource Group %q): %+v", name, resourceGroup, err)
}

d.Set("name", resp.Name)
d.Set("resource_group_name", resourceGroup)
if location := resp.Location; location != nil {
d.Set("location", azure.NormalizeLocation(*location))
}

return nil
}

func resourceArmNetAppAccountDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).Netapp.AccountClient
ctx := meta.(*ArmClient).StopContext

id, err := azure.ParseAzureResourceID(d.Id())
if err != nil {
return err
}
resourceGroup := id.ResourceGroup
name := id.Path["netAppAccounts"]

future, err := client.Delete(ctx, resourceGroup, name)
if err != nil {
return fmt.Errorf("Error deleting NetApp Account %q (Resource Group %q): %+v", name, resourceGroup, err)
}

if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
if !response.WasNotFound(future.Response()) {
return fmt.Errorf("Error waiting for deleting NetApp Account %q (Resource Group %q): %+v", name, resourceGroup, err)
}
}

return nil
}

func expandArmNetAppActiveDirectories(input []interface{}) *[]netapp.ActiveDirectory {
results := make([]netapp.ActiveDirectory, 0)
for _, item := range input {
v := item.(map[string]interface{})
dns := strings.Join(*utils.ExpandStringSlice(v["dns_servers"].([]interface{})), ",")

result := netapp.ActiveDirectory{
DNS: utils.String(dns),
Domain: utils.String(v["domain"].(string)),
OrganizationalUnit: utils.String(v["organizational_unit"].(string)),
Password: utils.String(v["password"].(string)),
SmbServerName: utils.String(v["smb_server_name"].(string)),
Username: utils.String(v["username"].(string)),
}

results = append(results, result)
}
return &results
}
Loading

0 comments on commit 2ccff85

Please sign in to comment.