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
16 changes: 16 additions & 0 deletions deploy/kustomize/release-tls-selfsigned/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# The release base plus self-signed webhook TLS for clusters
# without cert-manager, so the admission webhook stays ENABLED
# everywhere. Running with --enable-webhook=false is strongly
# discouraged: parameter, immutability, naming and adoption
# errors then surface as Ready=False conditions instead of
# failing the apply. See ../webhook-certgen/README.md.
# The webhook convention hardcodes the buckety namespace (VWC
# clientConfig, cert-manager annotation, certgen Job args), so
# this composition sets it too and is applyable standalone.
# Create the namespace first: kubectl create namespace buckety
namespace: buckety
resources:
- ../release
- ../webhook-certgen
45 changes: 45 additions & 0 deletions deploy/kustomize/webhook-certgen/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
# webhook-certgen

Self-signed webhook TLS without cert-manager. Two
`kube-webhook-certgen` Jobs (the ingress-nginx pattern) mint a
serving certificate into the conventional
`buckety-controller-webhook-tls` Secret and patch the
`buckety-controller` ValidatingWebhookConfiguration's caBundle.
The controller Deployment already mounts that Secret; nothing
else changes.

Use it when your cluster does not run cert-manager, composed next
to the release base:

```yaml
resources:
- github.com/Yolean/buckety-controller/deploy/kustomize/release-tls-selfsigned?ref=<sha>
```

or as `../release` + `../webhook-certgen` separately. With
cert-manager present, skip this and create a Certificate named
`buckety-controller-webhook` with secretName
`buckety-controller-webhook-tls` instead (docs/SCAFFOLDING.md
"Webhook TLS"); the VWC's `cert-manager.io/inject-ca-from`
annotation is inert without cert-manager, so both paths share one
base.

Running with `--enable-webhook=false` is strongly discouraged now
that TLS needs no external infrastructure: without admission,
invalid parameters, immutability violations, bad resolved names
and refused adoptions surface as Ready=False conditions instead
of failing the apply.

Operational notes:

- Startup ordering self-heals: the controller's TLS volume is
optional, so a Pod scheduled before the Secret exists restarts
until the create Job has run; the patch Job retries until the
Secret is readable.
- Completed Jobs self-delete (ttlSecondsAfterFinished) so a
converge loop that re-applies this directory re-runs them:
`create` keeps the existing Secret, `patch` re-writes the same
caBundle. Idempotent by construction.
- certgen issues a long-lived certificate (no rotation). Fine for
dev and internal clusters; where rotation policy matters,
prefer the cert-manager path.
33 changes: 33 additions & 0 deletions deploy/kustomize/webhook-certgen/job-create.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-create
namespace: buckety
spec:
# Completed Jobs self-delete so a later converge pass recreates
# and re-runs them; `create` keeps an existing Secret, so the
# rerun is a no-op once TLS is in place.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: create
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- create
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
# controller-runtime's cert watcher wants these exact file
# names in the mounted Secret; certgen defaults differ.
- --cert-name=tls.crt
- --key-name=tls.key
- --host=buckety-controller-webhook.buckety.svc,buckety-controller-webhook.buckety.svc.cluster.local
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
32 changes: 32 additions & 0 deletions deploy/kustomize/webhook-certgen/job-patch.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-patch
namespace: buckety
spec:
# See job-create.yaml on the TTL. `patch` rewrites caBundle from
# the Secret every run; failures before the create Job finishes
# simply retry via OnFailure.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: patch
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- patch
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
- --webhook-name=buckety-controller
- --patch-validating=true
- --patch-mutating=false
- --patch-failure-policy=Fail
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
11 changes: 11 additions & 0 deletions deploy/kustomize/webhook-certgen/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# Self-signed webhook TLS without cert-manager: kube-webhook-certgen
# Jobs mint the serving cert into the conventional Secret and patch
# the ValidatingWebhookConfiguration caBundle. See README.md.
# Compose next to ../release, or use ../release-tls-selfsigned.
resources:
- serviceaccount.yaml
- rbac.yaml
- job-create.yaml
- job-patch.yaml
46 changes: 46 additions & 0 deletions deploy/kustomize/webhook-certgen/rbac.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: buckety-webhook-certgen
namespace: buckety
rules:
- apiGroups: [""]
resources: [secrets]
verbs: [get, create]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: buckety-webhook-certgen
namespace: buckety
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: buckety-webhook-certgen
rules:
- apiGroups: [admissionregistration.k8s.io]
resources: [validatingwebhookconfigurations]
resourceNames: [buckety-controller]
verbs: [get, update]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: buckety-webhook-certgen
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
5 changes: 5 additions & 0 deletions deploy/kustomize/webhook-certgen/serviceaccount.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: buckety-webhook-certgen
namespace: buckety
15 changes: 10 additions & 5 deletions docs/SCAFFOLDING.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,11 +83,16 @@ must create a `Certificate` named `buckety-controller-webhook`
in the controller namespace with secretName
`buckety-controller-webhook-tls`.

Platforms without cert-manager (ystack at the time of this
writing is one) drop `webhook.yaml` from the overlay AND pass
`--enable-webhook=false` to the controller binary. The manager
starts and the reconcilers run; per-driver parameter validation
moves from admission to the reconcile loop and surfaces on
Platforms without cert-manager use
`deploy/kustomize/webhook-certgen/` (or the
`deploy/kustomize/release-tls-selfsigned/` composition):
kube-webhook-certgen Jobs mint the Secret and patch the caBundle,
so the webhook stays enabled with zero cert infrastructure.

