├── .goreleaser.tmpl ├── CODEOWNERS ├── .github ├── labeler-issues.yml ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── docs.yml │ └── enhancement.yml ├── workflows │ ├── issues.yml │ ├── pull-requests.yml │ ├── golangci-lint.yml │ ├── test.yml │ ├── release.yml │ ├── lock.yml │ └── stale.yml ├── labeler-pull-requests.yml ├── pull_request_template.md └── dependabot.yml ├── terraform-registry-manifest.json ├── examples ├── resources │ ├── cluster │ │ ├── personality │ │ │ ├── cluster_personality.tf │ │ │ └── variables.tf │ │ ├── variables.tf │ │ └── vcf_cluster.tf │ ├── instance │ │ └── versions.tf │ ├── credentials │ │ ├── variables.tf │ │ ├── vcf_credentials_update.tf │ │ ├── vcf_credentials_auto_rotate_policy.tf │ │ └── vcf_credentials_rotate.tf │ ├── certificates │ │ ├── certificate_authority │ │ │ ├── variables.tf │ │ │ └── vcf_certificate_authority.tf │ │ ├── csr │ │ │ ├── variables.tf │ │ │ └── vcf_csr.tf │ │ ├── certificate │ │ │ ├── variables.tf │ │ │ └── vcf_certificate.tf │ │ └── external_certificate │ │ │ ├── vcf_external_certificate.tf │ │ │ └── variables.tf │ ├── network_pool │ │ ├── variables.tf │ │ └── vcf_network_pool.tf │ ├── user │ │ ├── vcf_user.tf │ │ └── variables.tf │ ├── host │ │ ├── variables.tf │ │ └── vcf_host.tf │ ├── domain │ │ └── variables.tf │ └── edge_cluster │ │ ├── variables.tf │ │ └── vcf_edge_cluster.tf ├── data-sources │ ├── credentials │ │ └── vcf_credentials.tf │ ├── cluster │ │ ├── vcf_cluster.tf │ │ └── variables.tf │ ├── network_pool │ │ ├── vcf_network_pool.tf │ │ └── variables.tf │ ├── domain │ │ ├── vcf_domain.tf │ │ └── variables.tf │ └── host │ │ ├── variables.tf │ │ └── vcf_host.tf ├── provider │ ├── provider.tf │ └── variables.tf ├── README.md ├── workflows │ └── private-ai-foundation │ │ ├── steps │ │ ├── 01 │ │ │ ├── variables.tf │ │ │ └── main.tf │ │ ├── 04 │ │ │ ├── variables.tf │ │ │ └── main.tf │ │ ├── 05 │ │ │ └── variables.tf │ │ ├── 03 │ │ │ └── variables.tf │ │ └── 02 │ │ │ └── variables.tf │ │ └── README.md ├── variables.tf └── main.tf ├── .gitignore ├── internal ├── version │ └── version.go ├── provider │ ├── data_network_pool_test.go │ ├── data_host_test.go │ ├── data_source_credentials_test.go │ ├── resource_credentials_password_update_test.go │ ├── resource_ceip_test.go │ ├── resource_cluster_personality_test.go │ ├── resource_credentials_password_rotate_test.go │ ├── resource_credentials_auto_rotate_policy_test.go │ ├── data_source_cluster_test.go │ ├── resource_network_pool_test.go │ ├── resource_user_test.go │ ├── data_certificate_test.go │ ├── resource_csr_test.go │ ├── data_source_cluster.go │ └── data_source_domain_test.go ├── vsan │ └── witness_host_subresource.go ├── api_client │ ├── sddc_manager_client_test.go │ └── client_util.go ├── sddc │ ├── sddc_credentials_subresource.go │ ├── sddc_vcf_operations_fleet_management_subresource.go │ ├── sddc_vcf_operations_collector_subresource.go │ ├── sddc_vsan_subresource.go │ ├── dns_subresource.go │ ├── sddc_host_subresource.go │ ├── sddc_manager_subresource.go │ ├── sddc_security_subresource.go │ ├── sddc_vcf_automation_subresource.go │ └── sddc_vcenter_subresource.go ├── nsx_edge_cluster │ └── cluster_profile_subresource.go ├── datastores │ ├── vmfs_datastore_subresource.go │ ├── vsan_remote_datastore_cluster_subresource.go │ ├── vsan_datastore_subresource.go │ ├── nfs_datastore_subresource.go │ └── vvol_datastore_subresource.go ├── credentials │ ├── constants.go │ └── credential_data_subresource.go ├── network │ ├── vmnic_subresource.go │ ├── portgroup_subresource.go │ └── nsx_manager_subresource.go ├── certificates │ └── csr_subresource.go └── resource_utils │ └── resource_utils.go ├── tools └── tools.go ├── scripts └── gofmtcheck.sh ├── NOTICE ├── Makefile ├── .golangci.yml ├── docs ├── resources │ ├── user.md │ ├── credentials_update.md │ ├── credentials_rotate.md │ ├── credentials_auto_rotate_policy.md │ ├── cluster_personality.md │ ├── ceip.md │ ├── certificate_authority.md │ ├── csr.md │ ├── network_pool.md │ ├── host.md │ └── external_certificate.md ├── data-sources │ ├── network_pool.md │ ├── certificate.md │ └── credentials.md ├── build.md ├── images │ └── icon-color.svg └── index.md ├── .goreleaser.yml ├── main.go └── CONTRIBUTING.md /.goreleaser.tmpl: -------------------------------------------------------------------------------- 1 | # Release {{ .Version }} ({{ .Date }}) -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | @vmware/terraform-provider-vcf-maintainers 2 | -------------------------------------------------------------------------------- /.github/labeler-issues.yml: -------------------------------------------------------------------------------- 1 | --- 2 | pending-review: 3 | - '.*' 4 | -------------------------------------------------------------------------------- /terraform-registry-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1, 3 | "metadata": { 4 | "protocol_versions": ["5.0"] 5 | } 6 | } -------------------------------------------------------------------------------- /examples/resources/cluster/personality/cluster_personality.tf: -------------------------------------------------------------------------------- 1 | resource "vcf_cluster_personality" "personality" { 2 | name = "personality1" 3 | cluster_id = var.cluster_id 4 | domain_id = var.domain_id 5 | } -------------------------------------------------------------------------------- /examples/resources/instance/versions.tf: -------------------------------------------------------------------------------- 1 | # Terraform and Provider Version Constraints 2 | terraform { 3 | required_version = ">= 1.0" 4 | 5 | required_providers { 6 | vcf = { 7 | source = "vmware/vcf" 8 | version = "0.17.0" 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /examples/data-sources/credentials/vcf_credentials.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | data "vcf_credentials" "creds" { 10 | 11 | } 12 | 13 | data "vcf_credentials" "creds_vc" { 14 | resource_type = "VCENTER" 15 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore any built binaries. 2 | terraform-provider-vcf* 3 | 4 | # Ignore distribution directories. 5 | dist/ 6 | 7 | # Ignore editor directories. 8 | .idea/ 9 | .vscode/ 10 | 11 | # Ignore temporary editor files. 12 | *~ 13 | 14 | # Ignore macOS desktop services store files. 15 | **/.DS_Store 16 | -------------------------------------------------------------------------------- /examples/resources/credentials/variables.tf: -------------------------------------------------------------------------------- 1 | variable "esxi_host_1" { 2 | default = "10.10.01.01" 3 | description = "Name of the first host in the setup" 4 | } 5 | 6 | variable "esxi_host_1_pass" { 7 | default = "s0m3_p@$w0rd" 8 | description = "The new password for the host" 9 | sensitive = true 10 | } -------------------------------------------------------------------------------- /internal/version/version.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package version 6 | 7 | // ProviderVersion is set during the release process to the release version of the binary. 8 | var ProviderVersion = "dev" 9 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: VMware Cloud Foundation Product Documentation 4 | url: https://docs.vmware.com/en/VMware-Cloud-Foundation/ 5 | about: Efficiently manage virtual machine and container workloads. Deliver cloud benefits to on-premises, full-stack hyperconverged infrastructure deployments. 6 | -------------------------------------------------------------------------------- /tools/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | // © Broadcom. All Rights Reserved. 5 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 6 | // SPDX-License-Identifier: MPL-2.0 7 | 8 | package tools 9 | 10 | import ( 11 | // Documentation generation. 12 | _ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs" 13 | ) 14 | -------------------------------------------------------------------------------- /examples/provider/provider.tf: -------------------------------------------------------------------------------- 1 | # Required Provider 2 | terraform { 3 | required_providers { 4 | vcf = { 5 | source = "vmware/vcf" 6 | } 7 | } 8 | } 9 | 10 | # Provider Configuration 11 | provider "vcf" { 12 | sddc_manager_username = var.sddc_manager_username 13 | sddc_manager_password = var.sddc_manager_password 14 | sddc_manager_host = var.sddc_manager_host 15 | } 16 | -------------------------------------------------------------------------------- /examples/data-sources/cluster/vcf_cluster.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | provider "vcf" { 10 | sddc_manager_username = var.sddc_manager_username 11 | sddc_manager_password = var.sddc_manager_password 12 | sddc_manager_host = var.sddc_manager_host 13 | } 14 | 15 | data "vcf_cluster" "cluster1" { 16 | cluster_id = var.vcf_cluster_id 17 | } -------------------------------------------------------------------------------- /examples/data-sources/network_pool/vcf_network_pool.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | provider "vcf" { 10 | sddc_manager_username = var.sddc_manager_username 11 | sddc_manager_password = var.sddc_manager_password 12 | sddc_manager_host = var.sddc_manager_host 13 | } 14 | 15 | data "vcf_network_pool" "example" { 16 | name = "example-pool" 17 | } 18 | -------------------------------------------------------------------------------- /examples/resources/credentials/vcf_credentials_update.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | resource "vcf_credentials_update" "vc_0_update" { 10 | resource_name = var.esxi_host_1 11 | resource_type = "ESXI" 12 | credentials { 13 | credential_type = "SSH" 14 | user_name = "root" 15 | password = var.esxi_host_1_pass 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /scripts/gofmtcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Check gofmt 4 | echo "==> Checking that code complies with gofmt requirements..." 5 | gofmt_files=$(find . -name '*.go' | grep -v vendor | xargs gofmt -l -s) 6 | if [[ -n ${gofmt_files} ]]; then 7 | echo 'gofmt needs running on the following files:' 8 | echo "${gofmt_files}" 9 | echo "You can use the command: \`make fmt\` to reformat code." 10 | exit 1 11 | fi 12 | 13 | exit 0 14 | -------------------------------------------------------------------------------- /examples/provider/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_username" { 2 | description = "Username used to authenticate against an SDDC Manager instance" 3 | default = "" 4 | } 5 | 6 | variable "sddc_manager_password" { 7 | description = "Password used to authenticate against an SDDC Manager instance" 8 | default = "" 9 | } 10 | 11 | variable "sddc_manager_host" { 12 | description = "FQDN of an SDDC Manager instance" 13 | default = "" 14 | } 15 | -------------------------------------------------------------------------------- /examples/data-sources/domain/vcf_domain.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | provider "vcf" { 10 | sddc_manager_username = var.sddc_manager_username 11 | sddc_manager_password = var.sddc_manager_password 12 | sddc_manager_host = var.sddc_manager_host 13 | } 14 | 15 | data "vcf_domain" "sfo-m01" { 16 | domain_id = var.domain_id 17 | } 18 | 19 | data "vcf_domain" "sfo-w01" { 20 | name = var.domain_name 21 | } -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | © Broadcom. All Rights Reserved. 2 | The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | 4 | This product is licensed to you under the Mozilla Public License, V2.0 (the "License"). You may not use this product except in compliance with the License. 5 | 6 | This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file. 7 | -------------------------------------------------------------------------------- /examples/resources/certificates/certificate_authority/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_username" { 2 | description = "Username used to authenticate against an SDDC Manager instance" 3 | default = "" 4 | } 5 | 6 | variable "sddc_manager_password" { 7 | description = "Password used to authenticate against an SDDC Manager instance" 8 | default = "" 9 | } 10 | 11 | variable "sddc_manager_host" { 12 | description = "Fully qualified domain name of an SDDC Manager instance" 13 | default = "" 14 | } -------------------------------------------------------------------------------- /examples/resources/network_pool/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_host" { 2 | description = "The fully qualified domain name of the SDDC Manager instance." 3 | } 4 | 5 | variable "sddc_manager_username" { 6 | description = "The username to authenticate to the SDDC Manager instance." 7 | sensitive = true 8 | } 9 | 10 | variable "sddc_manager_password" { 11 | description = "The password to authenticate to the SDDC Manager instance." 12 | sensitive = true 13 | } 14 | 15 | variable "network_pool_name" { 16 | description = "The name of the network pool." 17 | } 18 | -------------------------------------------------------------------------------- /examples/data-sources/network_pool/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_host" { 2 | description = "The fully qualified domain name of the SDDC Manager instance." 3 | } 4 | 5 | variable "sddc_manager_username" { 6 | description = "The username to authenticate to the SDDC Manager instance." 7 | sensitive = true 8 | } 9 | 10 | variable "sddc_manager_password" { 11 | description = "The password to authenticate to the SDDC Manager instance." 12 | sensitive = true 13 | } 14 | 15 | variable "network_pool_name" { 16 | description = "The name of the network pool." 17 | } 18 | -------------------------------------------------------------------------------- /.github/workflows/issues.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Issue Labels 3 | 4 | on: 5 | issues: 6 | types: 7 | - opened 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | label-issues: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | issues: write 17 | steps: 18 | - name: Apply Labels 19 | uses: github/issue-labeler@c1b0f9f52a63158c4adc09425e858e87b32e9685 # v3.4 20 | with: 21 | repo-token: '${{ secrets.GITHUB_TOKEN }}' 22 | configuration-path: .github/labeler-issues.yml 23 | enable-versioned-regex: 0 24 | include-title: 1 25 | -------------------------------------------------------------------------------- /examples/resources/certificates/csr/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_username" { 2 | description = "Username used to authenticate against an SDDC Manager instance" 3 | default = "" 4 | } 5 | 6 | variable "sddc_manager_password" { 7 | description = "Password used to authenticate against an SDDC Manager instance" 8 | default = "" 9 | } 10 | 11 | variable "sddc_manager_host" { 12 | description = "Fully qualified domain name of an SDDC Manager instance" 13 | default = "" 14 | } 15 | 16 | variable "vcf_domain_id" { 17 | description = "Id of the domain for whose resources CSRs are to be generated" 18 | default = "" 19 | } -------------------------------------------------------------------------------- /examples/resources/certificates/certificate/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_username" { 2 | description = "Username used to authenticate against an SDDC Manager instance" 3 | default = "" 4 | } 5 | 6 | variable "sddc_manager_password" { 7 | description = "Password used to authenticate against an SDDC Manager instance" 8 | default = "" 9 | } 10 | 11 | variable "sddc_manager_host" { 12 | description = "Fully qualified domain name of an SDDC Manager instance" 13 | default = "" 14 | } 15 | 16 | variable "vcf_domain_id" { 17 | description = "Id of the domain for whose resources CSRs are to be generated" 18 | default = "" 19 | } -------------------------------------------------------------------------------- /examples/resources/credentials/vcf_credentials_auto_rotate_policy.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | data "vcf_credentials" "sddc_creds" { 10 | resource_type = "VCENTER" 11 | } 12 | 13 | resource "vcf_credentials_auto_rotate_policy" "vc_0_autorotate" { 14 | resource_id = data.vcf_credentials.sddc_creds.credentials[0].resource[0].id 15 | resource_type = data.vcf_credentials.sddc_creds.credentials[0].resource[0].type 16 | user_name = data.vcf_credentials.sddc_creds.credentials[0].user_name 17 | enable_auto_rotation = true 18 | auto_rotate_days = 7 19 | } -------------------------------------------------------------------------------- /examples/data-sources/domain/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_host" { 2 | description = "The fully qualified domain name of the SDDC Manager instance." 3 | } 4 | 5 | variable "sddc_manager_username" { 6 | description = "The username to authenticate to the SDDC Manager instance." 7 | sensitive = true 8 | } 9 | 10 | variable "sddc_manager_password" { 11 | description = "The password to authenticate to the SDDC Manager instance." 12 | sensitive = true 13 | } 14 | 15 | variable "domain_id" { 16 | description = "The ID of the workload domain." 17 | } 18 | 19 | variable "domain_name" { 20 | description = "The name of the workload domain." 21 | name = "sfo-w01" 22 | } 23 | -------------------------------------------------------------------------------- /examples/resources/credentials/vcf_credentials_rotate.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | data "vcf_credentials" "sddc_creds" { 10 | resource_type = "VCENTER" 11 | account_type = "USER" 12 | } 13 | 14 | resource "vcf_credentials_rotate" "vc_0_rotate" { 15 | resource_name = data.vcf_credentials.sddc_creds.credentials[0].resource[0].name 16 | resource_type = data.vcf_credentials.sddc_creds.credentials[0].resource[0].type 17 | credentials { 18 | credential_type = data.vcf_credentials.sddc_creds.credentials[0].credential_type 19 | user_name = data.vcf_credentials.sddc_creds.credentials[0].user_name 20 | } 21 | } -------------------------------------------------------------------------------- /.github/workflows/pull-requests.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Pull Request Labels 3 | 4 | on: 5 | pull_request_target: 6 | branches: 7 | - main 8 | types: 9 | - opened 10 | - synchronize 11 | - reopened 12 | - edited 13 | - ready_for_review 14 | 15 | permissions: 16 | contents: read 17 | 18 | jobs: 19 | label-pull-requests: 20 | runs-on: ubuntu-latest 21 | permissions: 22 | pull-requests: write 23 | steps: 24 | - name: Apply Labels 25 | uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1 26 | with: 27 | configuration-path: .github/labeler-pull-requests.yml 28 | repo-token: '${{ secrets.GITHUB_TOKEN }}' 29 | -------------------------------------------------------------------------------- /examples/data-sources/cluster/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_username" { 2 | description = "Username used to authenticate against an SDDC Manager instance" 3 | default = "" 4 | } 5 | 6 | variable "sddc_manager_password" { 7 | description = "Password used to authenticate against an SDDC Manager instance" 8 | default = "" 9 | } 10 | 11 | variable "sddc_manager_host" { 12 | description = "Fully qualified domain name of an SDDC Manager instance" 13 | default = "" 14 | } 15 | 16 | variable "vcf_cluster_id" { 17 | description = "Id of the cluster that is to be used as a data source. Note: management domain default cluster ID can be used to refer to some of it's attributes" 18 | default = "" 19 | } -------------------------------------------------------------------------------- /examples/resources/certificates/certificate_authority/vcf_certificate_authority.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | provider "vcf" { 10 | sddc_manager_username = var.sddc_manager_username 11 | sddc_manager_password = var.sddc_manager_password 12 | sddc_manager_host = var.sddc_manager_host 13 | } 14 | 15 | resource "vcf_certificate_authority" "ca" { 16 | open_ssl { 17 | common_name = "test.openssl.eng.vmware.com" 18 | country = "BG" 19 | state = "Sofia-grad" 20 | locality = "Sofia" 21 | organization = "VMware" 22 | ogranization_unit = "CIBG" 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /examples/resources/certificates/csr/vcf_csr.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | provider "vcf" { 10 | sddc_manager_username = var.sddc_manager_username 11 | sddc_manager_password = var.sddc_manager_password 12 | sddc_manager_host = var.sddc_manager_host 13 | } 14 | 15 | resource "vcf_csr" "csr1" { 16 | domain_id = var.vcf_domain_id 17 | country = "BG" 18 | email = "admin@vmware.com" 19 | key_size = "3072" 20 | locality = "Sofia" 21 | state = "Sofia-grad" 22 | organization = "VMware Inc." 23 | organization_unit = "VCF" 24 | resource = "VCENTER" 25 | } -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | TEST?=$$(go list ./... |grep -v 'vendor') 2 | PKG_NAME=internal 3 | 4 | documentation: 5 | go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs generate --examples-dir=./examples 6 | 7 | fmtcheck: 8 | @sh -c "'$(CURDIR)/scripts/gofmtcheck.sh'" 9 | 10 | lint: 11 | @echo "==> Checking source code against linters..." 12 | @golangci-lint run ./$(PKG_NAME)/... 13 | 14 | build: fmtcheck 15 | go install 16 | 17 | init: 18 | go build -o terraform-provider-vcf 19 | terraform init 20 | 21 | test: fmtcheck 22 | go test -i $(TEST) || exit 1 23 | echo $(TEST) | \ 24 | xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4 25 | 26 | testacc: 27 | TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 240m -parallel=4 28 | -------------------------------------------------------------------------------- /examples/data-sources/host/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_host" { 2 | type = string 3 | description = "The fully qualified domain name of the SDDC Manager instance." 4 | } 5 | 6 | variable "sddc_manager_username" { 7 | type = string 8 | description = "The username to authenticate to the SDDC Manager instance." 9 | sensitive = true 10 | } 11 | 12 | variable "sddc_manager_password" { 13 | type = string 14 | description = "The password to authenticate to the SDDC Manager instance." 15 | sensitive = true 16 | } 17 | 18 | variable "host_fqdn" { 19 | type = string 20 | description = "The fully qualified domain name of the ESXi host." 21 | default = "sfo-w01-esx01.sfo.rainpole.io" 22 | } 23 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | This directory contains examples that are mostly used for documentation, but can also be run/tested manually via the Terraform CLI. 4 | 5 | The document generation tool looks for files in the following locations by default. All other *.tf files besides the ones mentioned below are ignored by the documentation tool. This is useful for creating examples that can run and/or ar testable even if some parts are not relevant for the documentation. 6 | 7 | * **provider/provider.tf** example file for the provider index page 8 | * **data-sources/`full data source name`/data-source.tf** example file for the named data source page 9 | * **resources/`full resource name`/resource.tf** example file for the named data source page 10 | -------------------------------------------------------------------------------- /examples/resources/user/vcf_user.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | provider "vcf" { 10 | sddc_manager_username = var.sddc_manager_username 11 | sddc_manager_password = var.sddc_manager_password 12 | sddc_manager_host = var.sddc_manager_host 13 | } 14 | 15 | resource "vcf_user" "user1" { 16 | name = var.sso_username 17 | domain = var.sso_domain 18 | type = "USER" 19 | role_name = "ADMIN" 20 | } 21 | 22 | # Service users have api_key output associated with them 23 | resource "vcf_user" "service_user1" { 24 | name = var.sso_service_username 25 | domain = var.sso_domain 26 | type = "SERVICE" 27 | role_name = "VIEWER" 28 | } -------------------------------------------------------------------------------- /examples/resources/cluster/personality/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_username" { 2 | description = "Username used to authenticate against an SDDC Manager instance" 3 | default = "" 4 | } 5 | 6 | variable "sddc_manager_password" { 7 | description = "Password used to authenticate against an SDDC Manager instance" 8 | default = "" 9 | } 10 | 11 | variable "sddc_manager_host" { 12 | description = "Fully qualified domain name of an SDDC Manager instance" 13 | default = "" 14 | } 15 | 16 | variable "cluster_id" { 17 | description = "Id of the cluster in the vCenter server (e.g. domain-c21)" 18 | default = "" 19 | } 20 | 21 | variable "domain_id" { 22 | description = "Id of the domain in which the cluster is to be created" 23 | default = "" 24 | } 25 | -------------------------------------------------------------------------------- /examples/workflows/private-ai-foundation/steps/01/variables.tf: -------------------------------------------------------------------------------- 1 | variable "vcenter_username" { 2 | description = "Username used to authenticate against the vCenter Server" 3 | } 4 | 5 | variable "vcenter_password" { 6 | description = "Password used to authenticate against the vCenter Server" 7 | } 8 | 9 | variable "vcenter_server" { 10 | description = "FQDN or IP Address of the vCenter Server for the management domain" 11 | } 12 | 13 | variable "datacenter_name" { 14 | description = "The name of the datacenter where the new cluster will be created" 15 | } 16 | 17 | variable "cluster_name" { 18 | description = "The name of the compute cluster" 19 | } 20 | 21 | variable "depot_location" { 22 | description = "The URL where the contents for the offline software depot are hosted" 23 | } -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | version: "2" 2 | linters: 3 | default: none 4 | enable: 5 | - copyloopvar 6 | - durationcheck 7 | - errcheck 8 | - godot 9 | - govet 10 | - ineffassign 11 | - makezero 12 | - misspell 13 | - nilerr 14 | - predeclared 15 | - staticcheck 16 | - unconvert 17 | - unparam 18 | - unused 19 | exclusions: 20 | generated: lax 21 | presets: 22 | - comments 23 | - common-false-positives 24 | - legacy 25 | - std-error-handling 26 | paths: 27 | - third_party$ 28 | - builtin$ 29 | - examples$ 30 | issues: 31 | max-same-issues: 0 32 | formatters: 33 | enable: 34 | - gofmt 35 | exclusions: 36 | generated: lax 37 | paths: 38 | - third_party$ 39 | - builtin$ 40 | - examples$ 41 | -------------------------------------------------------------------------------- /examples/workflows/private-ai-foundation/steps/04/variables.tf: -------------------------------------------------------------------------------- 1 | variable "vcenter_username" { 2 | description = "Username used to authenticate against the vCenter Server" 3 | } 4 | 5 | variable "vcenter_password" { 6 | description = "Password used to authenticate against the vCenter Server" 7 | } 8 | 9 | variable "vcenter_server" { 10 | description = "FQDN or IP Address of the vCenter Server for the workload domain" 11 | } 12 | 13 | variable "datacenter_name" { 14 | description = "The name of the datacenter" 15 | } 16 | 17 | variable "vsan_datastore_name" { 18 | description = "The name of the vsan datastore" 19 | } 20 | 21 | variable "content_library_name" { 22 | description = "The name of the content library" 23 | } 24 | 25 | variable "content_library_url" { 26 | description = "The subscription URL for the content library" 27 | } -------------------------------------------------------------------------------- /examples/resources/host/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_username" { 2 | description = "Username used to authenticate against an SDDC Manager instance" 3 | default = "" 4 | } 5 | 6 | variable "sddc_manager_password" { 7 | description = "Password used to authenticate against an SDDC Manager instance" 8 | default = "" 9 | } 10 | 11 | variable "sddc_manager_host" { 12 | description = "FQDN of an SDDC Manager instance" 13 | default = "" 14 | } 15 | 16 | variable "host_fqdn" { 17 | description = "FQDN of an ESXi host that is to be commissioned" 18 | default = "" 19 | } 20 | 21 | variable "host_ssh_user" { 22 | description = "SSH user in ESXi host that is to be commissioned" 23 | default = "" 24 | } 25 | 26 | variable "host_ssh_pass" { 27 | description = "SSH pass in ESXi host that is to be commissioned" 28 | default = "" 29 | } -------------------------------------------------------------------------------- /examples/resources/user/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_username" { 2 | description = "Username used to authenticate against an SDDC Manager instance" 3 | default = "" 4 | } 5 | 6 | variable "sddc_manager_password" { 7 | description = "Password used to authenticate against an SDDC Manager instance" 8 | default = "" 9 | } 10 | 11 | variable "sddc_manager_host" { 12 | description = "FQDN of an SDDC Manager instance" 13 | default = "" 14 | } 15 | 16 | variable "sso_domain" { 17 | description = "The SSO domain in which an SSO user is to be created" 18 | default = "rainpole.io" 19 | } 20 | 21 | variable "sso_username" { 22 | description = "Username of an SSO user to be created" 23 | default = "" 24 | } 25 | 26 | variable "sso_service_username" { 27 | description = "Username of an SSO service user to be created" 28 | default = "" 29 | } -------------------------------------------------------------------------------- /.github/workflows/golangci-lint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: golangci-lint 3 | 4 | on: 5 | pull_request: 6 | paths-ignore: 7 | - README.md 8 | push: 9 | paths-ignore: 10 | - README.md 11 | 12 | permissions: 13 | contents: read 14 | 15 | jobs: 16 | build: 17 | name: Build 18 | runs-on: ubuntu-latest 19 | timeout-minutes: 5 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 23 | - name: Setup Go 24 | uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 25 | with: 26 | go-version-file: go.mod 27 | cache: true 28 | - run: go mod download 29 | - run: go build -v . 30 | - name: Run Linters 31 | uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0 32 | with: 33 | version: v2.1.6 34 | -------------------------------------------------------------------------------- /examples/resources/certificates/external_certificate/vcf_external_certificate.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | provider "vcf" { 10 | sddc_manager_username = var.sddc_manager_username 11 | sddc_manager_password = var.sddc_manager_password 12 | sddc_manager_host = var.sddc_manager_host 13 | } 14 | 15 | resource "vcf_csr" "vcenter_csr" { 16 | domain_id = var.vcf_domain_id 17 | country = "BG" 18 | email = "admin@vmware.com" 19 | key_size = "3072" 20 | locality = "Sofia" 21 | state = "Sofia-grad" 22 | organization = "VMware Inc." 23 | organization_unit = "VCF" 24 | resource = "VCENTER" 25 | } 26 | 27 | resource "vcf_external_certificate" "vcenter_cert" { 28 | csr_id = vcf_csr.vcenter_csr.id 29 | resource_certificate = var.new_certificate 30 | ca_certificate = var.ca_certificate 31 | } -------------------------------------------------------------------------------- /.github/labeler-pull-requests.yml: -------------------------------------------------------------------------------- 1 | --- 2 | chore: 3 | - changed-files: 4 | - any-glob-to-any-file: 5 | - ".github/**/*" 6 | - ".gitignore" 7 | - ".release" 8 | - "scripts/**/*" 9 | - "tools/**/*" 10 | - "go.mod" 11 | - "go.sum" 12 | dependencies: 13 | - changed-files: 14 | - any-glob-to-any-file: 15 | - "go.mod" 16 | - "go.sum" 17 | documentation: 18 | - changed-files: 19 | - any-glob-to-any-file: 20 | - "**/*.md" 21 | - "examples/**/*" 22 | - "docs/**/*" 23 | github-actions: 24 | - changed-files: 25 | - any-glob-to-any-file: 26 | - ".github/workflows/**/*" 27 | needs-review: 28 | - changed-files: 29 | - any-glob-to-any-file: 30 | - "**" 31 | provider: 32 | - changed-files: 33 | - any-glob-to-any-file: 34 | - "internal/**/*" 35 | - "Makefile" 36 | - "go.mod" 37 | - "go.sum" 38 | - "main.go" 39 | -------------------------------------------------------------------------------- /examples/resources/network_pool/vcf_network_pool.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | provider "vcf" { 10 | sddc_manager_username = var.sddc_manager_username 11 | sddc_manager_password = var.sddc_manager_password 12 | sddc_manager_host = var.sddc_manager_host 13 | } 14 | 15 | resource "vcf_network_pool" "example" { 16 | name = var.network_pool_name 17 | network { 18 | gateway = "192.168.8.1" 19 | mask = "255.255.255.0" 20 | mtu = 9000 21 | subnet = "192.168.8.0" 22 | type = "VSAN" 23 | vlan_id = 100 24 | ip_pools { 25 | start = "192.168.8.5" 26 | end = "192.168.8.50" 27 | } 28 | } 29 | network { 30 | gateway = "192.168.9.1" 31 | mask = "255.255.255.0" 32 | mtu = 9000 33 | subnet = "192.168.9.0" 34 | type = "vMotion" 35 | vlan_id = 100 36 | ip_pools { 37 | start = "192.168.9.5" 38 | end = "192.168.9.50" 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /examples/resources/certificates/external_certificate/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_username" { 2 | description = "Username used to authenticate against an SDDC Manager instance" 3 | default = "" 4 | } 5 | 6 | variable "sddc_manager_password" { 7 | description = "Password used to authenticate against an SDDC Manager instance" 8 | default = "" 9 | } 10 | 11 | variable "sddc_manager_host" { 12 | description = "Fully qualified domain name of an SDDC Manager instance" 13 | default = "" 14 | } 15 | 16 | variable "vcf_domain_id" { 17 | description = "Id of the domain for whose resources CSRs are to be generated" 18 | default = "" 19 | } 20 | 21 | variable "new_certificate" { 22 | description = "PEM encoded certificate for a resource within a Domain that is to replace the old one. Can be issued by an external to VCF CA." 23 | default = "" 24 | } 25 | 26 | variable "ca_certificate" { 27 | description = "PEM encoded certificate of the CA that issued the above resource certificate" 28 | default = "" 29 | } -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Test 3 | 4 | on: 5 | pull_request: 6 | paths-ignore: 7 | - README.md 8 | push: 9 | paths-ignore: 10 | - README.md 11 | 12 | permissions: 13 | contents: read 14 | 15 | jobs: 16 | test: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 21 | - name: Setup Go 22 | uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 23 | with: 24 | go-version-file: go.mod 25 | cache: true 26 | - name: Install Dependencies 27 | run: go mod download 28 | - name: Build 29 | run: go build -v . 30 | - name: Run Generate 31 | run: go generate ./... 32 | - name: Check Generated Code 33 | run: | 34 | git diff --compact-summary --exit-code || \ 35 | (echo; echo "Unexpected difference in directories after code generation. Run 'go generate ./...' command and commit."; exit 1) 36 | -------------------------------------------------------------------------------- /docs/resources/user.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "vcf_user Resource - terraform-provider-vcf" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # vcf_user (Resource) 10 | 11 | Used to create and destroy SSO users with specified roles in an SSO domain 12 | 13 | 14 | ## Schema 15 | 16 | ### Required 17 | 18 | - `domain` (String) The domain of the user 19 | - `name` (String) The name of the user 20 | - `role_name` (String) The name of the role to assign to the user 21 | - `type` (String) The type of the user. One of: USER, GROUP, SERVICE 22 | 23 | ### Optional 24 | 25 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 26 | 27 | ### Read-Only 28 | 29 | - `api_key` (String, Sensitive) API Key for a service user 30 | - `creation_timestamp` (String) 31 | - `id` (String) The ID of this resource. 32 | 33 | 34 | ### Nested Schema for `timeouts` 35 | 36 | Optional: 37 | 38 | - `create` (String) 39 | -------------------------------------------------------------------------------- /examples/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_username" { 2 | description = "username used to authenticate against an SDDC Manager instance" 3 | default = "" 4 | } 5 | 6 | variable "sddc_manager_password" { 7 | description = "Password used to authenticate against an SDDC Manager instance" 8 | default = "" 9 | } 10 | 11 | variable "sddc_manager_host" { 12 | description = "FQDN of an SDDC Manager instance" 13 | default = "" 14 | } 15 | 16 | variable "esxi_1_user" { 17 | description = "SSH user of ESXi1 server" 18 | default = "" 19 | } 20 | 21 | variable "esxi_1_pass" { 22 | description = "SSH password of ESXi1 server" 23 | default = "" 24 | } 25 | 26 | variable "esxi_2_user" { 27 | description = "SSH user of ESXi2 server" 28 | default = "" 29 | } 30 | 31 | variable "esxi_2_pass" { 32 | description = "SSH password of ESXi2 server" 33 | default = "" 34 | } 35 | 36 | variable "esxi_3_user" { 37 | description = "SSH user of ESXi3 server" 38 | default = "" 39 | } 40 | 41 | variable "esxi_3_pass" { 42 | description = "SSH password of ESXi3 server" 43 | default = "" 44 | } -------------------------------------------------------------------------------- /docs/data-sources/network_pool.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "vcf_network_pool Data Source - terraform-provider-vcf" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # vcf_network_pool (Data Source) 10 | 11 | 12 | 13 | 14 | 15 | 16 | ## Schema 17 | 18 | ### Required 19 | 20 | - `name` (String) The name of the network pool 21 | 22 | ### Read-Only 23 | 24 | - `id` (String) The ID of the network pool 25 | - `network` (List of Object) The network in the network pool (see [below for nested schema](#nestedatt--network)) 26 | 27 | 28 | ### Nested Schema for `network` 29 | 30 | Read-Only: 31 | 32 | - `gateway` (String) 33 | - `ip_pools` (List of Object) (see [below for nested schema](#nestedobjatt--network--ip_pools)) 34 | - `mask` (String) 35 | - `mtu` (Number) 36 | - `subnet` (String) 37 | - `type` (String) 38 | - `vlan_id` (Number) 39 | 40 | 41 | ### Nested Schema for `network.ip_pools` 42 | 43 | Read-Only: 44 | 45 | - `end` (String) 46 | - `start` (String) 47 | -------------------------------------------------------------------------------- /docs/resources/credentials_update.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "vcf_credentials_update Resource - terraform-provider-vcf" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # vcf_credentials_update (Resource) 10 | 11 | 12 | 13 | 14 | 15 | 16 | ## Schema 17 | 18 | ### Required 19 | 20 | - `credentials` (Block List, Min: 1) The credentials that should be updated (see [below for nested schema](#nestedblock--credentials)) 21 | - `resource_name` (String) The name of the resource which credentials will be updated 22 | - `resource_type` (String) The type of the resource which credentials will be updated 23 | 24 | ### Read-Only 25 | 26 | - `id` (String) The ID of this resource. 27 | - `last_update_time` (String) The time of the last password rotation. 28 | 29 | 30 | ### Nested Schema for `credentials` 31 | 32 | Required: 33 | 34 | - `credential_type` (String) The type(s) of the account. One among: SSO, SSH, API, FTP, AUDIT 35 | - `password` (String, Sensitive) The password for the account. 36 | - `user_name` (String) The user name of the account. 37 | -------------------------------------------------------------------------------- /examples/resources/certificates/certificate/vcf_certificate.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | provider "vcf" { 10 | sddc_manager_username = var.sddc_manager_username 11 | sddc_manager_password = var.sddc_manager_password 12 | sddc_manager_host = var.sddc_manager_host 13 | } 14 | 15 | resource "vcf_certificate_authority" "ca" { 16 | open_ssl { 17 | common_name = "test.openssl.eng.vmware.com" 18 | country = "BG" 19 | state = "Sofia-grad" 20 | locality = "Sofia" 21 | organization = "VMware" 22 | ogranization_unit = "VCF" 23 | } 24 | } 25 | 26 | resource "vcf_csr" "vcenter_csr" { 27 | domain_id = var.vcf_domain_id 28 | country = "BG" 29 | email = "admin@vmware.com" 30 | key_size = "3072" 31 | locality = "Sofia" 32 | state = "Sofia-grad" 33 | organization = "VMware Inc." 34 | organization_unit = "VCF" 35 | resource = "VCENTER" 36 | } 37 | 38 | resource "vcf_certificate" "vcenter_cert" { 39 | csr_id = vcf_csr.vcenter_csr.id 40 | ca_id = vcf_certificate_authority.ca.id 41 | } -------------------------------------------------------------------------------- /docs/resources/credentials_rotate.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "vcf_credentials_rotate Resource - terraform-provider-vcf" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # vcf_credentials_rotate (Resource) 10 | 11 | 12 | 13 | 14 | 15 | 16 | ## Schema 17 | 18 | ### Required 19 | 20 | - `credentials` (Block List, Min: 1) The credentials that should be rotated (see [below for nested schema](#nestedblock--credentials)) 21 | - `resource_name` (String) The name of the resource which credentials will be rotated 22 | - `resource_type` (String) The type of the resource which credentials will be rotated 23 | 24 | ### Read-Only 25 | 26 | - `id` (String) The ID of this resource. 27 | - `last_rotate_time` (String) The time of the last password rotation. 28 | 29 | 30 | ### Nested Schema for `credentials` 31 | 32 | Required: 33 | 34 | - `credential_type` (String) The type(s) of the account. One among: SSO, SSH, API, FTP, AUDIT 35 | - `user_name` (String) The user name of the account. 36 | 37 | Read-Only: 38 | 39 | - `password` (String, Sensitive) The password for the account. 40 | -------------------------------------------------------------------------------- /internal/provider/data_network_pool_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023-2024 Broadcom. All Rights Reserved. 2 | // SPDX-License-Identifier: MPL-2.0 3 | 4 | package provider 5 | 6 | import ( 7 | "fmt" 8 | "testing" 9 | 10 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 11 | 12 | "github.com/vmware/terraform-provider-vcf/internal/constants" 13 | ) 14 | 15 | func TestAccDataSourceVcfNetworkPool(t *testing.T) { 16 | resource.Test(t, resource.TestCase{ 17 | PreCheck: func() { testAccPreCheck(t) }, 18 | ProtoV6ProviderFactories: muxedFactories(), 19 | Steps: []resource.TestStep{ 20 | { 21 | Config: testAccDataSourceVcfNetworkPoolConfig(constants.VcfTestNetworkPoolName), 22 | Check: resource.ComposeTestCheckFunc( 23 | resource.TestCheckResourceAttrSet("data.vcf_network_pool.test_pool", "id"), 24 | resource.TestCheckResourceAttr("data.vcf_network_pool.test_pool", "name", constants.VcfTestNetworkPoolName), 25 | ), 26 | }, 27 | }, 28 | }) 29 | } 30 | 31 | func testAccDataSourceVcfNetworkPoolConfig(networkPoolName string) string { 32 | return fmt.Sprintf(` 33 | data "vcf_network_pool" "test_pool" { 34 | name = %q 35 | } 36 | `, networkPoolName) 37 | } 38 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Release 3 | 4 | on: 5 | push: 6 | tags: 7 | - v* 8 | 9 | permissions: 10 | contents: write 11 | 12 | jobs: 13 | release: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Checkout 17 | uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 18 | with: 19 | fetch-depth: 0 20 | - name: Setup Go 21 | uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 22 | with: 23 | go-version-file: go.mod 24 | - name: Import GPG Key 25 | uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0 26 | id: import_gpg 27 | with: 28 | gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} 29 | passphrase: ${{ secrets.GPG_PASSPHRASE }} 30 | - name: Run GoReleaser 31 | uses: goreleaser/goreleaser-action@e435ccd777264be153ace6237001ef4d979d3a7a # v6.4.0 32 | with: 33 | version: latest 34 | args: release --clean --release-header .goreleaser.tmpl 35 | env: 36 | GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} 37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | -------------------------------------------------------------------------------- /docs/resources/credentials_auto_rotate_policy.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "vcf_credentials_auto_rotate_policy Resource - terraform-provider-vcf" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # vcf_credentials_auto_rotate_policy (Resource) 10 | 11 | 12 | 13 | 14 | 15 | 16 | ## Schema 17 | 18 | ### Required 19 | 20 | - `enable_auto_rotation` (Boolean) Enable or disable the automatic credential rotation 21 | - `resource_type` (String) The type of the resource which credentials autorotate policy will be managed 22 | - `user_name` (String) The account name which autorotate policy will be managed 23 | 24 | ### Optional 25 | 26 | - `auto_rotate_days` (Number) The number of days after the credentials will be automatically rotated. Must be between 1 and 90 27 | - `resource_id` (String) The ID of the resource which credentials autorotate policy will be managed 28 | - `resource_name` (String) The name of the resource which credentials autorotate policy will be managed 29 | 30 | ### Read-Only 31 | 32 | - `auto_rotate_next_schedule` (String) The next time automatic rotation will be started 33 | - `id` (String) The ID of this resource. 34 | -------------------------------------------------------------------------------- /docs/resources/cluster_personality.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "vcf_cluster_personality Resource - terraform-provider-vcf" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # vcf_cluster_personality (Resource) 10 | 11 | This resource exports cluster images (personalities) from vLCM-managed compute clusters. 12 | VCF allows for the creation of images from both managed and external (standalone) vCenter servers. 13 | 14 | This resource only supports the former. 15 | 16 | 17 | ## Schema 18 | 19 | ### Required 20 | 21 | - `cluster_id` (String) The identifier of the source cluster within the vCenter server (e.g. domain-c1) 22 | - `domain_id` (String) The identifier of the domain which contains the vcenter and source cluster 23 | - `name` (String) The name for the personality 24 | 25 | ### Optional 26 | 27 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 28 | 29 | ### Read-Only 30 | 31 | - `id` (String) The ID of this resource. 32 | 33 | 34 | ### Nested Schema for `timeouts` 35 | 36 | Optional: 37 | 38 | - `create` (String) 39 | - `delete` (String) 40 | - `update` (String) 41 | -------------------------------------------------------------------------------- /examples/resources/host/vcf_host.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | provider "vcf" { 10 | sddc_manager_username = var.sddc_manager_username 11 | sddc_manager_password = var.sddc_manager_password 12 | sddc_manager_host = var.sddc_manager_host 13 | } 14 | 15 | resource "vcf_network_pool" "eng_pool" { 16 | name = "engineering-pool" 17 | network { 18 | gateway = "192.168.8.1" 19 | mask = "255.255.255.0" 20 | mtu = 9000 21 | subnet = "192.168.8.0" 22 | type = "VSAN" 23 | vlan_id = 100 24 | ip_pools { 25 | start = "192.168.8.5" 26 | end = "192.168.8.50" 27 | } 28 | } 29 | network { 30 | gateway = "192.168.9.1" 31 | mask = "255.255.255.0" 32 | mtu = 9000 33 | subnet = "192.168.9.0" 34 | type = "vMotion" 35 | vlan_id = 100 36 | ip_pools { 37 | start = "192.168.9.5" 38 | end = "192.168.9.50" 39 | } 40 | } 41 | } 42 | 43 | resource "vcf_host" "host1" { 44 | fqdn = var.host_fqdn 45 | username = var.host_ssh_user 46 | password = var.host_ssh_pass 47 | network_pool_id = vcf_network_pool.eng_pool.id 48 | storage_type = "VSAN" 49 | } -------------------------------------------------------------------------------- /examples/workflows/private-ai-foundation/steps/04/main.tf: -------------------------------------------------------------------------------- 1 | # This step creates a subscribed content library. 2 | # You can use a custom subscription URL or you can use 3 | # the content published by Broadcom 4 | 5 | terraform { 6 | required_providers { 7 | vsphere = { 8 | source = "hashicorp/vsphere" 9 | } 10 | } 11 | } 12 | 13 | # Connect to the vCenter Server backing the workload domain 14 | provider "vsphere" { 15 | user = var.vcenter_username 16 | password = var.vcenter_password 17 | vsphere_server = var.vcenter_server 18 | } 19 | 20 | # Request the Datacenter you created in step 2 as part of your workload domain 21 | data "vsphere_datacenter" "dc" { 22 | name = var.datacenter_name 23 | } 24 | 25 | # Request the vSAN datastore you created in step 2 as part of your workload domain 26 | data "vsphere_datastore" "vsan_ds" { 27 | datacenter_id = "${data.vsphere_datacenter.dc.id}" 28 | name = var.vsan_datastore_name 29 | } 30 | 31 | # Create a subscribed Content Library 32 | resource "vsphere_content_library" "library" { 33 | name = var.content_library_name 34 | storage_backing = [ data.vsphere_datastore.vsan_ds.id ] 35 | subscription { 36 | subscription_url = var.content_library_url 37 | } 38 | } -------------------------------------------------------------------------------- /internal/vsan/witness_host_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package vsan 6 | 7 | import ( 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 10 | 11 | validation_utils "github.com/vmware/terraform-provider-vcf/internal/validation" 12 | ) 13 | 14 | func WitnessHostSubresource() *schema.Resource { 15 | return &schema.Resource{ 16 | Schema: map[string]*schema.Schema{ 17 | "vsan_ip": { 18 | Type: schema.TypeString, 19 | Required: true, 20 | Description: "IP address for the witness host on the vSAN network", 21 | ValidateFunc: validation.IsIPv4Address, 22 | }, 23 | "vsan_cidr": { 24 | Type: schema.TypeString, 25 | Required: true, 26 | Description: "CIDR address for the witness host on the vSAN network", 27 | ValidateFunc: validation_utils.ValidateCidrIPv4AddressSchema, 28 | }, 29 | "fqdn": { 30 | Type: schema.TypeString, 31 | Required: true, 32 | Description: "Fully qualified domain name of the witness host. It should be routable on the vSAN network", 33 | ValidateFunc: validation.NoZeroValues, 34 | }, 35 | }, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /internal/api_client/sddc_manager_client_test.go: -------------------------------------------------------------------------------- 1 | package api_client 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | "testing" 7 | 8 | "github.com/vmware/vcf-sdk-go/vcf" 9 | ) 10 | 11 | func TestGetResponseAs_pos(t *testing.T) { 12 | taskId := "id" 13 | model := vcf.Task{Id: &taskId} 14 | body, _ := json.Marshal(model) 15 | httpResponse := http.Response{StatusCode: 200} 16 | response := vcf.GetTaskResponse{ 17 | Body: body, 18 | HTTPResponse: &httpResponse, 19 | } 20 | 21 | result, err := GetResponseAs[vcf.Task](response) 22 | 23 | if err != nil { 24 | t.Fatal("received an unexpected error", err) 25 | } 26 | 27 | if result == nil { 28 | t.Fatal("response is nil") 29 | } 30 | 31 | if *result.Id != taskId { 32 | t.Fatal("response does not contain correct payload") 33 | } 34 | } 35 | 36 | func TestGetResponseAs_neg(t *testing.T) { 37 | message := "message" 38 | model := vcf.Error{Message: &message} 39 | body, _ := json.Marshal(model) 40 | httpResponse := http.Response{StatusCode: 400} 41 | response := vcf.GetTaskResponse{ 42 | Body: body, 43 | HTTPResponse: &httpResponse, 44 | } 45 | 46 | result, err := GetResponseAs[vcf.Task](response) 47 | 48 | if result != nil { 49 | t.Fatal("received an unexpected response", result) 50 | } 51 | 52 | if err == nil { 53 | t.Fatal("error is nil") 54 | } 55 | 56 | if *err.Message != message { 57 | t.Fatal("response does not contain correct payload") 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /internal/sddc/sddc_credentials_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package sddc 6 | 7 | import ( 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | utils "github.com/vmware/terraform-provider-vcf/internal/resource_utils" 10 | "github.com/vmware/terraform-provider-vcf/internal/validation" 11 | "github.com/vmware/vcf-sdk-go/installer" 12 | ) 13 | 14 | func getCredentialsSchema() *schema.Schema { 15 | return &schema.Schema{ 16 | Type: schema.TypeList, 17 | Optional: true, 18 | MaxItems: 1, 19 | Elem: &schema.Resource{ 20 | Schema: map[string]*schema.Schema{ 21 | "password": { 22 | Type: schema.TypeString, 23 | Required: true, 24 | ValidateFunc: validation.ValidatePassword, 25 | }, 26 | "username": { 27 | Type: schema.TypeString, 28 | Required: true, 29 | }, 30 | }, 31 | }, 32 | } 33 | } 34 | 35 | func getCredentialsFromSchema(rawData []interface{}) *installer.SddcCredentials { 36 | if len(rawData) <= 0 { 37 | return nil 38 | } 39 | data := rawData[0].(map[string]interface{}) 40 | password := data["password"].(string) 41 | username := utils.ToStringPointer(data["username"]) 42 | 43 | credentialsBinding := &installer.SddcCredentials{ 44 | Password: password, 45 | Username: username, 46 | } 47 | return credentialsBinding 48 | } 49 | -------------------------------------------------------------------------------- /.github/workflows/lock.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Lock 3 | 4 | on: 5 | schedule: 6 | - cron: 30 00 * * * 7 | 8 | permissions: 9 | contents: read 10 | 11 | jobs: 12 | lock: 13 | runs-on: ubuntu-latest 14 | permissions: 15 | issues: write 16 | pull-requests: write 17 | discussions: write 18 | steps: 19 | - uses: dessant/lock-threads@1bf7ec25051fe7c00bdd17e6a7cf3d7bfb7dc771 # v5.0.1 20 | with: 21 | github-token: '${{ secrets.GITHUB_TOKEN }}' 22 | issue-comment: > 23 | I'm going to lock this issue because it has been closed for 30 24 | days. This helps our maintainers find and focus on the active 25 | issues. 26 | 27 | 28 | If you have found a problem that seems similar to this, 29 | please open a new issue and complete the issue template so we can 30 | capture all the details necessary to investigate further. 31 | issue-inactive-days: '30' 32 | pr-comment: > 33 | I'm going to lock this pull request because it has been closed for 34 | 30 days. This helps our maintainers find and focus on the active 35 | issues. 36 | 37 | 38 | If you have found a problem that seems related to this 39 | change, please open a new issue and complete the issue template so 40 | we can capture all the details necessary to investigate further. 41 | pr-inactive-days: '30' 42 | -------------------------------------------------------------------------------- /internal/provider/data_host_test.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package provider 6 | 7 | import ( 8 | "fmt" 9 | "os" 10 | "testing" 11 | 12 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 13 | 14 | "github.com/vmware/terraform-provider-vcf/internal/constants" 15 | ) 16 | 17 | func TestAccDataSourceVcfHost(t *testing.T) { 18 | hosts := []string{ 19 | os.Getenv(constants.VcfTestHost1Fqdn), 20 | os.Getenv(constants.VcfTestHost2Fqdn), 21 | os.Getenv(constants.VcfTestHost3Fqdn), 22 | os.Getenv(constants.VcfTestHost4Fqdn), 23 | } 24 | 25 | var steps []resource.TestStep 26 | for _, fqdn := range hosts { 27 | steps = append(steps, resource.TestStep{ 28 | Config: testAccDataSourceVcfHostConfig(fqdn), 29 | Check: resource.ComposeTestCheckFunc( 30 | resource.TestCheckResourceAttrSet("data.vcf_host.test_host", "id"), 31 | resource.TestCheckResourceAttr("data.vcf_host.test_host", "fqdn", fqdn), 32 | ), 33 | }) 34 | } 35 | 36 | resource.ParallelTest(t, resource.TestCase{ 37 | PreCheck: func() { testAccPreCheck(t) }, 38 | ProtoV6ProviderFactories: muxedFactories(), 39 | Steps: steps, 40 | }) 41 | } 42 | 43 | func testAccDataSourceVcfHostConfig(hostFqdn string) string { 44 | return fmt.Sprintf(` 45 | data "vcf_host" "test_host" { 46 | fqdn = %q 47 | } 48 | `, hostFqdn) 49 | } 50 | -------------------------------------------------------------------------------- /docs/resources/ceip.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "vcf_ceip Resource - terraform-provider-vcf" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # vcf_ceip (Resource) 10 | 11 | 12 | VCF participates in VMware’s Customer Experience Improvement Program (“CEIP”). 13 | The CEIP provides VMware with information that enables VMware to improve its products and services, to fix problems, 14 | and to advise you on how best to deploy and use our products. As part of the CEIP, VMware collects technical 15 | information about your organization’s use of VMware products and services on a regular basis in association 16 | with your organization’s VMware license key(s). This information does not personally identify any individual. 17 | For additional information regarding the CEIP, please visit the [Trust & Assurance Center](https://www.vmware.com/solutions/trustvmware/ceip.html) 18 | You can select your participation preferences below. 19 | 20 | 21 | 22 | ## Schema 23 | 24 | ### Required 25 | 26 | - `status` (String) User provided CEIP operation. One among: ENABLED, DISABLED 27 | 28 | ### Optional 29 | 30 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 31 | 32 | ### Read-Only 33 | 34 | - `id` (String) The ID of this resource. 35 | 36 | 37 | ### Nested Schema for `timeouts` 38 | 39 | Optional: 40 | 41 | - `create` (String) 42 | - `update` (String) 43 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | In order to have a good experience with our community, we recommend that you read the [contributing guidelines](https://github.com/vmware/terraform-provider-vcf/blob/main/CONTRIBUTING.md) for making a pull request. 2 | 3 | **Summary of Pull Request** 4 | 5 | 8 | 9 | **Type of Pull Request** 10 | 11 | 14 | 15 | - [ ] This is a bug fix. 16 | - [ ] This is an enhancement or feature. 17 | - [ ] This is a code style/formatting update. 18 | - [ ] This is a documentation update. 19 | - [ ] This is a refactoring update. 20 | - [ ] This is a chore update 21 | - [ ] This is something else. 22 | Please describe: 23 | 24 | **Related to Existing Issues** 25 | 26 | 29 | 30 | Issue Number: N/A 31 | 32 | **Test and Documentation Coverage** 33 | 34 | 37 | 38 | For bug fixes or features: 39 | 40 | - [ ] Tests have been completed. 41 | - [ ] Documentation has been added/updated. 42 | 43 | **Breaking Changes?** 44 | 45 | 48 | 49 | - [ ] Yes, there are breaking changes. 50 | - [ ] No, there are no breaking changes. 51 | 52 | 55 | -------------------------------------------------------------------------------- /examples/workflows/private-ai-foundation/steps/05/variables.tf: -------------------------------------------------------------------------------- 1 | variable "vcenter_username" { 2 | description = "Username used to authenticate against the vCenter Server" 3 | } 4 | 5 | variable "vcenter_password" { 6 | description = "Password used to authenticate against the vCenter Server" 7 | } 8 | 9 | variable "vcenter_server" { 10 | description = "FQDN or IP Address of the vCenter Server for the workload domain" 11 | } 12 | 13 | variable "datacenter_name" { 14 | description = "The name of the datacenter" 15 | } 16 | 17 | variable "cluster_name" { 18 | description = "The name of the compute cluster" 19 | } 20 | 21 | variable "storage_policy_name" { 22 | description = "The name of the storage policy" 23 | } 24 | 25 | variable "management_network_name" { 26 | description = "The name of the management network. This should be a distributed portgroup on the DVS which the edge nodes are are connected to" 27 | } 28 | 29 | variable "contenty_library_name" { 30 | description = "The name of the subscribed content library" 31 | } 32 | 33 | variable "dvs_name" { 34 | description = "The name of the distributed switch" 35 | } 36 | 37 | variable "edge_cluster" { 38 | description = "The identifier of the edge cluster" 39 | } 40 | 41 | variable "host1_fqdn" { 42 | description = "The fully qualified domain name of one of the hosts in the cluster" 43 | } 44 | 45 | variable "namespace_name" { 46 | description = "The name for the new vSphere Namespace" 47 | } 48 | 49 | variable "virtual_machine_class_name" { 50 | description = "The name of the new Virtual Machine Class" 51 | } -------------------------------------------------------------------------------- /docs/build.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | VMware Cloud Foundation 9 | 10 | # Building the Terraform Provider for VMware Cloud Foundation 11 | 12 | The instructions outlined below are specific to macOS and Linux only. 13 | 14 | If you wish to work on the provider, you'll first need [Go][golang-install] installed on your 15 | machine. Check the [requirements][requirements] before proceeding. 16 | 17 | 1. Clone the repository to: `$GOPATH/src/github.com/vmware/terraform-provider-vcf` 18 | 19 | ```sh 20 | mkdir -p $GOPATH/src/github.com/vmware 21 | cd $GOPATH/src/github.com/vmware 22 | git clone git@github.com:vmware/terraform-provider-vcf.git 23 | ``` 24 | 25 | 2. Enter the provider directory to build the provider. 26 | 27 | ```sh 28 | cd $GOPATH/src/github.com/vmware/terraform-provider-vcf 29 | go get 30 | go build -o terraform-provider-vcf 31 | ``` 32 | 33 | 3. Add the following to your `~/.terraformrc`: 34 | 35 | ```hcl 36 | provider_installation { 37 | dev_overrides { 38 | "vmware/vcf" = "/Users/rainpole/go/bin" 39 | } 40 | 41 | direct {} 42 | } 43 | ``` 44 | 45 | Where `/Users/rainpole/go/bin` is your `GOPATH/bin` path. 46 | 47 | 4. Run `go install` to install the development binary. 48 | 49 | [golang-install]: https://golang.org/doc/install 50 | [requirements]: https://github.com/vmware/terraform-provider-vcf#requirements 51 | -------------------------------------------------------------------------------- /internal/nsx_edge_cluster/cluster_profile_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package nsx_edge_cluster 6 | 7 | import ( 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 10 | ) 11 | 12 | func ClusterProfileSchema() *schema.Resource { 13 | return &schema.Resource{ 14 | Schema: map[string]*schema.Schema{ 15 | "name": { 16 | Type: schema.TypeString, 17 | Required: true, 18 | Description: "The name of the profile", 19 | ValidateFunc: validation.NoZeroValues, 20 | }, 21 | "bfd_allowed_hop": { 22 | Type: schema.TypeInt, 23 | Required: true, 24 | Description: "BFD allowed hop", 25 | ValidateFunc: validation.IntBetween(1, 255), 26 | }, 27 | "bfd_declare_dead_multiple": { 28 | Type: schema.TypeInt, 29 | Required: true, 30 | Description: "BFD declare dead multiple", 31 | ValidateFunc: validation.IntBetween(2, 16), 32 | }, 33 | "bfd_probe_interval": { 34 | Type: schema.TypeInt, 35 | Required: true, 36 | Description: "BFD probe interval", 37 | ValidateFunc: validation.IntBetween(500, 60000), 38 | }, 39 | "standby_relocation_threshold": { 40 | Type: schema.TypeInt, 41 | Required: true, 42 | Description: "Standby relocation threshold", 43 | ValidateFunc: validation.IntBetween(10, 1000), 44 | }, 45 | }, 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /internal/datastores/vmfs_datastore_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package datastores 6 | 7 | import ( 8 | "fmt" 9 | 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | "github.com/vmware/vcf-sdk-go/vcf" 12 | ) 13 | 14 | // VmfsDatastoreSchema this helper function extracts the VMFS Datastore schema, so that 15 | // it's made available for both Domain and Cluster creation. 16 | func VmfsDatastoreSchema() *schema.Resource { 17 | return &schema.Resource{ 18 | Schema: map[string]*schema.Schema{ 19 | "datastore_names": { 20 | Type: schema.TypeList, 21 | Required: true, 22 | Description: "VMFS datastore names used for VMFS on FC for cluster creation", 23 | Elem: &schema.Schema{Type: schema.TypeString}, 24 | }, 25 | }, 26 | } 27 | } 28 | 29 | func TryConvertToVmfsDatastoreSpec(object map[string]interface{}) (*vcf.VmfsDatastoreSpec, error) { 30 | if object == nil { 31 | return nil, fmt.Errorf("cannot convert to VmfsDatastoreSpec, object is nil") 32 | } 33 | datastoreNames := object["datastore_names"].([]string) 34 | if len(datastoreNames) == 0 { 35 | return nil, fmt.Errorf("cannot convert to VmfsDatastoreSpec, datastore_names is required") 36 | } 37 | result := &vcf.VmfsDatastoreSpec{} 38 | var specs []vcf.FcSpec 39 | for _, datastoreName := range datastoreNames { 40 | specs = append(specs, vcf.FcSpec{DatastoreName: datastoreName}) 41 | } 42 | result.FcSpec = &specs 43 | return result, nil 44 | } 45 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | 4 | project_name: terraform-provider-vcf 5 | 6 | before: 7 | hooks: 8 | - go mod tidy 9 | 10 | builds: 11 | - id: default 12 | binary: '{{ .ProjectName }}_v{{ .Version }}' 13 | goos: 14 | - linux 15 | - windows 16 | - darwin 17 | - freebsd 18 | goarch: 19 | - amd64 20 | - '386' 21 | - arm 22 | - arm64 23 | ignore: 24 | - goos: darwin 25 | goarch: '386' 26 | env: 27 | - CGO_ENABLED=0 28 | flags: 29 | - -trimpath 30 | ldflags: 31 | - -s -w -X 'github.com/vmware/terraform-provider-vcf/internal/version.ProviderVersion={{ .Version }}' 32 | mod_timestamp: '{{ .CommitTimestamp }}' 33 | 34 | archives: 35 | - id: default 36 | name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' 37 | formats: ['zip'] 38 | 39 | checksum: 40 | name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' 41 | algorithm: sha256 42 | extra_files: 43 | - glob: 'terraform-registry-manifest.json' 44 | name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' 45 | 46 | signs: 47 | - id: default 48 | artifacts: checksum 49 | args: 50 | - "--batch" 51 | - "--local-user" 52 | - "{{ .Env.GPG_FINGERPRINT }}" 53 | - "--output" 54 | - "${signature}" 55 | - "--detach-sign" 56 | - "${artifact}" 57 | 58 | release: 59 | extra_files: 60 | - glob: 'terraform-registry-manifest.json' 61 | name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' 62 | 63 | changelog: 64 | disable: true 65 | -------------------------------------------------------------------------------- /internal/provider/data_source_credentials_test.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package provider 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 11 | ) 12 | 13 | func TestAccDataSourceCredentialsAll(t *testing.T) { 14 | resource.Test(t, resource.TestCase{ 15 | PreCheck: func() { testAccSDDCManagerOrCloudBuilderPreCheck(t) }, 16 | ProtoV6ProviderFactories: muxedFactories(), 17 | Steps: []resource.TestStep{{ 18 | Config: testAccDataSourceCredentialsAll(), 19 | Check: resource.TestCheckResourceAttrSet("data.vcf_credentials.creds", "credentials.#"), 20 | }}, 21 | }) 22 | } 23 | 24 | func TestAccDataSourceCredentials_VC(t *testing.T) { 25 | resource.Test(t, resource.TestCase{ 26 | PreCheck: func() { testAccSDDCManagerOrCloudBuilderPreCheck(t) }, 27 | ProtoV6ProviderFactories: muxedFactories(), 28 | Steps: []resource.TestStep{{ 29 | Config: testAccDataSourceCredentialsVc(), 30 | Check: resource.ComposeTestCheckFunc( 31 | resource.TestCheckResourceAttr("data.vcf_credentials.creds", "credentials.0.credential_type", "SSH"), 32 | resource.TestCheckResourceAttr("data.vcf_credentials.creds", "credentials.1.credential_type", "SSO"), 33 | ), 34 | }}, 35 | }) 36 | } 37 | 38 | func testAccDataSourceCredentialsAll() string { 39 | return ` 40 | data "vcf_credentials" "creds" { 41 | 42 | } 43 | ` 44 | } 45 | 46 | func testAccDataSourceCredentialsVc() string { 47 | return ` 48 | data "vcf_credentials" "creds" { 49 | resource_type = "VCENTER" 50 | } 51 | ` 52 | } 53 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package main 6 | 7 | import ( 8 | "context" 9 | "flag" 10 | "log" 11 | 12 | "github.com/hashicorp/terraform-plugin-framework/providerserver" 13 | "github.com/hashicorp/terraform-plugin-go/tfprotov6" 14 | "github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server" 15 | "github.com/hashicorp/terraform-plugin-mux/tf5to6server" 16 | "github.com/hashicorp/terraform-plugin-mux/tf6muxserver" 17 | 18 | "github.com/vmware/terraform-provider-vcf/internal/provider" 19 | ) 20 | 21 | func main() { 22 | ctx := context.Background() 23 | 24 | var debugMode bool 25 | flag.BoolVar(&debugMode, "debug", false, "set to true to run the provider with support for debuggers like delve") 26 | flag.Parse() 27 | 28 | upgradedSdkServer, err := tf5to6server.UpgradeServer( 29 | ctx, 30 | provider.Provider().GRPCProvider, 31 | ) 32 | 33 | if err != nil { 34 | log.Fatal(err) 35 | } 36 | 37 | providers := []func() tfprotov6.ProviderServer{ 38 | providerserver.NewProtocol6(provider.New()), 39 | func() tfprotov6.ProviderServer { 40 | return upgradedSdkServer 41 | }, 42 | } 43 | 44 | muxServer, err := tf6muxserver.NewMuxServer(ctx, providers...) 45 | 46 | if err != nil { 47 | log.Fatal(err) 48 | } 49 | 50 | var serveOpts []tf6server.ServeOpt 51 | 52 | if debugMode { 53 | serveOpts = append(serveOpts, tf6server.WithManagedDebug()) 54 | } 55 | 56 | err = tf6server.Serve( 57 | "registry.terraform.io/vmware/vcf", 58 | muxServer.ProviderServer, 59 | serveOpts..., 60 | ) 61 | 62 | if err != nil { 63 | log.Fatal(err) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /internal/provider/resource_credentials_password_update_test.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package provider 6 | 7 | import ( 8 | "fmt" 9 | "os" 10 | "testing" 11 | 12 | "github.com/hashicorp/terraform-plugin-testing/helper/acctest" 13 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 14 | "github.com/vmware/terraform-provider-vcf/internal/constants" 15 | ) 16 | 17 | func TestAccCredentialsResourcePasswordUpdate(t *testing.T) { 18 | newPassword := fmt.Sprintf("%s$1A", acctest.RandString(7)) 19 | 20 | resource.Test(t, resource.TestCase{ 21 | PreCheck: func() { testAccSDDCManagerOrCloudBuilderPreCheck(t) }, 22 | ProtoV6ProviderFactories: muxedFactories(), 23 | Steps: []resource.TestStep{{ 24 | Config: testAccResourceCredentialsPasswordUpdateConfig(newPassword), 25 | Check: resource.TestCheckResourceAttr("data.vcf_credentials.esx_creds", "credentials.0.password", newPassword), 26 | }}, 27 | }) 28 | } 29 | 30 | func testAccResourceCredentialsPasswordUpdateConfig(newPassword string) string { 31 | 32 | return fmt.Sprintf(` 33 | resource "vcf_credentials_update" "vc_0_update" { 34 | resource_name = %[1]q 35 | resource_type = "ESXI" 36 | credentials { 37 | credential_type = "SSH" 38 | user_name = "root" 39 | password = %[2]q 40 | } 41 | } 42 | 43 | data "vcf_credentials" "esx_creds" { 44 | resource_type = "ESXI" 45 | account_type = "USER" 46 | resource_name = %[1]q 47 | 48 | depends_on = [ 49 | vcf_credentials_update.vc_0_update 50 | ] 51 | } 52 | 53 | `, os.Getenv(constants.VcfTestHost1Fqdn), newPassword) 54 | } 55 | -------------------------------------------------------------------------------- /internal/datastores/vsan_remote_datastore_cluster_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package datastores 6 | 7 | import ( 8 | "fmt" 9 | 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | "github.com/vmware/vcf-sdk-go/vcf" 12 | ) 13 | 14 | // VsanRemoteDatastoreClusterSchema this helper function extracts the VSAN Datastore Cluster 15 | // schema, so that it's made available for both Domain and Cluster creation. 16 | func VsanRemoteDatastoreClusterSchema() *schema.Resource { 17 | return &schema.Resource{ 18 | Schema: map[string]*schema.Schema{ 19 | "datastore_uuids": { 20 | Type: schema.TypeList, 21 | Required: true, 22 | Description: "vSAN HCI Mesh remote datastore UUIDs", 23 | Elem: &schema.Schema{Type: schema.TypeString}, 24 | }, 25 | }, 26 | } 27 | } 28 | 29 | func TryConvertToVSANRemoteDatastoreClusterSpec(object map[string]interface{}) (*vcf.VsanRemoteDatastoreClusterSpec, error) { 30 | if object == nil { 31 | return nil, fmt.Errorf("cannot convert to VSANRemoteDatastoreClusterSpec, object is nil") 32 | } 33 | datastoreUuids := object["datastore_uuids"].([]string) 34 | if len(datastoreUuids) == 0 { 35 | return nil, fmt.Errorf("cannot convert to VSANRemoteDatastoreClusterSpec, datastore_uuids is required") 36 | } 37 | result := &vcf.VsanRemoteDatastoreClusterSpec{} 38 | var specs []vcf.VsanRemoteDatastoreSpec 39 | for _, datastoreUuid := range datastoreUuids { 40 | specs = append(specs, vcf.VsanRemoteDatastoreSpec{DatastoreUuid: datastoreUuid}) 41 | } 42 | result.VsanRemoteDatastoreSpec = &specs 43 | return result, nil 44 | } 45 | -------------------------------------------------------------------------------- /internal/provider/resource_ceip_test.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package provider 6 | 7 | import ( 8 | "context" 9 | "fmt" 10 | "log" 11 | "testing" 12 | 13 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 14 | "github.com/hashicorp/terraform-plugin-testing/terraform" 15 | 16 | "github.com/vmware/terraform-provider-vcf/internal/api_client" 17 | ) 18 | 19 | func TestAccResourceVcfCeip(t *testing.T) { 20 | resource.Test(t, resource.TestCase{ 21 | PreCheck: func() { testAccPreCheck(t) }, 22 | ProtoV6ProviderFactories: muxedFactories(), 23 | CheckDestroy: testCheckVcfCeipDestroy, 24 | Steps: []resource.TestStep{ 25 | { 26 | Config: testAccVcfCeip(), 27 | Check: testCheckVcfCeipCreate, 28 | }, 29 | }, 30 | }) 31 | } 32 | 33 | func testAccVcfCeip() string { 34 | return ` 35 | resource "vcf_ceip" "ceip" { 36 | status = "ENABLED" 37 | }` 38 | } 39 | 40 | func testVerifyVcfCeip(enabledState string) error { 41 | apiClient := testAccProvider.Meta().(*api_client.SddcManagerClient).ApiClient 42 | 43 | ceipResult, err := apiClient.GetCeipStatusWithResponse(context.TODO()) 44 | if err != nil { 45 | log.Println("error = ", err) 46 | return err 47 | } 48 | if ceipResult.JSON200.Status == enabledState { 49 | return nil 50 | } else { 51 | return fmt.Errorf("CEIP not in status %q", enabledState) 52 | } 53 | 54 | } 55 | 56 | func testCheckVcfCeipCreate(_ *terraform.State) error { 57 | return testVerifyVcfCeip(EnabledState) 58 | } 59 | 60 | func testCheckVcfCeipDestroy(_ *terraform.State) error { 61 | return testVerifyVcfCeip(DisabledState) 62 | } 63 | -------------------------------------------------------------------------------- /internal/provider/resource_cluster_personality_test.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package provider 6 | 7 | import ( 8 | "fmt" 9 | "os" 10 | "testing" 11 | 12 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 13 | 14 | "github.com/vmware/terraform-provider-vcf/internal/constants" 15 | ) 16 | 17 | func TestAccClusterPersonality_basic(t *testing.T) { 18 | resource.Test(t, resource.TestCase{ 19 | PreCheck: func() { testAccPersonalityPreCheck(t) }, 20 | ProtoV6ProviderFactories: muxedFactories(), 21 | Steps: []resource.TestStep{ 22 | { 23 | Config: getClusterPersonalityConfig(), 24 | Check: resource.ComposeTestCheckFunc( 25 | resource.TestCheckResourceAttrSet("vcf_cluster_personality.personality", "id"), 26 | ), 27 | }, 28 | }, 29 | }) 30 | } 31 | 32 | func getClusterPersonalityConfig() string { 33 | return fmt.Sprintf(` 34 | resource "vcf_cluster_personality" "personality" { 35 | name = "personality1" 36 | cluster_id = %q 37 | domain_id = %q 38 | } 39 | `, 40 | os.Getenv(constants.VcfTestClusterId), 41 | os.Getenv(constants.VcfTestDomainDataSourceId)) 42 | } 43 | 44 | // testAccPreCheck validates all required environment variables for running these acceptance 45 | // tests are set. 46 | func testAccPersonalityPreCheck(t *testing.T) { 47 | if v := os.Getenv(constants.VcfTestClusterId); v == "" { 48 | t.Fatalf("%s must be set for acceptance tests", constants.VcfTestClusterId) 49 | } 50 | if v := os.Getenv(constants.VcfTestDomainDataSourceId); v == "" { 51 | t.Fatalf("%s must be set for acceptance tests", constants.VcfTestDomainDataSourceId) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /examples/resources/cluster/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_username" { 2 | description = "Username used to authenticate against an SDDC Manager instance" 3 | default = "" 4 | } 5 | 6 | variable "sddc_manager_password" { 7 | description = "Password used to authenticate against an SDDC Manager instance" 8 | default = "" 9 | } 10 | 11 | variable "sddc_manager_host" { 12 | description = "Fully qualified domain name of an SDDC Manager instance" 13 | default = "" 14 | } 15 | 16 | variable "esx_host1_fqdn" { 17 | description = "Fully qualified domain name of ESXi host 1" 18 | default = "" 19 | } 20 | 21 | variable "esx_host1_pass" { 22 | description = "Password to authenticate to the ESXi host 1" 23 | default = "" 24 | } 25 | 26 | variable "esx_host2_fqdn" { 27 | description = "Fully qualified domain name of ESXi host 2" 28 | default = "" 29 | } 30 | 31 | variable "esx_host2_pass" { 32 | description = "Password to authenticate to the ESXi host 2" 33 | default = "" 34 | } 35 | 36 | variable "esx_host3_fqdn" { 37 | description = "Fully qualified domain name of ESXi host 3" 38 | default = "" 39 | } 40 | 41 | variable "esx_host3_pass" { 42 | description = "Password to authenticate to the ESXi host 3" 43 | default = "" 44 | } 45 | 46 | variable "domain_id" { 47 | description = "Id of the domain in which the Cluster is to be created" 48 | default = "" 49 | } 50 | 51 | variable "esx_license_key" { 52 | description = "License key for an ESXi host in the free pool. This is required except in cases where the ESXi host has already been licensed outside of the VMware Cloud Foundation system" 53 | default = "" 54 | } 55 | 56 | variable "vsan_license_key" { 57 | description = "vSAN license key to be used" 58 | default = "" 59 | } 60 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Stale 3 | 4 | on: 5 | schedule: 6 | - cron: 00 00 * * * 7 | 8 | permissions: 9 | contents: read 10 | 11 | jobs: 12 | stale: 13 | runs-on: ubuntu-latest 14 | permissions: 15 | issues: write 16 | pull-requests: write 17 | steps: 18 | - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9.1.0 19 | with: 20 | repo-token: ${{ secrets.GITHUB_TOKEN }} 21 | days-before-stale: 60 22 | days-before-close: 30 23 | exempt-issue-labels: needs-triage 24 | exempt-pr-labels: needs-review 25 | remove-stale-when-updated: true 26 | delete-branch: false 27 | stale-issue-label: stale 28 | stale-issue-message: > 29 | 'Marking this issue as stale due to inactivity. This helps us focus 30 | on the active issues. If this issue receives no comments in the next 31 | 30 days it will automatically be closed. 32 | 33 | 34 | If this issue was automatically closed and you feel this issue 35 | should be reopened, we encourage creating a new issue linking back 36 | to this one for added context. 37 | 38 | Thank you!' 39 | stale-pr-label: stale 40 | stale-pr-message: > 41 | 'Marking this pull request as stale due to inactivity. This helps us 42 | focus on the active pull requests. If this pull request receives no 43 | comments in the next 30 days it will automatically be closed. 44 | 45 | If this pull request was automatically closed and you feel this pull 46 | request should be reopened, we encourage creating a new pull request 47 | linking back to this one for added context. 48 | 49 | Thank you!' 50 | -------------------------------------------------------------------------------- /docs/images/icon-color.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/data-sources/certificate.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "vcf_certificate Data Source - terraform-provider-vcf" 4 | subcategory: "" 5 | description: |- 6 | Datasource used to extract certificate details for various resources based on fields like domain, issued_by, issued_to, key_size, and others. 7 | --- 8 | 9 | # vcf_certificate (Data Source) 10 | 11 | Datasource used to extract certificate details for various resources based on fields like domain, issued_by, issued_to, key_size, and others. 12 | 13 | 14 | 15 | 16 | ## Schema 17 | 18 | ### Required 19 | 20 | - `domain_id` (String) The ID of the domain to fetch certificates for. 21 | - `resource_fqdn` (String) the fqdn of resource certificate. 22 | 23 | ### Read-Only 24 | 25 | - `certificate` (List of Object) List of certificates retrieved from the API. (see [below for nested schema](#nestedatt--certificate)) 26 | - `id` (String) The ID of this resource. 27 | 28 | 29 | ### Nested Schema for `certificate` 30 | 31 | Read-Only: 32 | 33 | - `certificate_error` (String) 34 | - `domain` (String) 35 | - `expiration_status` (String) 36 | - `is_installed` (Boolean) 37 | - `issued_by` (String) 38 | - `issued_to` (String) 39 | - `key_size` (String) 40 | - `not_after` (String) 41 | - `not_before` (String) 42 | - `number_of_days_to_expire` (Number) 43 | - `pem_encoded` (String) 44 | - `public_key` (String) 45 | - `public_key_algorithm` (String) 46 | - `serial_number` (String) 47 | - `signature_algorithm` (String) 48 | - `subject` (String) 49 | - `subject_alternative_name` (List of String) 50 | - `subject_cn` (String) 51 | - `subject_country` (String) 52 | - `subject_locality` (String) 53 | - `subject_org` (String) 54 | - `subject_ou` (String) 55 | - `subject_st` (String) 56 | - `thumbprint` (String) 57 | - `thumbprint_algorithm` (String) 58 | - `version` (String) 59 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | schedule: 6 | interval: weekly 7 | labels: 8 | - chore 9 | - github-actions 10 | commit-message: 11 | prefix: "chore(gh):" 12 | include: 13 | - dependency-name 14 | - new-version 15 | separator: " " 16 | - package-ecosystem: gomod 17 | directory: / 18 | groups: 19 | terraform: 20 | patterns: 21 | - github.com/hashicorp/terraform-plugin-* 22 | golang-x: 23 | patterns: 24 | - golang.org/x/* 25 | google-golang: 26 | patterns: 27 | - google.golang.org/* 28 | ignore: 29 | # go-cty should only be updated via terraform-plugin-sdk 30 | - dependency-name: github.com/hashicorp/go-cty 31 | # hcl/v2 should only be updated via terraform-plugin-sdk 32 | - dependency-name: github.com/hashicorp/hcl/v2 33 | # terraform-plugin-go should only be updated via terraform-plugin-framework 34 | - dependency-name: github.com/hashicorp/terraform-plugin-go 35 | # terraform-plugin-log should only be updated via terraform-plugin-framework 36 | - dependency-name: github.com/hashicorp/terraform-plugin-log 37 | # go-hclog should only be updated via terraform-plugin-log 38 | - dependency-name: github.com/hashicorp/go-hclog 39 | # grpc should only be updated via terraform-plugin-go/terraform-plugin-framework 40 | - dependency-name: google.golang.org/grpc 41 | # protobuf should only be updated via terraform-plugin-go/terraform-plugin-framework 42 | - dependency-name: google.golang.org/protobuf 43 | schedule: 44 | interval: weekly 45 | open-pull-requests-limit: 30 46 | labels: 47 | - chore 48 | - dependencies 49 | commit-message: 50 | prefix: "chore(deps):" 51 | include: 52 | - dependency-name 53 | - new-version 54 | separator: " " 55 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/docs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Documentation 3 | description: Found a typo or something that needs clarification? 4 | labels: 5 | - [documentation, needs-review] 6 | body: 7 | - type: markdown 8 | attributes: 9 | value: > 10 | When filing a documentation issue, please include the following information. 11 | - type: checkboxes 12 | id: terms 13 | attributes: 14 | label: Code of Conduct 15 | description: >- 16 | This project has a [Code of Conduct](https://github.com/vmware/terraform-provider-vcf/blob/main/CODE_OF_CONDUCT.md) 17 | that all participants are expected to understand and follow. 18 | options: 19 | - label: I have read and agree to the project's Code of Conduct. 20 | required: true 21 | - type: input 22 | id: version-provider 23 | attributes: 24 | label: Provider Version 25 | description: Please provide the provider version. 26 | validations: 27 | required: true 28 | - type: textarea 29 | id: motivation 30 | attributes: 31 | label: Motivation 32 | description: Why should we update our docs or examples? 33 | validations: 34 | required: false 35 | - type: textarea 36 | id: suggestion 37 | attributes: 38 | label: Suggestion 39 | description: What should we do instead? 40 | validations: 41 | required: false 42 | - type: markdown 43 | attributes: 44 | value: "### Community Note\n* Please vote on this issue by adding a \U0001F44D [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request\n* Please do not leave \"+1\" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request\n* If you are interested in working on this issue or have submitted a pull request, please leave a comment\n" 45 | -------------------------------------------------------------------------------- /internal/credentials/constants.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package credentials 6 | 7 | const ( 8 | AccountTypeSystem = "SYSTEM" 9 | AccountTypeService = "SERVICE" 10 | AccountTypeUser = "USER" 11 | ) 12 | 13 | const ( 14 | ResourceTypeEsxi = "ESXI" 15 | ResourceTypeVcenter = "VCENTER" 16 | ResourceTypePsc = "PSC" 17 | ResourceTypeNsxManager = "NSX_MANAGER" 18 | ResourceTypeNsxController = "NSX_CONTROLLER" 19 | ResourceTypeNsxEdge = "NSXT_EDGE" 20 | ResourceTypeNsxtManager = "NSXT_MANAGER" 21 | ResourceTypeVrli = "VRLI" 22 | ResourceTypeVra = "VRA" 23 | ResourceTypeWsa = "WSA" 24 | ResourceTypeVrslcm = "VRSLCM" 25 | ResourceTypeVxrailManager = "VXRAIL_MANAGER" 26 | ResourceTypeNsxAlb = "NSX_ALB" 27 | ResourceTypeBackup = "BACKUP" 28 | ResourceTypeVrops = "VROPS" 29 | ) 30 | 31 | const ( 32 | ConfigAutoRotate = "UPDATE_AUTO_ROTATE_POLICY" 33 | Rotate = "ROTATE" 34 | Update = "UPDATE" 35 | ) 36 | 37 | const ( 38 | AutorotateDays30 = 30 39 | 40 | AutorotateDays90 = 90 41 | AutorotateDaysMax = AutorotateDays90 42 | AutoRotateDaysMin = 1 43 | ) 44 | 45 | func AllAccountTypes() []string { 46 | return []string{AccountTypeUser, AccountTypeService, AccountTypeSystem} 47 | } 48 | 49 | func AllCredentialTypes() []string { 50 | return []string{"SSO", "SSH", "API", "FTP", "AUDIT"} 51 | } 52 | 53 | func AllResourceTypes() []string { 54 | return []string{ 55 | ResourceTypeBackup, 56 | ResourceTypeEsxi, 57 | ResourceTypeNsxAlb, 58 | ResourceTypeNsxEdge, 59 | ResourceTypeNsxController, 60 | ResourceTypeNsxManager, 61 | ResourceTypeNsxtManager, 62 | ResourceTypeVcenter, 63 | ResourceTypePsc, 64 | ResourceTypeVrli, 65 | ResourceTypeVra, 66 | ResourceTypeWsa, 67 | ResourceTypeVrslcm, 68 | ResourceTypeVxrailManager, 69 | ResourceTypeVrops, 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /internal/sddc/sddc_vcf_operations_fleet_management_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package sddc 6 | 7 | import ( 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | utils "github.com/vmware/terraform-provider-vcf/internal/resource_utils" 10 | "github.com/vmware/vcf-sdk-go/installer" 11 | ) 12 | 13 | func GetVcfOperationsFleetManagementSchema() *schema.Schema { 14 | return &schema.Schema{ 15 | Type: schema.TypeList, 16 | Optional: true, 17 | MaxItems: 1, 18 | Elem: &schema.Resource{ 19 | Schema: map[string]*schema.Schema{ 20 | "hostname": { 21 | Type: schema.TypeString, 22 | Description: "Host name for the node", 23 | Required: true, 24 | }, 25 | "root_user_password": { 26 | Type: schema.TypeString, 27 | Description: "root password", 28 | Optional: true, 29 | Sensitive: true, 30 | }, 31 | "admin_user_password": { 32 | Type: schema.TypeString, 33 | Description: "root password", 34 | Optional: true, 35 | Sensitive: true, 36 | }, 37 | }, 38 | }, 39 | } 40 | } 41 | 42 | func GetVcfOperationsFleetManagementSpecFromSchema(rawData []interface{}) *installer.VcfOperationsFleetManagementSpec { 43 | if len(rawData) <= 0 { 44 | return nil 45 | } 46 | data := rawData[0].(map[string]interface{}) 47 | 48 | var rootPassword *string 49 | if data["root_user_password"].(string) != "" { 50 | rootPassword = utils.ToPointer[string](data["root_user_password"]) 51 | } 52 | 53 | var adminPassword *string 54 | if data["admin_user_password"].(string) != "" { 55 | adminPassword = utils.ToPointer[string](data["admin_user_password"]) 56 | } 57 | 58 | spec := &installer.VcfOperationsFleetManagementSpec{ 59 | AdminUserPassword: adminPassword, 60 | RootUserPassword: rootPassword, 61 | Hostname: data["hostname"].(string), 62 | } 63 | return spec 64 | } 65 | -------------------------------------------------------------------------------- /examples/resources/domain/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_username" { 2 | description = "Username used to authenticate against an SDDC Manager instance" 3 | default = "" 4 | } 5 | 6 | variable "sddc_manager_password" { 7 | description = "Password used to authenticate against an SDDC Manager instance" 8 | default = "" 9 | } 10 | 11 | variable "sddc_manager_host" { 12 | description = "Fully qualified domain name of an SDDC Manager instance" 13 | default = "" 14 | } 15 | 16 | variable "vcenter_root_password" { 17 | description = "root password for the vCenter Server Appliance (8-20 characters)" 18 | default = "" 19 | } 20 | 21 | variable "nsx_manager_admin_password" { 22 | description = "NSX Manager admin user password" 23 | default = "" 24 | } 25 | 26 | variable "esx_host1_fqdn" { 27 | description = "Fully qualified domain name of ESXi host 1" 28 | default = "" 29 | } 30 | 31 | variable "esx_host1_pass" { 32 | description = "Password to authenticate to the ESXi host 1" 33 | default = "" 34 | } 35 | 36 | variable "esx_host2_fqdn" { 37 | description = "Fully qualified domain name of ESXi host 2" 38 | default = "" 39 | } 40 | 41 | variable "esx_host2_pass" { 42 | description = "Password to authenticate to the ESXi host 2" 43 | default = "" 44 | } 45 | 46 | variable "esx_host3_fqdn" { 47 | description = "Fully qualified domain name of ESXi host 3" 48 | default = "" 49 | } 50 | 51 | variable "esx_host3_pass" { 52 | description = "Password to authenticate to the ESXi host 3" 53 | default = "" 54 | } 55 | 56 | variable "nsx_license_key" { 57 | description = "NSX license to be used" 58 | default = "" 59 | } 60 | 61 | variable "esx_license_key" { 62 | description = "License key for an ESXi host in the free pool. This is required except in cases where the ESXi host has already been licensed outside of the VMware Cloud Foundation system" 63 | default = "" 64 | } 65 | 66 | variable "vsan_license_key" { 67 | description = "vSAN license key to be used" 68 | default = "" 69 | } -------------------------------------------------------------------------------- /internal/sddc/sddc_vcf_operations_collector_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package sddc 6 | 7 | import ( 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 10 | utils "github.com/vmware/terraform-provider-vcf/internal/resource_utils" 11 | "github.com/vmware/vcf-sdk-go/installer" 12 | ) 13 | 14 | func GetVcfOperationsCollectorSchema() *schema.Schema { 15 | return &schema.Schema{ 16 | Type: schema.TypeList, 17 | Optional: true, 18 | MaxItems: 1, 19 | Elem: &schema.Resource{ 20 | Schema: map[string]*schema.Schema{ 21 | "hostname": { 22 | Type: schema.TypeString, 23 | Description: "Host name for the node", 24 | Required: true, 25 | }, 26 | "root_user_password": { 27 | Type: schema.TypeString, 28 | Description: "root password", 29 | Optional: true, 30 | Sensitive: true, 31 | }, 32 | "appliance_size": { 33 | Type: schema.TypeString, 34 | Description: "Appliance size", 35 | Optional: true, 36 | ValidateFunc: validation.StringInSlice([]string{"small", "standard"}, true), 37 | }, 38 | }, 39 | }, 40 | } 41 | } 42 | 43 | func GetVcfOperationsCollectorSpecFromSchema(rawData []interface{}) *installer.VcfOperationsCollectorSpec { 44 | if len(rawData) <= 0 { 45 | return nil 46 | } 47 | data := rawData[0].(map[string]interface{}) 48 | 49 | var rootPassword *string 50 | if data["root_user_password"].(string) != "" { 51 | rootPassword = utils.ToPointer[string](data["root_user_password"]) 52 | } 53 | 54 | var applianceSize *string 55 | if data["appliance_size"].(string) != "" { 56 | applianceSize = utils.ToPointer[string](data["appliance_size"]) 57 | } 58 | 59 | spec := &installer.VcfOperationsCollectorSpec{ 60 | ApplianceSize: applianceSize, 61 | RootUserPassword: rootPassword, 62 | Hostname: data["hostname"].(string), 63 | } 64 | return spec 65 | } 66 | -------------------------------------------------------------------------------- /internal/sddc/sddc_vsan_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package sddc 6 | 7 | import ( 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | utils "github.com/vmware/terraform-provider-vcf/internal/resource_utils" 10 | "github.com/vmware/vcf-sdk-go/installer" 11 | ) 12 | 13 | func GetVsanSchema() *schema.Schema { 14 | return &schema.Schema{ 15 | Type: schema.TypeList, 16 | Optional: true, 17 | MaxItems: 1, 18 | Elem: &schema.Resource{ 19 | Schema: map[string]*schema.Schema{ 20 | "datastore_name": { 21 | Type: schema.TypeString, 22 | Description: "Datastore Name", 23 | Required: true, 24 | }, 25 | "vsan_dedup": { 26 | Type: schema.TypeBool, 27 | Description: "VSAN feature Deduplication and Compression flag, one flag for both features", 28 | Optional: true, 29 | }, 30 | "esa_enabled": { 31 | Type: schema.TypeBool, 32 | Optional: true, 33 | Description: "Enable vSAN ESA", 34 | }, 35 | "failures_to_tolerate": { 36 | Type: schema.TypeInt, 37 | Description: "Host failures to tolerate", 38 | Optional: true, 39 | }, 40 | }, 41 | }, 42 | } 43 | } 44 | 45 | func GetVsanSpecFromSchema(rawData []interface{}) *installer.VsanSpec { 46 | if len(rawData) <= 0 { 47 | return nil 48 | } 49 | data := rawData[0].(map[string]interface{}) 50 | datastoreName := data["datastore_name"].(string) 51 | vsanDedup := data["vsan_dedup"].(bool) 52 | esaEnabled := data["esa_enabled"].(bool) 53 | 54 | vsanSpecBinding := &installer.VsanSpec{ 55 | DatastoreName: &datastoreName, 56 | VsanDedup: &vsanDedup, 57 | EsaConfig: &installer.VsanEsaConfig{Enabled: &esaEnabled}, 58 | } 59 | 60 | // Add failures_to_tolerate if provided 61 | if failuresToTolerate, ok := data["failures_to_tolerate"].(int); ok { 62 | vsanSpecBinding.FailuresToTolerate = utils.ToInt32Pointer(failuresToTolerate) 63 | } 64 | 65 | return vsanSpecBinding 66 | } 67 | -------------------------------------------------------------------------------- /internal/provider/resource_credentials_password_rotate_test.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package provider 6 | 7 | import ( 8 | "errors" 9 | "testing" 10 | 11 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 12 | "github.com/hashicorp/terraform-plugin-testing/terraform" 13 | ) 14 | 15 | func TestAccCredentialsResourcePasswordRotate(t *testing.T) { 16 | resource.Test(t, resource.TestCase{ 17 | PreCheck: func() { testAccSDDCManagerOrCloudBuilderPreCheck(t) }, 18 | ProtoV6ProviderFactories: muxedFactories(), 19 | Steps: []resource.TestStep{{ 20 | Config: testAccResourceCredentialsPasswordRotateConfig(), 21 | Check: testAccResourceCredentialsPasswordRotateCheck, 22 | }}, 23 | }) 24 | } 25 | 26 | func testAccResourceCredentialsPasswordRotateConfig() string { 27 | 28 | return ` 29 | data "vcf_credentials" "sddc_creds" { 30 | resource_type = "VCENTER" 31 | account_type = "USER" 32 | } 33 | 34 | resource "vcf_credentials_rotate" "vc_0_rotate" { 35 | resource_name = data.vcf_credentials.sddc_creds.credentials[0].resource[0].name 36 | resource_type = data.vcf_credentials.sddc_creds.credentials[0].resource[0].type 37 | credentials { 38 | credential_type = data.vcf_credentials.sddc_creds.credentials[0].credential_type 39 | user_name = data.vcf_credentials.sddc_creds.credentials[0].user_name 40 | } 41 | } 42 | ` 43 | 44 | } 45 | 46 | func testAccResourceCredentialsPasswordRotateCheck(state *terraform.State) error { 47 | resources := state.RootModule().Resources 48 | dataCredentials := resources["data.vcf_credentials.sddc_creds"] 49 | resourceRotate := resources["vcf_credentials_rotate.vc_0_rotate"] 50 | passFromCredentials := dataCredentials.Primary.Attributes["credentials.0.password"] 51 | passFromRotation := resourceRotate.Primary.Attributes["credentials.0.password"] 52 | 53 | if passFromRotation == passFromCredentials { 54 | return errors.New("rotation is not passed, passwords are the same") 55 | } 56 | 57 | return nil 58 | } 59 | -------------------------------------------------------------------------------- /internal/sddc/dns_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package sddc 6 | 7 | import ( 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 10 | utils "github.com/vmware/terraform-provider-vcf/internal/resource_utils" 11 | "github.com/vmware/vcf-sdk-go/installer" 12 | ) 13 | 14 | func GetDnsSchema() *schema.Schema { 15 | return &schema.Schema{ 16 | Type: schema.TypeList, 17 | Required: true, 18 | MaxItems: 1, 19 | Elem: &schema.Resource{ 20 | Schema: map[string]*schema.Schema{ 21 | "domain": { 22 | Type: schema.TypeString, 23 | Description: "Tenant domain. Parent tenant domain including TLD suffix Example: vmware.com", 24 | Required: true, 25 | }, 26 | "name_server": { 27 | Type: schema.TypeString, 28 | Description: "Primary nameserver IPv4 address. Example: 172.0.0.4", 29 | Optional: true, 30 | ValidateFunc: validation.IsIPAddress, 31 | }, 32 | "secondary_name_server": { 33 | Type: schema.TypeString, 34 | Description: "Secondary nameserver IPv4 address. Example: 172.0.0.5", 35 | Optional: true, 36 | ValidateFunc: validation.IsIPAddress, 37 | }, 38 | }, 39 | }, 40 | } 41 | } 42 | 43 | func GetDnsSpecFromSchema(rawData []interface{}) *installer.DnsSpec { 44 | if len(rawData) <= 0 { 45 | return nil 46 | } 47 | data := rawData[0].(map[string]interface{}) 48 | domain := utils.ToStringPointer(data["domain"]) 49 | nameServer := data["name_server"].(string) 50 | secondaryNameserver := data["secondary_name_server"].(string) 51 | 52 | nameservers := make([]string, 0) 53 | if len(nameServer) > 0 { 54 | nameservers = append(nameservers, nameServer) 55 | } 56 | 57 | if len(secondaryNameserver) > 0 { 58 | nameservers = append(nameservers, secondaryNameserver) 59 | } 60 | 61 | dnsSpecBinding := &installer.DnsSpec{ 62 | Nameservers: &nameservers, 63 | Subdomain: *domain, 64 | } 65 | return dnsSpecBinding 66 | } 67 | -------------------------------------------------------------------------------- /examples/workflows/private-ai-foundation/steps/01/main.tf: -------------------------------------------------------------------------------- 1 | # This step generates a custom host image with vGPU drivers 2 | # on the vCenter for the management domain. 3 | # The source for the offline software depot for this step has to 4 | # contain the drivers. 5 | 6 | terraform { 7 | required_providers { 8 | vsphere = { 9 | source = "hashicorp/vsphere" 10 | } 11 | } 12 | } 13 | 14 | # Connect to the vCenter Server backing the management domain 15 | provider "vsphere" { 16 | user = var.vcenter_username 17 | password = var.vcenter_password 18 | vsphere_server = var.vcenter_server 19 | } 20 | 21 | # Read a datacenter. Can be any datacenter 22 | data "vsphere_datacenter" "dc" { 23 | name = var.datacenter_name 24 | } 25 | 26 | # Retrieve the list of available host images from vLCM 27 | # It is also valid to base your custom image on the build of a particular host 28 | # but this scenario is not automated 29 | data "vsphere_host_base_images" "base_images" {} 30 | 31 | # Create an offline software depot 32 | # The source for the depot should contain the vGPU drivers 33 | resource "vsphere_offline_software_depot" "depot" { 34 | location = var.depot_location 35 | } 36 | 37 | # Create a compute cluster 38 | # It will remain empty and its sole purpose is to be used by vLCM to configure 39 | # a custom image with the GPU drivers 40 | resource "vsphere_compute_cluster" "image_source_cluster" { 41 | name = var.cluster_name 42 | datacenter_id = data.vsphere_datacenter.dc.id 43 | 44 | # The "host_image" block enables vLCM on the cluster and configures a custom image with the provided settings 45 | # It is recommended to add this block after you have configured your depot and retrieved the list of base images 46 | # so that you can select the correct values 47 | # This example uses the first available image and the first available component 48 | host_image { 49 | esx_version = data.vsphere_host_base_images.base_images.version.0 50 | component { 51 | key = vsphere_offline_software_depot.depot.component.0.key 52 | version = vsphere_offline_software_depot.depot.component.0.version.0 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /internal/network/vmnic_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package network 6 | 7 | import ( 8 | "fmt" 9 | 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 12 | utils "github.com/vmware/terraform-provider-vcf/internal/resource_utils" 13 | "github.com/vmware/vcf-sdk-go/vcf" 14 | 15 | validationutils "github.com/vmware/terraform-provider-vcf/internal/validation" 16 | ) 17 | 18 | // VMNicSchema this helper function extracts the VMNic Schema, so that 19 | // it's made available for both workload domain and cluster creation. 20 | func VMNicSchema() *schema.Resource { 21 | return &schema.Resource{ 22 | Schema: map[string]*schema.Schema{ 23 | "id": { 24 | Type: schema.TypeString, 25 | Required: true, 26 | Description: "ESXI host vmnic ID to be associated with a VDS, once added to cluster", 27 | ValidateFunc: validation.NoZeroValues, 28 | }, 29 | "uplink": { 30 | Type: schema.TypeString, 31 | Optional: true, 32 | Description: "Uplink to be associated with vmnic", 33 | ValidateFunc: validation.NoZeroValues, 34 | }, 35 | "vds_name": { 36 | Type: schema.TypeString, 37 | Optional: true, 38 | Description: "Name of the VDS to associate with the ESXi host", 39 | ValidateFunc: validation.NoZeroValues, 40 | }, 41 | }, 42 | } 43 | } 44 | 45 | func TryConvertToVmNic(object map[string]interface{}) (*vcf.VmNic, error) { 46 | if object == nil { 47 | return nil, fmt.Errorf("cannot convert to VMNic, object is nil") 48 | } 49 | id := object["id"].(string) 50 | if len(id) == 0 { 51 | return nil, fmt.Errorf("cannot convert to VMNic, id is required") 52 | } 53 | result := &vcf.VmNic{} 54 | result.Id = id 55 | if uplink, ok := object["uplink"]; ok && !validationutils.IsEmpty(uplink) { 56 | result.Uplink = utils.ToStringPointer(uplink) 57 | } 58 | if vdsName, ok := object["vds_name"]; ok && !validationutils.IsEmpty(vdsName) { 59 | result.VdsName = vdsName.(string) 60 | } 61 | return result, nil 62 | } 63 | -------------------------------------------------------------------------------- /docs/data-sources/credentials.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "vcf_credentials Data Source - terraform-provider-vcf" 4 | subcategory: "" 5 | description: |- 6 | Datasource used to extract credentials for different resources that are part of the SDDC deployment based on name, ip, type, domain or account type 7 | --- 8 | 9 | # vcf_credentials (Data Source) 10 | 11 | Datasource used to extract credentials for different resources that are part of the SDDC deployment based on name, ip, type, domain or account type 12 | 13 | 14 | 15 | 16 | ## Schema 17 | 18 | ### Optional 19 | 20 | - `account_type` (String) The type(s) of the account.One among USER, SYSTEM, SERVICE 21 | - `domain_name` (String) The domain in which context we do the credentials read. 22 | - `page` (Number) The page of credentials that is returned as result. 23 | - `page_size` (Number) the size of the credentials list . Default is 0 so the user will get all records in one page 24 | - `resource_ip` (String) The IP Address of the resource 25 | - `resource_name` (String) The name of the resource 26 | - `resource_type` (String) The type of the resource. One among ESXI, VCENTER, PSC, NSX_MANAGER, NSX_CONTROLLER, NSXT_EDGE, NSXT_MANAGER, VRLI, VROPS, VRA, WSA, VRSLCM, VXRAIL_MANAGER, NSX_ALB, BACKUP 27 | 28 | ### Read-Only 29 | 30 | - `credentials` (List of Object) List of credentials read from the API (see [below for nested schema](#nestedatt--credentials)) 31 | - `id` (String) The ID of this resource. 32 | 33 | 34 | ### Nested Schema for `credentials` 35 | 36 | Read-Only: 37 | 38 | - `account_type` (String) 39 | - `auto_rotate_frequency_days` (Number) 40 | - `auto_rotate_next_schedule` (String) 41 | - `creation_time` (String) 42 | - `credential_type` (String) 43 | - `id` (String) 44 | - `modification_time` (String) 45 | - `password` (String) 46 | - `resource` (List of Object) (see [below for nested schema](#nestedobjatt--credentials--resource)) 47 | - `user_name` (String) 48 | 49 | 50 | ### Nested Schema for `credentials.resource` 51 | 52 | Read-Only: 53 | 54 | - `domain` (String) 55 | - `id` (String) 56 | - `ip` (String) 57 | - `name` (String) 58 | - `type` (String) 59 | -------------------------------------------------------------------------------- /internal/provider/resource_credentials_auto_rotate_policy_test.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package provider 6 | 7 | import ( 8 | "fmt" 9 | "testing" 10 | "time" 11 | 12 | "github.com/hashicorp/terraform-plugin-testing/helper/acctest" 13 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 14 | 15 | "github.com/vmware/terraform-provider-vcf/internal/credentials" 16 | ) 17 | 18 | func TestAccResourceAutorotatePolicy_resourceId(t *testing.T) { 19 | rotateDays := acctest.RandIntRange(credentials.AutoRotateDaysMin, credentials.AutorotateDaysMax) 20 | timeAfter := time.Now().AddDate(0, 0, rotateDays) 21 | resource.Test(t, resource.TestCase{ 22 | PreCheck: func() { testAccSDDCManagerOrCloudBuilderPreCheck(t) }, 23 | ProtoV6ProviderFactories: muxedFactories(), 24 | Steps: []resource.TestStep{{ 25 | Config: testAccAutorotatePolicyResourceIdConfig(rotateDays), 26 | Check: resource.TestCheckResourceAttrWith("vcf_credentials_auto_rotate_policy.vc_0_autorotate", "auto_rotate_next_schedule", func(value string) error { 27 | nextAutorotate, err := time.Parse(time.RFC3339, value) 28 | if err != nil { 29 | return err 30 | } 31 | nextAutorotateDate := nextAutorotate.Format(time.DateOnly) 32 | timeAfterDate := timeAfter.Format(time.DateOnly) 33 | if nextAutorotateDate != timeAfterDate { 34 | return fmt.Errorf("%s different from %s", nextAutorotate, timeAfterDate) 35 | } 36 | 37 | return nil 38 | }), 39 | }}, 40 | }) 41 | } 42 | 43 | func testAccAutorotatePolicyResourceIdConfig(rotateDays int) string { 44 | return fmt.Sprintf(` 45 | data "vcf_credentials" "sddc_creds" { 46 | resource_type = "VCENTER" 47 | } 48 | 49 | resource "vcf_credentials_auto_rotate_policy" "vc_0_autorotate" { 50 | resource_id = data.vcf_credentials.sddc_creds.credentials[0].resource[0].id 51 | resource_type = data.vcf_credentials.sddc_creds.credentials[0].resource[0].type 52 | resource_name = data.vcf_credentials.sddc_creds.credentials[0].resource[0].name 53 | user_name = data.vcf_credentials.sddc_creds.credentials[0].user_name 54 | enable_auto_rotation = true 55 | auto_rotate_days = %v 56 | } 57 | `, rotateDays) 58 | } 59 | -------------------------------------------------------------------------------- /internal/certificates/csr_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package certificates 6 | 7 | import ( 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | "github.com/vmware/vcf-sdk-go/vcf" 10 | ) 11 | 12 | func CsrSchema() *schema.Resource { 13 | return &schema.Resource{ 14 | Schema: map[string]*schema.Schema{ 15 | "csr_pem": { 16 | Type: schema.TypeString, 17 | Description: "The CSR encoded content", 18 | Computed: true, 19 | }, 20 | "csr_string": { 21 | Type: schema.TypeString, 22 | Description: "The CSR decoded content", 23 | Computed: true, 24 | }, 25 | "resource": { 26 | Type: schema.TypeList, 27 | Description: "Resource associated with CSR", 28 | Computed: true, 29 | Elem: ResourceSchema(), 30 | }, 31 | }, 32 | } 33 | } 34 | 35 | func ResourceSchema() *schema.Resource { 36 | return &schema.Resource{ 37 | Schema: map[string]*schema.Schema{ 38 | "resource_id": { 39 | Type: schema.TypeString, 40 | Computed: true, 41 | Description: "Resource ID", 42 | }, 43 | "type": { 44 | Type: schema.TypeString, 45 | Computed: true, 46 | Description: "Resource type", 47 | }, 48 | "fqdn": { 49 | Type: schema.TypeString, 50 | Computed: true, 51 | Description: "Resource FQDN", 52 | }, 53 | "name": { 54 | Type: schema.TypeString, 55 | Computed: true, 56 | Description: "Name of the resource", 57 | }, 58 | }, 59 | } 60 | } 61 | 62 | func FlattenCsr(csr *vcf.Csr) map[string]interface{} { 63 | result := make(map[string]interface{}) 64 | result["csr_pem"] = *csr.CsrEncodedContent 65 | result["csr_string"] = *csr.CsrDecodedContent 66 | flattenedResource := FlattenResource(csr.Resource) 67 | result["resource"] = []interface{}{flattenedResource} 68 | return result 69 | } 70 | 71 | func FlattenResource(resource *vcf.Resource) map[string]interface{} { 72 | result := make(map[string]interface{}) 73 | 74 | result["resource_id"] = resource.ResourceId 75 | result["type"] = resource.Type 76 | result["fqdn"] = resource.Fqdn 77 | result["name"] = resource.Name 78 | 79 | return result 80 | } 81 | -------------------------------------------------------------------------------- /examples/resources/edge_cluster/variables.tf: -------------------------------------------------------------------------------- 1 | variable "sddc_manager_username" { 2 | description = "Username used to authenticate against an SDDC Manager instance." 3 | default = "" 4 | } 5 | 6 | variable "sddc_manager_password" { 7 | description = "Password used to authenticate against an SDDC Manager instance." 8 | default = "" 9 | } 10 | 11 | variable "sddc_manager_host" { 12 | description = "Fully qualified domain name of an SDDC Manager instance." 13 | default = "" 14 | } 15 | 16 | variable "cluster_name" { 17 | description = "The display name of the edge cluster." 18 | default = "" 19 | } 20 | 21 | variable "cluster_root_pass" { 22 | description = "The root user password for the edge cluster." 23 | default = "" 24 | } 25 | 26 | variable "cluster_admin_pass" { 27 | description = "The admin user password for the edge cluster." 28 | default = "" 29 | } 30 | 31 | variable "cluster_audit_pass" { 32 | description = "The audit user password for the edge cluster." 33 | default = "" 34 | } 35 | 36 | variable "compute_cluster_id" { 37 | description = "The identifier of the compute cluster where the edge nodes will be deployed." 38 | default = "" 39 | } 40 | 41 | variable "edge_node_1_name" { 42 | description = "The display name of the first edge node." 43 | default = "" 44 | } 45 | 46 | variable "edge_node_1_root_pass" { 47 | description = "The root user password for the first edge node." 48 | default = "" 49 | } 50 | 51 | variable "edge_node_1_admin_pass" { 52 | description = "The admin user password for the first edge node." 53 | default = "" 54 | } 55 | 56 | variable "edge_node_1_audit_pass" { 57 | description = "The audit user password for the first edge node." 58 | default = "" 59 | } 60 | 61 | variable "edge_node_2_name" { 62 | description = "The display name of the second edge node." 63 | default = "" 64 | } 65 | 66 | variable "edge_node_2_root_pass" { 67 | description = "The root user password for the second edge node." 68 | default = "" 69 | } 70 | 71 | variable "edge_node_2_admin_pass" { 72 | description = "The admin user password for the second edge node." 73 | default = "" 74 | } 75 | 76 | variable "edge_node_2_audit_pass" { 77 | description = "The audit user password for the second edge node." 78 | default = "" 79 | } 80 | -------------------------------------------------------------------------------- /examples/workflows/private-ai-foundation/README.md: -------------------------------------------------------------------------------- 1 | # Private AI Foundation via Terraform - Samples 2 | 3 | This repository contains sample automation for enabling a Tanzu Kubernetes Cluster with NVIDIA GPUs in VMware Cloud Foundation. 4 | 5 | The configuration is divided into several steps which are intended to be executed in order. 6 | Each step is designed to be atomic and can be executed independently from the rest provided that its prerequisites in terms of infrastructure are in place. 7 | 8 | These examples also use the [vSphere Terraform Provider](https://github.com/hashicorp/terraform-provider-vsphere) 9 | 10 | ## Workflow Overview 11 | 12 | ### Starting State 13 | 14 | This configuration is intended to be applied on an environment with a configured management domain. 15 | 16 | ### Desired State 17 | 18 | Using these samples you can: 19 | 20 | * Create a cluster image with vGPU drivers provided by NVIDIA 21 | * Create a subscribed content library with custom container images 22 | * Deploy a workload domain with vSAN storage and NSX network backing 23 | * Create an NSX Edge Cluster 24 | * Enable vSphere Supervisor on a cluster 25 | * Configure a vSphere Namespace and a Virtual Machine Class with your vGPU drivers 26 | 27 | ## Contents 28 | 29 | ### The [steps](https://github.com/vmware/terraform-provider-vcf/-/tree/main/examples/workflows/private-ai-foundation/steps) directory contains the sample configuration divided into a number of examples/workflows/private-ai-foundation/steps 30 | #### [Step 1](https://github.com/vmware/terraform-provider-vcf/-/blob/main/examples/workflows/private-ai-foundation/steps/01) - Create a vLCM cluster image with NVIDIA GPU drivers 31 | #### [Step 2](https://github.com/vmware/terraform-provider-vcf/-/blob/main/examples/workflows/private-ai-foundation/steps/02) - Export the cluster image and create a workload domain with it 32 | #### [Step 3](https://github.com/vmware/terraform-provider-vcf/-/blob/main/examples/workflows/private-ai-foundation/steps/03) - Create an NSX Edge Cluster 33 | #### [Step 4](https://github.com/vmware/terraform-provider-vcf/-/blob/main/examples/workflows/private-ai-foundation/steps/04) - Create a subscribed Content Library 34 | #### [Step 5](https://github.com/vmware/terraform-provider-vcf/-/blob/main/examples/workflows/private-ai-foundation/steps/05) - Enable Supervisor, create a vSphere Namespace and a VM class 35 | -------------------------------------------------------------------------------- /internal/sddc/sddc_host_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package sddc 6 | 7 | import ( 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 10 | utils "github.com/vmware/terraform-provider-vcf/internal/resource_utils" 11 | "github.com/vmware/vcf-sdk-go/installer" 12 | ) 13 | 14 | func GetSddcHostSchema() *schema.Schema { 15 | return &schema.Schema{ 16 | Type: schema.TypeList, 17 | Required: true, 18 | Elem: &schema.Resource{ 19 | Schema: map[string]*schema.Schema{ 20 | "credentials": getCredentialsSchema(), 21 | "hostname": { 22 | Type: schema.TypeString, 23 | Description: "ESXi hostname. If just the short hostname is provided, then FQDN will be generated using the \"domain\" from dns configuration. Must also adhere to RFC 1123 naming conventions. Example: \"esx-1\" length from 3 to 63", 24 | Required: true, 25 | ValidateFunc: validation.StringLenBetween(3, 63), 26 | }, 27 | "ssh_thumbprint": { 28 | Type: schema.TypeString, 29 | Description: "Host SSH thumbprint (RSA SHA256)", 30 | Optional: true, 31 | }, 32 | "ssl_thumbprint": { 33 | Type: schema.TypeString, 34 | Description: "Host SSH thumbprint (RSA SHA256)", 35 | Optional: true, 36 | }, 37 | }, 38 | }, 39 | } 40 | } 41 | 42 | func GetSddcHostSpecsFromSchema(rawData []interface{}) *[]installer.SddcHostSpec { 43 | var hostSpecs []installer.SddcHostSpec 44 | for _, rawListEntity := range rawData { 45 | hostSpecRaw := rawListEntity.(map[string]interface{}) 46 | hostname := hostSpecRaw["hostname"].(string) 47 | sshThumbprint := utils.ToStringPointer(hostSpecRaw["ssh_thumbprint"]) 48 | sslThumbprint := utils.ToStringPointer(hostSpecRaw["ssl_thumbprint"]) 49 | 50 | hostSpec := installer.SddcHostSpec{ 51 | Hostname: hostname, 52 | SshThumbprint: sshThumbprint, 53 | SslThumbprint: sslThumbprint, 54 | } 55 | if credentialsData := getCredentialsFromSchema(hostSpecRaw["credentials"].([]interface{})); credentialsData != nil { 56 | hostSpec.Credentials = credentialsData 57 | } 58 | hostSpecs = append(hostSpecs, hostSpec) 59 | } 60 | return &hostSpecs 61 | } 62 | -------------------------------------------------------------------------------- /examples/main.tf: -------------------------------------------------------------------------------- 1 | # Required Provider 2 | terraform { 3 | required_providers { 4 | vcf = { 5 | source = "vmware/vcf" 6 | } 7 | } 8 | } 9 | 10 | # Provider Configuration 11 | provider "vcf" { 12 | sddc_manager_username = var.sddc_manager_username 13 | sddc_manager_password = var.sddc_manager_password 14 | sddc_manager_host = var.sddc_manager_host 15 | } 16 | 17 | # Resources 18 | resource "vcf_ceip" "ceip" { 19 | status = "DISABLE" 20 | } 21 | 22 | resource "vcf_user" "testuser1" { 23 | name = "testuser1@vrack.vsphere.local" 24 | domain = "vrack.vsphere.local" 25 | type = "USER" 26 | role_name = "VIEWER" 27 | } 28 | 29 | resource "vcf_user" "serviceuser1" { 30 | name = "serviceuser1" 31 | domain = "Nil" 32 | type = "SERVICE" 33 | role_name = "ADMIN" 34 | } 35 | 36 | output "serviceuser1_apikey" { 37 | value = vcf_user.serviceuser1.api_key 38 | } 39 | 40 | resource "vcf_network_pool" "eng_pool" { 41 | name = "engineering-pool2" 42 | network { 43 | gateway = "192.168.8.1" 44 | mask = "255.255.255.0" 45 | mtu = 9000 46 | subnet = "192.168.8.0" 47 | type = "VSAN" 48 | vlan_id = 100 49 | ip_pools { 50 | start = "192.168.8.5" 51 | end = "192.168.8.50" 52 | } 53 | } 54 | network { 55 | gateway = "192.168.9.1" 56 | mask = "255.255.255.0" 57 | mtu = 9000 58 | subnet = "192.168.9.0" 59 | type = "vMotion" 60 | vlan_id = 100 61 | ip_pools { 62 | start = "192.168.9.5" 63 | end = "192.168.9.50" 64 | } 65 | } 66 | } 67 | 68 | resource "vcf_host" "esxi_1" { 69 | fqdn = "esxi-1.vrack.vsphere.local" 70 | username = var.esxi_1_user 71 | password = var.esxi_1_pass 72 | network_pool_name = "bringup-networkpool" 73 | storage_type = "VSAN" 74 | } 75 | 76 | resource "vcf_host" "esxi_2" { 77 | fqdn = "esxi-2.vrack.vsphere.local" 78 | username = var.esxi_2_user 79 | password = var.esxi_2_pass 80 | network_pool_name = "bringup-networkpool" 81 | storage_type = "VSAN" 82 | } 83 | 84 | resource "vcf_host" "esxi_3" { 85 | fqdn = "esxi-3.vrack.vsphere.local" 86 | username = var.esxi_3_user 87 | password = var.esxi_3_pass 88 | network_pool_name = "bringup-networkpool" 89 | storage_type = "VSAN" 90 | } -------------------------------------------------------------------------------- /internal/provider/data_source_cluster_test.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package provider 6 | 7 | import ( 8 | "fmt" 9 | "os" 10 | "testing" 11 | 12 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 13 | 14 | "github.com/vmware/terraform-provider-vcf/internal/constants" 15 | ) 16 | 17 | func TestAccDataSourceVcfCluster(t *testing.T) { 18 | resource.Test(t, resource.TestCase{ 19 | PreCheck: func() { testAccPreCheck(t) }, 20 | ProtoV6ProviderFactories: muxedFactories(), 21 | Steps: []resource.TestStep{ 22 | { 23 | Config: testAccVcfClusterDataSourceConfig( 24 | os.Getenv(constants.VcfTestClusterDataSourceId)), 25 | Check: resource.ComposeTestCheckFunc( 26 | resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "name"), 27 | resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "domain_id"), 28 | resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "primary_datastore_name"), 29 | resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "primary_datastore_type"), 30 | resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "is_default"), 31 | resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "is_stretched"), 32 | resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "host.0.id"), 33 | resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "host.0.host_name"), 34 | resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "host.0.ip_address"), 35 | resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "host.1.id"), 36 | resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "host.1.host_name"), 37 | resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "host.1.ip_address"), 38 | resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "host.2.id"), 39 | resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "host.2.host_name"), 40 | resource.TestCheckResourceAttrSet("data.vcf_cluster.cluster1", "host.2.ip_address"), 41 | ), 42 | }, 43 | }, 44 | }) 45 | } 46 | 47 | func testAccVcfClusterDataSourceConfig(domainId string) string { 48 | return fmt.Sprintf(` 49 | data "vcf_cluster" "cluster1" { 50 | cluster_id = %q 51 | }`, domainId) 52 | } 53 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Enhancement Request 3 | description: Is something critical missing? Suggest an enhancement. 4 | labels: 5 | - [enhancement, needs-review] 6 | body: 7 | - type: markdown 8 | attributes: 9 | value: > 10 | Before filing an enhancement, please search the existing issues and use the 11 | [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) 12 | feature to add up-votes to existing requests. 13 | 14 | 15 | When filing an enhancement, please include the following information. 16 | - type: checkboxes 17 | id: terms 18 | attributes: 19 | label: Code of Conduct 20 | description: >- 21 | This project has a [Code of 22 | Conduct](https://github.com/vmware/terraform-provider-vcf/blob/main/CODE_OF_CONDUCT.md) 23 | that all participants are expected to understand and follow. 24 | options: 25 | - label: I have read and agree to the project's Code of Conduct. 26 | required: true 27 | - label: Vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue initial description to help the maintainers prioritize. 28 | required: false 29 | - label: Do not leave "+1" or other comments that do not add relevant information or questions. 30 | required: false 31 | - label: If you are interested in working on this issue or have submitted a pull request, please leave a comment. 32 | required: false 33 | - type: textarea 34 | id: description 35 | attributes: 36 | label: Description 37 | description: A written overview of the enhancement. 38 | validations: 39 | required: true 40 | - type: textarea 41 | id: use-case 42 | attributes: 43 | label: Use Case(s) 44 | description: Any relevant use-cases that you see. 45 | validations: 46 | required: true 47 | - type: textarea 48 | id: potential-configuration 49 | attributes: 50 | label: Potential Configuration 51 | description: Provide a potential configuration. 52 | validations: 53 | required: true 54 | - type: textarea 55 | id: references 56 | attributes: 57 | label: References 58 | description: Provide any references. 59 | validations: 60 | required: false 61 | -------------------------------------------------------------------------------- /internal/provider/resource_network_pool_test.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package provider 6 | 7 | import ( 8 | "context" 9 | "fmt" 10 | "log" 11 | "testing" 12 | 13 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 14 | "github.com/hashicorp/terraform-plugin-testing/terraform" 15 | 16 | "github.com/vmware/terraform-provider-vcf/internal/constants" 17 | ) 18 | 19 | func TestAccResourceVcfNetworkPool(t *testing.T) { 20 | resource.Test(t, resource.TestCase{ 21 | PreCheck: func() { testAccPreCheck(t) }, 22 | ProtoV6ProviderFactories: muxedFactories(), 23 | CheckDestroy: testCheckVcfNetworkPoolDestroy, 24 | Steps: []resource.TestStep{ 25 | { 26 | Config: testAccVcfNetworkPoolConfig(constants.VcfTestNetworkPoolName), 27 | Check: resource.ComposeTestCheckFunc( 28 | resource.TestCheckResourceAttrSet("vcf_network_pool.test_pool", "id"), 29 | ), 30 | }, 31 | }, 32 | }) 33 | } 34 | 35 | func testAccVcfNetworkPoolConfig(networkPoolName string) string { 36 | return fmt.Sprintf(` 37 | resource "vcf_network_pool" "test_pool" { 38 | name = %q 39 | network { 40 | gateway = "192.168.4.1" 41 | mask = "255.255.255.0" 42 | mtu = 8940 43 | subnet = "192.168.4.0" 44 | type = "VSAN" 45 | vlan_id = 100 46 | ip_pools { 47 | start = "192.168.4.5" 48 | end = "192.168.4.50" 49 | } 50 | } 51 | network { 52 | gateway = "192.168.5.1" 53 | mask = "255.255.255.0" 54 | mtu = 8940 55 | subnet = "192.168.5.0" 56 | type = "vMotion" 57 | vlan_id = 100 58 | ip_pools { 59 | start = "192.168.5.5" 60 | end = "192.168.5.50" 61 | } 62 | } 63 | }`, networkPoolName) 64 | } 65 | 66 | func testCheckVcfNetworkPoolDestroy(_ *terraform.State) error { 67 | apiClient := (interface{}(testAccFrameworkProvider)).(*FrameworkProvider).SddcManagerClient.ApiClient 68 | 69 | hosts, err := apiClient.GetNetworkPoolWithResponse(context.TODO()) 70 | if err != nil { 71 | log.Println("error = ", err) 72 | return err 73 | } 74 | 75 | for _, networkPool := range *hosts.JSON200.Elements { 76 | if networkPool.Name == constants.VcfTestNetworkPoolName { 77 | return fmt.Errorf("found networkPool %q", *networkPool.Id) 78 | } 79 | } 80 | 81 | return nil 82 | } 83 | -------------------------------------------------------------------------------- /internal/api_client/client_util.go: -------------------------------------------------------------------------------- 1 | package api_client 2 | 3 | import ( 4 | "github.com/vmware/vcf-sdk-go/installer" 5 | "github.com/vmware/vcf-sdk-go/vcf" 6 | ) 7 | 8 | func ConvertToVcfError(err installer.Error) vcf.Error { 9 | var causes *[]vcf.ErrorCause 10 | if err.Causes != nil { 11 | mappedCauses := mapValues(*err.Causes, convertToVcfErrorCause) 12 | causes = &mappedCauses 13 | } 14 | 15 | var nestedErrors *[]vcf.Error 16 | if err.NestedErrors != nil { 17 | mappedNestedErrors := mapValues(*err.NestedErrors, ConvertToVcfError) 18 | nestedErrors = &mappedNestedErrors 19 | } 20 | 21 | return vcf.Error{ 22 | Arguments: err.Arguments, 23 | Causes: causes, 24 | Context: err.Context, 25 | ErrorCode: err.ErrorCode, 26 | ErrorType: err.ErrorType, 27 | Message: err.Message, 28 | NestedErrors: nestedErrors, 29 | ReferenceToken: err.ReferenceToken, 30 | RemediationMessage: err.RemediationMessage, 31 | } 32 | } 33 | 34 | func ConvertToVcfValidation(val installer.Validation) vcf.Validation { 35 | var validationChecks *[]vcf.ValidationCheck 36 | if val.ValidationChecks != nil { 37 | mappedValidationChecks := mapValues(*val.ValidationChecks, convertToVcfValidationCheck) 38 | validationChecks = &mappedValidationChecks 39 | } 40 | 41 | return vcf.Validation{ 42 | AdditionalProperties: val.AdditionalProperties, 43 | Description: val.Description, 44 | ExecutionStatus: val.ExecutionStatus, 45 | Id: val.Id, 46 | ResultStatus: val.ResultStatus, 47 | ValidationChecks: validationChecks, 48 | } 49 | } 50 | 51 | func convertToVcfErrorCause(cause installer.ErrorCause) vcf.ErrorCause { 52 | return vcf.ErrorCause{ 53 | Message: cause.Message, 54 | Type: cause.Type, 55 | } 56 | } 57 | 58 | func convertToVcfValidationCheck(check installer.ValidationCheck) vcf.ValidationCheck { 59 | var errorResponse *vcf.Error 60 | if check.ErrorResponse != nil { 61 | value := ConvertToVcfError(*check.ErrorResponse) 62 | errorResponse = &value 63 | } 64 | return vcf.ValidationCheck{ 65 | Description: check.Description, 66 | ErrorResponse: errorResponse, 67 | ResultStatus: check.ResultStatus, 68 | Severity: check.Severity, 69 | } 70 | } 71 | 72 | func mapValues[T, K interface{}](src []T, f func(T) K) []K { 73 | r := make([]K, len(src)) 74 | for i, v := range src { 75 | r[i] = f(v) 76 | } 77 | return r 78 | } 79 | -------------------------------------------------------------------------------- /internal/provider/resource_user_test.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package provider 6 | 7 | import ( 8 | "context" 9 | "fmt" 10 | "log" 11 | "testing" 12 | 13 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 14 | "github.com/hashicorp/terraform-plugin-testing/terraform" 15 | 16 | "github.com/vmware/terraform-provider-vcf/internal/api_client" 17 | ) 18 | 19 | const ( 20 | testUserName1 = "testuser1@vrack.vsphere.local" 21 | testUserName2 = "serviceuser1" 22 | ) 23 | 24 | func TestAccResourceVcfUser(t *testing.T) { 25 | resource.Test(t, resource.TestCase{ 26 | PreCheck: func() { testAccPreCheck(t) }, 27 | ProtoV6ProviderFactories: muxedFactories(), 28 | CheckDestroy: testCheckVcfUserDestroy, 29 | Steps: []resource.TestStep{ 30 | { 31 | Config: testAccVcfUserConfig(), 32 | Check: resource.ComposeTestCheckFunc( 33 | resource.TestCheckResourceAttrSet("vcf_user.testuser1", "id"), 34 | resource.TestCheckResourceAttrSet("vcf_user.testuser1", "creation_timestamp"), 35 | resource.TestCheckResourceAttrSet("vcf_user.serviceuser1", "id"), 36 | resource.TestCheckResourceAttrSet("vcf_user.serviceuser1", "api_key"), 37 | resource.TestCheckResourceAttrSet("vcf_user.serviceuser1", "creation_timestamp"), 38 | ), 39 | }, 40 | }, 41 | }) 42 | } 43 | 44 | func testAccVcfUserConfig() string { 45 | return fmt.Sprintf(` 46 | resource "vcf_user" "testuser1" { 47 | name = %q 48 | domain = "vrack.vsphere.local" 49 | type = "USER" 50 | role_name = "VIEWER" 51 | } 52 | 53 | resource "vcf_user" "serviceuser1" { 54 | name = %q 55 | domain = "vrack.vsphere.local" 56 | type = "SERVICE" 57 | role_name = "VIEWER" 58 | } 59 | `, testUserName1, testUserName2) 60 | } 61 | 62 | func testCheckVcfUserDestroy(_ *terraform.State) error { 63 | apiClient := testAccProvider.Meta().(*api_client.SddcManagerClient).ApiClient 64 | 65 | ok, err := apiClient.GetUsersWithResponse(context.TODO()) 66 | if err != nil { 67 | log.Println("error = ", err) 68 | return err 69 | } 70 | 71 | // Check if the users with the known usernames exist 72 | for _, user := range *ok.JSON200.Elements { 73 | if user.Name == testUserName1 || user.Name == testUserName2 { 74 | return fmt.Errorf("found user with username %q", user.Name) 75 | } 76 | } 77 | 78 | // Didn't find the test users 79 | return nil 80 | } 81 | -------------------------------------------------------------------------------- /internal/provider/data_certificate_test.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package provider 6 | 7 | import ( 8 | "testing" 9 | 10 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 11 | ) 12 | 13 | func TestAccDataSourceCertificate(t *testing.T) { 14 | resource.Test(t, resource.TestCase{ 15 | PreCheck: func() { testAccSDDCManagerOrCloudBuilderPreCheck(t) }, 16 | ProtoV6ProviderFactories: muxedFactories(), 17 | Steps: []resource.TestStep{ 18 | { 19 | Config: testAccDataSourceCertificateConfig(), 20 | Check: resource.ComposeTestCheckFunc( 21 | resource.TestCheckResourceAttr("data.vcf_certificate.cert", "certificate.0.subject_cn", "sfo-w01-vc01.sfo.rainpole.io"), 22 | resource.TestCheckResourceAttr("data.vcf_certificate.cert", "certificate.0.subject_locality", "Palo Alto"), 23 | resource.TestCheckResourceAttr("data.vcf_certificate.cert", "certificate.0.subject_st", "California"), 24 | resource.TestCheckResourceAttr("data.vcf_certificate.cert", "certificate.0.subject_country", "US"), 25 | resource.TestCheckResourceAttr("data.vcf_certificate.cert", "certificate.0.subject_org", "VMware Inc."), 26 | resource.TestCheckResourceAttr("data.vcf_certificate.cert", "certificate.0.subject_ou", "VCF"), 27 | resource.TestCheckResourceAttr("data.vcf_certificate.cert", "certificate.0.public_key_algorithm", "RSA"), 28 | resource.TestCheckResourceAttr("data.vcf_certificate.cert", "certificate.0.key_size", "3072"), 29 | resource.TestCheckResourceAttr("data.vcf_certificate.cert", "certificate.0.signature_algorithm", "SHA256withRSA"), 30 | resource.TestCheckResourceAttr("data.vcf_certificate.cert", "certificate.0.expiration_status", "ACTIVE"), 31 | resource.TestCheckResourceAttr("data.vcf_certificate.cert", "certificate.0.issued_to", "sfo-w01-vc01.sfo.rainpole.io"), 32 | resource.TestCheckResourceAttr("data.vcf_certificate.cert", "certificate.0.issued_by", "CN=rainpole-RPL-AD01-CA, DC=rainpole, DC=io"), 33 | resource.TestCheckResourceAttr("data.vcf_certificate.cert", "certificate.0.version", "V3"), 34 | ), 35 | }, 36 | }, 37 | }) 38 | } 39 | 40 | func testAccDataSourceCertificateConfig() string { 41 | return ` 42 | data "vcf_domain" "w01" { 43 | name = "sfo-w01" 44 | } 45 | data "vcf_certificate" "cert" { 46 | domain_id = data.vcf_domain.w01.id 47 | resource_fqdn = "sfo-w01-vc01.sfo.rainpole.io" 48 | } 49 | ` 50 | } 51 | -------------------------------------------------------------------------------- /docs/resources/certificate_authority.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "vcf_certificate_authority Resource - terraform-provider-vcf" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # vcf_certificate_authority (Resource) 10 | 11 | VMware Cloud Foundation supports the ability to manage certificates by integrating with Microsoft Active Directory Certificate Services (Microsoft CA) or OpenSSL CA. 12 | Before you can perform certificate operations using this provider you must ensure that the Microsoft Certificate Authority or OpenSSL Certificate Authority are configured correctly. 13 | 14 | 15 | 16 | 17 | ## Schema 18 | 19 | ### Optional 20 | 21 | - `microsoft` (Block List, Max: 1) Configuration describing Microsoft CA server (see [below for nested schema](#nestedblock--microsoft)) 22 | - `open_ssl` (Block List, Max: 1) Configuration describing OpenSSL CA server (see [below for nested schema](#nestedblock--open_ssl)) 23 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 24 | 25 | ### Read-Only 26 | 27 | - `id` (String) The ID of this resource. 28 | - `type` (String) Certificate authority type. "id" has the same value. Microsoft or OpenSSL 29 | 30 | 31 | ### Nested Schema for `microsoft` 32 | 33 | Required: 34 | 35 | - `secret` (String, Sensitive) Microsoft CA server password 36 | - `server_url` (String) Microsoft CA server URL 37 | - `template_name` (String) Microsoft CA server template name 38 | - `username` (String) Microsoft CA server username 39 | 40 | 41 | 42 | ### Nested Schema for `open_ssl` 43 | 44 | Required: 45 | 46 | - `common_name` (String) OpenSSL CA domain name 47 | - `country` (String) ISO 3166 country code where company is legally registered 48 | - `locality` (String) The city or locality where company is legally registered 49 | - `organization` (String) The name under which your company is known. The listed organization must be the legal registrant of the domain name in the certificate request. 50 | - `organization_unit` (String) Organization with which the certificate is associated 51 | - `state` (String) Full name (do not abbreviate) of the state, province, region, or territory where your company is legally registered. 52 | 53 | 54 | 55 | ### Nested Schema for `timeouts` 56 | 57 | Optional: 58 | 59 | - `create` (String) 60 | - `delete` (String) 61 | - `read` (String) 62 | - `update` (String) 63 | -------------------------------------------------------------------------------- /examples/workflows/private-ai-foundation/steps/03/variables.tf: -------------------------------------------------------------------------------- 1 | variable "vcenter_username" { 2 | description = "Username used to authenticate against the vCenter Server" 3 | } 4 | 5 | variable "vcenter_password" { 6 | description = "Password used to authenticate against the vCenter Server" 7 | } 8 | 9 | variable "vcenter_server" { 10 | description = "FQDN or IP Address of the vCenter Server" 11 | } 12 | 13 | variable "datacenter_name" { 14 | description = "The name of the datacenter" 15 | } 16 | 17 | variable "cluster_id" { 18 | description = "The identifier (in SDDC manager) of the compute cluster" 19 | } 20 | 21 | variable "sddc_manager_username" { 22 | description = "Username used to authenticate against an SDDC Manager instance" 23 | } 24 | 25 | variable "sddc_manager_password" { 26 | description = "Password used to authenticate against an SDDC Manager instance" 27 | } 28 | 29 | variable "sddc_manager_host" { 30 | description = "FQDN or IP Address of an SDDC Manager instance" 31 | } 32 | 33 | variable "edge_cluster_name" { 34 | description = "The name of the edge cluster" 35 | } 36 | 37 | variable "edge_cluster_root_pass" { 38 | description = "The root user password for the edge cluster" 39 | } 40 | 41 | variable "edge_cluster_admin_pass" { 42 | description = "The administrator password for the edge cluster" 43 | } 44 | 45 | variable "edge_cluster_audit_pass" { 46 | description = "The audit user password for the edge cluster" 47 | } 48 | 49 | variable "edge_node1_cidr" { 50 | description = "The IP address of the first edge node (in CIDR format, e.g. 10.0.0.12/24)" 51 | } 52 | 53 | variable "edge_node1_root_pass" { 54 | description = "The root user password for the first edge node" 55 | } 56 | 57 | variable "edge_node1_admin_pass" { 58 | description = "The administrator password for the first edge node" 59 | } 60 | 61 | variable "edge_node1_audit_pass" { 62 | description = "The audit user password for the first edge node" 63 | } 64 | 65 | variable "edge_node2_cidr" { 66 | description = "The IP address of the second edge node (in CIDR format, e.g. 10.0.0.12/24)" 67 | } 68 | 69 | variable "edge_node2_root_pass" { 70 | description = "The root user password for the second edge node" 71 | } 72 | 73 | variable "edge_node2_admin_pass" { 74 | description = "The administrator password for the second edge node" 75 | } 76 | 77 | variable "edge_node2_audit_pass" { 78 | description = "The audit user password for the second edge node" 79 | } 80 | 81 | variable "bgp_peer_password" { 82 | description = "The password for the bgp peers" 83 | } -------------------------------------------------------------------------------- /docs/resources/csr.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "vcf_csr Resource - terraform-provider-vcf" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # vcf_csr (Resource) 10 | 11 | Prerequisites for generating CSRs: 12 | * The SDDC Manager should be up and running. 13 | * The resources of the target domain (e.g. MGMT) should be in ACTIVE state. 14 | 15 | Generated CSRs are prerequisite to installing certificates of SDDC components with either 16 | external or internal CA. 17 | 18 | 19 | ## Schema 20 | 21 | ### Required 22 | 23 | - `country` (String) ISO 3166 country code where company is legally registered 24 | - `domain_id` (String) Domain Id or Name for which the CSRs should be generated 25 | - `email` (String) Contact email address 26 | - `fqdn` (String) FQDN of the resource 27 | - `key_size` (Number) Certificate public key size. One among: 2048, 3072, 4096 28 | - `locality` (String) The city or locality where company is legally registered 29 | - `organization` (String) The name under which your company is known. The listed organization must be the legal registrant of the domain name in the certificate request. 30 | - `organization_unit` (String) Organization with which the certificate is associated 31 | - `resource` (String) Resources for which the CSRs are to be generated. One among: SDDC_MANAGER, PSC, VCENTER, NSX_MANAGER, NSXT_MANAGER, VROPS, VRSLCM, VXRAIL_MANAGER 32 | - `state` (String) Full name (do not abbreviate) of the state, province, region, or territory where your company is legally registered. 33 | 34 | ### Optional 35 | 36 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 37 | 38 | ### Read-Only 39 | 40 | - `csr` (List of Object) Resulting CSR (see [below for nested schema](#nestedatt--csr)) 41 | - `id` (String) The ID of this resource. 42 | 43 | 44 | ### Nested Schema for `timeouts` 45 | 46 | Optional: 47 | 48 | - `create` (String) 49 | - `delete` (String) 50 | - `read` (String) 51 | - `update` (String) 52 | 53 | 54 | 55 | ### Nested Schema for `csr` 56 | 57 | Read-Only: 58 | 59 | - `csr_pem` (String) The resulting CSR content in encoded format 60 | - `csr_string` (String) The resulting CSR content in decoded format 61 | - `resource` (List of Object) (see [below for nested schema](#nestedobjatt--csr--resource)) 62 | 63 | 64 | ### Nested Schema for `csr.resource` 65 | 66 | Read-Only: 67 | 68 | - `fqdn` (String) Resource FQDN 69 | - `name` (String) VCF 4.5.2 API does not return info for this field 70 | - `resource_id` (String) VCF 4.5.2 API does not return info for this field 71 | - `type` (String) VCF 4.5.2 API does not return info for this field 72 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to terraform-provider-vcf 2 | 3 | Before you start working with terraform-provider-vcf please read our Developer Certificate 4 | of Origin. All contributions to this repository must be signed as described on 5 | that page. Your signature certifies that you wrote the patch or have the right 6 | to pass it on as an open-source patch 7 | 8 | For any questions about the DCO process, please refer to our [FAQ](https://cla.vmware.com/dco). 9 | 10 | ## Contribution Flow 11 | 12 | This is a general outline of what a contributor's workflow looks like: 13 | 14 | - Create a topic branch from where you want to base your work 15 | - Make commits of logical units 16 | - Make sure your commit messages are in the proper format (see below) 17 | - Push your changes to a topic branch in your fork of the repository 18 | - Submit a pull request 19 | 20 | Example: 21 | 22 | ``` shell 23 | git remote add upstream https://github.com/vmware/terraform-provider-vcf.git 24 | git checkout -b my-new-feature main 25 | git commit -a 26 | git push origin my-new-feature 27 | ``` 28 | 29 | ### Staying In Sync With Upstream 30 | 31 | If your branch gets out of sync with the `vmware/main` branch, use the 32 | following to update: 33 | 34 | ``` shell 35 | git checkout my-new-feature 36 | git fetch -a 37 | git pull --rebase upstream main 38 | git push --force-with-lease origin my-new-feature 39 | ``` 40 | 41 | ### Updating Pull Requests 42 | 43 | If your pull request fails to pass CI or needs changes based on code review, 44 | you'll most likely want to squash these changes into existing commits. 45 | 46 | If your pull request contains a single commit or your changes are related to 47 | the most recent commit, you can simply amend the commit. 48 | 49 | ``` shell 50 | git add . 51 | git commit --amend 52 | git push --force-with-lease origin my-new-feature 53 | ``` 54 | 55 | If you need to squash changes into an earlier commit, you can use: 56 | 57 | ``` shell 58 | git add . 59 | git commit --fixup 60 | git rebase -i --autosquash main 61 | git push --force-with-lease origin my-new-feature 62 | ``` 63 | 64 | Be sure to add a comment to the pull request indicating your new changes are 65 | ready to review. GitHub does not provide a notification for a git push. 66 | 67 | ### Code Style 68 | 69 | ### Formatting Commit Messages 70 | 71 | We follow the conventions on [How to Write a Git Commit Message](http://chris.beams.io/posts/git-commit/). 72 | 73 | Be sure to include any related GitHub issue references in the commit message. 74 | See [GFM syntax](https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown) 75 | for referencing issues and commits. 76 | 77 | ## Reporting Bugs and Creating Issues 78 | 79 | When opening a new issue, try to roughly follow the commit message format 80 | conventions above. 81 | -------------------------------------------------------------------------------- /docs/resources/network_pool.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "vcf_network_pool Resource - terraform-provider-vcf" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # vcf_network_pool (Resource) 10 | 11 | Used to create a Network pool in the system. The added network pool would be used during domain deployments, host commission/expansion flows. 12 | If a network pool which is already added before is added, you will get an error with HTTP status 400. 13 | If a malformed network pool is added (payload for network parameters, name which is already exist), you will get an error. 14 | 15 | The following data is prerequisite for creating a new Network Pool 16 | 17 | * Name 18 | * List of networks associated with network pool in which each network has 19 | * Network type - It can be VSAN, VMOTION or NFS Type. 20 | * VLAN ID - Valid Vlan id range is 0 to 4096. 21 | * MTU - Valid MTU range is 1500 to 9216. 22 | * Subnet - Networks of diferent types (e.g. VSAN/VMOTION/NFS) must not have overlapping subnets 23 | * Subnet mask 24 | * gateway - The gateway defined for the specified subnet 25 | * List of IP address ranges - the start and end IP address of each IP Pool should be part of the subnet 26 | 27 | 28 | 29 | ## Schema 30 | 31 | ### Required 32 | 33 | - `name` (String) The name of the network pool 34 | 35 | ### Optional 36 | 37 | - `network` (Block List) Represents a network in a network pool (see [below for nested schema](#nestedblock--network)) 38 | - `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts)) 39 | 40 | ### Read-Only 41 | 42 | - `id` (String) Service generated identifier for the network pool. 43 | 44 | 45 | ### Nested Schema for `network` 46 | 47 | Required: 48 | 49 | - `vlan_id` (Number) VLAN ID associated with the network 50 | 51 | Optional: 52 | 53 | - `gateway` (String) Gateway for the network 54 | - `ip_pools` (Block List) List of IP pool ranges to use (see [below for nested schema](#nestedblock--network--ip_pools)) 55 | - `mask` (String) Subnet mask for the subnet of the network 56 | - `mtu` (Number) Gateway for the network 57 | - `subnet` (String) Subnet associated with the network 58 | - `type` (String) Network Type of the network 59 | 60 | 61 | ### Nested Schema for `network.ip_pools` 62 | 63 | Optional: 64 | 65 | - `end` (String) End IP address of the IP pool 66 | - `start` (String) Start IP address of the IP pool 67 | 68 | 69 | 70 | 71 | ### Nested Schema for `timeouts` 72 | 73 | Optional: 74 | 75 | - `create` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are "s" (seconds), "m" (minutes), "h" (hours). 76 | -------------------------------------------------------------------------------- /internal/provider/resource_csr_test.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package provider 6 | 7 | import ( 8 | "fmt" 9 | "os" 10 | "testing" 11 | 12 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 13 | 14 | "github.com/vmware/terraform-provider-vcf/internal/constants" 15 | ) 16 | 17 | func TestAccResourceVcfCsr_vCenter(t *testing.T) { 18 | resource.Test(t, resource.TestCase{ 19 | PreCheck: func() { 20 | testAccPreCheck(t) 21 | }, 22 | ProtoV6ProviderFactories: muxedFactories(), 23 | Steps: []resource.TestStep{ 24 | { 25 | Config: testAccVcfCsrConfig(os.Getenv(constants.VcfTestDomainDataSourceId), "VCENTER", os.Getenv(constants.VcfTestVcenterFqdn)), 26 | Check: resource.ComposeTestCheckFunc( 27 | resource.TestCheckResourceAttrSet("vcf_csr.csr1", "csr.0.csr_pem"), 28 | resource.TestCheckResourceAttrSet("vcf_csr.csr1", "csr.0.csr_string"), 29 | resource.TestCheckResourceAttrSet("vcf_csr.csr1", "csr.0.resource.0.fqdn")), 30 | }, 31 | }, 32 | }) 33 | } 34 | 35 | func TestAccResourceVcfCsr_sddcManager(t *testing.T) { 36 | resource.Test(t, resource.TestCase{ 37 | PreCheck: func() { 38 | testAccPreCheck(t) 39 | }, 40 | ProtoV6ProviderFactories: muxedFactories(), 41 | Steps: []resource.TestStep{ 42 | { 43 | Config: testAccVcfCsrConfig(os.Getenv(constants.VcfTestDomainDataSourceId), "SDDC_MANAGER", os.Getenv(constants.VcfTestSddcManagerFqdn)), 44 | Check: resource.ComposeTestCheckFunc( 45 | resource.TestCheckResourceAttrSet("vcf_csr.csr1", "csr.0.csr_pem"), 46 | resource.TestCheckResourceAttrSet("vcf_csr.csr1", "csr.0.csr_string"), 47 | resource.TestCheckResourceAttrSet("vcf_csr.csr1", "csr.0.resource.0.fqdn")), 48 | }, 49 | }, 50 | }) 51 | } 52 | 53 | func TestAccResourceVcfCsr_nsxManager(t *testing.T) { 54 | resource.Test(t, resource.TestCase{ 55 | PreCheck: func() { 56 | testAccPreCheck(t) 57 | }, 58 | ProtoV6ProviderFactories: muxedFactories(), 59 | Steps: []resource.TestStep{ 60 | { 61 | Config: testAccVcfCsrConfig(os.Getenv(constants.VcfTestDomainDataSourceId), "NSXT_MANAGER", os.Getenv(constants.VcfTestNsxManagerFqdn)), 62 | Check: resource.ComposeTestCheckFunc( 63 | resource.TestCheckResourceAttrSet("vcf_csr.csr1", "csr.0.csr_pem"), 64 | resource.TestCheckResourceAttrSet("vcf_csr.csr1", "csr.0.csr_string"), 65 | resource.TestCheckResourceAttrSet("vcf_csr.csr1", "csr.0.resource.0.fqdn")), 66 | }, 67 | }, 68 | }) 69 | } 70 | 71 | func testAccVcfCsrConfig(domainID, resource, fqdn string) string { 72 | return fmt.Sprintf(` 73 | resource "vcf_csr" "csr1" { 74 | domain_id = %q 75 | country = "BG" 76 | email = "admin@vmware.com" 77 | key_size = "3072" 78 | locality = "Sofia" 79 | state = "Sofia-grad" 80 | organization = "VMware Inc." 81 | organization_unit = "VCF" 82 | resource = %q 83 | fqdn = %q 84 | }`, 85 | domainID, resource, fqdn, 86 | ) 87 | } 88 | -------------------------------------------------------------------------------- /internal/network/portgroup_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package network 6 | 7 | import ( 8 | "fmt" 9 | "strings" 10 | 11 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 12 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 13 | "github.com/vmware/vcf-sdk-go/vcf" 14 | 15 | validationutils "github.com/vmware/terraform-provider-vcf/internal/validation" 16 | ) 17 | 18 | // PortgroupSchema this helper function extracts the Portgroup Schema, so that 19 | // it's made available for both workload domain and cluster creation. 20 | func PortgroupSchema() *schema.Resource { 21 | return &schema.Resource{ 22 | Schema: map[string]*schema.Schema{ 23 | "name": { 24 | Type: schema.TypeString, 25 | Required: true, 26 | Description: "Port group name", 27 | ValidateFunc: validation.NoZeroValues, 28 | }, 29 | "transport_type": { 30 | Type: schema.TypeString, 31 | Required: true, 32 | Description: "Port group transport type, One among: VSAN, VMOTION, MANAGEMENT, PUBLIC, " + 33 | "NFS, VREALIZE, ISCSI, EDGE_INFRA_OVERLAY_UPLINK", 34 | ValidateFunc: validation.StringInSlice([]string{ 35 | "VSAN", "VMOTION", "MANAGEMENT", "PUBLIC", "NFS", "VREALIZE", "ISCSI", "EDGE_INFRA_OVERLAY_UPLINK", 36 | }, true), 37 | DiffSuppressFunc: func(k, oldValue, newValue string, d *schema.ResourceData) bool { 38 | return oldValue == strings.ToUpper(newValue) || strings.ToUpper(oldValue) == newValue 39 | }, 40 | }, 41 | "active_uplinks": { 42 | Type: schema.TypeList, 43 | Optional: true, 44 | Description: "List of active uplinks associated with portgroup. This is only supported for VxRail.", 45 | Elem: &schema.Schema{Type: schema.TypeString}, 46 | }, 47 | }, 48 | } 49 | } 50 | 51 | func tryConvertToPortgroupSpec(object map[string]interface{}) (*vcf.PortgroupSpec, error) { 52 | result := &vcf.PortgroupSpec{} 53 | if object == nil { 54 | return nil, fmt.Errorf("cannot convert to PortgroupSpec, object is nil") 55 | } 56 | name := object["name"].(string) 57 | if len(name) == 0 { 58 | return nil, fmt.Errorf("cannot convert to PortgroupSpec, name is required") 59 | } 60 | result.Name = name 61 | if transportType, ok := object["transport_type"]; ok && !validationutils.IsEmpty(transportType) { 62 | transportTypeString := transportType.(string) 63 | result.TransportType = transportTypeString 64 | } 65 | if activeUplinks, ok := object["active_uplinks"].([]string); ok && !validationutils.IsEmpty(activeUplinks) { 66 | result.ActiveUplinks = &activeUplinks 67 | } 68 | 69 | return result, nil 70 | } 71 | 72 | func flattenPortgroupSpec(spec vcf.PortgroupSpec) map[string]interface{} { 73 | result := make(map[string]interface{}) 74 | result["name"] = spec.Name 75 | result["transport_type"] = spec.TransportType 76 | result["active_uplinks"] = spec.ActiveUplinks 77 | 78 | return result 79 | } 80 | -------------------------------------------------------------------------------- /internal/sddc/sddc_manager_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package sddc 6 | 7 | import ( 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 10 | "github.com/vmware/vcf-sdk-go/installer" 11 | 12 | validation_utils "github.com/vmware/terraform-provider-vcf/internal/validation" 13 | ) 14 | 15 | func GetSddcManagerSchema() *schema.Schema { 16 | sddcManagerSchema := &schema.Schema{ 17 | Type: schema.TypeList, 18 | MaxItems: 1, 19 | Optional: true, 20 | Elem: &schema.Resource{ 21 | Schema: map[string]*schema.Schema{ 22 | "hostname": { 23 | Type: schema.TypeString, 24 | Description: "SDDC Manager Hostname. If just the short hostname is provided, then FQDN will be generated using the \"domain\" from dns configuration, length 3-63", 25 | Optional: true, 26 | ValidateFunc: validation.StringLenBetween(3, 63), 27 | }, 28 | "local_user_password": { 29 | Type: schema.TypeString, 30 | Description: "The local account is a built-in admin account (password for the break glass user admin@local) in VCF that can be used in emergency scenarios. The password of this account must be at least 12 characters long. It also must contain at-least 1 uppercase, 1 lowercase, 1 special character specified in braces [!%@$^#?] and 1 digit. In addition, a character cannot be repeated more than 3 times consecutively.", 31 | Optional: true, 32 | ValidateFunc: validation_utils.ValidatePassword, 33 | }, 34 | "root_user_password": { 35 | Type: schema.TypeString, 36 | Description: "The password for the root user", 37 | Required: true, 38 | ValidateFunc: validation_utils.ValidatePassword, 39 | }, 40 | "ssh_password": { 41 | Type: schema.TypeString, 42 | Description: "The password for the vcf user (ssh connections only)", 43 | Required: true, 44 | ValidateFunc: validation_utils.ValidatePassword, 45 | }, 46 | }, 47 | }, 48 | } 49 | 50 | return sddcManagerSchema 51 | } 52 | 53 | func GetSddcManagerSpecFromSchema(rawData []interface{}) *installer.SddcManagerSpec { 54 | if len(rawData) <= 0 { 55 | return nil 56 | } 57 | data := rawData[0].(map[string]interface{}) 58 | hostname := data["hostname"].(string) 59 | localUserPassword := data["local_user_password"].(string) 60 | rootUserPassword := data["root_user_password"].(string) 61 | sshPassword := data["ssh_password"].(string) 62 | 63 | sddcManagerSpec := &installer.SddcManagerSpec{ 64 | Hostname: hostname, 65 | } 66 | 67 | if localUserPassword != "" { 68 | sddcManagerSpec.LocalUserPassword = &localUserPassword 69 | } 70 | 71 | if rootUserPassword != "" { 72 | sddcManagerSpec.RootPassword = &rootUserPassword 73 | } 74 | 75 | if sshPassword != "" { 76 | sddcManagerSpec.SshPassword = &sshPassword 77 | } 78 | 79 | return sddcManagerSpec 80 | } 81 | -------------------------------------------------------------------------------- /examples/resources/edge_cluster/vcf_edge_cluster.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | provider "vcf" { 10 | sddc_manager_username = var.sddc_manager_username 11 | sddc_manager_password = var.sddc_manager_password 12 | sddc_manager_host = var.sddc_manager_host 13 | } 14 | 15 | resource "vcf_edge_cluster" "cluster_1" { 16 | name = var.cluster_name 17 | root_password = var.cluster_root_pass 18 | admin_password = var.cluster_admin_pass 19 | audit_password = var.cluster_audit_pass 20 | tier0_name = "T0_cluster_1" 21 | tier1_name = "T1_cluster_1" 22 | form_factor = "MEDIUM" 23 | profile_type = "DEFAULT" 24 | routing_type = "EBGP" 25 | high_availability = "ACTIVE_ACTIVE" 26 | mtu = 9000 27 | asn = "65004" 28 | 29 | edge_node { 30 | name = var.edge_node_1_name 31 | compute_cluster_id = var.compute_cluster_id 32 | root_password = var.edge_node_1_root_pass 33 | admin_password = var.edge_node_1_admin_pass 34 | audit_password = var.edge_node_1_audit_pass 35 | management_ip = "10.0.0.52/24" 36 | management_gateway = "10.0.0.250" 37 | tep_gateway = "192.168.52.1" 38 | tep1_ip = "192.168.52.12/24" 39 | tep2_ip = "192.168.52.13/24" 40 | tep_vlan = 1252 41 | inter_rack_cluster = false 42 | 43 | uplink { 44 | vlan = 2083 45 | interface_ip = "192.168.18.2/24" 46 | bgp_peer { 47 | ip = "192.168.18.10/24" 48 | password = "VMware1!" 49 | asn = "65001" 50 | } 51 | } 52 | 53 | uplink { 54 | vlan = 2084 55 | interface_ip = "192.168.19.2/24" 56 | bgp_peer { 57 | ip = "192.168.19.10/24" 58 | password = "VMware1!" 59 | asn = "65001" 60 | } 61 | } 62 | } 63 | 64 | edge_node { 65 | name = var.edge_node_2_name 66 | compute_cluster_id = var.compute_cluster_id 67 | root_password = var.edge_node_2_root_pass 68 | admin_password = var.edge_node_2_admin_pass 69 | audit_password = var.edge_node_2_audit_pass 70 | management_ip = "10.0.0.53/24" 71 | management_gateway = "10.0.0.250" 72 | tep_gateway = "192.168.52.1" 73 | tep1_ip = "192.168.52.14/24" 74 | tep2_ip = "192.168.52.15/24" 75 | tep_vlan = 1252 76 | inter_rack_cluster = false 77 | 78 | uplink { 79 | vlan = 2083 80 | interface_ip = "192.168.18.3/24" 81 | bgp_peer { 82 | ip = "192.168.18.10/24" 83 | password = "VMware1!" 84 | asn = "65001" 85 | } 86 | } 87 | 88 | uplink { 89 | vlan = 2084 90 | interface_ip = "192.168.19.3/24" 91 | bgp_peer { 92 | ip = "192.168.19.10/24" 93 | password = "VMware1!" 94 | asn = "65001" 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /internal/sddc/sddc_security_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package sddc 6 | 7 | import ( 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 10 | utils "github.com/vmware/terraform-provider-vcf/internal/resource_utils" 11 | "github.com/vmware/vcf-sdk-go/installer" 12 | ) 13 | 14 | var esxiCertsModes = []string{"Custom", "VMCA"} 15 | 16 | func GetSecuritySchema() *schema.Schema { 17 | return &schema.Schema{ 18 | Type: schema.TypeList, 19 | MaxItems: 1, 20 | Optional: true, 21 | Elem: &schema.Resource{ 22 | Schema: map[string]*schema.Schema{ 23 | "esxi_certs_mode": { 24 | Type: schema.TypeString, 25 | Description: "ESXi certificates mode. One among: Custom, VMCA", 26 | Optional: true, 27 | ValidateFunc: validation.StringInSlice(esxiCertsModes, false), 28 | }, 29 | "root_ca_certs": getRootCaCertsSchema(), 30 | }, 31 | }, 32 | } 33 | } 34 | 35 | func getRootCaCertsSchema() *schema.Schema { 36 | return &schema.Schema{ 37 | Type: schema.TypeList, 38 | Description: "Root Certificate Authority certificate list", 39 | Optional: true, 40 | Elem: &schema.Resource{ 41 | Schema: map[string]*schema.Schema{ 42 | "alias": { 43 | Type: schema.TypeString, 44 | Description: "Certificate alias", 45 | Optional: true, 46 | }, 47 | "cert_chain": { 48 | Type: schema.TypeList, 49 | Description: "List of Base64 encoded certificates", 50 | Optional: true, 51 | Elem: &schema.Schema{ 52 | Type: schema.TypeString, 53 | }, 54 | }, 55 | }, 56 | }, 57 | } 58 | } 59 | 60 | func GetSecuritySpecSchema(rawData []interface{}) *installer.SecuritySpec { 61 | if len(rawData) <= 0 { 62 | return nil 63 | } 64 | data := rawData[0].(map[string]interface{}) 65 | esxiCertsMode := data["esxi_certs_mode"].(string) 66 | 67 | securitySpecBinding := &installer.SecuritySpec{ 68 | EsxiCertsMode: &esxiCertsMode, 69 | } 70 | if rootCaCerts := getRootCaCertsBindingFromSchema(data["root_ca_certs"].([]interface{})); len(rootCaCerts) > 0 { 71 | securitySpecBinding.RootCaCerts = &rootCaCerts 72 | } 73 | 74 | return securitySpecBinding 75 | } 76 | 77 | func getRootCaCertsBindingFromSchema(rawData []interface{}) []installer.RootCaCerts { 78 | var rootCaCertsBindingsList []installer.RootCaCerts 79 | for _, rootCaCerts := range rawData { 80 | data := rootCaCerts.(map[string]interface{}) 81 | alias := data["alias"].(string) 82 | 83 | rootCaCertsBinding := installer.RootCaCerts{ 84 | Alias: &alias, 85 | } 86 | if certChain, ok := data["cert_chain"].([]interface{}); ok { 87 | certChainSlice := utils.ToStringSlice(certChain) 88 | rootCaCertsBinding.CertChain = &certChainSlice 89 | } 90 | 91 | rootCaCertsBindingsList = append(rootCaCertsBindingsList, rootCaCertsBinding) 92 | } 93 | return rootCaCertsBindingsList 94 | } 95 | -------------------------------------------------------------------------------- /internal/sddc/sddc_vcf_automation_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package sddc 6 | 7 | import ( 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | utils "github.com/vmware/terraform-provider-vcf/internal/resource_utils" 10 | "github.com/vmware/vcf-sdk-go/installer" 11 | ) 12 | 13 | func GetVcfAutomationSchema() *schema.Schema { 14 | return &schema.Schema{ 15 | Type: schema.TypeList, 16 | Optional: true, 17 | MaxItems: 1, 18 | Elem: &schema.Resource{ 19 | Schema: map[string]*schema.Schema{ 20 | "hostname": { 21 | Type: schema.TypeString, 22 | Description: "Host name for the automation appliance", 23 | Required: true, 24 | }, 25 | "admin_user_password": { 26 | Type: schema.TypeString, 27 | Description: "Administrator password", 28 | Optional: true, 29 | Sensitive: true, 30 | }, 31 | "internal_cluster_cidr": { 32 | Type: schema.TypeString, 33 | Description: "Internal Cluster CIDR. One among: 198.18.0.0/15, 240.0.0.0/15, 250.0.0.0/15", 34 | Required: true, 35 | }, 36 | "node_prefix": { 37 | Type: schema.TypeString, 38 | Description: "Node Prefix. It cannot be blank and must begin and end with an alphanumeric character, and can only contain lowercase alphanumeric characters or hyphens.", 39 | Optional: true, 40 | }, 41 | "ip_pool": { 42 | Type: schema.TypeList, 43 | Description: "List of IP addresses. For Standard deployment model two IP addresses need to be specified and for High Availability four IP addresses need to be specified", 44 | Required: true, 45 | Elem: &schema.Schema{ 46 | Type: schema.TypeString, 47 | }, 48 | }, 49 | }, 50 | }, 51 | } 52 | } 53 | 54 | func GetVcfAutomationSpecFromSchema(rawData []interface{}) *installer.VcfAutomationSpec { 55 | if len(rawData) <= 0 { 56 | return nil 57 | } 58 | data := rawData[0].(map[string]interface{}) 59 | 60 | var adminPassword *string 61 | if data["admin_user_password"].(string) != "" { 62 | adminPassword = utils.ToPointer[string](data["admin_user_password"]) 63 | } 64 | 65 | var nodePrefix *string 66 | if data["node_prefix"].(string) != "" { 67 | nodePrefix = utils.ToPointer[string](data["node_prefix"]) 68 | } 69 | 70 | var internalClusterCidr *string 71 | if data["internal_cluster_cidr"].(string) != "" { 72 | internalClusterCidr = utils.ToPointer[string](data["internal_cluster_cidr"]) 73 | } 74 | 75 | var ipPools *[]string 76 | if data["ip_pool"] != nil && len(data["ip_pool"].([]interface{})) > 0 { 77 | ipPools = utils.ToPointer[[]string](utils.ToStringSlice(data["ip_pool"].([]interface{}))) 78 | } 79 | 80 | spec := &installer.VcfAutomationSpec{ 81 | AdminUserPassword: adminPassword, 82 | Hostname: data["hostname"].(string), 83 | InternalClusterCidr: internalClusterCidr, 84 | IpPool: ipPools, 85 | NodePrefix: nodePrefix, 86 | } 87 | return spec 88 | } 89 | -------------------------------------------------------------------------------- /internal/provider/data_source_cluster.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package provider 6 | 7 | import ( 8 | "context" 9 | "time" 10 | 11 | "github.com/hashicorp/terraform-plugin-sdk/v2/diag" 12 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 13 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 14 | 15 | "github.com/vmware/terraform-provider-vcf/internal/api_client" 16 | "github.com/vmware/terraform-provider-vcf/internal/cluster" 17 | "github.com/vmware/terraform-provider-vcf/internal/network" 18 | ) 19 | 20 | func DataSourceCluster() *schema.Resource { 21 | return &schema.Resource{ 22 | ReadContext: dataSourceClusterRead, 23 | Timeouts: &schema.ResourceTimeout{ 24 | Read: schema.DefaultTimeout(20 * time.Minute), 25 | }, 26 | Schema: map[string]*schema.Schema{ 27 | "cluster_id": { 28 | Type: schema.TypeString, 29 | Required: true, 30 | ValidateFunc: validation.NoZeroValues, 31 | Description: "The ID of the Cluster to be used as data source", 32 | }, 33 | "name": { 34 | Type: schema.TypeString, 35 | Computed: true, 36 | Description: "Name of the domain", 37 | }, 38 | "domain_id": { 39 | Type: schema.TypeString, 40 | Computed: true, 41 | Description: "The ID of a workload domain that the cluster belongs to", 42 | }, 43 | "domain_name": { 44 | Type: schema.TypeString, 45 | Computed: true, 46 | Description: "The name of a workload domain that the cluster belongs to", 47 | }, 48 | "host": { 49 | Type: schema.TypeList, 50 | Computed: true, 51 | Description: "List of ESXi host information present in the Cluster", 52 | Elem: cluster.HostSpecSchema(), 53 | }, 54 | "vds": { 55 | Type: schema.TypeList, 56 | Computed: true, 57 | Description: "vSphere Distributed Switches to add to the Cluster", 58 | Elem: network.VdsSchema(), 59 | }, 60 | "primary_datastore_name": { 61 | Type: schema.TypeString, 62 | Computed: true, 63 | Description: "Name of the primary datastore", 64 | }, 65 | "primary_datastore_type": { 66 | Type: schema.TypeString, 67 | Computed: true, 68 | Description: "Storage type of the primary datastore", 69 | }, 70 | "is_default": { 71 | Type: schema.TypeBool, 72 | Computed: true, 73 | Description: "Status of the cluster if default or not", 74 | }, 75 | "is_stretched": { 76 | Type: schema.TypeBool, 77 | Computed: true, 78 | Description: "Status of the cluster if stretched or not", 79 | }, 80 | }, 81 | } 82 | } 83 | 84 | func dataSourceClusterRead(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics { 85 | apiClient := meta.(*api_client.SddcManagerClient).ApiClient 86 | clusterId := data.Get("cluster_id").(string) 87 | _, err := cluster.ImportCluster(ctx, data, apiClient, clusterId) 88 | if err != nil { 89 | return diag.FromErr(err) 90 | } 91 | return nil 92 | } 93 | -------------------------------------------------------------------------------- /docs/resources/host.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "vcf_host Resource - terraform-provider-vcf" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # vcf_host (Resource) 10 | 11 | Prerequisites for commissioning Hosts 12 | 13 | - The following data is required: 14 | 15 | - Username of each host 16 | - Password of each host 17 | - FQDN of each host 18 | - Network pool ID to which each host has to be associated with 19 | 20 | - The host, if intended to be used for a vSAN domain, should be vSAN compliant and certified as per the VMware Hardware Compatibility Guide. 21 | BIOS, HBA, SSD, HDD, etc. of the host must match the VMware Hardware Compatibility Guide. 22 | - The host must have the drivers and firmware versions specified in the VMware Hardware Compatibility Guide. 23 | - The host must have the supported version of ESXi (i.e 6.7.0-13006603) pre-installed on it. 24 | - SSH and syslog must be enabled on the host. 25 | - The host must be configured with DNS server for forward and reverse lookup and FQDN. 26 | - The host name must be same as the FQDN. 27 | - The host must have a standard switch with two NIC ports with a minimum 10 Gbps speed. 28 | - The management IP must be configured to the first NIC port. 29 | - Ensure that the host has a standard switch and the default uplinks with 10Gb speed are configured starting with traditional numbering (e.g., vmnic0) and increasing sequentially. 30 | - Ensure that the host hardware health status is healthy without any errors. 31 | - All disk partitions on HDD / SSD are deleted. 32 | - The hosts, if intended to be used for vSAN, domain must be associated with vSAN enabled network pool. 33 | - The hosts, if intended to be used for NFS, domain must be associated with NFS enabled network pool. 34 | - The hosts, if intended to be used for VMFS on FC, domain must be associated with either a NFS enabled or vMotion enabled network pool. 35 | - The hosts, if intended to be used for VVOL, domain must be associated with either a NFS enabled or vMotion enabled network pool. 36 | - The hosts, if intended to be used for vSAN HCI Mesh(VSAN_REMOTE), domain must be associated with vSAN enabled network pool. 37 | 38 | 39 | ## Schema 40 | 41 | ### Required 42 | 43 | - `fqdn` (String) Fully qualified domain name of ESXi host 44 | - `password` (String, Sensitive) Password to authenticate to the ESXi host 45 | - `storage_type` (String) Storage Type. One among: VSAN, VSAN_ESA, VSAN_REMOTE, NFS, VMFS_FC, VVOL 46 | - `username` (String) Username to authenticate to the ESXi host 47 | 48 | ### Optional 49 | 50 | - `network_pool_id` (String) ID of the network pool to associate the ESXi host with 51 | - `network_pool_name` (String) Name of the network pool to associate the ESXi host with 52 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 53 | 54 | ### Read-Only 55 | 56 | - `id` (String) The ID of this resource. 57 | - `status` (String) Assignable status of the host. 58 | 59 | 60 | ### Nested Schema for `timeouts` 61 | 62 | Optional: 63 | 64 | - `create` (String) 65 | - `delete` (String) 66 | -------------------------------------------------------------------------------- /internal/sddc/sddc_vcenter_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package sddc 6 | 7 | import ( 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 10 | validation_utils "github.com/vmware/terraform-provider-vcf/internal/validation" 11 | "github.com/vmware/vcf-sdk-go/installer" 12 | ) 13 | 14 | var vmSizeValues = []string{"tiny", "small", "medium", "large", "xlarge"} 15 | var storageSizes = []string{"lstorage", "xlstorage"} 16 | 17 | func GetVcenterSchema() *schema.Schema { 18 | return &schema.Schema{ 19 | Type: schema.TypeList, 20 | Required: true, 21 | MaxItems: 1, 22 | Elem: &schema.Resource{ 23 | Schema: map[string]*schema.Schema{ 24 | "root_vcenter_password": { 25 | Type: schema.TypeString, 26 | Description: "vCenter root password. The password must be between 8 characters and 20 characters long. It must also contain at least one uppercase and lowercase letter, one number, and one character from '! \" # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \\ ] ^ _ ` { Ι } ~' and all characters must be ASCII. Space is not allowed in password.", 27 | Required: true, 28 | Sensitive: true, 29 | ValidateFunc: validation_utils.ValidatePassword, 30 | }, 31 | "ssl_thumbprint": { 32 | Type: schema.TypeString, 33 | Description: "vCenter Server SSL thumbprint (SHA256)", 34 | Optional: true, 35 | }, 36 | "storage_size": { 37 | Type: schema.TypeString, 38 | Description: "vCenter VM storage size. One among:lstorage, xlstorage", 39 | Optional: true, 40 | ValidateFunc: validation.StringInSlice(storageSizes, false), 41 | }, 42 | "vcenter_hostname": { 43 | Type: schema.TypeString, 44 | Description: "vCenter Server hostname address. If just the short hostname is provided, then FQDN will be generated using the \"domain\" from dns configuration", 45 | Required: true, 46 | }, 47 | "vm_size": { 48 | Type: schema.TypeString, 49 | Description: "vCenter Server Appliance size. One among: tiny, small, medium, large, xlarge", 50 | Optional: true, 51 | ValidateFunc: validation.StringInSlice(vmSizeValues, false), 52 | }, 53 | }, 54 | }, 55 | } 56 | } 57 | 58 | func GetVcenterSpecFromSchema(rawData []interface{}) *installer.SddcVcenterSpec { 59 | if len(rawData) <= 0 { 60 | return nil 61 | } 62 | data := rawData[0].(map[string]interface{}) 63 | rootVcenterPassword := data["root_vcenter_password"].(string) 64 | sslThumbprint := data["ssl_thumbprint"].(string) 65 | storageSize := data["storage_size"].(string) 66 | vcenterHostname := data["vcenter_hostname"].(string) 67 | vmSize := data["vm_size"].(string) 68 | 69 | vcenterSpecBinding := &installer.SddcVcenterSpec{ 70 | RootVcenterPassword: rootVcenterPassword, 71 | SslThumbprint: &sslThumbprint, 72 | StorageSize: &storageSize, 73 | VcenterHostname: vcenterHostname, 74 | VmSize: &vmSize, 75 | } 76 | return vcenterSpecBinding 77 | } 78 | -------------------------------------------------------------------------------- /internal/datastores/vsan_datastore_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package datastores 6 | 7 | import ( 8 | "fmt" 9 | 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 12 | utils "github.com/vmware/terraform-provider-vcf/internal/resource_utils" 13 | "github.com/vmware/vcf-sdk-go/vcf" 14 | 15 | validationutils "github.com/vmware/terraform-provider-vcf/internal/validation" 16 | ) 17 | 18 | // VsanDatastoreSchema this helper function extracts the vSAN Datastore schema, so that 19 | // it's made available for both workload domain and cluster creation. 20 | func VsanDatastoreSchema() *schema.Resource { 21 | return &schema.Resource{ 22 | Schema: map[string]*schema.Schema{ 23 | "datastore_name": { 24 | Type: schema.TypeString, 25 | Required: true, 26 | Description: "vSAN datastore name used for cluster creation", 27 | ValidateFunc: validation.NoZeroValues, 28 | }, 29 | "failures_to_tolerate": { 30 | Type: schema.TypeInt, 31 | Optional: true, 32 | Description: "Number of ESXi host failures to tolerate in the vSAN cluster. One of 1 or 2.", 33 | ValidateFunc: validation.IntBetween(1, 2), 34 | }, 35 | "dedup_and_compression_enabled": { 36 | Type: schema.TypeBool, 37 | Optional: true, 38 | Description: "Enable vSAN deduplication and compression", 39 | }, 40 | "esa_enabled": { 41 | Type: schema.TypeBool, 42 | Optional: true, 43 | Description: "Enable vSAN ESA", 44 | }, 45 | }, 46 | } 47 | } 48 | 49 | func TryConvertToVsanDatastoreSpec(object map[string]interface{}) (*vcf.VsanDatastoreSpec, error) { 50 | if object == nil { 51 | return nil, fmt.Errorf("cannot convert to VSANDatastoreSpec, object is nil") 52 | } 53 | datastoreName := object["datastore_name"].(string) 54 | if len(datastoreName) == 0 { 55 | return nil, fmt.Errorf("cannot convert to VSANDatastoreSpec, datastore_name is required") 56 | } 57 | result := &vcf.VsanDatastoreSpec{} 58 | result.DatastoreName = datastoreName 59 | if dedupAndCompressionEnabled, ok := object["dedup_and_compression_enabled"]; ok && !validationutils.IsEmpty(dedupAndCompressionEnabled) { 60 | result.DedupAndCompressionEnabled = utils.ToBoolPointer(dedupAndCompressionEnabled) 61 | } 62 | if esaEnabled, ok := object["esa_enabled"]; ok && !validationutils.IsEmpty(esaEnabled) { 63 | value := esaEnabled.(bool) 64 | esaConfig := vcf.EsaConfig{Enabled: value} 65 | result.EsaConfig = &esaConfig 66 | } 67 | // FIX: Only set FailuresToTolerate if explicitly provided AND > 0 68 | if failuresToTolerate, exists := object["failures_to_tolerate"]; exists { 69 | if !validationutils.IsEmpty(failuresToTolerate) { 70 | failuresToTolerateInt := int32(failuresToTolerate.(int)) 71 | if failuresToTolerateInt > 0 { 72 | result.FailuresToTolerate = &failuresToTolerateInt 73 | } 74 | // If failuresToTolerateInt == 0, don't set it (leave as nil) 75 | } 76 | } 77 | // If key doesn't exist at all, FailuresToTolerate remains nil 78 | 79 | return result, nil 80 | } 81 | -------------------------------------------------------------------------------- /internal/credentials/credential_data_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package credentials 6 | 7 | import ( 8 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 9 | ) 10 | 11 | func CredentialDataSubresource() *schema.Resource { 12 | return &schema.Resource{ 13 | Schema: map[string]*schema.Schema{ 14 | "id": { 15 | Type: schema.TypeString, 16 | Description: "The ID hash of the credential", 17 | Required: true, 18 | }, 19 | "user_name": { 20 | Type: schema.TypeString, 21 | Description: "The username of the account to which the credential belong", 22 | Required: true, 23 | }, 24 | "password": { 25 | Type: schema.TypeString, 26 | Description: "The password of the account to which the credential belong", 27 | Computed: true, 28 | }, 29 | "account_type": { 30 | Type: schema.TypeString, 31 | Computed: true, 32 | Description: "One among USER, SYSTEM, SERVICE", 33 | }, 34 | "credential_type": { 35 | Type: schema.TypeString, 36 | Computed: true, 37 | Description: "The type of the credential. For example FTP, SSH, etc.", 38 | }, 39 | "auto_rotate_frequency_days": { 40 | Type: schema.TypeInt, 41 | Computed: true, 42 | Description: "After how many days the credentials will be auto rotated. One among 30, 60, 90", 43 | }, 44 | "auto_rotate_next_schedule": { 45 | Type: schema.TypeString, 46 | Computed: true, 47 | Description: "The time of the next rotation", 48 | }, 49 | "creation_time": { 50 | Type: schema.TypeString, 51 | Computed: true, 52 | Description: "The time when the credential is created", 53 | }, 54 | "modification_time": { 55 | Type: schema.TypeString, 56 | Computed: true, 57 | Description: "The last time the credentials are changed", 58 | }, 59 | "resource": { 60 | Type: schema.TypeList, 61 | Computed: true, 62 | Elem: &schema.Resource{ 63 | Schema: map[string]*schema.Schema{ 64 | "id": { 65 | Type: schema.TypeString, 66 | Computed: true, 67 | Description: "The ID hash of the resource to which the credential belongs", 68 | }, 69 | "domain": { 70 | Type: schema.TypeString, 71 | Computed: true, 72 | Description: "The VCF domain to which the resource belongs", 73 | }, 74 | "ip": { 75 | Type: schema.TypeString, 76 | Computed: true, 77 | Description: "The ip address of the resource related to the credential", 78 | }, 79 | "name": { 80 | Type: schema.TypeString, 81 | Computed: true, 82 | Description: "The name of the resource as registered in SDDC Manager inventory", 83 | }, 84 | "type": { 85 | Type: schema.TypeString, 86 | Computed: true, 87 | Description: "The type of the resource.One among ESXI, VCENTER, PSC, NSX_MANAGER, NSX_CONTROLLER, NSXT_EDGE, NSXT_MANAGER, VRLI, VROPS, VRA, WSA, VRSLCM, VXRAIL_MANAGER, NSX_ALB, BACKUP", 88 | }, 89 | }, 90 | }, 91 | }, 92 | }, 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /examples/workflows/private-ai-foundation/steps/02/variables.tf: -------------------------------------------------------------------------------- 1 | variable "vcenter_username" { 2 | description = "Username used to authenticate against the vCenter Server" 3 | } 4 | 5 | variable "vcenter_password" { 6 | description = "Password used to authenticate against the vCenter Server" 7 | } 8 | 9 | variable "vcenter_server" { 10 | description = "FQDN or IP Address of the vCenter Server for the management domain" 11 | } 12 | 13 | variable "datacenter_name" { 14 | description = "The name of the datacenter" 15 | } 16 | 17 | variable "source_cluster_name" { 18 | description = "The name of the compute cluster" 19 | } 20 | 21 | variable "sddc_manager_username" { 22 | description = "Username used to authenticate against an SDDC Manager instance" 23 | } 24 | 25 | variable "sddc_manager_password" { 26 | description = "Password used to authenticate against an SDDC Manager instance" 27 | } 28 | 29 | variable "sddc_manager_host" { 30 | description = "FQDN or IP Address of an SDDC Manager instance" 31 | } 32 | 33 | variable "vcenter_root_password" { 34 | description = "root password for the vCenter Server Appliance (8-20 characters)" 35 | } 36 | 37 | variable "nsx_manager_admin_password" { 38 | description = "NSX Manager admin user password" 39 | } 40 | 41 | variable "esx_host1_fqdn" { 42 | description = "Fully qualified domain name of ESXi host 1" 43 | } 44 | 45 | variable "esx_host1_pass" { 46 | description = "Password to authenticate to the ESXi host 1" 47 | } 48 | 49 | variable "esx_host2_fqdn" { 50 | description = "Fully qualified domain name of ESXi host 2" 51 | } 52 | 53 | variable "esx_host2_pass" { 54 | description = "Password to authenticate to the ESXi host 2" 55 | } 56 | 57 | variable "esx_host3_fqdn" { 58 | description = "Fully qualified domain name of ESXi host 3" 59 | } 60 | 61 | variable "esx_host3_pass" { 62 | description = "Password to authenticate to the ESXi host 3" 63 | } 64 | 65 | variable "nsx_license_key" { 66 | description = "NSX license to be used" 67 | } 68 | 69 | variable "esx_license_key" { 70 | description = "License key for an ESXi host in the free pool." 71 | } 72 | 73 | variable "vsan_license_key" { 74 | description = "vSAN license key to be used" 75 | } 76 | 77 | variable "workload_domain_name" { 78 | description = "The name for the new workload domain" 79 | } 80 | 81 | variable "management_domain_id" { 82 | description = "The identifier off the management domain" 83 | } 84 | 85 | variable "workload_vcenter_address" { 86 | description = "The IP address for the vCenter Server in the new workload domain" 87 | } 88 | 89 | variable "workload_vcenter_fqdn" { 90 | description = "The fully qualified domain name for the vCenter Server in the new workload domain" 91 | } 92 | 93 | variable "nsx_manager_node1_address" { 94 | description = "The IP address for the first NSX Manager node" 95 | } 96 | 97 | variable "nsx_manager_node2_address" { 98 | description = "The IP address for the second NSX Manager node" 99 | } 100 | 101 | variable "nsx_manager_node3_address" { 102 | description = "The IP address for the third NSX Manager node" 103 | } 104 | 105 | variable "nsx_manager_vip_address" { 106 | description = "The virtual IP for the NSX Manager" 107 | } -------------------------------------------------------------------------------- /internal/network/nsx_manager_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package network 6 | 7 | import ( 8 | "fmt" 9 | 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 12 | "github.com/vmware/terraform-provider-vcf/internal/resource_utils" 13 | "github.com/vmware/vcf-sdk-go/vcf" 14 | 15 | validationutils "github.com/vmware/terraform-provider-vcf/internal/validation" 16 | ) 17 | 18 | // NsxManagerNodeSchema this helper function extracts the NSX Manager Node schema, which contains 19 | // the parameters required to install and configure NSX Manager in a workload domain. 20 | func NsxManagerNodeSchema() *schema.Resource { 21 | return &schema.Resource{ 22 | Schema: map[string]*schema.Schema{ 23 | "name": { 24 | Type: schema.TypeString, 25 | Required: true, 26 | Description: "Name of the NSX Manager appliance, e.g., sfo-w01-nsx01 ", 27 | ValidateFunc: validation.NoZeroValues, 28 | }, 29 | "ip_address": { 30 | Type: schema.TypeString, 31 | Required: true, 32 | Description: "IPv4 address of the NSX Manager appliance", 33 | ValidateFunc: validationutils.ValidateIPv4AddressSchema, 34 | }, 35 | "fqdn": { 36 | Type: schema.TypeString, 37 | Required: true, 38 | Description: "Fully qualified domain name of the NSX Manager appliance, e.g., sfo-w01-nsx01a.sfo.rainpole.io", 39 | ValidateFunc: validation.NoZeroValues, 40 | }, 41 | "subnet_mask": { 42 | Type: schema.TypeString, 43 | Required: true, 44 | Description: "IPv4 subnet mask for the NSX Manager appliance", 45 | ValidateFunc: validationutils.ValidateIPv4AddressSchema, 46 | }, 47 | "gateway": { 48 | Type: schema.TypeString, 49 | Required: true, 50 | Description: "IPv4 gateway the NSX Manager appliance", 51 | ValidateFunc: validationutils.ValidateIPv4AddressSchema, 52 | }, 53 | }, 54 | } 55 | } 56 | 57 | func TryConvertToNsxManagerNodeSpec(object map[string]interface{}) (vcf.NsxManagerSpec, error) { 58 | result := vcf.NsxManagerSpec{} 59 | if object == nil { 60 | return result, fmt.Errorf("cannot convert to NsxManagerSpec, object is nil") 61 | } 62 | name := object["name"].(string) 63 | if len(name) == 0 { 64 | return result, fmt.Errorf("cannot convert to NsxManagerSpec, name is required") 65 | } 66 | ipAddress := object["ip_address"].(string) 67 | if len(ipAddress) == 0 { 68 | return result, fmt.Errorf("cannot convert to NsxManagerSpec, ip_address is required") 69 | } 70 | result.Name = &name 71 | result.NetworkDetailsSpec = vcf.NetworkDetailsSpec{ 72 | IpAddress: &ipAddress, 73 | } 74 | if fqdn, ok := object["fqdn"]; ok && !validationutils.IsEmpty(fqdn) { 75 | result.NetworkDetailsSpec.DnsName = fqdn.(string) 76 | } 77 | if subnetMask, ok := object["subnet_mask"]; ok && !validationutils.IsEmpty(subnetMask) { 78 | result.NetworkDetailsSpec.SubnetMask = resource_utils.ToStringPointer(subnetMask) 79 | } 80 | if gateway, ok := object["gateway"]; ok && !validationutils.IsEmpty(gateway) { 81 | result.NetworkDetailsSpec.Gateway = resource_utils.ToStringPointer(gateway) 82 | } 83 | return result, nil 84 | } 85 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | page_title: "Terraform Provider for VMware Cloud Foundation" 3 | subcategory: "" 4 | description: |- 5 | --- 6 | 7 | VMware Cloud Foundation 8 | 9 | # Terraform Provider for VMware Cloud Foundation 10 | 11 | The following table lists the supported platforms for this provider. 12 | 13 | | Platform | Support | 14 | |-------------------------------|-----------------------| 15 | | VMware Cloud Foundation 9.0.0 | `≥ v0.17.0` | 16 | | VMware Cloud Foundation 5.2.1 | `≥ v0.13.0 < v0.17.0` | 17 | | VMware Cloud Foundation 5.2.0 | `≥ v0.12.0` | 18 | | VMware Cloud Foundation 5.1+ | `≥ v0.9.0` | 19 | | VMware Cloud Foundation 5.0 | `≥ v0.9.0` | 20 | | VMware Cloud Foundation 4.5 | `≤ v0.8.0` | 21 | | VMware Cloud Foundation 4.4 | `≤ v0.8.0` | 22 | 23 | [^1]: VMware Cloud Foundation on Dell VxRAIL is **not supported** by this provider. 24 | 25 | The plugin supports versions in accordance with the 26 | [Broadcom Product Lifecycle][product-lifecycle]. [^1] 27 | 28 | See the VMware Cloud Foundation 29 | [release notes](https://docs.vmware.com/en/VMware-Cloud-Foundation/) for the 30 | individual build numbers. 31 | 32 | [product-lifecycle]: https://support.broadcom.com/group/ecx/productlifecycle 33 | 34 | ## Example Usage 35 | 36 | ```hcl 37 | terraform { 38 | required_providers { 39 | vcf = { 40 | source = "vmware/vcf" 41 | version = "x.y.z" 42 | } 43 | } 44 | } 45 | 46 | provider "vcf" { 47 | sddc_manager_host = var.sddc_manager_host 48 | sddc_manager_username = var.sddc_manager_username 49 | sddc_manager_password = var.sddc_manager_password 50 | allow_unverified_tls = var.allow_unverified_tls 51 | } 52 | ``` 53 | 54 | Refer to the provider documentation for information on all of the resources 55 | and data sources supported by this provider. Each includes a detailed 56 | description of the purpose and how to use it. 57 | 58 | ## Argument Reference 59 | 60 | The following arguments are used to configure the provider: 61 | 62 | - `sddc_manager_host` - (Optional) Fully qualified domain name or IP address of 63 | the SDDC Manager. 64 | - `sddc_manager_password` - (Optional) Password to authenticate to SDDC Manager. 65 | - `sddc_manager_username` - (Optional) Username to authenticate to SDDC Manager. 66 | - `installer_host` (String) The fully qualified domain name or IP address of the installer. 67 | - `installer_password` (String) The password to authenticate to the installer. 68 | - `installer_username` (String) The username to authenticate to the installer. 69 | - `allow_unverified_tls` (Boolean) If enabled, this allows the use of TLS 70 | certificates that cannot be verified. 71 | 72 | ## Enable Logging 73 | 74 | To enable logging for the provider, you can set the `TF_LOG_PROVIDER_VCF` 75 | environment variable. This will enable detailed logging for the provider during 76 | the Terraform run with task updates from the API. 77 | 78 | For example, set the environment variable for the provider: 79 | 80 | ```sh 81 | export TF_LOG_PROVIDER_VCF=INFO 82 | ``` 83 | 84 | For more information on enabling logging, refer to 85 | [the Terraform documentation](https://developer.hashicorp.com/terraform/plugin/log/managing). 86 | -------------------------------------------------------------------------------- /internal/resource_utils/resource_utils.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package resource_utils 6 | 7 | // ToPointer - Utility to obtain a pointer to any rvalue without having to declare a local variable. 8 | func ToPointer[T interface{}](object interface{}) *T { 9 | if object == nil { 10 | return nil 11 | } 12 | objectAsT := object.(T) 13 | return &objectAsT 14 | } 15 | 16 | func ToBoolPointer(object interface{}) *bool { 17 | if object == nil { 18 | return nil 19 | } 20 | objectAsBool := object.(bool) 21 | return &objectAsBool 22 | } 23 | 24 | func ToStringPointer(object interface{}) *string { 25 | if object == nil { 26 | return nil 27 | } 28 | objectAsString := object.(string) 29 | return &objectAsString 30 | } 31 | 32 | func ToInt32Pointer(object interface{}) *int32 { 33 | if object == nil { 34 | return nil 35 | } 36 | objectAsInt32 := int32(object.(int)) 37 | return &objectAsInt32 38 | } 39 | 40 | func ToIntPointer(object interface{}) *int { 41 | if object == nil { 42 | return nil 43 | } 44 | objectAsInt := object.(int) 45 | return &objectAsInt 46 | } 47 | 48 | func ToStringSlice(params []interface{}) []string { 49 | var paramSlice []string 50 | for _, p := range params { 51 | if param, ok := p.(string); ok { 52 | paramSlice = append(paramSlice, param) 53 | } 54 | } 55 | return paramSlice 56 | } 57 | 58 | // CreateIdToObjectMap Creates a Map with string ID index to Object. 59 | func CreateIdToObjectMap(objectsList []interface{}) map[string]interface{} { 60 | // crete a map of new host id -> host 61 | result := make(map[string]interface{}) 62 | for _, listEntryRaw := range objectsList { 63 | listEntry := listEntryRaw.(map[string]interface{}) 64 | id := listEntry["id"].(string) 65 | result[id] = listEntry 66 | } 67 | return result 68 | } 69 | 70 | // CalculateAddedRemovedResources utility method that provides the newly created or removed 71 | // resources as a separate list, provided the new and old values of the resource list. 72 | func CalculateAddedRemovedResources(newResourcesList, oldResourcesList []interface{}) ( 73 | addedResources []map[string]interface{}, removedResources []map[string]interface{}) { 74 | isAddingResources := len(newResourcesList) > len(oldResourcesList) 75 | if isAddingResources { 76 | oldResourcesMap := CreateIdToObjectMap(oldResourcesList) 77 | for _, newHostListEntryRaw := range newResourcesList { 78 | newResourceListEntry := newHostListEntryRaw.(map[string]interface{}) 79 | newHostEntryId := newResourceListEntry["id"].(string) 80 | _, currentResourceAlreadyPresent := oldResourcesMap[newHostEntryId] 81 | if !currentResourceAlreadyPresent { 82 | addedResources = append(addedResources, newResourceListEntry) 83 | } 84 | } 85 | } else { 86 | newResourcesMap := CreateIdToObjectMap(newResourcesList) 87 | for _, oldHostListEntryRaw := range oldResourcesList { 88 | oldResourceListEntry := oldHostListEntryRaw.(map[string]interface{}) 89 | oldHostEntryId := oldResourceListEntry["id"].(string) 90 | _, currentResourceAlreadyPresent := newResourcesMap[oldHostEntryId] 91 | if !currentResourceAlreadyPresent { 92 | removedResources = append(removedResources, oldResourceListEntry) 93 | } 94 | } 95 | } 96 | 97 | return addedResources, removedResources 98 | } 99 | -------------------------------------------------------------------------------- /examples/data-sources/host/vcf_host.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | provider "vcf" { 10 | sddc_manager_username = var.sddc_manager_username 11 | sddc_manager_password = var.sddc_manager_password 12 | sddc_manager_host = var.sddc_manager_host 13 | } 14 | 15 | data "vcf_host" "example" { 16 | fqdn = var.host_fqdn 17 | } 18 | 19 | output "host_id" { 20 | value = data.vcf_host.example.id 21 | } 22 | 23 | output "host_fqdn" { 24 | value = data.vcf_host.example.fqdn 25 | } 26 | 27 | output "host_hardware" { 28 | value = [ 29 | for hw in data.vcf_host.example.hardware : { 30 | hybrid = hw.hybrid 31 | model = hw.model 32 | vendor = hw.vendor 33 | } 34 | ] 35 | } 36 | 37 | output "host_version" { 38 | value = data.vcf_host.example.version 39 | } 40 | 41 | output "host_status" { 42 | value = data.vcf_host.example.status 43 | } 44 | 45 | output "host_domain" { 46 | value = [ 47 | for domain in data.vcf_host.example.domain : { 48 | id = domain.id 49 | } 50 | ] 51 | } 52 | 53 | output "host_cluster" { 54 | value = [ 55 | for cluster in data.vcf_host.example.cluster : { 56 | id = cluster.id 57 | } 58 | ] 59 | } 60 | 61 | output "host_network_pool" { 62 | value = [ 63 | for pool in data.vcf_host.example.network_pool : { 64 | id = pool.id 65 | name = pool.name 66 | } 67 | ] 68 | } 69 | 70 | output "host_cpu" { 71 | value = [ 72 | for cpu in coalesce(tolist(data.vcf_host.example.cpu), []) : { 73 | cores = cpu.cores 74 | frequency_mhz = cpu.frequency_mhz 75 | used_frequency_mhz = cpu.used_frequency_mhz 76 | cpu_cores = [ 77 | for core in coalesce(tolist(cpu.cpu_cores), []) : { 78 | frequency_mhz = core.frequency_mhz 79 | manufacturer = core.manufacturer 80 | model = core.model 81 | } 82 | ] 83 | } 84 | ] 85 | } 86 | 87 | output "host_memory" { 88 | value = [ 89 | for mem in data.vcf_host.example.memory : { 90 | total_capacity_mb = mem.total_capacity_mb 91 | used_capacity_mb = mem.used_capacity_mb 92 | } 93 | ] 94 | } 95 | 96 | output "host_storage" { 97 | value = [ 98 | for storage in coalesce(tolist(data.vcf_host.example.storage), []) : { 99 | total_capacity_mb = storage.total_capacity_mb 100 | used_capacity_mb = storage.used_capacity_mb 101 | disks = [ 102 | for disk in coalesce(tolist(storage.disks), []) : { 103 | capacity_mb = disk.capacity_mb 104 | disk_type = disk.disk_type 105 | manufacturer = disk.manufacturer 106 | model = disk.model 107 | } 108 | ] 109 | } 110 | ] 111 | } 112 | 113 | output "host_physical_nics" { 114 | value = [ 115 | for nic in data.vcf_host.example.physical_nics : { 116 | device_name = nic.device_name 117 | mac_address = nic.mac_address 118 | speed = nic.speed 119 | unit = nic.unit 120 | } 121 | ] 122 | } 123 | 124 | output "host_ip_addresses" { 125 | value = [ 126 | for ip in data.vcf_host.example.ip_addresses : { 127 | ip_address = ip.ip_address 128 | type = ip.type 129 | } 130 | ] 131 | } 132 | -------------------------------------------------------------------------------- /internal/datastores/nfs_datastore_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package datastores 6 | 7 | import ( 8 | "fmt" 9 | 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 11 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 12 | utils "github.com/vmware/terraform-provider-vcf/internal/resource_utils" 13 | "github.com/vmware/vcf-sdk-go/vcf" 14 | 15 | validationutils "github.com/vmware/terraform-provider-vcf/internal/validation" 16 | ) 17 | 18 | // NfsDatastoreSchema this helper function extracts the NFS Datastore schema, so that 19 | // it's made available for both workload domain and cluster creation. 20 | func NfsDatastoreSchema() *schema.Resource { 21 | return &schema.Resource{ 22 | Schema: map[string]*schema.Schema{ 23 | "datastore_name": { 24 | Type: schema.TypeString, 25 | Required: true, 26 | Description: "NFS datastore name used for cluster creation", 27 | ValidateFunc: validation.NoZeroValues, 28 | }, 29 | "path": { 30 | Type: schema.TypeString, 31 | Required: true, 32 | Description: "Shared directory path used for NFS based cluster creation", 33 | ValidateFunc: validation.NoZeroValues, 34 | }, 35 | "read_only": { 36 | Type: schema.TypeBool, 37 | Required: true, 38 | Description: "Readonly is used to identify whether to mount the directory as readOnly or not", 39 | }, 40 | "server_name": { 41 | Type: schema.TypeString, 42 | Required: true, 43 | Description: "Fully qualified domain name or IP address of the NFS endpoint", 44 | ValidateFunc: validation.NoZeroValues, 45 | }, 46 | "user_tag": { 47 | Type: schema.TypeString, 48 | Optional: true, 49 | Description: "User tag used to annotate NFS share", 50 | ValidateFunc: validation.NoZeroValues, 51 | }, 52 | }, 53 | } 54 | } 55 | 56 | func TryConvertToNfsDatastoreSpec(object map[string]interface{}) (*vcf.NfsDatastoreSpec, error) { 57 | if object == nil { 58 | return nil, fmt.Errorf("cannot convert to NfsDatastoreSpec, object is nil") 59 | } 60 | datastoreName := object["datastore_name"].(string) 61 | if len(datastoreName) == 0 { 62 | return nil, fmt.Errorf("cannot convert to NfsDatastoreSpec, datastore_name is required") 63 | } 64 | path := object["path"].(string) 65 | if len(path) == 0 { 66 | return nil, fmt.Errorf("cannot convert to NfsDatastoreSpec, path is required") 67 | } 68 | result := &vcf.NfsDatastoreSpec{} 69 | result.DatastoreName = datastoreName 70 | result.NasVolume = vcf.NasVolumeSpec{} 71 | result.NasVolume.Path = path 72 | if readOnly, ok := object["read_only"]; ok && !validationutils.IsEmpty(readOnly) { 73 | result.NasVolume.ReadOnly = readOnly.(bool) 74 | } else { 75 | return nil, fmt.Errorf("cannot convert to NfsDatastoreSpec, read_only is required") 76 | } 77 | if serverName, ok := object["server_name"]; ok && !validationutils.IsEmpty(serverName) { 78 | result.NasVolume.ServerName = []string{} 79 | result.NasVolume.ServerName = append(result.NasVolume.ServerName, serverName.(string)) 80 | } else { 81 | return nil, fmt.Errorf("cannot convert to NfsDatastoreSpec, server_name is required") 82 | } 83 | if userTag, ok := object["user_tag"]; ok && !validationutils.IsEmpty(userTag) { 84 | result.NasVolume.UserTag = utils.ToStringPointer(userTag) 85 | } 86 | return result, nil 87 | } 88 | -------------------------------------------------------------------------------- /examples/resources/cluster/vcf_cluster.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | vcf = { 4 | source = "vmware/vcf" 5 | } 6 | } 7 | } 8 | 9 | provider "vcf" { 10 | sddc_manager_username = var.sddc_manager_username 11 | sddc_manager_password = var.sddc_manager_password 12 | sddc_manager_host = var.sddc_manager_host 13 | } 14 | 15 | resource "vcf_network_pool" "domain_pool" { 16 | name = "cluster-pool" 17 | network { 18 | gateway = "192.168.12.1" 19 | mask = "255.255.255.0" 20 | mtu = 9000 21 | subnet = "192.168.12.0" 22 | type = "VSAN" 23 | vlan_id = 100 24 | ip_pools { 25 | start = "192.168.12.5" 26 | end = "192.168.12.50" 27 | } 28 | } 29 | network { 30 | gateway = "192.168.13.1" 31 | mask = "255.255.255.0" 32 | mtu = 9000 33 | subnet = "192.168.13.0" 34 | type = "vMotion" 35 | vlan_id = 100 36 | ip_pools { 37 | start = "192.168.13.5" 38 | end = "192.168.13.50" 39 | } 40 | } 41 | } 42 | 43 | resource "vcf_host" "host1" { 44 | fqdn = var.esx_host1_fqdn 45 | username = "root" 46 | password = var.esx_host1_pass 47 | network_pool_id = vcf_network_pool.domain_pool.id 48 | storage_type = "VSAN" 49 | } 50 | 51 | resource "vcf_host" "host2" { 52 | fqdn = var.esx_host2_fqdn 53 | username = "root" 54 | password = var.esx_host2_pass 55 | network_pool_id = vcf_network_pool.domain_pool.id 56 | storage_type = "VSAN" 57 | } 58 | resource "vcf_host" "host3" { 59 | fqdn = var.esx_host3_fqdn 60 | username = "root" 61 | password = var.esx_host3_pass 62 | network_pool_id = vcf_network_pool.domain_pool.id 63 | storage_type = "VSAN" 64 | } 65 | 66 | resource "vcf_cluster" "cluster1" { 67 | // Here you can reference a terraform managed domain's id 68 | domain_id = var.domain_id 69 | name = "sfo-m01-cl01" 70 | host { 71 | id = vcf_host.host1.id 72 | license_key = var.esx_license_key 73 | vmnic { 74 | id = "vmnic0" 75 | vds_name = "sfo-m01-cl01-vds01" 76 | } 77 | vmnic { 78 | id = "vmnic1" 79 | vds_name = "sfo-m01-cl01-vds01" 80 | } 81 | } 82 | host { 83 | id = vcf_host.host2.id 84 | license_key = var.esx_license_key 85 | vmnic { 86 | id = "vmnic0" 87 | vds_name = "sfo-m01-cl01-vds01" 88 | } 89 | vmnic { 90 | id = "vmnic1" 91 | vds_name = "sfo-m01-cl01-vds01" 92 | } 93 | } 94 | host { 95 | id = vcf_host.host3.id 96 | license_key = var.esx_license_key 97 | vmnic { 98 | id = "vmnic0" 99 | vds_name = "sfo-m01-cl01-vds01" 100 | } 101 | vmnic { 102 | id = "vmnic1" 103 | vds_name = "sfo-m01-cl01-vds01" 104 | } 105 | } 106 | vds { 107 | name = "sfo-m01-cl01-vds01" 108 | portgroup { 109 | name = "sfo-m01-cl01-vds01-pg-mgmt" 110 | transport_type = "MANAGEMENT" 111 | } 112 | portgroup { 113 | name = "sfo-m01-cl01-vds01-pg-vsan" 114 | transport_type = "VSAN" 115 | } 116 | portgroup { 117 | name = "sfo-m01-cl01-vds01-pg-vmotion" 118 | transport_type = "VMOTION" 119 | } 120 | } 121 | vsan_datastore { 122 | datastore_name = "sfo-m01-cl01-ds-vsan01" 123 | failures_to_tolerate = 1 124 | license_key = var.vsan_license_key 125 | } 126 | geneve_vlan_id = 3 127 | } -------------------------------------------------------------------------------- /internal/provider/data_source_domain_test.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package provider 6 | 7 | import ( 8 | "fmt" 9 | "os" 10 | "testing" 11 | 12 | "github.com/hashicorp/terraform-plugin-testing/helper/resource" 13 | 14 | "github.com/vmware/terraform-provider-vcf/internal/constants" 15 | ) 16 | 17 | func testAccVcfDomainDataSourceSteps(config string) []resource.TestStep { 18 | return []resource.TestStep{ 19 | { 20 | Config: config, 21 | Check: resource.ComposeTestCheckFunc( 22 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "vcenter_configuration.0.id"), 23 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "vcenter_configuration.0.fqdn"), 24 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "status"), 25 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "type"), 26 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "sso_id"), 27 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "sso_name"), 28 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.id"), 29 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.name"), 30 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.primary_datastore_name"), 31 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.primary_datastore_type"), 32 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.is_default"), 33 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.is_stretched"), 34 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.host.0.id"), 35 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.host.1.id"), 36 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.host.2.id"), 37 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "cluster.0.host.3.id"), 38 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.id"), 39 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.vip_fqdn"), 40 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.nsx_manager_node.0.name"), 41 | resource.TestCheckResourceAttrSet("data.vcf_domain.domain1", "nsx_configuration.0.nsx_manager_node.0.fqdn"), 42 | ), 43 | }, 44 | } 45 | } 46 | 47 | func testAccVcfDomainDataSourceConfigById(domainId string) string { 48 | return fmt.Sprintf(` 49 | data "vcf_domain" "domain1" { 50 | domain_id = %q 51 | }`, domainId) 52 | } 53 | 54 | func testAccVcfDomainDataSourceConfigByName(name string) string { 55 | return fmt.Sprintf(` 56 | data "vcf_domain" "domain1" { 57 | name = %q 58 | }`, name) 59 | } 60 | 61 | func TestAccDataSourceVcfDomainById(t *testing.T) { 62 | config := testAccVcfDomainDataSourceConfigById(os.Getenv(constants.VcfTestDomainDataSourceId)) 63 | 64 | resource.Test(t, resource.TestCase{ 65 | PreCheck: func() { testAccPreCheck(t) }, 66 | ProtoV6ProviderFactories: muxedFactories(), 67 | Steps: testAccVcfDomainDataSourceSteps(config), 68 | }) 69 | } 70 | 71 | func TestAccDataSourceVcfDomainByName(t *testing.T) { 72 | config := testAccVcfDomainDataSourceConfigByName(os.Getenv(constants.VcfTestDomainDataSourceName)) 73 | 74 | resource.Test(t, resource.TestCase{ 75 | PreCheck: func() { testAccPreCheck(t) }, 76 | ProtoV6ProviderFactories: muxedFactories(), 77 | Steps: testAccVcfDomainDataSourceSteps(config), 78 | }) 79 | } 80 | -------------------------------------------------------------------------------- /internal/datastores/vvol_datastore_subresource.go: -------------------------------------------------------------------------------- 1 | // © Broadcom. All Rights Reserved. 2 | // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 | // SPDX-License-Identifier: MPL-2.0 4 | 5 | package datastores 6 | 7 | import ( 8 | "fmt" 9 | "strings" 10 | 11 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" 12 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" 13 | "github.com/vmware/vcf-sdk-go/vcf" 14 | ) 15 | 16 | // VvolDatastoreSchema this helper function extracts the VVOL Datastore schema, so that 17 | // it's made available for both Domain and Cluster creation. 18 | func VvolDatastoreSchema() *schema.Resource { 19 | return &schema.Resource{ 20 | Schema: map[string]*schema.Schema{ 21 | "datastore_name": { 22 | Type: schema.TypeString, 23 | Required: true, 24 | Description: "vVol datastore name used for cluster creation", 25 | ValidateFunc: validation.NoZeroValues, 26 | }, 27 | "storage_container_id": { 28 | Type: schema.TypeString, 29 | Required: true, 30 | Description: "UUID of the VASA storage container", 31 | ValidateFunc: validation.IsUUID, 32 | }, 33 | "storage_protocol_type": { 34 | Type: schema.TypeString, 35 | Required: true, 36 | Description: "Type of the VASA storage protocol. One among: ISCSI, NFS, FC.", 37 | ValidateFunc: validation.StringInSlice( 38 | []string{"ISCSI", "NFS", "FC"}, true), 39 | DiffSuppressFunc: func(k, oldValue, newValue string, d *schema.ResourceData) bool { 40 | return oldValue == strings.ToUpper(newValue) || strings.ToUpper(oldValue) == newValue 41 | }, 42 | }, 43 | "user_id": { 44 | Type: schema.TypeString, 45 | Required: true, 46 | Description: "UUID of the VASA storage user", 47 | ValidateFunc: validation.IsUUID, 48 | }, 49 | "vasa_provider_id": { 50 | Type: schema.TypeString, 51 | Required: true, 52 | Description: "UUID of the VASA storage provider", 53 | ValidateFunc: validation.IsUUID, 54 | }, 55 | }, 56 | } 57 | } 58 | 59 | func TryConvertToVvolDatastoreSpec(object map[string]interface{}) (*vcf.VvolDatastoreSpec, error) { 60 | if object == nil { 61 | return nil, fmt.Errorf("cannot convert to VvolDatastoreSpec, object is nil") 62 | } 63 | result := &vcf.VvolDatastoreSpec{} 64 | result.VasaProviderSpec = vcf.VasaProviderSpec{} 65 | 66 | datastoreName := object["datastore_name"].(string) 67 | if len(datastoreName) == 0 { 68 | return nil, fmt.Errorf("cannot convert to VvolDatastoreSpec, datastore_name is required") 69 | } 70 | result.Name = datastoreName 71 | 72 | storageContainerId := object["storage_container_id"].(string) 73 | if len(storageContainerId) == 0 { 74 | return nil, fmt.Errorf("cannot convert to VvolDatastoreSpec, storage_container_id is required") 75 | } 76 | result.VasaProviderSpec.StorageContainerId = storageContainerId 77 | 78 | storageContainerProtocolType := object["storage_protocol_type"].(string) 79 | if len(storageContainerProtocolType) == 0 { 80 | return nil, fmt.Errorf("cannot convert to VvolDatastoreSpec, storage_protocol_type is required") 81 | } 82 | result.VasaProviderSpec.StorageProtocolType = storageContainerProtocolType 83 | 84 | userId := object["user_id"].(string) 85 | if len(userId) == 0 { 86 | return nil, fmt.Errorf("cannot convert to VvolDatastoreSpec, userId is required") 87 | } 88 | result.VasaProviderSpec.UserId = userId 89 | 90 | vasaProviderId := object["vasa_provider_id"].(string) 91 | if len(vasaProviderId) == 0 { 92 | return nil, fmt.Errorf("cannot convert to VvolDatastoreSpec, vasa_provider_id is required") 93 | } 94 | result.VasaProviderSpec.VasaProviderId = vasaProviderId 95 | 96 | return result, nil 97 | } 98 | -------------------------------------------------------------------------------- /docs/resources/external_certificate.md: -------------------------------------------------------------------------------- 1 | --- 2 | # generated by https://github.com/hashicorp/terraform-plugin-docs 3 | page_title: "vcf_external_certificate Resource - terraform-provider-vcf" 4 | subcategory: "" 5 | description: |- 6 | 7 | --- 8 | 9 | # vcf_external_certificate (Resource) 10 | 11 | Replaces a Certificate of a Domain resource (VCENTER, SDDC_MANAGER) with a Certificate, generated by an external CA. 12 | 13 | Prerequisites for installing a certificate: 14 | * The SDDC Manager should be up and running. 15 | * The resources of the target domain (e.g. MGMT) should be in ACTIVE state. 16 | * CSR generated for the target resource. 17 | 18 | Warnings: 19 | * Certificate installation will replace the already installed certificates. 20 | 21 | Notes: 22 | * The CSRs cannot be fetched after successful certificate installation. 23 | * Only the latest generated CSRs will exist in the VCF environment after a series of generate CSR operation. 24 | * Only the latest generated certificates will exist in the VCF environment after a series of generate certificate operation. 25 | 26 | 27 | 28 | ## Schema 29 | 30 | ### Required 31 | 32 | - `csr_id` (String) The ID of the CSR generated for a resource. A generated CSR is required for certificate replacement. 33 | 34 | ### Optional 35 | 36 | - `ca_certificate` (String) Certificate of the CA issuing the replacement certificate 37 | - `certificate_chain` (String) Certificate Chain 38 | - `resource_certificate` (String) Resource Certificate 39 | - `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) 40 | 41 | ### Read-Only 42 | 43 | - `certificate` (List of Object) The resulting certificate details (see [below for nested schema](#nestedatt--certificate)) 44 | - `id` (String) The ID of this resource. 45 | 46 | 47 | ### Nested Schema for `timeouts` 48 | 49 | Optional: 50 | 51 | - `create` (String) 52 | - `delete` (String) 53 | - `read` (String) 54 | - `update` (String) 55 | 56 | 57 | 58 | ### Nested Schema for `certificate` 59 | 60 | Read-Only: 61 | 62 | - `certificate_error` (String) Error if certificate cannot be fetched. Example: Status : NOT_TRUSTED, Message : Certificate Expired 63 | - `domain` (String) Domain of the resource certificate 64 | - `expiration_status` (String) Certificate expiry status. One among: ACTIVE, ABOUT_TO_EXPIRE, EXPIRED 65 | - `issued_by` (String) The certificate authority that issued the certificate 66 | - `issued_to` (String) To whom the certificate is issued 67 | - `key_size` (String) The key size of the certificate 68 | - `not_after` (String) The timestamp after which certificate is not valid 69 | - `not_before` (String) The timestamp before which certificate is not valid 70 | - `number_of_days_to_expire` (Number) Number of days left for the certificate to expire 71 | - `pem_encoded` (String) The PEM encoded certificate content 72 | - `public_key` (String) The public key of the certificate 73 | - `public_key_algorithm` (String) The public key algorithm of the certificate 74 | - `serial_number` (String) The serial number of the certificate 75 | - `signature_algorithm` (String) Algorithm used to sign the certificate 76 | - `subject` (String) Complete distinguished name to which the certificate is issued 77 | - `subject_alternative_name` (List of String) The alternative names to which the certificate is issued 78 | - `subject_cn` (String) 79 | - `subject_country` (String) 80 | - `subject_locality` (String) 81 | - `subject_org` (String) 82 | - `subject_ou` (String) 83 | - `subject_st` (String) 84 | - `thumbprint` (String) Thumbprint generated using certificate content 85 | - `thumbprint_algorithm` (String) Algorithm used to generate thumbprint 86 | - `version` (String) The X.509 version of the certificate 87 | --------------------------------------------------------------------------------