diff --git a/CHANGELOG.md b/CHANGELOG.md index c362609dd..cdb4edfea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,13 @@ FEATURES: ENHANCEMENTS: * Added GetRancherVersion function to provider config +* Updated `vsphere_config` argument schema on `rancher2_node_template` resource to support Rancher v2.3.3 features +* Updated rancher to v2.3.3 and k3s to v0.10.2 on acceptance tests BUG FIXES: - +* Set `annotations` argument as computed on `rancher2_node_template` resource +* Added `rancher2_node_template` resource workaround on docs when upgrade Rancher to v2.3.3 ## 1.7.0 (November 20, 2019) diff --git a/rancher2/schema_node_template.go b/rancher2/schema_node_template.go index 8534e2464..68d38a9b3 100644 --- a/rancher2/schema_node_template.go +++ b/rancher2/schema_node_template.go @@ -134,6 +134,7 @@ func nodeTemplateFields() map[string]*schema.Schema { "annotations": &schema.Schema{ Type: schema.TypeMap, Optional: true, + Computed: true, }, "labels": &schema.Schema{ Type: schema.TypeMap, diff --git a/rancher2/schema_node_template_vsphere.go b/rancher2/schema_node_template_vsphere.go index 4b9e52ff5..f12117e6a 100644 --- a/rancher2/schema_node_template_vsphere.go +++ b/rancher2/schema_node_template_vsphere.go @@ -6,10 +6,12 @@ import ( ) const ( - vmwarevsphereConfigDriver = "vmwarevsphere" + vmwarevsphereConfigDriver = "vmwarevsphere" + vmwarevsphereConfigCreationTypeDefault = "legacy" ) var ( + vmwarevsphereConfigCreationType = []string{"vm", "template", "library", "legacy"} vmwarevsphereConfigVappIpallocationpolicies = []string{"dhcp", "fixed", "transient", "fixedAllocated"} vmwarevsphereConfigVappIpprotocols = []string{"IPv4", "IPv6"} vmwarevsphereConfigVappTransports = []string{"iso", "com.vmware.guestInfo"} @@ -20,10 +22,16 @@ var ( type vmwarevsphereConfig struct { Boot2dockerURL string `json:"boot2dockerUrl,omitempty" yaml:"boot2dockerUrl,omitempty"` Cfgparam []string `json:"cfgparam,omitempty" yaml:"cfgparam,omitempty"` + CloneFrom string `json:"cloneFrom,omitempty" yaml:"cloneFrom,omitempty"` + CloudConfig string `json:"cloudConfig,omitempty" yaml:"cloudConfig,omitempty"` Cloudinit string `json:"cloudinit,omitempty" yaml:"cloudinit,omitempty"` + ContentLibrary string `json:"contentLibrary,omitempty" yaml:"contentLibrary,omitempty"` CPUCount string `json:"cpuCount,omitempty" yaml:"cpuCount,omitempty"` + CreationType string `json:"creationType,omitempty" yaml:"creationType,omitempty"` + CustomAttributes []string `json:"customAttribute,omitempty" yaml:"customAttribute,omitempty"` Datacenter string `json:"datacenter,omitempty" yaml:"datacenter,omitempty"` Datastore string `json:"datastore,omitempty" yaml:"datastore,omitempty"` + DatastoreCluster string `json:"datastoreCluster,omitempty" yaml:"datastoreCluster,omitempty"` DiskSize string `json:"diskSize,omitempty" yaml:"diskSize,omitempty"` Folder string `json:"folder,omitempty" yaml:"folder,omitempty"` Hostsystem string `json:"hostsystem,omitempty" yaml:"hostsystem,omitempty"` @@ -31,6 +39,11 @@ type vmwarevsphereConfig struct { Network []string `json:"network,omitempty" yaml:"network,omitempty"` Password string `json:"password,omitempty" yaml:"password,omitempty"` Pool string `json:"pool,omitempty" yaml:"pool,omitempty"` + SshPassword string `json:"sshPassword,omitempty" yaml:"sshPassword,omitempty"` + SshPort string `json:"sshPort,omitempty" yaml:"sshPort,omitempty"` + SshUser string `json:"sshUser,omitempty" yaml:"sshUser,omitempty"` + SshUserGroup string `json:"sshUserGroup,omitempty" yaml:"sshUserGroup,omitempty"` + Tags []string `json:"tag,omitempty" yaml:"tag,omitempty"` Username string `json:"username,omitempty" yaml:"username,omitempty"` VappIpallocationpolicy string `json:"vappIpallocationpolicy,omitempty" yaml:"vappIpallocationpolicy,omitempty"` VappIpprotocol string `json:"vappIpprotocol,omitempty" yaml:"vappIpprotocol,omitempty"` @@ -45,55 +58,101 @@ type vmwarevsphereConfig struct { func vsphereConfigFields() map[string]*schema.Schema { s := map[string]*schema.Schema{ "boot2docker_url": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Default: "https://releases.rancher.com/os/latest/rancheros-vmware.iso", + Type: schema.TypeString, + Optional: true, + Default: "https://releases.rancher.com/os/latest/rancheros-vmware.iso", + Description: "vSphere URL for boot2docker image", }, "cfgparam": &schema.Schema{ - Type: schema.TypeList, - Optional: true, + Type: schema.TypeList, + Optional: true, + Description: "vSphere vm configuration parameters (used for guestinfo)", Elem: &schema.Schema{ Type: schema.TypeString, }, }, + "clone_from": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Description: "If you choose creation type clone a name of what you want to clone is required", + }, + "cloud_config": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Description: "Filepath to a cloud-config yaml file to put into the ISO user-data", + }, "cloudinit": &schema.Schema{ - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + Description: "vSphere cloud-init filepath or url to add to guestinfo", + }, + "content_library": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Description: "If you choose to clone from a content library template specify the name of the library", }, "cpu_count": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Default: "2", + Type: schema.TypeString, + Optional: true, + Default: "2", + Description: "vSphere CPU number for docker VM", + }, + "creation_type": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: vmwarevsphereConfigCreationTypeDefault, + ValidateFunc: validation.StringInSlice(vmwarevsphereConfigCreationType, true), + Description: "Creation type when creating a new virtual machine. Supported values: vm, template, library, legacy", + }, + "custom_attributes": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Description: "vSphere custom attributes, format key/value e.g. '200=my custom value'", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, "datacenter": &schema.Schema{ - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + Description: "vSphere datacenter for virtual machine", }, "datastore": &schema.Schema{ - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + Description: "vSphere datastore for virtual machine", + }, + "datastore_cluster": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Description: "vSphere datastore cluster for virtual machine", }, "disk_size": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Default: "20480", + Type: schema.TypeString, + Optional: true, + Default: "20480", + Description: "vSphere size of disk for docker VM (in MB)", }, "folder": &schema.Schema{ - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + Description: "vSphere folder for the docker VM. This folder must already exist in the datacenter", }, "hostsystem": &schema.Schema{ - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + Description: "vSphere compute resource where the docker VM will be instantiated. This can be omitted if using a cluster with DRS", }, "memory_size": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - Default: "2048", + Type: schema.TypeString, + Optional: true, + Default: "2048", + Description: "vSphere size of memory for docker VM (in MB)", }, "network": &schema.Schema{ - Type: schema.TypeList, - Optional: true, + Type: schema.TypeList, + Optional: true, + Description: "vSphere network where the virtual machine will be attached", Elem: &schema.Schema{ Type: schema.TypeString, }, @@ -105,8 +164,42 @@ func vsphereConfigFields() map[string]*schema.Schema { Description: "vSphere password", }, "pool": &schema.Schema{ - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, + Description: "vSphere resource pool for docker VM", + }, + "ssh_password": { + Type: schema.TypeString, + Optional: true, + Sensitive: true, + Default: "tcuser", + Description: "If using a non-B2D image you can specify the ssh password", + }, + "ssh_port": { + Type: schema.TypeString, + Optional: true, + Default: "22", + Description: "If using a non-B2D image you can specify the ssh port", + }, + "ssh_user": { + Type: schema.TypeString, + Optional: true, + Default: "docker", + Description: "If using a non-B2D image you can specify the ssh user", + }, + "ssh_user_group": { + Type: schema.TypeString, + Optional: true, + Default: "staff", + Description: "If using a non-B2D image the uploaded keys will need chown'ed, defaults to staff e.g. docker:staff", + }, + "tags": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Description: "vSphere tags id e.g. urn:xxx", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, "username": { Type: schema.TypeString, @@ -116,16 +209,19 @@ func vsphereConfigFields() map[string]*schema.Schema { "vapp_ip_allocation_policy": &schema.Schema{ Type: schema.TypeString, Optional: true, + Description: "vSphere vApp IP allocation policy. Supported values are: dhcp, fixed, transient and fixedAllocated", ValidateFunc: validation.StringInSlice(vmwarevsphereConfigVappIpallocationpolicies, true), }, "vapp_ip_protocol": &schema.Schema{ Type: schema.TypeString, Optional: true, + Description: "vSphere vApp IP protocol for this deployment. Supported values are: IPv4 and IPv6", ValidateFunc: validation.StringInSlice(vmwarevsphereConfigVappIpprotocols, true), }, "vapp_property": &schema.Schema{ - Type: schema.TypeList, - Optional: true, + Type: schema.TypeList, + Optional: true, + Description: "vSphere vApp properties", Elem: &schema.Schema{ Type: schema.TypeString, }, @@ -133,6 +229,7 @@ func vsphereConfigFields() map[string]*schema.Schema { "vapp_transport": &schema.Schema{ Type: schema.TypeString, Optional: true, + Description: "vSphere OVF environment transports to use for properties. Supported values are: iso and com.vmware.guestInfo", ValidateFunc: validation.StringInSlice(vmwarevsphereConfigVappTransports, true), }, "vcenter": { diff --git a/rancher2/structure_node_template_vsphere.go b/rancher2/structure_node_template_vsphere.go index 1e7d47f14..1615d13f4 100644 --- a/rancher2/structure_node_template_vsphere.go +++ b/rancher2/structure_node_template_vsphere.go @@ -14,18 +14,36 @@ func flattenVsphereConfig(in *vmwarevsphereConfig) []interface{} { if len(in.Cfgparam) > 0 { obj["cfgparam"] = toArrayInterface(in.Cfgparam) } + if len(in.CloneFrom) > 0 { + obj["clone_from"] = in.CloneFrom + } + if len(in.CloudConfig) > 0 { + obj["cloud_config"] = in.CloudConfig + } if len(in.Cloudinit) > 0 { obj["cloudinit"] = in.Cloudinit } + if len(in.ContentLibrary) > 0 { + obj["content_library"] = in.ContentLibrary + } if len(in.CPUCount) > 0 { obj["cpu_count"] = in.CPUCount } + if len(in.CreationType) > 0 { + obj["creation_type"] = in.CreationType + } + if len(in.CustomAttributes) > 0 { + obj["custom_attributes"] = toArrayInterface(in.CustomAttributes) + } if len(in.Datacenter) > 0 { - obj["datacenter"] = in.Datastore + obj["datacenter"] = in.Datacenter } if len(in.Datastore) > 0 { obj["datastore"] = in.Datastore } + if len(in.DatastoreCluster) > 0 { + obj["datastore_cluster"] = in.DatastoreCluster + } if len(in.DiskSize) > 0 { obj["disk_size"] = in.DiskSize } @@ -47,6 +65,21 @@ func flattenVsphereConfig(in *vmwarevsphereConfig) []interface{} { if len(in.Pool) > 0 { obj["pool"] = in.Pool } + if len(in.SshPassword) > 0 { + obj["ssh_password"] = in.SshPassword + } + if len(in.SshPort) > 0 { + obj["ssh_port"] = in.SshPort + } + if len(in.SshUser) > 0 { + obj["ssh_user"] = in.SshUser + } + if len(in.SshUserGroup) > 0 { + obj["ssh_user_group"] = in.SshUserGroup + } + if len(in.Tags) > 0 { + obj["tags"] = toArrayInterface(in.Tags) + } if len(in.Username) > 0 { obj["username"] = in.Username } @@ -87,18 +120,36 @@ func expandVsphereConfig(p []interface{}) *vmwarevsphereConfig { if v, ok := in["cfgparam"].([]interface{}); ok && len(v) > 0 { obj.Cfgparam = toArrayString(v) } + if v, ok := in["clone_from"].(string); ok && len(v) > 0 { + obj.CloneFrom = v + } + if v, ok := in["cloud_config"].(string); ok && len(v) > 0 { + obj.CloudConfig = v + } if v, ok := in["cloudinit"].(string); ok && len(v) > 0 { obj.Cloudinit = v } + if v, ok := in["content_library"].(string); ok && len(v) > 0 { + obj.ContentLibrary = v + } if v, ok := in["cpu_count"].(string); ok && len(v) > 0 { obj.CPUCount = v } + if v, ok := in["creation_type"].(string); ok && len(v) > 0 { + obj.CreationType = v + } + if v, ok := in["custom_attributes"].([]interface{}); ok && len(v) > 0 { + obj.CustomAttributes = toArrayString(v) + } if v, ok := in["datacenter"].(string); ok && len(v) > 0 { obj.Datacenter = v } if v, ok := in["datastore"].(string); ok && len(v) > 0 { obj.Datastore = v } + if v, ok := in["datastore_cluster"].(string); ok && len(v) > 0 { + obj.DatastoreCluster = v + } if v, ok := in["disk_size"].(string); ok && len(v) > 0 { obj.DiskSize = v } @@ -120,6 +171,21 @@ func expandVsphereConfig(p []interface{}) *vmwarevsphereConfig { if v, ok := in["pool"].(string); ok && len(v) > 0 { obj.Pool = v } + if v, ok := in["ssh_password"].(string); ok && len(v) > 0 { + obj.SshPassword = v + } + if v, ok := in["ssh_port"].(string); ok && len(v) > 0 { + obj.SshPort = v + } + if v, ok := in["ssh_user"].(string); ok && len(v) > 0 { + obj.SshUser = v + } + if v, ok := in["ssh_user_group"].(string); ok && len(v) > 0 { + obj.SshUserGroup = v + } + if v, ok := in["tags"].([]interface{}); ok && len(v) > 0 { + obj.Tags = toArrayString(v) + } if v, ok := in["username"].(string); ok && len(v) > 0 { obj.Username = v } diff --git a/scripts/start_testacc.sh b/scripts/start_testacc.sh index 137372d4a..4b65e4e40 100755 --- a/scripts/start_testacc.sh +++ b/scripts/start_testacc.sh @@ -24,10 +24,10 @@ export TESTACC_K3S_KUBECONFIG_NAME=${TESTACC_K3S_KUBECONFIG_NAME:-"testacc_kubec TESTACC_K3S_KUBECONFIG=${TESTACC_TEMP_DIR}"/"${TESTACC_K3S_KUBECONFIG_NAME} TESTACC_K3S_PORT=${TESTACC_K3S_PORT:-6443} TESTACC_K3S_SECRET=${TESTACC_K3S_SECRET:-"somethingtotallyrandom"} -TESTACC_K3S_VERSION=${TESTACC_K3S_VERSION:-"v0.10.1"} +TESTACC_K3S_VERSION=${TESTACC_K3S_VERSION:-"v0.10.2"} TESTACC_RANCHER_PORT=${TESTACC_RANCHER_PORT:-44443} -TESTACC_RANCHER_VERSION=${TESTACC_RANCHER_VERSION:-"v2.3.2"} +TESTACC_RANCHER_VERSION=${TESTACC_RANCHER_VERSION:-"v2.3.3"} # Download required software if not available ## jq diff --git a/website/docs/r/nodeTemplate.html.markdown b/website/docs/r/nodeTemplate.html.markdown index ca060c05f..ebbb791bc 100644 --- a/website/docs/r/nodeTemplate.html.markdown +++ b/website/docs/r/nodeTemplate.html.markdown @@ -12,6 +12,8 @@ Provides a Rancher v2 Node Template resource. This can be used to create Node Te amazonec2, azure, digitalocean, openstack and vsphere drivers are supported for node templates. +**Note** If you are upgrading to Rancher v2.3.3, please take a look to [final section](#Upgrading-to-Rancher-v2.3.3) + ## Example Usage ```hcl @@ -219,10 +221,16 @@ The following attributes are exported: * `boot2docker_url` - (Optional) vSphere URL for boot2docker iso image. Default `https://releases.rancher.com/os/latest/rancheros-vmware.iso` (string) * `cfgparam` - (Optional) vSphere vm configuration parameters (used for guestinfo) (list) +* `clone_from` - (Optional) If you choose creation type clone a name of what you want to clone is required. From Rancher v2.3.3 (string) +* `cloud_config` - (Optional) Filepath to a cloud-config yaml file to put into the ISO user-data. From Rancher v2.3.3 (string) * `cloudinit` - (Optional) vSphere cloud-init file or url to set in the guestinfo (string) +* `content_library` - (Optional) If you choose to clone from a content library template specify the name of the library. From Rancher v2.3.3 (string) * `cpu_count` - (Optional) vSphere CPU number for docker VM. Default `2` (string) +* `creation_type` - (Optional) Creation type when creating a new virtual machine. Supported values: vm, template, library, legacy. Default `legacy`. From Rancher v2.3.3 (string) +* `custom_attributes` - (Optional) vSphere custom attributes, format key/value e.g. `200=my custom value`. From Rancher v2.3.3 (List) * `datacenter` - (Optional) vSphere datacenter for docker VM (string) * `datastore` - (Optional) vSphere datastore for docker VM (string) +* `datastore_cluster` - (Optional) vSphere datastore cluster for virtual machine. From Rancher v2.3.3 (string) * `disk_size` - (Optional) vSphere size of disk for docker VM (in MB). Default `20480` (string) * `folder` - (Optional) vSphere folder for the docker VM. This folder must already exist in the datacenter (string) * `hostsystem` - (Optional) vSphere compute resource where the docker VM will be instantiated. This can be omitted if using a cluster with DRS (string) @@ -230,6 +238,11 @@ The following attributes are exported: * `network` - (Optional) vSphere network where the docker VM will be attached (list) * `password` - (Optional/Sensitive) vSphere password. Mandatory on Rancher v2.0.x and v2.1.x. Use `rancher2_cloud_credential` from Rancher v2.2.x (string) * `pool` - (Optional) vSphere resource pool for docker VM (string) +* `ssh_password` - (Optional) If using a non-B2D image you can specify the ssh password. Default `tcuser`. From Rancher v2.3.3 (string) +* `ssh_port` - (Optional) If using a non-B2D image you can specify the ssh port. Default `22`. From Rancher v2.3.3 (string) +* `ssh_user` - (Optional) If using a non-B2D image you can specify the ssh user. Default `docker`. From Rancher v2.3.3 (string) +* `ssh_user_group` - (Optional) If using a non-B2D image the uploaded keys will need chown'ed. Default `staff`. From Rancher v2.3.3 (string) +* `tags` - (Optional) vSphere tags id e.g. `urn:xxx`. From Rancher v2.3.3 (list) * `username` - (Optional/Sensitive) vSphere username. Mandatory on Rancher v2.0.x and v2.1.x. Use `rancher2_cloud_credential` from Rancher v2.2.x (string) * `vapp_ip_allocation_policy` - (Optional) vSphere vApp IP allocation policy. Supported values are: `dhcp`, `fixed`, `transient` and `fixedAllocated` (string) * `vapp_ip_protocol` - (Optional) vSphere vApp IP protocol for this deployment. Supported values are: `IPv4` and `IPv6` (string) @@ -255,3 +268,15 @@ Node Template can be imported using the Rancher Node Template ID $ terraform import rancher2_node_template.foo ``` +## Upgrading to Rancher v2.3.3 + +Due to [this feature](https://github.com/rancher/rancher/pull/23718) included on Rancher v2.3.3, `rancher2_node_template` are now global scope objects with RBAC around them, instead of user scope objects as they were. This means that existing node templates `id` field is changing on upgrade. Because the Terraform provider can not find the old `id`, it will try to recreate them. + +As a workaround, if you are upgrading Rancher from previous releases to v2.3.3, you need to get node templates new id from Rancher API, refresh tfstate and import `rancher2_node_template` resources with new id. + +``` +$ curl -sk -X GET -H "Authorization: Bearer ${RANCHER_TOKEN_KEY}" ${RANCHER_URL}/v3/nodeTemplates | jq .data +$ terraform refresh +$ terraform import rancher2_node_template. +$ terraform apply +```