diff --git a/Tiltfile b/Tiltfile index dd67c866f681..73682d7bf34f 100644 --- a/Tiltfile +++ b/Tiltfile @@ -411,45 +411,54 @@ def prepare_all(): def cluster_templates(): substitutions = settings.get("kustomize_substitutions", {}) + # Ensure we have default values for a small set of well-known variables + substitutions["NAMESPACE"] = substitutions.get("NAMESPACE", "default") + substitutions["KUBERNETES_VERSION"] = substitutions.get("KUBERNETES_VERSION", "v1.24.0") + substitutions["CONTROL_PLANE_MACHINE_COUNT"] = substitutions.get("CONTROL_PLANE_MACHINE_COUNT", "1") + substitutions["WORKER_MACHINE_COUNT"] = substitutions.get("WORKER_MACHINE_COUNT", "3") + + # Note: this is a workaround to pass env variables to cmd buttons while this is not supported natively like in local_resource + for name, value in substitutions.items(): + os.environ[name] = value + template_dirs = settings.get("template_dirs", { "docker": ["./test/infrastructure/docker/templates"], }) for provider, provider_dirs in template_dirs.items(): + p = providers.get(provider) + label = p.get("label", provider) + for template_dir in provider_dirs: template_list = [filename for filename in listdir(template_dir) if os.path.basename(filename).endswith("yaml")] for filename in template_list: - deploy_templates(filename, provider, substitutions) + deploy_templates(filename, label, substitutions) -def deploy_templates(filename, provider, substitutions): +def deploy_templates(filename, label, substitutions): # validate filename exists if not os.path.exists(filename): fail(filename + " not found") - os.environ["NAMESPACE"] = substitutions.get("NAMESPACE", "default") - os.environ["KUBERNETES_VERSION"] = substitutions.get("KUBERNETES_VERSION", "v1.24.0") - os.environ["CONTROL_PLANE_MACHINE_COUNT"] = substitutions.get("CONTROL_PLANE_MACHINE_COUNT", "1") - os.environ["WORKER_MACHINE_COUNT"] = substitutions.get("WORKER_MACHINE_COUNT", "3") - basename = os.path.basename(filename) if basename.endswith(".yaml"): if basename.startswith("clusterclass-"): template_name = basename.replace("clusterclass-", "").replace(".yaml", "") - deploy_clusterclass(template_name, provider, filename) + deploy_clusterclass(template_name, label, filename, substitutions) elif basename.startswith("cluster-template-"): clusterclass_name = basename.replace("cluster-template-", "").replace(".yaml", "") - deploy_cluster_template(clusterclass_name, provider, filename) + deploy_cluster_template(clusterclass_name, label, filename, substitutions) -def deploy_clusterclass(clusterclass_name, provider, filename): - apply_clusterclass_cmd = "cat " + filename + " | " + envsubst_cmd + " | " + kubectl_cmd + " apply -f - && echo \"ClusterClass created from\'" + filename + "\', don't forget to delete\n\"" - delete_clusterclass_cmd = kubectl_cmd + " delete clusterclass " + clusterclass_name + ' --ignore-not-found=true; echo "\n"' +def deploy_clusterclass(clusterclass_name, label, filename, substitutions): + apply_clusterclass_cmd = "cat " + filename + " | " + envsubst_cmd + " | " + kubectl_cmd + " apply --namespace=$NAMESPACE -f - && echo \"ClusterClass created from\'" + filename + "\', don't forget to delete\n\"" + delete_clusterclass_cmd = kubectl_cmd + " --namespace=$NAMESPACE delete clusterclass " + clusterclass_name + ' --ignore-not-found=true; echo "\n"' local_resource( name = clusterclass_name, cmd = ["bash", "-c", apply_clusterclass_cmd], + env = substitutions, auto_init = False, trigger_mode = TRIGGER_MODE_MANUAL, - labels = [provider + "-clusterclasses"], + labels = [label + ".clusterclasses"], ) cmd_button( @@ -457,7 +466,10 @@ def deploy_clusterclass(clusterclass_name, provider, filename): argv = ["bash", "-c", apply_clusterclass_cmd], resource = clusterclass_name, icon_name = "note_add", - text = "Apply ClusterClass", + text = "Apply `" + clusterclass_name + "` ClusterClass", + inputs = [ + text_input("NAMESPACE", default = substitutions.get("NAMESPACE")), + ], ) cmd_button( @@ -465,20 +477,23 @@ def deploy_clusterclass(clusterclass_name, provider, filename): argv = ["bash", "-c", delete_clusterclass_cmd], resource = clusterclass_name, icon_name = "delete_forever", - text = "Delete ClusterClass", + text = "Delete `" + clusterclass_name + "` ClusterClass", + inputs = [ + text_input("NAMESPACE", default = substitutions.get("NAMESPACE")), + ], ) -def deploy_cluster_template(template_name, provider, filename): - apply_cluster_template_cmd = "CLUSTER_NAME=" + template_name + "-$RANDOM; " + clusterctl_cmd + " generate cluster $CLUSTER_NAME --from " + filename + " | " + kubectl_cmd + " apply -f - && echo \"Cluster '$CLUSTER_NAME' created, don't forget to delete\n\"" - - delete_clusters_cmd = 'DELETED=$(echo "$(bash -c "' + kubectl_cmd + ' get clusters --no-headers -o custom-columns=":metadata.name"")" | grep -E "^' + template_name + '-[[:digit:]]{1,5}$"); if [ -z "$DELETED" ]; then echo "Nothing to delete for cluster template ' + template_name + '"; else echo "Deleting clusters:\n$DELETED\n"; echo $DELETED | xargs -L1 ' + kubectl_cmd + ' delete cluster; fi; echo "\n"' +def deploy_cluster_template(template_name, label, filename, substitutions): + apply_cluster_template_cmd = "CLUSTER_NAME=" + template_name + "-$RANDOM;" + clusterctl_cmd + " generate cluster $CLUSTER_NAME --from " + filename + " | " + kubectl_cmd + " apply -f - && echo \"Cluster '$CLUSTER_NAME' created, don't forget to delete\n\"" + delete_clusters_cmd = 'DELETED=$(echo "$(bash -c "' + kubectl_cmd + ' --namespace=$NAMESPACE get clusters -A --no-headers -o custom-columns=":metadata.name"")" | grep -E "^' + template_name + '-[[:digit:]]{1,5}$"); if [ -z "$DELETED" ]; then echo "Nothing to delete for cluster template ' + template_name + '"; else echo "Deleting clusters:\n$DELETED\n"; echo $DELETED | xargs -L1 ' + kubectl_cmd + ' delete cluster; fi; echo "\n"' local_resource( name = template_name, cmd = ["bash", "-c", apply_cluster_template_cmd], + env = substitutions, auto_init = False, trigger_mode = TRIGGER_MODE_MANUAL, - labels = [provider + "-cluster-templates"], + labels = [label + ".templates"], ) cmd_button( @@ -487,6 +502,12 @@ def deploy_cluster_template(template_name, provider, filename): resource = template_name, icon_name = "add_box", text = "Create `" + template_name + "` cluster", + inputs = [ + text_input("NAMESPACE", default = substitutions.get("NAMESPACE")), + text_input("KUBERNETES_VERSION", default = substitutions.get("KUBERNETES_VERSION")), + text_input("CONTROL_PLANE_MACHINE_COUNT", default = substitutions.get("CONTROL_PLANE_MACHINE_COUNT")), + text_input("WORKER_MACHINE_COUNT", default = substitutions.get("WORKER_MACHINE_COUNT")), + ], ) cmd_button( @@ -495,6 +516,9 @@ def deploy_cluster_template(template_name, provider, filename): resource = template_name, icon_name = "delete_forever", text = "Delete `" + template_name + "` clusters", + inputs = [ + text_input("NAMESPACE", default = substitutions.get("NAMESPACE")), + ], ) cmd_button( diff --git a/docs/book/src/developer/tilt.md b/docs/book/src/developer/tilt.md index 88e6131ca903..6a421bd47518 100644 --- a/docs/book/src/developer/tilt.md +++ b/docs/book/src/developer/tilt.md @@ -278,15 +278,16 @@ These can be customized for your specific needs. ### Deploying a workload cluster -After your kind management cluster is up and running with Tilt, you can deploy a workload clusters in the Tilt web UI based off of YAML templates from specified directories. By default, templates are read from `./test/infrastructure/docker/templates`. +After your kind management cluster is up and running with Tilt, you can deploy a workload clusters in the Tilt web UI based off of YAML templates from the directories specified in +the `template_dirs` field from the [tilt-settings.yaml](#tilt-settings-fields) file (default `./test/infrastructure/docker/templates`). -These deployment resources are found in the Tilt web UI under the label grouping `-cluster-templates` and `-clusterclasses` for each specified provider, i.e. `docker-cluster-templates` and `docker-clusterclasses`. +Templates should be named according to clusterctl conventions: -The `-cluster-templates` category contains cluster templates, you can create a cluster by clicking "Create cluster" or the clockwise arrow icon ⟳. Note that each time a cluster template is deployed, it deploys a new workload cluster in addition to the existing ones. To delete all clusters based off of a template, click on "Delete \ cluster," and click on "Delete all workload clusters" to delete all workload clusters. +- template files must be named `cluster-template-{name}.yaml`; those files will be accessible in the Tilt web UI under the label grouping `{provider-label}.templates`, i.e. `CAPD.templates`. +- cluster class files must be named `clusterclass-{name}.yaml`; those file will be accessible in the Tilt web UI under the label grouping `{provider-label}.clusterclasses`, i.e. `CAPD.clusterclasses`. -The `-clusterclasses` category contains ClusterClass definitions and you can create them by clicking on the "Create clusterclass" or the clockwise arrow icon ⟳ and delete them by clicking on "Delete clusterclass". - -Variables in a cluster template are substituted with values from `kustomize_substitutions` in `tilt-settings.yaml`. The default substitutions are: +By selecting one of those items in the Tilt web UI set of buttons will appear, allowing to create - with a dropdown for customizing variable substitutions - or delete clusters. +Custom values for variable substitutions can be set using `kustomize_substitutions` in `tilt-settings.yaml`, e.g. ```yaml kustomize_substitutions: @@ -296,8 +297,6 @@ kustomize_substitutions: WORKER_MACHINE_COUNT: 3 ``` -Lastly, cluster template directories can be specified from the `template_dirs` field in `tilt-settings.yaml`. See [tilt-settings fields](#tilt-settings-fields) for an example. -

Use of clusterctl

When the worker cluster has been created using tilt, `clusterctl` should not be used for management @@ -308,8 +307,6 @@ This limitation is an acceptable trade-off while executing fast dev-test iterati you are interested in testing clusterctl workflows, you should refer to the [clusterctl developer instructions](../clusterctl/developers.md). - - ## Available providers The following providers are currently defined in the Tiltfile: