Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ EXAMPLES_PREFIX ?= $(patsubst %,example-%,$(EXAMPLES))
.PHONY: examples
examples: $(EXAMPLES_PREFIX) ## Run the examples.
example-%: manifests generate fmt vet
go run github.com/ntnn/mdextract/cmd/mdextract@main -output run.bash -tags bash,ci ./examples/$*/README.md \
go get github.com/ntnn/mdextract
go run github.com/ntnn/mdextract@main -output run.bash -tags bash,ci ./examples/$*/README.md \
&& trap 'rm -f run.bash' EXIT \
&& bash -xe ./run.bash

Expand Down
38 changes: 20 additions & 18 deletions examples/certs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,16 +133,18 @@ kubectl --kubeconfig ./kubeconfigs/consumer.kubeconfig apply -f ./examples/certs
<!--
```bash ci
source ./hack/lib.bash
kubectl::wait ./kubeconfigs/internalca.kubeconfig certificates.example.platform-mesh.io/cert-from-consumer default create
kubectl::wait ./kubeconfigs/internalca.kubeconfig certificates.cert-manager.io/cert-from-consumer default create
kubectl::wait ./kubeconfigs/internalca.kubeconfig certificates.cert-manager.io/cert-from-consumer default condition=Ready
consumer_cluster="consumer#/kubeconfigs/consumer/kubeconfig+default"
provider_cert="$(echo -n "$consumer_cluster" | sha256sum | cut -c1-12)-cert-from-consumer"
kubectl::wait ./kubeconfigs/internalca.kubeconfig certificates.example.platform-mesh.io/$provider_cert default create
kubectl::wait ./kubeconfigs/internalca.kubeconfig certificates.cert-manager.io/$provider_cert default create
kubectl::wait ./kubeconfigs/internalca.kubeconfig certificates.cert-manager.io/$provider_cert default condition=Ready
```
-->

This will be picked up by resource-broker and sent to the InternalCA provider:

```bash ci
kubectl --kubeconfig ./kubeconfigs/internalca.kubeconfig get certificates.example.platform-mesh.io cert-from-consumer -o yaml
kubectl --kubeconfig ./kubeconfigs/internalca.kubeconfig get certificates.example.platform-mesh.io "$provider_cert" -o yaml
```

```yaml
Expand All @@ -154,7 +156,7 @@ metadata:
- broker.platform-mesh.io/generic-finalizer
- kro.run/finalizer
# ...
name: cert-from-consumer
name: d480f64dc494-cert-from-consumer
namespace: default
# ...
spec:
Expand All @@ -167,7 +169,7 @@ status:
group: core
kind: Secret
version: v1
name: cert-from-consumer
name: d480f64dc494-cert-from-consumer
namespace: default
state: ACTIVE
status: Available
Expand All @@ -186,7 +188,7 @@ items:
kind: Certificate
metadata:
# ...
name: cert-from-consumer
name: d480f64dc494-cert-from-consumer
namespace: default
# ...
spec:
Expand Down Expand Up @@ -216,7 +218,7 @@ items:
blockOwnerDeletion: true
controller: true
kind: Certificate
name: cert-from-consumer
name: d480f64dc494-cert-from-consumer
uid: f6010fea-e5b6-4be7-b6c3-b57165dc2588
# ...
type: kubernetes.io/tls
Expand Down Expand Up @@ -280,18 +282,18 @@ kubectl --kubeconfig ./kubeconfigs/consumer.kubeconfig patch certificate cert-fr

<!--
```bash ci
kubectl::wait ./kubeconfigs/externalca.kubeconfig certificates.example.platform-mesh.io/cert-from-consumer default create
kubectl::wait ./kubeconfigs/externalca.kubeconfig certificates.cert-manager.io/cert-from-consumer default create
kubectl::wait ./kubeconfigs/externalca.kubeconfig certificates.cert-manager.io/cert-from-consumer default condition=Ready
kubectl::wait ./kubeconfigs/externalca.kubeconfig certificates.example.platform-mesh.io/$provider_cert default create
kubectl::wait ./kubeconfigs/externalca.kubeconfig certificates.cert-manager.io/$provider_cert default create
kubectl::wait ./kubeconfigs/externalca.kubeconfig certificates.cert-manager.io/$provider_cert default condition=Ready
```
-->

resource-broker will first create the Certificate in the ExternalCA provider:

<!--
```bash ci
kubectl::wait ./kubeconfigs/externalca.kubeconfig certificates.cert-manager.io/cert-from-consumer default create
kubectl::wait ./kubeconfigs/externalca.kubeconfig certificates.cert-manager.io/cert-from-consumer default condition=Ready
kubectl::wait ./kubeconfigs/externalca.kubeconfig certificates.cert-manager.io/$provider_cert default create
kubectl::wait ./kubeconfigs/externalca.kubeconfig certificates.cert-manager.io/$provider_cert default condition=Ready
```
-->

Expand All @@ -311,7 +313,7 @@ items:
- broker.platform-mesh.io/generic-finalizer
- kro.run/finalizer
# ..
name: cert-from-consumer
name: d480f64dc494-cert-from-consumer
namespace: default
# ..
spec:
Expand All @@ -324,7 +326,7 @@ items:
group: core
kind: Secret
version: v1
name: cert-from-consumer
name: d480f64dc494-cert-from-consumer
namespace: default
state: ACTIVE
status: Available
Expand All @@ -333,7 +335,7 @@ items:
kind: Certificate
metadata:
# ...
name: cert-from-consumer
name: d480f64dc494-cert-from-consumer
namespace: default
# ..
spec:
Expand Down Expand Up @@ -364,7 +366,7 @@ items:
blockOwnerDeletion: true
controller: true
kind: Certificate
name: cert-from-consumer
name: d480f64dc494-cert-from-consumer
# ...
type: kubernetes.io/tls
kind: List
Expand All @@ -376,7 +378,7 @@ And then delete it from the InternalCA provider:

<!--
```bash ci
kubectl::wait ./kubeconfigs/internalca.kubeconfig certificates.example.platform-mesh.io/cert-from-consumer default delete
kubectl::wait ./kubeconfigs/internalca.kubeconfig certificates.example.platform-mesh.io/$provider_cert default delete
```
-->

Expand Down
16 changes: 10 additions & 6 deletions examples/certs/run.bash
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,23 @@ _stop_broker() {
}

_cleanup() {
local consumer_cluster
consumer_cluster="consumer#$(kubectl --kubeconfig "$kind_consumer" config current-context)"
local hash
hash=$(echo -n "$consumer_cluster" | sha256sum | cut -c1-12)
local provider_cert="${hash}-cert-from-consumer"

kubectl::delete "$kind_consumer" \
certificates.example.platform-mesh.io/cert-from-consumer \
secret/cert-from-consumer

kubectl::delete "$kind_internalca" \
certificates.example.platform-mesh.io/cert-from-consumer \
certificates.cert-manager.io/cert-from-consumer \
secret/cert-from-consumer
"certificates.example.platform-mesh.io/$provider_cert" \
"secret/$provider_cert"

kubectl::delete "$kind_externalca" \
certificates.example.platform-mesh.io/cert-from-consumer \
certificates.cert-manager.io/cert-from-consumer \
secret/cert-from-consumer
"certificates.example.platform-mesh.io/$provider_cert" \
"secret/$provider_cert"
return 0
}

Expand Down
116 changes: 99 additions & 17 deletions examples/kcp-certs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,65 @@ spec:
kubectl --kubeconfig="./kubeconfigs/workspaces/consumer.kubeconfig" apply -f ./examples/kcp-certs/cert.yaml
```

The resource-broker will see the Certificate in the virtual workspace of the APIExport, pass it to a matching provider. Since the fqdn is `app.internal.corp` the InternalCA provider will issue the certificate:
The resource-broker will see the Certificate in the virtual workspace of the APIExport, pass it to a matching provider. Since the fqdn is `app.internal.corp` the InternalCA provider will issue the certificate.

> [!NOTE]
> Provider-side resource names are prefixed with a hash of the consumer cluster name to prevent
> naming conflicts when multiple consumers create resources with the same name.
> The original consumer-side name `cert-from-consumer` becomes `{hash}-cert-from-consumer` in
> the provider's virtual workspace.

