Skip to content

Commit ad98d1b

Browse files
authored
Introduce serving profile (#6)
The platform provides a "serving" profile to install a serverless runtime providing developers with an image -> URL experience. Fixes gh-5
1 parent 8af2b35 commit ad98d1b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+495
-281
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ jobs:
1818
registry-server: ghcr.io
1919
registry-username: ${{ github.actor }}
2020
image: ${{ github.repository }}
21-
version: 0.10.0-RC2
21+
version: 0.10.0-RC3
2222
secrets:
2323
pull-request-token: ${{ secrets.GH_ORG_PAT }}

.github/workflows/test.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,14 @@ jobs:
99
permissions:
1010
contents: read
1111
uses: kadras-io/github-reusable-workflows/.github/workflows/carvel-package-test-config.yml@main
12+
13+
test-integration:
14+
name: Integration Tests
15+
strategy:
16+
matrix:
17+
k8s_version: [v1.25, v1.26, v1.27]
18+
permissions:
19+
contents: read
20+
uses: kadras-io/github-reusable-workflows/.github/workflows/carvel-package-test-integration.yml@main
21+
with:
22+
k8s_version: ${{ matrix.k8s_version }}

Makefile

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
K8S_VERSION=v1.26
1+
K8S_VERSION=v1.27
22

33
# Build package configuration
44
build: package
@@ -20,12 +20,20 @@ clean:
2020

2121
# Process the configuration manifests with ytt
2222
ytt:
23-
ytt --file package/config
23+
ytt -f package/config --data-values-file test/unit/config/values.yml
2424

2525
# Use ytt to generate an OpenAPI specification
2626
schema:
2727
ytt -f package/config/values-schema.yml --data-values-schema-inspect -o openapi-v3 > schema-openapi.yml
2828

29+
# Use kbld to resolve the OCI images referenced within the manifests
30+
kbld:
31+
rm -f package/.imgpkg/images.yml && mkdir -p package/.imgpkg && kbld --file package/config --imgpkg-lock-output package/.imgpkg/images.yml 1>> /dev/null
32+
2933
# Check the ytt-annotated Kubernetes configuration and its validation
3034
test-config:
31-
ytt -f package/config | kubeconform -ignore-missing-schemas -summary
35+
ytt -f package/config --data-values-file test/unit/config/values.yml | kubeconform -ignore-missing-schemas -summary
36+
37+
# Run package integration tests
38+
test-integration: test/integration
39+
kubectl kuttl test --config test/integration/kuttl-test.yml --kind-config test/setup/kind/$(K8S_VERSION)/kind-config.yml

README.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
![Test Workflow](https://github.com/kadras-io/engineering-platform/actions/workflows/test.yml/badge.svg)
44
![Release Workflow](https://github.com/kadras-io/engineering-platform/actions/workflows/release.yml/badge.svg)
5-
[![The SLSA Level 3 badge](https://slsa.dev/images/gh-badge-level3.svg)](https://slsa.dev/spec/v0.1/levels)
5+
[![The SLSA Level 3 badge](https://slsa.dev/images/gh-badge-level3.svg)](https://slsa.dev/spec/v1.0/levels)
66
[![The Apache 2.0 license badge](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
77
[![Follow us on Twitter](https://img.shields.io/static/v1?label=Twitter&message=Follow&color=1DA1F2)](https://twitter.com/kadrasIO)
88

@@ -26,10 +26,9 @@ A curated set of Carvel packages to build an engineering platform supporting app
2626
Add the Kadras [package repository](https://github.com/kadras-io/kadras-packages) to your Kubernetes cluster:
2727

2828
```shell
29-
kubectl create namespace kadras-packages
3029
kctrl package repository add -r kadras-packages \
3130
--url ghcr.io/kadras-io/kadras-packages \
32-
-n kadras-packages
31+
-n kadras-packages --create-namespace
3332
```
3433

3534
<details><summary>Installation without package repository</summary>
@@ -75,11 +74,10 @@ The Engineering Platform package can be customized via a `values.yml` file.
7574

7675
```yaml
7776
platform:
77+
platform:
78+
profile: serving
7879
ingress:
7980
domain: thomasvitale.com
80-
oci_registry:
81-
server: ghcr.io
82-
repository: thomasvitale
8381
```
8482
8583
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.
10098

10199
| Config | Default | Description |
102100
|-------|-------------------|-------------|
101+
| `platform.profile` | `full` | The platform profile to install. Options: `full`, `serving`. |
103102
| `platform.namespace` | `kadras-packages` | The namespace where to install the platform. |
104103
| `platform.excluded_packages` | `[]` | A list of packages to exclude from being installed. |
105104
| `platform.ca_cert_data` | `""` | PEM-encoded certificate data to trust TLS connections with a custom CA. |
106-
| `platform.ingress.domain.issuer.type` | `private` | The type of ClusterIssuer the platform will use to enable TLS communications. Options: `private`, `letsencrypt_staging`, `letsencrypt`, `custom`. |
107-
| `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`. |
105+
| `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. |
106+
| `platform.ingress.domain` | `""` | The base domain name the platform will use to configure the Ingress controller. It must be a valid DNS name. |
107+
| `platform.ingress.issuer.type` | `private` | The type of ClusterIssuer the platform will use to enable TLS communications. Options: `private`, `letsencrypt_staging`, `letsencrypt`, `custom`. |
108+
| `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`. |
109+
| `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`. |
108110
| `platform.oci_registry.server` | `""` | The server of the OCI Registry where the platform will publish and consume OCI images. |
109111
| `platform.oci_registry.repository` | `""` | The repository in the OCI Registry where the platform will publish and consume OCI images. |
110-
| `platform.oci_registry.credentials.username` | `""` | Username to access the OCI registry. Note: Use `_json_key` for GCR. |
111-
| `platform.oci_registry.credentials.password` | `""` | Token to access the OCI registry. Note: Use contents of service account key json for GCR. |
112112
| `platform.oci_registry.secret.name` | `supply-chain-registry-credentials` | The name of the Secret holding the credentials to access the OCI registry. |
113113
| `platform.oci_registry.secret.namespace` | `kadras-packages` | The namespace of the Secret holding the credentials to access the OCI registry. |
114114
| `platform.cosign.secret.name` | `supply-chain-cosign-key-pair` | The name of the Secret holding the Cosign key pair. |
115115
| `platform.cosign.secret.namespace` | `kadras-packages` | The namespace of the Secret holding the Cosign key pair. |
116+
| `platform.git.server` | `https://github.com` | The server hosting the Git repositories used by the plaform. |
117+
| `platform.git.secret.name` | `supply-chain-git-credentials` | The name of the Secret holding the credentials to access the Git server. |
118+
| `platform.git.secret.namespace` | `kadras-packages` | The namespace of the Secret holding the credentials to access the Git server. |
116119

117120
Each Kadras package included in the platform can be configured independently.
118121

@@ -148,7 +151,4 @@ This project is licensed under the **Apache License 2.0**. See [LICENSE](LICENSE
148151

149152
## 🙏&nbsp; Acknowledgments
150153

151-
This package is inspired by:
152-
153-
* the App Toolkit package used in [Tanzu Community Edition](https://github.com/vmware-tanzu/community-edition) before its retirement;
154-
* the [OSS Stack](https://github.com/vrabbi/tap-oss) example of [Tanzu Application Platform](https://tanzu.vmware.com/application-platform).
154+
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).

docs/install.md

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## 1. Prerequisites
44

5-
* Kubernetes 1.24+
5+
* Kubernetes 1.25+
66
* Carvel [`kctrl`](https://carvel.dev/kapp-controller/docs/latest/install/#installing-kapp-controller-cli-kctrl) CLI.
77
* Sigstore [`cosign`](https://docs.sigstore.dev/cosign/installation/) CLI.
88
* 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 @@
1414

1515
## 2. Add the Kadras Repository
1616

17-
Add the Kadras repository to make all Kadras packages available to the cluster.
17+
Add the Kadras repository to make all the platform packages available to the cluster.
1818

1919
```shell
20-
kubectl create namespace kadras-packages
2120
kctrl package repository add -r kadras-packages \
2221
--url ghcr.io/kadras-io/kadras-packages \
23-
-n kadras-packages
22+
-n kadras-packages --create-namespace
2423
```
2524

2625
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
6160

6261
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.
6362

64-
## 5. Configure the Platform
63+
## 5. Create Secret for Git server
64+
65+
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.
66+
67+
```shell
68+
export SUPPLY_CHAIN_GIT_USERNAME=<username>
69+
export SUPPLY_CHAIN_GIT_TOKEN=<token>
70+
```
71+
72+
* `<username>` is the username to access the Git server.
73+
* `<token>` is a token with read/write permissions to access the Git server.
74+
75+
```shell
76+
kubectl create secret generic supply-chain-git-credentials \
77+
--from-literal=username"${SUPPLY_CHAIN_REGISTRY_USERNAME}" \
78+
--from-literal=password="${SUPPLY_CHAIN_REGISTRY_TOKEN}" \
79+
--namespace=kadras-packages
80+
```
81+
82+
## 6. Configure the Platform
6583

6684
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.
6785

@@ -73,26 +91,11 @@ platform:
7391
oci_registry:
7492
server: <oci-server>
7593
repository: <oci-repository>
76-
77-
cosign:
78-
secret:
79-
name: supply-chain-cosign-key-pair
80-
namespace: kadras-packages
81-
82-
workspace_provisioner:
83-
namespaces:
84-
- name: default
85-
git:
86-
credentials:
87-
username: <github-username>
88-
password: <github-token>
8994
```
9095
9196
* `<domain>` 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`.
9297
* `<oci-server>` 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`.
9398
* `<oci-repository>` 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.
94-
* `<github-username>` 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.
95-
* `<github-token>` 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.
9699

97100
## 6. Install the Platform
98101

package/config/buildpacks-catalog.yml

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
#@ load("@ytt:data", "data")
22
#@ load("@ytt:struct", "struct")
33
#@ load("@ytt:yaml", "yaml")
4-
#@ load("/helpers.star", "is_package_enabled")
4+
#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles")
55

6-
#@ if is_package_enabled("buildpacks-catalog"):
6+
#@ if is_package_enabled("buildpacks-catalog") and is_any_profile_enabled([profiles.full]):
77

8-
#@ def build_package_values():
9-
#@ values = {
10-
#@ "kp_default_repository": {}
11-
#@ }
8+
#@ def compute_package_values():
9+
#@ values = struct.decode(data.values.buildpacks.catalog)
1210
#@
13-
#@ if data.values.buildpacks.catalog:
14-
#@ values.update(struct.decode(data.values.buildpacks.catalog))
15-
#@ end
16-
#@ 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):
17-
#@ values["kp_default_repository"]["name"] = data.values.platform.oci_registry.server.rstrip("/") + "/" + data.values.platform.oci_registry.repository.rstrip("/") + "/buildpacks"
11+
#@ #! Compute values for OCI Registry server
12+
#@ if data.values.platform.oci_registry.server and data.values.platform.oci_registry.repository:
13+
#@ 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:
14+
#@ values["kp_default_repository"] = {}
15+
#@ values["kp_default_repository"]["name"] = data.values.platform.oci_registry.server.rstrip("/") + "/" + data.values.platform.oci_registry.repository.rstrip("/") + "/buildpacks"
16+
#@ end
1817
#@ end
1918
#@
2019
#@ return struct.encode(values)
@@ -47,6 +46,6 @@ metadata:
4746
name: buildpacks-catalog-values
4847
namespace: #@ data.values.platform.namespace
4948
stringData:
50-
values.yaml: #@ yaml.encode(build_package_values())
49+
values.yaml: #@ yaml.encode(compute_package_values())
5150

5251
#@ end

package/config/cartographer-blueprints.yml

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
#@ load("@ytt:data", "data")
22
#@ load("@ytt:struct", "struct")
33
#@ load("@ytt:yaml", "yaml")
4-
#@ load("/helpers.star", "is_package_enabled")
4+
#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles")
55

6-
#@ if is_package_enabled("cartographer-blueprints"):
6+
#@ if is_package_enabled("cartographer-blueprints") and is_any_profile_enabled([profiles.full]):
77

8-
#@ def build_package_values():
9-
#@ values = {}
10-
#@
11-
#@ if data.values.cartographer.blueprints:
12-
#@ values.update(struct.decode(data.values.cartographer.blueprints))
13-
#@ end
14-
#@
15-
#@ return struct.encode(values)
8+
#@ def compute_package_values():
9+
#@ return data.values.cartographer.blueprints
1610
#@ end
1711

1812
---
@@ -44,6 +38,6 @@ metadata:
4438
name: cartographer-blueprints-values
4539
namespace: #@ data.values.platform.namespace
4640
stringData:
47-
values.yaml: #@ yaml.encode(build_package_values())
41+
values.yaml: #@ yaml.encode(compute_package_values())
4842

4943
#@ end

package/config/cartographer-delivery.yml

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
#@ load("@ytt:data", "data")
22
#@ load("@ytt:struct", "struct")
33
#@ load("@ytt:yaml", "yaml")
4-
#@ load("/helpers.star", "is_package_enabled")
4+
#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles")
55

6-
#@ if is_package_enabled("cartographer-delivery"):
6+
#@ if is_package_enabled("cartographer-delivery") and is_any_profile_enabled([profiles.full]):
77

8-
#@ def build_package_values():
9-
#@ values = {}
10-
#@
11-
#@ if data.values.cartographer.delivery:
12-
#@ values.update(struct.decode(data.values.cartographer.delivery))
13-
#@ end
14-
#@
15-
#@ return struct.encode(values)
8+
#@ def compute_package_values():
9+
#@ return data.values.cartographer.delivery
1610
#@ end
1711

1812
---
@@ -43,6 +37,6 @@ metadata:
4337
name: cartographer-delivery-values
4438
namespace: #@ data.values.platform.namespace
4539
stringData:
46-
values.yaml: #@ yaml.encode(build_package_values())
40+
values.yaml: #@ yaml.encode(compute_package_values())
4741

4842
#@ end

package/config/cartographer-supply-chains.yml

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
#@ load("@ytt:data", "data")
22
#@ load("@ytt:struct", "struct")
33
#@ load("@ytt:yaml", "yaml")
4-
#@ load("/helpers.star", "is_package_enabled")
4+
#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles")
55

6-
#@ if is_package_enabled("cartographer-supply-chains"):
6+
#@ if is_package_enabled("cartographer-supply-chains") and is_any_profile_enabled([profiles.full]):
77

8-
#@ def build_package_values():
9-
#@ values = {
10-
#@ "registry": {}
11-
#@ }
8+
#@ def compute_package_values():
9+
#@ values = struct.decode(data.values.cartographer.supply_chains)
1210
#@
13-
#@ if data.values.cartographer.supply_chains:
14-
#@ values.update(struct.decode(data.values.cartographer.supply_chains))
15-
#@ end
16-
#@ 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):
17-
#@ values["registry"]["server"] = data.values.platform.oci_registry.server.rstrip("/")
18-
#@ values["registry"]["repository"] = data.values.platform.oci_registry.repository.rstrip("/") + "/workloads"
11+
#@ #! Compute values for OCI Registry server
12+
#@ if data.values.platform.oci_registry.server and data.values.platform.oci_registry.repository:
13+
#@ 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:
14+
#@ values["registry"] = {}
15+
#@ values["registry"]["server"] = data.values.platform.oci_registry.server.rstrip("/")
16+
#@ values["registry"]["repository"] = data.values.platform.oci_registry.repository.rstrip("/") + "/workloads"
17+
#@ end
1918
#@ end
2019
#@
2120
#@ return struct.encode(values)
@@ -49,6 +48,6 @@ metadata:
4948
name: cartographer-supply-chains-values
5049
namespace: #@ data.values.platform.namespace
5150
stringData:
52-
values.yaml: #@ yaml.encode(build_package_values())
51+
values.yaml: #@ yaml.encode(compute_package_values())
5352

5453
#@ end

package/config/cartographer.yml

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
#@ load("@ytt:data", "data")
22
#@ load("@ytt:struct", "struct")
33
#@ load("@ytt:yaml", "yaml")
4-
#@ load("/helpers.star", "is_package_enabled")
4+
#@ load("/helpers.star", "is_any_profile_enabled", "is_package_enabled", "profiles")
55

6-
#@ if is_package_enabled("cartographer"):
6+
#@ if is_package_enabled("cartographer") and is_any_profile_enabled([profiles.full]):
77

8-
#@ def build_package_values():
9-
#@ values = {
10-
#@ "ca_cert_data": ""
11-
#@ }
8+
#@ def compute_package_values():
9+
#@ values = struct.decode(data.values.cartographer.core)
1210
#@
13-
#@ if data.values.cartographer.core:
14-
#@ values.update(struct.decode(data.values.cartographer.core))
15-
#@ end
16-
#@ 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):
17-
#@ values["ca_cert_data"] = data.values.platform.ca_cert_data
11+
#@ #! Compute values for CA Certificates
12+
#@ if data.values.platform.ca_cert_data:
13+
#@ values["ca_cert_data"] = values["ca_cert_data"] + data.values.platform.ca_cert_data
1814
#@ end
1915
#@
2016
#@ return struct.encode(values)
@@ -47,6 +43,6 @@ metadata:
4743
name: cartographer-values
4844
namespace: #@ data.values.platform.namespace
4945
stringData:
50-
values.yaml: #@ yaml.encode(build_package_values())
46+
values.yaml: #@ yaml.encode(compute_package_values())
5147

5248
#@ end

0 commit comments

Comments
 (0)