`--enable-webhook=false` remains only as a last-resort escape
hatch and is strongly discouraged. The manager starts and the
reconcilers run; per-driver parameter validation moves from
admission to the reconcile loop and surfaces on
`Buckety.status.conditions` instead of failing the apply. CRD
CEL still enforces spec.backend / spec.name / bucketyRef /
credentialsSecretName immutability and the role/retentionPolicy
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
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
16 changes: 16 additions & 0 deletions deploy/kustomize/release-tls-selfsigned/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# The release base plus self-signed webhook TLS for clusters
# without cert-manager, so the admission webhook stays ENABLED
# everywhere. Running with --enable-webhook=false is strongly
# discouraged: parameter, immutability, naming and adoption
# errors then surface as Ready=False conditions instead of
# failing the apply. See ../webhook-certgen/README.md.
# The webhook convention hardcodes the buckety namespace (VWC
# clientConfig, cert-manager annotation, certgen Job args), so
# this composition sets it too and is applyable standalone.
# Create the namespace first: kubectl create namespace buckety
namespace: buckety
resources:
- ../release
- ../webhook-certgen
45 changes: 45 additions & 0 deletions deploy/kustomize/webhook-certgen/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
# webhook-certgen

Self-signed webhook TLS without cert-manager. Two
`kube-webhook-certgen` Jobs (the ingress-nginx pattern) mint a
serving certificate into the conventional
`buckety-controller-webhook-tls` Secret and patch the
`buckety-controller` ValidatingWebhookConfiguration's caBundle.
The controller Deployment already mounts that Secret; nothing
else changes.

Use it when your cluster does not run cert-manager, composed next
to the release base:

```yaml
resources:
- github.com/Yolean/buckety-controller/deploy/kustomize/release-tls-selfsigned?ref=<sha>
```

or as `../release` + `../webhook-certgen` separately. With
cert-manager present, skip this and create a Certificate named
`buckety-controller-webhook` with secretName
`buckety-controller-webhook-tls` instead (docs/SCAFFOLDING.md
"Webhook TLS"); the VWC's `cert-manager.io/inject-ca-from`
annotation is inert without cert-manager, so both paths share one
base.

Running with `--enable-webhook=false` is strongly discouraged now
that TLS needs no external infrastructure: without admission,
invalid parameters, immutability violations, bad resolved names
and refused adoptions surface as Ready=False conditions instead
of failing the apply.

Operational notes:

- Startup ordering self-heals: the controller's TLS volume is
optional, so a Pod scheduled before the Secret exists restarts
until the create Job has run; the patch Job retries until the
Secret is readable.
- Completed Jobs self-delete (ttlSecondsAfterFinished) so a
converge loop that re-applies this directory re-runs them:
`create` keeps the existing Secret, `patch` re-writes the same
caBundle. Idempotent by construction.
- certgen issues a long-lived certificate (no rotation). Fine for
dev and internal clusters; where rotation policy matters,
prefer the cert-manager path.
33 changes: 33 additions & 0 deletions deploy/kustomize/webhook-certgen/job-create.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-create
namespace: buckety
spec:
# Completed Jobs self-delete so a later converge pass recreates
# and re-runs them; `create` keeps an existing Secret, so the
# rerun is a no-op once TLS is in place.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: create
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- create
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
# controller-runtime's cert watcher wants these exact file
# names in the mounted Secret; certgen defaults differ.
- --cert-name=tls.crt
- --key-name=tls.key
- --host=buckety-controller-webhook.buckety.svc,buckety-controller-webhook.buckety.svc.cluster.local
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
32 changes: 32 additions & 0 deletions deploy/kustomize/webhook-certgen/job-patch.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-patch
namespace: buckety
spec:
# See job-create.yaml on the TTL. `patch` rewrites caBundle from
# the Secret every run; failures before the create Job finishes
# simply retry via OnFailure.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: patch
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- patch
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
- --webhook-name=buckety-controller
- --patch-validating=true
- --patch-mutating=false
- --patch-failure-policy=Fail
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
11 changes: 11 additions & 0 deletions deploy/kustomize/webhook-certgen/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# Self-signed webhook TLS without cert-manager: kube-webhook-certgen
# Jobs mint the serving cert into the conventional Secret and patch
# the ValidatingWebhookConfiguration caBundle. See README.md.
# Compose next to ../release, or use ../release-tls-selfsigned.
resources:
- serviceaccount.yaml
- rbac.yaml
- job-create.yaml
- job-patch.yaml
46 changes: 46 additions & 0 deletions deploy/kustomize/webhook-certgen/rbac.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: buckety-webhook-certgen
namespace: buckety
rules:
- apiGroups: [""]
resources: [secrets]
verbs: [get, create]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: buckety-webhook-certgen
namespace: buckety
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: buckety-webhook-certgen
rules:
- apiGroups: [admissionregistration.k8s.io]
resources: [validatingwebhookconfigurations]
resourceNames: [buckety-controller]
verbs: [get, update]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: buckety-webhook-certgen
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
5 changes: 5 additions & 0 deletions deploy/kustomize/webhook-certgen/serviceaccount.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: buckety-webhook-certgen
namespace: buckety
15 changes: 10 additions & 5 deletions docs/SCAFFOLDING.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,11 +83,16 @@ must create a `Certificate` named `buckety-controller-webhook`
in the controller namespace with secretName
`buckety-controller-webhook-tls`.

Platforms without cert-manager (ystack at the time of this
writing is one) drop `webhook.yaml` from the overlay AND pass
`--enable-webhook=false` to the controller binary. The manager
starts and the reconcilers run; per-driver parameter validation
moves from admission to the reconcile loop and surfaces on
Platforms without cert-manager use
`deploy/kustomize/webhook-certgen/` (or the
`deploy/kustomize/release-tls-selfsigned/` composition):
kube-webhook-certgen Jobs mint the Secret and patch the caBundle,
so the webhook stays enabled with zero cert infrastructure.