In the provider's virtual workspace the Certificate looks like this.

Grab the hash-prefixed name from the VW:

<!--
Wait for the certificate to appear in the provider's virtual workspace:
```bash ci
kubectl::wait::list \
kubeconfigs/workspaces/internalca.vw.kubeconfig \
certificates.example.platform-mesh.io \
--all-namespaces
```
-->

```bash ci
provider_cert="$(kubectl --kubeconfig kubeconfigs/workspaces/internalca.vw.kubeconfig get certificates.example.platform-mesh.io -A -o jsonpath="{.items[0].metadata.name}")"
```

```bash ci
kubectl --kubeconfig kubeconfigs/workspaces/internalca.vw.kubeconfig get certificates.example.platform-mesh.io "$provider_cert" -o yaml
```

```yaml
apiVersion: v1
items:
- apiVersion: example.platform-mesh.io/v1alpha1
kind: Certificate
metadata:
# ...
name: {hash}-cert-from-consumer
namespace: default
# ...
spec:
fqdn: app.internal.corp
status:
# ...
relatedResources:
secret:
gvk:
group: core
kind: Secret
version: v1
name: {hash}-cert-from-consumer
namespace: default
# ...
kind: List
metadata:
resourceVersion: ""
```

On the compute cluster, api-syncagent further transforms the name using its own cluster IDs and hashes:

<!--
```bash ci
Expand All @@ -326,13 +384,10 @@ kubectl::wait::list \
```
-->


```bash ci
kubectl --kubeconfig kubeconfigs/internalca.kubeconfig get certificates.example.platform-mesh.io --all-namespaces
```

For synchronisation api-syncagent is used, which uses the cluster IDs and hashes to uniquely name the resources:

```
NAMESPACE NAME STATE SYNCED AGE
9n832d7e4xebepg1 2747cabbb481a433679f-42b4d6246cf320c6cee5 ACTIVE True 10m
Expand Down Expand Up @@ -362,15 +417,15 @@ items:
group: core
kind: Secret
version: v1
name: 2747cabbb481a433679f-42b4d6246cf320c6cee5
name: {hash}-cert-from-consumer
namespace: default
# ...
kind: List
metadata:
resourceVersion: ""
```

Grab the name and namespace:
Grab the name and namespace from the compute cluster:

```bash ci
secret_name="$(kubectl --kubeconfig kubeconfigs/internalca.kubeconfig get certificates.example.platform-mesh.io --all-namespaces -o jsonpath="{.items[0].metadata.name}")"
Expand All @@ -382,7 +437,7 @@ Wait for the certificate to be issued.
```bash ci
kubectl::wait::cert::subject \
kubeconfigs/internalca.kubeconfig \
"$secret_name" \
"$provider_cert" \
"$secret_namespace" \
"app.internal.corp"
```
Expand All @@ -399,7 +454,7 @@ kubectl --kubeconfig kubeconfigs/internalca.kubeconfig get secrets --namespace "
Decoding the `tls.crt` field shows the certificate was correctly issued for `app.internal.corp`:

```bash ci
kubectl --kubeconfig kubeconfigs/internalca.kubeconfig get secrets --namespace "$secret_namespace" "$secret_name" -o jsonpath="{.data.tls\.crt}" \
kubectl --kubeconfig kubeconfigs/internalca.kubeconfig get secrets --namespace "$secret_namespace" "$provider_cert" -o jsonpath="{.data.tls\.crt}" \
| base64 --decode \
| openssl x509 -noout -subject
# subject=CN=app.internal.corp
Expand All @@ -412,27 +467,27 @@ Wait for the certificate secret to be synced:
```bash ci
kubectl::wait::cert::subject \
kubeconfigs/workspaces/consumer.kubeconfig \
"$secret_name" \
"cert-from-consumer" \
"default" \
"app.internal.corp"
```
-->

```bash ci
kubectl --kubeconfig kubeconfigs/workspaces/consumer.kubeconfig get secrets "$secret_name"
kubectl --kubeconfig kubeconfigs/workspaces/consumer.kubeconfig get secrets "cert-from-consumer"
```

