diff --git a/.changes/v4.0.0/1343-features.md b/.changes/v4.0.0/1343-features.md index a21894dd1..f31138ba9 100644 --- a/.changes/v4.0.0/1343-features.md +++ b/.changes/v4.0.0/1343-features.md @@ -1,2 +1,4 @@ -* **New Resource:** `vcd_vcenter` to manage vCenter servers [GH-1343, GH-1348] -* **New Resource:** `vcd_nsxt_manager` to manage NSX-T Managers [GH-1343] +* **New Resource:** `vcd_tm_vcenter` to manage TM vCenter servers [GH-1343, GH-1348, GH-1355] +* **New Data Source:** `vcd_tm_vcenter` to read TM vCenter servers [GH-1355] +* **New Resource:** `vcd_tm_nsxt_manager` to manage NSX-T Managers [GH-1343, GH-1355] +* **New Data Source:** `vcd_tm_nsxt_manager` to manage NSX-T Managers [GH-1343, GH-1355] diff --git a/.changes/v4.0.0/1353-notes.md b/.changes/v4.0.0/1353-notes.md index c4fd4157a..a8eb426b4 100644 --- a/.changes/v4.0.0/1353-notes.md +++ b/.changes/v4.0.0/1353-notes.md @@ -1,5 +1,6 @@ * Improve scripts for TM test support - `make testtm-acc`, `testtm-acc-coverage`, `make testtm-binary`, `make testtm-binary-prepare` [GH-1353] +* Add `make testacc-coverage` VCD acceptance test run with coverage [GH-1355] * Adjusts `TESTING.md` for TM testing [GH-1353] * Splits sample test configs to `sample_vcd_test_config.json` for VCD and `sample_vcd_test_config_tm.json` for TM [GH-1353] diff --git a/.gitignore b/.gitignore index c196a06ee..3dcb0c38a 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ website/node_modules *.cover vcd/vcd_test_config*.json +vcd_test_config*.json vcd/go-vcloud-director.log vcd/test-artifacts website/vendor diff --git a/GNUmakefile b/GNUmakefile index 5bfa35794..c2924ee09 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -88,6 +88,10 @@ testacc-orguser: testunit testacc: testunit @sh -c "'$(CURDIR)/scripts/runtest.sh' acceptance" +# Runs the full acceptance test as system administrator +testacc-coverage: testunit + @sh -c "'$(CURDIR)/scripts/runtest.sh' acceptance-coverage" + # Runs the acceptance test for tm testtm-acc: fmtcheck testunit @sh -c "'$(CURDIR)/scripts/runtest.sh' tm-acceptance" diff --git a/go.mod b/go.mod index d59f3d8ff..a045f9a0f 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/hashicorp/go-version v1.6.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 github.com/kr/pretty v0.3.1 - github.com/vmware/go-vcloud-director/v3 v3.0.0-alpha.6 + github.com/vmware/go-vcloud-director/v3 v3.0.0-alpha.7 ) require ( diff --git a/go.sum b/go.sum index 20523d855..5024d348c 100644 --- a/go.sum +++ b/go.sum @@ -149,8 +149,8 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/vmware/go-vcloud-director/v3 v3.0.0-alpha.6 h1:gCv8L2S9kIbgIiwmiX3Pip+BChuyMAB/XqSKUsFF3Og= -github.com/vmware/go-vcloud-director/v3 v3.0.0-alpha.6/go.mod h1:68KHsVns52dsq/w5JQYzauaU/+NAi1FmCxhBrFc/VoQ= +github.com/vmware/go-vcloud-director/v3 v3.0.0-alpha.7 h1:puIYeYmnPOisLptusccwNQKXVMS930Ja6KTyhjvqTow= +github.com/vmware/go-vcloud-director/v3 v3.0.0-alpha.7/go.mod h1:68KHsVns52dsq/w5JQYzauaU/+NAi1FmCxhBrFc/VoQ= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= diff --git a/scripts/runtest.sh b/scripts/runtest.sh index 2c509fd02..f8fcba7c9 100755 --- a/scripts/runtest.sh +++ b/scripts/runtest.sh @@ -80,13 +80,13 @@ function check_for_config_file { function unit_test { if [ -n "$VERBOSE" ] then - echo "go test -race -tags unit ${TEST} || exit 1" - echo "go test -race -tags unit -v -timeout 5m" + echo "go test -tags unit ${TEST} || exit 1" + echo "go test -tags unit -v -timeout 5m" fi if [ -z "$DRY_RUN" ] then - go test -race -tags unit ${TEST} || exit 1 - go test -race -tags unit -v -timeout 5m + go test -tags unit ${TEST} || exit 1 + go test -tags unit -v -timeout 5m fi } @@ -378,7 +378,10 @@ case $wanted in acceptance_test functional ;; acceptance) - acceptance_test functional + acceptance_test "unit functional" + ;; + acceptance-coverage) + acceptance_test "unit functional" "-coverprofile testacc.cover" ;; sequential-acceptance) acceptance_test functional "-race --parallel=1" diff --git a/vcd/datasource_not_found_test.go b/vcd/datasource_not_found_test.go index a0bff912f..e18988f74 100644 --- a/vcd/datasource_not_found_test.go +++ b/vcd/datasource_not_found_test.go @@ -5,6 +5,7 @@ package vcd import ( "fmt" "regexp" + "strings" "testing" "github.com/vmware/go-vcloud-director/v3/govcd" @@ -36,6 +37,10 @@ func TestAccDataSourceNotFound(t *testing.T) { func testSpecificDataSourceNotFound(dataSourceName string, vcdClient *VCDClient) func(*testing.T) { return func(t *testing.T) { + if !vcdClient.Client.IsTm() && strings.HasPrefix(dataSourceName, "vcd_tm") { + t.Skipf("Skipping %s datasource not found test on VCD", dataSourceName) + } + type skipAlways struct { dataSourceName string reason string diff --git a/vcd/datasource_vcd_nsxt_manager.go b/vcd/datasource_vcd_nsxt_manager.go index ef5f15e4e..6bb4bf9d4 100644 --- a/vcd/datasource_vcd_nsxt_manager.go +++ b/vcd/datasource_vcd_nsxt_manager.go @@ -2,66 +2,58 @@ package vcd import ( "context" - "fmt" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/vmware/go-vcloud-director/v3/govcd" - "github.com/vmware/go-vcloud-director/v3/types/v56" ) -// TODO: TM: validate compatibility with old data source - func datasourceVcdNsxtManager() *schema.Resource { return &schema.Resource{ - ReadContext: datasourceVcdNsxtManagerRead, - + ReadContext: datasourceNsxtManagerRead, Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, Required: true, - Description: fmt.Sprintf("Name of %s", labelNsxtManager), - }, - "description": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("Description of %s", labelNsxtManager), - }, - "username": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("Username for authenticating to %s", labelNsxtManager), - }, - "url": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("URL of %s", labelNsxtManager), - }, - "network_provider_scope": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("Network Provider Scope for %s", labelNsxtManager), - }, - "status": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("Status of %s", labelNsxtManager), + Description: "Name of NSX-T manager.", }, "href": { Type: schema.TypeString, Computed: true, - Description: fmt.Sprintf("HREF of %s", labelNsxtManager), + Description: "HREF of NSX-T manager.", }, }, } } -func datasourceVcdNsxtManagerRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { +func datasourceNsxtManagerRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { vcdClient := meta.(*VCDClient) - c := crudConfig[*govcd.NsxtManagerOpenApi, types.NsxtManagerOpenApi]{ - entityLabel: labelNsxtManager, - getEntityFunc: vcdClient.GetNsxtManagerOpenApiByName, - stateStoreFunc: setNsxtManagerData, + nsxtManagerName := d.Get("name").(string) + + nsxtManagers, err := vcdClient.QueryNsxtManagerByName(nsxtManagerName) + if err != nil { + return diag.Errorf("could not find NSX-T manager by name '%s': %s", nsxtManagerName, err) } - return readDatasource(ctx, d, meta, c) + + if len(nsxtManagers) == 0 { + return diag.Errorf("%s found %d NSX-T managers with name '%s'", + govcd.ErrorEntityNotFound, len(nsxtManagers), nsxtManagerName) + } + + if len(nsxtManagers) > 1 { + return diag.Errorf("found %d NSX-T managers with name '%s'", len(nsxtManagers), nsxtManagerName) + } + + // We try to keep IDs clean + id := extractUuid(nsxtManagers[0].HREF) + urn, err := govcd.BuildUrnWithUuid("urn:vcloud:nsxtmanager:", id) + if err != nil { + return diag.Errorf("could not construct URN from id '%s': %s", id, err) + } + dSet(d, "name", nsxtManagers[0].Name) + dSet(d, "href", nsxtManagers[0].HREF) + d.SetId(urn) + + return nil } diff --git a/vcd/datasource_vcd_tm_nsxt_manager.go b/vcd/datasource_vcd_tm_nsxt_manager.go new file mode 100644 index 000000000..fa690d718 --- /dev/null +++ b/vcd/datasource_vcd_tm_nsxt_manager.go @@ -0,0 +1,65 @@ +package vcd + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/vmware/go-vcloud-director/v3/govcd" + "github.com/vmware/go-vcloud-director/v3/types/v56" +) + +func datasourceVcdTmNsxtManager() *schema.Resource { + return &schema.Resource{ + ReadContext: datasourceVcdNsxtManagerRead, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: fmt.Sprintf("Name of %s", labelNsxtManager), + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("Description of %s", labelNsxtManager), + }, + "username": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("Username for authenticating to %s", labelNsxtManager), + }, + "url": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("URL of %s", labelNsxtManager), + }, + "network_provider_scope": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("Network Provider Scope for %s", labelNsxtManager), + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("Status of %s", labelNsxtManager), + }, + "href": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("HREF of %s", labelNsxtManager), + }, + }, + } +} + +func datasourceVcdNsxtManagerRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + c := crudConfig[*govcd.NsxtManagerOpenApi, types.NsxtManagerOpenApi]{ + entityLabel: labelNsxtManager, + getEntityFunc: vcdClient.GetNsxtManagerOpenApiByName, + stateStoreFunc: setNsxtManagerData, + } + return readDatasource(ctx, d, meta, c) +} diff --git a/vcd/datasource_vcd_tm_vcenter.go b/vcd/datasource_vcd_tm_vcenter.go new file mode 100644 index 000000000..b04c0cedf --- /dev/null +++ b/vcd/datasource_vcd_tm_vcenter.go @@ -0,0 +1,101 @@ +package vcd + +import ( + "context" + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/vmware/go-vcloud-director/v3/govcd" + "github.com/vmware/go-vcloud-director/v3/types/v56" +) + +func datasourceVcdTmVcenter() *schema.Resource { + return &schema.Resource{ + ReadContext: datasourceVcdVcenterRead, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: fmt.Sprintf("Name of %s", labelTmVirtualCenter), + }, + "url": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("URL of %s", labelTmVirtualCenter), + }, + "username": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("Username of %s", labelTmVirtualCenter), + }, + "is_enabled": { + Type: schema.TypeBool, + Computed: true, + Description: fmt.Sprintf("Should the %s be enabled", labelTmVirtualCenter), + }, + "description": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("Description of %s", labelTmVirtualCenter), + }, + "has_proxy": { + Type: schema.TypeBool, + Computed: true, + Description: fmt.Sprintf("A flag that shows if %s has proxy defined", labelTmVirtualCenter), + }, + "is_connected": { + Type: schema.TypeBool, + Computed: true, + Description: fmt.Sprintf("A flag that shows if %s is connected", labelTmVirtualCenter), + }, + "mode": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("Mode of %s", labelTmVirtualCenter), + }, + "connection_status": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("Listener state of %s", labelTmVirtualCenter), + }, + "cluster_health_status": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("Mode of %s", labelTmVirtualCenter), + }, + "vcenter_version": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("Version of %s", labelTmVirtualCenter), + }, + "uuid": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("%s UUID", labelTmVirtualCenter), + }, + "vcenter_host": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("%s hostname", labelTmVirtualCenter), + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "vCenter status", + }, + }, + } +} + +func datasourceVcdVcenterRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + vcdClient := meta.(*VCDClient) + + c := crudConfig[*govcd.VCenter, types.VSphereVirtualCenter]{ + entityLabel: labelTmVirtualCenter, + getEntityFunc: vcdClient.GetVCenterByName, + stateStoreFunc: setTmVcenterData, + } + return readDatasource(ctx, d, meta, c) +} diff --git a/vcd/datasource_vcd_vcenter.go b/vcd/datasource_vcd_vcenter.go index 11e22ea16..dc4606a7e 100644 --- a/vcd/datasource_vcd_vcenter.go +++ b/vcd/datasource_vcd_vcenter.go @@ -2,91 +2,97 @@ package vcd import ( "context" - "fmt" + "log" + "net/url" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/vmware/go-vcloud-director/v3/govcd" "github.com/vmware/go-vcloud-director/v3/types/v56" ) -// TODO: TM: validate compatibility with old data source - func datasourceVcdVcenter() *schema.Resource { return &schema.Resource{ - ReadContext: datasourceVcdVcenterRead, - + ReadContext: datasourceVcenterRead, Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, Required: true, - Description: fmt.Sprintf("Name of %s", labelVirtualCenter), + Description: "Name of vCenter.", }, - "url": { + "vcenter_version": { Type: schema.TypeString, Computed: true, - Description: fmt.Sprintf("URL of %s", labelVirtualCenter), + Description: "vCenter version", }, - "username": { + "vcenter_host": { Type: schema.TypeString, Computed: true, - Description: fmt.Sprintf("Username of %s", labelVirtualCenter), + Description: "vCenter hostname", }, - "is_enabled": { - Type: schema.TypeBool, - Computed: true, - Description: fmt.Sprintf("Should the %s be enabled", labelVirtualCenter), - }, - "description": { + "status": { Type: schema.TypeString, Computed: true, - Description: fmt.Sprintf("Description of %s", labelVirtualCenter), - }, - "has_proxy": { - Type: schema.TypeBool, - Computed: true, - Description: fmt.Sprintf("A flag that shows if %s has proxy defined", labelVirtualCenter), + Description: "vCenter status", }, - "is_connected": { + "is_enabled": { Type: schema.TypeBool, Computed: true, - Description: fmt.Sprintf("A flag that shows if %s is connected", labelVirtualCenter), - }, - "mode": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("Mode of %s", labelVirtualCenter), - }, - "listener_state": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("Listener state of %s", labelVirtualCenter), - }, - "cluster_health_status": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("Mode of %s", labelVirtualCenter), - }, - "version": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("Version of %s", labelVirtualCenter), + Description: "vCenter version", }, - "uuid": { + // In UI this field is called `connection`, but it is a reserved field in Terrraform + "connection_status": { Type: schema.TypeString, Computed: true, - Description: fmt.Sprintf("%s UUID", labelVirtualCenter), + Description: "vCenter connection state", }, }, } } -func datasourceVcdVcenterRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { +func datasourceVcenterRead(_ context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { vcdClient := meta.(*VCDClient) - c := crudConfig[*govcd.VCenter, types.VSphereVirtualCenter]{ - entityLabel: labelVirtualCenter, - getEntityFunc: vcdClient.GetVCenterByName, - stateStoreFunc: setTmVcenterData, + + vCenterName := d.Get("name").(string) + + vcs, err := govcd.QueryVirtualCenters(vcdClient.VCDClient, "name=="+url.QueryEscape(vCenterName)) + if err != nil { + return diag.Errorf("error occured while querying vCenters: %s", err) + } + + if len(vcs) == 0 { + return diag.Errorf("%s: could not identify single vCenter. Got %d with name '%s'", + govcd.ErrorEntityNotFound, len(vcs), vCenterName) + } + + if len(vcs) > 1 { + return diag.Errorf("could not identify single vCenter. Got %d with name '%s'", + len(vcs), vCenterName) + } + + uuid := extractUuid(vcs[0].HREF) + urn, err := govcd.BuildUrnWithUuid("urn:vcloud:vimserver:", uuid) + if err != nil { + return diag.Errorf("could not build URN for ID '%s': %s", uuid, err) + } + + d.SetId(urn) + setVcenterData(d, vcs[0]) + + return nil +} + +func setVcenterData(d *schema.ResourceData, vc *types.QueryResultVirtualCenterRecordType) { + dSet(d, "vcenter_version", vc.VcVersion) + // vc.Url is in format `https://XXXX.com/sdk` while UI shows hostname only so we extract it + // The error should not be a reason to fail datasource if it is invalid so it is just logged + host, err := url.Parse(vc.Url) + if err != nil { + log.Printf("[DEBUG] [vCenter read] - could not parse vCenter URL '%s': %s", vc.Url, err) } - return readDatasource(ctx, d, meta, c) + dSet(d, "vcenter_host", host.Host) + dSet(d, "status", vc.Status) + dSet(d, "is_enabled", vc.IsEnabled) + dSet(d, "connection_status", vc.ListenerState) } diff --git a/vcd/datasource_vcd_vcenter_test.go b/vcd/datasource_vcd_vcenter_test.go index b8daf9d37..05af24a7a 100644 --- a/vcd/datasource_vcd_vcenter_test.go +++ b/vcd/datasource_vcd_vcenter_test.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -func TestAccVcdVcenterDS(t *testing.T) { +func TestAccVcdVcenter(t *testing.T) { preTestChecks(t) skipIfNotSysAdmin(t) @@ -47,5 +47,5 @@ func TestAccVcdVcenterDS(t *testing.T) { const datasourceTestVcenter = ` data "vcd_vcenter" "vc" { name = "{{.Vcenter}}" -} + } ` diff --git a/vcd/provider.go b/vcd/provider.go index a9d32e319..60adf476d 100644 --- a/vcd/provider.go +++ b/vcd/provider.go @@ -66,8 +66,8 @@ var globalDataSourceMap = map[string]*schema.Resource{ "vcd_vm_sizing_policy": datasourceVcdVmSizingPolicy(), // 3.0 "vcd_nsxt_manager": datasourceVcdNsxtManager(), // 3.0 "vcd_nsxt_tier0_router": datasourceVcdNsxtTier0Router(), // 3.0 - "vcd_portgroup": datasourceVcdPortgroup(), // 3.0 "vcd_vcenter": datasourceVcdVcenter(), // 3.0 + "vcd_portgroup": datasourceVcdPortgroup(), // 3.0 "vcd_resource_list": datasourceVcdResourceList(), // 3.1 "vcd_resource_schema": datasourceVcdResourceSchema(), // 3.1 "vcd_nsxt_edge_cluster": datasourceVcdNsxtEdgeCluster(), // 3.1 @@ -181,6 +181,8 @@ var globalDataSourceMap = map[string]*schema.Resource{ "vcd_tm_supervisor": datasourceVcdTmSupervisor(), // 4.0 "vcd_tm_supervisor_zone": datasourceVcdTmSupervisorZone(), // 4.0 "vcd_tm_region": datasourceVcdTmRegion(), // 4.0 + "vcd_tm_nsxt_manager": datasourceVcdTmNsxtManager(), // 4.0 + "vcd_tm_vcenter": datasourceVcdTmVcenter(), // 4.0 } var globalResourceMap = map[string]*schema.Resource{ @@ -308,8 +310,8 @@ var globalResourceMap = map[string]*schema.Resource{ "vcd_nsxt_alb_virtual_service_http_resp_rules": resourceVcdAlbVirtualServiceRespRules(), // 3.14 "vcd_nsxt_alb_virtual_service_http_sec_rules": resourceVcdAlbVirtualServiceSecRules(), // 3.14 "vcd_tm_content_library": resourceVcdTmContentLibrary(), // 4.0 - "vcd_nsxt_manager": resourceVcdNsxtManager(), // 4.0 - "vcd_vcenter": resourceVcdVcenter(), // 4.0 + "vcd_tm_nsxt_manager": resourceVcdTmNsxtManager(), // 4.0 + "vcd_tm_vcenter": resourceVcdTmVcenter(), // 4.0 "vcd_tm_org": resourceVcdTmOrg(), // 4.0 "vcd_tm_region": resourceVcdTmRegion(), // 4.0 } diff --git a/vcd/resource_vcd_nsxt_manager.go b/vcd/resource_vcd_tm_nsxt_manager.go similarity index 98% rename from vcd/resource_vcd_nsxt_manager.go rename to vcd/resource_vcd_tm_nsxt_manager.go index 105ba3482..32f588d60 100644 --- a/vcd/resource_vcd_nsxt_manager.go +++ b/vcd/resource_vcd_tm_nsxt_manager.go @@ -12,7 +12,7 @@ import ( const labelNsxtManager = "NSX-T Manager" -func resourceVcdNsxtManager() *schema.Resource { +func resourceVcdTmNsxtManager() *schema.Resource { return &schema.Resource{ CreateContext: resourceVcdNsxtManagerCreate, ReadContext: resourceVcdNsxtManagerRead, @@ -53,7 +53,7 @@ func resourceVcdNsxtManager() *schema.Resource { Type: schema.TypeBool, Required: true, ForceNew: true, - Description: fmt.Sprintf("Defines if the %s certificate should automatically be trusted", labelVirtualCenter), + Description: fmt.Sprintf("Defines if the %s certificate should automatically be trusted", labelNsxtManager), }, "network_provider_scope": { Type: schema.TypeString, diff --git a/vcd/resource_vcd_nsxt_manager_test.go b/vcd/resource_vcd_tm_nsxt_manager_test.go similarity index 61% rename from vcd/resource_vcd_nsxt_manager_test.go rename to vcd/resource_vcd_tm_nsxt_manager_test.go index 4bde6eb40..eae70831f 100644 --- a/vcd/resource_vcd_nsxt_manager_test.go +++ b/vcd/resource_vcd_tm_nsxt_manager_test.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -func TestAccVcdNsxtManager(t *testing.T) { +func TestAccVcdTmNsxtManager(t *testing.T) { preTestChecks(t) skipIfNotSysAdmin(t) @@ -49,31 +49,31 @@ func TestAccVcdNsxtManager(t *testing.T) { { Config: configText1, Check: resource.ComposeTestCheckFunc( - resource.TestMatchResourceAttr("vcd_nsxt_manager.test", "id", regexp.MustCompile(`^urn:vcloud:nsxtmanager:`)), - resource.TestMatchResourceAttr("vcd_nsxt_manager.test", "href", regexp.MustCompile(`api/admin/extension/nsxtManagers/`)), - resource.TestCheckResourceAttr("vcd_nsxt_manager.test", "name", params["Testname"].(string)), - resource.TestCheckResourceAttr("vcd_nsxt_manager.test", "description", "terraform test"), - resource.TestCheckResourceAttrSet("vcd_nsxt_manager.test", "status"), - resource.TestCheckResourceAttr("vcd_nsxt_manager.test", "url", params["Url"].(string)), + resource.TestMatchResourceAttr("vcd_tm_nsxt_manager.test", "id", regexp.MustCompile(`^urn:vcloud:nsxtmanager:`)), + resource.TestMatchResourceAttr("vcd_tm_nsxt_manager.test", "href", regexp.MustCompile(`api/admin/extension/nsxtManagers/`)), + resource.TestCheckResourceAttr("vcd_tm_nsxt_manager.test", "name", params["Testname"].(string)), + resource.TestCheckResourceAttr("vcd_tm_nsxt_manager.test", "description", "terraform test"), + resource.TestCheckResourceAttrSet("vcd_tm_nsxt_manager.test", "status"), + resource.TestCheckResourceAttr("vcd_tm_nsxt_manager.test", "url", params["Url"].(string)), ), }, { Config: configText2, Check: resource.ComposeTestCheckFunc( - resource.TestMatchResourceAttr("vcd_nsxt_manager.test", "id", regexp.MustCompile(`^urn:vcloud:nsxtmanager:`)), - resource.TestMatchResourceAttr("vcd_nsxt_manager.test", "href", regexp.MustCompile(`api/admin/extension/nsxtManagers/`)), - resource.TestCheckResourceAttr("vcd_nsxt_manager.test", "name", params["Testname"].(string)), - resource.TestCheckResourceAttr("vcd_nsxt_manager.test", "description", ""), + resource.TestMatchResourceAttr("vcd_tm_nsxt_manager.test", "id", regexp.MustCompile(`^urn:vcloud:nsxtmanager:`)), + resource.TestMatchResourceAttr("vcd_tm_nsxt_manager.test", "href", regexp.MustCompile(`api/admin/extension/nsxtManagers/`)), + resource.TestCheckResourceAttr("vcd_tm_nsxt_manager.test", "name", params["Testname"].(string)), + resource.TestCheckResourceAttr("vcd_tm_nsxt_manager.test", "description", ""), ), }, { Config: configText3, Check: resource.ComposeTestCheckFunc( - resourceFieldsEqual("vcd_nsxt_manager.test", "data.vcd_nsxt_manager.test", []string{"%", "auto_trust_certificate", "password"}), + resourceFieldsEqual("vcd_tm_nsxt_manager.test", "data.vcd_tm_nsxt_manager.test", []string{"%", "auto_trust_certificate", "password"}), ), }, { - ResourceName: "vcd_nsxt_manager.test", + ResourceName: "vcd_tm_nsxt_manager.test", ImportState: true, ImportStateVerify: true, ImportStateId: params["Testname"].(string), @@ -86,7 +86,7 @@ func TestAccVcdNsxtManager(t *testing.T) { } const testAccVcdNsxtManagerStep1 = ` -resource "vcd_nsxt_manager" "test" { +resource "vcd_tm_nsxt_manager" "test" { name = "{{.Testname}}" description = "terraform test" username = "{{.Username}}" @@ -97,7 +97,7 @@ resource "vcd_nsxt_manager" "test" { } ` const testAccVcdNsxtManagerStep2 = ` -resource "vcd_nsxt_manager" "test" { +resource "vcd_tm_nsxt_manager" "test" { name = "{{.Testname}}" description = "" username = "{{.Username}}" @@ -108,7 +108,7 @@ resource "vcd_nsxt_manager" "test" { ` const testAccVcdNsxtManagerStep3DS = testAccVcdNsxtManagerStep1 + ` -data "vcd_nsxt_manager" "test" { - name = vcd_nsxt_manager.test.name +data "vcd_tm_nsxt_manager" "test" { + name = vcd_tm_nsxt_manager.test.name } ` diff --git a/vcd/resource_vcd_tm_region_test.go b/vcd/resource_vcd_tm_region_test.go index 763f9d236..87d30cb10 100644 --- a/vcd/resource_vcd_tm_region_test.go +++ b/vcd/resource_vcd_tm_region_test.go @@ -61,8 +61,8 @@ func TestAccVcdTmRegion(t *testing.T) { { Config: configText1, Check: resource.ComposeTestCheckFunc( - resource.TestMatchResourceAttr("vcd_nsxt_manager.test", "id", regexp.MustCompile(`^urn:vcloud:nsxtmanager:`)), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "id"), + resource.TestMatchResourceAttr("vcd_tm_nsxt_manager.test", "id", regexp.MustCompile(`^urn:vcloud:nsxtmanager:`)), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "id"), resource.TestCheckResourceAttrSet("vcd_tm_region.test", "id"), cachedRegionId.cacheTestResourceFieldValue("vcd_tm_region.test", "id"), resource.TestCheckResourceAttr("vcd_tm_region.test", "is_enabled", "true"), @@ -76,9 +76,9 @@ func TestAccVcdTmRegion(t *testing.T) { resource.TestCheckTypeSetElemAttr("vcd_tm_region.test", "storage_policy_names.*", testConfig.Tm.VcenterStorageProfile), resource.TestCheckResourceAttrSet("data.vcd_tm_supervisor.test", "id"), - resource.TestCheckResourceAttrPair("data.vcd_tm_supervisor.test", "vcenter_id", "vcd_vcenter.test", "id"), + resource.TestCheckResourceAttrPair("data.vcd_tm_supervisor.test", "vcenter_id", "vcd_tm_vcenter.test", "id"), resource.TestCheckResourceAttrSet("data.vcd_tm_supervisor_zone.test", "id"), - resource.TestCheckResourceAttrPair("data.vcd_tm_supervisor_zone.test", "vcenter_id", "vcd_vcenter.test", "id"), + resource.TestCheckResourceAttrPair("data.vcd_tm_supervisor_zone.test", "vcenter_id", "vcd_tm_vcenter.test", "id"), resource.TestCheckResourceAttrSet("data.vcd_tm_supervisor_zone.test", "cpu_capacity_mhz"), resource.TestCheckResourceAttrSet("data.vcd_tm_supervisor_zone.test", "cpu_used_mhz"), resource.TestCheckResourceAttrSet("data.vcd_tm_supervisor_zone.test", "memory_capacity_mib"), @@ -88,8 +88,8 @@ func TestAccVcdTmRegion(t *testing.T) { { Config: configText2, Check: resource.ComposeTestCheckFunc( - resource.TestMatchResourceAttr("vcd_nsxt_manager.test", "id", regexp.MustCompile(`^urn:vcloud:nsxtmanager:`)), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "id"), + resource.TestMatchResourceAttr("vcd_tm_nsxt_manager.test", "id", regexp.MustCompile(`^urn:vcloud:nsxtmanager:`)), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "id"), resource.TestCheckResourceAttrSet("vcd_tm_region.test", "id"), cachedRegionId.testCheckCachedResourceFieldValueChanged("vcd_tm_region.test", "id"), resource.TestCheckResourceAttr("vcd_tm_region.test", "is_enabled", "true"), @@ -103,10 +103,10 @@ func TestAccVcdTmRegion(t *testing.T) { resource.TestCheckTypeSetElemAttr("vcd_tm_region.test", "storage_policy_names.*", testConfig.Tm.VcenterStorageProfile), resource.TestCheckResourceAttrSet("data.vcd_tm_supervisor.test", "id"), - resource.TestCheckResourceAttrPair("data.vcd_tm_supervisor.test", "vcenter_id", "vcd_vcenter.test", "id"), + resource.TestCheckResourceAttrPair("data.vcd_tm_supervisor.test", "vcenter_id", "vcd_tm_vcenter.test", "id"), resource.TestCheckResourceAttrSet("data.vcd_tm_supervisor_zone.test", "id"), - resource.TestCheckResourceAttrPair("data.vcd_tm_supervisor_zone.test", "vcenter_id", "vcd_vcenter.test", "id"), + resource.TestCheckResourceAttrPair("data.vcd_tm_supervisor_zone.test", "vcenter_id", "vcd_tm_vcenter.test", "id"), resource.TestCheckResourceAttrSet("data.vcd_tm_supervisor_zone.test", "cpu_capacity_mhz"), resource.TestCheckResourceAttrSet("data.vcd_tm_supervisor_zone.test", "cpu_used_mhz"), resource.TestCheckResourceAttrSet("data.vcd_tm_supervisor_zone.test", "memory_capacity_mib"), @@ -137,7 +137,7 @@ func TestAccVcdTmRegion(t *testing.T) { } const testAccVcdRegionPrerequisites = ` -resource "vcd_nsxt_manager" "test" { +resource "vcd_tm_nsxt_manager" "test" { name = "{{.Testname}}" description = "terraform test" username = "{{.NsxtManagerUsername}}" @@ -147,7 +147,7 @@ resource "vcd_nsxt_manager" "test" { auto_trust_certificate = true } -resource "vcd_vcenter" "test" { +resource "vcd_tm_vcenter" "test" { name = "{{.Testname}}" url = "{{.VcenterUrl}}" auto_trust_certificate = true @@ -160,9 +160,9 @@ resource "vcd_vcenter" "test" { data "vcd_tm_supervisor" "test" { name = "{{.VcenterSupervisor}}" - vcenter_id = vcd_vcenter.test.id + vcenter_id = vcd_tm_vcenter.test.id - depends_on = [vcd_vcenter.test] + depends_on = [vcd_tm_vcenter.test] } data "vcd_tm_supervisor_zone" "test" { @@ -176,7 +176,7 @@ resource "vcd_tm_region" "test" { name = "{{.Testname}}" description = "Terraform description" is_enabled = true - nsx_manager_id = vcd_nsxt_manager.test.id + nsx_manager_id = vcd_tm_nsxt_manager.test.id supervisor_ids = [data.vcd_tm_supervisor.test.id] storage_policy_names = ["{{.VcenterStorageProfile}}"] } @@ -188,7 +188,7 @@ resource "vcd_tm_region" "test" { name = "{{.Testname}}" description = "Terraform description updated" is_enabled = true - nsx_manager_id = vcd_nsxt_manager.test.id + nsx_manager_id = vcd_tm_nsxt_manager.test.id supervisor_ids = [data.vcd_tm_supervisor.test.id] storage_policy_names = ["{{.VcenterStorageProfile}}"] } diff --git a/vcd/resource_vcd_vcenter.go b/vcd/resource_vcd_tm_vcenter.go similarity index 70% rename from vcd/resource_vcd_vcenter.go rename to vcd/resource_vcd_tm_vcenter.go index 9f52bb408..e649091ae 100644 --- a/vcd/resource_vcd_vcenter.go +++ b/vcd/resource_vcd_tm_vcenter.go @@ -12,101 +12,111 @@ import ( "github.com/vmware/go-vcloud-director/v3/util" ) -const labelVirtualCenter = "vCenter Server" +const labelTmVirtualCenter = "Tenant Manager vCenter Server" -func resourceVcdVcenter() *schema.Resource { +func resourceVcdTmVcenter() *schema.Resource { return &schema.Resource{ - CreateContext: resourceVcdVcenterCreate, - ReadContext: resourceVcdVcenterRead, - UpdateContext: resourceVcdVcenterUpdate, - DeleteContext: resourceVcdVcenterDelete, + CreateContext: resourceVcdTmVcenterCreate, + ReadContext: resourceVcdTmVcenterRead, + UpdateContext: resourceVcdTmVcenterUpdate, + DeleteContext: resourceVcdTmVcenterDelete, Importer: &schema.ResourceImporter{ - StateContext: resourceVcdVcenterImport, + StateContext: resourceVcdTmVcenterImport, }, Schema: map[string]*schema.Schema{ "name": { Type: schema.TypeString, Required: true, - Description: fmt.Sprintf("Name of %s", labelVirtualCenter), + Description: fmt.Sprintf("Name of %s", labelTmVirtualCenter), }, "url": { Type: schema.TypeString, Required: true, - Description: fmt.Sprintf("URL including port of %s", labelVirtualCenter), + Description: fmt.Sprintf("URL including port of %s", labelTmVirtualCenter), }, "auto_trust_certificate": { Type: schema.TypeBool, Required: true, ForceNew: true, - Description: fmt.Sprintf("Defines if the %s certificate should automatically be trusted", labelVirtualCenter), + Description: fmt.Sprintf("Defines if the %s certificate should automatically be trusted", labelTmVirtualCenter), }, "refresh_vcenter_on_read": { Type: schema.TypeBool, Optional: true, - Description: fmt.Sprintf("Defines if the %s should be refreshed on every read operation", labelVirtualCenter), + Description: fmt.Sprintf("Defines if the %s should be refreshed on every read operation", labelTmVirtualCenter), }, "refresh_policies_on_read": { Type: schema.TypeBool, Optional: true, - Description: fmt.Sprintf("Defines if the %s should refresh Policies on every read operation", labelVirtualCenter), + Description: fmt.Sprintf("Defines if the %s should refresh Policies on every read operation", labelTmVirtualCenter), }, "username": { Type: schema.TypeString, Required: true, - Description: fmt.Sprintf("Username of %s", labelVirtualCenter), + Description: fmt.Sprintf("Username of %s", labelTmVirtualCenter), }, "password": { Type: schema.TypeString, Required: true, Sensitive: true, - Description: fmt.Sprintf("Password of %s", labelVirtualCenter), + Description: fmt.Sprintf("Password of %s", labelTmVirtualCenter), }, "is_enabled": { Type: schema.TypeBool, Optional: true, Default: true, - Description: fmt.Sprintf("Should the %s be enabled", labelVirtualCenter), + Description: fmt.Sprintf("Should the %s be enabled", labelTmVirtualCenter), }, "description": { Type: schema.TypeString, Optional: true, - Description: fmt.Sprintf("Description of %s", labelVirtualCenter), + Description: fmt.Sprintf("Description of %s", labelTmVirtualCenter), }, "has_proxy": { Type: schema.TypeBool, Computed: true, - Description: fmt.Sprintf("A flag that shows if %s has proxy defined", labelVirtualCenter), + Description: fmt.Sprintf("A flag that shows if %s has proxy defined", labelTmVirtualCenter), }, "is_connected": { Type: schema.TypeBool, Computed: true, - Description: fmt.Sprintf("A flag that shows if %s is connected", labelVirtualCenter), + Description: fmt.Sprintf("A flag that shows if %s is connected", labelTmVirtualCenter), }, "mode": { Type: schema.TypeString, Computed: true, - Description: fmt.Sprintf("Mode of %s", labelVirtualCenter), + Description: fmt.Sprintf("Mode of %s", labelTmVirtualCenter), }, - "listener_state": { + "connection_status": { Type: schema.TypeString, Computed: true, - Description: fmt.Sprintf("Listener state of %s", labelVirtualCenter), + Description: fmt.Sprintf("Listener state of %s", labelTmVirtualCenter), }, "cluster_health_status": { Type: schema.TypeString, Computed: true, - Description: fmt.Sprintf("Mode of %s", labelVirtualCenter), + Description: fmt.Sprintf("Mode of %s", labelTmVirtualCenter), }, - "version": { + "vcenter_version": { Type: schema.TypeString, Computed: true, - Description: fmt.Sprintf("Version of %s", labelVirtualCenter), + Description: fmt.Sprintf("Version of %s", labelTmVirtualCenter), }, "uuid": { Type: schema.TypeString, Computed: true, - Description: fmt.Sprintf("%s UUID", labelVirtualCenter), + Description: fmt.Sprintf("%s UUID", labelTmVirtualCenter), + }, + "vcenter_host": { + Type: schema.TypeString, + Computed: true, + Description: fmt.Sprintf("%s hostname", labelTmVirtualCenter), + }, + "status": { + Type: schema.TypeString, + Computed: true, + Description: "vCenter status", }, }, } @@ -127,7 +137,7 @@ func getTmVcenterType(_ *VCDClient, d *schema.ResourceData) (*types.VSphereVirtu func setTmVcenterData(d *schema.ResourceData, v *govcd.VCenter) error { if v == nil || v.VSphereVCenter == nil { - return fmt.Errorf("nil object for %s", labelVirtualCenter) + return fmt.Errorf("nil object for %s", labelTmVirtualCenter) } dSet(d, "name", v.VSphereVCenter.Name) @@ -140,32 +150,48 @@ func setTmVcenterData(d *schema.ResourceData, v *govcd.VCenter) error { dSet(d, "has_proxy", v.VSphereVCenter.HasProxy) dSet(d, "is_connected", v.VSphereVCenter.IsConnected) dSet(d, "mode", v.VSphereVCenter.Mode) - dSet(d, "listener_state", v.VSphereVCenter.ListenerState) + dSet(d, "connection_status", v.VSphereVCenter.ListenerState) dSet(d, "cluster_health_status", v.VSphereVCenter.ClusterHealthStatus) - dSet(d, "version", v.VSphereVCenter.VcVersion) + dSet(d, "vcenter_version", v.VSphereVCenter.VcVersion) dSet(d, "uuid", v.VSphereVCenter.Uuid) + host, err := url.Parse(v.VSphereVCenter.Url) + if err != nil { + return fmt.Errorf("error parsing URL for storing 'vcenter_host': %s", err) + } + dSet(d, "vcenter_host", host.Host) + + // Status is a derivative value that was present in XML Query API, but is no longer maintained + // The value was derived from multiple fields based on a complex logic. Instead, evaluating if + // vCenter is ready for operations, would be to rely on `is_enabled`, `is_connected` and + // optionally `cluster_health_status` fields. + // + // The `status` is a rough approximation of this value + dSet(d, "status", "NOT_READY") + if v.VSphereVCenter.IsConnected && v.VSphereVCenter.ListenerState == "CONNECTED" { + dSet(d, "status", "READY") + } d.SetId(v.VSphereVCenter.VcId) return nil } -func resourceVcdVcenterCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { +func resourceVcdTmVcenterCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { vcdClient := meta.(*VCDClient) c := crudConfig[*govcd.VCenter, types.VSphereVirtualCenter]{ - entityLabel: labelVirtualCenter, + entityLabel: labelTmVirtualCenter, getTypeFunc: getTmVcenterType, stateStoreFunc: setTmVcenterData, createFunc: vcdClient.CreateVcenter, - resourceReadFunc: resourceVcdVcenterRead, + resourceReadFunc: resourceVcdTmVcenterRead, // certificate should be trusted for the vCenter to work preCreateHooks: []schemaHook{autoTrustHostCertificate("url", "auto_trust_certificate")}, } return createResource(ctx, d, meta, c) } -func resourceVcdVcenterUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { +func resourceVcdTmVcenterUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { // return immediately if only flags are updated if !d.HasChangesExcept("refresh_vcenter_on_read", "refresh_policies_on_read") { return nil @@ -173,16 +199,16 @@ func resourceVcdVcenterUpdate(ctx context.Context, d *schema.ResourceData, meta vcdClient := meta.(*VCDClient) c := crudConfig[*govcd.VCenter, types.VSphereVirtualCenter]{ - entityLabel: labelVirtualCenter, + entityLabel: labelTmVirtualCenter, getTypeFunc: getTmVcenterType, getEntityFunc: vcdClient.GetVCenterById, - resourceReadFunc: resourceVcdVcenterRead, + resourceReadFunc: resourceVcdTmVcenterRead, } return updateResource(ctx, d, meta, c) } -func resourceVcdVcenterRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { +func resourceVcdTmVcenterRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { vcdClient := meta.(*VCDClient) // TODO: TM: remove this block and use the commented one within crudConfig below. @@ -201,7 +227,7 @@ func resourceVcdVcenterRead(ctx context.Context, d *schema.ResourceData, meta in shouldRefresh := d.Get("refresh_vcenter_on_read").(bool) shouldRefreshPolicies := d.Get("refresh_policies_on_read").(bool) c := crudConfig[*govcd.VCenter, types.VSphereVirtualCenter]{ - entityLabel: labelVirtualCenter, + entityLabel: labelTmVirtualCenter, // getEntityFunc: vcdClient.GetVCenterById,// TODO: TM: use this function getEntityFunc: fakeGetById, // TODO: TM: remove this function stateStoreFunc: setTmVcenterData, @@ -213,11 +239,11 @@ func resourceVcdVcenterRead(ctx context.Context, d *schema.ResourceData, meta in return readResource(ctx, d, meta, c) } -func resourceVcdVcenterDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { +func resourceVcdTmVcenterDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { vcdClient := meta.(*VCDClient) c := crudConfig[*govcd.VCenter, types.VSphereVirtualCenter]{ - entityLabel: labelVirtualCenter, + entityLabel: labelTmVirtualCenter, getEntityFunc: vcdClient.GetVCenterById, preDeleteHooks: []outerEntityHook[*govcd.VCenter]{disableVcenter}, // vCenter must be disabled before deletion } @@ -225,12 +251,12 @@ func resourceVcdVcenterDelete(ctx context.Context, d *schema.ResourceData, meta return deleteResource(ctx, d, meta, c) } -func resourceVcdVcenterImport(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { +func resourceVcdTmVcenterImport(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { vcdClient := meta.(*VCDClient) v, err := vcdClient.GetVCenterByName(d.Id()) if err != nil { - return nil, fmt.Errorf("error retrieving %s by name: %s", labelVirtualCenter, err) + return nil, fmt.Errorf("error retrieving %s by name: %s", labelTmVirtualCenter, err) } d.SetId(v.VSphereVCenter.VcId) diff --git a/vcd/resource_vcd_vcenter_test.go b/vcd/resource_vcd_tm_vcenter_test.go similarity index 50% rename from vcd/resource_vcd_vcenter_test.go rename to vcd/resource_vcd_tm_vcenter_test.go index 46d708ed2..a8f1bf114 100644 --- a/vcd/resource_vcd_vcenter_test.go +++ b/vcd/resource_vcd_tm_vcenter_test.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) -func TestAccVcdVcenter(t *testing.T) { +func TestAccVcdTmVcenter(t *testing.T) { preTestChecks(t) skipIfNotSysAdmin(t) @@ -55,56 +55,57 @@ func TestAccVcdVcenter(t *testing.T) { { Config: configText1, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "id"), - resource.TestCheckResourceAttr("vcd_vcenter.test", "name", t.Name()), - resource.TestCheckResourceAttr("vcd_vcenter.test", "description", ""), - resource.TestCheckResourceAttr("vcd_vcenter.test", "is_enabled", "true"), - resource.TestCheckResourceAttr("vcd_vcenter.test", "has_proxy", "false"), - - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "cluster_health_status"), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "is_connected"), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "listener_state"), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "mode"), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "uuid"), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "version"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "id"), + resource.TestCheckResourceAttr("vcd_tm_vcenter.test", "name", t.Name()), + resource.TestCheckResourceAttr("vcd_tm_vcenter.test", "description", ""), + resource.TestCheckResourceAttr("vcd_tm_vcenter.test", "is_enabled", "true"), + resource.TestCheckResourceAttr("vcd_tm_vcenter.test", "has_proxy", "false"), + + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "cluster_health_status"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "is_connected"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "connection_status"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "mode"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "uuid"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "vcenter_version"), ), }, { Config: configText2, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "id"), - resource.TestCheckResourceAttr("vcd_vcenter.test", "name", t.Name()+"-rename"), - resource.TestCheckResourceAttr("vcd_vcenter.test", "is_enabled", "false"), - resource.TestCheckResourceAttr("vcd_vcenter.test", "description", "description from Terraform"), - resource.TestCheckResourceAttr("vcd_vcenter.test", "has_proxy", "false"), - - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "cluster_health_status"), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "is_connected"), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "listener_state"), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "mode"), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "uuid"), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "version"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "id"), + resource.TestCheckResourceAttr("vcd_tm_vcenter.test", "name", t.Name()+"-rename"), + resource.TestCheckResourceAttr("vcd_tm_vcenter.test", "is_enabled", "false"), + resource.TestCheckResourceAttr("vcd_tm_vcenter.test", "description", "description from Terraform"), + resource.TestCheckResourceAttr("vcd_tm_vcenter.test", "has_proxy", "false"), + + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "cluster_health_status"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "is_connected"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "connection_status"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "mode"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "uuid"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "vcenter_version"), + resource.TestCheckResourceAttr("vcd_tm_vcenter.test", "status", "READY"), ), }, { Config: configText3, Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "id"), - resource.TestCheckResourceAttr("vcd_vcenter.test", "name", t.Name()), - resource.TestCheckResourceAttr("vcd_vcenter.test", "description", ""), - resource.TestCheckResourceAttr("vcd_vcenter.test", "is_enabled", "true"), - resource.TestCheckResourceAttr("vcd_vcenter.test", "has_proxy", "false"), - - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "cluster_health_status"), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "is_connected"), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "listener_state"), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "mode"), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "uuid"), - resource.TestCheckResourceAttrSet("vcd_vcenter.test", "version"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "id"), + resource.TestCheckResourceAttr("vcd_tm_vcenter.test", "name", t.Name()), + resource.TestCheckResourceAttr("vcd_tm_vcenter.test", "description", ""), + resource.TestCheckResourceAttr("vcd_tm_vcenter.test", "is_enabled", "true"), + resource.TestCheckResourceAttr("vcd_tm_vcenter.test", "has_proxy", "false"), + + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "cluster_health_status"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "is_connected"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "connection_status"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "mode"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "uuid"), + resource.TestCheckResourceAttrSet("vcd_tm_vcenter.test", "vcenter_version"), ), }, { - ResourceName: "vcd_vcenter.test", + ResourceName: "vcd_tm_vcenter.test", ImportState: true, ImportStateVerify: true, ImportStateId: params["Testname"].(string), @@ -113,7 +114,7 @@ func TestAccVcdVcenter(t *testing.T) { { Config: configText4, Check: resource.ComposeTestCheckFunc( - resourceFieldsEqual("data.vcd_vcenter.test", "vcd_vcenter.test", []string{"%"}), + resourceFieldsEqual("data.vcd_tm_vcenter.test", "vcd_tm_vcenter.test", []string{"%"}), ), }, }, @@ -123,7 +124,7 @@ func TestAccVcdVcenter(t *testing.T) { } const testAccVcdVcenterStep1 = ` -resource "vcd_vcenter" "test" { +resource "vcd_tm_vcenter" "test" { name = "{{.Testname}}" url = "{{.VcenterUrl}}" auto_trust_certificate = true @@ -136,7 +137,7 @@ resource "vcd_vcenter" "test" { ` const testAccVcdVcenterStep2 = ` -resource "vcd_vcenter" "test" { +resource "vcd_tm_vcenter" "test" { name = "{{.Testname}}-rename" description = "description from Terraform" auto_trust_certificate = true @@ -148,7 +149,7 @@ resource "vcd_vcenter" "test" { ` const testAccVcdVcenterStep3 = ` -resource "vcd_vcenter" "test" { +resource "vcd_tm_vcenter" "test" { name = "{{.Testname}}" url = "{{.VcenterUrl}}" auto_trust_certificate = true @@ -159,7 +160,7 @@ resource "vcd_vcenter" "test" { ` const testAccVcdVcenterStep4DS = testAccVcdVcenterStep3 + ` -data "vcd_vcenter" "test" { - name = vcd_vcenter.test.name +data "vcd_tm_vcenter" "test" { + name = vcd_tm_vcenter.test.name } ` diff --git a/vcd/tm_common_test.go b/vcd/tm_common_test.go index bef91971b..696e3e946 100644 --- a/vcd/tm_common_test.go +++ b/vcd/tm_common_test.go @@ -3,8 +3,9 @@ package vcd import ( - "github.com/vmware/go-vcloud-director/v3/govcd" "testing" + + "github.com/vmware/go-vcloud-director/v3/govcd" ) // getVCenterHcl gets a vCenter data source as first returned parameter and its HCL reference as second one, @@ -15,10 +16,10 @@ func getVCenterHcl(t *testing.T) (string, string) { vc, err := vcdClient.GetVCenterByUrl(testConfig.Tm.VcenterUrl) if err == nil { return ` -data "vcd_vcenter" "vc" { +data "vcd_tm_vcenter" "vc" { name = "` + vc.VSphereVCenter.Name + `" } -`, "data.vcd_vcenter.vc" +`, "data.vcd_tm_vcenter.vc" } if !govcd.ContainsNotFound(err) { t.Fatal(err) @@ -29,7 +30,7 @@ data "vcd_vcenter" "vc" { return "", "" } return ` -resource "vcd_vcenter" "vc" { +resource "vcd_tm_vcenter" "vc" { name = "` + t.Name() + `" url = "` + testConfig.Tm.VcenterUrl + `" auto_trust_certificate = true @@ -39,7 +40,7 @@ resource "vcd_vcenter" "vc" { password = "` + testConfig.Tm.VcenterPassword + `" is_enabled = true } -`, "vcd_vcenter.vc" +`, "vcd_tm_vcenter.vc" } // getNsxManagerHcl gets a NSX Manager data source as first returned parameter and its HCL reference as second one, @@ -50,10 +51,10 @@ func getNsxManagerHcl(t *testing.T) (string, string) { nsxtManager, err := vcdClient.GetNsxtManagerOpenApiByUrl(testConfig.Tm.NsxtManagerUrl) if err == nil { return ` -data "vcd_nsxt_manager" "nsx_manager" { +data "vcd_tm_nsxt_manager" "nsx_manager" { name = "` + nsxtManager.NsxtManagerOpenApi.Name + `" } -`, "data.vcd_nsxt_manager.nsx_manager" +`, "data.vcd_tm_nsxt_manager.nsx_manager" } if !govcd.ContainsNotFound(err) { t.Fatal(err) @@ -64,7 +65,7 @@ data "vcd_nsxt_manager" "nsx_manager" { return "", "" } return ` -resource "vcd_nsxt_manager" "nsx_manager" { +resource "vcd_tm_nsxt_manager" "nsx_manager" { name = "` + t.Name() + `" description = "` + t.Name() + `" username = "` + testConfig.Tm.NsxtManagerUsername + `" @@ -74,7 +75,7 @@ resource "vcd_nsxt_manager" "nsx_manager" { auto_trust_certificate = true } -`, "vcd_nsxt_manager.nsx_manager" +`, "vcd_tm_nsxt_manager.nsx_manager" } // getRegionHcl gets a Region data source as first returned parameter and its HCL reference as second one, diff --git a/website/docs/d/nsxt_manager.html.markdown b/website/docs/d/nsxt_manager.html.markdown index 1b54075d3..ccbcc7cf3 100644 --- a/website/docs/d/nsxt_manager.html.markdown +++ b/website/docs/d/nsxt_manager.html.markdown @@ -35,7 +35,3 @@ The following arguments are supported: * `id` - ID of the manager * `href` - Full URL of the manager - -All attributes defined in -[`vcd_nsxt_manager`](/providers/vmware/vcd/latest/docs/resources/nsxt_manager#attribute-reference) -are supported. diff --git a/website/docs/d/tm_nsxt_manager.html.markdown b/website/docs/d/tm_nsxt_manager.html.markdown new file mode 100644 index 000000000..ba5921118 --- /dev/null +++ b/website/docs/d/tm_nsxt_manager.html.markdown @@ -0,0 +1,34 @@ +--- +layout: "vcd" +page_title: "VMware Cloud Director: vcd_tm_nsxt_manager" +sidebar_current: "docs-vcd-data-source-tm-nsxt-manager" +description: |- + Provides a data source for available Tenant Manager NSX-T manager. +--- + +# vcd\_tm\_nsxt\_manager + +Provides a data source for available Tenant Manager NSX-T manager. + +## Example Usage + +```hcl +data "vcd_tm_nsxt_manager" "main" { + name = "nsxt-manager-one" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) NSX-T manager name + +## Attribute reference + +* `id` - ID of the manager +* `href` - Full URL of the manager + +All attributes defined in +[`vcd_tm_nsxt_manager`](/providers/vmware/vcd/latest/docs/resources/tm_nsxt_manager#attribute-reference) +are supported. diff --git a/website/docs/d/tm_vcenter.html.markdown b/website/docs/d/tm_vcenter.html.markdown new file mode 100644 index 000000000..3a074a35a --- /dev/null +++ b/website/docs/d/tm_vcenter.html.markdown @@ -0,0 +1,34 @@ +--- +layout: "vcd" +page_title: "VMware Cloud Director: vcd_tm_vcenter" +sidebar_current: "docs-vcd-data-source-tm-vcenter" +description: |- + Provides a data source for vCenter server attached to VCD. +--- + +# vcd\_tm\_vcenter + +Provides a data source for vCenter server attached to VCD. + +Supported in provider *v3.0+* + + +## Example Usage + +```hcl +data "vcd_tm_vcenter" "vc" { + name = "vcenter-one" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) vCenter name + +## Attribute reference + +All attributes defined in +[`vcd_tm_vcenter`](/providers/vmware/vcd/latest/docs/resources/tm_vcenter#attribute-reference) are +supported. diff --git a/website/docs/d/vcenter.html.markdown b/website/docs/d/vcenter.html.markdown index 1a6e6836f..ebfda7b93 100644 --- a/website/docs/d/vcenter.html.markdown +++ b/website/docs/d/vcenter.html.markdown @@ -29,6 +29,8 @@ The following arguments are supported: ## Attribute reference -All attributes defined in -[`vcd_vcenter`](/providers/vmware/vcd/latest/docs/resources/vcenter#attribute-reference) are -supported. +* `connection_status` - vCenter connection status (e.g. `CONNECTED`). +* `is_enabled` - Boolean value if vCenter is enabled. +* `status` - vCenter status (e.g. `READY`). +* `vcenter_host` - Hostname of configured vCenter. +* `vcenter_version` - vCenter version (e.g. `6.7.0`) diff --git a/website/docs/r/nsxt_manager.html.markdown b/website/docs/r/tm_nsxt_manager.html.markdown similarity index 85% rename from website/docs/r/nsxt_manager.html.markdown rename to website/docs/r/tm_nsxt_manager.html.markdown index 894be73c4..43015d43a 100644 --- a/website/docs/r/nsxt_manager.html.markdown +++ b/website/docs/r/tm_nsxt_manager.html.markdown @@ -1,21 +1,21 @@ --- layout: "vcd" -page_title: "VMware Cloud Director: vcd_nsxt_manager" -sidebar_current: "docs-vcd-resource-nsxt-manager" +page_title: "VMware Cloud Director: vcd_tm_nsxt_manager" +sidebar_current: "docs-vcd-resource-tm-nsxt-manager" description: |- - Provides a resource to manage NSX-T Managers. + Provides a resource to manage Tenant Manager NSX-T Managers. --- -# vcd\_nsxt\_manager +# vcd\_tm\_nsxt\_manager -Provides a resource to manage NSX-T Managers. +Provides a resource to manage Tenant Manager NSX-T Managers. ~> Only `System Administrator` can create this resource. ## Example Usage ```hcl -resource "vcd_nsxt_manager" "test" { +resource "vcd_tm_nsxt_manager" "test" { name = "TestAccVcdTmNsxtManager" description = "terraform test" username = "admin" @@ -63,7 +63,7 @@ supplying path for it. An example is below: [docs-import]: https://www.terraform.io/docs/import/ ``` -terraform import vcd_nsxt_manager.imported my-nsxt-manager +terraform import vcd_tm_nsxt_manager.imported my-nsxt-manager ``` The above would import the `my-nsxt-manager` NSX-T Manager settings that are defined at provider diff --git a/website/docs/r/tm_region.html.markdown b/website/docs/r/tm_region.html.markdown index 21a9fc49d..72c67d869 100644 --- a/website/docs/r/tm_region.html.markdown +++ b/website/docs/r/tm_region.html.markdown @@ -24,7 +24,7 @@ data "vcd_tm_supervisor" "one" { resource "vcd_tm_region" "one" { name = "region-one" is_enabled = true - nsx_manager_id = data.vcd_nsxt_manager.test.id + nsx_manager_id = data.vcd_tm_nsxt_manager.test.id supervisor_ids = [data.vcd_tm_supervisor.test.id] storage_policy_names = ["vSAN Default Storage Policy"] } @@ -38,7 +38,7 @@ The following arguments are supported: * `description` - (Optional) An optional description for Region * `is_enabled` - (Optional) Defines if the Region is enabled. Default is `true` * `nsx_manager_id` - (Required) NSX-T Manager assigned to this region. Can be looked up using - [`vcd_nsxt_manager`](/providers/vmware/vcd/latest/docs/data-sources/nsxt_manager) + [`vcd_tm_nsxt_manager`](/providers/vmware/vcd/latest/docs/data-sources/tm_nsxt_manager) * `supervisor_ids` - (Required) A set of Supervisor IDs. At least one is required. Can be looked up using [`vcd_tm_supervisor`](/providers/vmware/vcd/latest/docs/data-sources/tm_supervisor) * `storage_policy_names` - (Required) A set of Storage Policy names to be used for this region. At diff --git a/website/docs/r/vcenter.html.markdown b/website/docs/r/tm_vcenter.html.markdown similarity index 86% rename from website/docs/r/vcenter.html.markdown rename to website/docs/r/tm_vcenter.html.markdown index 7b4c64074..bb611d13c 100644 --- a/website/docs/r/vcenter.html.markdown +++ b/website/docs/r/tm_vcenter.html.markdown @@ -1,12 +1,12 @@ --- layout: "vcd" -page_title: "VMware Cloud Director: vcd_vcenter" -sidebar_current: "docs-vcd-resource-vcenter" +page_title: "VMware Cloud Director: vcd_tm_vcenter" +sidebar_current: "docs-vcd-resource-tm-vcenter" description: |- Provides a resource to manage vCenters. --- -# vcd\_nsxt\_vcenter +# vcd\_tm\_vcenter Provides a resource to manage vCenters. @@ -15,7 +15,7 @@ Provides a resource to manage vCenters. ## Example Usage ```hcl -resource "vcd_vcenter" "test" { +resource "vcd_tm_vcenter" "test" { name = "TestAccVcdTmVcenter-rename" url = "https://host:443" auto_trust_certificate = true @@ -61,11 +61,14 @@ The following attributes are exported on this resource: * `is_connected` - Defines if the vCenter server is connected. * `mode` - One of `NONE`, `IAAS` (scoped to the provider), `SDDC` (scoped to tenants), `MIXED` (both uses are possible) -* `listener_state` - `INITIAL`, `INVALID_SETTINGS`, `UNSUPPORTED`, `DISCONNECTED`, `CONNECTING`, +* `connection_status` - `INITIAL`, `INVALID_SETTINGS`, `UNSUPPORTED`, `DISCONNECTED`, `CONNECTING`, `CONNECTED_SYNCING`, `CONNECTED`, `STOP_REQ`, `STOP_AND_PURGE_REQ`, `STOP_ACK` * `cluster_health_status` - Cluster health status. One of `GRAY` , `RED` , `YELLOW` , `GREEN` * `version` - vCenter version * `uuid` - UUID of vCenter +* `vcenter_host` - Host of vCenter server +* `status` - Status can be `READY` or `NOT_READY`. It is a derivative field of `is_connected` and + `connection_status` so relying on those fields could be more precise. ## Importing @@ -79,7 +82,7 @@ path for it. An example is below: [docs-import]: https://www.terraform.io/docs/import/ ``` -terraform import vcd_vcenter.imported my-vcenter +terraform import vcd_tm_vcenter.imported my-vcenter ``` The above would import the `my-vcenter` vCenter settings that are defined at provider level. diff --git a/website/vcd.erb b/website/vcd.erb index 6e707c2c9..3676778ce 100644 --- a/website/vcd.erb +++ b/website/vcd.erb @@ -499,6 +499,12 @@ > vcd_tm_region + > + vcd_tm_nsxt_manager + + > + vcd_tm_vcenter + > @@ -869,11 +875,11 @@ > vcd_tm_content_library - > - vcd_vcenter + > + vcd_tm_vcenter - > - vcd_nsxt_manager + > + vcd_tm_nsxt_manager > vcd_tm_region