diff --git a/CHANGELOG.md b/CHANGELOG.md index c5706101..ab3e7119 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +## 1.8.1 (April 18, 2023) +[Full Changelog](https://github.com/nutanix/terraform-provider-nutanix/compare/feat/1.8.0-ga...feat/1.8.1) + +**New Feature:** +- Added a datasource for NDB network available ips. [\#570](https://github.com/nutanix/terraform-provider-nutanix/pull/570) + + New Data Source : + - nutanix_ndb_network_available_ips + +**Implemented enhancements:** +- Handling the case if ndb cluster id is given wrong. [\#571](https://github.com/nutanix/terraform-provider-nutanix/pull/571) +- Support for imports on ndb day-2 actions. [\#561](https://github.com/nutanix/terraform-provider-nutanix/pull/561) +- Changing the provider version in ndb examples from beta to ga. [\#580](https://github.com/nutanix/terraform-provider-nutanix/pull/580) + +**Fixed bugs:** +- Tf ntnx provider crash for wrong ndb cluster id. [\#567](https://github.com/nutanix/terraform-provider-nutanix/issues/567) +- lcm_config should be Set without plugin crash in clone resource. [\#583](https://github.com/nutanix/terraform-provider-nutanix/issues/583) + +**Closed issues:** +- NDB datasource for network available ips. [\#569](https://github.com/nutanix/terraform-provider-nutanix/issues/569) +- Support for adding import on ndb day2 actions. [\#582](https://github.com/nutanix/terraform-provider-nutanix/issues/582) +- How to configure IP address for Nutanix Packer images. [\#576](https://github.com/nutanix/terraform-provider-nutanix/issues/576) + + ## 1.8.0 (Feb 23, 2023) [Full Changelog](https://github.com/nutanix/terraform-provider-nutanix/compare/feat/v1.8.0-beta-2...feat/1.8.0-ga) diff --git a/README.md b/README.md index 88f3d23c..f274a6a1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Terraform provider plugin to integrate with Nutanix Enterprise Cloud -NOTE: The latest version of the Nutanix provider is [v1.8.0-beta.2](https://github.com/nutanix/terraform-provider-nutanix/releases/tag/v1.8.0-beta.2) +NOTE: The latest version of the Nutanix provider is [v1.8.1](https://github.com/nutanix/terraform-provider-nutanix/releases/tag/v1.8.1) Modules based on Terraform Nutanix Provider can be found here : [Modules](https://github.com/nutanix/terraform-provider-nutanix/tree/master/modules) ## Build, Quality Status @@ -79,7 +79,9 @@ Foundation Central based modules and examples : Foundation based modules & examp > For the 1.8.0 release of the provider, it will have N-2 compatibility with the Nutanix database service. This release was tested with v2.5.1.1, v2.5.1 and v2.5 versions. -Note: For 1.8.0 release, only postgress database type is qualified and officially supported. Older versions of NDB may not support some resources. +> For the 1.8.1 release of the provider, it will have N-2 compatibility with the Nutanix database service. This release was tested with v2.5.1.1, v2.5.1 and v2.5 versions. + +Note: For NDB related modules, only postgress database type is qualified and officially supported. Older versions of NDB may not support some resources. Checkout example : https://github.com/nutanix/terraform-provider-nutanix/blob/master/examples/ndb/ @@ -285,6 +287,7 @@ From foundation getting released in 1.5.0-beta, provider configuration will acco * nutanix_ndb_networks * nutanix_ndb_maintenance_window * nutanix_ndb_maintenance_windows +* nutanix_ndb_network_available_ips ## Quick Install diff --git a/client/era/era_service.go b/client/era/era_service.go index 483ea513..60a036db 100644 --- a/client/era/era_service.go +++ b/client/era/era_service.go @@ -67,10 +67,10 @@ type Service interface { UpdateTimeMachineCluster(ctx context.Context, tmsID string, clsID string, body *TmsClusterIntentInput) (*TmsClusterResponse, error) DeleteTimeMachineCluster(ctx context.Context, tmsID string, clsID string, body *DeleteTmsClusterInput) (*ProvisionDatabaseResponse, error) CreateTags(ctx context.Context, body *CreateTagsInput) (*TagsIntentResponse, error) - ReadTags(ctx context.Context, id string) (*GetTagsResponse, error) + ReadTags(ctx context.Context, id string, name string) (*GetTagsResponse, error) UpdateTags(ctx context.Context, body *GetTagsResponse, id string) (*GetTagsResponse, error) DeleteTags(ctx context.Context, id string) (*string, error) - ListTags(ctx context.Context) (*ListTagsResponse, error) + ListTags(ctx context.Context, entityType string) (*ListTagsResponse, error) CreateNetwork(ctx context.Context, body *NetworkIntentInput) (*NetworkIntentResponse, error) GetNetwork(ctx context.Context, id string, name string) (*NetworkIntentResponse, error) UpdateNetwork(ctx context.Context, body *NetworkIntentInput, id string) (*NetworkIntentResponse, error) @@ -91,6 +91,7 @@ type Service interface { CreateCluster(ctx context.Context, body *ClusterIntentInput) (*ProvisionDatabaseResponse, error) UpdateCluster(ctx context.Context, req *ClusterUpdateInput, id string) (*ListClusterResponse, error) DeleteCluster(ctx context.Context, req *DeleteClusterInput, id string) (*ProvisionDatabaseResponse, error) + GetAvailableIPs(ctx context.Context, id string) (*GetNetworkAvailableIPs, error) } type ServiceClient struct { @@ -317,7 +318,7 @@ func (sc ServiceClient) GetOperation(req GetOperationRequest) (*GetOperationResp } func (sc ServiceClient) GetDatabaseInstance(ctx context.Context, dbInstanceID string) (*GetDatabaseResponse, error) { - httpReq, err := sc.c.NewRequest(ctx, http.MethodGet, fmt.Sprintf("/databases/%s?detailed=false&load-dbserver-cluster=false", dbInstanceID), nil) + httpReq, err := sc.c.NewRequest(ctx, http.MethodGet, fmt.Sprintf("/databases/%s?detailed=true&load-dbserver-cluster=false", dbInstanceID), nil) if err != nil { return nil, err } @@ -759,8 +760,16 @@ func (sc ServiceClient) CreateTimeMachineCluster(ctx context.Context, tmsID stri return res, sc.c.Do(ctx, httpReq, res) } -func (sc ServiceClient) ReadTags(ctx context.Context, id string) (*GetTagsResponse, error) { - httpReq, err := sc.c.NewRequest(ctx, http.MethodGet, fmt.Sprintf("/tags?id=%s", id), nil) +func (sc ServiceClient) ReadTags(ctx context.Context, id, name string) (*GetTagsResponse, error) { + path := "/tags" + if id != "" { + path += fmt.Sprintf("?id=%s", id) + } + if name != "" { + path += fmt.Sprintf("?name=%s", name) + } + + httpReq, err := sc.c.NewRequest(ctx, http.MethodGet, path, nil) if err != nil { return nil, err } @@ -898,8 +907,12 @@ func (sc ServiceClient) DeleteNetwork(ctx context.Context, id string) (*string, return res, sc.c.Do(ctx, httpReq, res) } -func (sc ServiceClient) ListTags(ctx context.Context) (*ListTagsResponse, error) { - httpReq, err := sc.c.NewRequest(ctx, http.MethodGet, "/tags", nil) +func (sc ServiceClient) ListTags(ctx context.Context, entityType string) (*ListTagsResponse, error) { + path := "/tags" + if entityType != "" { + path += fmt.Sprintf("?entityType=%s", entityType) + } + httpReq, err := sc.c.NewRequest(ctx, http.MethodGet, path, nil) if err != nil { return nil, err } @@ -909,7 +922,7 @@ func (sc ServiceClient) ListTags(ctx context.Context) (*ListTagsResponse, error) } func (sc ServiceClient) ListNetwork(ctx context.Context) (*ListNetworkResponse, error) { - httpReq, err := sc.c.NewRequest(ctx, http.MethodGet, "/resources/networks", nil) + httpReq, err := sc.c.NewRequest(ctx, http.MethodGet, "/resources/networks?detailed=true", nil) if err != nil { return nil, err } @@ -1057,3 +1070,12 @@ func (sc ServiceClient) UpdateCluster(ctx context.Context, req *ClusterUpdateInp res := new(ListClusterResponse) return res, sc.c.Do(ctx, httpReq, res) } + +func (sc ServiceClient) GetAvailableIPs(ctx context.Context, id string) (*GetNetworkAvailableIPs, error) { + httpReq, err := sc.c.NewRequest(ctx, http.MethodGet, fmt.Sprintf("/profiles/%s/get-available-ips", id), nil) + if err != nil { + return nil, err + } + res := new(GetNetworkAvailableIPs) + return res, sc.c.Do(ctx, httpReq, res) +} diff --git a/client/era/era_structs.go b/client/era/era_structs.go index b9ef0433..3c4792f2 100644 --- a/client/era/era_structs.go +++ b/client/era/era_structs.go @@ -1598,8 +1598,10 @@ type GetTagsResponse struct { type ListTagsResponse []*GetTagsResponse type IPAddresses struct { - IP *string `json:"ip,omitempty"` - Status *string `json:"status,omitempty"` + IP *string `json:"ip,omitempty"` + Status *string `json:"status,omitempty"` + DBServerID *string `json:"dbserverID,omitempty"` + DBServerName *string `json:"dbserverName,omitempty"` } type IPPools struct { @@ -1635,6 +1637,7 @@ type NetworkIntentResponse struct { PropertiesMap *NetworkPropertiesmap `json:"propertiesMap,omitempty"` StretchedVlanID *string `json:"stretchedVlanId,omitempty"` IPPools []*IPPools `json:"ipPools,omitempty"` + IPAddresses []*IPAddresses `json:"ipAddresses,omitempty"` } type ListNetworkResponse []*NetworkIntentResponse @@ -1969,3 +1972,14 @@ type ClusterUpdateInput struct { Description *string `json:"description,omitempty"` IPAddresses []*string `json:"ipAddresses,omitempty"` } + +type GetNetworkAvailableIPs []struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + PropertyName *string `json:"propertyName,omitempty"` + Type *string `json:"type,omitempty"` + ClusterID *string `json:"clusterId,omitempty"` + ClusterName *string `json:"clusterName,omitempty"` + IPAddresses []*string `json:"ipAddresses,omitempty"` + Managed bool `json:"managed,omitempty"` +} diff --git a/examples/ndb/database_instance/main.tf b/examples/ndb/database_instance/main.tf index c301983b..2686a2ce 100644 --- a/examples/ndb/database_instance/main.tf +++ b/examples/ndb/database_instance/main.tf @@ -2,7 +2,7 @@ terraform{ required_providers { nutanix = { source = "nutanix/nutanix" - version = "1.8.0-beta.2" + version = "1.8.0" } } } diff --git a/examples/ndb/database_restore/main.tf b/examples/ndb/database_restore/main.tf index 0f47530c..31cffdc5 100644 --- a/examples/ndb/database_restore/main.tf +++ b/examples/ndb/database_restore/main.tf @@ -2,7 +2,7 @@ terraform{ required_providers { nutanix = { source = "nutanix/nutanix" - version = "1.8.0-beta.2" + version = "1.8.0" } } } diff --git a/examples/ndb/linked_databases/main.tf b/examples/ndb/linked_databases/main.tf index 8cdb8e09..815f5c7e 100644 --- a/examples/ndb/linked_databases/main.tf +++ b/examples/ndb/linked_databases/main.tf @@ -2,7 +2,7 @@ terraform{ required_providers { nutanix = { source = "nutanix/nutanix" - version = "1.8.0-beta.2" + version = "1.8.0" } } } diff --git a/examples/ndb/profiles/main.tf b/examples/ndb/profiles/main.tf index d23acf18..bd957f96 100644 --- a/examples/ndb/profiles/main.tf +++ b/examples/ndb/profiles/main.tf @@ -2,7 +2,7 @@ terraform{ required_providers { nutanix = { source = "nutanix/nutanix" - version = "1.8.0-beta.2" + version = "1.8.0" } } } diff --git a/nutanix/common_schema_validation.go b/nutanix/common_schema_validation.go index 43efcd7a..75276250 100644 --- a/nutanix/common_schema_validation.go +++ b/nutanix/common_schema_validation.go @@ -7,8 +7,7 @@ import ( ) var requiredResourceFields map[string][]string = map[string][]string{ - "era_provision_database": {"databasetype", "softwareprofileid", "softwareprofileversionid", "computeprofileid", - "networkprofileid", "dbparameterprofileid", "nxclusterid", "sshpublickey", "timemachineinfo", "nodes"}, + "era_provision_database": {"databasetype", "dbparameterprofileid", "timemachineinfo", "nodes"}, } func schemaValidation(resourceName string, d *schema.ResourceData) error { diff --git a/nutanix/data_source_nutanix_ndb_cluster.go b/nutanix/data_source_nutanix_ndb_cluster.go index c4a55b46..83d05bdd 100644 --- a/nutanix/data_source_nutanix_ndb_cluster.go +++ b/nutanix/data_source_nutanix_ndb_cluster.go @@ -183,7 +183,7 @@ func dataSourceNutanixEraClusterRead(ctx context.Context, d *schema.ResourceData resp, err := conn.Service.GetCluster(ctx, clusterID.(string), clusterName.(string)) if err != nil { - diag.FromErr(err) + return diag.FromErr(err) } if err := d.Set("id", resp.ID); err != nil { diff --git a/nutanix/data_source_nutanix_ndb_cluster_test.go b/nutanix/data_source_nutanix_ndb_cluster_test.go index b4e929e5..4da238c7 100644 --- a/nutanix/data_source_nutanix_ndb_cluster_test.go +++ b/nutanix/data_source_nutanix_ndb_cluster_test.go @@ -1,13 +1,13 @@ package nutanix import ( + "regexp" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) func TestAccEraClusterDataSource_basic(t *testing.T) { - // r := randIntBetween(31, 40) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccEraPreCheck(t) }, Providers: testAccProviders, @@ -45,6 +45,19 @@ func TestAccEraClusterDataSource_ByName(t *testing.T) { }) } +func TestAccEraClusterDataSource_WithWrongID(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccEraPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccEraClusterDataSourceConfigWithWrongID(), + ExpectError: regexp.MustCompile("exit status 1"), + }, + }, + }) +} + func testAccEraClusterDataSourceConfig() string { return ` data "nutanix_ndb_clusters" "test1" {} @@ -66,3 +79,11 @@ func testAccEraClusterDataSourceConfigByName() string { } ` } + +func testAccEraClusterDataSourceConfigWithWrongID() string { + return ` + data "nutanix_ndb_cluster" "test" { + cluster_id = "0000000-0000-0000-0000-00000000000" + } + ` +} diff --git a/nutanix/data_source_nutanix_ndb_network.go b/nutanix/data_source_nutanix_ndb_network.go index a6bd66fd..278567f1 100644 --- a/nutanix/data_source_nutanix_ndb_network.go +++ b/nutanix/data_source_nutanix_ndb_network.go @@ -5,6 +5,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + era "github.com/terraform-providers/terraform-provider-nutanix/client/era" ) func dataSourceNutanixEraNetwork() *schema.Resource { @@ -81,6 +82,62 @@ func dataSourceNutanixEraNetwork() *schema.Resource { }, }, }, + "ip_addresses": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "dbserver_id": { + Type: schema.TypeString, + Computed: true, + }, + "dbserver_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "ip_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "start_ip": { + Type: schema.TypeString, + Computed: true, + }, + "end_ip": { + Type: schema.TypeString, + Computed: true, + }, + "addresses": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, }, } } @@ -135,6 +192,38 @@ func dataSourceNutanixEraNetworkRead(ctx context.Context, d *schema.ResourceData d.Set("stretched_vlan_id", resp.StretchedVlanID) } + if resp.IPAddresses != nil { + d.Set("ip_addresses", flattenIPAddress(resp.IPAddresses)) + } + if resp.IPPools != nil { + d.Set("ip_pools", flattenIPPools(resp.IPPools)) + } d.SetId(*resp.ID) return nil } + +func flattenIPAddress(ips []*era.IPAddresses) []interface{} { + if len(ips) > 0 { + ipList := make([]interface{}, 0) + + for _, v := range ips { + ip := map[string]interface{}{} + + if v.IP != nil { + ip["ip"] = v.IP + } + if v.Status != nil { + ip["status"] = v.Status + } + if v.DBServerID != nil { + ip["dbserver_id"] = v.DBServerID + } + if v.DBServerName != nil { + ip["dbserver_name"] = v.DBServerName + } + ipList = append(ipList, ip) + } + return ipList + } + return nil +} diff --git a/nutanix/data_source_nutanix_ndb_networks.go b/nutanix/data_source_nutanix_ndb_networks.go index 4e6f367d..0b1d902f 100644 --- a/nutanix/data_source_nutanix_ndb_networks.go +++ b/nutanix/data_source_nutanix_ndb_networks.go @@ -86,6 +86,62 @@ func dataSourceNutanixEraNetworks() *schema.Resource { }, }, }, + "ip_addresses": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + "dbserver_id": { + Type: schema.TypeString, + Computed: true, + }, + "dbserver_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "ip_pools": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "start_ip": { + Type: schema.TypeString, + Computed: true, + }, + "end_ip": { + Type: schema.TypeString, + Computed: true, + }, + "addresses": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "ip": { + Type: schema.TypeString, + Computed: true, + }, + "status": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + }, + }, }, }, }, @@ -134,6 +190,12 @@ func flattenNetworkListResponse(ntw *era.ListNetworkResponse) []interface{} { if v.StretchedVlanID != nil { val["stretched_vlan_id"] = v.StretchedVlanID } + if v.IPPools != nil { + val["ip_pools"] = flattenIPPools(v.IPPools) + } + if v.IPAddresses != nil { + val["ip_addresses"] = flattenIPAddress(v.IPAddresses) + } networkList = append(networkList, val) } diff --git a/nutanix/data_source_nutanix_ndb_profiles.go b/nutanix/data_source_nutanix_ndb_profiles.go index 37c83d25..a0d20911 100644 --- a/nutanix/data_source_nutanix_ndb_profiles.go +++ b/nutanix/data_source_nutanix_ndb_profiles.go @@ -393,6 +393,12 @@ func flattenProfilesResponse(erp *Era.ProfileListResponse) []map[string]interfac d["latest_version"] = v.Latestversion d["latest_version_id"] = v.Latestversionid d["versions"] = flattenVersions(v.Versions) + if v.Clusteravailability != nil { + d["cluster_availability"] = flattenClusterAvailability(v.Clusteravailability) + } + if v.Nxclusterid != nil { + d["nx_cluster_id"] = v.Nxclusterid + } lst = append(lst, d) } diff --git a/nutanix/data_source_nutanix_ndb_profiles_available_ips.go b/nutanix/data_source_nutanix_ndb_profiles_available_ips.go new file mode 100644 index 00000000..e90cb437 --- /dev/null +++ b/nutanix/data_source_nutanix_ndb_profiles_available_ips.go @@ -0,0 +1,107 @@ +package nutanix + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + era "github.com/terraform-providers/terraform-provider-nutanix/client/era" + "github.com/terraform-providers/terraform-provider-nutanix/utils" +) + +func dataSourceNutanixNDBProfileAvailableIPs() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceNutanixNDBProfileAvailableIPsRead, + Schema: map[string]*schema.Schema{ + "profile_id": { + Type: schema.TypeString, + Required: true, + }, + "available_ips": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "property_name": { + Type: schema.TypeString, + Computed: true, + }, + "type": { + Type: schema.TypeString, + Computed: true, + }, + "managed": { + Type: schema.TypeBool, + Computed: true, + }, + "ip_addresses": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "cluster_id": { + Type: schema.TypeString, + Computed: true, + }, + "cluster_name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func dataSourceNutanixNDBProfileAvailableIPsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + conn := meta.(*Client).Era + + profileID := "" + if ID, ok := d.GetOk("profile_id"); ok { + profileID = ID.(string) + } + resp, err := conn.Service.GetAvailableIPs(ctx, profileID) + if err != nil { + return diag.FromErr(err) + } + + if e := d.Set("available_ips", flattenAvailableIPsResponse(resp)); err != nil { + return diag.FromErr(e) + } + + d.SetId(profileID) + return nil +} + +func flattenAvailableIPsResponse(ips *era.GetNetworkAvailableIPs) []map[string]interface{} { + if ips != nil { + lst := []map[string]interface{}{} + for _, v := range *ips { + d := map[string]interface{}{} + + d["id"] = v.ID + d["name"] = v.Name + d["property_name"] = v.PropertyName + d["type"] = v.Type + d["managed"] = v.Managed + d["cluster_id"] = v.ClusterID + d["cluster_name"] = v.ClusterName + d["ip_addresses"] = utils.StringValueSlice(v.IPAddresses) + + lst = append(lst, d) + } + return lst + } + return nil +} diff --git a/nutanix/data_source_nutanix_ndb_profiles_available_ips_test.go b/nutanix/data_source_nutanix_ndb_profiles_available_ips_test.go new file mode 100644 index 00000000..52be388e --- /dev/null +++ b/nutanix/data_source_nutanix_ndb_profiles_available_ips_test.go @@ -0,0 +1,49 @@ +package nutanix + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccEraProfilesAvailableIPsDataSource_basic(t *testing.T) { + networkName := testVars.NDB.TestStaticNetwork + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccEraPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccEraProfilesAvailableIPsDataSourceConfig(networkName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.nutanix_ndb_network_available_ips.ips", "available_ips.#"), + resource.TestCheckResourceAttrSet("data.nutanix_ndb_network_available_ips.ips", "available_ips.0.id"), + resource.TestCheckResourceAttrSet("data.nutanix_ndb_network_available_ips.ips", "available_ips.0.name"), + resource.TestCheckResourceAttrSet("data.nutanix_ndb_network_available_ips.ips", "available_ips.0.type"), + resource.TestCheckResourceAttrSet("data.nutanix_ndb_network_available_ips.ips", "available_ips.0.managed"), + resource.TestCheckResourceAttrSet("data.nutanix_ndb_network_available_ips.ips", "available_ips.0.ip_addresses.#"), + ), + }, + }, + }) +} + +func testAccEraProfilesAvailableIPsDataSourceConfig(networkName string) string { + return fmt.Sprintf(` + data "nutanix_ndb_profiles" "test" { + profile_type = "Network" + } + + locals { + my_vlan_static = { + for obj in data.nutanix_ndb_profiles.test.profiles : + obj.name => obj + if obj.name == "%[1]s" + }["%[1]s"] + } + + data "nutanix_ndb_network_available_ips" "ips"{ + profile_id = local.my_vlan_static.id + } + `, networkName) +} diff --git a/nutanix/data_source_nutanix_ndb_tag.go b/nutanix/data_source_nutanix_ndb_tag.go index 744b944e..f41bce09 100644 --- a/nutanix/data_source_nutanix_ndb_tag.go +++ b/nutanix/data_source_nutanix_ndb_tag.go @@ -12,12 +12,16 @@ func dataSourceNutanixNDBTag() *schema.Resource { ReadContext: dataSourceNutanixNDBTagRead, Schema: map[string]*schema.Schema{ "id": { - Type: schema.TypeString, - Required: true, + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"name"}, }, "name": { - Type: schema.TypeString, - Computed: true, + Type: schema.TypeString, + Optional: true, + Computed: true, + ConflictsWith: []string{"id"}, }, "description": { Type: schema.TypeString, @@ -58,8 +62,14 @@ func dataSourceNutanixNDBTag() *schema.Resource { func dataSourceNutanixNDBTagRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*Client).Era - tagID := d.Get("id") - resp, err := conn.Service.ReadTags(ctx, tagID.(string)) + tagID, iok := d.GetOk("id") + tagName, nok := d.GetOk("name") + + if !iok && !nok { + return diag.Errorf("please provide one of id or name attributes") + } + + resp, err := conn.Service.ReadTags(ctx, tagID.(string), tagName.(string)) if err != nil { return diag.FromErr(err) } @@ -100,6 +110,6 @@ func dataSourceNutanixNDBTagRead(ctx context.Context, d *schema.ResourceData, me return diag.FromErr(err) } - d.SetId(tagID.(string)) + d.SetId(*resp.ID) return nil } diff --git a/nutanix/data_source_nutanix_ndb_tag_test.go b/nutanix/data_source_nutanix_ndb_tag_test.go index 764e67ff..bf860092 100644 --- a/nutanix/data_source_nutanix_ndb_tag_test.go +++ b/nutanix/data_source_nutanix_ndb_tag_test.go @@ -1,18 +1,20 @@ package nutanix import ( + "fmt" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) func TestAccEraTagDataSource_basic(t *testing.T) { + r := randIntBetween(10, 20) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccEraPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ { - Config: testAccEraTagDataSourceConfig(), + Config: testAccEraTagDataSourceConfig(r), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("data.nutanix_ndb_tags.tags", "tags.#"), resource.TestCheckResourceAttrSet("data.nutanix_ndb_tags.tags", "tags.0.name"), @@ -25,10 +27,30 @@ func TestAccEraTagDataSource_basic(t *testing.T) { }) } -func testAccEraTagDataSourceConfig() string { - return ` +func TestAccEraTagDataSource_ByName(t *testing.T) { + r := randIntBetween(21, 30) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccEraPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccEraTagDataSourceConfigByName(r), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.nutanix_ndb_tags.tags", "tags.#"), + resource.TestCheckResourceAttrSet("data.nutanix_ndb_tags.tags", "tags.0.name"), + resource.TestCheckResourceAttrSet("data.nutanix_ndb_tags.tags", "tags.0.status"), + resource.TestCheckResourceAttr("data.nutanix_ndb_tag.tag", "values", "0"), + resource.TestCheckResourceAttr("data.nutanix_ndb_tag.tag", "status", "ENABLED"), + ), + }, + }, + }) +} + +func testAccEraTagDataSourceConfig(r int) string { + return fmt.Sprintf(` resource "nutanix_ndb_tag" "acctest-managed" { - name= "test-tag" + name= "test-tag-%[1]d" description = "test tag description" entity_type = "DATABASE" required = false @@ -39,5 +61,22 @@ func testAccEraTagDataSourceConfig() string { data "nutanix_ndb_tag" "tag"{ id = data.nutanix_ndb_tags.tags.tags.0.id } - ` + `, r) +} + +func testAccEraTagDataSourceConfigByName(r int) string { + return fmt.Sprintf(` + resource "nutanix_ndb_tag" "acctest-managed" { + name= "test-tag-name-%[1]d" + description = "test tag description" + entity_type = "DATABASE" + required = false + } + + data "nutanix_ndb_tags" "tags"{ } + + data "nutanix_ndb_tag" "tag"{ + name = data.nutanix_ndb_tags.tags.tags.0.name + } + `, r) } diff --git a/nutanix/data_source_nutanix_ndb_tags.go b/nutanix/data_source_nutanix_ndb_tags.go index 311b11fd..f2fe1526 100644 --- a/nutanix/data_source_nutanix_ndb_tags.go +++ b/nutanix/data_source_nutanix_ndb_tags.go @@ -6,6 +6,7 @@ import ( "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" era "github.com/terraform-providers/terraform-provider-nutanix/client/era" ) @@ -13,6 +14,12 @@ func dataSourceNutanixNDBTags() *schema.Resource { return &schema.Resource{ ReadContext: dataSourceNutanixNDBTagsRead, Schema: map[string]*schema.Schema{ + "entity_type": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"DATABASE", "TIME_MACHINE", + "CLONE", "DATABASE_SERVER"}, false), + }, "tags": { Type: schema.TypeList, Computed: true, @@ -68,7 +75,12 @@ func dataSourceNutanixNDBTags() *schema.Resource { func dataSourceNutanixNDBTagsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*Client).Era - resp, err := conn.Service.ListTags(ctx) + entityType := "" + if entity, eok := d.GetOk("entity_type"); eok { + entityType = entity.(string) + } + + resp, err := conn.Service.ListTags(ctx, entityType) if err != nil { return diag.FromErr(err) } diff --git a/nutanix/data_source_nutanix_ndb_tags_test.go b/nutanix/data_source_nutanix_ndb_tags_test.go index 43868e2d..bc49915c 100644 --- a/nutanix/data_source_nutanix_ndb_tags_test.go +++ b/nutanix/data_source_nutanix_ndb_tags_test.go @@ -1,18 +1,20 @@ package nutanix import ( + "fmt" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) func TestAccEraTagsDataSource_basic(t *testing.T) { + r := randIntBetween(11, 15) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccEraPreCheck(t) }, Providers: testAccProviders, Steps: []resource.TestStep{ { - Config: testAccEraTagsDataSourceConfig(), + Config: testAccEraTagsDataSourceConfig(r), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttrSet("data.nutanix_ndb_tags.tags", "tags.#"), resource.TestCheckResourceAttrSet("data.nutanix_ndb_tags.tags", "tags.0.name"), @@ -28,15 +30,54 @@ func TestAccEraTagsDataSource_basic(t *testing.T) { }) } -func testAccEraTagsDataSourceConfig() string { - return ` +func TestAccEraTagsDataSource_WithEntityType(t *testing.T) { + r := randIntBetween(21, 25) + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccEraPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccEraTagsDataSourceConfigWithEntityType(r), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.nutanix_ndb_tags.tags", "tags.#"), + resource.TestCheckResourceAttrSet("data.nutanix_ndb_tags.tags", "tags.0.name"), + resource.TestCheckResourceAttrSet("data.nutanix_ndb_tags.tags", "tags.0.status"), + resource.TestCheckResourceAttrSet("data.nutanix_ndb_tags.tags", "tags.0.values"), + resource.TestCheckResourceAttrSet("data.nutanix_ndb_tags.tags", "tags.0.status"), + resource.TestCheckResourceAttrSet("data.nutanix_ndb_tags.tags", "tags.0.required"), + resource.TestCheckResourceAttrSet("data.nutanix_ndb_tags.tags", "tags.0.status"), + resource.TestCheckResourceAttrSet("data.nutanix_ndb_tags.tags", "tags.0.required"), + resource.TestCheckResourceAttr("data.nutanix_ndb_tags.tags", "tags.0.entity_type", "DATABASE"), + ), + }, + }, + }) +} + +func testAccEraTagsDataSourceConfig(r int) string { + return fmt.Sprintf(` resource "nutanix_ndb_tag" "acctest-managed" { - name= "test-tag" + name= "test-tag-%[1]d" description = "test tag description" entity_type = "DATABASE" required = false } data "nutanix_ndb_tags" "tags"{ } - ` + `, r) +} + +func testAccEraTagsDataSourceConfigWithEntityType(r int) string { + return fmt.Sprintf(` + resource "nutanix_ndb_tag" "acctest-managed" { + name= "test-tag-%[1]d" + description = "test tag description" + entity_type = "DATABASE" + required = false + } + + data "nutanix_ndb_tags" "tags"{ + entity_type= "DATABASE" + } + `, r) } diff --git a/nutanix/main_test.go b/nutanix/main_test.go index bcde564e..87954c73 100644 --- a/nutanix/main_test.go +++ b/nutanix/main_test.go @@ -55,6 +55,7 @@ type TestConfig struct { SubnetMask string `json:"subnet_mask"` StorageContainer string `json:"strorage_container"` } `json:"register_cluster_info"` + TestStaticNetwork string `json:"test_static_network"` } `json:"ndb"` } diff --git a/nutanix/provider.go b/nutanix/provider.go index 65ff7804..694e7964 100644 --- a/nutanix/provider.go +++ b/nutanix/provider.go @@ -211,6 +211,7 @@ func Provider() *schema.Provider { "nutanix_ndb_networks": dataSourceNutanixEraNetworks(), "nutanix_ndb_dbserver": dataSourceNutanixNDBDBServer(), "nutanix_ndb_dbservers": dataSourceNutanixNDBDBServers(), + "nutanix_ndb_network_available_ips": dataSourceNutanixNDBProfileAvailableIPs(), }, ResourcesMap: map[string]*schema.Resource{ "nutanix_virtual_machine": resourceNutanixVirtualMachine(), diff --git a/nutanix/resource_nutanix_ndb_clone.go b/nutanix/resource_nutanix_ndb_clone.go index 883b958b..b7503240 100644 --- a/nutanix/resource_nutanix_ndb_clone.go +++ b/nutanix/resource_nutanix_ndb_clone.go @@ -48,6 +48,7 @@ func resourceNutanixNDBClone() *schema.Resource { "time_zone": { Type: schema.TypeString, Optional: true, + Computed: true, }, "node_count": { Type: schema.TypeInt, @@ -82,17 +83,17 @@ func resourceNutanixNDBClone() *schema.Resource { "properties": { Type: schema.TypeList, Description: "List of all the properties", - Computed: true, + Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, - Computed: true, + Optional: true, }, "value": { Type: schema.TypeString, - Computed: true, + Optional: true, }, }, }, @@ -433,11 +434,16 @@ func resourceNutanixNDBCloneRead(ctx context.Context, d *schema.ResourceData, me conn := meta.(*Client).Era filterParams := &era.FilterParams{} - filterParams.Detailed = "false" + filterParams.Detailed = "true" filterParams.AnyStatus = "false" filterParams.LoadDBServerCluster = "false" filterParams.TimeZone = "UTC" + // check if d.Id() is nil + if d.Id() == "" { + return diag.Errorf("id is required for read operation") + } + resp, err := conn.Service.GetClone(ctx, d.Id(), "", filterParams) if err != nil { return diag.FromErr(err) @@ -514,10 +520,6 @@ func resourceNutanixNDBCloneRead(ctx context.Context, d *schema.ResourceData, me return diag.FromErr(err) } - if err := d.Set("lcm_config", flattenDBLcmConfig(resp.Lcmconfig)); err != nil { - return diag.FromErr(err) - } - if err := d.Set("time_machine", flattenDBTimeMachine(resp.TimeMachine)); err != nil { return diag.FromErr(err) } diff --git a/nutanix/resource_nutanix_ndb_clone_test.go b/nutanix/resource_nutanix_ndb_clone_test.go index ca17cdba..8ff0dcf9 100644 --- a/nutanix/resource_nutanix_ndb_clone_test.go +++ b/nutanix/resource_nutanix_ndb_clone_test.go @@ -29,6 +29,7 @@ func TestAccEra_Clonebasic(t *testing.T) { resource.TestCheckResourceAttrSet(resourceClone, "database_name"), resource.TestCheckResourceAttrSet(resourceClone, "database_nodes.#"), resource.TestCheckResourceAttrSet(resourceClone, "linked_databases.#"), + resource.TestCheckResourceAttrSet(resourceClone, "time_machine.#"), ), }, }, @@ -77,7 +78,6 @@ func testAccEraCloneConfig(name, desc, vmName, sshKey string) string { nx_cluster_id = local.clusters.EraCluster.id ssh_public_key = "%[4]s" snapshot_id = data.nutanix_ndb_tms_capability.test.last_continuous_snapshot.0.id - time_zone = "Asia/Calcutta" create_dbserver = true compute_profile_id = local.compute_profiles["DEFAULT_OOB_SMALL_COMPUTE"].id network_profile_id = local.network_profiles.DEFAULT_OOB_POSTGRESQL_NETWORK.id diff --git a/nutanix/resource_nutanix_ndb_cluster.go b/nutanix/resource_nutanix_ndb_cluster.go index 7b55fc0a..1e87ac3b 100644 --- a/nutanix/resource_nutanix_ndb_cluster.go +++ b/nutanix/resource_nutanix_ndb_cluster.go @@ -17,6 +17,9 @@ func resourceNutanixNDBCluster() *schema.Resource { ReadContext: resourceNutanixNDBClusterRead, UpdateContext: resourceNutanixNDBClusterUpdate, DeleteContext: resourceNutanixNDBClusterDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, @@ -354,6 +357,11 @@ func resourceNutanixNDBClusterCreate(ctx context.Context, d *schema.ResourceData func resourceNutanixNDBClusterRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*Client).Era + // check if d.Id() is nil + if d.Id() == "" { + return diag.Errorf("id is required for read operation") + } + resp, err := conn.Service.GetCluster(ctx, d.Id(), "") if err != nil { return diag.FromErr(err) diff --git a/nutanix/resource_nutanix_ndb_database.go b/nutanix/resource_nutanix_ndb_database.go index 0a06de83..8fcc5e6c 100644 --- a/nutanix/resource_nutanix_ndb_database.go +++ b/nutanix/resource_nutanix_ndb_database.go @@ -40,7 +40,6 @@ func resourceDatabaseInstance() *schema.Resource { Computed: true, Optional: true, }, - "description": { Type: schema.TypeString, Optional: true, @@ -558,6 +557,10 @@ func readDatabaseInstance(ctx context.Context, d *schema.ResourceData, m interfa } if resp != nil { + if err = d.Set("database_instance_id", databaseInstanceID); err != nil { + return diag.FromErr(err) + } + if err = d.Set("description", resp.Description); err != nil { return diag.FromErr(err) } diff --git a/nutanix/resource_nutanix_ndb_database_restore.go b/nutanix/resource_nutanix_ndb_database_restore.go index cb8b3112..97caee1a 100644 --- a/nutanix/resource_nutanix_ndb_database_restore.go +++ b/nutanix/resource_nutanix_ndb_database_restore.go @@ -3,6 +3,7 @@ package nutanix import ( "context" "log" + "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -20,6 +21,9 @@ func resourceNutanixNDBDatabaseRestore() *schema.Resource { Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(EraProvisionTimeout), }, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, Schema: map[string]*schema.Schema{ "database_id": { Type: schema.TypeString, @@ -143,6 +147,10 @@ func resourceNutanixNDBDatabaseRestore() *schema.Resource { }, "database_nodes": dataSourceEraDatabaseNodes(), "linked_databases": dataSourceEraLinkedDatabases(), + "database_instance_id": { + Type: schema.TypeString, + Computed: true, + }, }, } } @@ -152,8 +160,10 @@ func resourceNutanixNDBDatabaseRestoreCreate(ctx context.Context, d *schema.Reso req := &era.DatabaseRestoreRequest{} databaseID := "" - if dbID, ok := d.GetOk("database_id"); ok { + if dbID, ok := d.GetOk("database_id"); ok && len(dbID.(string)) > 0 { databaseID = dbID.(string) + } else { + return diag.Errorf("database_id is a required field to perform restore") } if snapID, ok := d.GetOk("snapshot_id"); ok { @@ -214,14 +224,21 @@ func resourceNutanixNDBDatabaseRestoreCreate(ctx context.Context, d *schema.Reso return diag.Errorf("error waiting to perform db restore (%s) to create: %s", resp.Entityid, errWaitTask) } - d.SetId(resp.Operationid) - log.Printf("NDB database restore with %s id is performed successfully", d.Id()) + setID := databaseID + "/" + resp.Operationid + d.SetId(setID) + log.Printf("NDB database restore with %s id is performed successfully", databaseID) return resourceNutanixNDBDatabaseRestoreRead(ctx, d, meta) } func resourceNutanixNDBDatabaseRestoreRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - databaseID := d.Get("database_id").(string) - ctx = NewContext(ctx, dbID(databaseID)) + splitID := strings.Split(d.Id(), "/") + dbUUID := splitID[0] + + if databaseID, ok := d.GetOk("database_id"); ok { + ctx = NewContext(ctx, dbID(databaseID.(string))) + } else { + ctx = NewContext(ctx, dbID(dbUUID)) + } return readDatabaseInstance(ctx, d, meta) } diff --git a/nutanix/resource_nutanix_ndb_database_scale.go b/nutanix/resource_nutanix_ndb_database_scale.go index 211fbe73..b2614342 100644 --- a/nutanix/resource_nutanix_ndb_database_scale.go +++ b/nutanix/resource_nutanix_ndb_database_scale.go @@ -3,6 +3,7 @@ package nutanix import ( "context" "log" + "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -20,6 +21,9 @@ func resourceNutanixNDBScaleDatabase() *schema.Resource { Timeouts: &schema.ResourceTimeout{ Create: schema.DefaultTimeout(EraProvisionTimeout), }, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, Schema: map[string]*schema.Schema{ "database_uuid": { Type: schema.TypeString, @@ -147,6 +151,10 @@ func resourceNutanixNDBScaleDatabase() *schema.Resource { }, "database_nodes": dataSourceEraDatabaseNodes(), "linked_databases": dataSourceEraLinkedDatabases(), + "database_instance_id": { + Type: schema.TypeString, + Computed: true, + }, }, } } @@ -156,8 +164,10 @@ func resourceNutanixNDBScaleDatabaseCreate(ctx context.Context, d *schema.Resour req := &era.DatabaseScale{} dbUUID := "" - if db, ok := d.GetOk("database_uuid"); ok { + if db, dok := d.GetOk("database_uuid"); dok && len(db.(string)) > 0 { dbUUID = db.(string) + } else { + return diag.Errorf("database_id is a required field to perform scale") } if app, ok := d.GetOk("application_type"); ok { @@ -229,14 +239,21 @@ func resourceNutanixNDBScaleDatabaseCreate(ctx context.Context, d *schema.Resour return diag.Errorf("error waiting for db Instance (%s) to scale: %s", resp.Entityid, errWaitTask) } - d.SetId(resp.Operationid) - log.Printf("NDB database with %s id is scaled successfully", d.Id()) + setID := dbUUID + "/" + resp.Operationid + d.SetId(setID) + log.Printf("NDB database with %s id is scaled successfully", dbUUID) return resourceNutanixNDBScaleDatabaseRead(ctx, d, meta) } func resourceNutanixNDBScaleDatabaseRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - databaseID := d.Get("database_uuid").(string) - ctx = NewContext(ctx, dbID(databaseID)) + splitID := strings.Split(d.Id(), "/") + dbUUID := splitID[0] + + if databaseID, ok := d.GetOk("database_uuid"); ok { + ctx = NewContext(ctx, dbID(databaseID.(string))) + } else { + ctx = NewContext(ctx, dbID(dbUUID)) + } return readDatabaseInstance(ctx, d, meta) } diff --git a/nutanix/resource_nutanix_ndb_database_scale_test.go b/nutanix/resource_nutanix_ndb_database_scale_test.go index 984baaeb..011a7ba8 100644 --- a/nutanix/resource_nutanix_ndb_database_scale_test.go +++ b/nutanix/resource_nutanix_ndb_database_scale_test.go @@ -22,6 +22,7 @@ func TestAccEra_Scalebasic(t *testing.T) { resource.TestCheckResourceAttr(resourceNameScaleDB, "data_storage_size", storageSize), resource.TestCheckResourceAttrSet(resourceNameScaleDB, "name"), resource.TestCheckResourceAttrSet(resourceNameScaleDB, "description"), + resource.TestCheckResourceAttrSet(resourceNameScaleDB, "time_machine.#"), ), }, }, diff --git a/nutanix/resource_nutanix_ndb_database_snapshot.go b/nutanix/resource_nutanix_ndb_database_snapshot.go index e3cabc60..daba15cd 100644 --- a/nutanix/resource_nutanix_ndb_database_snapshot.go +++ b/nutanix/resource_nutanix_ndb_database_snapshot.go @@ -37,7 +37,8 @@ func resourceNutanixNDBDatabaseSnapshot() *schema.Resource { }, "name": { Type: schema.TypeString, - Required: true, + Optional: true, + Default: "era_manual_snapshot", }, "remove_schedule_in_days": { Type: schema.TypeInt, @@ -227,9 +228,11 @@ func resourceNutanixNDBDatabaseSnapshotCreate(ctx context.Context, d *schema.Res tmsID = *res.ID } - if name, ok := d.GetOk("name"); ok { + if name, ok := d.GetOk("name"); ok && len(name.(string)) > 0 { req.Name = utils.StringPtr(name.(string)) snapshotName = utils.StringValue(req.Name) + } else { + snapshotName = "era_manual_snapshot" } if rm, ok := d.GetOk("remove_schedule_in_days"); ok { @@ -318,6 +321,11 @@ func resourceNutanixNDBDatabaseSnapshotRead(ctx context.Context, d *schema.Resou filterParams.LoadReplicatedChildSnapshots = "false" filterParams.TimeZone = "UTC" + // check if d.Id() is nil + if d.Id() == "" { + return diag.Errorf("id is required for read operation") + } + resp, err := conn.Service.GetSnapshot(ctx, d.Id(), filterParams) if err != nil { return diag.FromErr(err) diff --git a/nutanix/resource_nutanix_nbd_database_test.go b/nutanix/resource_nutanix_ndb_database_test.go similarity index 99% rename from nutanix/resource_nutanix_nbd_database_test.go rename to nutanix/resource_nutanix_ndb_database_test.go index 69d7b623..d8fb584b 100644 --- a/nutanix/resource_nutanix_nbd_database_test.go +++ b/nutanix/resource_nutanix_ndb_database_test.go @@ -27,6 +27,7 @@ func TestAccEra_basic(t *testing.T) { resource.TestCheckResourceAttr(resourceNameDB, "databasetype", "postgres_database"), resource.TestCheckResourceAttr(resourceNameDB, "database_nodes.#", "1"), resource.TestCheckResourceAttrSet(resourceNameDB, "time_machine_id"), + resource.TestCheckResourceAttrSet(resourceNameDB, "time_machine.#"), ), }, }, diff --git a/nutanix/resource_nutanix_ndb_dbservervm.go b/nutanix/resource_nutanix_ndb_dbservervm.go index 728ac843..87e822f1 100644 --- a/nutanix/resource_nutanix_ndb_dbservervm.go +++ b/nutanix/resource_nutanix_ndb_dbservervm.go @@ -315,6 +315,10 @@ func resourceNutanixNDBServerVMCreate(ctx context.Context, d *schema.ResourceDat func resourceNutanixNDBServerVMRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*Client).Era + // check if d.Id() is nil + if d.Id() == "" { + return diag.Errorf("id is required for read operation") + } resp, err := conn.Service.ReadDBServerVM(ctx, d.Id()) if err != nil { return diag.FromErr(err) diff --git a/nutanix/resource_nutanix_ndb_linked_databases.go b/nutanix/resource_nutanix_ndb_linked_databases.go index 8c2ac199..e38a1cd1 100644 --- a/nutanix/resource_nutanix_ndb_linked_databases.go +++ b/nutanix/resource_nutanix_ndb_linked_databases.go @@ -123,8 +123,10 @@ func resourceNutanixNDBLinkedDBCreate(ctx context.Context, d *schema.ResourceDat databaseID := "" databaseName := "" SetID := "" - if dbID, dok := d.GetOk("database_id"); dok { + if dbID, dok := d.GetOk("database_id"); dok && len(dbID.(string)) > 0 { databaseID = dbID.(string) + } else { + return diag.Errorf("database_id is a required field") } dbNames := []*era.LinkedDatabases{} @@ -196,6 +198,10 @@ func resourceNutanixNDBLinkedDBRead(ctx context.Context, d *schema.ResourceData, databaseID := d.Get("database_id") + // check if database id is nil + if databaseID == "" { + return diag.Errorf("database id is required for read operation") + } response, er := conn.Service.GetDatabaseInstance(ctx, databaseID.(string)) if er != nil { return diag.FromErr(er) diff --git a/nutanix/resource_nutanix_ndb_maintenance_task.go b/nutanix/resource_nutanix_ndb_maintenance_task.go index 2820b1b1..8d76c40e 100644 --- a/nutanix/resource_nutanix_ndb_maintenance_task.go +++ b/nutanix/resource_nutanix_ndb_maintenance_task.go @@ -141,6 +141,12 @@ func resourceNutanixNDBMaintenanceTaskCreate(ctx context.Context, d *schema.Reso func resourceNutanixNDBMaintenanceTaskRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*Client).Era maintenanceID := d.Get("maintenance_window_id") + + // check if maintenance id is nil + if maintenanceID == "" { + return diag.Errorf("id is required for read operation") + } + resp, err := conn.Service.ReadMaintenanceWindow(ctx, maintenanceID.(string)) if err != nil { return diag.FromErr(err) diff --git a/nutanix/resource_nutanix_ndb_maintenance_window.go b/nutanix/resource_nutanix_ndb_maintenance_window.go index 5ce781b3..d9d9b1ac 100644 --- a/nutanix/resource_nutanix_ndb_maintenance_window.go +++ b/nutanix/resource_nutanix_ndb_maintenance_window.go @@ -17,6 +17,9 @@ func resourceNutanixNDBMaintenanceWindow() *schema.Resource { ReadContext: resourceNutanixNDBMaintenanceWindowRead, UpdateContext: resourceNutanixNDBMaintenanceWindowUpdate, DeleteContext: resourceNutanixNDBMaintenanceWindowDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, @@ -206,6 +209,10 @@ func resourceNutanixNDBMaintenanceWindowCreate(ctx context.Context, d *schema.Re func resourceNutanixNDBMaintenanceWindowRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*Client).Era + // check if d.Id() is nil + if d.Id() == "" { + return diag.Errorf("id is required for read operation") + } resp, err := conn.Service.ReadMaintenanceWindow(ctx, d.Id()) if err != nil { return diag.FromErr(err) diff --git a/nutanix/resource_nutanix_ndb_maintenance_window_test.go b/nutanix/resource_nutanix_ndb_maintenance_window_test.go index f65d625f..587974a4 100644 --- a/nutanix/resource_nutanix_ndb_maintenance_window_test.go +++ b/nutanix/resource_nutanix_ndb_maintenance_window_test.go @@ -10,7 +10,8 @@ import ( const resourceMaintenaceWindowName = "nutanix_ndb_maintenance_window.acctest-managed" func TestAccEra_MaintenanceWindow(t *testing.T) { - name := "test-maintenance" + r := randIntBetween(10, 20) + name := fmt.Sprintf("test-maintenance-%d", r) desc := "this is desc" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccEraPreCheck(t) }, @@ -31,8 +32,9 @@ func TestAccEra_MaintenanceWindow(t *testing.T) { } func TestAccEra_MaintenanceWindowUpdate(t *testing.T) { - name := "test-maintenance" - updatedName := "test-maintenance-updated" + r := randIntBetween(21, 30) + name := fmt.Sprintf("test-maintenance-%d", r) + updatedName := fmt.Sprintf("test-maintenance-updated-%d", r) desc := "this is desc" updatedDesc := "this desc is updated" resource.Test(t, resource.TestCase{ @@ -64,7 +66,8 @@ func TestAccEra_MaintenanceWindowUpdate(t *testing.T) { } func TestAccEra_MaintenanceWindow_MonthlyRecurrence(t *testing.T) { - name := "test-maintenance" + r := randIntBetween(25, 30) + name := fmt.Sprintf("test-maintenance-%d", r) desc := "this is desc" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccEraPreCheck(t) }, diff --git a/nutanix/resource_nutanix_ndb_network.go b/nutanix/resource_nutanix_ndb_network.go index 808903b4..db8ec130 100644 --- a/nutanix/resource_nutanix_ndb_network.go +++ b/nutanix/resource_nutanix_ndb_network.go @@ -236,6 +236,11 @@ func resourceNutanixNDBNetworkCreate(ctx context.Context, d *schema.ResourceData func resourceNutanixNDBNetworkRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*Client).Era + // check if d.Id() is nil + if d.Id() == "" { + return diag.Errorf("id is required for read operation") + } + resp, err := conn.Service.GetNetwork(ctx, d.Id(), "") if err != nil { return diag.FromErr(err) @@ -385,10 +390,18 @@ func flattenIPPools(pools []*era.IPPools) []interface{} { for _, v := range pools { ips := map[string]interface{}{} - ips["id"] = v.ID - ips["modified_by"] = v.ModifiedBy - ips["start_ip"] = v.StartIP - ips["end_ip"] = v.EndIP + if v.ID != nil { + ips["id"] = v.ID + } + if v.ModifiedBy != nil { + ips["modified_by"] = v.ModifiedBy + } + if v.StartIP != nil { + ips["start_ip"] = v.StartIP + } + if v.EndIP != nil { + ips["end_ip"] = v.EndIP + } if v.IPAddresses != nil { ipAdd := make([]interface{}, 0) diff --git a/nutanix/resource_nutanix_ndb_profiles.go b/nutanix/resource_nutanix_ndb_profiles.go index 03a0163c..bf3ff8a0 100644 --- a/nutanix/resource_nutanix_ndb_profiles.go +++ b/nutanix/resource_nutanix_ndb_profiles.go @@ -19,6 +19,9 @@ func resourceNutanixNDBProfile() *schema.Resource { ReadContext: resourceNutanixNDBProfileRead, UpdateContext: resourceNutanixNDBProfileUpdate, DeleteContext: resourceNutanixNDBProfileDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, @@ -731,6 +734,10 @@ func resourceNutanixNDBProfileRead(ctx context.Context, d *schema.ResourceData, profileFilter := &era.ProfileFilter{} profileFilter.ProfileID = d.Id() + // check if d.Id() is nil + if d.Id() == "" { + return diag.Errorf("id is required for read operation") + } resp, err := conn.Service.GetProfile(ctx, profileFilter) if err != nil { return diag.FromErr(err) diff --git a/nutanix/resource_nutanix_ndb_sla.go b/nutanix/resource_nutanix_ndb_sla.go index 56d94f57..432223cb 100644 --- a/nutanix/resource_nutanix_ndb_sla.go +++ b/nutanix/resource_nutanix_ndb_sla.go @@ -16,6 +16,9 @@ func resourceNutanixNDBSla() *schema.Resource { ReadContext: resourceNutanixNDBSlaRead, UpdateContext: resourceNutanixNDBSlaUpdate, DeleteContext: resourceNutanixNDBSlaDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, @@ -138,6 +141,10 @@ func resourceNutanixNDBSlaRead(ctx context.Context, d *schema.ResourceData, meta // get the sla + // check if d.Id() is nil + if d.Id() == "" { + return diag.Errorf("id is required for read operation") + } resp, err := conn.Service.GetSLA(ctx, d.Id(), "") if err != nil { return diag.FromErr(err) diff --git a/nutanix/resource_nutanix_ndb_software_version_profile.go b/nutanix/resource_nutanix_ndb_software_version_profile.go index 22e797e3..cdd1d14c 100644 --- a/nutanix/resource_nutanix_ndb_software_version_profile.go +++ b/nutanix/resource_nutanix_ndb_software_version_profile.go @@ -304,6 +304,10 @@ func resourceNutanixNDBSoftwareVersionProfileRead(ctx context.Context, d *schema // Get Profile Version API profileVersionID := d.Get("profile_id") + // check if d.Id() is nil + if d.Id() == "" { + return diag.Errorf("profile version id is required for read operation") + } resp, err := conn.Service.GetSoftwareProfileVersion(ctx, profileVersionID.(string), d.Id()) if err != nil { return diag.FromErr(err) diff --git a/nutanix/resource_nutanix_ndb_stretched_vlans.go b/nutanix/resource_nutanix_ndb_stretched_vlans.go index de75edfd..ea47efe2 100644 --- a/nutanix/resource_nutanix_ndb_stretched_vlans.go +++ b/nutanix/resource_nutanix_ndb_stretched_vlans.go @@ -176,6 +176,10 @@ func resourceNutanixNDBStretchedVlanCreate(ctx context.Context, d *schema.Resour func resourceNutanixNDBStretchedVlanRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*Client).Era + // check if d.Id() is nil + if d.Id() == "" { + return diag.Errorf("stretched vlan id is required for read operation") + } resp, err := conn.Service.GetStretchedVlan(ctx, d.Id()) if err != nil { return diag.FromErr(err) diff --git a/nutanix/resource_nutanix_ndb_tags.go b/nutanix/resource_nutanix_ndb_tags.go index 2b10a2b7..6ce05b2f 100644 --- a/nutanix/resource_nutanix_ndb_tags.go +++ b/nutanix/resource_nutanix_ndb_tags.go @@ -17,6 +17,9 @@ func resourceNutanixNDBTags() *schema.Resource { ReadContext: resourceNutanixNDBTagsRead, UpdateContext: resourceNutanixNDBTagsUpdate, DeleteContext: resourceNutanixNDBTagsDelete, + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, @@ -96,7 +99,7 @@ func resourceNutanixNDBTagsCreate(ctx context.Context, d *schema.ResourceData, m uniqueID := "" // fetch all the tags - tagsListResp, er := conn.Service.ListTags(ctx) + tagsListResp, er := conn.Service.ListTags(ctx, entityType) if er != nil { return diag.FromErr(er) } @@ -114,7 +117,11 @@ func resourceNutanixNDBTagsCreate(ctx context.Context, d *schema.ResourceData, m func resourceNutanixNDBTagsRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { conn := meta.(*Client).Era - resp, err := conn.Service.ReadTags(ctx, d.Id()) + // check if d.Id() is nil + if d.Id() == "" { + return diag.Errorf("tag id is required for read operation") + } + resp, err := conn.Service.ReadTags(ctx, d.Id(), "") if err != nil { return diag.FromErr(err) @@ -161,7 +168,7 @@ func resourceNutanixNDBTagsUpdate(ctx context.Context, d *schema.ResourceData, m // read the tag - resp, err := conn.Service.ReadTags(ctx, d.Id()) + resp, err := conn.Service.ReadTags(ctx, d.Id(), "") if err != nil { return diag.FromErr(err) } diff --git a/test_config.json b/test_config.json index cd9218a1..0ad04e01 100644 --- a/test_config.json +++ b/test_config.json @@ -71,7 +71,8 @@ "static_ip":"", "gateway":"", "subnet_mask":"" - } + }, + "test_static_network":"" } } diff --git a/website/docs/d/ndb_network.html.markdown b/website/docs/d/ndb_network.html.markdown index 2fc6d462..18139b22 100644 --- a/website/docs/d/ndb_network.html.markdown +++ b/website/docs/d/ndb_network.html.markdown @@ -41,6 +41,23 @@ The following attributes are exported: * `stretched_vlan_id`: stretched vlan id * `properties`: properties of network * `properties_map`: properties map of network +* `ip_addresses`: IP addresses of network +* `ip_pools`: IP Pools of network + +### ip_addresses +* `ip`: ip +* `status`: status of ip +* `dbserver_id`: dbserver id +* `dbserver_name`: dbserver name + +### ip_pools +* `start_ip`: start ip +* `end_ip`: end ip +* `addresses`: address of ips ranges + +### addresses +* `ip`: ip of pool +* `status`: ip status ### properties_map * `vlan_subnet_mask`: subnet mask of vlan diff --git a/website/docs/d/ndb_network_available_ips.html.markdown b/website/docs/d/ndb_network_available_ips.html.markdown new file mode 100644 index 00000000..70041d42 --- /dev/null +++ b/website/docs/d/ndb_network_available_ips.html.markdown @@ -0,0 +1,38 @@ +--- +layout: "nutanix" +page_title: "NUTANIX: nutanix_ndb_network_available_ips" +sidebar_current: "docs-nutanix-datasource-ndb-network-available-ips" +description: |- + List of available IPs in Network +--- + +# nutanix_ndb_network_available_ips + + List of available IPs in Network + +## Example Usage + +```hcl + data "nutanix_ndb_network_available_ips" "network"{ + profile_id = "{{ network_profile_id }}" + } +``` + + +## Attribute Reference + +The following attributes are exported: + +* `profile_id`: (Required) Network Profile id. +* `available_ips`: List of network available ips + +### available_ips + +* `id`: network profile id +* `name`: Network Name +* `property_name`: property name of vlan +* `type`: type of network +* `managed`: managed by ndb or not +* `ip_addresses`: list of available ips in network +* `cluster_id`: cluster id +* `cluster_name`: cluster name \ No newline at end of file diff --git a/website/docs/d/ndb_networks.html.markdown b/website/docs/d/ndb_networks.html.markdown index 44ac0408..c8f5303c 100644 --- a/website/docs/d/ndb_networks.html.markdown +++ b/website/docs/d/ndb_networks.html.markdown @@ -31,6 +31,23 @@ The following attributes are exported: * `stretched_vlan_id`: stretched vlan id * `properties`: properties of network * `properties_map`: properties map of network +* `ip_addresses`: IP addresses of network +* `ip_pools`: IP Pools of network + +### ip_addresses +* `ip`: ip +* `status`: status of ip +* `dbserver_id`: dbserver id +* `dbserver_name`: dbserver name + +### ip_pools +* `start_ip`: start ip +* `end_ip`: end ip +* `addresses`: address of ips ranges + +### addresses +* `ip`: ip of pool +* `status`: ip status ### properties_map * `vlan_subnet_mask`: subnet mask of vlan diff --git a/website/docs/d/ndb_tag.html.markdown b/website/docs/d/ndb_tag.html.markdown index c22dadac..0b84b018 100644 --- a/website/docs/d/ndb_tag.html.markdown +++ b/website/docs/d/ndb_tag.html.markdown @@ -22,7 +22,8 @@ Describes a tag in Nutanix Database Service ## Argument Reference The following arguments are supported: -* `id` : tag id +* `id` : (Optional) tag id. Conflicts with name. +* `name`: (Optional) tag name. Conflicts with id. ## Attribute Reference diff --git a/website/docs/d/ndb_tags.html.markdown b/website/docs/d/ndb_tags.html.markdown index 2b868b19..bee3f72e 100644 --- a/website/docs/d/ndb_tags.html.markdown +++ b/website/docs/d/ndb_tags.html.markdown @@ -21,6 +21,7 @@ List of tags in Nutanix Database Service The following attributes are exported: * `tags`: List of tags present in NDB. +* `entity_type`: (Optional) entity type of specific tag. Valid values are DATABASE, TIME_MACHINE, CLONE,DATABASE_SERVER. ### tags * `name`: name for the tag diff --git a/website/docs/r/ndb_database.html.markdown b/website/docs/r/ndb_database.html.markdown index 904a1c44..2ad3217f 100644 --- a/website/docs/r/ndb_database.html.markdown +++ b/website/docs/r/ndb_database.html.markdown @@ -4,15 +4,17 @@ page_title: "NUTANIX: nutanix_ndb_database" sidebar_current: "docs-nutanix-resource-ndb-database" description: |- This operation submits a request to create, update and delete database instance in Nutanix database service (NDB). - Note: For 1.8.0-beta.1 release, only postgress database type is qualified and officially supported. + Note: For 1.8.0 release, only postgress database type is qualified and officially supported. --- # nutanix_ndb_database -Provides a resource to create database instance based on the input parameters. For 1.8.0-beta.1 release, only postgress database type is qualified and officially supported. +Provides a resource to create database instance based on the input parameters. For 1.8.0 release, only postgress database type is qualified and officially supported. ## Example Usage +### NDB database resource with new database server VM + ``` hcl resource "nutanix_ndb_database" "dbp" { @@ -95,10 +97,12 @@ resource "nutanix_ndb_database" "dbp" { } } } +``` -// resource to provision HA instance +### NDB database resource to provision HA instance with new database server VM +``` hcl resource "nutanix_ndb_database" "dbp" { databasetype = "postgres_database" name = "test-pg-inst-HA-tf" @@ -264,13 +268,94 @@ resource "nutanix_ndb_database" "dbp" { } ``` +### NDB database resource with registered database server VM + +```hcl + resource "nutanix_ndb_database" "dbp" { + + // name of database type + databasetype = "postgres_database" + + // required name of db instance + name = "test-inst" + description = "add description" + + // adding the profiles details + dbparameterprofileid = "{{ db_parameter_profile_id }}" + + // required dbserver id + dbserverId = "{{ dbserver_id }}" + createdbserver = false + + // postgreSQL Info + postgresql_info{ + listener_port = "{{ listner_port }}" + + database_size= "{{ 200 }}" + + db_password = "password" + + database_names= "testdb1" + } + actionarguments{ + name = "host_ip" + value = "{{ hostIP }}" + } + + // node for single instance + nodes{ + // id of dbserver vm + dbserverid = "{{ dbserver_id }}" + } + + // time machine info + timemachineinfo { + name= "test-pg-inst" + description="description of time machine" + slaid= "{{ sla_id }}" + + // schedule info fields are optional. + schedule { + snapshottimeofday{ + hours= 16 + minutes= 0 + seconds= 0 + } + continuousschedule{ + enabled=true + logbackupinterval= 30 + snapshotsperday=1 + } + weeklyschedule{ + enabled=true + dayofweek= "WEDNESDAY" + } + monthlyschedule{ + enabled = true + dayofmonth= "27" + } + quartelyschedule{ + enabled=true + startmonth="JANUARY" + dayofmonth= 27 + } + yearlyschedule{ + enabled= false + dayofmonth= 31 + month="DECEMBER" + } + } + } +} +``` + ## Argument Reference The following arguments are supported: * `name`: - (Required) Name of the instance. * `description`: - (Optional) The description -* `databasetype`: - (Optional) Type of database. Valid values: oracle_database, postgres_database, sqlserver_database, mariadb_database and mysql_database +* `databasetype`: - (Required) Type of database. Valid values: postgres_database * `softwareprofileid`: - (Optional) ID of software profile * `softwareprofileversionid`: - (Optional) ID of version in software profile * `computeprofileid`: - (Optional) ID of compute profile diff --git a/website/docs/r/ndb_database_snapshot.html.markdown b/website/docs/r/ndb_database_snapshot.html.markdown index e1db8040..0bc549f3 100644 --- a/website/docs/r/ndb_database_snapshot.html.markdown +++ b/website/docs/r/ndb_database_snapshot.html.markdown @@ -36,7 +36,7 @@ Provides a resource to perform the snapshot for database instance based on the i * `time_machine_id`: (Optional) Time Machine Id * `time_machine_name`:(Optional) Time Machine Name -* `name`: (Required) Snapshot name +* `name`: (Optional) Snapshot name. Default value is era_manual_snapshot. * `remove_schedule_in_days`: (Optional) Removal schedule after which the snapshot should be removed. * `expiry_date_timezone`: (Optional) Default is set to Asia/Calcutta * `replicate_to_clusters`: (Optional) snapshots to be replicated to clusters. diff --git a/website/docs/r/ndb_dbservervm.html.markdown b/website/docs/r/ndb_dbservervm.html.markdown index f3d85187..c8caaaac 100644 --- a/website/docs/r/ndb_dbservervm.html.markdown +++ b/website/docs/r/ndb_dbservervm.html.markdown @@ -57,7 +57,7 @@ Provides a resource to create database server VMs based on the input parameters. The following arguments are supported: -* `database_type`: (Required) database type +* `database_type`: (Required) database type. Valid values: postgres_database * `software_profile_id`: (Optional) software profile id you want to provision a database server VM from an existing software profile.Required with software_profile_version_id. Conflicts with time_machine_id . * `software_profile_version_id`: (Optional) SOftware Profile Version Id. * `time_machine_id`: (Optional) Time Machine id you want to provision a database server VM by using the database and operating system software stored in a time machine. Conflicts with software_profile_id. diff --git a/website/docs/r/ndb_profiles.html.markdown b/website/docs/r/ndb_profiles.html.markdown index d5ca2ad6..61eb6ce8 100644 --- a/website/docs/r/ndb_profiles.html.markdown +++ b/website/docs/r/ndb_profiles.html.markdown @@ -4,7 +4,7 @@ page_title: "NUTANIX: nutanix_ndb_profile" sidebar_current: "docs-nutanix-resource-ndb-profile" description: |- This operation submits a request to create, update and delete profiles in Nutanix database service (NDB). - Note: For 1.8.0-beta.2 release, only postgress database type is qualified and officially supported. + Note: For 1.8.0 release, only postgress database type is qualified and officially supported. --- # nutanix_ndb_profile diff --git a/website/docs/r/ndb_register_database.html.markdown b/website/docs/r/ndb_register_database.html.markdown index 9fbdfcc4..ef6fdc35 100644 --- a/website/docs/r/ndb_register_database.html.markdown +++ b/website/docs/r/ndb_register_database.html.markdown @@ -157,7 +157,7 @@ Provides a resource to register the database based on the input parameters. ## Argument Reference -* `database_type`: (Required) type of database +* `database_type`: (Required) type of database. Required value: postgres_database * `database_name`: (Required) name of database * `description`: (Optional) description * `clustered`: (Optional) clustered or not. Default is false diff --git a/website/nutanix.erb b/website/nutanix.erb index 7d8689b1..00f6ebd4 100644 --- a/website/nutanix.erb +++ b/website/nutanix.erb @@ -232,6 +232,9 @@ > nutanix_ndb_tags + > + nutanix_ndb_network_available_ips +