`--enable-webhook=false` remains only as a last-resort escape
hatch and is strongly discouraged. The manager starts and the
reconcilers run; per-driver parameter validation moves from
admission to the reconcile loop and surfaces on
`Buckety.status.conditions` instead of failing the apply. CRD
CEL still enforces spec.backend / spec.name / bucketyRef /
credentialsSecretName immutability and the role/retentionPolicy
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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
16 changes: 16 additions & 0 deletions deploy/kustomize/release-tls-selfsigned/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# The release base plus self-signed webhook TLS for clusters
# without cert-manager, so the admission webhook stays ENABLED
# everywhere. Running with --enable-webhook=false is strongly
# discouraged: parameter, immutability, naming and adoption
# errors then surface as Ready=False conditions instead of
# failing the apply. See ../webhook-certgen/README.md.
# The webhook convention hardcodes the buckety namespace (VWC
# clientConfig, cert-manager annotation, certgen Job args), so
# this composition sets it too and is applyable standalone.
# Create the namespace first: kubectl create namespace buckety
namespace: buckety
resources:
- ../release
- ../webhook-certgen
45 changes: 45 additions & 0 deletions deploy/kustomize/webhook-certgen/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
# webhook-certgen

Self-signed webhook TLS without cert-manager. Two
`kube-webhook-certgen` Jobs (the ingress-nginx pattern) mint a
serving certificate into the conventional
`buckety-controller-webhook-tls` Secret and patch the
`buckety-controller` ValidatingWebhookConfiguration's caBundle.
The controller Deployment already mounts that Secret; nothing
else changes.

Use it when your cluster does not run cert-manager, composed next
to the release base:

```yaml
resources:
- github.com/Yolean/buckety-controller/deploy/kustomize/release-tls-selfsigned?ref=<sha>
```

or as `../release` + `../webhook-certgen` separately. With
cert-manager present, skip this and create a Certificate named
`buckety-controller-webhook` with secretName
`buckety-controller-webhook-tls` instead (docs/SCAFFOLDING.md
"Webhook TLS"); the VWC's `cert-manager.io/inject-ca-from`
annotation is inert without cert-manager, so both paths share one
base.

Running with `--enable-webhook=false` is strongly discouraged now
that TLS needs no external infrastructure: without admission,
invalid parameters, immutability violations, bad resolved names
and refused adoptions surface as Ready=False conditions instead
of failing the apply.

Operational notes:

- Startup ordering self-heals: the controller's TLS volume is
optional, so a Pod scheduled before the Secret exists restarts
until the create Job has run; the patch Job retries until the
Secret is readable.
- Completed Jobs self-delete (ttlSecondsAfterFinished) so a
converge loop that re-applies this directory re-runs them:
`create` keeps the existing Secret, `patch` re-writes the same
caBundle. Idempotent by construction.
- certgen issues a long-lived certificate (no rotation). Fine for
dev and internal clusters; where rotation policy matters,
prefer the cert-manager path.
33 changes: 33 additions & 0 deletions deploy/kustomize/webhook-certgen/job-create.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-create
namespace: buckety
spec:
# Completed Jobs self-delete so a later converge pass recreates
# and re-runs them; `create` keeps an existing Secret, so the
# rerun is a no-op once TLS is in place.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: create
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- create
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
# controller-runtime's cert watcher wants these exact file
# names in the mounted Secret; certgen defaults differ.
- --cert-name=tls.crt
- --key-name=tls.key
- --host=buckety-controller-webhook.buckety.svc,buckety-controller-webhook.buckety.svc.cluster.local
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
32 changes: 32 additions & 0 deletions deploy/kustomize/webhook-certgen/job-patch.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-patch
namespace: buckety
spec:
# See job-create.yaml on the TTL. `patch` rewrites caBundle from
# the Secret every run; failures before the create Job finishes
# simply retry via OnFailure.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: patch
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- patch
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
- --webhook-name=buckety-controller
- --patch-validating=true
- --patch-mutating=false
- --patch-failure-policy=Fail
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
11 changes: 11 additions & 0 deletions deploy/kustomize/webhook-certgen/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# Self-signed webhook TLS without cert-manager: kube-webhook-certgen
# Jobs mint the serving cert into the conventional Secret and patch
# the ValidatingWebhookConfiguration caBundle. See README.md.
# Compose next to ../release, or use ../release-tls-selfsigned.
resources:
- serviceaccount.yaml
- rbac.yaml
- job-create.yaml
- job-patch.yaml
46 changes: 46 additions & 0 deletions deploy/kustomize/webhook-certgen/rbac.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: buckety-webhook-certgen
namespace: buckety
rules:
- apiGroups: [""]
resources: [secrets]
verbs: [get, create]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: buckety-webhook-certgen
namespace: buckety
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: buckety-webhook-certgen
rules:
- apiGroups: [admissionregistration.k8s.io]
resources: [validatingwebhookconfigurations]
resourceNames: [buckety-controller]
verbs: [get, update]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: buckety-webhook-certgen
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
5 changes: 5 additions & 0 deletions deploy/kustomize/webhook-certgen/serviceaccount.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: buckety-webhook-certgen
namespace: buckety
15 changes: 10 additions & 5 deletions docs/SCAFFOLDING.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,11 +83,16 @@ must create a `Certificate` named `buckety-controller-webhook`
in the controller namespace with secretName
`buckety-controller-webhook-tls`.

Platforms without cert-manager (ystack at the time of this
writing is one) drop `webhook.yaml` from the overlay AND pass
`--enable-webhook=false` to the controller binary. The manager
starts and the reconcilers run; per-driver parameter validation
moves from admission to the reconcile loop and surfaces on
Platforms without cert-manager use
`deploy/kustomize/webhook-certgen/` (or the
`deploy/kustomize/release-tls-selfsigned/` composition):
kube-webhook-certgen Jobs mint the Secret and patch the caBundle,
so the webhook stays enabled with zero cert infrastructure.

`--enable-webhook=false` remains only as a last-resort escape
hatch and is strongly discouraged. The manager starts and the
reconcilers run; per-driver parameter validation moves from
admission to the reconcile loop and surfaces on
`Buckety.status.conditions` instead of failing the apply. CRD
CEL still enforces spec.backend / spec.name / bucketyRef /
credentialsSecretName immutability and the role/retentionPolicy
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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
16 changes: 16 additions & 0 deletions deploy/kustomize/release-tls-selfsigned/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# The release base plus self-signed webhook TLS for clusters
# without cert-manager, so the admission webhook stays ENABLED
# everywhere. Running with --enable-webhook=false is strongly
# discouraged: parameter, immutability, naming and adoption
# errors then surface as Ready=False conditions instead of
# failing the apply. See ../webhook-certgen/README.md.
# The webhook convention hardcodes the buckety namespace (VWC
# clientConfig, cert-manager annotation, certgen Job args), so
# this composition sets it too and is applyable standalone.
# Create the namespace first: kubectl create namespace buckety
namespace: buckety
resources:
- ../release
- ../webhook-certgen
45 changes: 45 additions & 0 deletions deploy/kustomize/webhook-certgen/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
# webhook-certgen

