From 6bfdc751091d687adae241435d1b433776ecbeb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20L=C3=BCke?= Date: Wed, 12 Aug 2020 12:43:00 +0200 Subject: [PATCH] Add the kvm-libvirt platform to lokoctl The KVM libvirt Terraform module was not yet available from lokoctl despite it being an easy way to try out Lokomotive without any cloud provider accounts (and their attached costs). It allows to use Lokomotive on any Flatcar Container Linux image, even local development builds. It also gives direct access to the VGA console for debugging. The cluster VMs can be shut down in virt-manager while they are not needed. --- README.md | 1 + .../flatcar-linux/kubernetes/bootkube.tf | 5 + .../flatcar-linux/kubernetes/controllers.tf | 2 +- .../flatcar-linux/kubernetes/outputs.tf | 12 - .../flatcar-linux/kubernetes/require.tf | 3 +- .../flatcar-linux/kubernetes/variables.tf | 13 +- .../kubernetes/workers/require.tf | 29 +- .../kvm-libvirt-cluster.lokocfg.envsubst | 11 + cli/cmd/root.go | 1 + .../platforms/kvm-libvirt.md | 142 +++++++++ docs/quickstarts/kvm-libvirt.md | 284 ++++++++++++++++++ pkg/assets/generated_assets.go | 24 +- pkg/platform/kvmlibvirt/kvmlibvirt.go | 198 ++++++++++++ pkg/platform/kvmlibvirt/template.go | 186 ++++++++++++ 14 files changed, 863 insertions(+), 48 deletions(-) create mode 100644 ci/kvm-libvirt/kvm-libvirt-cluster.lokocfg.envsubst create mode 100644 docs/configuration-reference/platforms/kvm-libvirt.md create mode 100644 docs/quickstarts/kvm-libvirt.md create mode 100644 pkg/platform/kvmlibvirt/kvmlibvirt.go create mode 100644 pkg/platform/kvmlibvirt/template.go diff --git a/README.md b/README.md index a1890551a..281adc073 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ Follow one of the quickstart guides for the supported platforms: * [Packet quickstart](docs/quickstarts/packet.md) * [AWS quickstart](docs/quickstarts/aws.md) * [Bare metal quickstart](docs/quickstarts/baremetal.md) +* [KVM libvirt quickstart](docs/quickstarts/kvm-libvirt.md) ## Documentation diff --git a/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/bootkube.tf b/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/bootkube.tf index 8c5463ce2..ef3718986 100644 --- a/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/bootkube.tf +++ b/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/bootkube.tf @@ -18,6 +18,11 @@ module "bootkube" { enable_reporting = var.enable_reporting enable_aggregation = var.enable_aggregation + # Disable the self hosted kubelet. + disable_self_hosted_kubelet = var.disable_self_hosted_kubelet + # Extra flags to API server. + kube_apiserver_extra_flags = var.kube_apiserver_extra_flags + certs_validity_period_hours = var.certs_validity_period_hours } diff --git a/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/controllers.tf b/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/controllers.tf index 01c4daf7f..c2c6e4db2 100644 --- a/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/controllers.tf +++ b/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/controllers.tf @@ -11,7 +11,7 @@ resource "libvirt_pool" "volumetmp" { resource "libvirt_volume" "base" { name = "${var.cluster_name}-base" - source = var.os_image_unpacked + source = var.os_image pool = libvirt_pool.volumetmp.name format = "qcow2" } diff --git a/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/outputs.tf b/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/outputs.tf index 90950d075..912c1aa7c 100644 --- a/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/outputs.tf +++ b/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/outputs.tf @@ -6,18 +6,6 @@ output "kubeconfig" { value = module.bootkube.kubeconfig-kubelet } -output "machine_domain" { - value = var.machine_domain -} - -output "cluster_name" { - value = var.cluster_name -} - -output "ssh_keys" { - value = var.ssh_keys -} - output "libvirtpool" { value = libvirt_pool.volumetmp.name } diff --git a/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/require.tf b/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/require.tf index 2318ef10c..e0b437615 100644 --- a/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/require.tf +++ b/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/require.tf @@ -4,13 +4,12 @@ terraform { required_version = ">= 0.12.0" required_providers { - ct = "= 0.5.0" + ct = "~> 0.5.0" local = "~> 1.2" null = "~> 2.1" template = "~> 2.1" tls = "~> 2.0" libvirt = "~> 0.6.0" - packet = "~> 2.7.3" random = "~> 2.2" } } diff --git a/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/variables.tf b/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/variables.tf index b6ad0eece..0e034a681 100644 --- a/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/variables.tf +++ b/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/variables.tf @@ -6,7 +6,7 @@ variable "cluster_name" { } # Nodes -variable "os_image_unpacked" { +variable "os_image" { type = string description = "Path to unpacked Flatcar Container Linux image flatcar_production_qemu_image.img (probably after a qemu-img resize IMG +5G)" } @@ -105,6 +105,17 @@ variable "enable_aggregation" { default = true } +variable "kube_apiserver_extra_flags" { + description = "Extra flags passed to self-hosted kube-apiserver." + type = list(string) + default = [] +} + +variable "disable_self_hosted_kubelet" { + description = "Disable the self hosted kubelet installed by default" + type = bool +} + # Certificates variable "certs_validity_period_hours" { diff --git a/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/workers/require.tf b/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/workers/require.tf index 7da021ee4..e0b437615 100644 --- a/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/workers/require.tf +++ b/assets/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/workers/require.tf @@ -2,25 +2,14 @@ terraform { required_version = ">= 0.12.0" -} - -provider "ct" { - version = "0.4.0" -} - -provider "local" { - version = "1.4.0" -} - -provider "template" { - version = "~> 2.1" -} - -provider "tls" { - version = "~> 2.0" -} -provider "libvirt" { - version = "~> 0.6.0" - uri = "qemu:///system" + required_providers { + ct = "~> 0.5.0" + local = "~> 1.2" + null = "~> 2.1" + template = "~> 2.1" + tls = "~> 2.0" + libvirt = "~> 0.6.0" + random = "~> 2.2" + } } diff --git a/ci/kvm-libvirt/kvm-libvirt-cluster.lokocfg.envsubst b/ci/kvm-libvirt/kvm-libvirt-cluster.lokocfg.envsubst new file mode 100644 index 000000000..42554f517 --- /dev/null +++ b/ci/kvm-libvirt/kvm-libvirt-cluster.lokocfg.envsubst @@ -0,0 +1,11 @@ +cluster "kvm-libvirt" { + asset_dir = pathexpand("~/lokoctl-assets") + ssh_pubkeys = [file(pathexpand("~/.ssh/id_rsa.pub"))] + cluster_name = "vmcluster" + machine_domain = "vmcluster.k8s" + os_image = "file:///var/tmp/flatcar_production_qemu_image.img" + + worker_pool "one" { + count = 2 + } +} diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 5bdccd899..a837cff4c 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -25,6 +25,7 @@ import ( _ "github.com/kinvolk/lokomotive/pkg/platform/aks" _ "github.com/kinvolk/lokomotive/pkg/platform/aws" _ "github.com/kinvolk/lokomotive/pkg/platform/baremetal" + _ "github.com/kinvolk/lokomotive/pkg/platform/kvmlibvirt" _ "github.com/kinvolk/lokomotive/pkg/platform/packet" // Register backends by adding an anonymous import. diff --git a/docs/configuration-reference/platforms/kvm-libvirt.md b/docs/configuration-reference/platforms/kvm-libvirt.md new file mode 100644 index 000000000..bce848f0e --- /dev/null +++ b/docs/configuration-reference/platforms/kvm-libvirt.md @@ -0,0 +1,142 @@ +# Lokomotive KVM libvirt configuration reference + +## Contents + +* [Introduction](#introduction) +* [Prerequisites](#prerequisites) +* [Configuration](#configuration) +* [Attribute reference](#attribute-reference) +* [Applying](#applying) +* [Destroying](#destroying) + +## Introduction + +This configuration reference provides information on configuring a Lokomotive cluster on KVM libvirt VMs +with all the configuration options available to the user. + +## Prerequisites + +* Terraform providers and libvirt setup from the [quickstart guide](../../quickstarts/kvm-libvirt.md) +* `lokoctl` [installed locally.](../../installer/lokoctl.md) +* `kubectl` installed locally to access the Kubernetes cluster. + +### Configuration + +To create a Lokomotive cluster, we need to define a configuration. + +Example configuration file: + +```tf + +cluster "kvm-libvirt" { + + asset_dir = pathexpand("./assets") + + cluster_name = "vmcluster" + + machine_domain = "vmcluster.k8s" + + os_image = "file:///home/myuser/Downloads/flatcar_production_qemu_image.img" + + ssh_pubkeys = [file(pathexpand("~/.ssh/id_rsa.pub"))] + + controller_count = 1 + + node_ip_pool = "192.168.192.0/24" + + disable_self_hosted_kubelet = false + + kube_apiserver_extra_flags = [] + + controller_virtual_cpus = 1 + controller_virtual_memory = 2048 + + controller_clc_snippets = [] + + network_mtu = 1480 + network_ip_autodetection_method = "first-found" + + pod_cidr = "10.1.0.0/16" + service_cidr = "10.2.0.0/16" + + cluster_domain_suffix = "cluster.local" + + enable_reporting = false + enable_aggregation = true + + certs_validity_period_hours = 8760 + + worker_pool "worker-pool-1" { + count = 2 + + virtual_cpus = 1 + virtual_memory = 2048 + + labels = "foo=oof,bar=,baz=zab" + + clc_snippets = [ + <NOTE: Lokomotive uses a relatively restrictive Pod Security Policy by default. This policy +>disallows running containers as root. Refer to the +>[Pod Security Policy documentation](../concepts/securing-lokomotive-cluster.md#cluster-wide-pod-security-policy) +>for more details. + +## Cleanup + +To destroy the cluster, execute the following command: + +```console +lokoctl cluster destroy +``` + +Confirm you want to destroy the cluster by typing `yes` and hitting **Enter**. + +You can now safely delete the directory created for this guide if you no longer need it. + +## Troubleshooting + +If you want to log in using SSH for debugging purposes, use the Flatcar Container Linux default user `core`. + +You can look up the node IP address in `virt-manager` or resolve them from the hostnames, +using the libvirt DNS server: + +```console +host vmcluster-controller-0.vmcluster.k8s 192.168.192.1 +Using domain server: +Name: 192.168.192.1 +Address: 192.168.192.1#53 +Aliases: + +vmcluster-controller-0.vmcluster.k8s has address 192.168.192.10 +``` + +On each node list the containers with `docker ps` and follow the system logs with `journalctl -f`. + diff --git a/pkg/assets/generated_assets.go b/pkg/assets/generated_assets.go index 121f440ac..930c42f39 100644 --- a/pkg/assets/generated_assets.go +++ b/pkg/assets/generated_assets.go @@ -4974,9 +4974,9 @@ var vfsgenAssets = func() http.FileSystem { "/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/bootkube.tf": &vfsgen۰CompressedFileInfo{ name: "bootkube.tf", modTime: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC), - uncompressedSize: 1222, + uncompressedSize: 1417, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x94\xc1\x6e\xdb\x3c\x0c\xc7\xef\x7a\x0a\xc2\x9f\x4f\x05\xaa\xaf\x2f\x90\xd3\x76\xde\x65\xc7\xa2\x10\x14\x89\x49\x88\xca\x92\x41\xd1\x5e\x8a\xc0\xef\x3e\xc8\x89\x13\xd9\x5d\xb1\xcb\x04\x9f\xc4\x9f\xff\xfc\x8b\xa4\xd4\x25\x3f\x04\x84\x66\x9f\x92\xbc\x0f\x7b\x6c\xe0\xa2\x00\x72\x1a\xd8\x21\x5c\xd7\x0e\x1a\xad\xff\xbf\x7e\x77\x4c\x01\xb8\x30\x64\x41\x36\xd1\x76\x08\x3b\x18\x2d\xeb\x7a\x4b\x29\x80\xff\xe0\x9b\x8d\x31\x09\x0c\x19\xc1\x7d\xb8\x40\x0e\x3c\xf6\x18\x3d\x46\x47\x98\x21\x45\x70\x29\x0a\xa7\x10\x90\x33\x24\x06\x39\x21\x31\x7c\xff\xf1\x13\x18\x5d\x62\x9f\x15\x80\xed\xc9\x64\xe4\xb1\x20\xf7\xb5\x83\x57\x6f\xc5\x6a\xc1\xae\x0f\x56\xd0\x1c\x28\xa0\x7e\xa8\x15\x0f\xf9\xf5\xe5\x4d\x73\x49\xc7\xe8\xdf\xd6\x4a\x06\xcf\x52\xa8\x00\x3b\x08\xb4\x1f\x89\xc5\xf8\xd4\x59\x8a\x95\xc8\x73\x67\xdd\x89\x22\xea\x27\x1d\x51\x7e\x25\x7e\x37\x14\x05\xf9\x60\x1d\xea\x17\x6d\xbd\x67\xcc\x19\xb3\x7e\xd9\x88\x53\x9f\x17\x9b\xff\x46\x1c\xc5\xf9\x4f\x45\xd8\xc1\xdf\x4b\xa0\x9f\xee\x15\x28\x1e\x73\x46\x31\x9e\x18\xa0\x2e\x65\x69\xde\x3d\xa4\x00\x16\x3f\x9d\x0c\x5b\xac\x0a\xa9\x8a\xa4\xde\xd8\x41\x92\x47\x41\x27\x94\xa2\xe9\x50\x4e\xc9\x6f\x7e\xfa\x82\x2a\x42\x7d\xf2\xc6\x91\x5f\x19\x5b\x72\x2e\xb1\x32\x9a\xc8\x23\x39\xdc\xa0\x57\xac\x8e\x55\x03\x7a\x2d\xbc\xc9\xc3\xe1\x40\xe7\xcd\xa4\xae\x62\xa5\xcc\xd1\xee\x03\x1a\xc6\x3e\xb1\x50\x3c\xd6\xf2\xdb\xd8\x03\xb7\xc7\x23\xe3\xd1\x96\x13\x7d\xc2\xab\x58\x39\xa6\x43\x96\x6c\x46\x1b\xc8\x93\x7c\x98\x1e\x99\x92\x37\xa7\x34\x70\x5e\xac\x7d\x4d\xa8\x49\xa9\xd2\x71\x68\x56\x2d\x6f\xa0\xd9\x34\xfd\x7a\x8d\x5d\x1a\xa2\x3c\x0c\x3d\x18\x33\x47\x14\xc0\x22\x53\x2e\x79\xdb\x5e\xea\xfb\x3b\x3d\x57\x93\xda\xb6\x17\x8a\x1e\xcf\x93\x6e\xdb\xcb\x6d\x6c\x6f\xb5\x9b\x9a\x72\xac\xd1\xce\xfe\x4b\x56\x80\x19\xad\x9b\x33\xa7\xd3\xf3\xf6\x0c\xac\x9e\x0e\xf8\xd3\xe3\x51\xa8\x75\x9e\x1b\xb5\xde\x54\x00\x93\x9a\xd4\xef\x00\x00\x00\xff\xff\xd6\xbc\xe7\xbf\xc6\x04\x00\x00"), + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x94\xcf\x6e\xdb\x30\x0c\xc6\xef\x7a\x8a\x0f\x59\x4e\x05\xaa\xf5\x05\x72\x18\xd6\x1d\x76\x19\x06\xec\x58\x14\x82\x22\x31\x89\x50\x59\x32\x28\x3a\x4b\x11\xe4\xdd\x07\xd9\xf9\x63\xbb\x6b\x77\x99\xe1\x93\xbe\x9f\x3f\x52\x34\xc9\x26\xfb\x2e\x12\x16\xeb\x9c\xe5\xa5\x5b\xd3\x02\x47\x05\x94\xdc\xb1\x23\x0c\xcf\x0a\x0b\xad\x3f\x0f\xef\x15\x53\x80\x8b\x5d\x11\x62\x93\x6c\x43\x58\x61\x6f\x59\x8f\x8f\x94\x02\x3e\xe1\xab\x4d\x29\x0b\xba\x42\x70\xaf\x2e\x06\x07\x4f\x2d\x25\x4f\xc9\x05\x2a\xc8\x09\x2e\x27\xe1\x1c\x23\x71\x41\x66\xc8\x8e\x02\xe3\xf1\xc7\x2f\x30\xb9\xcc\xbe\x28\xc0\xb6\xc1\x14\xe2\x7d\x45\xae\xcf\x0a\x4f\xde\x8a\xd5\x42\x4d\x1b\xad\x90\xd9\x84\x48\xfa\xe6\x56\x73\x28\x4f\x0f\xcf\x9a\x6b\x38\x26\xff\x3c\x75\x32\x74\x90\x4a\x45\xac\x10\xc3\x7a\x1f\x58\x8c\xcf\x8d\x0d\x69\x64\x72\xdf\x58\xb7\x0b\x89\xf4\x9d\x4e\x24\xbf\x33\xbf\x98\x90\x84\x78\x63\x1d\xe9\x07\x6d\xbd\x67\x2a\x85\x8a\x7e\x98\x99\x87\xb6\x5c\xd2\xfc\x3f\xe6\x24\xce\xbf\x29\xc2\x0a\xff\x2e\x81\xbe\xbb\x56\xa0\xe6\x58\x0a\x89\xf1\x81\x81\x71\x29\xeb\xcf\xbb\x4a\x0a\xb8\xe4\xd3\x48\x37\xc7\x46\x92\x1a\x91\xa1\x35\xb6\x93\xec\x49\xc8\x49\xc8\xc9\x34\x24\xbb\xec\x67\x1f\xbd\x43\x55\xa3\x36\x7b\xe3\x82\x9f\x24\x76\x89\x79\xd1\x6a\x6b\x12\xef\x83\xa3\x19\x3a\x60\x63\x6d\xd4\xa0\x43\xe1\x4d\xe9\x36\x9b\x70\x98\x75\xea\x44\xab\x65\x4e\x76\x1d\xc9\x30\xb5\x99\x25\xa4\xed\xd8\x7e\xae\xdd\x70\xbb\xdd\x32\x6d\x6d\xbd\xd1\x1b\x7c\xa4\x0d\x23\xf1\x18\x4a\x15\x6a\xa7\xa3\x50\xdc\x60\x97\x8b\x90\x47\x9d\xab\x48\xa2\x15\xe0\x07\xc4\x54\xd9\x0c\xb2\x39\xcb\x67\xf3\x0f\x88\x3e\xc8\xb7\x83\xb0\xc5\x26\xda\x6d\x81\x64\x7c\xf9\xf9\x1d\x43\xf3\x54\xfb\x0a\x1a\xdb\x86\xe1\xa4\x0e\x02\x5b\x33\xb0\x83\xfb\xfb\x40\xbd\x82\x23\x96\x62\xf6\x36\x06\x1f\xe4\xd5\xb4\xc4\x21\x7b\xb3\xcb\x1d\x5f\xbe\xff\x80\x50\x27\xa5\x6a\xd3\x62\x31\xe9\xda\x05\x16\xb3\xbe\x1d\x36\x91\xcb\x5d\x92\x5b\x4d\x6f\x8c\xe9\x15\x05\x5c\x6c\xea\x9e\x5a\x2e\x8f\xe3\x15\x74\xba\x1f\x0d\xdb\x72\x79\x0c\xc9\xd3\xe1\xa4\x97\xcb\xe3\x79\xf2\xce\xbf\xff\xb4\xa8\xd7\xda\xdb\x3e\xff\x1a\x15\xe8\xd1\x71\x7f\xf5\xe1\x74\x7f\xdc\x03\x93\xed\x87\xbf\xed\xbf\x4a\x4d\xe3\x9c\xa9\xe9\xa1\x02\x4e\xea\xa4\xfe\x04\x00\x00\xff\xff\xc0\x5a\x13\xb4\x89\x05\x00\x00"), }, "/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/cl": &vfsgen۰DirInfo{ name: "cl", @@ -4992,23 +4992,23 @@ var vfsgenAssets = func() http.FileSystem { "/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/controllers.tf": &vfsgen۰CompressedFileInfo{ name: "controllers.tf", modTime: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC), - uncompressedSize: 3100, + uncompressedSize: 3091, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x56\x4d\x6f\x23\x37\x0c\xbd\xcf\xaf\x20\xb4\x3e\x24\x6d\x32\xce\x6e\x81\xa2\x08\xe0\x53\xf7\xdc\x3d\xb4\xb7\x20\x10\x64\x89\x63\x6b\xad\x91\xa6\x92\xc6\x89\x61\xf8\xbf\x17\x94\xe6\xd3\x6b\x67\xd3\xf8\x34\x96\xc8\x47\xf2\xf1\x91\x33\x1e\x83\x6b\xbd\x44\x60\x5e\x58\xe5\x6a\x1e\xa2\xd7\x76\xc3\x80\xed\x9d\x69\x6b\x6c\x44\xdc\x32\x38\x16\x00\x06\xed\x26\x6e\x01\x56\xf0\x7b\x01\x10\x1a\x94\x5a\x18\x58\x41\x25\x4c\xc0\xe2\x54\x14\x23\x94\xd1\xeb\xbd\xf6\x91\x37\xce\x99\x01\x29\xd6\x4d\x06\xb2\xa2\x46\x58\x01\xdb\xd7\x61\x71\x9c\x45\x2d\xc7\x98\xa5\xc7\xd0\x9a\x78\x62\x05\x40\x3c\x34\xc9\x41\x69\x4f\x7f\xe9\x9a\xfe\x2e\xf7\xc2\x2f\x63\xdd\x2c\xdf\x09\x74\x31\xc5\x6c\xc8\x80\xad\x45\xc0\x49\x7e\x54\x27\x5b\x1c\xf7\xc2\x97\xd2\xb4\x21\xa2\xe7\x74\x7e\xba\x4f\x76\x44\x40\x06\x5a\x01\x99\xb8\xc0\x75\x2d\x36\xc8\x5b\xdb\x08\xb9\x43\x45\x69\x3a\x67\x12\xcc\x94\x8d\x72\xe0\xa2\x24\xb8\x02\xa0\x72\xbe\x16\x91\xa2\xfd\x2b\xdd\xcb\x97\x9f\xa5\x29\x9d\x8d\xde\x19\x83\xfe\x5e\xe9\xb0\x9b\x65\xdc\xff\xae\x64\x3e\x71\x5d\x1c\xa5\x6b\x6d\x2c\xb5\x55\xf8\x7a\x2a\xbb\xc8\x00\xe9\x74\x0a\x94\x50\x06\x3f\x9e\xee\x0b\x00\x22\xa1\xcb\x89\x6b\x35\xa9\x31\x9f\x95\x74\x5f\xea\x09\x0b\x23\xe2\xbb\xd8\x98\x54\xf2\x16\x2b\x7a\x63\x75\xd4\xce\x32\x60\xe3\xe3\x94\x90\xff\xcb\xc4\xfd\x00\x33\x49\xfd\x67\x39\xf7\xa4\x5d\x65\x8b\x8e\xd0\x52\x8f\x95\x88\xa2\x94\x91\x4b\x67\x2b\xbd\x99\xd8\x0e\x81\xc3\xd3\x24\x9f\xe7\xd2\xa3\x55\xe8\x51\x5d\xae\xdf\x62\x7c\x71\x7e\x47\x23\x56\x5b\x8c\xe7\x62\xe8\x12\x9a\x94\x5e\x00\xd4\x4e\x0d\xd7\xcc\x8a\x48\x95\x2a\x57\x0b\x6d\x47\x97\x5a\xc8\xad\xb6\xc8\xf3\x79\x01\x20\x94\xf2\x18\x02\x06\x58\xc1\x13\x59\x58\xa7\x90\xeb\x26\x31\xf2\x5c\x10\x84\x0d\x29\x3a\x80\x71\x52\x18\xee\xac\x39\xc0\x0a\xa2\x6f\x31\x9d\x7e\x02\x29\x6c\xde\x1a\xd5\x21\xdb\xa4\x4c\x03\x6c\xd1\x93\xc9\xe9\x72\x89\x39\x85\xb9\xf0\xbb\xf4\x72\xb9\x1d\xfb\x57\xc9\x7f\x7b\x9a\xaf\x2a\x81\x68\xd9\xcb\xa6\x1d\x38\xa1\x6c\x5a\x61\xb8\x6c\xda\x40\x34\x62\xed\xfc\xe1\xec\x2e\x1f\x12\x1d\xd5\x0b\x97\xd5\x86\x0f\xbd\x58\x01\x73\x4d\x5c\x3a\xbf\x29\x2b\x23\xa2\x14\xfe\xde\x68\xdb\xbe\x2e\xb3\x12\xf2\xec\x79\xa4\x3d\xd2\x09\x61\x22\xbb\xfe\xa8\xec\x1f\xe6\x1a\xd1\x2a\x35\x40\x87\x5d\xd7\x81\x37\x06\xf3\x6c\x7d\xfc\x00\x44\x7d\x28\x00\x36\x5e\x34\x5b\x2d\x87\x96\xea\x10\xd1\xf2\x7e\x0f\x77\x6a\x60\xbd\x75\x27\x43\xae\x6d\x44\x5f\x09\x89\x9d\xdb\x70\xae\xce\x66\xbf\xbb\x28\x93\x6a\x73\x58\x80\xad\x0b\x71\xb2\xc8\x3e\xd2\xb0\xa9\x50\x3b\x90\x27\xa9\x95\x27\xe8\x9b\x73\xd9\xde\xc1\xe7\x07\xf8\x15\x26\x18\xb7\xcf\xf0\x09\xfe\xf9\xf6\xf5\xdb\x23\xb4\x01\x41\x04\x68\xda\xb5\xd1\x32\xa1\x82\xb6\xb0\x6b\xd7\x98\x1b\x96\x82\xbd\x08\x1d\x79\xe5\x3c\x37\x28\x02\x8e\x6a\x4f\x52\xa6\x51\x07\x36\xcc\xfa\x5c\xc1\xc3\xb4\xcf\x34\xfc\x8e\x15\xd2\xef\x90\x88\x75\x63\x44\x44\x5e\x69\x33\xeb\x6a\x8e\x76\x6d\x8b\x00\x04\xab\x9b\x06\x63\xb8\x10\xca\x48\xde\xdf\x8e\x05\xcc\x02\xcd\x8b\xe8\x42\xbd\xb7\x84\x1e\x89\x3e\x19\xb4\xc1\x1b\xb6\x38\xa6\xf7\x73\xed\x54\x6b\xf0\xb4\x94\x66\x39\x7a\x95\x07\x51\x9b\x32\xd6\x8d\x61\xb7\x24\xb1\xbd\xf0\x94\xf2\xb1\xdb\x25\x7f\x0a\x6b\x5d\x4c\x5d\x92\x07\x49\x2d\x52\xd8\x50\x91\x56\x6a\x0c\xe0\x2c\x8c\x50\x01\x9c\x87\xb8\x45\xed\xe1\xeb\x5f\x7f\x83\x47\xe9\xbc\x0a\x09\x08\xa3\x54\xfc\xec\xe5\xf9\x61\xe9\x25\xb0\x71\x93\x7e\xf8\x65\x9c\xad\xe7\x2b\x78\x1a\x42\x93\x74\x68\x11\x65\xbc\x14\xe2\xbb\xd3\xf6\x86\xdd\xb1\xbb\x4b\xea\x20\xaf\x50\xfe\x32\xa8\xe0\x36\x61\x8d\x5a\x3e\xab\x9d\xd2\xb0\xf1\xe6\xf3\xc3\x1d\xe4\xd6\x94\x6b\xe7\x22\x99\x97\xa3\xcf\x3d\x3d\x1a\x8c\x19\x2b\x84\x2d\xdf\xe1\x21\xc0\x39\x8f\xdf\x83\xb3\x68\xa5\x53\x98\xc6\xaf\xb7\xcb\x5e\x3d\x21\xca\x06\x1e\xd0\xef\xb5\xa4\xd9\x84\x15\xcc\x46\xb6\xbf\xa1\x43\x1a\xd9\x33\xdf\x44\x0f\x0f\x6d\x55\xe9\xd7\xf3\x37\xde\xec\x72\x3e\x97\xe7\xb2\x4e\x1c\x7d\x40\xc9\x6c\xb1\x38\x5e\x6f\xec\xe2\x98\x7b\xba\xda\xc6\xd8\x84\xc7\xe5\xf2\x5d\xd6\x97\x15\xf0\xf8\xe5\xb7\x3f\x1e\x18\x7c\xa2\xb5\x34\x95\x9a\x58\xbb\x3d\xfe\x30\x22\x09\x69\xec\xc3\x44\x60\x33\xfa\xba\x4f\xf1\x0b\x9f\x09\xc4\xd5\x7f\x01\x00\x00\xff\xff\x53\xe7\x56\x31\x1c\x0c\x00\x00"), + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x9c\x56\x4d\x6f\x23\x37\x0c\xbd\xcf\xaf\x20\xb4\x3e\x64\xdb\x64\xbc\xbb\x05\x8a\x22\x80\x4f\xdd\x73\xf7\xd0\xde\x82\x40\x90\x25\x8e\xad\x8d\x46\x9a\x4a\x1a\x27\x86\xe1\xff\x5e\x50\x9a\xef\xb5\xb3\x69\x7c\x1a\x4b\xe4\x23\xf9\xf8\xc8\x19\x8f\xc1\xb5\x5e\x22\x30\x2f\xac\x72\x35\x0f\xd1\x6b\xbb\x63\xc0\x0e\xce\xb4\x35\x36\x22\xee\x19\x9c\x0a\x00\x83\x76\x17\xf7\x00\x1b\xf8\xbd\x00\x08\x0d\x4a\x2d\x0c\x6c\xa0\x12\x26\x60\x71\x2e\x8a\x11\xca\xe8\xed\x41\xfb\xc8\x1b\xe7\xcc\x80\x14\xeb\x26\x03\x59\x51\x23\x6c\x80\x1d\xea\xb0\x3a\xcd\xa2\x96\x63\xcc\xd2\x63\x68\x4d\x3c\xb3\x02\x20\x1e\x9b\xe4\xa0\xb4\xa7\xbf\x74\x4d\x7f\xd7\x07\xe1\xd7\xb1\x6e\xd6\x6f\x04\xba\x98\x62\x36\x64\xc0\xb6\x22\xe0\x24\x3f\xaa\x93\xad\x4e\x07\xe1\x4b\x69\xda\x10\xd1\x73\x3a\x3f\xdf\x25\x3b\x22\x20\x03\x6d\x80\x4c\x5c\xe0\xba\x16\x3b\xa4\xec\x9c\x33\xc9\x7b\x4a\x42\x39\x50\x50\x12\x4a\x01\x50\x39\x5f\x8b\x48\x41\xfe\x95\xee\xf9\xcb\xcf\xb2\x93\xce\x46\xef\x8c\x41\x7f\xa7\x74\x78\x9a\x25\xda\xff\xae\x24\x3c\x71\x5d\x9d\xa4\x6b\x6d\x2c\xb5\x55\xf8\x72\x2e\xbb\xc8\x00\xe9\x74\x0a\x94\x50\x06\x3f\x9e\xee\x0b\x00\xaa\xbd\xcb\x89\x6b\x35\xa9\x31\x9f\x95\x74\x5f\x6a\x35\xb2\x30\x22\xbe\x89\x8d\x49\x25\xaf\xb1\xa2\x77\x56\x47\xed\x2c\x03\x36\x3e\x4e\x09\xf9\xbf\x4c\xdc\x0d\x30\x93\xd4\x7f\x96\x73\x4f\xda\x55\xb6\xe8\x08\x2d\xf5\x58\x89\x28\x4a\x19\xb9\x74\xb6\xd2\xbb\x89\xed\x10\x38\x3c\x4c\xf2\x79\x2c\x3d\x5a\x85\x1e\xd5\xe5\xfa\x2d\xc6\x67\xe7\x9f\x68\xb2\x6a\x8b\x71\x29\x86\x2e\xa1\x49\xe9\x05\x40\xed\xd4\x70\xcd\xac\x88\x54\xa9\x72\xb5\xd0\x76\x74\xa9\x85\xdc\x6b\x8b\x3c\x9f\x17\x00\x42\x29\x8f\x21\x60\x80\x0d\x3c\x90\x85\x75\x0a\xb9\x6e\x12\x23\x8f\x05\x41\xd8\x90\xa2\x03\x18\x27\x85\xe1\xce\x9a\x23\x6c\x20\xfa\x16\xd3\xe9\x07\x90\xc2\xe6\x65\x51\x1d\xb3\x4d\xca\x34\xc0\x1e\x3d\x99\x9c\x2f\x97\x98\x53\x98\x0b\xbf\x4b\x2f\x97\xdb\xb1\x7f\x95\xfc\xd7\x87\xf8\xaa\x12\x88\x96\x83\x6c\xda\x81\x13\xca\xa6\x15\x86\xcb\xa6\x0d\x44\x23\xd6\xce\x1f\x17\x77\xf9\x90\xe8\xa8\x9e\xb9\xac\x76\x7c\xe8\xc5\x06\x98\x6b\xe2\xda\xf9\x5d\x59\x19\x11\xa5\xf0\x77\x46\xdb\xf6\x65\x9d\x95\x90\x67\xcf\x23\xad\x8f\x4e\x08\x13\xd9\xf5\x47\x65\xff\x30\xd7\x88\x56\xa9\x01\x3a\x3c\x75\x1d\x78\x65\x30\x17\xeb\xe3\x07\x20\xea\x43\x01\xb0\xf3\xa2\xd9\x6b\x39\xb4\x54\x87\x88\x96\xf7\xeb\xb7\x53\x03\xeb\xad\x3b\x19\x72\x6d\x23\xfa\x4a\x48\xec\xdc\x86\x73\xb5\x98\xfd\xee\xa2\x4c\xaa\xcd\x61\x01\xf6\x2e\xc4\xc9\x22\x7b\x4f\xc3\xa6\x42\xed\x40\x1e\xa4\x56\x9e\xa0\x6f\x96\xb2\xbd\x85\xcf\x9f\xe0\x57\x98\x60\x7c\x7c\x84\x0f\xf0\xcf\xb7\xaf\xdf\xee\xa1\x0d\x08\x22\x40\xd3\x6e\x8d\x96\x09\x15\xb4\x85\xa7\x76\x8b\xb9\x61\x29\xd8\xb3\xd0\x91\x57\xce\x73\x83\x22\xe0\xa8\xf6\x24\x65\x1a\x75\x60\xc3\xac\xcf\x15\x3c\x4c\xfb\x4c\xc3\x6f\x58\x21\xfd\x0e\x89\x58\x37\x46\x44\xe4\x95\x36\xb3\xae\xe6\x68\xd7\xb6\x08\x40\xb0\xba\x69\x30\x86\x0b\xa1\x8c\xe4\xfd\xed\x58\xc0\x2c\xd0\xbc\x88\x2e\xd4\x5b\x4b\xe8\x91\xe8\x4b\x41\x1b\xbc\x61\xab\x53\x7a\x2d\xd7\x4e\xb5\x06\xcf\x6b\x69\xd6\xa3\x57\x79\x14\xb5\x29\x63\xdd\x18\xf6\x91\x24\x76\x10\x9e\x52\x3e\x75\xbb\xe4\x4f\x61\xad\x8b\xa9\x4b\xf2\x28\xa9\x45\x0a\x1b\x2a\xd2\x4a\x8d\x01\x9c\x85\x11\x2a\x80\xf3\x10\xf7\xa8\x3d\x7c\xfd\xeb\x6f\xf0\x28\x9d\x57\x21\x01\x61\x94\x8a\x2f\x5e\x9e\xef\x96\x5e\x02\x1b\x37\xe9\xbb\x5f\xc6\xd9\x7a\xbe\x82\xa7\x21\x34\x49\x87\x16\x51\xc6\x4b\x21\xbe\x3b\x6d\x6f\xd8\x2d\xbb\xbd\xa4\x0e\xf2\x0a\xe5\x2f\x83\x0a\x3e\x26\xac\x51\xcb\x8b\xda\x29\x0d\x1b\x6f\x3e\x7f\xba\x85\xdc\x9a\x72\xeb\x5c\x24\xf3\x72\xf4\xb9\xa3\x47\x83\x31\x63\x85\xb0\xe7\x4f\x78\x0c\xb0\xe4\xf1\x7b\x70\x16\xad\x74\x0a\xd3\xf8\xf5\x76\xd9\xab\x27\x44\xd9\xc0\x03\xfa\x83\x96\x34\x9b\xb0\x81\xd9\xc8\xf6\x37\x74\x48\x23\xbb\xf0\x4d\xf4\xf0\xd0\x56\x95\x7e\x59\xbe\xf1\x66\x97\xf3\xb9\x5c\xca\x3a\x71\xf4\x0e\x25\xb3\xd5\xea\x74\xbd\xb1\xab\x53\xee\xe9\x66\x1f\x63\x13\xee\xd7\xeb\x37\x59\x5f\x56\xc0\xfd\x97\xdf\xfe\xf8\xc4\xe0\x03\xad\xa5\xa9\xd4\xc4\xd6\x1d\xf0\x87\x11\x49\x48\x63\x1f\x26\x02\x9b\xd1\xd7\x7d\x81\x5f\xf8\x4c\x20\xae\xfe\x0b\x00\x00\xff\xff\x22\x86\x0d\xec\x13\x0c\x00\x00"), }, "/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/outputs.tf": &vfsgen۰CompressedFileInfo{ name: "outputs.tf", modTime: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC), - uncompressedSize: 935, + uncompressedSize: 777, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x92\x51\x6e\x84\x20\x10\x86\xdf\x3d\x05\xd9\x3e\x2f\x37\xe8\x59\xcc\x08\xb3\x95\x38\x30\x04\x06\x93\x4d\xb3\x77\x6f\x8c\xdb\x56\x70\xdb\xf0\x66\xf2\x7f\xdf\x87\x06\xb9\x48\x2c\xa2\x2e\x4b\x99\xd0\x70\xb8\xb9\x8f\x2b\x58\xef\xc2\x45\x7d\x0e\x4a\xad\x40\x05\xd5\xbb\xf2\x6c\x0b\xa1\x9e\x98\x65\x03\x75\x4b\x0f\x8f\x61\x38\x97\xba\x1b\xdb\x23\xa1\x1c\x2b\x1e\xcc\xec\x02\x8e\x96\x3d\xb4\x6f\xb3\x42\xd2\xf5\x7e\x34\x0d\x95\x2c\x98\xc6\x00\x1e\xcf\xde\x71\x3d\x5a\x39\xcf\xe3\x82\xf7\x7c\x36\xbe\x97\x23\x4d\x6e\x5a\x5d\x92\xc8\x4c\xb5\xf0\x1c\xc6\x6d\xd1\x2b\x53\xf1\x28\x3e\xea\xf6\xb4\x27\x36\x41\x46\x67\x5f\x17\x76\x59\x6f\x88\x76\x76\x93\xdf\x76\x26\xeb\x3b\x78\x52\x86\x83\x60\x10\x75\xe3\xa4\x80\x48\x59\x8c\xc4\x77\xb4\xca\xcc\x90\x24\xeb\x9f\xb3\x22\xdb\xab\x99\xd1\x2c\x91\x5d\xd8\x3e\x7d\xaf\xfc\x7f\x39\x7f\x48\xed\x3d\x5f\x21\xba\x8c\x69\xed\xac\xbe\x54\xda\x66\x0a\x28\x98\xbb\x7b\x15\xde\xb6\x08\xa5\x3b\xf4\xcb\x56\x7f\x13\x90\x33\xdc\x15\xa9\xd0\xea\xb6\x79\x61\xcf\xe2\x56\xec\xea\x9c\xf0\xe1\x31\x7c\x05\x00\x00\xff\xff\x35\x1f\xf0\x39\xa7\x03\x00\x00"), + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\xd1\x51\x6a\xc4\x20\x10\xc6\xf1\x77\x4f\x31\x6c\x9f\xd7\x1b\xf4\x2c\x8b\xd1\xd9\xee\x90\xd1\x11\x33\x0a\x4b\xd9\xbb\x17\x49\x69\x37\xd9\xb4\xf8\x16\xf0\xff\xfd\x42\xa2\x54\xcd\x55\xe1\x34\xd7\x09\xbd\xa4\x2b\x7d\x9c\x5d\x88\x94\x4e\xf0\x69\x00\x9a\xe3\x8a\xf0\x0e\x51\x42\x65\xb4\x93\x88\xf6\xd0\xee\x6b\xf3\x30\xe6\x55\x1a\x36\xfa\x23\xa3\x3e\x2b\x4c\x53\xa3\xa2\x59\x84\xb7\xcc\xf7\xc1\xa5\x9f\xd8\x26\x5c\x23\x6a\xcc\x36\xb9\x88\x07\xfb\xc9\x2d\x48\xe1\x58\x58\xc7\xb6\x27\x96\x42\x1f\xbf\xad\xcd\x62\xef\x2e\x32\x78\x49\x8a\x49\xe1\x2a\x05\x1c\x33\x04\xcc\x2c\x77\x0c\xe0\x6f\xae\xe8\x62\x7f\xde\x95\x25\x9c\xfd\x0d\xfd\x9c\x85\x92\x62\xb9\xac\xca\xff\x9f\xff\xc7\x68\xff\x27\xcf\x2e\xd3\x82\xa5\x0d\xaa\x87\x93\xbd\x59\x12\x2a\x2e\xc3\xde\x26\xdf\x5b\x8c\x3a\x0c\xfd\xb6\xcf\x8a\x77\x4c\x5e\x86\x90\x4d\xba\xb9\x6d\x99\x25\x8a\x52\xc3\x21\xe7\x25\x37\x0f\xf3\x15\x00\x00\xff\xff\xe7\x43\x4b\x14\x09\x03\x00\x00"), }, "/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/require.tf": &vfsgen۰CompressedFileInfo{ name: "require.tf", modTime: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC), - uncompressedSize: 313, + uncompressedSize: 288, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\x8e\xc1\x8e\x83\x20\x14\x45\xf7\x7c\xc5\x8d\xb3\x27\xea\x64\x66\x56\xfa\x15\xb3\x9f\x30\xf2\xda\x90\x22\xd0\x07\xba\x69\xec\xb7\x37\x4a\x69\x6d\xca\x8e\x73\xee\x21\x7c\xe0\x97\x98\xd5\xc1\xf3\x88\x99\x38\x1a\xef\xa0\x9c\x46\xb0\xd3\xd1\xb8\x82\xa2\x10\xe9\x31\xbb\x08\x80\xe9\x3c\x19\x26\xfd\x57\x9a\x0e\x55\xdf\xa1\x96\x4d\x2b\xeb\x4a\xec\x17\x81\xfd\x6c\x34\x71\xdc\x42\x60\x48\xc8\xa7\x43\xb5\x16\x5f\x6b\xb0\xde\xad\x1f\x94\xbd\x8b\x6b\x8f\x46\xb6\x99\xbb\xc9\x5a\x3c\x79\x2b\x9b\xcc\x13\x8d\xc1\xaa\x44\x6f\xdc\x46\xbc\xec\xcb\xfb\xe6\x7f\x36\x9c\x0a\xaf\xe5\x77\x31\x41\x0d\x27\x4a\xbb\xe2\x47\x7e\x66\xc3\xca\x69\x3f\xee\xcc\xf6\xa7\x45\x2c\xe2\x16\x00\x00\xff\xff\x68\x6b\xdb\x28\x39\x01\x00\x00"), + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\x8d\xc1\xce\x82\x30\x10\x84\xef\x7d\x8a\x09\xff\xbd\x01\x92\xdf\x1b\x3c\x85\x77\x53\xe9\x6a\x9a\x2c\x2d\x6e\x0b\x17\x83\xcf\x6e\x80\x54\x30\xee\xf1\x9b\xf9\x76\xfe\x70\x26\x11\x73\x0b\xd2\x63\x22\x89\x2e\x78\x18\x6f\x31\xf0\x78\x77\x3e\xa3\xa8\x54\xfa\xd4\x9e\x0a\x10\x7a\x8c\x4e\xc8\x5e\xb2\xd3\xa0\x68\x1b\x94\xba\xaa\x75\x59\xa8\x63\x63\x90\x30\x39\x4b\x12\x57\x11\xe8\x12\xb6\x6b\x50\xbc\x5a\x94\xfa\x7f\x31\x16\xc0\xa1\x33\xbc\x27\x95\xae\x37\xee\x47\xe6\x83\x51\xeb\x6a\xe3\x89\xfa\x81\x4d\xa2\x1f\xce\x11\x5f\xfd\xfc\xdf\x5d\x27\x27\x69\x5f\x3e\xe5\x44\x8c\xb7\xa1\x3f\x18\xeb\xf2\xac\x66\xf5\x0e\x00\x00\xff\xff\x6c\xb6\x93\x3d\x20\x01\x00\x00"), }, "/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/ssh.tf": &vfsgen۰CompressedFileInfo{ name: "ssh.tf", @@ -5020,9 +5020,9 @@ var vfsgenAssets = func() http.FileSystem { "/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/variables.tf": &vfsgen۰CompressedFileInfo{ name: "variables.tf", modTime: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC), - uncompressedSize: 2644, + uncompressedSize: 2930, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x56\x5f\x6f\xdb\x36\x10\x7f\xd7\xa7\x38\xa4\x0f\x75\xb0\x55\xb5\x83\x2c\xcb\x80\xf6\xa1\x73\xba\x2e\x58\x9d\x65\x4d\x93\x97\x61\x20\x28\xf2\x24\x11\xa1\x48\xf5\x8e\x74\xea\x0d\xfb\xee\x03\x25\xc5\x75\x6c\x79\x4b\x86\xfa\xc5\x80\x79\xf7\xfb\x73\xbc\x3b\xfa\x19\x9c\x5d\x5c\x01\xa1\xf2\xa4\x39\xcb\x96\x92\x8c\x2c\x2c\xc2\x81\xb2\x91\x03\x92\x70\xb2\xc1\x03\xf8\x2b\x03\x08\xab\x16\x61\xf8\xbc\x06\x0e\x64\x5c\x95\x01\x68\x64\x45\xa6\x0d\xc6\x3b\x78\x0d\x07\xd7\xce\x7c\x8a\x08\x43\x3a\x74\xe9\xd9\xdf\x59\xf6\x0c\x2e\xbc\x46\xde\x60\xf0\x2c\x4c\x23\x2b\x14\xd1\xb5\x52\xdd\xa2\x7e\x0a\xcd\xa5\x0c\x35\x04\x0f\xf7\xb9\xf0\x93\x95\x41\x49\x82\xb9\x77\x41\x1a\x87\x04\xef\x8d\x8b\x9f\xa1\xa3\x80\xb2\x3f\x15\x2d\x79\x1d\x55\x02\x11\x9f\xb0\x89\xbd\x80\xdc\x34\x15\x4c\x5a\xf2\x85\x2c\xec\x0a\x64\x99\x84\x4b\x48\x01\x2f\xd2\x11\x21\x9b\x3f\x11\xce\x17\xef\xe0\x9b\xef\xde\x1d\x76\x76\x36\x0a\xe5\x5d\x20\x6f\x2d\x92\x50\x3e\xba\x30\xe6\xc2\xc5\xa6\x40\xea\x5c\x94\x32\xda\x30\xfc\x3c\xdb\xf5\x75\xd1\x45\x82\x2f\xe1\x0b\x2e\xc3\xc4\xe4\x98\x43\x23\x53\x49\x79\x5b\x40\x23\x55\x6d\x1c\x0a\xed\x1b\x69\xdc\x53\x8a\xb8\xe8\x33\x61\xc8\x7c\x08\xeb\xbc\x46\x61\x5a\xd1\x7a\x6f\xff\x03\x74\xd3\xd3\xc1\xec\x87\xa3\x7c\x76\x72\x9a\xa7\xef\xe9\xcb\xa3\xe3\x83\xbd\x3d\x72\xb3\x80\xf3\x4b\x98\x9f\x9f\x7d\xd8\xa2\x5e\x1a\x0a\x51\x5a\xa1\xda\xc8\x5f\xab\x9c\x03\x26\xcc\x2f\xaf\x79\x0f\x5d\x83\x8d\xa7\xd5\x13\x08\x8f\xa6\xc7\xa7\xbb\x9c\x37\x03\xd3\x87\x37\x0b\x30\x0e\x16\x3f\xfe\x4b\xc3\x58\x25\xd8\x99\xb6\xc5\x30\x6a\xd4\x1a\x0e\x93\xbe\xd0\x87\xbb\x44\xf3\x35\xd0\x4e\xd7\xcf\xbd\x2b\x4d\x05\x6b\xec\x1d\xe9\xbf\xff\xd1\x0f\x65\x1f\x18\x49\x26\xd0\x4d\x95\xcc\xb5\xb8\xc5\xd5\xff\x90\x75\x75\xf5\x33\xb4\xb1\xb0\x46\x41\x02\x80\xd2\x13\x44\x46\x82\xe7\xca\x13\x3e\xdf\xaa\x86\x64\xc6\x20\xb4\xa1\x9e\x68\xcf\x98\x4b\xd0\x86\x50\x05\x4f\x2b\xb8\xab\x91\x10\x2a\x74\x48\x32\xa0\x86\x0e\x81\x81\x6b\x1f\xad\x86\x02\xa1\xb5\x52\xa1\x86\x89\xea\x8b\xc2\xc0\xa8\x08\x43\x1a\x9c\x3d\x4d\xfc\xb0\xf1\x31\xdc\x79\xba\x15\x4d\x88\xa3\x9a\xe6\x17\xe7\x60\x5c\x40\x2a\xa5\x42\x58\x7c\xbc\xde\x85\xdd\xd7\xa0\xc7\xa7\xd3\x71\x2e\xd3\x0a\x19\x83\xd7\x18\xb0\xdf\x4e\x0d\x86\xda\xeb\x51\xfe\x45\x77\xd4\x55\x65\x9d\x02\xa1\x46\xa8\x3d\x07\x38\xbf\x5c\x1e\x83\xd4\x9a\x90\x79\xaf\xdf\x9d\xa1\x2d\x0d\x71\x78\x51\xfa\xe8\xf4\xd6\xfd\xb4\x5e\x0b\x65\xf4\xf8\xf5\xa4\xd9\xed\x19\x49\xba\x0a\x3b\x4d\xcc\xa6\x72\xf0\x4b\x2c\x90\x1c\x06\x64\x68\xbd\x7e\x82\x92\xd9\x34\x9f\xe5\xd3\x7c\xfa\x72\x76\xb2\xa5\x84\x91\x96\x46\xe1\x5e\x35\xaf\x5e\xbd\xfd\xf5\x2c\x7b\x94\xa4\x01\x8a\xf3\xec\x63\x8d\x30\xeb\xca\x06\x77\xc6\xda\xd4\x3e\x84\xe9\x18\x75\xd7\xb8\xb7\xb1\x40\x21\x5b\xd3\xfd\x44\xdf\x76\x75\x9e\x4d\x43\xbd\x37\x21\xf5\xb8\x76\x9c\x67\x49\x4c\xb6\x61\x7b\xc4\x72\x6f\xf7\x68\xdc\xee\xfd\x03\xdc\x2f\x67\xc1\xb1\x2c\xcd\xe7\xd1\x5b\xf8\x2d\x22\x19\xec\x07\xad\x8f\x66\xb8\x33\x69\x70\x6a\x84\x3e\x6f\xad\x55\x3a\xbe\x43\x42\x0d\xc5\x6a\x2d\x15\xce\x06\x3d\x86\xef\xdf\xed\xdc\x7a\x25\x2d\x4c\x30\xaf\x72\x28\xbd\xcf\x07\xc9\x39\x2f\x55\xfe\x20\xe6\x10\x1e\x7f\xb7\x0f\x12\xb7\xec\xa2\x4b\xdf\x82\xb0\xf5\x14\x8c\xab\xc6\xf6\x4e\xe1\xbd\xdd\xb5\xff\xb6\xcb\x84\xc8\xe9\xa1\xf7\x04\xd2\x49\xbb\x0a\x46\x31\xac\xc1\xba\x7f\x0a\x2d\x07\x42\xd9\x30\x4c\xe6\xd2\x1a\xe5\x0f\x77\xb7\x62\x29\x2d\xe3\xa8\x2e\x59\x55\x84\x55\xb7\x25\x47\xef\x60\x10\x91\x2a\xbe\xd1\x67\x6f\xbe\x64\xc1\x7b\xb9\x42\x82\xc9\x40\xc8\x49\x52\xa0\x88\x23\x4b\x69\x6d\x73\x53\x5a\x8a\x1d\x56\x36\x52\x30\xa5\x51\x32\xe0\xc3\x7f\x6c\x48\x81\xc5\x52\x5a\xa3\x4d\x58\x89\x16\xc9\x78\x2d\x6a\x1f\x89\x47\x25\xdf\x0c\x91\xe9\x75\x94\xd6\x76\xda\xd5\x06\x76\x7a\xbc\xfa\xec\xc7\xee\xb7\xd3\xef\x4f\xd2\x7e\xfb\x27\x00\x00\xff\xff\xfd\x93\x3e\xa8\x54\x0a\x00\x00"), + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x56\xdf\x6f\xdb\x36\x10\x7e\xf7\x5f\x71\x48\x1f\xea\x60\x8b\x6a\x07\x59\x96\x01\xed\x43\xe7\x74\x5d\xb0\x3a\xcb\x9a\x26\x2f\xc3\x40\xd0\xe4\x49\x22\x42\x91\xea\x1d\xe9\xc4\x1b\xf6\xbf\x0f\x94\x54\xc7\xb6\xe4\x2d\x19\xea\x17\x03\xe2\xdd\xf7\x7d\x77\xbc\x1f\x7c\x01\xe7\x97\xd7\x40\xa8\x3c\x69\x1e\x8d\x96\x92\x8c\x5c\x58\x84\x03\x65\x23\x07\x24\xe1\x64\x85\x07\xf0\xd7\x08\x20\xac\x6a\x84\xee\xf7\x06\x38\x90\x71\xc5\x08\x40\x23\x2b\x32\x75\x30\xde\xc1\x1b\x38\xb8\x71\xe6\x73\x44\xe8\xdc\xa1\x71\x1f\xfd\x3d\x1a\xbd\x80\x4b\xaf\x91\x37\x18\x3c\x0b\x53\xc9\xe2\x59\xe8\x57\x32\x94\x10\x3c\x44\x57\x4b\x75\x87\x1a\x7e\xb2\x32\x28\x49\x30\xf3\x2e\x48\xe3\x90\xe0\x83\x71\xf1\x01\x1a\x64\xc8\xdb\x53\x51\x93\xd7\x51\x25\x10\xf1\x19\xab\xd8\xf2\x66\xa6\x2a\x60\x5c\x93\x5f\xc8\x85\x5d\x81\xcc\x93\x5e\x09\xc9\xe0\x28\x1d\x11\xb2\xf9\x13\xe1\x62\xfe\x1e\xbe\xf9\xee\xfd\x61\x13\xc5\x46\x7e\xbc\x0b\xe4\xad\x45\x12\xca\x47\x17\x86\xa2\x70\xb1\x5a\x20\x35\x51\xe4\x32\xda\xd0\x7d\x9e\xf6\xe3\xba\x6c\x2c\xc1\xe7\xf0\x88\xcb\x30\x36\x19\x66\x50\xc9\x94\x49\xde\x15\x50\x49\x55\x1a\x87\x42\xfb\x4a\x1a\xf7\x9c\x24\xce\x5b\x4f\xe8\x3c\xb7\x61\x9d\xd7\x28\x4c\x2d\x6a\xef\xed\x7f\x80\x6e\xc6\x74\x30\xfd\xe1\x38\x9b\x9e\x9e\x65\xe9\x7f\xf2\xea\xf8\xe4\x60\x6f\x69\xdc\xce\xe1\xe2\x0a\x66\x17\xe7\x1f\x77\xa8\x97\x86\x42\x94\x56\xa8\x3a\xf2\xd7\x4a\x67\x87\x09\xb3\xab\x1b\xde\x43\x57\x61\xe5\x69\xf5\x0c\xc2\xe3\xc9\xc9\x59\x9f\xf3\xb6\x63\xfa\xf8\x76\x0e\xc6\xc1\xfc\xc7\x7f\x29\x18\xab\x04\x3b\x53\xd7\x18\x06\x03\xb5\x86\xc3\xb8\x4d\xf4\x61\x9f\x68\xb6\x06\xea\x55\xfd\xcc\xbb\xdc\x14\xb0\xc6\xee\x49\xff\xfd\x8f\xb6\x17\x5b\xc3\x48\x32\x81\x6e\xaa\x64\x2e\xc5\x1d\xae\xfe\x87\xac\xeb\xeb\x9f\xa1\x8e\x0b\x6b\x14\x24\x00\xc8\x3d\x41\x64\x24\x78\xa9\x3c\xe1\xcb\x9d\x6c\x48\x66\x0c\x42\x1b\x6a\x89\xf6\xb4\xb9\x04\x6d\x08\x55\xf0\xb4\x82\xfb\x12\x09\xa1\x40\x87\x24\x03\x6a\x68\x10\x18\xb8\xf4\xd1\x6a\x58\x20\xd4\x56\x2a\xd4\x30\x56\x6d\x52\x18\x18\x15\x61\x48\x8d\xb3\xa7\x88\xb7\x0b\x1f\xc3\xbd\xa7\x3b\x51\x85\x38\xa8\x69\x76\x79\x01\xc6\x05\xa4\x5c\x2a\x84\xf9\xa7\x9b\x3e\xec\xbe\x02\x3d\x39\x9b\x0c\x73\x99\x5a\xc8\x18\xbc\xc6\x80\xed\x74\xaa\x30\x94\x5e\x0f\xf2\xcf\x9b\xa3\x26\x2b\x6b\x17\x08\x25\x42\xe9\x39\xc0\xc5\xd5\xf2\x04\xa4\xd6\x84\xcc\x7b\xe3\xed\x35\x6d\x6e\x88\xc3\x51\xee\xa3\xd3\x3b\xf7\x53\x7b\x2d\x94\xd1\xc3\xd7\x93\x7a\xb7\x65\x24\xe9\x0a\x6c\x34\x31\x9b\xc2\xc1\x2f\x71\x81\xe4\x30\x20\x43\xed\xf5\x33\x94\x4c\x27\xd9\x34\x9b\x64\x93\x57\xd3\xd3\x1d\x25\x8c\xb4\x34\x0a\xf7\xaa\x79\xfd\xfa\xdd\xaf\xe7\xa3\x27\x49\xea\xa0\x38\x1b\x7d\x2a\x11\xa6\x4d\xda\xe0\xde\x58\x9b\xca\x87\x30\x1d\xa3\x6e\x0a\xf7\x2e\x2e\x50\xc8\xda\x34\x9f\xe8\xdb\x26\xcf\xd3\x49\x28\xf7\x3a\xa4\x1a\xd7\x8e\xb3\x51\x12\x33\xda\x08\x7b\x20\xe4\x36\xdc\xe3\xe1\x70\xbf\xec\xdd\x76\x38\x0b\x8e\x79\x6e\x1e\x06\x6f\xe1\xb7\x88\x64\xb0\x6d\xb4\xd6\x9a\xe1\xde\xa4\xc6\x29\x11\x5a\xbf\xb5\x56\xe9\xf8\x1e\x09\x35\x2c\x56\x6b\xa9\x70\xde\xe9\x31\xfc\x65\x5d\x67\xd6\x2b\x69\x61\x8c\x59\x91\x41\xee\x7d\xd6\x49\xce\x78\xa9\xb2\x2d\x9b\x43\x78\xfa\xdd\x6e\x39\xee\x84\x8b\x2e\xfd\x0b\xc2\xda\x53\x30\xae\x18\x9a\x3b\x0b\xef\x6d\x3f\xfc\x77\x8d\x27\x44\x4e\x8b\xde\x13\x48\x27\xed\x2a\x18\xc5\xb0\x06\x6b\x5e\x0a\x35\x07\x42\x59\x31\x8c\x67\xd2\x1a\xe5\x0f\xfb\x53\x31\x97\x96\x71\x50\x97\x2c\x0a\xc2\xa2\x99\x92\x83\x77\xd0\x89\x48\x19\xdf\xa8\xb3\xb7\x8f\x5e\xf0\x41\xae\x90\x60\xdc\x11\x72\x92\x14\x28\xe2\xc0\x50\x5a\x87\xb9\x29\x2d\xd9\x6e\x2b\xdb\x2e\x4d\x81\x0f\x81\xa4\xc8\xad\x2c\x78\x58\x61\x3a\x87\xe6\x1c\xea\x34\x33\x9b\x11\xc2\x68\xf3\xa3\x34\x38\x50\x37\xb5\x7e\xb4\x06\xcc\xfa\xc2\x7a\x73\xbf\xbf\x51\x1e\xe5\x69\xc3\x4d\xe6\x12\x83\x68\x19\x44\x62\xb0\x18\x06\xf5\x9d\xb7\xf6\x6d\xd1\xa2\xcd\x61\x43\x95\xc5\x00\xc6\x71\x90\xd6\xb6\xa5\xdb\x51\xef\xc9\x5d\xbb\xd9\x90\x82\xc9\x8d\x92\x01\xb7\xdf\xb3\x48\x81\xc5\x52\x5a\xa3\x4d\x58\x89\x1a\xc9\x78\x2d\x4a\x1f\x69\x38\x6f\xb7\x9d\x65\x7a\x44\x48\x6b\x1b\x7d\x6a\x03\x3b\xed\xf8\xd6\xfb\xa9\x6b\xe0\xec\xfb\xd3\xb4\x06\xfe\x09\x00\x00\xff\xff\xe2\x9a\x1f\x5d\x72\x0b\x00\x00"), }, "/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/workers": &vfsgen۰DirInfo{ name: "workers", @@ -5042,9 +5042,9 @@ var vfsgenAssets = func() http.FileSystem { "/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/workers/require.tf": &vfsgen۰CompressedFileInfo{ name: "require.tf", modTime: time.Date(1970, 1, 1, 0, 0, 1, 0, time.UTC), - uncompressedSize: 332, + uncompressedSize: 288, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x6c\xce\x41\x8b\x83\x30\x10\x05\xe0\x7b\x7e\xc5\x23\x7b\x8f\x51\x96\x3d\x2c\xe8\xaf\xd8\xfb\x92\xea\xb4\x04\x12\xa3\x93\x44\x28\xa5\xfe\xf6\x62\xc1\x52\x1a\xe7\x38\x7c\xef\xf1\xbe\xf0\x47\xcc\xe6\x1c\xd8\x63\x21\x8e\x36\x8c\x30\xe3\x80\xc9\xe5\x8b\x1d\xf7\x57\x14\x22\xbd\xd8\x4d\x00\x4c\x73\xb6\x4c\xc3\xff\x9e\x69\x21\xbb\x16\x5a\xd5\x8d\xd2\x52\xdc\x85\x98\x38\x2c\x76\x20\x86\xec\x93\x7c\x66\xde\xa8\x56\xdf\x05\x73\xa1\x37\xae\x90\xf5\x81\x4c\xe4\x27\x67\x12\x15\x78\xed\xd0\xa8\xfa\x53\xbb\x78\x0c\x8b\x01\xf6\xb4\x58\x2e\xc7\xae\x1d\xb4\xfa\xd9\x38\x90\xd9\x62\xbb\x16\x72\x26\x9f\x7f\xab\xaa\x8a\xd7\x98\xc8\x6f\x5d\x8f\x00\x00\x00\xff\xff\xc7\x00\x6c\x9b\x4c\x01\x00\x00"), + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x64\x8d\xc1\xce\x82\x30\x10\x84\xef\x7d\x8a\x09\xff\xbd\x01\x92\xdf\x1b\x3c\x85\x77\x53\xe9\x6a\x9a\x2c\x2d\x6e\x0b\x17\x83\xcf\x6e\x80\x54\x30\xee\xf1\x9b\xf9\x76\xfe\x70\x26\x11\x73\x0b\xd2\x63\x22\x89\x2e\x78\x18\x6f\x31\xf0\x78\x77\x3e\xa3\xa8\x54\xfa\xd4\x9e\x0a\x10\x7a\x8c\x4e\xc8\x5e\xb2\xd3\xa0\x68\x1b\x94\xba\xaa\x75\x59\xa8\x63\x63\x90\x30\x39\x4b\x12\x57\x11\xe8\x12\xb6\x6b\x50\xbc\x5a\x94\xfa\x7f\x31\x16\xc0\xa1\x33\xbc\x27\x95\xae\x37\xee\x47\xe6\x83\x51\xeb\x6a\xe3\x89\xfa\x81\x4d\xa2\x1f\xce\x11\x5f\xfd\xfc\xdf\x5d\x27\x27\x69\x5f\x3e\xe5\x44\x8c\xb7\xa1\x3f\x18\xeb\xf2\xac\x66\xf5\x0e\x00\x00\xff\xff\x6c\xb6\x93\x3d\x20\x01\x00\x00"), }, "/terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/workers/variables.tf": &vfsgen۰CompressedFileInfo{ name: "variables.tf", diff --git a/pkg/platform/kvmlibvirt/kvmlibvirt.go b/pkg/platform/kvmlibvirt/kvmlibvirt.go new file mode 100644 index 000000000..000696332 --- /dev/null +++ b/pkg/platform/kvmlibvirt/kvmlibvirt.go @@ -0,0 +1,198 @@ +// Copyright 2020 The Lokomotive Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package kvmlibvirt + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "text/template" + + "github.com/hashicorp/hcl/v2" + "github.com/hashicorp/hcl/v2/gohcl" + "github.com/mitchellh/go-homedir" + "github.com/pkg/errors" + + "github.com/kinvolk/lokomotive/pkg/platform" + "github.com/kinvolk/lokomotive/pkg/terraform" +) + +type workerPool struct { + Name string `hcl:"pool_name,label"` + Count int `hcl:"count"` + VirtualCPUs int `hcl:"virtual_cpus,optional"` + VirtualMemory int `hcl:"virtual_memory,optional"` + CLCSnippets []string `hcl:"clc_snippets,optional"` + Labels string `hcl:"labels,optional"` +} + +type config struct { + AssetDir string `hcl:"asset_dir"` + ClusterName string `hcl:"cluster_name"` + ControllerCount int `hcl:"controller_count,optional"` + MachineDomain string `hcl:"machine_domain"` + OSImage string `hcl:"os_image"` + NodeIpPool string `hcl:"node_ip_pool,optional"` + SSHPubKeys []string `hcl:"ssh_pubkeys"` + WorkerPools []workerPool `hcl:"worker_pool,block"` + DisableSelfHostedKubelet bool `hcl:"disable_self_hosted_kubelet,optional"` + KubeAPIServerExtraFlags []string `hcl:"kube_apiserver_extra_flags,optional"` + ControllerVirtualCPUs int `hcl:"controller_virtual_cpus,optional"` + ControllerVirtualMemory int `hcl:"controller_virtual_memory,optional"` + ControllerCLCSnippets []string `hcl:"controller_clc_snippets,optional"` + NetworkMTU int `hcl:"network_mtu,optional"` + NetworkIpAutodetectionMethod string `hcl:"network_ip_autodetection_method,optional"` + PodCidr string `hcl:"pod_cidr,optional"` + ServiceCidr string `hcl:"service_cidr,optional"` + ClusterDomainSuffix string `hcl:"cluster_domain_suffix,optional"` + EnableReporting bool `hcl:"enable_reporting,optional"` + EnableAggregation bool `hcl:"enable_aggregation,optional"` + CertsValidityPeriodHours int `hcl:"certs_validity_period_hours,optional"` +} + +func init() { + platform.Register("kvm-libvirt", NewConfig()) +} + +func (c *config) LoadConfig(configBody *hcl.Body, evalContext *hcl.EvalContext) hcl.Diagnostics { + if configBody == nil { + return hcl.Diagnostics{} + } + + if diags := gohcl.DecodeBody(*configBody, evalContext, c); diags.HasErrors() { + return diags + } + + return c.checkValidConfig() +} + +// Meta is part of Platform interface and returns common information about the platform configuration. +func (c *config) Meta() platform.Meta { + nodes := c.ControllerCount + for _, workerpool := range c.WorkerPools { + nodes += workerpool.Count + } + return platform.Meta{ + AssetDir: c.AssetDir, + ExpectedNodes: nodes, + } +} + +func NewConfig() *config { + return &config{} +} + +func (c *config) Apply(ex *terraform.Executor) error { + if err := c.Initialize(ex); err != nil { + return err + } + + return ex.Apply() +} + +func (c *config) Destroy(ex *terraform.Executor) error { + if err := c.Initialize(ex); err != nil { + return err + } + + return ex.Destroy() +} + +func (c *config) Initialize(ex *terraform.Executor) error { + assetDir, err := homedir.Expand(c.AssetDir) + if err != nil { + return err + } + + terraformRootDir := terraform.GetTerraformRootDir(assetDir) + + return createTerraformConfigFile(c, terraformRootDir) +} + +func createTerraformConfigFile(cfg *config, terraformRootDir string) error { + tmplName := "cluster.tf" + t := template.New(tmplName).Funcs(template.FuncMap{"StringsJoin": strings.Join}) + t, err := t.Parse(terraformConfigTmpl) + if err != nil { + return errors.Wrap(err, "failed to parse template") + } + + path := filepath.Join(terraformRootDir, tmplName) + f, err := os.Create(path) + if err != nil { + return errors.Wrapf(err, "failed to create file %q", path) + } + defer f.Close() + + terraformCfg := struct { + Config config + }{ + Config: *cfg, + } + + if err := t.Execute(f, terraformCfg); err != nil { + return errors.Wrapf(err, "failed to write template to file: %q", path) + } + return nil +} + +// checkValidConfig validates cluster configuration. +func (c *config) checkValidConfig() hcl.Diagnostics { + var diagnostics hcl.Diagnostics + + diagnostics = append(diagnostics, c.checkNotEmptyWorkers()...) + diagnostics = append(diagnostics, c.checkWorkerPoolNamesUnique()...) + + return diagnostics +} + +// checkNotEmptyWorkers checks if the cluster has at least 1 node pool defined. +func (c *config) checkNotEmptyWorkers() hcl.Diagnostics { + var diagnostics hcl.Diagnostics + + if len(c.WorkerPools) == 0 { + diagnostics = append(diagnostics, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "At least one worker pool must be defined", + Detail: "Make sure to define at least one worker pool block in your cluster block", + }) + } + + return diagnostics +} + +// checkWorkerPoolNamesUnique verifies that all worker pool names are unique. +func (c *config) checkWorkerPoolNamesUnique() hcl.Diagnostics { + var diagnostics hcl.Diagnostics + + dup := make(map[string]bool) + + for _, w := range c.WorkerPools { + if !dup[w.Name] { + dup[w.Name] = true + continue + } + + // It is duplicated. + diagnostics = append(diagnostics, &hcl.Diagnostic{ + Severity: hcl.DiagError, + Summary: "Worker pools name should be unique", + Detail: fmt.Sprintf("Worker pool '%v' is duplicated", w.Name), + }) + } + + return diagnostics +} diff --git a/pkg/platform/kvmlibvirt/template.go b/pkg/platform/kvmlibvirt/template.go new file mode 100644 index 000000000..1b31fe9b8 --- /dev/null +++ b/pkg/platform/kvmlibvirt/template.go @@ -0,0 +1,186 @@ +// Copyright 2020 The Lokomotive Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package kvmlibvirt + +var terraformConfigTmpl = ` +module "kvm-libvirt-{{.Config.ClusterName}}" { + source = "../terraform-modules/kvm-libvirt/flatcar-linux/kubernetes" + + cluster_name = "{{.Config.ClusterName}}" + + ssh_keys = {{ StringsJoin .Config.SSHPubKeys "\", \"" | printf "[%q]" }} + + asset_dir = "../cluster-assets" + + os_image = "{{.Config.OSImage}}" + + machine_domain = "{{.Config.MachineDomain}}" + + {{- if .Config.NodeIpPool}} + node_ip_pool = "{{.Config.NodeIpPool}}" + {{- end }} + + {{- if .Config.ControllerCount}} + controller_count = {{.Config.ControllerCount}} + {{- end }} + + {{- if .Config.ControllerVirtualCPUs}} + virtual_cpus = {{ .Config.ControllerVirtualCPUs}} + {{- end }} + + {{- if .Config.ControllerVirtualMemory}} + virtual_memory {{ .Config.ControllerVirtualMemory}} + {{- end }} + + {{- if .Config.NetworkMTU }} + network_mtu = {{.Config.NetworkMTU}} + {{- end }} + + {{- if .Config.NetworkIpAutodetectionMethod }} + network_ip_autodetection_method = {{ .Config.NetworkIpAutodetectionMethod }} + {{- end }} + + {{- if .Config.PodCidr }} + pod_cidr = {{.Config.PodCidr }} + {{- end }} + {{- if .Config.ServiceCidr }} + service_cidr = {{.Config.ServiceCidr }} + {{- end }} + + {{- if .Config.ClusterDomainSuffix }} + cluster_domain_suffix = {{.Config.ClusterDomainSuffix }} + {{- end }} + + enable_reporting = {{.Config.EnableReporting}} + enable_aggregation = {{.Config.EnableAggregation}} + + {{- if .Config.ControllerCLCSnippets }} + controller_clc_snippets = {{ StringsJoin .Config.ControllerCLCSnippets "\", \"" | printf "[%q]" }} + {{- end }} + + disable_self_hosted_kubelet = {{ .Config.DisableSelfHostedKubelet }} + + {{- if .Config.KubeAPIServerExtraFlags }} + kube_apiserver_extra_flags = {{ StringsJoin .Config.KubeAPIServerExtraFlags "\", \"" | printf "[%q]" }} + {{- end }} + + {{- if .Config.CertsValidityPeriodHours }} + certs_validity_period_hours = {{.Config.CertsValidityPeriodHours}} + {{- end }} +} + +{{ range $index, $pool := .Config.WorkerPools }} +module "worker-pool-{{ $index }}" { + source = "../terraform-modules/kvm-libvirt/flatcar-linux/kubernetes/workers" + + ssh_keys = {{ StringsJoin $.Config.SSHPubKeys "\", \"" | printf "[%q]" }} + machine_domain = "{{$.Config.MachineDomain}}" + cluster_name = "{{$.Config.ClusterName}}" + {{- if $.Config.ClusterDomainSuffix }} + cluster_domain_suffix = {{$.Config.ClusterDomainSuffix }} + {{- end }} + {{- if $.Config.ServiceCidr }} + service_cidr = {{$.Config.ServiceCidr }} + {{- end }} + + libvirtpool = module.kvm-libvirt-{{$.Config.ClusterName}}.libvirtpool + libvirtbaseid = module.kvm-libvirt-{{$.Config.ClusterName}}.libvirtbaseid + kubeconfig = module.kvm-libvirt-{{$.Config.ClusterName}}.kubeconfig + + pool_name = "{{ $pool.Name }}" + worker_count = "{{ $pool.Count}}" + + {{- if $pool.VirtualCPUs }} + virtual_cpus = {{ $pool.VirtualCPUs }} + {{- end }} + + {{- if $pool.VirtualMemory }} + virtual_memory {{ $pool.VirtualMemory }} + {{- end }} + + {{- if $pool.Labels }} + labels = {{ $pool.Labels }} + {{- end }} + + {{- if $pool.CLCSnippets }} + clc_snippets = {{ StringsJoin $pool.CLCSnippets "\", \"" | printf "[%q]" }} + {{- end }} +} +{{- end }} + +provider "libvirt" { + uri = "qemu:///system" + version = "~> 0.6.0" +} + +provider "ct" { + version = "~> 0.5.0" +} + +provider "local" { + version = "~> 1.2" +} + +provider "null" { + version = "~> 2.1" +} + +provider "template" { + version = "~> 2.1" +} + +provider "tls" { + version = "~> 2.0" +} + +provider "random" { + version = "~> 2.2" +} + + +# Stub output, which indicates, that Terraform run at least once. +# Used when checking, if we should ask user for confirmation, when +# applying changes to the cluster. +output "initialized" { + value = true + sensitive = true +} + +# values.yaml content for all deployed charts. +output "pod-checkpointer_values" { + value = module.kvm-libvirt-{{.Config.ClusterName}}.pod-checkpointer_values + sensitive = true +} + +output "kube-apiserver_values" { + value = module.kvm-libvirt-{{.Config.ClusterName}}.kube-apiserver_values + sensitive = true +} + +output "kubernetes_values" { + value = module.kvm-libvirt-{{.Config.ClusterName}}.kubernetes_values + sensitive = true +} + +output "kubelet_values" { + value = module.kvm-libvirt-{{.Config.ClusterName}}.kubelet_values + sensitive = true +} + +output "calico_values" { + value = module.kvm-libvirt-{{.Config.ClusterName}}.calico_values + sensitive = true +} +`