Skip to content

Commit

Permalink
improve-templates-in-tilt
Browse files Browse the repository at this point in the history
  • Loading branch information
fabriziopandini committed Aug 4, 2022
1 parent 2e73a26 commit 804ffc4
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 30 deletions.
64 changes: 44 additions & 20 deletions Tiltfile
Original file line number Diff line number Diff line change
Expand Up @@ -411,74 +411,89 @@ 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(
clusterclass_name + ":apply",
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(
clusterclass_name + ":delete",
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(
Expand All @@ -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(
Expand All @@ -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(
Expand Down
17 changes: 7 additions & 10 deletions docs/book/src/developer/tilt.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<provider>-cluster-templates` and `<provider>-clusterclasses` for each specified provider, i.e. `docker-cluster-templates` and `docker-clusterclasses`.
Templates should be named according to clusterctl conventions:

The `<provider>-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-template\> 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 `<provider>-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:
Expand All @@ -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.

<h1>Use of clusterctl</h1>

When the worker cluster has been created using tilt, `clusterctl` should not be used for management
Expand All @@ -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).

</aside>

## Available providers

The following providers are currently defined in the Tiltfile:
Expand Down

0 comments on commit 804ffc4

Please sign in to comment.