Self-signed webhook TLS without cert-manager. Two
`kube-webhook-certgen` Jobs (the ingress-nginx pattern) mint a
serving certificate into the conventional
`buckety-controller-webhook-tls` Secret and patch the
`buckety-controller` ValidatingWebhookConfiguration's caBundle.
The controller Deployment already mounts that Secret; nothing
else changes.

Use it when your cluster does not run cert-manager, composed next
to the release base:

```yaml
resources:
- github.com/Yolean/buckety-controller/deploy/kustomize/release-tls-selfsigned?ref=<sha>
```

or as `../release` + `../webhook-certgen` separately. With
cert-manager present, skip this and create a Certificate named
`buckety-controller-webhook` with secretName
`buckety-controller-webhook-tls` instead (docs/SCAFFOLDING.md
"Webhook TLS"); the VWC's `cert-manager.io/inject-ca-from`
annotation is inert without cert-manager, so both paths share one
base.

Running with `--enable-webhook=false` is strongly discouraged now
that TLS needs no external infrastructure: without admission,
invalid parameters, immutability violations, bad resolved names
and refused adoptions surface as Ready=False conditions instead
of failing the apply.

Operational notes:

- Startup ordering self-heals: the controller's TLS volume is
optional, so a Pod scheduled before the Secret exists restarts
until the create Job has run; the patch Job retries until the
Secret is readable.
- Completed Jobs self-delete (ttlSecondsAfterFinished) so a
converge loop that re-applies this directory re-runs them:
`create` keeps the existing Secret, `patch` re-writes the same
caBundle. Idempotent by construction.
- certgen issues a long-lived certificate (no rotation). Fine for
dev and internal clusters; where rotation policy matters,
prefer the cert-manager path.
33 changes: 33 additions & 0 deletions deploy/kustomize/webhook-certgen/job-create.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-create
namespace: buckety
spec:
# Completed Jobs self-delete so a later converge pass recreates
# and re-runs them; `create` keeps an existing Secret, so the
# rerun is a no-op once TLS is in place.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: create
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- create
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
# controller-runtime's cert watcher wants these exact file
# names in the mounted Secret; certgen defaults differ.
- --cert-name=tls.crt
- --key-name=tls.key
- --host=buckety-controller-webhook.buckety.svc,buckety-controller-webhook.buckety.svc.cluster.local
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
32 changes: 32 additions & 0 deletions deploy/kustomize/webhook-certgen/job-patch.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-patch
namespace: buckety
spec:
# See job-create.yaml on the TTL. `patch` rewrites caBundle from
# the Secret every run; failures before the create Job finishes
# simply retry via OnFailure.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: patch
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- patch
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
- --webhook-name=buckety-controller
- --patch-validating=true
- --patch-mutating=false
- --patch-failure-policy=Fail
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
11 changes: 11 additions & 0 deletions deploy/kustomize/webhook-certgen/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# Self-signed webhook TLS without cert-manager: kube-webhook-certgen
# Jobs mint the serving cert into the conventional Secret and patch
# the ValidatingWebhookConfiguration caBundle. See README.md.
# Compose next to ../release, or use ../release-tls-selfsigned.
resources:
- serviceaccount.yaml
- rbac.yaml
- job-create.yaml
- job-patch.yaml
46 changes: 46 additions & 0 deletions deploy/kustomize/webhook-certgen/rbac.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: buckety-webhook-certgen
namespace: buckety
rules:
- apiGroups: [""]
resources: [secrets]
verbs: [get, create]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: buckety-webhook-certgen
namespace: buckety
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: buckety-webhook-certgen
rules:
- apiGroups: [admissionregistration.k8s.io]
resources: [validatingwebhookconfigurations]
resourceNames: [buckety-controller]
verbs: [get, update]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: buckety-webhook-certgen
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
5 changes: 5 additions & 0 deletions deploy/kustomize/webhook-certgen/serviceaccount.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: buckety-webhook-certgen
namespace: buckety
15 changes: 10 additions & 5 deletions docs/SCAFFOLDING.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,11 +83,16 @@ must create a `Certificate` named `buckety-controller-webhook`
in the controller namespace with secretName
`buckety-controller-webhook-tls`.

Platforms without cert-manager (ystack at the time of this
writing is one) drop `webhook.yaml` from the overlay AND pass
`--enable-webhook=false` to the controller binary. The manager
starts and the reconcilers run; per-driver parameter validation
moves from admission to the reconcile loop and surfaces on
Platforms without cert-manager use
`deploy/kustomize/webhook-certgen/` (or the
`deploy/kustomize/release-tls-selfsigned/` composition):
kube-webhook-certgen Jobs mint the Secret and patch the caBundle,
so the webhook stays enabled with zero cert infrastructure.

`--enable-webhook=false` remains only as a last-resort escape
hatch and is strongly discouraged. The manager starts and the
reconcilers run; per-driver parameter validation moves from
admission to the reconcile loop and surfaces on
`Buckety.status.conditions` instead of failing the apply. CRD
CEL still enforces spec.backend / spec.name / bucketyRef /
credentialsSecretName immutability and the role/retentionPolicy
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
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
16 changes: 16 additions & 0 deletions deploy/kustomize/release-tls-selfsigned/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# The release base plus self-signed webhook TLS for clusters
# without cert-manager, so the admission webhook stays ENABLED
# everywhere. Running with --enable-webhook=false is strongly
# discouraged: parameter, immutability, naming and adoption
# errors then surface as Ready=False conditions instead of
# failing the apply. See ../webhook-certgen/README.md.
# The webhook convention hardcodes the buckety namespace (VWC
# clientConfig, cert-manager annotation, certgen Job args), so
# this composition sets it too and is applyable standalone.
# Create the namespace first: kubectl create namespace buckety
namespace: buckety
resources:
- ../release
- ../webhook-certgen
45 changes: 45 additions & 0 deletions deploy/kustomize/webhook-certgen/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
# webhook-certgen

