diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 769d8d6..ba0e337 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,6 +18,6 @@ jobs: registry-server: ghcr.io registry-username: ${{ github.actor }} image: ${{ github.repository }} - version: 0.10.0-RC2 + version: 0.10.0-RC3 secrets: pull-request-token: ${{ secrets.GH_ORG_PAT }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 992352b..f178585 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,3 +9,14 @@ jobs: permissions: contents: read uses: kadras-io/github-reusable-workflows/.github/workflows/carvel-package-test-config.yml@main + + test-integration: + name: Integration Tests + strategy: + matrix: + k8s_version: [v1.25, v1.26, v1.27] + permissions: + contents: read + uses: kadras-io/github-reusable-workflows/.github/workflows/carvel-package-test-integration.yml@main + with: + k8s_version: ${{ matrix.k8s_version }} diff --git a/Makefile b/Makefile index c09baed..04dcda4 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -K8S_VERSION=v1.26 +K8S_VERSION=v1.27 # Build package configuration build: package @@ -20,12 +20,20 @@ clean: # Process the configuration manifests with ytt ytt: - ytt --file package/config + ytt -f package/config --data-values-file test/unit/config/values.yml # Use ytt to generate an OpenAPI specification schema: ytt -f package/config/values-schema.yml --data-values-schema-inspect -o openapi-v3 > schema-openapi.yml +# Use kbld to resolve the OCI images referenced within the manifests +kbld: + rm -f package/.imgpkg/images.yml && mkdir -p package/.imgpkg && kbld --file package/config --imgpkg-lock-output package/.imgpkg/images.yml 1>> /dev/null + # Check the ytt-annotated Kubernetes configuration and its validation test-config: - ytt -f package/config | kubeconform -ignore-missing-schemas -summary + ytt -f package/config --data-values-file test/unit/config/values.yml | kubeconform -ignore-missing-schemas -summary + +# Run package integration tests +test-integration: test/integration + kubectl kuttl test --config test/integration/kuttl-test.yml --kind-config test/setup/kind/$(K8S_VERSION)/kind-config.yml diff --git a/README.md b/README.md index 269cc2a..06260cd 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![Test Workflow](https://github.com/kadras-io/engineering-platform/actions/workflows/test.yml/badge.svg) ![Release Workflow](https://github.com/kadras-io/engineering-platform/actions/workflows/release.yml/badge.svg) -[![The SLSA Level 3 badge](https://slsa.dev/images/gh-badge-level3.svg)](https://slsa.dev/spec/v0.1/levels) +[![The SLSA Level 3 badge](https://slsa.dev/images/gh-badge-level3.svg)](https://slsa.dev/spec/v1.0/levels) [![The Apache 2.0 license badge](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![Follow us on Twitter](https://img.shields.io/static/v1?label=Twitter&message=Follow&color=1DA1F2)](https://twitter.com/kadrasIO) @@ -26,10 +26,9 @@ A curated set of Carvel packages to build an engineering platform supporting app Add the Kadras [package repository](https://github.com/kadras-io/kadras-packages) to your Kubernetes cluster: ```shell - kubectl create namespace kadras-packages kctrl package repository add -r kadras-packages \ --url ghcr.io/kadras-io/kadras-packages \ - -n kadras-packages + -n kadras-packages --create-namespace ```
Installation without package repository @@ -75,11 +74,10 @@ The Engineering Platform package can be customized via a `values.yml` file. ```yaml platform: + platform: + profile: serving ingress: domain: thomasvitale.com - oci_registry: - server: ghcr.io - repository: thomasvitale ``` Reference the `values.yml` file from the `kctrl` command when installing or upgrading the package. @@ -100,19 +98,24 @@ The Engineering Platform package has the following configurable properties. | Config | Default | Description | |-------|-------------------|-------------| +| `platform.profile` | `full` | The platform profile to install. Options: `full`, `serving`. | | `platform.namespace` | `kadras-packages` | The namespace where to install the platform. | | `platform.excluded_packages` | `[]` | A list of packages to exclude from being installed. | | `platform.ca_cert_data` | `""` | PEM-encoded certificate data to trust TLS connections with a custom CA. | -| `platform.ingress.domain.issuer.type` | `private` | The type of ClusterIssuer the platform will use to enable TLS communications. Options: `private`, `letsencrypt_staging`, `letsencrypt`, `custom`. | -| `platform.ingress.domain.issuer.name` | `""` | A reference to a custom ClusterIssuer previously created on the cluster where the platform will be installed. Required when the type is `custom`. | +| `platform.infrastructure_provider` | `""` | The underlying infrastructure provider. Options are `local` and `vsphere`. This field is not required, but it enables better validation and defaulting if provided. | +| `platform.ingress.domain` | `""` | The base domain name the platform will use to configure the Ingress controller. It must be a valid DNS name. | +| `platform.ingress.issuer.type` | `private` | The type of ClusterIssuer the platform will use to enable TLS communications. Options: `private`, `letsencrypt_staging`, `letsencrypt`, `custom`. | +| `platform.ingress.issuer.name` | `""` | A reference to a custom ClusterIssuer previously created on the cluster where the platform will be installed. Required when the type is `custom`. | +| `platform.ingress.issuer.email` | `""` | The email address that Let's Encrypt will use to send info on expiring certificates or other issues. Required when the type is `letsencrypt_staging` or `letsencrypt`. | | `platform.oci_registry.server` | `""` | The server of the OCI Registry where the platform will publish and consume OCI images. | | `platform.oci_registry.repository` | `""` | The repository in the OCI Registry where the platform will publish and consume OCI images. | -| `platform.oci_registry.credentials.username` | `""` | Username to access the OCI registry. Note: Use `_json_key` for GCR. | -| `platform.oci_registry.credentials.password` | `""` | Token to access the OCI registry. Note: Use contents of service account key json for GCR. | | `platform.oci_registry.secret.name` | `supply-chain-registry-credentials` | The name of the Secret holding the credentials to access the OCI registry. | | `platform.oci_registry.secret.namespace` | `kadras-packages` | The namespace of the Secret holding the credentials to access the OCI registry. | | `platform.cosign.secret.name` | `supply-chain-cosign-key-pair` | The name of the Secret holding the Cosign key pair. | | `platform.cosign.secret.namespace` | `kadras-packages` | The namespace of the Secret holding the Cosign key pair. | +| `platform.git.server` | `https://github.com` | The server hosting the Git repositories used by the plaform. | +| `platform.git.secret.name` | `supply-chain-git-credentials` | The name of the Secret holding the credentials to access the Git server. | +| `platform.git.secret.namespace` | `kadras-packages` | The namespace of the Secret holding the credentials to access the Git server. | Each Kadras package included in the platform can be configured independently. @@ -148,7 +151,4 @@ This project is licensed under the **Apache License 2.0**. See [LICENSE](LICENSE ## 🙏  Acknowledgments -This package is inspired by: - -* the App Toolkit package used in [Tanzu Community Edition](https://github.com/vmware-tanzu/community-edition) before its retirement; -* the [OSS Stack](https://github.com/vrabbi/tap-oss) example of [Tanzu Application Platform](https://tanzu.vmware.com/application-platform). +This package is inspired by the App Toolkit package used in [Tanzu Community Edition](https://github.com/vmware-tanzu/community-edition) before its retirement and the [open-source example](https://github.com/vrabbi/tap-oss) of [Tanzu Application Platform](https://tanzu.vmware.com/application-platform) by [Scott Rosenberg](https://vrabbi.cloud). diff --git a/docs/install.md b/docs/install.md index b3bbe68..a73c54a 100644 --- a/docs/install.md +++ b/docs/install.md @@ -2,7 +2,7 @@ ## 1. Prerequisites -* Kubernetes 1.24+ +* Kubernetes 1.25+ * Carvel [`kctrl`](https://carvel.dev/kapp-controller/docs/latest/install/#installing-kapp-controller-cli-kctrl) CLI. * Sigstore [`cosign`](https://docs.sigstore.dev/cosign/installation/) CLI. * Carvel [kapp-controller](https://carvel.dev/kapp-controller) deployed in your Kubernetes cluster. You can install it with Carvel [`kapp`](https://carvel.dev/kapp/docs/latest/install) (recommended choice) or `kubectl`. @@ -14,13 +14,12 @@ ## 2. Add the Kadras Repository -Add the Kadras repository to make all Kadras packages available to the cluster. +Add the Kadras repository to make all the platform packages available to the cluster. ```shell - kubectl create namespace kadras-packages kctrl package repository add -r kadras-packages \ --url ghcr.io/kadras-io/kadras-packages \ - -n kadras-packages + -n kadras-packages --create-namespace ``` You can check the full list of available packages as follows. @@ -61,7 +60,26 @@ Next, use Cosign to generate a key-pair that will be used by the platform to sig The previous command will create a cosign.pub file in the current directory. That's the public key you can use the verify OCI artifacts built and signed by the platform. -## 5. Configure the Platform +## 5. Create Secret for Git server + +Then, create a Secret with the credentials to access your Git server in read/write mode. It will be used by the platform to work with Git repositories. + + ```shell + export SUPPLY_CHAIN_GIT_USERNAME= + export SUPPLY_CHAIN_GIT_TOKEN= + ``` + +* `` is the username to access the Git server. +* `` is a token with read/write permissions to access the Git server. + + ```shell + kubectl create secret generic supply-chain-git-credentials \ + --from-literal=username"${SUPPLY_CHAIN_REGISTRY_USERNAME}" \ + --from-literal=password="${SUPPLY_CHAIN_REGISTRY_TOKEN}" \ + --namespace=kadras-packages + ``` + +## 6. Configure the Platform The installation of the Kadras Engineering Platform can be configured via YAML. Create a `values.yml` file with any configuration you need for the platform. The following is a minimal configuration example. @@ -73,26 +91,11 @@ platform: oci_registry: server: repository: - - cosign: - secret: - name: supply-chain-cosign-key-pair - namespace: kadras-packages - -workspace_provisioner: - namespaces: - - name: default - git: - credentials: - username: - password: ``` * `` is the base domain name the platform will use to configure the Ingress controller. It must be a valid DNS name. For example, `lab.thomasvitale.com`. * `` is the server of the OCI registry where the platform will publish and consume OCI images. It must be the same used in step 3 when creating a Secret with the OCI registry credentials. For example, `ghcr.io`, `gcr.io`, `quay.io`, `index.docker.io`. * `` is the repository in the OCI registry where the platform will publish and consume OCI images. It must be the same used in step 3 when creating a Secret with the OCI registry credentials. For example, it might be your username or organization name depending on which OCI server you're using. -* `` is your username to access your Git repositories on GitHub. It's not needed if you won't use the GitOps workflows offered by the platform and only use public Git repositories. -* `` is a token with read/write permissions to access your Git repositories on GitHub. It's not needed if you won't use the GitOps workflows offered by the platform and only use public Git repositories. ## 6. Install the Platform diff --git a/package/config/buildpacks-catalog.yml b/package/config/buildpacks-catalog.yml index 443b40c..59e87f0 100644 --- a/package/config/buildpacks-catalog.yml +++ b/package/config/buildpacks-catalog.yml @@ -1,20 +1,19 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("buildpacks-catalog"): +#@ if is_package_enabled("buildpacks-catalog") and is_any_profile_enabled([profiles.full]): -#@ def build_package_values(): -#@ values = { -#@ "kp_default_repository": {} -#@ } +#@ def compute_package_values(): +#@ values = struct.decode(data.values.buildpacks.catalog) #@ -#@ if data.values.buildpacks.catalog: -#@ values.update(struct.decode(data.values.buildpacks.catalog)) -#@ end -#@ if data.values.platform.oci_registry.server and data.values.platform.oci_registry.repository and (not hasattr(data.values.buildpacks.catalog, "kp_default_repository") or not hasattr(data.values.buildpacks.catalog.kp_default_repository, "name") or not data.values.buildpacks.catalog.kp_default_repository.name): -#@ values["kp_default_repository"]["name"] = data.values.platform.oci_registry.server.rstrip("/") + "/" + data.values.platform.oci_registry.repository.rstrip("/") + "/buildpacks" +#@ #! Compute values for OCI Registry server +#@ if data.values.platform.oci_registry.server and data.values.platform.oci_registry.repository: +#@ if not hasattr(data.values.buildpacks.catalog, "kp_default_repository") or not hasattr(data.values.buildpacks.catalog.kp_default_repository, "name") or not data.values.buildpacks.catalog.kp_default_repository.name: +#@ values["kp_default_repository"] = {} +#@ values["kp_default_repository"]["name"] = data.values.platform.oci_registry.server.rstrip("/") + "/" + data.values.platform.oci_registry.repository.rstrip("/") + "/buildpacks" +#@ end #@ end #@ #@ return struct.encode(values) @@ -47,6 +46,6 @@ metadata: name: buildpacks-catalog-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end diff --git a/package/config/cartographer-blueprints.yml b/package/config/cartographer-blueprints.yml index d5b8c3d..e56c72f 100644 --- a/package/config/cartographer-blueprints.yml +++ b/package/config/cartographer-blueprints.yml @@ -1,18 +1,12 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("cartographer-blueprints"): +#@ if is_package_enabled("cartographer-blueprints") and is_any_profile_enabled([profiles.full]): -#@ def build_package_values(): -#@ values = {} -#@ -#@ if data.values.cartographer.blueprints: -#@ values.update(struct.decode(data.values.cartographer.blueprints)) -#@ end -#@ -#@ return struct.encode(values) +#@ def compute_package_values(): +#@ return data.values.cartographer.blueprints #@ end --- @@ -44,6 +38,6 @@ metadata: name: cartographer-blueprints-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end diff --git a/package/config/cartographer-delivery.yml b/package/config/cartographer-delivery.yml index 623b9c7..898d0bb 100644 --- a/package/config/cartographer-delivery.yml +++ b/package/config/cartographer-delivery.yml @@ -1,18 +1,12 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("cartographer-delivery"): +#@ if is_package_enabled("cartographer-delivery") and is_any_profile_enabled([profiles.full]): -#@ def build_package_values(): -#@ values = {} -#@ -#@ if data.values.cartographer.delivery: -#@ values.update(struct.decode(data.values.cartographer.delivery)) -#@ end -#@ -#@ return struct.encode(values) +#@ def compute_package_values(): +#@ return data.values.cartographer.delivery #@ end --- @@ -43,6 +37,6 @@ metadata: name: cartographer-delivery-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end diff --git a/package/config/cartographer-supply-chains.yml b/package/config/cartographer-supply-chains.yml index f024011..a9c5647 100644 --- a/package/config/cartographer-supply-chains.yml +++ b/package/config/cartographer-supply-chains.yml @@ -1,21 +1,20 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("cartographer-supply-chains"): +#@ if is_package_enabled("cartographer-supply-chains") and is_any_profile_enabled([profiles.full]): -#@ def build_package_values(): -#@ values = { -#@ "registry": {} -#@ } +#@ def compute_package_values(): +#@ values = struct.decode(data.values.cartographer.supply_chains) #@ -#@ if data.values.cartographer.supply_chains: -#@ values.update(struct.decode(data.values.cartographer.supply_chains)) -#@ end -#@ if data.values.platform.oci_registry.server and data.values.platform.oci_registry.repository and (not hasattr(data.values.cartographer.supply_chains, "registry") or not hasattr(data.values.cartographer.supply_chains.registry, "server") or not hasattr(data.values.cartographer.supply_chains.registry, "repository") or not data.values.cartographer.supply_chains.registry.server or not data.values.cartographer.supply_chains.registry.repository): -#@ values["registry"]["server"] = data.values.platform.oci_registry.server.rstrip("/") -#@ values["registry"]["repository"] = data.values.platform.oci_registry.repository.rstrip("/") + "/workloads" +#@ #! Compute values for OCI Registry server +#@ if data.values.platform.oci_registry.server and data.values.platform.oci_registry.repository: +#@ if not hasattr(data.values.cartographer.supply_chains, "registry") or not hasattr(data.values.cartographer.supply_chains.registry, "server") or not hasattr(data.values.cartographer.supply_chains.registry, "repository") or not data.values.cartographer.supply_chains.registry.server or not data.values.cartographer.supply_chains.registry.repository: +#@ values["registry"] = {} +#@ values["registry"]["server"] = data.values.platform.oci_registry.server.rstrip("/") +#@ values["registry"]["repository"] = data.values.platform.oci_registry.repository.rstrip("/") + "/workloads" +#@ end #@ end #@ #@ return struct.encode(values) @@ -49,6 +48,6 @@ metadata: name: cartographer-supply-chains-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end diff --git a/package/config/cartographer.yml b/package/config/cartographer.yml index 6f5ed49..0806e64 100644 --- a/package/config/cartographer.yml +++ b/package/config/cartographer.yml @@ -1,20 +1,16 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("cartographer"): +#@ if is_package_enabled("cartographer") and is_any_profile_enabled([profiles.full]): -#@ def build_package_values(): -#@ values = { -#@ "ca_cert_data": "" -#@ } +#@ def compute_package_values(): +#@ values = struct.decode(data.values.cartographer.core) #@ -#@ if data.values.cartographer.core: -#@ values.update(struct.decode(data.values.cartographer.core)) -#@ end -#@ if data.values.platform.ca_cert_data and (not hasattr(data.values.cartographer.core, "ca_cert_data") or not data.values.cartographer.core.ca_cert_data): -#@ values["ca_cert_data"] = data.values.platform.ca_cert_data +#@ #! Compute values for CA Certificates +#@ if data.values.platform.ca_cert_data: +#@ values["ca_cert_data"] = values["ca_cert_data"] + data.values.platform.ca_cert_data #@ end #@ #@ return struct.encode(values) @@ -47,6 +43,6 @@ metadata: name: cartographer-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end \ No newline at end of file diff --git a/package/config/cert-manager-issuers.yml b/package/config/cert-manager-issuers.yml index 4b229b5..438300d 100644 --- a/package/config/cert-manager-issuers.yml +++ b/package/config/cert-manager-issuers.yml @@ -1,9 +1,9 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("cert-manager-issuers"): +#@ if is_package_enabled("cert-manager-issuers") and is_any_profile_enabled([profiles.full, profiles.serving]): #@ def is_letsencrypt_issuer(issuer): #@ return issuer.type == "letsencrypt_staging" or issuer.type == "letsencrypt" @@ -17,17 +17,16 @@ #@ end #@ end -#@ def build_package_values(): -#@ values = { -#@ "letsencrypt": {} -#@ } +#@ def compute_package_values(): +#@ values = struct.decode(data.values.cert_manager.issuers) #@ -#@ if data.values.cert_manager.issuers: -#@ values.update(struct.decode(data.values.cert_manager.issuers)) -#@ end -#@ if data.values.platform.ingress.issuer and is_letsencrypt_issuer(data.values.platform.ingress.issuer) and (not hasattr(data.values.cert_manager.issuers, "letsencrypt") or not hasattr(data.values.cert_manager.issuers.letsencrypt, "include") or not data.values.cert_manager.issuers.letsencrypt.include): -#@ values["letsencrypt"]["include"] = True -#@ values["letsencrypt"]["staging"] = is_letsencrypt_staging(data.values.platform.ingress.issuer) +#@ if data.values.platform.ingress.issuer and is_letsencrypt_issuer(data.values.platform.ingress.issuer) and data.values.platform.ingress.issuer.email: +#@ if not hasattr(data.values.cert_manager.issuers, "letsencrypt") or not hasattr(data.values.cert_manager.issuers.letsencrypt, "include") or not data.values.cert_manager.issuers.letsencrypt.include: +#@ values["letsencrypt"] = {} +#@ values["letsencrypt"]["include"] = True +#@ values["letsencrypt"]["staging"] = is_letsencrypt_staging(data.values.platform.ingress.issuer) +#@ values["letsencrypt"]["email"] = data.values.platform.ingress.issuer.email +#@ end #@ end #@ #@ return struct.encode(values) @@ -48,7 +47,7 @@ spec: packageRef: refName: cert-manager-issuers.packages.kadras.io versionSelection: - constraints: 0.2.0 + constraints: 0.2.1 prereleases: {} values: - secretRef: @@ -60,6 +59,6 @@ metadata: name: cert-manager-issuers-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end \ No newline at end of file diff --git a/package/config/cert-manager.yml b/package/config/cert-manager.yml index a6a90f2..d68671d 100644 --- a/package/config/cert-manager.yml +++ b/package/config/cert-manager.yml @@ -1,18 +1,12 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("cert-manager"): +#@ if is_package_enabled("cert-manager") and is_any_profile_enabled([profiles.full, profiles.serving]): -#@ def build_package_values(): -#@ values = {} -#@ -#@ if data.values.cert_manager.core: -#@ values.update(struct.decode(data.values.cert_manager.core)) -#@ end -#@ -#@ return struct.encode(values) +#@ def compute_package_values(): +#@ return data.values.cert_manager.core #@ end --- @@ -29,7 +23,7 @@ spec: packageRef: refName: cert-manager.packages.kadras.io versionSelection: - constraints: 1.12.1 + constraints: 1.12.2 prereleases: {} values: - secretRef: @@ -41,6 +35,6 @@ metadata: name: cert-manager-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end \ No newline at end of file diff --git a/package/config/contour.yml b/package/config/contour.yml index 656afe4..5de61e1 100644 --- a/package/config/contour.yml +++ b/package/config/contour.yml @@ -1,20 +1,22 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("contour"): +#@ if is_package_enabled("contour") and is_any_profile_enabled([profiles.full, profiles.serving]): -#@ def build_package_values(): -#@ values = { -#@ "certificates": {} -#@ } +#@ def compute_package_values(): +#@ values = struct.decode(data.values.contour) #@ -#@ if data.values.contour: -#@ values.update(struct.decode(data.values.contour)) +#@ if is_package_enabled("cert-manager"): +#@ if not hasattr(data.values.contour, "certificates") or not hasattr(data.values.contour.certificates, "useCertManager"): +#@ values["certificates"] = {} +#@ values["certificates"]["useCertManager"] = True +#@ end #@ end -#@ if is_package_enabled("cert-manager") and (not hasattr(data.values.contour, "certificates") or not hasattr(data.values.contour.certificates, "useCertManager")): -#@ values["certificates"]["useCertManager"] = True +#@ +#@ if not hasattr(data.values.contour, "infrastructure_provider"): +#@ values["infrastructure_provider"] = data.values.platform.infrastructure_provider #@ end #@ #@ return struct.encode(values) @@ -35,7 +37,7 @@ spec: packageRef: refName: contour.packages.kadras.io versionSelection: - constraints: 1.24.3+kadras.2 + constraints: 1.25.0+kadras.3 values: - secretRef: name: contour-values @@ -46,6 +48,6 @@ metadata: name: contour-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end \ No newline at end of file diff --git a/package/config/fluxcd-source.controller.yml b/package/config/fluxcd-source.controller.yml index a6f35ad..6e556d0 100644 --- a/package/config/fluxcd-source.controller.yml +++ b/package/config/fluxcd-source.controller.yml @@ -1,18 +1,12 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("fluxcd-source-controller"): +#@ if is_package_enabled("fluxcd-source-controller") and is_any_profile_enabled([profiles.full]): -#@ def build_package_values(): -#@ values = {} -#@ -#@ if data.values.flux.source_controller: -#@ values.update(struct.decode(data.values.flux.source_controller)) -#@ end -#@ -#@ return struct.encode(values) +#@ def compute_package_values(): +#@ return data.values.flux.source_controller #@ end --- @@ -40,6 +34,6 @@ metadata: name: fluxcd-source-controller-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end diff --git a/package/config/helpers.star b/package/config/helpers.star index c6b5af5..3a4a01f 100644 --- a/package/config/helpers.star +++ b/package/config/helpers.star @@ -1,9 +1,23 @@ load("@ytt:data", "data") +load("@ytt:struct", "struct") + +profiles = struct.make( + full="full", + serving="serving" +) def is_package_enabled(name): return (name not in data.values.platform.excluded_packages) end +def is_profile_enabled(profile): + return data.values.platform.profile == profile +end + +def is_any_profile_enabled(profiles): + return data.values.platform.profile in profiles +end + def get_issuer_name(issuer): if issuer.type == "private": return "kadras-ca-issuer" diff --git a/package/config/knative-serving.yml b/package/config/knative-serving.yml index fc55ca1..8bcb4dc 100644 --- a/package/config/knative-serving.yml +++ b/package/config/knative-serving.yml @@ -1,26 +1,24 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled", "get_issuer_name") +#@ load("/helpers.star", "get_issuer_name", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("knative-serving"): +#@ if is_package_enabled("knative-serving") and is_any_profile_enabled([profiles.full, profiles.serving]): -#@ def build_package_values(): -#@ values = { -#@ "ca_cert_data": "", -#@ "domain_name": "", -#@ "ingress_issuer": "" -#@ } +#@ def compute_package_values(): +#@ values = struct.decode(data.values.knative.serving) #@ -#@ if data.values.knative.serving: -#@ values.update(struct.decode(data.values.knative.serving)) -#@ end +#@ #! Compute values for CA Certificates #@ if data.values.platform.ca_cert_data and (not hasattr(data.values.knative.serving, "ca_cert_data") or not data.values.knative.serving.ca_cert_data): #@ values["ca_cert_data"] = data.values.platform.ca_cert_data #@ end +#@ +#@ #! Compute values for Ingress Domain Name #@ if data.values.platform.ingress.domain and (not hasattr(data.values.knative.serving, "domain_name") or not data.values.knative.serving.domain_name): #@ values["domain_name"] = data.values.platform.ingress.domain #@ end +#@ +#@ #! Compute values for Ingress Issuer #@ if data.values.platform.ingress.issuer and (not hasattr(data.values.knative.serving, "ingress_issuer") or not data.values.knative.serving.ingress_issuer): #@ values["ingress_issuer"] = get_issuer_name(data.values.platform.ingress.issuer) #@ end @@ -44,7 +42,7 @@ spec: packageRef: refName: knative-serving.packages.kadras.io versionSelection: - constraints: 1.10.2 + constraints: 1.10.2+kadras.1 values: - secretRef: name: knative-serving-values @@ -55,6 +53,6 @@ metadata: name: knative-serving-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end \ No newline at end of file diff --git a/package/config/kpack.yml b/package/config/kpack.yml index 71bde39..39b90f2 100644 --- a/package/config/kpack.yml +++ b/package/config/kpack.yml @@ -1,11 +1,11 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("kpack"): +#@ if is_package_enabled("kpack") and is_any_profile_enabled([profiles.full]): -#@ def build_package_values(): +#@ def compute_package_values(): #@ values = { #@ "ca_cert_data": "", #@ "kp_default_repository": {} @@ -14,28 +14,25 @@ #@ if data.values.buildpacks.kpack: #@ values.update(struct.decode(data.values.buildpacks.kpack)) #@ end -#@ if data.values.platform.ca_cert_data and (not hasattr(data.values.buildpacks.kpack, "ca_cert_data") or not data.values.buildpacks.kpack.ca_cert_data): -#@ values["ca_cert_data"] = data.values.platform.ca_cert_data -#@ end -#@ if data.values.platform.oci_registry.server and data.values.platform.oci_registry.repository and (not hasattr(data.values.buildpacks.kpack, "kp_default_repository") or not hasattr(data.values.buildpacks.kpack.kp_default_repository, "name") or not data.values.buildpacks.kpack.kp_default_repository.name): -#@ values["kp_default_repository"]["name"] = data.values.platform.oci_registry.server.rstrip("/") + "/" + data.values.platform.oci_registry.repository.rstrip("/") + "/buildpacks" +#@ +#@ #! Compute values for CA Certificates +#@ if data.values.platform.ca_cert_data: +#@ values["ca_cert_data"] = values["ca_cert_data"] + data.values.platform.ca_cert_data #@ end -#@ if hasattr(data.values.platform.oci_registry.credentials, "username") and hasattr(data.values.platform.oci_registry.credentials, "password") and data.values.platform.oci_registry.credentials.username and data.values.platform.oci_registry.credentials.password: -#@ if not hasattr(data.values.buildpacks.kpack, "kp_default_repository") or not hasattr(data.values.buildpacks.kpack.kp_default_repository, "credentials") or not hasattr(data.values.buildpacks.kpack.kp_default_repository.credentials, "username") or not hasattr(data.values.buildpacks.kpack.kp_default_repository.credentials, "password") or not data.values.buildpacks.kpack.kp_default_repository.credentials.username or not data.values.buildpacks.kpack.kp_default_repository.credentials.password: -#@ if not hasattr(data.values.buildpacks.kpack, "kp_default_repository") or not hasattr(data.values.buildpacks.kpack.kp_default_repository, "secret") or not hasattr(data.values.buildpacks.kpack.kp_default_repository.secret, "name") or not hasattr(data.values.buildpacks.kpack.kp_default_repository.secret, "namespace") or not data.values.buildpacks.kpack.kp_default_repository.secret.name or not data.values.buildpacks.kpack.kp_default_repository.secret.namespace: -#@ values["kp_default_repository"]["credentials"] = {} -#@ values["kp_default_repository"]["credentials"]["username"] = data.values.platform.oci_registry.credentials.username -#@ values["kp_default_repository"]["credentials"]["password"] = data.values.platform.oci_registry.credentials.password -#@ end +#@ +#@ #! Compute values for OCI Registry server +#@ if data.values.platform.oci_registry.server and data.values.platform.oci_registry.repository: +#@ if not hasattr(data.values.buildpacks.kpack, "kp_default_repository") or not hasattr(data.values.buildpacks.kpack.kp_default_repository, "name") or not data.values.buildpacks.kpack.kp_default_repository.name: +#@ values["kp_default_repository"]["name"] = data.values.platform.oci_registry.server.rstrip("/") + "/" + data.values.platform.oci_registry.repository.rstrip("/") + "/buildpacks" #@ end #@ end +#@ +#@ #! Compute values for OCI Registry secret #@ if data.values.platform.oci_registry.secret.name and data.values.platform.oci_registry.secret.namespace: -#@ if not hasattr(data.values.buildpacks.kpack, "kp_default_repository") or not hasattr(data.values.buildpacks.kpack.kp_default_repository, "credentials") or not hasattr(data.values.buildpacks.kpack.kp_default_repository.credentials, "username") or not hasattr(data.values.buildpacks.kpack.kp_default_repository.credentials, "password") or not data.values.buildpacks.kpack.kp_default_repository.credentials.username or not data.values.buildpacks.kpack.kp_default_repository.credentials.password: -#@ if not hasattr(data.values.buildpacks.kpack, "kp_default_repository") or not hasattr(data.values.buildpacks.kpack.kp_default_repository, "secret") or not hasattr(data.values.buildpacks.kpack.kp_default_repository.secret, "name") or not hasattr(data.values.buildpacks.kpack.kp_default_repository.secret, "namespace") or not data.values.buildpacks.kpack.kp_default_repository.secret.name or not data.values.buildpacks.kpack.kp_default_repository.secret.namespace: -#@ values["kp_default_repository"]["secret"] = {} -#@ values["kp_default_repository"]["secret"]["name"] = data.values.platform.oci_registry.secret.name -#@ values["kp_default_repository"]["secret"]["namespace"] = data.values.platform.oci_registry.secret.namespace -#@ end +#@ if not hasattr(data.values.buildpacks.kpack, "kp_default_repository") or not hasattr(data.values.buildpacks.kpack.kp_default_repository, "secret") or not hasattr(data.values.buildpacks.kpack.kp_default_repository.secret, "name") or not hasattr(data.values.buildpacks.kpack.kp_default_repository.secret, "namespace") or not data.values.buildpacks.kpack.kp_default_repository.secret.name or not data.values.buildpacks.kpack.kp_default_repository.secret.namespace: +#@ values["kp_default_repository"]["secret"] = {} +#@ values["kp_default_repository"]["secret"]["name"] = data.values.platform.oci_registry.secret.name +#@ values["kp_default_repository"]["secret"]["namespace"] = data.values.platform.oci_registry.secret.namespace #@ end #@ end #@ @@ -69,6 +66,6 @@ metadata: name: kpack-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end diff --git a/package/config/metrics-server.yml b/package/config/metrics-server.yml index a676d9f..98808c8 100644 --- a/package/config/metrics-server.yml +++ b/package/config/metrics-server.yml @@ -1,18 +1,12 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("metrics-server"): +#@ if is_package_enabled("metrics-server") and is_any_profile_enabled([profiles.full, profiles.serving]): -#@ def build_package_values(): -#@ values = {} -#@ -#@ if data.values.metrics_server: -#@ values.update(struct.decode(data.values.metrics_server)) -#@ end -#@ -#@ return struct.encode(values) +#@ def compute_package_values(): +#@ return data.values.metrics_server #@ end --- @@ -41,6 +35,6 @@ metadata: name: metrics-server-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end diff --git a/package/config/rbac.yml b/package/config/rbac/cluster-admin.yml similarity index 92% rename from package/config/rbac.yml rename to package/config/rbac/cluster-admin.yml index b4dfcb1..5a1db9a 100644 --- a/package/config/rbac.yml +++ b/package/config/rbac/cluster-admin.yml @@ -1,5 +1,7 @@ #@ load("@ytt:data", "data") +#! RBAC for kapp-controller to install all the platform packages. + --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole @@ -14,6 +16,7 @@ rules: - '*' verbs: - '*' + --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -29,6 +32,7 @@ subjects: - kind: ServiceAccount name: kadras-install-sa namespace: #@ data.values.platform.namespace + --- apiVersion: v1 kind: ServiceAccount diff --git a/package/config/roles/deliverable.yml b/package/config/rbac/deliverable.yml similarity index 100% rename from package/config/roles/deliverable.yml rename to package/config/rbac/deliverable.yml diff --git a/package/config/roles/workload.yml b/package/config/rbac/workload.yml similarity index 100% rename from package/config/roles/workload.yml rename to package/config/rbac/workload.yml diff --git a/package/config/secretgen-controller.yml b/package/config/secretgen-controller.yml index 6a0f660..ac94699 100644 --- a/package/config/secretgen-controller.yml +++ b/package/config/secretgen-controller.yml @@ -1,18 +1,12 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("secretgen-controller"): +#@ if is_package_enabled("secretgen-controller") and is_any_profile_enabled([profiles.serving]): -#@ def build_package_values(): -#@ values = {} -#@ -#@ if data.values.secretgen_controller: -#@ values.update(struct.decode(data.values.secretgen_controller)) -#@ end -#@ -#@ return struct.encode(values) +#@ def compute_package_values(): +#@ return data.values.secretgen_controller #@ end --- @@ -29,7 +23,7 @@ spec: packageRef: refName: secretgen-controller.packages.kadras.io versionSelection: - constraints: 0.14.2 + constraints: 0.14.8 prereleases: {} values: - secretRef: @@ -41,6 +35,6 @@ metadata: name: secretgen-controller-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end diff --git a/package/config/spring-boot-conventions.yml b/package/config/spring-boot-conventions.yml index def1e5f..ac83708 100644 --- a/package/config/spring-boot-conventions.yml +++ b/package/config/spring-boot-conventions.yml @@ -1,18 +1,12 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("spring-boot-conventions"): +#@ if is_package_enabled("spring-boot-conventions") and is_any_profile_enabled([profiles.full]): -#@ def build_package_values(): -#@ values = {} -#@ -#@ if data.values.conventions.spring_boot: -#@ values.update(struct.decode(data.values.conventions.spring_boot)) -#@ end -#@ -#@ return struct.encode(values) +#@ def compute_package_values(): +#@ return data.values.conventions.spring_boot #@ end --- @@ -41,6 +35,6 @@ metadata: name: spring-boot-conventions-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end \ No newline at end of file diff --git a/package/config/tekton-catalog.yml b/package/config/tekton-catalog.yml index cff5cde..4a54d84 100644 --- a/package/config/tekton-catalog.yml +++ b/package/config/tekton-catalog.yml @@ -1,18 +1,12 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("tekton-catalog"): +#@ if is_package_enabled("tekton-catalog") and is_any_profile_enabled([profiles.full]): -#@ def build_package_values(): -#@ values = {} -#@ -#@ if data.values.tekton.catalog: -#@ values.update(struct.decode(data.values.tekton.catalog)) -#@ end -#@ -#@ return struct.encode(values) +#@ def compute_package_values(): +#@ return data.values.tekton.catalog #@ end --- @@ -42,6 +36,6 @@ metadata: name: tekton-catalog-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end diff --git a/package/config/tekton-pipelines.yml b/package/config/tekton-pipelines.yml index a164b5e..669eec9 100644 --- a/package/config/tekton-pipelines.yml +++ b/package/config/tekton-pipelines.yml @@ -1,20 +1,16 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("tekton-pipelines"): +#@ if is_package_enabled("tekton-pipelines") and is_any_profile_enabled([profiles.full]): -#@ def build_package_values(): -#@ values = { -#@ "ca_cert_data": "" -#@ } +#@ def compute_package_values(): +#@ values = struct.decode(data.values.tekton.pipelines) #@ -#@ if data.values.tekton.pipelines: -#@ values.update(struct.decode(data.values.tekton.pipelines)) -#@ end -#@ if data.values.platform.ca_cert_data and (not hasattr(data.values.tekton.pipelines, "ca_cert_data") or not data.values.tekton.pipelines.ca_cert_data): -#@ values["ca_cert_data"] = data.values.platform.ca_cert_data +#@ #! Compute values for CA Certificates +#@ if data.values.platform.ca_cert_data: +#@ values["ca_cert_data"] = values["ca_cert_data"] + data.values.platform.ca_cert_data #@ end #@ #@ return struct.encode(values) @@ -46,6 +42,6 @@ metadata: name: tekton-pipelines-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end diff --git a/package/config/values-schema.yml b/package/config/values-schema.yml index a8ad457..42781c6 100644 --- a/package/config/values-schema.yml +++ b/package/config/values-schema.yml @@ -4,6 +4,9 @@ #@schema/desc "Configuration for the platform packages." platform: + #@schema/desc "The platform profile to install. Options: `full`, `serving`." + #@schema/validation one_of=["full", "serving"] + profile: full #@schema/desc "The namespace where to install the platform." namespace: kadras-packages #@schema/desc "A list of packages to exclude from being installed." @@ -13,6 +16,11 @@ platform: #@schema/desc "PEM-encoded certificate data to trust TLS connections with a custom CA." ca_cert_data: "" + #@schema/desc "The underlying infrastructure provider. Options are `local` and `vsphere`. This field is not required, but it enables better validation and defaulting if provided." + #@schema/validation one_of=["local", "vsphere"] + #@schema/nullable + infrastructure_provider: "" + #@schema/desc "Setting for the Ingress controller that the platform will use." ingress: #@schema/desc "The base domain name the platform will use to configure the Ingress controller. It must be a valid DNS name." @@ -25,9 +33,11 @@ platform: #@schema/desc "A reference to a custom ClusterIssuer previously created on the cluster where the platform will be installed. Required when the type is `custom`." #@schema/validation when=lambda _, ctx: ctx.parent["type"] == "custom" name: "" + #@schema/desc "The email address that Let's Encrypt will use to send info on expiring certificates or other issues. Required when the type is `letsencrypt_staging` or `letsencrypt`." + #@schema/validation when=lambda _, ctx: ctx.parent["type"] == "letsencrypt_staging" or ctx.parent["type"] == "letsencrypt" + email: "" #@schema/desc "Settings for the OCI registry that the platform will use." - #@schema/validation one_not_null=["credentials", "secret"] oci_registry: #@schema/desc "The server of the OCI Registry where the platform will publish and consume OCI images." #@schema/examples ("GitHub Container Registry", "ghcr.io") @@ -35,13 +45,6 @@ platform: #@schema/desc "The repository in the OCI Registry where the platform will publish and consume OCI images." #@schema/examples ("Repository on GitHub Container Registry", "my-org") repository: "" - #@schema/desc "Credentials to access the OCI registry." - #@schema/nullable - credentials: - #@schema/desc "Username to access the OCI registry. Note: Use `_json_key` for GCR." - username: "" - #@schema/desc "Token to access the OCI registry. Note: Use contents of service account key json for GCR." - password: "" #@schema/desc "Configuration for the Secret holding the credentials to access the OCI registry." secret: #@schema/desc "The name of the Secret holding the credentials to access the OCI registry." @@ -54,9 +57,21 @@ platform: #@schema/desc "Configuration for the Secret holding the Cosign key pair." secret: #@schema/desc "The name of the Secret holding the Cosign key pair." - name: "" + name: supply-chain-cosign-key-pair #@schema/desc "The namespace of the Secret holding the Cosign key pair." - namespace: "" + namespace: kadras-packages + + #@schema/desc "Settings for the Git server that the platform will use." + git: + #@schema/desc "The server hosting the Git repositories used by the plaform." + #@schema/examples ("GitHub", "https://github.com") + server: https://github.com + #@schema/desc "Configuration for the Secret holding the credentials to access the Git server." + secret: + #@schema/desc "The name of the Secret holding the credentials to access the Git server." + name: supply-chain-git-credentials + #@schema/desc "The namespace of the Secret holding the credentials to access the Git server." + namespace: kadras-packages #@schema/desc "Configuration for Buildpacks related packages." buildpacks: diff --git a/package/config/workspace-provisioner.yml b/package/config/workspace-provisioner.yml index 594ab08..de564f1 100644 --- a/package/config/workspace-provisioner.yml +++ b/package/config/workspace-provisioner.yml @@ -1,30 +1,53 @@ #@ load("@ytt:data", "data") #@ load("@ytt:struct", "struct") #@ load("@ytt:yaml", "yaml") -#@ load("/helpers.star", "is_package_enabled") +#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles") -#@ if is_package_enabled("workspace-provisioner"): +#@ if is_package_enabled("workspace-provisioner") and is_any_profile_enabled([profiles.full, profiles.serving]): -#@ def build_package_values(): -#@ values = { -#@ "oci_registry": { -#@ "secret": {} -#@ }, -#@ "cosign": { -#@ "secret": {} -#@ } -#@ } +#@ def compute_package_values(): +#@ values = struct.decode(data.values.workspace_provisioner) #@ -#@ if data.values.workspace_provisioner: -#@ values.update(struct.decode(data.values.workspace_provisioner)) +#@ #! Compute values for OCI Registry server +#@ if is_any_profile_enabled([profiles.full]): +#@ if data.values.platform.oci_registry.secret.name and data.values.platform.oci_registry.secret.namespace: +#@ if not hasattr(data.values.workspace_provisioner, "oci_registry") or not hasattr(data.values.workspace_provisioner.oci_registry, "secret") or not hasattr(data.values.workspace_provisioner.oci_registry.secret, "name") or not hasattr(data.values.workspace_provisioner.oci_registry.secret, "namespace") or not data.values.workspace_provisioner.oci_registry.secret.name or not data.values.workspace_provisioner.oci_registry.secret.namespace: +#@ values["oci_registry"] = {} +#@ values["oci_registry"]["secret"] = {} +#@ values["oci_registry"]["secret"]["name"] = data.values.platform.oci_registry.secret.name +#@ values["oci_registry"]["secret"]["namespace"] = data.values.platform.oci_registry.secret.namespace +#@ end +#@ end #@ end -#@ if data.values.platform.oci_registry.secret.name and data.values.platform.oci_registry.secret.namespace and (not hasattr(data.values.workspace_provisioner, "oci_registry") or not hasattr(data.values.workspace_provisioner.oci_registry, "secret") or not hasattr(data.values.workspace_provisioner.oci_registry.secret, "name") or not hasattr(data.values.workspace_provisioner.oci_registry.secret, "namespace") or not data.values.workspace_provisioner.oci_registry.secret.name or not data.values.workspace_provisioner.oci_registry.secret.namespace): -#@ values["oci_registry"]["secret"]["name"] = data.values.platform.oci_registry.secret.name -#@ values["oci_registry"]["secret"]["namespace"] = data.values.platform.oci_registry.secret.namespace +#@ +#@ #! Compute values for Cosign +#@ if is_any_profile_enabled([profiles.full]): +#@ if data.values.platform.cosign.secret.name and data.values.platform.cosign.secret.namespace: +#@ if not hasattr(data.values.workspace_provisioner, "cosign") or not hasattr(data.values.workspace_provisioner.cosign, "secret") or not hasattr(data.values.workspace_provisioner.cosign.secret, "name") or not hasattr(data.values.workspace_provisioner.cosign.secret, "namespace") or not data.values.workspace_provisioner.cosign.secret.name or not data.values.workspace_provisioner.cosign.secret.namespace: +#@ values["cosign"] = {} +#@ values["cosign"]["secret"] = {} +#@ values["cosign"]["secret"]["name"] = data.values.platform.cosign.secret.name +#@ values["cosign"]["secret"]["namespace"] = data.values.platform.cosign.secret.namespace +#@ end +#@ end +#@ end +#@ +#@ #! Compute values for Git server +#@ if is_any_profile_enabled([profiles.full]): +#@ if data.values.platform.git.server and data.values.platform.git.secret.name and data.values.platform.git.secret.namespace: +#@ if not hasattr(data.values.workspace_provisioner, "git") or not hasattr(data.values.workspace_provisioner.git, "server") or not hasattr(data.values.workspace_provisioner.git, "secret") or not hasattr(data.values.workspace_provisioner.cosign.secret, "name") or not hasattr(data.values.workspace_provisioner.cosign.secret, "namespace") or not data.values.workspace_provisioner.git.server or not data.values.workspace_provisioner.cosign.secret.name or not data.values.workspace_provisioner.cosign.secret.namespace: +#@ values["git"] = {} +#@ values["git"]["server"] = data.values.platform.git.server +#@ values["git"]["secret"] = {} +#@ values["git"]["secret"]["name"] = data.values.platform.git.secret.name +#@ values["git"]["secret"]["namespace"] = data.values.platform.git.secret.namespace +#@ end +#@ end #@ end -#@ if data.values.platform.cosign.secret.name and data.values.platform.cosign.secret.namespace and (not hasattr(data.values.workspace_provisioner, "cosign") or not hasattr(data.values.workspace_provisioner.cosign, "secret") or not hasattr(data.values.workspace_provisioner.cosign.secret, "name") or not hasattr(data.values.workspace_provisioner.cosign.secret, "namespace") or not data.values.workspace_provisioner.cosign.secret.name or not data.values.workspace_provisioner.cosign.secret.namespace): -#@ values["cosign"]["secret"]["name"] = data.values.platform.cosign.secret.name -#@ values["cosign"]["secret"]["namespace"] = data.values.platform.cosign.secret.namespace +#@ +#@ #! Compute values for namespaces +#@ if not hasattr(data.values.workspace_provisioner, "namespaces"): +#@ values["namespaces"] = [{"name": "default"}] #@ end #@ #@ return struct.encode(values) @@ -45,7 +68,7 @@ spec: packageRef: refName: workspace-provisioner.packages.kadras.io versionSelection: - constraints: 0.1.1 + constraints: 0.2.0 values: - secretRef: name: workspace-provisioner-values @@ -56,6 +79,6 @@ metadata: name: workspace-provisioner-values namespace: #@ data.values.platform.namespace stringData: - values.yaml: #@ yaml.encode(build_package_values()) + values.yaml: #@ yaml.encode(compute_package_values()) #@ end diff --git a/test/integration/kuttl-test.yml b/test/integration/kuttl-test.yml new file mode 100644 index 0000000..692b5c5 --- /dev/null +++ b/test/integration/kuttl-test.yml @@ -0,0 +1,46 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestSuite +testDirs: +- ./test/integration +manifestDirs: +- ./test/setup/assets +parallel: 1 +startKIND: true +kindContext: integration +kindNodeCache: true +timeout: 120 +artifactsDir: /tmp/kuttl-artifacts +commands: + - script: | + kapp deploy -a kapp-controller -y \ + -f https://github.com/carvel-dev/kapp-controller/releases/latest/download/release.yml + - script: | + kubectl create namespace kadras-packages + - script: | + kapp deploy -a cert-manager-issuers-package -n kadras-packages -y \ + -f https://github.com/kadras-io/cert-manager-issuers/releases/latest/download/metadata.yml \ + -f https://github.com/kadras-io/cert-manager-issuers/releases/latest/download/package.yml + - script: | + kapp deploy -a cert-manager-package -n kadras-packages -y \ + -f https://github.com/kadras-io/package-for-cert-manager/releases/latest/download/metadata.yml \ + -f https://github.com/kadras-io/package-for-cert-manager/releases/latest/download/package.yml + - script: | + kapp deploy -a contour-package -n kadras-packages -y \ + -f https://github.com/kadras-io/package-for-contour/releases/latest/download/metadata.yml \ + -f https://github.com/kadras-io/package-for-contour/releases/latest/download/package.yml + - script: | + kapp deploy -a knative-serving-package -n kadras-packages -y \ + -f https://github.com/kadras-io/package-for-knative-serving/releases/latest/download/metadata.yml \ + -f https://github.com/kadras-io/package-for-knative-serving/releases/latest/download/package.yml + - script: | + kapp deploy -a metrics-server-package -n kadras-packages -y \ + -f https://github.com/kadras-io/package-for-metrics-server/releases/latest/download/metadata.yml \ + -f https://github.com/kadras-io/package-for-metrics-server/releases/latest/download/package.yml + - script: | + kapp deploy -a secretgen-controller-package -n kadras-packages -y \ + -f https://github.com/kadras-io/package-for-secretgen-controller/releases/latest/download/metadata.yml \ + -f https://github.com/kadras-io/package-for-secretgen-controller/releases/latest/download/package.yml + - script: | + kapp deploy -a workspace-provisioner-package -n kadras-packages -y \ + -f https://github.com/kadras-io/workspace-provisioner/releases/latest/download/metadata.yml \ + -f https://github.com/kadras-io/workspace-provisioner/releases/latest/download/package.yml diff --git a/test/integration/serving/00-install.yaml b/test/integration/serving/00-install.yaml new file mode 100644 index 0000000..3f1bb4e --- /dev/null +++ b/test/integration/serving/00-install.yaml @@ -0,0 +1,8 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: | + cd ../../../package && \ + kubectl config set-context --current --namespace=tests && \ + ytt -f ../test/integration/serving/config -f package-resources.yml | kctrl dev -f- --local -y diff --git a/test/integration/serving/01-application.yaml b/test/integration/serving/01-application.yaml new file mode 100644 index 0000000..bb9304f --- /dev/null +++ b/test/integration/serving/01-application.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: band-service + namespace: tests +spec: + template: + spec: + containers: + - name: band-service + image: ghcr.io/thomasvitale/band-service + ports: + - containerPort: 8080 diff --git a/test/integration/serving/01-assert.yaml b/test/integration/serving/01-assert.yaml new file mode 100644 index 0000000..2bb5d2b --- /dev/null +++ b/test/integration/serving/01-assert.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +commands: + - script: | + curl -k --fail-with-body https://band-service.tests.127.0.0.1.sslip.io diff --git a/test/integration/serving/02-uninstall.yaml b/test/integration/serving/02-uninstall.yaml new file mode 100644 index 0000000..4fbb14e --- /dev/null +++ b/test/integration/serving/02-uninstall.yaml @@ -0,0 +1,8 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: | + cd ../../../package && \ + kubectl config set-context --current --namespace=tests && \ + ytt -f ../test/integration/serving/config -f package-resources.yml | kctrl dev -f- --local --delete -y diff --git a/test/integration/serving/config/overlay.yml b/test/integration/serving/config/overlay.yml new file mode 100644 index 0000000..8bdfbf6 --- /dev/null +++ b/test/integration/serving/config/overlay.yml @@ -0,0 +1,9 @@ +#@ load("@ytt:overlay", "overlay") + +#@overlay/match by=overlay.subset({"metadata":{"name":"engineering-platform"}, "kind":"PackageInstall"}) +--- +spec: + #@overlay/match missing_ok=True + values: + - secretRef: + name: engineering-platform-values diff --git a/test/integration/serving/config/values.yml b/test/integration/serving/config/values.yml new file mode 100644 index 0000000..e909e7d --- /dev/null +++ b/test/integration/serving/config/values.yml @@ -0,0 +1,13 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: engineering-platform-values + namespace: tests +stringData: + values.yaml: | + platform: + profile: serving + infrastructure_provider: local + ingress: + domain: 127.0.0.1.sslip.io diff --git a/test/setup/kind/local/kind-config.yml b/test/setup/kind/local/kind-config.yml new file mode 100644 index 0000000..11c02ce --- /dev/null +++ b/test/setup/kind/local/kind-config.yml @@ -0,0 +1,12 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane +- role: worker + extraPortMappings: + - containerPort: 80 + hostPort: 80 + listenAddress: "0.0.0.0" + - containerPort: 443 + hostPort: 443 + listenAddress: "0.0.0.0" diff --git a/test/setup/kind/v1.24/kind-config.yml b/test/setup/kind/v1.24/kind-config.yml deleted file mode 100644 index 580e675..0000000 --- a/test/setup/kind/v1.24/kind-config.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -kind: Cluster -apiVersion: kind.x-k8s.io/v1alpha4 -nodes: -- role: control-plane - image: kindest/node:v1.24.12 -- role: worker - image: kindest/node:v1.24.12 diff --git a/test/setup/kind/v1.25/kind-config.yml b/test/setup/kind/v1.25/kind-config.yml index 18a17bd..c987572 100644 --- a/test/setup/kind/v1.25/kind-config.yml +++ b/test/setup/kind/v1.25/kind-config.yml @@ -3,6 +3,13 @@ kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane - image: kindest/node:v1.25.8 + image: kindest/node:v1.25.11 - role: worker - image: kindest/node:v1.25.8 + image: kindest/node:v1.25.11 + extraPortMappings: + - containerPort: 80 + hostPort: 80 + listenAddress: "0.0.0.0" + - containerPort: 443 + hostPort: 443 + listenAddress: "0.0.0.0" diff --git a/test/setup/kind/v1.26/kind-config.yml b/test/setup/kind/v1.26/kind-config.yml index 254a0ab..296dfd1 100644 --- a/test/setup/kind/v1.26/kind-config.yml +++ b/test/setup/kind/v1.26/kind-config.yml @@ -3,6 +3,13 @@ kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane - image: kindest/node:v1.26.3 + image: kindest/node:v1.26.6 - role: worker - image: kindest/node:v1.26.3 + image: kindest/node:v1.26.6 + extraPortMappings: + - containerPort: 80 + hostPort: 80 + listenAddress: "0.0.0.0" + - containerPort: 443 + hostPort: 443 + listenAddress: "0.0.0.0" diff --git a/test/setup/kind/v1.27/kind-config.yml b/test/setup/kind/v1.27/kind-config.yml new file mode 100644 index 0000000..372e1d5 --- /dev/null +++ b/test/setup/kind/v1.27/kind-config.yml @@ -0,0 +1,15 @@ +--- +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane + image: kindest/node:v1.27.3 +- role: worker + image: kindest/node:v1.27.3 + extraPortMappings: + - containerPort: 80 + hostPort: 80 + listenAddress: "0.0.0.0" + - containerPort: 443 + hostPort: 443 + listenAddress: "0.0.0.0" diff --git a/test/unit/config/values.yml b/test/unit/config/values.yml new file mode 100644 index 0000000..4186299 --- /dev/null +++ b/test/unit/config/values.yml @@ -0,0 +1,25 @@ +--- + +platform: + infrastructure_provider: local + + ingress: + domain: kadras.io + + oci_registry: + server: "ghcr.io" + repository: "my-org" + secret: + name: supply-chain-registry-credentials + namespace: kadras-packages + + cosign: + secret: + name: supply-chain-cosign-key-pair + namespace: kadras-packages + + git: + server: https://github.com + secret: + name: supply-chain-git-credentials + namespace: kadras-packages diff --git a/test/unit/test.sh b/test/unit/test.sh new file mode 100644 index 0000000..b8d9fc6 --- /dev/null +++ b/test/unit/test.sh @@ -0,0 +1,36 @@ +kapp deploy -a kapp-controller -y \ + -f https://github.com/carvel-dev/kapp-controller/releases/latest/download/release.yml + +kubectl create namespace kadras-packages + +kapp deploy -a cert-manager-issuers-package -n kadras-packages -y \ + -f https://github.com/kadras-io/cert-manager-issuers/releases/latest/download/metadata.yml \ + -f https://github.com/kadras-io/cert-manager-issuers/releases/latest/download/package.yml + +kapp deploy -a cert-manager-package -n kadras-packages -y \ + -f https://github.com/kadras-io/package-for-cert-manager/releases/latest/download/metadata.yml \ + -f https://github.com/kadras-io/package-for-cert-manager/releases/latest/download/package.yml + +kapp deploy -a contour-package -n kadras-packages -y \ + -f https://github.com/kadras-io/package-for-contour/releases/latest/download/metadata.yml \ + -f https://github.com/kadras-io/package-for-contour/releases/latest/download/package.yml + +kapp deploy -a knative-serving-package -n kadras-packages -y \ + -f https://github.com/kadras-io/package-for-knative-serving/releases/latest/download/metadata.yml \ + -f https://github.com/kadras-io/package-for-knative-serving/releases/latest/download/package.yml + +kapp deploy -a metrics-server-package -n kadras-packages -y \ + -f https://github.com/kadras-io/package-for-metrics-server/releases/latest/download/metadata.yml \ + -f https://github.com/kadras-io/package-for-metrics-server/releases/latest/download/package.yml + +kapp deploy -a secretgen-controller-package -n kadras-packages -y \ + -f https://github.com/kadras-io/package-for-secretgen-controller/releases/latest/download/metadata.yml \ + -f https://github.com/kadras-io/package-for-secretgen-controller/releases/latest/download/package.yml + +kapp deploy -a workspace-provisioner-package -n kadras-packages -y \ + -f https://github.com/kadras-io/workspace-provisioner/releases/latest/download/metadata.yml \ + -f https://github.com/kadras-io/workspace-provisioner/releases/latest/download/package.yml + +make prepare + +ytt -f ../test/integration/serving/config -f package-resources.yml | kctrl dev -f- --local -y