Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vcd_ui_plugin resource and data source to programmatically manage UI Plugins #1059

Merged
merged 30 commits into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .changes/v3.10.0/1059-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* **New Resource:** `vcd_ui_plugin` to programmatically install and manage UI Plugins [GH-1059]
* **New Data Source:** `vcd_ui_plugin` to fetch existing UI Plugins [GH-1059]
2 changes: 2 additions & 0 deletions .changes/v3.10.0/1059-improvements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* The guide to install the Container Service Extension v4.0 now additionally explains how to install the
Kubernetes Container Clusters UI Plugin [GH-1059]
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
# You can check the comments on each resource/data source for more help and context.
# ------------------------------------------------------------------------------------------------------------

# VCD Provider configuration. It must be at least v3.9.0 and configured with a System administrator account.
# VCD Provider configuration. It must be at least v3.10.0 and configured with a System administrator account.
terraform {
required_providers {
vcd = {
source = "vmware/vcd"
version = ">= 3.9"
version = ">= 3.10"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# * Please read the guide present at https://registry.terraform.io/providers/vmware/vcd/latest/docs/guides/container_service_extension_4_0
# before applying this configuration.
#
# * Please apply "3.9-cse-4.0-install-step1.tf" first, located at
# * Please apply "3.10-cse-4.0-install-step1.tf" first, located at
# https://github.com/vmware/terraform-provider-vcd/tree/main/examples/container-service-extension-4.0/install/step1
#
# * Please review this HCL configuration before applying, to change the settings to the ones that fit best with your organization.
Expand All @@ -15,13 +15,13 @@
# You can check the comments on each resource/data source for more help and context.
# ------------------------------------------------------------------------------------------------------------

# VCD Provider configuration. It must be at least v3.9.0 and configured with a System administrator account.
# VCD Provider configuration. It must be at least v3.10.0 and configured with a System administrator account.
# This is needed to build the minimum setup for CSE v4.0 to work, like Organizations, VDCs, Provider Gateways, etc.
terraform {
required_providers {
vcd = {
source = "vmware/vcd"
version = ">= 3.9"
version = ">= 3.10"
}
}
}
Expand Down Expand Up @@ -293,7 +293,7 @@ resource "vcd_catalog_vapp_template" "cse_ova" {
ova_path = format("%s/%s", var.cse_ova_folder, var.cse_ova_file)
}

# Fetch the RDE Type created in 3.9-cse-4.0-install-step1.tf. This is required to be able to create the following
# Fetch the RDE Type created in 3.10-cse-4.0-install-step1.tf. This is required to be able to create the following
# Rights Bundle.
data "vcd_rde_type" "existing_capvcdcluster_type" {
vendor = "vmware"
Expand Down Expand Up @@ -675,7 +675,7 @@ resource "vcd_nsxt_firewall" "tenant_firewall" {
}
}

# Fetch the RDE Type created in 3.9-cse-4.0-install-step1.tf, as we need to create the configuration instance.
# Fetch the RDE Type created in 3.10-cse-4.0-install-step1.tf, as we need to create the configuration instance.
data "vcd_rde_type" "existing_vcdkeconfig_type" {
vendor = "vmware"
nss = "VCDKEConfig"
Expand Down Expand Up @@ -769,6 +769,17 @@ resource "vcd_vapp_vm" "cse_server_vm" {
]
}

output "publish_ui_plugin" {
value = "When CSE Server '${vcd_vapp_vm.cse_server_vm.name}' is ready, please install the Kubernetes Container Clusters UI plug-in 4.0 for VCD that you can download from https://docs.vmware.com/en/VMware-Cloud-Director-Container-Service-Extension/index.html"
data "vcd_org" "system_org" {
name = var.administrator_org
}

resource vcd_ui_plugin "k8s_container_clusters_ui_plugin" {
count = var.k8s_container_clusters_ui_plugin_path == "" ? 0 : 1
plugin_path = var.k8s_container_clusters_ui_plugin_path
enabled = true
tenant_ids = [
data.vcd_org.system_org.id,
vcd_org.solutions_organization.id,
vcd_org.tenant_organization.id,
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,11 @@ github_personal_access_token = "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# This user was created in Step 1. You need to provide a valid API token for it
cse_admin_user = "cse-admin"
cse_admin_api_token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# ------------------------------------------------
# Other configuration
# ------------------------------------------------
# This path points to the .zip file that contains the bundled Kubernetes Container Clusters UI Plugin.
# It is optional: if not set, it won't be installed.
# Remember to remove older CSE UI plugins if present (for example 3.x plugins) before installing this one.
k8s_container_clusters_ui_plugin_path = "/home/change-me/container-ui-plugin 4.0.zip"
Original file line number Diff line number Diff line change
Expand Up @@ -313,3 +313,12 @@ variable "syslog_port" {
description = "VCDKEConfig: Port for system logs"
default = ""
}

# ------------------------------------------------
# Other configuration
# ------------------------------------------------
variable "k8s_container_clusters_ui_plugin_path" {
type = string
description = "Path to the Kubernetes Container Clusters UI Plugin zip file"
default = ""
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
github.com/hashicorp/go-version v1.6.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1
github.com/kr/pretty v0.2.1
github.com/vmware/go-vcloud-director/v2 v2.21.0-alpha.3
github.com/vmware/go-vcloud-director/v2 v2.21.0-alpha.4
)

require (
Expand All @@ -20,7 +20,7 @@ require (
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-checkpoint v0.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
github.com/hashicorp/go-hclog v1.4.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-plugin v1.4.8 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,8 @@ github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvC
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY=
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/vmware/go-vcloud-director/v2 v2.21.0-alpha.3 h1:ARVhW7teXbmDtUKZKsyc/H+U1Ri80kO5wNpO/Ndelec=
github.com/vmware/go-vcloud-director/v2 v2.21.0-alpha.3/go.mod h1:QPxGFgrUcSyzy9IlpwDE4UNT3tsOy2047tJOPEJ4nlw=
github.com/vmware/go-vcloud-director/v2 v2.21.0-alpha.4 h1:wbRWysHIpmI+M9NpJpMzEZ0PWCMtVKNHWu4ruMbQQTE=
github.com/vmware/go-vcloud-director/v2 v2.21.0-alpha.4/go.mod h1:QPxGFgrUcSyzy9IlpwDE4UNT3tsOy2047tJOPEJ4nlw=
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
Expand Down
Binary file added test-resources/ui_plugin.zip
Binary file not shown.
2 changes: 1 addition & 1 deletion vcd/config_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build api || functional || catalog || vapp || network || extnetwork || org || query || vm || vdc || gateway || disk || binary || lb || lbServiceMonitor || lbServerPool || lbAppProfile || lbAppRule || lbVirtualServer || access_control || user || standaloneVm || search || auth || nsxt || role || alb || certificate || vdcGroup || ldap || rde || ALL
//go:build api || functional || catalog || vapp || network || extnetwork || org || query || vm || vdc || gateway || disk || binary || lb || lbServiceMonitor || lbServerPool || lbAppProfile || lbAppRule || lbVirtualServer || access_control || user || standaloneVm || search || auth || nsxt || role || alb || certificate || vdcGroup || ldap || rde || uiPlugin || ALL

package vcd

Expand Down
77 changes: 77 additions & 0 deletions vcd/datasource_vcd_ui_plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package vcd

import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func datasourceVcdUIPlugin() *schema.Resource {
return &schema.Resource{
ReadContext: datasourceVcdUIPluginRead,
Schema: map[string]*schema.Schema{
"vendor": {
Type: schema.TypeString,
Required: true,
Description: "The UI Plugin vendor name. Combination of `vendor`, `name` and `version` must be unique",
},
"name": {
Type: schema.TypeString,
Required: true,
Description: "The UI Plugin name. Combination of `vendor`, `name` and `version` must be unique",
},
"version": {
Type: schema.TypeString,
Required: true,
Description: "The version of the UI Plugin. Combination of `vendor`, `name` and `version` must be unique",
},
"license": {
Type: schema.TypeString,
Computed: true,
Description: "The license of the UI Plugin",
},
"link": {
Type: schema.TypeString,
Computed: true,
Description: "The website of the UI Plugin",
},
"description": {
Type: schema.TypeString,
Computed: true,
Description: "The description of the UI Plugin",
},
"provider_scoped": {
Type: schema.TypeBool,
Computed: true,
Description: "'true' if the UI Plugin scope is the service provider. 'false' if not",
},
"tenant_scoped": {
Type: schema.TypeBool,
Computed: true,
Description: "true if the UI Plugin scope is the tenants (organizations)",
},
"enabled": {
Type: schema.TypeBool,
Computed: true,
Description: "true if the UI Plugin is enabled. 'false' if not",
},
"status": {
Type: schema.TypeString,
Computed: true,
Description: "Status of the UI Plugin",
},
"tenant_ids": {
Type: schema.TypeSet,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Computed: true,
Description: "Set of Organization IDs where the UI Plugin is published to",
},
},
}
}

func datasourceVcdUIPluginRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
return genericVcdUIPluginRead(ctx, d, meta, "datasource")
}
2 changes: 2 additions & 0 deletions vcd/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ var globalDataSourceMap = map[string]*schema.Resource{
"vcd_nsxt_edgegateway_dhcp_forwarding": datasourceVcdNsxtEdgegatewayDhcpForwarding(), // 3.10
"vcd_org_saml": datasourceVcdOrgSaml(), // 3.10
"vcd_org_saml_metadata": datasourceVcdOrgSamlMetadata(), // 3.10
"vcd_ui_plugin": datasourceVcdUIPlugin(), // 3.10
}

var globalResourceMap = map[string]*schema.Resource{
Expand Down Expand Up @@ -211,6 +212,7 @@ var globalResourceMap = map[string]*schema.Resource{
"vcd_ip_space": resourceVcdIpSpace(), // 3.10
"vcd_nsxt_edgegateway_dhcp_forwarding": resourceVcdNsxtEdgegatewayDhcpForwarding(), // 3.10
"vcd_org_saml": resourceVcdOrgSaml(), // 3.10
"vcd_ui_plugin": resourceVcdUIPlugin(), // 3.10
}

// Provider returns a terraform.ResourceProvider.
Expand Down
2 changes: 1 addition & 1 deletion vcd/provider_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build api || functional || catalog || vapp || network || extnetwork || org || query || vm || vdc || gateway || disk || binary || lb || lbAppProfile || lbAppRule || lbServiceMonitor || lbServerPool || lbVirtualServer || user || access_control || standaloneVm || search || auth || nsxt || role || alb || certificate || vdcGroup || ldap || rde || ALL
//go:build api || functional || catalog || vapp || network || extnetwork || org || query || vm || vdc || gateway || disk || binary || lb || lbAppProfile || lbAppRule || lbServiceMonitor || lbServerPool || lbVirtualServer || user || access_control || standaloneVm || search || auth || nsxt || role || alb || certificate || vdcGroup || ldap || rde || uiPlugin || ALL

package vcd

Expand Down
28 changes: 28 additions & 0 deletions vcd/remove_leftovers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,25 @@ func removeLeftovers(govcdClient *govcd.VCDClient, verbose bool) error {
if err != nil {
return err
}

// --------------------------------------------------------------
// Plugins
// --------------------------------------------------------------
uiPlugins, err := govcdClient.GetAllUIPlugins()
if err != nil {
return fmt.Errorf("error retrieving UI Plugins: %s", err)
}
for _, uiPlugin := range uiPlugins {
// This will delete all UI Plugins that match the `isTest` regex.
toBeDeleted := shouldDeleteEntity(alsoDelete, doNotDelete, uiPlugin.UIPluginMetadata.PluginName, "vcd_ui_plugin", 1, verbose)
if toBeDeleted {
err = deleteUIPlugin(uiPlugin)
if err != nil {
return err
}
}
}

return nil
}

Expand Down Expand Up @@ -655,3 +674,12 @@ func deleteRdeType(rdeType *govcd.DefinedEntityType) error {
}
return nil
}

func deleteUIPlugin(uiPlugin *govcd.UIPlugin) error {
fmt.Printf("\t\t REMOVING UI PLUGIN %s\n", uiPlugin.UIPluginMetadata.ID)
err := uiPlugin.Delete()
if err != nil {
return fmt.Errorf("error deleting UI Plugin '%s': %s", uiPlugin.UIPluginMetadata.ID, err)
}
return nil
}
Loading