Self-signed webhook TLS without cert-manager. Two
`kube-webhook-certgen` Jobs (the ingress-nginx pattern) mint a
serving certificate into the conventional
`buckety-controller-webhook-tls` Secret and patch the
`buckety-controller` ValidatingWebhookConfiguration's caBundle.
The controller Deployment already mounts that Secret; nothing
else changes.

Use it when your cluster does not run cert-manager, composed next
to the release base:

```yaml
resources:
- github.com/Yolean/buckety-controller/deploy/kustomize/release-tls-selfsigned?ref=<sha>
```

or as `../release` + `../webhook-certgen` separately. With
cert-manager present, skip this and create a Certificate named
`buckety-controller-webhook` with secretName
`buckety-controller-webhook-tls` instead (docs/SCAFFOLDING.md
"Webhook TLS"); the VWC's `cert-manager.io/inject-ca-from`
annotation is inert without cert-manager, so both paths share one
base.

Running with `--enable-webhook=false` is strongly discouraged now
that TLS needs no external infrastructure: without admission,
invalid parameters, immutability violations, bad resolved names
and refused adoptions surface as Ready=False conditions instead
of failing the apply.

Operational notes:

- Startup ordering self-heals: the controller's TLS volume is
optional, so a Pod scheduled before the Secret exists restarts
until the create Job has run; the patch Job retries until the
Secret is readable.
- Completed Jobs self-delete (ttlSecondsAfterFinished) so a
converge loop that re-applies this directory re-runs them:
`create` keeps the existing Secret, `patch` re-writes the same
caBundle. Idempotent by construction.
- certgen issues a long-lived certificate (no rotation). Fine for
dev and internal clusters; where rotation policy matters,
prefer the cert-manager path.
33 changes: 33 additions & 0 deletions deploy/kustomize/webhook-certgen/job-create.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-create
namespace: buckety
spec:
# Completed Jobs self-delete so a later converge pass recreates
# and re-runs them; `create` keeps an existing Secret, so the
# rerun is a no-op once TLS is in place.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: create
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- create
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
# controller-runtime's cert watcher wants these exact file
# names in the mounted Secret; certgen defaults differ.
- --cert-name=tls.crt
- --key-name=tls.key
- --host=buckety-controller-webhook.buckety.svc,buckety-controller-webhook.buckety.svc.cluster.local
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
32 changes: 32 additions & 0 deletions deploy/kustomize/webhook-certgen/job-patch.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-patch
namespace: buckety
spec:
# See job-create.yaml on the TTL. `patch` rewrites caBundle from
# the Secret every run; failures before the create Job finishes
# simply retry via OnFailure.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: patch
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- patch
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
- --webhook-name=buckety-controller
- --patch-validating=true
- --patch-mutating=false
- --patch-failure-policy=Fail
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
11 changes: 11 additions & 0 deletions deploy/kustomize/webhook-certgen/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# Self-signed webhook TLS without cert-manager: kube-webhook-certgen
# Jobs mint the serving cert into the conventional Secret and patch
# the ValidatingWebhookConfiguration caBundle. See README.md.
# Compose next to ../release, or use ../release-tls-selfsigned.
resources:
- serviceaccount.yaml
- rbac.yaml
- job-create.yaml
- job-patch.yaml
46 changes: 46 additions & 0 deletions deploy/kustomize/webhook-certgen/rbac.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: buckety-webhook-certgen
namespace: buckety
rules:
- apiGroups: [""]
resources: [secrets]
verbs: [get, create]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: buckety-webhook-certgen
namespace: buckety
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: buckety-webhook-certgen
rules:
- apiGroups: [admissionregistration.k8s.io]
resources: [validatingwebhookconfigurations]
resourceNames: [buckety-controller]
verbs: [get, update]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: buckety-webhook-certgen
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
5 changes: 5 additions & 0 deletions deploy/kustomize/webhook-certgen/serviceaccount.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: buckety-webhook-certgen
namespace: buckety
15 changes: 10 additions & 5 deletions docs/SCAFFOLDING.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,11 +83,16 @@ must create a `Certificate` named `buckety-controller-webhook`
in the controller namespace with secretName
`buckety-controller-webhook-tls`.

Platforms without cert-manager (ystack at the time of this
writing is one) drop `webhook.yaml` from the overlay AND pass
`--enable-webhook=false` to the controller binary. The manager
starts and the reconcilers run; per-driver parameter validation
moves from admission to the reconcile loop and surfaces on
Platforms without cert-manager use
`deploy/kustomize/webhook-certgen/` (or the
`deploy/kustomize/release-tls-selfsigned/` composition):
kube-webhook-certgen Jobs mint the Secret and patch the caBundle,
so the webhook stays enabled with zero cert infrastructure.

`--enable-webhook=false` remains only as a last-resort escape
hatch and is strongly discouraged. The manager starts and the
reconcilers run; per-driver parameter validation moves from
admission to the reconcile loop and surfaces on
`Buckety.status.conditions` instead of failing the apply. CRD
CEL still enforces spec.backend / spec.name / bucketyRef /
credentialsSecretName immutability and the role/retentionPolicy
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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
16 changes: 16 additions & 0 deletions deploy/kustomize/release-tls-selfsigned/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# The release base plus self-signed webhook TLS for clusters
# without cert-manager, so the admission webhook stays ENABLED
# everywhere. Running with --enable-webhook=false is strongly
# discouraged: parameter, immutability, naming and adoption
# errors then surface as Ready=False conditions instead of
# failing the apply. See ../webhook-certgen/README.md.
# The webhook convention hardcodes the buckety namespace (VWC
# clientConfig, cert-manager annotation, certgen Job args), so
# this composition sets it too and is applyable standalone.
# Create the namespace first: kubectl create namespace buckety
namespace: buckety
resources:
- ../release
- ../webhook-certgen
45 changes: 45 additions & 0 deletions deploy/kustomize/webhook-certgen/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
# webhook-certgen