And comparing the serial number shows it's the same certificate:

```bash ci
kubectl --kubeconfig kubeconfigs/internalca.kubeconfig \
get secrets --namespace "$secret_namespace" "$secret_name" \
get secrets --namespace "$secret_namespace" "$provider_cert" \
-o jsonpath="{.data.tls\.crt}" \
| base64 --decode \
| openssl x509 -noout -serial
# serial=0E7311D15E34081A8F1FD7447F1FF4C7BC055238
kubectl --kubeconfig kubeconfigs/workspaces/consumer.kubeconfig \
get secrets "$secret_name" \
get secrets "cert-from-consumer" \
-o jsonpath="{.data.tls\.crt}" \
| base64 --decode \
| openssl x509 -noout -serial
Expand Down Expand Up @@ -470,16 +525,43 @@ kubectl::wait::list \
```
-->

Grab the hash-prefixed name from the externalca VW:

<!--
Wait for the certificate to appear in the externalca provider's virtual workspace:
```bash ci
kubectl::wait::list \
kubeconfigs/workspaces/externalca.vw.kubeconfig \
certificates.example.platform-mesh.io \
--all-namespaces
```
-->

```bash ci
provider_cert="$(kubectl --kubeconfig kubeconfigs/workspaces/externalca.vw.kubeconfig get certificates.example.platform-mesh.io -A -o jsonpath="{.items[0].metadata.name}")"
```

```bash ci
secret_name="$(kubectl --kubeconfig kubeconfigs/externalca.kubeconfig get certificates.example.platform-mesh.io --all-namespaces -o jsonpath="{.items[0].metadata.name}")"
secret_namespace="$(kubectl --kubeconfig kubeconfigs/externalca.kubeconfig get certificates.example.platform-mesh.io --all-namespaces -o jsonpath="{.items[0].metadata.namespace}")"
```

<!--
Wait for the certificate to be issued.
```bash ci
kubectl::wait::cert::subject \
kubeconfigs/externalca.kubeconfig \
"$provider_cert" \
"$secret_namespace" \
"app.corp.com"
```
-->

And decoding the `tls.crt` field shows the certificate was correctly issued for `app.corp.com`:

```bash ci
kubectl --kubeconfig kubeconfigs/externalca.kubeconfig \
get secrets --namespace "$secret_namespace" "$secret_name" \
get secrets --namespace "$secret_namespace" "$provider_cert" \
-o jsonpath="{.data.tls\.crt}" \
| base64 --decode \
| openssl x509 -noout -subject
Expand All @@ -491,7 +573,7 @@ Wait for the certificate secret to be synced:
```bash ci
kubectl::wait::cert::subject \
kubeconfigs/workspaces/consumer.kubeconfig \
"$secret_name" \
"cert-from-consumer" \
"default" \
"app.corp.com"
```
Expand All @@ -501,7 +583,7 @@ And the secret in the consumer workspace has been updated accordingly:

```bash ci
kubectl --kubeconfig kubeconfigs/workspaces/consumer.kubeconfig \
get secrets "$secret_name" \
get secrets "cert-from-consumer" \
-o jsonpath="{.data.tls\.crt}" \
| base64 --decode \
| openssl x509 -noout -subject
Expand All @@ -512,13 +594,13 @@ And again comparing the serial numbers, now with the certificate in the external

```bash ci
kubectl --kubeconfig kubeconfigs/externalca.kubeconfig \
get secrets --namespace "$secret_namespace" "$secret_name" \
get secrets --namespace "$secret_namespace" "$provider_cert" \
-o jsonpath="{.data.tls\.crt}" \
| base64 --decode \
| openssl x509 -noout -serial
# serial=204F68FCA700404CB7745D7A603BA5A28DC68E95
kubectl --kubeconfig kubeconfigs/workspaces/consumer.kubeconfig \
get secrets "$secret_name" \
get secrets "cert-from-consumer" \
-o jsonpath="{.data.tls\.crt}" \
| base64 --decode \
| openssl x509 -noout -serial
Expand Down
Loading
Loading