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

added flexcache resource, data source and data sources. #134

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
7c8f83a
added flexcache resource, data source and data sources.
wenjun666 Feb 15, 2024
1f1ba5b
fix build fails.
wenjun666 Feb 15, 2024
d9738d4
pull intergration/main
wenjun666 Feb 23, 2024
adbd057
added missing files
wenjun666 Feb 23, 2024
41d43ff
Add edited files.
wenjun666 Feb 23, 2024
6c25289
fix build
wenjun666 Feb 23, 2024
462679c
fix flexcaches data source.
wenjun666 Feb 24, 2024
9ef5dc7
Lint.
wenjun666 Feb 28, 2024
a100454
Merge branch 'integration/main' of https://github.com/NetApp/terrafor…
wenjun666 Mar 1, 2024
87c8ffe
added import.
wenjun666 Mar 11, 2024
8bc4911
Edited docs for flexcache data source and resource
wenjun666 Mar 26, 2024
4397187
Added test for import in acc test.
wenjun666 Mar 26, 2024
1272f53
Edit generate_docs.py
wenjun666 Mar 26, 2024
9293dbc
edit flexcache acc test.
wenjun666 Apr 1, 2024
8825b54
edit flexcache example.
wenjun666 Apr 1, 2024
0eda414
edit flexcache acc test.
wenjun666 Apr 2, 2024
7826854
edit acc test.
wenjun666 Apr 2, 2024
a6465a4
edit acc test.
wenjun666 Apr 2, 2024
6990201
resolve conflict.
wenjun666 Apr 2, 2024
af2bf27
Edit test.
wenjun666 Apr 2, 2024
c2abe50
edit acc test.
wenjun666 Apr 2, 2024
f509bac
added id in read function.
wenjun666 Apr 2, 2024
f02e01c
edit acc test and reportcard.yml
wenjun666 Apr 2, 2024
db763ba
edit acc test.
wenjun666 Apr 2, 2024
1d25ce8
Edited examples/resources/netapp-ontap_storage_flexcache/resource.tf
wenjun666 Apr 3, 2024
4800da6
resolve conflict.
wenjun666 Apr 4, 2024
46c87f5
added if statements for size and size_unit
wenjun666 Apr 5, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
data "netapp-ontap_storage_flexcache_data_source" "storage_flexcache" {
# required to know which system to interface with
cx_profile_name = "cluster5"
name = "fc5"
svm_name = "automation"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
terraform {
required_providers {
netapp-ontap = {
source = "NetApp/netapp-ontap"
version = "0.0.1"
}
}
}


provider "netapp-ontap" {
# A connection profile defines how to interface with an ONTAP cluster or svm.
# At least one is required.
connection_profiles = [
{
name = "cluster1"
hostname = "********219"
username = var.username
password = var.password
validate_certs = var.validate_certs
},
{
name = "cluster2"
hostname = "********222"
username = var.username
password = var.password
validate_certs = var.validate_certs
},
{
name = "cluster3"
hostname = "10.193.176.159"
wenjun666 marked this conversation as resolved.
Show resolved Hide resolved
username = var.username
password = var.password
validate_certs = var.validate_certs
},
{
name = "cluster4"
hostname = "10.193.180.108"
wenjun666 marked this conversation as resolved.
Show resolved Hide resolved
username = var.username
password = var.password
validate_certs = var.validate_certs
},
{
name = "cluster5"
hostname = "10.193.176.186"
wenjun666 marked this conversation as resolved.
Show resolved Hide resolved
username = var.username
password = var.password
validate_certs = var.validate_certs
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Terraform will prompt for values, unless a tfvars file is present.
variable "username" {
type = string
}
variable "password" {
type = string
sensitive = true
}
variable "validate_certs" {
type = bool
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
data "netapp-ontap_storage_flexcaches_data_source" "storage_flexcache" {
# required to know which system to interface with
cx_profile_name = "cluster5"
filter = {
name = "aggr*"
svm_name = "automation"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
terraform {
required_providers {
netapp-ontap = {
source = "NetApp/netapp-ontap"
version = "0.0.1"
}
}
}


provider "netapp-ontap" {
# A connection profile defines how to interface with an ONTAP cluster or svm.
# At least one is required.
connection_profiles = [
{
name = "cluster1"
hostname = "********219"
username = var.username
password = var.password
validate_certs = var.validate_certs
},
{
name = "cluster2"
hostname = "********222"
username = var.username
password = var.password
validate_certs = var.validate_certs
},
{
name = "cluster3"
hostname = "10.193.176.159"
wenjun666 marked this conversation as resolved.
Show resolved Hide resolved
username = var.username
password = var.password
validate_certs = var.validate_certs
},
{
name = "cluster4"
hostname = "10.193.180.108"
wenjun666 marked this conversation as resolved.
Show resolved Hide resolved
username = var.username
password = var.password
validate_certs = var.validate_certs
},
{
name = "cluster5"
hostname = "10.193.176.186"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you remove the IP address

username = var.username
password = var.password
validate_certs = var.validate_certs
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Terraform will prompt for values, unless a tfvars file is present.
variable "username" {
type = string
}
variable "password" {
type = string
sensitive = true
}
variable "validate_certs" {
type = bool
}
51 changes: 51 additions & 0 deletions examples/resources/netapp-ontap_storage_flexcache/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
terraform {
required_providers {
netapp-ontap = {
source = "NetApp/netapp-ontap"
version = "0.0.1"
}
}
}


provider "netapp-ontap" {
# A connection profile defines how to interface with an ONTAP cluster or svm.
# At least one is required.
connection_profiles = [
{
name = "cluster1"
hostname = "********219"
username = var.username
password = var.password
validate_certs = var.validate_certs
},
{
name = "cluster2"
hostname = "********222"
username = var.username
password = var.password
validate_certs = var.validate_certs
},
{
name = "cluster3"
hostname = "10.193.176.159"
wenjun666 marked this conversation as resolved.
Show resolved Hide resolved
username = var.username
password = var.password
validate_certs = var.validate_certs
},
{
name = "cluster4"
hostname = "10.193.180.108"
wenjun666 marked this conversation as resolved.
Show resolved Hide resolved
username = var.username
password = var.password
validate_certs = var.validate_certs
},
{
name = "cluster5"
hostname = "10.193.176.186"
wenjun666 marked this conversation as resolved.
Show resolved Hide resolved
username = var.username
password = var.password
validate_certs = var.validate_certs
}
]
}
28 changes: 28 additions & 0 deletions examples/resources/netapp-ontap_storage_flexcache/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
resource "netapp-ontap_storage_flexcache_resource" "storage_flexcache" {
# required to know which system to interface with
cx_profile_name = "cluster5"
name = "fc10"
svm_name = "automation"
origins = [
{
volume = {
name = "vol1"
},
svm = {
name = "automation"
}
}
]
size = 400
size_unit = "mb"
guarantee = {
type = "none"
}
dr_cache = false
global_file_locking_enabled = false
aggregates = [
{
name = "aggr1"
}
]
}
11 changes: 11 additions & 0 deletions examples/resources/netapp-ontap_storage_flexcache/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Terraform will prompt for values, unless a tfvars file is present.
variable "username" {
type = string
}
variable "password" {
type = string
sensitive = true
}
variable "validate_certs" {
type = bool
}
160 changes: 160 additions & 0 deletions internal/interfaces/storage_flexcache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package interfaces

import (
"fmt"

"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/mitchellh/mapstructure"
"github.com/netapp/terraform-provider-netapp-ontap/internal/restclient"
"github.com/netapp/terraform-provider-netapp-ontap/internal/utils"
)

// StorageFlexcacheGetDataModelONTAP describes the GET record data model using go types for mapping.
type StorageFlexcacheGetDataModelONTAP struct {
Name string
SVM svm
Aggregates []StorageFlexcacheAggregate `mapstructure:"aggregates"`
Origins []StorageFlexcacheOrigin `mapstructure:"origins"`
JunctionPath string `mapstructure:"junction_path,omitempty"`
Size int `mapstructure:"size,omitempty"`
Path string `mapstructure:"path,omitempty"`
Guarantee StorageFlexcacheGuarantee `mapstructure:"guarantee,omitempty"`
DrCache bool `mapstructure:"dr_cache,omitempty"`
GlobalFileLockingEnabled bool `mapstructure:"global_file_locking_enabled,omitempty"`
UseTieredAggregate bool `mapstructure:"use_tiered_aggregate,omitempty"`
ConstituentsPerAggregate int `mapstructure:"constituents_per_aggregate,omitempty"`
UUID string
}

// StorageFlexcacheResourceModel describes the resource data model.
type StorageFlexcacheResourceModel struct {
Name string `mapstructure:"name,omitempty"`
SVM svm `mapstructure:"svm,omitempty"`
Origins []map[string]interface{} `mapstructure:"origins,omitempty"`
JunctionPath string `mapstructure:"junction_path,omitempty"`
Size int `mapstructure:"size,omitempty"`
Path string `mapstructure:"path,omitempty"`
Guarantee StorageFlexcacheGuarantee `mapstructure:"guarantee,omitempty"`
DrCache bool `mapstructure:"dr_cache"`
GlobalFileLockingEnabled bool `mapstructure:"global_file_locking_enabled"`
UseTieredAggregate bool `mapstructure:"use_tiered_aggregate"`
ConstituentsPerAggregate int `mapstructure:"constituents_per_aggregate,omitempty"`
Aggregates []map[string]interface{} `mapstructure:"aggregates,omitempty"`
}

// StorageFlexcacheGuarantee describes the guarantee data model of Guarantee within StorageFlexcacheResourceModel.
type StorageFlexcacheGuarantee struct {
Type string `mapstructure:"type,omitempty"`
}

// StorageFlexcacheOrigin describes the origin data model of Origin within StorageFlexcacheResourceModel.
type StorageFlexcacheOrigin struct {
Volume StorageFlexcacheVolume `mapstructure:"volume"`
SVM StorageFlexcacheSVM `mapstructure:"svm"`
}

// StorageFlexcacheVolume describes the volume data model of Volume within StorageFlexcacheOrigin.
type StorageFlexcacheVolume struct {
Name string `mapstructure:"name,omitempty"`
ID string `mapstructure:"uuid,omitempty"`
}

// StorageFlexcacheSVM describes the svm data model of SVM within StorageFlexcacheOrigin.
type StorageFlexcacheSVM struct {
Name string `mapstructure:"name,omitempty"`
ID string `mapstructure:"uuid,omitempty"`
}

// StorageFlexcacheAggregate describes the aggregate data model of Aggregate within StorageFlexcacheResourceModel.
type StorageFlexcacheAggregate struct {
Name string `mapstructure:"name,omitempty"`
ID string `mapstructure:"uuid,omitempty"`
}

// StorageFlexcacheDataSourceFilterModel describes the data source data model for queries.
type StorageFlexcacheDataSourceFilterModel struct {
Name string `mapstructure:"name"`
SVMName string `mapstructure:"svm.name"`
}

// GetStorageFlexcacheByName to get flexcache info by name.
func GetStorageFlexcacheByName(errorHandler *utils.ErrorHandler, r restclient.RestClient, name string, svmName string) (*StorageFlexcacheGetDataModelONTAP, error) {
query := r.NewQuery()
query.Add("name", name)
query.Add("svm.name", svmName)
query.Fields([]string{"size", "path", "origins", "guarantee.type", "constituents_per_aggregate", "dr_cache", "global_file_locking_enabled", "use_tiered_aggregate", "aggregates"})
statusCode, response, err := r.GetNilOrOneRecord("storage/flexcache/flexcaches", query, nil)
if err != nil {
return nil, errorHandler.MakeAndReportError("error reading flexcache info", fmt.Sprintf("error on GET storage/flexcache/flexcaches: %s", err))
}
var dataONTAP *StorageFlexcacheGetDataModelONTAP
if err := mapstructure.Decode(response, &dataONTAP); err != nil {
return nil, errorHandler.MakeAndReportError("error decoding flexcache info", fmt.Sprintf("error on decode storage/flexcache/flexcaches: %s, statusCode %d, response %#v", err, statusCode, response))
}
tflog.Debug(errorHandler.Ctx, fmt.Sprintf("Read flexcache source - udata: %#v", dataONTAP))
return dataONTAP, nil
}

// GetStorageFlexcaches to get flexcaches info by filter
func GetStorageFlexcaches(errorHandler *utils.ErrorHandler, r restclient.RestClient, filter *StorageFlexcacheDataSourceFilterModel) ([]StorageFlexcacheGetDataModelONTAP, error) {
api := "storage/flexcache/flexcaches"
query := r.NewQuery()
query.Fields([]string{"size", "path", "origins", "guarantee.type", "constituents_per_aggregate", "dr_cache", "global_file_locking_enabled", "use_tiered_aggregate", "aggregates"})
if filter != nil {
var filterMap map[string]interface{}
if err := mapstructure.Decode(filter, &filterMap); err != nil {
return nil, errorHandler.MakeAndReportError("error encoding storage flexcache filter info", fmt.Sprintf("error on filter %#v: %s", filter, err))
}
query.SetValues(filterMap)
}

statusCode, response, err := r.GetZeroOrMoreRecords(api, query, nil)
if err == nil && response == nil {
err = fmt.Errorf("no response for GET %s", api)
}
if err != nil {
return nil, errorHandler.MakeAndReportError("error reading storage flexcache info", fmt.Sprintf("error on GET %s: %s, statusCode %d", api, err, statusCode))
}

var dataONTAP []StorageFlexcacheGetDataModelONTAP
for _, info := range response {
var record StorageFlexcacheGetDataModelONTAP
if err := mapstructure.Decode(info, &record); err != nil {
return nil, errorHandler.MakeAndReportError(fmt.Sprintf("failed to decode response from GET %s", api),
fmt.Sprintf("error: %s, statusCode %d, info %#v", err, statusCode, info))
}
dataONTAP = append(dataONTAP, record)
}
tflog.Debug(errorHandler.Ctx, fmt.Sprintf("Read storage flexcache data source: %#v", dataONTAP))
return dataONTAP, nil
}

// POST API returns result, but does not include the attributes that are not set. Make a spearate GET call to get all attributes.
func CreateStorageFlexcache(errorHandler *utils.ErrorHandler, r restclient.RestClient, data StorageFlexcacheResourceModel) error {
var body map[string]interface{}
if err := mapstructure.Decode(data, &body); err != nil {
return errorHandler.MakeAndReportError("error encoding flexcache body", fmt.Sprintf("error on encoding storage/flexcache/flexcaches body: %s, body: %#v", err, data))
}
//The use-tiered-aggregate option is only supported when auto provisioning the FlexCache volume
if _, ok := body["aggregates"]; ok {
delete(body, "use_tiered_aggregate")
}
query := r.NewQuery()
query.Add("return_records", "false")
statusCode, _, err := r.CallCreateMethod("storage/flexcache/flexcaches", query, body)
if err != nil {
return errorHandler.MakeAndReportError("error creating flexcache", fmt.Sprintf("error on POST storage/flexcache/flexcaches: %s, statusCode %d", err, statusCode))
}

return nil

}

// DeleteStorageFlexcache to delete flexcache by id.
func DeleteStorageFlexcache(errorHandler *utils.ErrorHandler, r restclient.RestClient, id string) error {
statusCode, _, err := r.CallDeleteMethod("storage/flexcache/flexcaches/"+id, nil, nil)
if err != nil {
return errorHandler.MakeAndReportError("error deleting flexcache", fmt.Sprintf("error on DELETE storage/flexcache/flexcaches: %s, statusCode %d", err, statusCode))
}
return nil
}
Loading