| // Deploys admitomatic, a validating admission webhook. It is used in |
| // conjunction with Kubernetes' RBAC to provide a level of multitenancy to the |
| // cluster, adding extra restrictions to resources created by non-administrative |
| // users. |
| // |
| // For more information about admitomatic , see //cluster/admitomatic . |
| // |
| // As with every Kubernetes admission webhook, the Kubernetes control plane |
| // (ie. apiserver) needs to be able to dial the deployed admitomatic service. |
| // The authentication story for this is unfortunately quite sad and requires |
| // the use of a pre-generated one-shot CA and certificate. |
| // |
| // .---- self-signed -. |
| // v | |
| // Admitomatic CA ----------' <-- caBundle used by apiserver, |
| // | set in ValidatingWebhookConfiguration |
| // v |
| // Admitomatic Cert <-- admitomatic_tls_cert used by admitomatic |
| // |
| // This CA needs to be provisioned ahead of time by ourselves. In order to keep |
| // things simple (as admitomatic being an admission webhook becomes a core |
| // component of the k8s control plane), we generate this CA as plain text |
| // secrets, and store them with secretstore in git. This is done via clustercfg. |
| |
| local kube = import "../../../kube/kube.libsonnet"; |
| local prototext = import "../../../kube/prototext.libsonnet"; |
| |
| { |
| Environment: { |
| local env = self, |
| local cfg = env.cfg, |
| |
| cfg:: { |
| namespace: "admitomatic", |
| image: "registry.k0.hswaw.net/cluster/admitomatic@sha256:f7f0c007b2e12ca564282dd55c9334947854d58ebb5b305cf6e9e0060382d81d", |
| |
| proto: {}, |
| }, |
| |
| namespace: kube.Namespace(cfg.namespace), |
| local ns = self.namespace, |
| |
| config: ns.Contain(kube.ConfigMap("admitomatic")) { |
| data: { |
| "config.pb.text": prototext.manifestProtoText(cfg.proto), |
| }, |
| }, |
| |
| secret: ns.Contain(kube.Secret("admitomatic")) { |
| data_: { |
| "webhook.key": importstr "../../secrets/plain/admitomatic-webhook.key", |
| "webhook.crt": importstr "../../certs/admitomatic-webhook.cert", |
| }, |
| }, |
| |
| daemonset: ns.Contain(kube.DaemonSet("admitomatic")) { |
| spec+: { |
| template+: { |
| spec+: { |
| containers_: { |
| default: kube.Container("default") { |
| image: cfg.image, |
| args: [ |
| "/cluster/admitomatic/admitomatic", |
| "-admitomatic_config", "/admitomatic/config/config.pb.text", |
| "-admitomatic_listen", "0.0.0.0:8443", |
| "-admitomatic_tls_cert", "/admitomatic/secret/webhook.crt", |
| "-admitomatic_tls_key", "/admitomatic/secret/webhook.key", |
| // doesn't serve anything over gRPC. |
| "-hspki_disable" |
| ], |
| volumeMounts_: { |
| config: { mountPath: "/admitomatic/config" }, |
| secret: { mountPath: "/admitomatic/secret" }, |
| }, |
| ports_: { |
| public: { containerPort: 8443 }, |
| }, |
| }, |
| }, |
| volumes_: { |
| config: kube.ConfigMapVolume(env.config), |
| secret: kube.SecretVolume(env.secret), |
| }, |
| }, |
| }, |
| }, |
| }, |
| |
| svc: ns.Contain(kube.Service("admitomatic")) { |
| target:: env.daemonset, |
| }, |
| |
| webhook: kube.ValidatingWebhookConfiguration("admitomatic") { |
| webhooks_: { |
| "admitomatic.hswaw.net": { |
| rules: [ |
| { |
| apiGroups: ["networking.k8s.io"], |
| apiVersions: ["v1", "v1beta1"], |
| operations: ["CREATE", "UPDATE"], |
| resources: ["ingresses"], |
| scope: "Namespaced", |
| } |
| ], |
| clientConfig: { |
| service: { |
| namespace: env.svc.metadata.namespace, |
| name: env.svc.metadata.name, |
| port: 8443, |
| path: "/webhook", |
| }, |
| caBundle: std.base64(importstr "../../certs/ca-admitomatic.crt"), |
| }, |
| failurePolicy: "Ignore", |
| matchPolicy: "Equivalent", |
| admissionReviewVersions: ["v1", "v1beta1"], |
| sideEffects: "None", |
| timeoutSeconds: 5, |
| }, |
| }, |
| }, |
| }, |
| } |