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

Support for azurerm_netapp_snapshot_policy #14230

Merged
merged 19 commits into from
Dec 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions examples/netapp/nfsv3_volume_with_snapshot_policy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## Example: NetApp Files Snapshot Policy

This example shows how to create an Azure NetApp Snapshot Policy and how to apply it to a volume.

For more information, please refer to [How Azure NetApp Files snapshots work](https://docs.microsoft.com/en-us/azure/azure-netapp-files/snapshots-introduction) and [Manage snapshot policies in Azure NetApp Files](https://docs.microsoft.com/en-us/azure/azure-netapp-files/snapshots-manage-policy).
101 changes: 101 additions & 0 deletions examples/netapp/nfsv3_volume_with_snapshot_policy/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
provider "azurerm" {
features {}
}

resource "azurerm_resource_group" "example" {
name = "${var.prefix}-resources"
location = var.location
}

resource "azurerm_virtual_network" "example" {
name = "${var.prefix}-virtualnetwork"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
address_space = ["10.0.0.0/16"]
}

resource "azurerm_subnet" "example" {
name = "${var.prefix}-subnet"
resource_group_name = azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.2.0/24"]

delegation {
name = "testdelegation"

service_delegation {
name = "Microsoft.Netapp/volumes"
actions = ["Microsoft.Network/networkinterfaces/*", "Microsoft.Network/virtualNetworks/subnets/join/action"]
}
}
}

resource "azurerm_netapp_account" "example" {
name = "${var.prefix}-netappaccount"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
}

resource "azurerm_netapp_snapshot_policy" "example" {
name = "${var.prefix}-snapshotpolicy"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
account_name = azurerm_netapp_account.example.name
enabled = true

hourly_schedule {
snapshots_to_keep = 4
minute = 15
}

daily_schedule {
snapshots_to_keep = 2
hour = 20
minute = 15
}

weekly_schedule {
snapshots_to_keep = 1
days_of_week = ["Monday", "Friday"]
hour = 23
minute = 0
}

monthly_schedule {
snapshots_to_keep = 1
days_of_month = [1, 15, 20, 30]
hour = 5
minute = 45
}
}

resource "azurerm_netapp_pool" "example" {
name = "${var.prefix}-netapppool"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
account_name = azurerm_netapp_account.example.name
service_level = "Standard"
size_in_tb = 4
}

resource "azurerm_netapp_volume" "example" {
lifecycle {
prevent_destroy = true
}

name = "${var.prefix}-netappvolume"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
account_name = azurerm_netapp_account.example.name
pool_name = azurerm_netapp_pool.example.name
volume_path = "${var.prefix}-netappvolume"
service_level = "Standard"
protocols = ["NFSv3"]
subnet_id = azurerm_subnet.example.id
storage_quota_in_gb = 100
security_style = "Unix"

data_protection_snapshot_policy {
snapshot_policy_id = azurerm_netapp_snapshot_policy.example.id
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
variable "location" {
description = "The Azure location where all resources in this example should be created."
}

variable "prefix" {
description = "The prefix used for all resources used by this NetApp Volume"
}
21 changes: 13 additions & 8 deletions internal/services/netapp/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import (
)

type Client struct {
AccountClient *netapp.AccountsClient
PoolClient *netapp.PoolsClient
VolumeClient *netapp.VolumesClient
SnapshotClient *netapp.SnapshotsClient
AccountClient *netapp.AccountsClient
PoolClient *netapp.PoolsClient
VolumeClient *netapp.VolumesClient
SnapshotClient *netapp.SnapshotsClient
SnapshotPoliciesClient *netapp.SnapshotPoliciesClient
}

func NewClient(o *common.ClientOptions) *Client {
Expand All @@ -25,10 +26,14 @@ func NewClient(o *common.ClientOptions) *Client {
snapshotClient := netapp.NewSnapshotsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&snapshotClient.Client, o.ResourceManagerAuthorizer)

snapshotPoliciesClient := netapp.NewSnapshotPoliciesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&snapshotPoliciesClient.Client, o.ResourceManagerAuthorizer)

return &Client{
AccountClient: &accountClient,
PoolClient: &poolClient,
VolumeClient: &volumeClient,
SnapshotClient: &snapshotClient,
AccountClient: &accountClient,
PoolClient: &poolClient,
VolumeClient: &volumeClient,
SnapshotClient: &snapshotClient,
SnapshotPoliciesClient: &snapshotPoliciesClient,
}
}
202 changes: 202 additions & 0 deletions internal/services/netapp/netapp_snapshot_policy_data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
package netapp

import (
"fmt"
"time"

"github.com/hashicorp/terraform-provider-azurerm/helpers/azure"
"github.com/hashicorp/terraform-provider-azurerm/internal/clients"
"github.com/hashicorp/terraform-provider-azurerm/internal/services/netapp/validate"
"github.com/hashicorp/terraform-provider-azurerm/internal/tags"
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azurerm/internal/timeouts"
"github.com/hashicorp/terraform-provider-azurerm/utils"
)

func dataSourceNetAppSnapshotPolicy() *pluginsdk.Resource {
return &pluginsdk.Resource{
Read: dataSourceNetAppSnapshotPolicyRead,

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

Schema: map[string]*pluginsdk.Schema{
"name": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validate.SnapshotName,
},

"resource_group_name": azure.SchemaResourceGroupName(),

"location": azure.SchemaLocationForDataSource(),

"account_name": {
Type: pluginsdk.TypeString,
Required: true,
ValidateFunc: validate.AccountName,
},

"enabled": {
Type: pluginsdk.TypeBool,
Computed: true,
},

"hourly_schedule": {
Type: pluginsdk.TypeList,
Computed: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"snapshots_to_keep": {
Type: pluginsdk.TypeInt,
Computed: true,
},
katbyte marked this conversation as resolved.
Show resolved Hide resolved

"minute": {
Type: pluginsdk.TypeInt,
Computed: true,
},
katbyte marked this conversation as resolved.
Show resolved Hide resolved
},
},
},

"daily_schedule": {
Type: pluginsdk.TypeList,
Computed: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"snapshots_to_keep": {
Type: pluginsdk.TypeInt,
Computed: true,
},
katbyte marked this conversation as resolved.
Show resolved Hide resolved

"hour": {
Type: pluginsdk.TypeInt,
Computed: true,
},
katbyte marked this conversation as resolved.
Show resolved Hide resolved

"minute": {
Type: pluginsdk.TypeInt,
Computed: true,
},
katbyte marked this conversation as resolved.
Show resolved Hide resolved
},
},
},