Self-signed webhook TLS without cert-manager. Two
`kube-webhook-certgen` Jobs (the ingress-nginx pattern) mint a
serving certificate into the conventional
`buckety-controller-webhook-tls` Secret and patch the
`buckety-controller` ValidatingWebhookConfiguration's caBundle.
The controller Deployment already mounts that Secret; nothing
else changes.

Use it when your cluster does not run cert-manager, composed next
to the release base:

```yaml
resources:
- github.com/Yolean/buckety-controller/deploy/kustomize/release-tls-selfsigned?ref=<sha>
```

or as `../release` + `../webhook-certgen` separately. With
cert-manager present, skip this and create a Certificate named
`buckety-controller-webhook` with secretName
`buckety-controller-webhook-tls` instead (docs/SCAFFOLDING.md
"Webhook TLS"); the VWC's `cert-manager.io/inject-ca-from`
annotation is inert without cert-manager, so both paths share one
base.

Running with `--enable-webhook=false` is strongly discouraged now
that TLS needs no external infrastructure: without admission,
invalid parameters, immutability violations, bad resolved names
and refused adoptions surface as Ready=False conditions instead
of failing the apply.

Operational notes:

- Startup ordering self-heals: the controller's TLS volume is
optional, so a Pod scheduled before the Secret exists restarts
until the create Job has run; the patch Job retries until the
Secret is readable.
- Completed Jobs self-delete (ttlSecondsAfterFinished) so a
converge loop that re-applies this directory re-runs them:
`create` keeps the existing Secret, `patch` re-writes the same
caBundle. Idempotent by construction.
- certgen issues a long-lived certificate (no rotation). Fine for
dev and internal clusters; where rotation policy matters,
prefer the cert-manager path.
33 changes: 33 additions & 0 deletions deploy/kustomize/webhook-certgen/job-create.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-create
namespace: buckety
spec:
# Completed Jobs self-delete so a later converge pass recreates
# and re-runs them; `create` keeps an existing Secret, so the
# rerun is a no-op once TLS is in place.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: create
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- create
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
# controller-runtime's cert watcher wants these exact file
# names in the mounted Secret; certgen defaults differ.
- --cert-name=tls.crt
- --key-name=tls.key
- --host=buckety-controller-webhook.buckety.svc,buckety-controller-webhook.buckety.svc.cluster.local
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
32 changes: 32 additions & 0 deletions deploy/kustomize/webhook-certgen/job-patch.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-patch
namespace: buckety
spec:
# See job-create.yaml on the TTL. `patch` rewrites caBundle from
# the Secret every run; failures before the create Job finishes
# simply retry via OnFailure.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: patch
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- patch
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
- --webhook-name=buckety-controller
- --patch-validating=true
- --patch-mutating=false
- --patch-failure-policy=Fail
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
11 changes: 11 additions & 0 deletions deploy/kustomize/webhook-certgen/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# Self-signed webhook TLS without cert-manager: kube-webhook-certgen
# Jobs mint the serving cert into the conventional Secret and patch
# the ValidatingWebhookConfiguration caBundle. See README.md.
# Compose next to ../release, or use ../release-tls-selfsigned.
resources:
- serviceaccount.yaml
- rbac.yaml
- job-create.yaml
- job-patch.yaml
46 changes: 46 additions & 0 deletions deploy/kustomize/webhook-certgen/rbac.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: buckety-webhook-certgen
namespace: buckety
rules:
- apiGroups: [""]
resources: [secrets]
verbs: [get, create]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: buckety-webhook-certgen
namespace: buckety
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: buckety-webhook-certgen
rules:
- apiGroups: [admissionregistration.k8s.io]
resources: [validatingwebhookconfigurations]
resourceNames: [buckety-controller]
verbs: [get, update]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: buckety-webhook-certgen
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
5 changes: 5 additions & 0 deletions deploy/kustomize/webhook-certgen/serviceaccount.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: buckety-webhook-certgen
namespace: buckety
15 changes: 10 additions & 5 deletions docs/SCAFFOLDING.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,11 +83,16 @@ must create a `Certificate` named `buckety-controller-webhook`
in the controller namespace with secretName
`buckety-controller-webhook-tls`.

Platforms without cert-manager (ystack at the time of this
writing is one) drop `webhook.yaml` from the overlay AND pass
`--enable-webhook=false` to the controller binary. The manager
starts and the reconcilers run; per-driver parameter validation
moves from admission to the reconcile loop and surfaces on
Platforms without cert-manager use
`deploy/kustomize/webhook-certgen/` (or the
`deploy/kustomize/release-tls-selfsigned/` composition):
kube-webhook-certgen Jobs mint the Secret and patch the caBundle,
so the webhook stays enabled with zero cert infrastructure.

`--enable-webhook=false` remains only as a last-resort escape
hatch and is strongly discouraged. The manager starts and the
reconcilers run; per-driver parameter validation moves from
admission to the reconcile loop and surfaces on
`Buckety.status.conditions` instead of failing the apply. CRD
CEL still enforces spec.backend / spec.name / bucketyRef /
credentialsSecretName immutability and the role/retentionPolicy
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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
16 changes: 16 additions & 0 deletions deploy/kustomize/release-tls-selfsigned/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# The release base plus self-signed webhook TLS for clusters
# without cert-manager, so the admission webhook stays ENABLED
# everywhere. Running with --enable-webhook=false is strongly
# discouraged: parameter, immutability, naming and adoption
# errors then surface as Ready=False conditions instead of
# failing the apply. See ../webhook-certgen/README.md.
# The webhook convention hardcodes the buckety namespace (VWC
# clientConfig, cert-manager annotation, certgen Job args), so
# this composition sets it too and is applyable standalone.
# Create the namespace first: kubectl create namespace buckety
namespace: buckety
resources:
- ../release
- ../webhook-certgen
45 changes: 45 additions & 0 deletions deploy/kustomize/webhook-certgen/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
# webhook-certgen

