From f76fe78f766b1c3ec1d7274cc643919aabbec0c9 Mon Sep 17 00:00:00 2001 From: Chris Archibald Date: Fri, 18 Aug 2023 19:09:57 +0000 Subject: [PATCH] Sync bitbucket and GitHub --- README.md | 2 +- .../cluster_licensing_license_test.go | 57 +++ .../cluster_schedule_resource_test.go | 153 +++++++ internal/provider/config_test.go | 106 +++++ internal/provider/example_data_source_test.go | 23 + internal/provider/example_resource_test.go | 49 +++ .../networking_ip_interface_resource_test.go | 80 ++++ .../networking_ip_route_resource_test.go | 136 ++++++ ...otocols_nfs_export_policy_resource_test.go | 59 +++ .../protocols_nfs_service_resource_test.go | 77 ++++ internal/provider/provider_test.go | 22 + .../snapmirror_policy_resource_test.go | 412 ++++++++++++++++++ .../storage_aggregate_resource_test.go | 65 +++ .../provider/storage_snapshot_policy_test.go | 81 ++++ .../provider/storage_volume_resource_test.go | 67 +++ .../storage_volume_snapshot_resource_test.go | 74 ++++ internal/provider/svm_resource_test.go | 81 ++++ scripts/acctest.sh | 16 +- scripts/coverage.sh | 2 +- 19 files changed, 1559 insertions(+), 3 deletions(-) create mode 100644 internal/provider/cluster_licensing_license_test.go create mode 100644 internal/provider/cluster_schedule_resource_test.go create mode 100644 internal/provider/config_test.go create mode 100644 internal/provider/example_data_source_test.go create mode 100644 internal/provider/example_resource_test.go create mode 100644 internal/provider/networking_ip_interface_resource_test.go create mode 100644 internal/provider/networking_ip_route_resource_test.go create mode 100644 internal/provider/protocols_nfs_export_policy_resource_test.go create mode 100644 internal/provider/protocols_nfs_service_resource_test.go create mode 100644 internal/provider/provider_test.go create mode 100644 internal/provider/snapmirror_policy_resource_test.go create mode 100644 internal/provider/storage_aggregate_resource_test.go create mode 100644 internal/provider/storage_snapshot_policy_test.go create mode 100644 internal/provider/storage_volume_resource_test.go create mode 100644 internal/provider/storage_volume_snapshot_resource_test.go create mode 100644 internal/provider/svm_resource_test.go diff --git a/README.md b/README.md index bb7d06ea..254bf4d6 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ - NetApp logo + NetApp logo diff --git a/internal/provider/cluster_licensing_license_test.go b/internal/provider/cluster_licensing_license_test.go new file mode 100644 index 00000000..f9ae554e --- /dev/null +++ b/internal/provider/cluster_licensing_license_test.go @@ -0,0 +1,57 @@ +package provider + +import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "os" + "regexp" + "testing" +) + +func TestLicensingLicenseResouce(t *testing.T) { + testLicense := os.Getenv("TF_ACC_NETAPP_LICENSE") + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccLicensingLicenseResourceConfig("testme"), + ExpectError: regexp.MustCompile("1115159"), + }, + { + Config: testAccLicensingLicenseResourceConfig(testLicense), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_cluster_licensing_license_resource.cluster_licensing_license", "name", "insight_balance")), + }, + }, + }) +} + +func testAccLicensingLicenseResourceConfig(key string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_cluster_licensing_license_resource" "cluster_licensing_license" { + # required to know which system to interface with + cx_profile_name = "cluster4" + keys = ["%s"] +} +`, host, admin, password, key) +} diff --git a/internal/provider/cluster_schedule_resource_test.go b/internal/provider/cluster_schedule_resource_test.go new file mode 100644 index 00000000..4e0c4a4e --- /dev/null +++ b/internal/provider/cluster_schedule_resource_test.go @@ -0,0 +1,153 @@ +package provider + +import ( + "fmt" + "os" + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccClusterScheduleResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Test create interval schedule error + { + Config: testAccClusterScheduleResourceIntervalConfig("non-existant", "wrongvalue"), + ExpectError: regexp.MustCompile("error creating cluster_schedule"), + }, + // Create intervale and read + { + Config: testAccClusterScheduleResourceIntervalConfig("tf-interval-schedule-test", "PT8M30S"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_cluster_schedule_resource.example", "name", "tf-interval-schedule-test"), + resource.TestCheckResourceAttr("netapp-ontap_cluster_schedule_resource.example", "interval", "PT8M30S"), + ), + }, + // update and read + { + Config: testAccClusterScheduleResourceIntervalConfig("tf-interval-schedule-test", "PT8M20S"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_cluster_schedule_resource.example", "name", "tf-interval-schedule-test"), + resource.TestCheckResourceAttr("netapp-ontap_cluster_schedule_resource.example", "interval", "PT8M20S"), + ), + }, + // Create cron schedule and read + { + Config: testAccClusterScheduleCreateResourceCronConfig("tf-cron-schedule-test"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_cluster_schedule_resource.cron-example", "name", "tf-cron-schedule-test"), + ), + }, + // Update cron schedule and read + { + Config: testAccClusterScheduleUpdateResourceCronConfig("tf-cron-schedule-test"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_cluster_schedule_resource.cron-example", "name", "tf-cron-schedule-test"), + ), + }, + }, + }) +} + +func testAccClusterScheduleResourceIntervalConfig(name string, interval string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_cluster_schedule_resource" "example" { + # required to know which system to interface with + cx_profile_name = "cluster4" + name = "%s" + interval = "%s" +}`, host, admin, password, name, interval) +} + +func testAccClusterScheduleCreateResourceCronConfig(name string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_cluster_schedule_resource" "cron-example" { + # required to know which system to interface with + cx_profile_name = "cluster4" + name = "%s" + cron = { + minutes = [1, 2, 3, 4] + hours = [10] + days = [1, 2] + months = [6, 7] + weekdays = [1, 3, 4] + } +}`, host, admin, password, name) +} + +func testAccClusterScheduleUpdateResourceCronConfig(name string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_cluster_schedule_resource" "cron-example" { + # required to know which system to interface with + cx_profile_name = "cluster4" + name = "%s" + cron = { + minutes = [4, 5, 6] + hours = [2, 3] + days = [2] + months = [1, 6, 7] + weekdays = [3, 4, 5] + } +}`, host, admin, password, name) +} diff --git a/internal/provider/config_test.go b/internal/provider/config_test.go new file mode 100644 index 00000000..00637d5f --- /dev/null +++ b/internal/provider/config_test.go @@ -0,0 +1,106 @@ +package provider + +import ( + "context" + "reflect" + "testing" + + "github.com/hashicorp/terraform-plugin-framework/diag" + "github.com/netapp/terraform-provider-netapp-ontap/internal/restclient" + "github.com/netapp/terraform-provider-netapp-ontap/internal/utils" +) + +func TestConfig_GetConnectionProfile(t *testing.T) { + type fields struct { + ConnectionProfiles map[string]ConnectionProfile + Version string + } + type args struct { + name string + } + cxProfile := ConnectionProfile{} + cxProfiles := map[string]ConnectionProfile{"empty": cxProfile} + cxProfilesTwo := map[string]ConnectionProfile{"empty1": cxProfile, "empty2": cxProfile} + tests := []struct { + name string + fields fields + args args + want *ConnectionProfile + wantErr bool + }{ + {name: "test_found", fields: fields{ConnectionProfiles: cxProfiles, Version: "v1.2.3"}, args: args{name: "empty"}, want: &cxProfile, wantErr: false}, + {name: "test_found_one_profile_no_name", fields: fields{ConnectionProfiles: cxProfiles, Version: "v1.2.3"}, args: args{name: ""}, want: &cxProfile, wantErr: false}, + {name: "test_not_found", fields: fields{ConnectionProfiles: cxProfiles, Version: "v1.2.3"}, args: args{name: "other"}, want: nil, wantErr: true}, + {name: "test_no_config", fields: fields{ConnectionProfiles: cxProfiles, Version: "v1.2.3"}, args: args{name: "other"}, want: nil, wantErr: true}, + {name: "test_no_profiles", fields: fields{ConnectionProfiles: map[string]ConnectionProfile{}, Version: "v1.2.3"}, args: args{name: "other"}, want: nil, wantErr: true}, + {name: "test_two_profiles_no_name", fields: fields{ConnectionProfiles: cxProfilesTwo, Version: "v1.2.3"}, args: args{name: ""}, want: nil, wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Config{ + ConnectionProfiles: tt.fields.ConnectionProfiles, + Version: tt.fields.Version, + } + if tt.name == "test_no_config" { + c = nil + } + + got, err := c.GetConnectionProfile(tt.args.name) + if (err != nil) != tt.wantErr { + t.Errorf("Config.GetConnectionProfile() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Config.GetConnectionProfile() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConfig_NewClient(t *testing.T) { + type fields struct { + ConnectionProfiles map[string]ConnectionProfile + Version string + } + cxProfile := ConnectionProfile{} + cxProfiles := map[string]ConnectionProfile{"empty": cxProfile} + // cxProfilesTwo := map[string]ConnectionProfile{"empty1": cxProfile, "empty2": cxProfile} + restClient, err := restclient.NewClient(context.Background(), restclient.ConnectionProfile{}, "TerrafromONTAP/config_test/v1.2.3", 600) + if err != nil { + panic(err) + } + errorHandler := utils.NewErrorHandler(context.Background(), &diag.Diagnostics{}) + + tests := []struct { + name string + fields fields + cxProfileName string + resName string + want *restclient.RestClient + wantErr bool + }{ + {name: "test_found", fields: fields{ConnectionProfiles: cxProfiles, Version: "v1.2.3"}, cxProfileName: "empty", resName: "config_test", want: restClient, wantErr: false}, + {name: "test_not_found", fields: fields{ConnectionProfiles: cxProfiles, Version: "v1.2.3"}, cxProfileName: "other", want: nil, wantErr: true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := &Config{ + ConnectionProfiles: tt.fields.ConnectionProfiles, + Version: tt.fields.Version, + } + got, err := c.NewClient(errorHandler, tt.cxProfileName, tt.resName) + if (err != nil) != tt.wantErr { + t.Errorf("Config.NewClient() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got == nil || tt.want == nil { + if got != tt.want { + t.Errorf("Config.NewClient() error = %v, wantErr %v", err, tt.wantErr) + return + } + } else if ok, diffs := tt.want.Equals(got); !ok { + t.Errorf(diffs) + } + }) + } +} diff --git a/internal/provider/example_data_source_test.go b/internal/provider/example_data_source_test.go new file mode 100644 index 00000000..9562dba0 --- /dev/null +++ b/internal/provider/example_data_source_test.go @@ -0,0 +1,23 @@ +package provider + +//func TestAccExampleDataSource(t *testing.T) { +// resource.Test(t, resource.TestCase{ +// PreCheck: func() { testAccPreCheck(t) }, +// ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, +// Steps: []resource.TestStep{ +// // Read testing +// { +// Config: testAccExampleDataSourceConfig, +// Check: resource.ComposeAggregateTestCheckFunc( +// resource.TestCheckResourceAttr("data.netapp-ontap_example.test", "id", "example-id"), +// ), +// }, +// }, +// }) +//} + +const testAccExampleDataSourceConfig = ` +data "netapp-ontap_example" "test" { + configurable_attribute = "example" +} +` diff --git a/internal/provider/example_resource_test.go b/internal/provider/example_resource_test.go new file mode 100644 index 00000000..cf4f89ec --- /dev/null +++ b/internal/provider/example_resource_test.go @@ -0,0 +1,49 @@ +package provider + +import ( + "fmt" +) + +//func TestAccExampleResource(t *testing.T) { +// resource.Test(t, resource.TestCase{ +// PreCheck: func() { testAccPreCheck(t) }, +// ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, +// Steps: []resource.TestStep{ +// // Create and Read testing +// { +// Config: testAccExampleResourceConfig("one"), +// Check: resource.ComposeAggregateTestCheckFunc( +// resource.TestCheckResourceAttr("netapp-ontap_example.test", "configurable_attribute", "one"), +// resource.TestCheckResourceAttr("netapp-ontap_example.test", "id", "example-id"), +// ), +// }, +// // ImportState testing +// { +// ResourceName: "netapp-ontap_example.test", +// ImportState: true, +// ImportStateVerify: true, +// // This is not normally necessary, but is here because this +// // example code does not have an actual upstream service. +// // Once the Read method is able to refresh information from +// // the upstream service, this can be removed. +// ImportStateVerifyIgnore: []string{"configurable_attribute"}, +// }, +// // Update and Read testing +// { +// Config: testAccExampleResourceConfig("two"), +// Check: resource.ComposeAggregateTestCheckFunc( +// resource.TestCheckResourceAttr("netapp-ontap_example.test", "configurable_attribute", "two"), +// ), +// }, +// // Delete testing automatically occurs in TestCase +// }, +// }) +//} + +func testAccExampleResourceConfig(configurableAttribute string) string { + return fmt.Sprintf(` +resource "netapp-ontap_example" "test" { + configurable_attribute = %[1]q +} +`, configurableAttribute) +} diff --git a/internal/provider/networking_ip_interface_resource_test.go b/internal/provider/networking_ip_interface_resource_test.go new file mode 100644 index 00000000..c021cb77 --- /dev/null +++ b/internal/provider/networking_ip_interface_resource_test.go @@ -0,0 +1,80 @@ +package provider + +import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "os" + "regexp" + "testing" +) + +func TestAccNetworkingIpInterfaceResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // non-existant SVM return code 2621462. Must happen before create/read + { + Config: testAccNetworkingIPInterfaceResourceConfig("non-existant", "10.10.10.10", "ontap_cluster_1-01"), + ExpectError: regexp.MustCompile("2621462"), + }, + // non-existant homeport + { + Config: testAccNetworkingIPInterfaceResourceConfig("carchi-test", "10.10.10.10", "non-existant_home_node"), + ExpectError: regexp.MustCompile("393271"), + }, + // Create and Read + { + Config: testAccNetworkingIPInterfaceResourceConfig("carchi-test", "10.10.10.10", "ontap_cluster_1-01"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_networking_ip_interface_resource.example", "name", "test-interface"), + resource.TestCheckResourceAttr("netapp-ontap_networking_ip_interface_resource.example", "svm_name", "carchi-test"), + ), + }, + // Update and Read (when update is implemented this is what it would look like) + //{ + // Config: testAccNetworkingIPInterfaceResourceConfig("carchi-test", "10.10.10.20"), + // Check: resource.ComposeTestCheckFunc( + // resource.TestCheckResourceAttr("netapp-ontap_networking_ip_interface_resource.example", "name", "test-interface", "ontap_cluster_1-01"), + // ), + //}, + }, + }) +} + +func testAccNetworkingIPInterfaceResourceConfig(svmName, address, homeNode string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_networking_ip_interface_resource" "example" { + cx_profile_name = "cluster4" + name = "test-interface" + svm_name = "%s" + ip = { + address = "%s" + netmask = 18 + } + location = { + home_port = "e0d" + home_node = "%s" + } +} +`, host, admin, password, svmName, address, homeNode) +} diff --git a/internal/provider/networking_ip_route_resource_test.go b/internal/provider/networking_ip_route_resource_test.go new file mode 100644 index 00000000..8a6cd0a5 --- /dev/null +++ b/internal/provider/networking_ip_route_resource_test.go @@ -0,0 +1,136 @@ +package provider + +import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "os" + "regexp" + "testing" +) + +func TestAccNetworkingIpRouteResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Missing Required argument + { + Config: testAccNetworkingIPIRouteResourceConfigMissingVars("non-existent"), + ExpectError: regexp.MustCompile("Missing required argument"), + }, + // Non existent SVM + { + Config: testAccNetworkingIPIRouteResourceConfig("non-existent"), + ExpectError: regexp.MustCompile("2621462"), + }, + // Test create with no gateway + { + Config: testAccNetworkingIPIRouteResourceConfig("ansibleSVM"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_networking_ip_route_resource.example", "svm_name", "ansibleSVM"), + resource.TestCheckResourceAttr("netapp-ontap_networking_ip_route_resource.example", "destination.address", "0.0.0.0"), + resource.TestCheckResourceAttr("netapp-ontap_networking_ip_route_resource.example", "destination.netmask", "0"), + ), + }, + // test create with a gateway + { + Config: testAccNetworkingIPIRouteResourceWithGatewayConfig("ansibleSVM", "10.10.10.254", 20), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_networking_ip_route_resource.example", "svm_name", "ansibleSVM"), + resource.TestCheckResourceAttr("netapp-ontap_networking_ip_route_resource.example", "destination.address", "10.10.10.254"), + resource.TestCheckResourceAttr("netapp-ontap_networking_ip_route_resource.example", "destination.netmask", "20"), + ), + }, + }, + }) +} + +func testAccNetworkingIPIRouteResourceConfig(svmName string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_networking_ip_route_resource" "example" { + cx_profile_name = "cluster4" + svm_name = "%s" + gateway = "10.10.10.1" +} +`, host, admin, password, svmName) +} + +func testAccNetworkingIPIRouteResourceWithGatewayConfig(svmName string, address string, netmask int) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_networking_ip_route_resource" "example" { + cx_profile_name = "cluster4" + svm_name = "%s" + gateway = "10.10.10.1" + destination = { + address = "%s" + netmask = %d + } +} +`, host, admin, password, svmName, address, netmask) +} + +func testAccNetworkingIPIRouteResourceConfigMissingVars(svmName string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_networking_ip_route_resource" "example" { + cx_profile_name = "cluster4" + svm_name = "%s" +} +`, host, admin, password, svmName) +} diff --git a/internal/provider/protocols_nfs_export_policy_resource_test.go b/internal/provider/protocols_nfs_export_policy_resource_test.go new file mode 100644 index 00000000..670bacb0 --- /dev/null +++ b/internal/provider/protocols_nfs_export_policy_resource_test.go @@ -0,0 +1,59 @@ +package provider + +import ( + "fmt" + "os" + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccNFSExportPolicyResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccNFSExportPolicyResourceConfig("non-existant"), + ExpectError: regexp.MustCompile("svm non-existant not found"), + }, + // Read testing + { + Config: testAccNFSExportPolicyResourceConfig("carchi-test"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_protocols_nfs_export_policy_resource.example", "name", "acc_test"), + resource.TestCheckNoResourceAttr("netapp-ontap_protocols_nfs_export_policy_resource.example", "volname"), + ), + }, + }, + }) +} + +func testAccNFSExportPolicyResourceConfig(svm string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_protocols_nfs_export_policy_resource" "example" { + cx_profile_name = "cluster4" + svm_name = "%s" + name = "acc_test" +}`, host, admin, password, svm) +} diff --git a/internal/provider/protocols_nfs_service_resource_test.go b/internal/provider/protocols_nfs_service_resource_test.go new file mode 100644 index 00000000..f83a9dfa --- /dev/null +++ b/internal/provider/protocols_nfs_service_resource_test.go @@ -0,0 +1,77 @@ +package provider + +import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "os" + "regexp" + "testing" +) + +func TestAccNfsServiceResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Test error + { + Config: testAccNfsServiceResourceConfig("non-existant", "false"), + ExpectError: regexp.MustCompile("svm non-existant not found."), + }, + // Create and read + { + Config: testAccNfsServiceResourceConfig("carchi-test", "false"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_protocols_nfs_service_resource.example", "svm_name", "carchi-test"), + resource.TestCheckResourceAttr("netapp-ontap_protocols_nfs_service_resource.example", "protocol.v3_enabled", "false"), + resource.TestCheckResourceAttr("netapp-ontap_protocols_nfs_service_resource.example", "protocol.v40_enabled", "true"), + ), + }, + // update and read + { + Config: testAccNfsServiceResourceConfig("carchi-test", "true"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_protocols_nfs_service_resource.example", "svm_name", "carchi-test"), + resource.TestCheckResourceAttr("netapp-ontap_protocols_nfs_service_resource.example", "protocol.v3_enabled", "true"), + resource.TestCheckResourceAttr("netapp-ontap_protocols_nfs_service_resource.example", "protocol.v40_enabled", "true"), + ), + }, + }, + }) +} + +func testAccNfsServiceResourceConfig(svnName, enableV3 string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_protocols_nfs_service_resource" "example" { + # required to know which system to interface with + cx_profile_name = "cluster4" + svm_name = "%s" + enabled = true + protocol = { + v3_enabled = "%s" + v40_enabled = true + v40_features = { + acl_enabled = true + } + } +}`, host, admin, password, svnName, enableV3) +} diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go new file mode 100644 index 00000000..e73af8ba --- /dev/null +++ b/internal/provider/provider_test.go @@ -0,0 +1,22 @@ +package provider + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-framework/providerserver" + "github.com/hashicorp/terraform-plugin-go/tfprotov6" +) + +// testAccProtoV6ProviderFactories are used to instantiate a provider during +// acceptance testing. The factory function will be invoked for every Terraform +// CLI command executed to create a provider server to which the CLI can +// reattach. +var testAccProtoV6ProviderFactories = map[string]func() (tfprotov6.ProviderServer, error){ + "netapp-ontap": providerserver.NewProtocol6WithError(New("test")()), +} + +func testAccPreCheck(t *testing.T) { + // You can add code here to run prior to any test case execution, for example assertions + // about the appropriate environment variables being set are common to see in a pre-check + // function. +} diff --git a/internal/provider/snapmirror_policy_resource_test.go b/internal/provider/snapmirror_policy_resource_test.go new file mode 100644 index 00000000..4c26e996 --- /dev/null +++ b/internal/provider/snapmirror_policy_resource_test.go @@ -0,0 +1,412 @@ +package provider + +import ( + "fmt" + "os" + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccSnapmirrorPolicyResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Test snapmirror policy error + { + Config: testAccSnapmirrorPolicyResourceBasicConfig("non-existant"), + ExpectError: regexp.MustCompile("2621462"), + }, + // Test create snapmirror policy basic + { + Config: testAccSnapmirrorPolicyResourceBasicConfig("ansibleSVM"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "name", "carchitestme4"), + ), + }, + // Test adding transfer_schedule + { + Config: testAccSnapmirrorPolicyResourceAddTransferScheduleBasicConfig("ansibleSVM", "weekly"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "name", "carchitestme4"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "transfer_schedule_name", "weekly"), + ), + }, + // Test update transfer_schedule + { + Config: testAccSnapmirrorPolicyResourceAddTransferScheduleBasicConfig("ansibleSVM", "daily"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "name", "carchitestme4"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "transfer_schedule_name", "daily"), + ), + }, + // Test remove snapmirror policy transfer schedule + { + Config: testAccSnapmirrorPolicyResourceBasicConfig("ansibleSVM"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "name", "carchitestme4"), + ), + }, + // Test add snapmirror policy with comment and identity_preservation + { + Config: testAccSnapmirrorPolicyResourceConfig("ansibleSVM", "test comment", "full"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "name", "carchitestme4"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "comment", "test comment"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "identity_preservation", "full"), + ), + }, + // Test update snapmirror policy with comment and identity_preservation change + { + Config: testAccSnapmirrorPolicyResourceConfig("ansibleSVM", "update comment", "exclude_network_config"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "name", "carchitestme4"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "comment", "update comment"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "identity_preservation", "exclude_network_config"), + ), + }, + // Test update snapmirror policy with adding two retention rules + { + Config: testAccSnapmirrorPolicyResourceAddTwoRetentionConfig("ansibleSVM", "update comment", "exclude_network_config", "weekly", 5), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "name", "carchitestme4"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "comment", "update comment"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "identity_preservation", "exclude_network_config"), + // check number of reteion + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "retention.#", "2"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "retention.0.label", "hourly"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "retention.0.count", "7"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "retention.1.label", "weekly"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "retention.1.count", "5"), + ), + }, + // Test update snapmirror policy with removing one retention rule + { + Config: testAccSnapmirrorPolicyResourceRemoveOneRetentionConfig("ansibleSVM", "update comment", "exclude_network_config"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "name", "carchitestme4"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "comment", "update comment"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "identity_preservation", "exclude_network_config"), + // check number of reteion + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "retention.#", "1"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "retention.0.label", "hourly"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.example", "retention.0.count", "7"), + ), + }, + // Test create sync type snapmirror policy + { + Config: testAccSnapmirrorPolicyResourceSyncBasicConfig("ansibleSVM", "test sync"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.sync_example", "name", "test_sync"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.sync_example", "comment", "test sync"), + ), + }, + // Test update sync type snapmirror policy with changing comment + { + Config: testAccSnapmirrorPolicyResourceSyncBasicConfig("ansibleSVM", "test update sync comment"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.sync_example", "name", "test_sync"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.sync_example", "comment", "test update sync comment"), + ), + }, + // Test update sync type snapmirror policy with adding a retention + { + Config: testAccSnapmirrorPolicyResourceSyncAddRetentionConfig("ansibleSVM", "test add retenion in sync type"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.sync_example", "name", "test_sync"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.sync_example", "comment", "test add retenion in sync type"), + // check number of reteion + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.sync_example", "retention.#", "1"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.sync_example", "retention.0.label", "daily"), + resource.TestCheckResourceAttr("netapp-ontap_snapmirror_policy_resource.sync_example", "retention.0.count", "1"), + ), + }, + // Test update sync type snapmirror policy with adding extra retention - max is 1 + { + Config: testAccSnapmirrorPolicyResourceSyncAddExtraRetentionConfig("ansibleSVM", "test add extra retenion in sync type"), + ExpectError: regexp.MustCompile("error updating sync snapshot policies"), + }, + }, + }) +} + +func testAccSnapmirrorPolicyResourceBasicConfig(svm string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_snapmirror_policy_resource" "example" { + cx_profile_name = "cluster4" + name = "carchitestme4" + svm_name = "%s" + type = "async" +}`, host, admin, password, svm) +} + +func testAccSnapmirrorPolicyResourceAddTransferScheduleBasicConfig(svm string, transferScheduleName string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_snapmirror_policy_resource" "example" { + cx_profile_name = "cluster4" + name = "carchitestme4" + svm_name = "%s" + type = "async" + transfer_schedule_name = "%s" +}`, host, admin, password, svm, transferScheduleName) +} + +func testAccSnapmirrorPolicyResourceConfig(svm string, comment string, identityPreservation string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_snapmirror_policy_resource" "example" { + cx_profile_name = "cluster4" + name = "carchitestme4" + svm_name = "%s" + comment = "%s" + identity_preservation = "%s" + type = "async" +}`, host, admin, password, svm, comment, identityPreservation) +} + +func testAccSnapmirrorPolicyResourceAddTwoRetentionConfig(svm string, comment string, identityPreservation string, label string, count int) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_snapmirror_policy_resource" "example" { + cx_profile_name = "cluster4" + name = "carchitestme4" + svm_name = "%s" + comment = "%s" + identity_preservation = "%s" + type = "async" + retention = [ + { + label = "hourly" + count = 7 + creation_schedule_name = "hourly" + }, + { + label = "%s" + count = %d + }, + ] +}`, host, admin, password, svm, comment, identityPreservation, label, count) +} + +func testAccSnapmirrorPolicyResourceRemoveOneRetentionConfig(svm string, comment string, identityPreservation string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_snapmirror_policy_resource" "example" { + cx_profile_name = "cluster4" + name = "carchitestme4" + svm_name = "%s" + comment = "%s" + identity_preservation = "%s" + type = "async" + retention = [ + { + label = "hourly" + count = 7 + creation_schedule_name = "hourly" + } + ] +}`, host, admin, password, svm, comment, identityPreservation) +} + +func testAccSnapmirrorPolicyResourceSyncBasicConfig(svm string, comment string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_snapmirror_policy_resource" "sync_example" { + cx_profile_name = "cluster4" + name = "test_sync" + svm_name = "%s" + type = "sync" + sync_type = "sync" + comment = "%s" +}`, host, admin, password, svm, comment) +} + +func testAccSnapmirrorPolicyResourceSyncAddRetentionConfig(svm string, comment string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_snapmirror_policy_resource" "sync_example" { + cx_profile_name = "cluster4" + name = "test_sync" + svm_name = "%s" + type = "sync" + sync_type = "sync" + comment = "%s" + retention = [ + { + label = "daily" + count = 1 + } + ] +}`, host, admin, password, svm, comment) +} + +func testAccSnapmirrorPolicyResourceSyncAddExtraRetentionConfig(svm string, comment string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_snapmirror_policy_resource" "sync_example" { + cx_profile_name = "cluster4" + name = "test_sync" + svm_name = "%s" + type = "sync" + sync_type = "sync" + comment = "%s" + retention = [ + { + label = "daily" + count = 1 + }, + { + label = "daily" + count = 1 + } + ] +}`, host, admin, password, svm, comment) +} diff --git a/internal/provider/storage_aggregate_resource_test.go b/internal/provider/storage_aggregate_resource_test.go new file mode 100644 index 00000000..1233e1e2 --- /dev/null +++ b/internal/provider/storage_aggregate_resource_test.go @@ -0,0 +1,65 @@ +package provider + +import ( + "fmt" + "os" + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccStorageAggregateResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccStorageAggregateResourceConfig("non-existant"), + ExpectError: regexp.MustCompile("is an invalid value"), + }, + { + Config: testAccStorageAggregateResourceConfig("swenjun-vsim1"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_storage_aggregate_resource.example", "name", "acc_test_aggr"), + resource.TestCheckNoResourceAttr("netapp-ontap_storage_aggregate_resource.example", "vol"), + ), + }, + }, + }) +} + +func testAccStorageAggregateResourceConfig(node string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST2") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST2, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_storage_aggregate_resource" "example" { + cx_profile_name = "cluster4" + node = "%s" + name = "acc_test_aggr" + disk_count = 5 + disk_size = 1 + disk_size_unit= "gb" + is_mirrored = false + raid_type = "raid4" + snaplock_type = "compliance" + encryption = true +}`, host, admin, password, node) +} diff --git a/internal/provider/storage_snapshot_policy_test.go b/internal/provider/storage_snapshot_policy_test.go new file mode 100644 index 00000000..765549b6 --- /dev/null +++ b/internal/provider/storage_snapshot_policy_test.go @@ -0,0 +1,81 @@ +package provider + +import ( + "fmt" + "os" + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccStorageSnapshotPolicyResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Test create storage snapshot policy error + { + Config: testAccStorageSnapshotPolicyResourceConfig("non-existant", "unknowsvm", "wrong case", false), + ExpectError: regexp.MustCompile("error creating storage_snapshot_policy"), + }, + // Create create storage snapshot policy and read + { + Config: testAccStorageSnapshotPolicyResourceConfig("tf-sn-policy", "carchi-test", "create a test snapshot policy", true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_storage_snapshot_policy_resource.example", "name", "tf-sn-policy"), + resource.TestCheckResourceAttr("netapp-ontap_storage_snapshot_policy_resource.example", "comment", "create a test snapshot policy"), + resource.TestCheckResourceAttr("netapp-ontap_storage_snapshot_policy_resource.example", "enabled", "true"), + ), + }, + // Update storage snapshot policy on comment and read + { + Config: testAccStorageSnapshotPolicyResourceConfig("tf-sn-policy", "carchi-test", "Update the existing snapshot policy", true), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_storage_snapshot_policy_resource.example", "name", "tf-sn-policy"), + resource.TestCheckResourceAttr("netapp-ontap_storage_snapshot_policy_resource.example", "comment", "Update the existing snapshot policy"), + resource.TestCheckResourceAttr("netapp-ontap_storage_snapshot_policy_resource.example", "enabled", "true"), + ), + }, + }, + }) +} + +func testAccStorageSnapshotPolicyResourceConfig(name string, svmname string, comment string, enabled bool) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_storage_snapshot_policy_resource" "example" { + # required to know which system to interface with + cx_profile_name = "cluster4" + name = "%s" + svm_name = "%s" + comment = "%s" + enabled = "%t" + copies = [ + { + count = 3 + schedule = { + name = "daily" + } + }, + ] +}`, host, admin, password, name, svmname, comment, enabled) +} diff --git a/internal/provider/storage_volume_resource_test.go b/internal/provider/storage_volume_resource_test.go new file mode 100644 index 00000000..fe48f61a --- /dev/null +++ b/internal/provider/storage_volume_resource_test.go @@ -0,0 +1,67 @@ +package provider + +import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "os" + "regexp" + "testing" +) + +func TestAccStorageVolumeResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Test non existant SVM + { + Config: testAccStorageVolumeResourceConfig("non-existant", "terraformTest4"), + ExpectError: regexp.MustCompile("2621462"), + }, + // test bad volume name + { + Config: testAccStorageVolumeResourceConfig("non-existant", "name-cant-have-dashes"), + ExpectError: regexp.MustCompile("917888"), + }, + // Read testing + { + Config: testAccStorageVolumeResourceConfig("carchi-test", "terraformTest4"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_storage_volume_resource.example", "name", "terraformTest4"), + resource.TestCheckNoResourceAttr("netapp-ontap_storage_volume_resource.example", "volname"), + ), + }, + }, + }) +} + +func testAccStorageVolumeResourceConfig(svm, volName string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_storage_volume_resource" "example" { + cx_profile_name = "cluster4" + name = "%s" + svm_name = "%s" + aggregates = ["aggr2"] + size = 20 + size_unit = "mb" +}`, host, admin, password, volName, svm) +} diff --git a/internal/provider/storage_volume_snapshot_resource_test.go b/internal/provider/storage_volume_snapshot_resource_test.go new file mode 100644 index 00000000..0c8cc905 --- /dev/null +++ b/internal/provider/storage_volume_snapshot_resource_test.go @@ -0,0 +1,74 @@ +package provider + +import ( + "fmt" + "os" + "regexp" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccStorageVolumeSnapshotResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // non-existant SVM return code 2621462. Must happen before create/read + { + Config: testAccStorageVolumeSnapshotResourceConfig("non-existant", "my comment"), + ExpectError: regexp.MustCompile("Error: No svm found"), + }, + // Create and read testing + { + Config: testAccStorageVolumeSnapshotResourceConfig("carchi-test", "my comment"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_storage_volume_snapshot_resource.example", "volume_name", "carchi_test_root"), + resource.TestCheckResourceAttr("netapp-ontap_storage_volume_snapshot_resource.example", "name", "snaptest"), + resource.TestCheckResourceAttr("netapp-ontap_storage_volume_snapshot_resource.example", "svm_name", "carchi-test"), + resource.TestCheckResourceAttr("netapp-ontap_storage_volume_snapshot_resource.example", "comment", "my comment"), + ), + }, + // Update and read testing + { + Config: testAccStorageVolumeSnapshotResourceConfig("carchi-test", "new comment"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_storage_volume_snapshot_resource.example", "volume_name", "carchi_test_root"), + resource.TestCheckResourceAttr("netapp-ontap_storage_volume_snapshot_resource.example", "name", "snaptest"), + resource.TestCheckResourceAttr("netapp-ontap_storage_volume_snapshot_resource.example", "svm_name", "carchi-test"), + resource.TestCheckResourceAttr("netapp-ontap_storage_volume_snapshot_resource.example", "comment", "new comment"), + ), + }, + }, + }) +} + +func testAccStorageVolumeSnapshotResourceConfig(svmName string, comment string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_storage_volume_snapshot_resource" "example" { + cx_profile_name = "cluster4" + name = "snaptest" + volume_name = "carchi_test_root" + svm_name = "%s" + comment = "%s" +}`, host, admin, password, svmName, comment) +} diff --git a/internal/provider/svm_resource_test.go b/internal/provider/svm_resource_test.go new file mode 100644 index 00000000..33626ebc --- /dev/null +++ b/internal/provider/svm_resource_test.go @@ -0,0 +1,81 @@ +package provider + +import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "os" + "regexp" + "testing" +) + +func TestAccSvmResource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + ProtoV6ProviderFactories: testAccProtoV6ProviderFactories, + Steps: []resource.TestStep{ + { + Config: testAccSvmResourceConfig("tfsvm4", "test"), + Check: resource.ComposeTestCheckFunc( + // Check to see the svm name is correct, + resource.TestCheckResourceAttr("netapp-ontap_svm_resource.example", "name", "tfsvm4"), + // Check to see if Ipspace is set correctly + resource.TestCheckResourceAttr("netapp-ontap_svm_resource.example", "ipspace", "ansibleIpspace_newname"), + // Check that a UUID has been set (we don't know what the vaule is as it changes + resource.TestCheckResourceAttrSet("netapp-ontap_svm_resource.example", "uuid"), + resource.TestCheckResourceAttr("netapp-ontap_svm_resource.example", "comment", "test")), + }, + // Update a comment + { + Config: testAccSvmResourceConfig("tfsvm4", "carchi8py was here"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_svm_resource.example", "comment", "carchi8py was here"), + resource.TestCheckResourceAttr("netapp-ontap_svm_resource.example", "name", "tfsvm4")), + }, + // change SVM name + { + Config: testAccSvmResourceConfig("tfsvm3", "carchi8py was here"), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("netapp-ontap_svm_resource.example", "comment", "carchi8py was here"), + resource.TestCheckResourceAttr("netapp-ontap_svm_resource.example", "name", "tfsvm3")), + }, + // Fail if the name already exist + { + Config: testAccSvmResourceConfig("svm5", "carchi8py was here"), + ExpectError: regexp.MustCompile("13434908"), + }, + }, + }) +} +func testAccSvmResourceConfig(svm, comment string) string { + host := os.Getenv("TF_ACC_NETAPP_HOST") + admin := os.Getenv("TF_ACC_NETAPP_USER") + password := os.Getenv("TF_ACC_NETAPP_PASS") + if host == "" || admin == "" || password == "" { + fmt.Println("TF_ACC_NETAPP_HOST, TF_ACC_NETAPP_USER, and TF_ACC_NETAPP_PASS must be set for acceptance tests") + os.Exit(1) + } + return fmt.Sprintf(` +provider "netapp-ontap" { + connection_profiles = [ + { + name = "cluster4" + hostname = "%s" + username = "%s" + password = "%s" + validate_certs = false + }, + ] +} + +resource "netapp-ontap_svm_resource" "example" { + cx_profile_name = "cluster4" + name = "%s" + ipspace = "ansibleIpspace_newname" + comment = "%s" + snapshot_policy = "default-1weekly" + //subtype = "dp_destination" + language = "en_us.utf_8" + aggregates = ["aggr2"] + max_volumes = "200" +}`, host, admin, password, svm, comment) +} diff --git a/scripts/acctest.sh b/scripts/acctest.sh index 747fa918..1dbe6472 100755 --- a/scripts/acctest.sh +++ b/scripts/acctest.sh @@ -1,6 +1,20 @@ #!/usr/bin/env bash org_dir=$(pwd) +export TF_ACC=1 +#export TF_ACC_NETAPP_HOST="" +#export TF_ACC_NETAPP_HOST2=">" +#export TF_ACC_NETAPP_USER="admin" +#export TF_ACC_NETAPP_PASS="" +#export TF_ACC_NETAPP_LICENSE="" +rm -rf $org_dir/test mkdir $org_dir/test -TF_ACC=1 go test github.com/netapp/terraform-provider-netapp-ontap/internal/provider/acceptancetests -v || { echo "Build finished in error due to failed tests" && exit 1; } +go test -cover -coverprofile $org_dir/test/cover.out `go list ./... | grep -e provider` +if [ $? -eq 0 ] +then + go tool cover -html=$org_dir/test/cover.out +else + echo "Build finished in error due to failed tests" + exit 1 +fi diff --git a/scripts/coverage.sh b/scripts/coverage.sh index 9115ff79..e92cf8c9 100755 --- a/scripts/coverage.sh +++ b/scripts/coverage.sh @@ -4,7 +4,7 @@ org_dir=$(pwd) rm -rf $org_dir/test mkdir $org_dir/test -go test -coverprofile $org_dir/test/cover.out `go list ./... | grep -v acceptancetests` +go test -coverprofile $org_dir/test/cover.out `go list ./... | grep -v provider` if [ $? -eq 0 ] then go tool cover -html=$org_dir/test/cover.out