"weekly_schedule": {
Type: pluginsdk.TypeList,
Computed: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"snapshots_to_keep": {
Type: pluginsdk.TypeInt,
Computed: true,
},
katbyte marked this conversation as resolved.
Show resolved Hide resolved

"days_of_week": {
Type: pluginsdk.TypeSet,
Computed: true,
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeString,
},
},
katbyte marked this conversation as resolved.
Show resolved Hide resolved

"hour": {
Type: pluginsdk.TypeInt,
Computed: true,
},
katbyte marked this conversation as resolved.
Show resolved Hide resolved

"minute": {
Type: pluginsdk.TypeInt,
Computed: true,
},
katbyte marked this conversation as resolved.
Show resolved Hide resolved
},
},
},

"monthly_schedule": {
Type: pluginsdk.TypeList,
Computed: true,
Elem: &pluginsdk.Resource{
Schema: map[string]*pluginsdk.Schema{
"snapshots_to_keep": {
Type: pluginsdk.TypeInt,
Computed: true,
},
katbyte marked this conversation as resolved.
Show resolved Hide resolved

"days_of_month": {
Type: pluginsdk.TypeSet,
Computed: true,
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeInt,
},
},

"hour": {
Type: pluginsdk.TypeInt,
Computed: true,
},

"minute": {
Type: pluginsdk.TypeInt,
Computed: true,
},
},
},
},

"tags": tags.SchemaDataSource(),
},
}
}

func dataSourceNetAppSnapshotPolicyRead(d *pluginsdk.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).NetApp.SnapshotPoliciesClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

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

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

if resp.ID == nil || *resp.ID == "" {
return fmt.Errorf("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)

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

if props := resp.SnapshotPolicyProperties; props != nil {
d.Set("enabled", props.Enabled)
if err := d.Set("hourly_schedule", flattenNetAppVolumeSnapshotPolicyHourlySchedule(props.HourlySchedule)); err != nil {
return fmt.Errorf("setting `hourly_schedule`: %+v", err)
}
if err := d.Set("daily_schedule", flattenNetAppVolumeSnapshotPolicyDailySchedule(props.DailySchedule)); err != nil {
return fmt.Errorf("setting `daily_schedule`: %+v", err)
}
if err := d.Set("weekly_schedule", flattenNetAppVolumeSnapshotPolicyWeeklySchedule(props.WeeklySchedule)); err != nil {
return fmt.Errorf("setting `weekly_schedule`: %+v", err)
}
if err := d.Set("monthly_schedule", flattenNetAppVolumeSnapshotPolicyMonthlySchedule(props.MonthlySchedule)); err != nil {
return fmt.Errorf("setting `monthly_schedule`: %+v", err)
}
}

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

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check"
)

type NetAppSnapshotPolicyDataSource struct {
}

func TestAccDataSourceNetAppSnapshotPolicy_basic(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_netapp_snapshot_policy", "test")
r := NetAppSnapshotPolicyDataSource{}

data.DataSourceTest(t, []acceptance.TestStep{
{
Config: r.basic(data),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("resource_group_name").Exists(),
check.That(data.ResourceName).Key("account_name").Exists(),
check.That(data.ResourceName).Key("name").Exists(),
check.That(data.ResourceName).Key("enabled").Exists(),
),
},
})
}

func (NetAppSnapshotPolicyDataSource) basic(data acceptance.TestData) string {
return fmt.Sprintf(`
%s

data "azurerm_netapp_snapshot_policy" "test" {
name = azurerm_netapp_snapshot_policy.test.name
resource_group_name = azurerm_netapp_snapshot_policy.test.resource_group_name
account_name = azurerm_netapp_snapshot_policy.test.account_name
enabled = azurerm_netapp_snapshot_policy.test.enabled
}
`, NetAppSnapshotPolicyResource{}.basic(data))
}
Loading