Self-signed webhook TLS without cert-manager. Two
`kube-webhook-certgen` Jobs (the ingress-nginx pattern) mint a
serving certificate into the conventional
`buckety-controller-webhook-tls` Secret and patch the
`buckety-controller` ValidatingWebhookConfiguration's caBundle.
The controller Deployment already mounts that Secret; nothing
else changes.

Use it when your cluster does not run cert-manager, composed next
to the release base:

```yaml
resources:
- github.com/Yolean/buckety-controller/deploy/kustomize/release-tls-selfsigned?ref=<sha>
```

or as `../release` + `../webhook-certgen` separately. With
cert-manager present, skip this and create a Certificate named
`buckety-controller-webhook` with secretName
`buckety-controller-webhook-tls` instead (docs/SCAFFOLDING.md
"Webhook TLS"); the VWC's `cert-manager.io/inject-ca-from`
annotation is inert without cert-manager, so both paths share one
base.

Running with `--enable-webhook=false` is strongly discouraged now
that TLS needs no external infrastructure: without admission,
invalid parameters, immutability violations, bad resolved names
and refused adoptions surface as Ready=False conditions instead
of failing the apply.

Operational notes:

- Startup ordering self-heals: the controller's TLS volume is
optional, so a Pod scheduled before the Secret exists restarts
until the create Job has run; the patch Job retries until the
Secret is readable.
- Completed Jobs self-delete (ttlSecondsAfterFinished) so a
converge loop that re-applies this directory re-runs them:
`create` keeps the existing Secret, `patch` re-writes the same
caBundle. Idempotent by construction.
- certgen issues a long-lived certificate (no rotation). Fine for
dev and internal clusters; where rotation policy matters,
prefer the cert-manager path.
33 changes: 33 additions & 0 deletions deploy/kustomize/webhook-certgen/job-create.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-create
namespace: buckety
spec:
# Completed Jobs self-delete so a later converge pass recreates
# and re-runs them; `create` keeps an existing Secret, so the
# rerun is a no-op once TLS is in place.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: create
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- create
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
# controller-runtime's cert watcher wants these exact file
# names in the mounted Secret; certgen defaults differ.
- --cert-name=tls.crt
- --key-name=tls.key
- --host=buckety-controller-webhook.buckety.svc,buckety-controller-webhook.buckety.svc.cluster.local
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
32 changes: 32 additions & 0 deletions deploy/kustomize/webhook-certgen/job-patch.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-patch
namespace: buckety
spec:
# See job-create.yaml on the TTL. `patch` rewrites caBundle from
# the Secret every run; failures before the create Job finishes
# simply retry via OnFailure.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: patch
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- patch
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
- --webhook-name=buckety-controller
- --patch-validating=true
- --patch-mutating=false
- --patch-failure-policy=Fail
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
11 changes: 11 additions & 0 deletions deploy/kustomize/webhook-certgen/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# Self-signed webhook TLS without cert-manager: kube-webhook-certgen
# Jobs mint the serving cert into the conventional Secret and patch
# the ValidatingWebhookConfiguration caBundle. See README.md.
# Compose next to ../release, or use ../release-tls-selfsigned.
resources:
- serviceaccount.yaml
- rbac.yaml
- job-create.yaml
- job-patch.yaml
46 changes: 46 additions & 0 deletions deploy/kustomize/webhook-certgen/rbac.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: buckety-webhook-certgen
namespace: buckety
rules:
- apiGroups: [""]
resources: [secrets]
verbs: [get, create]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: buckety-webhook-certgen
namespace: buckety
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: buckety-webhook-certgen
rules:
- apiGroups: [admissionregistration.k8s.io]
resources: [validatingwebhookconfigurations]
resourceNames: [buckety-controller]
verbs: [get, update]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: buckety-webhook-certgen
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
5 changes: 5 additions & 0 deletions deploy/kustomize/webhook-certgen/serviceaccount.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: buckety-webhook-certgen
namespace: buckety
15 changes: 10 additions & 5 deletions docs/SCAFFOLDING.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,11 +83,16 @@ must create a `Certificate` named `buckety-controller-webhook`
in the controller namespace with secretName
`buckety-controller-webhook-tls`.

Platforms without cert-manager (ystack at the time of this
writing is one) drop `webhook.yaml` from the overlay AND pass
`--enable-webhook=false` to the controller binary. The manager
starts and the reconcilers run; per-driver parameter validation
moves from admission to the reconcile loop and surfaces on
Platforms without cert-manager use
`deploy/kustomize/webhook-certgen/` (or the
`deploy/kustomize/release-tls-selfsigned/` composition):
kube-webhook-certgen Jobs mint the Secret and patch the caBundle,
so the webhook stays enabled with zero cert infrastructure.

`--enable-webhook=false` remains only as a last-resort escape
hatch and is strongly discouraged. The manager starts and the
reconcilers run; per-driver parameter validation moves from
admission to the reconcile loop and surfaces on
`Buckety.status.conditions` instead of failing the apply. CRD
CEL still enforces spec.backend / spec.name / bucketyRef /
credentialsSecretName immutability and the role/retentionPolicy
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
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
16 changes: 16 additions & 0 deletions deploy/kustomize/release-tls-selfsigned/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# The release base plus self-signed webhook TLS for clusters
# without cert-manager, so the admission webhook stays ENABLED
# everywhere. Running with --enable-webhook=false is strongly
# discouraged: parameter, immutability, naming and adoption
# errors then surface as Ready=False conditions instead of
# failing the apply. See ../webhook-certgen/README.md.
# The webhook convention hardcodes the buckety namespace (VWC
# clientConfig, cert-manager annotation, certgen Job args), so
# this composition sets it too and is applyable standalone.
# Create the namespace first: kubectl create namespace buckety
namespace: buckety
resources:
- ../release
- ../webhook-certgen
45 changes: 45 additions & 0 deletions deploy/kustomize/webhook-certgen/README.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
# webhook-certgen

