From ed3dfeae9907757f42c0cce63fe1f00a4e2ec0a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szczepan=20Wi=C5=9Bniowski?= Date: Wed, 5 Apr 2023 01:55:48 +0200 Subject: [PATCH] fix(provider): Deprecate `virtual_environment` block (#288) refactor(provider): Allow specifying attributes outside of virtual_environment block Also deprecate virtual_environment block, update docs and examples. Fixes #117 Apparently CDKTF skips schemas without attributes, it has been fixed but it is available only in prerelease currently (https://github.com/hashicorp/terraform-cdk/pull/2736) Release-As: 0.17.0 --- docs/index.md | 48 +++---- example/main.tf | 10 +- proxmoxtf/provider/provider.go | 42 +++--- proxmoxtf/provider/provider_test.go | 30 +++-- proxmoxtf/provider/schema.go | 191 ++++++++++++---------------- 5 files changed, 150 insertions(+), 171 deletions(-) diff --git a/docs/index.md b/docs/index.md index fd378189..ff0b68ea 100644 --- a/docs/index.md +++ b/docs/index.md @@ -17,12 +17,10 @@ Use the navigation to the left to read about the available resources. ```terraform provider "proxmox" { - virtual_environment { - endpoint = "https://10.0.0.2:8006/" - username = "root@pam" - password = "the-password-set-during-installation-of-proxmox-ve" - insecure = true - } + endpoint = "https://10.0.0.2:8006/" + username = "root@pam" + password = "the-password-set-during-installation-of-proxmox-ve" + insecure = true } ``` @@ -46,10 +44,8 @@ in the Proxmox provider block: ```terraform provider "proxmox" { - virtual_environment { - username = "username@realm" - password = "a-strong-password" - } + username = "username@realm" + password = "a-strong-password" } ``` @@ -60,9 +56,7 @@ and `PROXMOX_VE_PASSWORD`, environment variables, representing your Proxmox username, realm and password, respectively: ```terraform -provider "proxmox" { - virtual_environment {} -} +provider "proxmox" {} ``` Usage: @@ -80,18 +74,16 @@ to [generic provider arguments](https://www.terraform.io/docs/configuration/prov e.g. `alias` and `version`), the following arguments are supported in the Proxmox `provider` block: -- `virtual_environment` - (Optional) The Proxmox Virtual Environment - configuration. - - `endpoint` - (Required) The endpoint for the Proxmox Virtual Environment - API (can also be sourced from `PROXMOX_VE_ENDPOINT`). Usually this is - `https://:8006/`. - - `insecure` - (Optional) Whether to skip the TLS verification step (can - also be sourced from `PROXMOX_VE_INSECURE`). If omitted, defaults - to `false`. - - `otp` - (Optional) The one-time password for the Proxmox Virtual - Environment API (can also be sourced from `PROXMOX_VE_OTP`). - - `password` - (Required) The password for the Proxmox Virtual Environment - API (can also be sourced from `PROXMOX_VE_PASSWORD`). - - `username` - (Required) The username and realm for the Proxmox Virtual - Environment API (can also be sourced from `PROXMOX_VE_USERNAME`). For - example, `root@pam`. +- `endpoint` - (Required) The endpoint for the Proxmox Virtual Environment + API (can also be sourced from `PROXMOX_VE_ENDPOINT`). Usually this is + `https://:8006/`. +- `insecure` - (Optional) Whether to skip the TLS verification step (can + also be sourced from `PROXMOX_VE_INSECURE`). If omitted, defaults + to `false`. +- `otp` - (Optional) The one-time password for the Proxmox Virtual + Environment API (can also be sourced from `PROXMOX_VE_OTP`). +- `password` - (Required) The password for the Proxmox Virtual Environment + API (can also be sourced from `PROXMOX_VE_PASSWORD`). +- `username` - (Required) The username and realm for the Proxmox Virtual + Environment API (can also be sourced from `PROXMOX_VE_USERNAME`). For + example, `root@pam`. diff --git a/example/main.tf b/example/main.tf index a50b4cad..5001e644 100644 --- a/example/main.tf +++ b/example/main.tf @@ -1,8 +1,6 @@ provider "proxmox" { - virtual_environment { - endpoint = var.virtual_environment_endpoint - username = var.virtual_environment_username - password = var.virtual_environment_password - insecure = true - } + endpoint = var.virtual_environment_endpoint + username = var.virtual_environment_username + password = var.virtual_environment_password + insecure = true } diff --git a/proxmoxtf/provider/provider.go b/proxmoxtf/provider/provider.go index 8daf1f86..ad73bb29 100644 --- a/proxmoxtf/provider/provider.go +++ b/proxmoxtf/provider/provider.go @@ -17,17 +17,14 @@ import ( ) const ( - dvProviderVirtualEnvironmentEndpoint = "" - dvProviderVirtualEnvironmentOTP = "" - dvProviderVirtualEnvironmentPassword = "" - dvProviderVirtualEnvironmentUsername = "" + dvProviderOTP = "" - mkProviderVirtualEnvironment = "virtual_environment" - mkProviderVirtualEnvironmentEndpoint = "endpoint" - mkProviderVirtualEnvironmentInsecure = "insecure" - mkProviderVirtualEnvironmentOTP = "otp" - mkProviderVirtualEnvironmentPassword = "password" - mkProviderVirtualEnvironmentUsername = "username" + mkProviderVirtualEnvironment = "virtual_environment" + mkProviderEndpoint = "endpoint" + mkProviderInsecure = "insecure" + mkProviderOTP = "otp" + mkProviderPassword = "password" + mkProviderUsername = "username" ) // ProxmoxVirtualEnvironment returns the object for this provider. @@ -51,15 +48,24 @@ func providerConfigure(_ context.Context, d *schema.ResourceData) (interface{}, veConfig := veConfigBlock[0].(map[string]interface{}) veClient, err = proxmox.NewVirtualEnvironmentClient( - veConfig[mkProviderVirtualEnvironmentEndpoint].(string), - veConfig[mkProviderVirtualEnvironmentUsername].(string), - veConfig[mkProviderVirtualEnvironmentPassword].(string), - veConfig[mkProviderVirtualEnvironmentOTP].(string), - veConfig[mkProviderVirtualEnvironmentInsecure].(bool), + veConfig[mkProviderEndpoint].(string), + veConfig[mkProviderUsername].(string), + veConfig[mkProviderPassword].(string), + veConfig[mkProviderOTP].(string), + veConfig[mkProviderInsecure].(bool), ) - if err != nil { - return nil, diag.FromErr(err) - } + } else { + veClient, err = proxmox.NewVirtualEnvironmentClient( + d.Get(mkProviderEndpoint).(string), + d.Get(mkProviderUsername).(string), + d.Get(mkProviderPassword).(string), + d.Get(mkProviderOTP).(string), + d.Get(mkProviderInsecure).(bool), + ) + } + + if err != nil { + return nil, diag.FromErr(err) } config := proxmoxtf.NewProviderConfiguration(veClient) diff --git a/proxmoxtf/provider/provider_test.go b/proxmoxtf/provider/provider_test.go index fd68ba31..ea98576e 100644 --- a/proxmoxtf/provider/provider_test.go +++ b/proxmoxtf/provider/provider_test.go @@ -33,27 +33,37 @@ func TestProviderSchema(t *testing.T) { test.AssertOptionalArguments(t, s, []string{ mkProviderVirtualEnvironment, + mkProviderUsername, + mkProviderPassword, + mkProviderEndpoint, + mkProviderInsecure, + mkProviderOTP, }) test.AssertValueTypes(t, s, map[string]schema.ValueType{ mkProviderVirtualEnvironment: schema.TypeList, + mkProviderUsername: schema.TypeString, + mkProviderPassword: schema.TypeString, + mkProviderEndpoint: schema.TypeString, + mkProviderInsecure: schema.TypeBool, + mkProviderOTP: schema.TypeString, }) veSchema := test.AssertNestedSchemaExistence(t, s, mkProviderVirtualEnvironment) test.AssertOptionalArguments(t, veSchema, []string{ - mkProviderVirtualEnvironmentEndpoint, - mkProviderVirtualEnvironmentInsecure, - mkProviderVirtualEnvironmentOTP, - mkProviderVirtualEnvironmentPassword, - mkProviderVirtualEnvironmentUsername, + mkProviderEndpoint, + mkProviderInsecure, + mkProviderOTP, + mkProviderPassword, + mkProviderUsername, }) test.AssertValueTypes(t, veSchema, map[string]schema.ValueType{ - mkProviderVirtualEnvironmentEndpoint: schema.TypeString, - mkProviderVirtualEnvironmentInsecure: schema.TypeBool, - mkProviderVirtualEnvironmentOTP: schema.TypeString, - mkProviderVirtualEnvironmentPassword: schema.TypeString, - mkProviderVirtualEnvironmentUsername: schema.TypeString, + mkProviderEndpoint: schema.TypeString, + mkProviderInsecure: schema.TypeBool, + mkProviderOTP: schema.TypeString, + mkProviderPassword: schema.TypeString, + mkProviderUsername: schema.TypeString, }) } diff --git a/proxmoxtf/provider/schema.go b/proxmoxtf/provider/schema.go index 2f3c19a4..b7b2142d 100644 --- a/proxmoxtf/provider/schema.go +++ b/proxmoxtf/provider/schema.go @@ -7,123 +7,96 @@ package provider import ( - "errors" - "net/url" + "fmt" "os" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) func createSchema() map[string]*schema.Schema { + providerSchema := nestedProviderSchema() + providerSchema[mkProviderVirtualEnvironment] = &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: nestedProviderSchema(), + }, + MaxItems: 1, + Deprecated: "Move attributes out of virtual_environment block", + } + + return providerSchema +} + +func nestedProviderSchema() map[string]*schema.Schema { return map[string]*schema.Schema{ - mkProviderVirtualEnvironment: { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - mkProviderVirtualEnvironmentEndpoint: { - Type: schema.TypeString, - Optional: true, - Description: "The endpoint for the Proxmox Virtual Environment API", - DefaultFunc: schema.MultiEnvDefaultFunc( - []string{"PROXMOX_VE_ENDPOINT", "PM_VE_ENDPOINT"}, - dvProviderVirtualEnvironmentEndpoint, - ), - ValidateFunc: func(v interface{}, k string) (warns []string, errs []error) { - value := v.(string) - - if value == "" { - return []string{}, []error{ - errors.New( - "you must specify an endpoint for the Proxmox Virtual Environment API (valid: https://host:port)", - ), - } - } - - _, err := url.ParseRequestURI(value) - if err != nil { - return []string{}, []error{ - errors.New( - "you must specify a valid endpoint for the Proxmox Virtual Environment API (valid: https://host:port)", - ), - } - } - - return []string{}, []error{} - }, - }, - mkProviderVirtualEnvironmentInsecure: { - Type: schema.TypeBool, - Optional: true, - Description: "Whether to skip the TLS verification step", - DefaultFunc: func() (interface{}, error) { - for _, k := range []string{"PROXMOX_VE_INSECURE", "PM_VE_INSECURE"} { - v := os.Getenv(k) - - if v == "true" || v == "1" { - return true, nil - } - } - - return false, nil - }, - }, - mkProviderVirtualEnvironmentOTP: { - Type: schema.TypeString, - Optional: true, - Description: "The one-time password for the Proxmox Virtual Environment API", - DefaultFunc: schema.MultiEnvDefaultFunc( - []string{"PROXMOX_VE_OTP", "PM_VE_OTP"}, - dvProviderVirtualEnvironmentOTP, - ), - }, - mkProviderVirtualEnvironmentPassword: { - Type: schema.TypeString, - Optional: true, - Description: "The password for the Proxmox Virtual Environment API", - DefaultFunc: schema.MultiEnvDefaultFunc( - []string{"PROXMOX_VE_PASSWORD", "PM_VE_PASSWORD"}, - dvProviderVirtualEnvironmentPassword, - ), - ValidateFunc: func(v interface{}, k string) (warns []string, errs []error) { - value := v.(string) - - if value == "" { - return []string{}, []error{ - errors.New( - "you must specify a password for the Proxmox Virtual Environment API", - ), - } - } - - return []string{}, []error{} - }, - }, - mkProviderVirtualEnvironmentUsername: { - Type: schema.TypeString, - Optional: true, - Description: "The username for the Proxmox Virtual Environment API", - DefaultFunc: schema.MultiEnvDefaultFunc( - []string{"PROXMOX_VE_USERNAME", "PM_VE_USERNAME"}, - dvProviderVirtualEnvironmentUsername, - ), - ValidateFunc: func(v interface{}, k string) (warns []string, errs []error) { - value := v.(string) - - if value == "" { - return []string{}, []error{ - errors.New( - "you must specify a username for the Proxmox Virtual Environment API (valid: username@realm)", - ), - } - } - - return []string{}, []error{} - }, - }, - }, + mkProviderEndpoint: { + Type: schema.TypeString, + Optional: true, + Description: "The endpoint for the Proxmox Virtual Environment API", + DefaultFunc: schema.MultiEnvDefaultFunc( + []string{"PROXMOX_VE_ENDPOINT", "PM_VE_ENDPOINT"}, + nil, + ), + AtLeastOneOf: []string{ + mkProviderEndpoint, + fmt.Sprintf("%s.0.%s", mkProviderVirtualEnvironment, mkProviderEndpoint), }, - MaxItems: 1, + ValidateFunc: validation.IsURLWithHTTPorHTTPS, + }, + mkProviderInsecure: { + Type: schema.TypeBool, + Optional: true, + Description: "Whether to skip the TLS verification step", + DefaultFunc: func() (interface{}, error) { + for _, k := range []string{"PROXMOX_VE_INSECURE", "PM_VE_INSECURE"} { + v := os.Getenv(k) + + if v == "true" || v == "1" { + return true, nil + } + } + + return false, nil + }, + }, + mkProviderOTP: { + Type: schema.TypeString, + Optional: true, + Description: "The one-time password for the Proxmox Virtual Environment API", + DefaultFunc: schema.MultiEnvDefaultFunc( + []string{"PROXMOX_VE_OTP", "PM_VE_OTP"}, + dvProviderOTP, + ), + }, + mkProviderPassword: { + Type: schema.TypeString, + Optional: true, + Description: "The password for the Proxmox Virtual Environment API", + DefaultFunc: schema.MultiEnvDefaultFunc( + []string{"PROXMOX_VE_PASSWORD", "PM_VE_PASSWORD"}, + nil, + ), + AtLeastOneOf: []string{ + mkProviderPassword, + fmt.Sprintf("%s.0.%s", mkProviderVirtualEnvironment, mkProviderPassword), + }, + ValidateFunc: validation.StringIsNotEmpty, + }, + mkProviderUsername: { + Type: schema.TypeString, + Optional: true, + Description: "The username for the Proxmox Virtual Environment API", + DefaultFunc: schema.MultiEnvDefaultFunc( + []string{"PROXMOX_VE_USERNAME", "PM_VE_USERNAME"}, + nil, + ), + AtLeastOneOf: []string{ + mkProviderUsername, + fmt.Sprintf("%s.0.%s", mkProviderVirtualEnvironment, mkProviderUsername), + }, + ValidateFunc: validation.StringIsNotEmpty, }, } }