Self-signed webhook TLS without cert-manager. Two
`kube-webhook-certgen` Jobs (the ingress-nginx pattern) mint a
serving certificate into the conventional
`buckety-controller-webhook-tls` Secret and patch the
`buckety-controller` ValidatingWebhookConfiguration's caBundle.
The controller Deployment already mounts that Secret; nothing
else changes.

Use it when your cluster does not run cert-manager, composed next
to the release base:

```yaml
resources:
- github.com/Yolean/buckety-controller/deploy/kustomize/release-tls-selfsigned?ref=<sha>
```

or as `../release` + `../webhook-certgen` separately. With
cert-manager present, skip this and create a Certificate named
`buckety-controller-webhook` with secretName
`buckety-controller-webhook-tls` instead (docs/SCAFFOLDING.md
"Webhook TLS"); the VWC's `cert-manager.io/inject-ca-from`
annotation is inert without cert-manager, so both paths share one
base.

Running with `--enable-webhook=false` is strongly discouraged now
that TLS needs no external infrastructure: without admission,
invalid parameters, immutability violations, bad resolved names
and refused adoptions surface as Ready=False conditions instead
of failing the apply.

Operational notes:

- Startup ordering self-heals: the controller's TLS volume is
optional, so a Pod scheduled before the Secret exists restarts
until the create Job has run; the patch Job retries until the
Secret is readable.
- Completed Jobs self-delete (ttlSecondsAfterFinished) so a
converge loop that re-applies this directory re-runs them:
`create` keeps the existing Secret, `patch` re-writes the same
caBundle. Idempotent by construction.
- certgen issues a long-lived certificate (no rotation). Fine for
dev and internal clusters; where rotation policy matters,
prefer the cert-manager path.
33 changes: 33 additions & 0 deletions deploy/kustomize/webhook-certgen/job-create.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-create
namespace: buckety
spec:
# Completed Jobs self-delete so a later converge pass recreates
# and re-runs them; `create` keeps an existing Secret, so the
# rerun is a no-op once TLS is in place.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: create
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- create
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
# controller-runtime's cert watcher wants these exact file
# names in the mounted Secret; certgen defaults differ.
- --cert-name=tls.crt
- --key-name=tls.key
- --host=buckety-controller-webhook.buckety.svc,buckety-controller-webhook.buckety.svc.cluster.local
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
32 changes: 32 additions & 0 deletions deploy/kustomize/webhook-certgen/job-patch.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
apiVersion: batch/v1
kind: Job
metadata:
name: buckety-webhook-certgen-patch
namespace: buckety
spec:
# See job-create.yaml on the TTL. `patch` rewrites caBundle from
# the Secret every run; failures before the create Job finishes
# simply retry via OnFailure.
ttlSecondsAfterFinished: 300
template:
spec:
restartPolicy: OnFailure
serviceAccountName: buckety-webhook-certgen
containers:
- name: patch
image: registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.6.9@sha256:01038e7de14b78d702d2849c3aad72fd25903c4765af63cf16aa3398f5d5f2dd
args:
- patch
- --namespace=buckety
- --secret-name=buckety-controller-webhook-tls
- --webhook-name=buckety-controller
- --patch-validating=true
- --patch-mutating=false
- --patch-failure-policy=Fail
securityContext:
allowPrivilegeEscalation: false
capabilities: {drop: [ALL]}
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
seccompProfile: {type: RuntimeDefault}
11 changes: 11 additions & 0 deletions deploy/kustomize/webhook-certgen/kustomization.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
# Self-signed webhook TLS without cert-manager: kube-webhook-certgen
# Jobs mint the serving cert into the conventional Secret and patch
# the ValidatingWebhookConfiguration caBundle. See README.md.
# Compose next to ../release, or use ../release-tls-selfsigned.
resources:
- serviceaccount.yaml
- rbac.yaml
- job-create.yaml
- job-patch.yaml
46 changes: 46 additions & 0 deletions deploy/kustomize/webhook-certgen/rbac.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: buckety-webhook-certgen
namespace: buckety
rules:
- apiGroups: [""]
resources: [secrets]
verbs: [get, create]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: buckety-webhook-certgen
namespace: buckety
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: buckety-webhook-certgen
rules:
- apiGroups: [admissionregistration.k8s.io]
resources: [validatingwebhookconfigurations]
resourceNames: [buckety-controller]
verbs: [get, update]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: buckety-webhook-certgen
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: buckety-webhook-certgen
subjects:
- kind: ServiceAccount
name: buckety-webhook-certgen
namespace: buckety
5 changes: 5 additions & 0 deletions deploy/kustomize/webhook-certgen/serviceaccount.yaml
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: buckety-webhook-certgen
namespace: buckety
15 changes: 10 additions & 5 deletions docs/SCAFFOLDING.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -83,11 +83,16 @@ must create a `Certificate` named `buckety-controller-webhook`
in the controller namespace with secretName
`buckety-controller-webhook-tls`.

Platforms without cert-manager (ystack at the time of this
writing is one) drop `webhook.yaml` from the overlay AND pass
`--enable-webhook=false` to the controller binary. The manager
starts and the reconcilers run; per-driver parameter validation
moves from admission to the reconcile loop and surfaces on
Platforms without cert-manager use
`deploy/kustomize/webhook-certgen/` (or the
`deploy/kustomize/release-tls-selfsigned/` composition):
kube-webhook-certgen Jobs mint the Secret and patch the caBundle,
so the webhook stays enabled with zero cert infrastructure.

`--enable-webhook=false` remains only as a last-resort escape
hatch and is strongly discouraged. The manager starts and the
reconcilers run; per-driver parameter validation moves from
admission to the reconcile loop and surfaces on
`Buckety.status.conditions` instead of failing the apply. CRD
CEL still enforces spec.backend / spec.name / bucketyRef /
credentialsSecretName immutability and the role/retentionPolicy
Expand Down