Serge Bazanski | 3c5d836 | 2021-02-06 17:27:02 +0000 | [diff] [blame^] | 1 | // Deploys admitomatic, a validating admission webhook. It is used in |
| 2 | // conjunction with Kubernetes' RBAC to provide a level of multitenancy to the |
| 3 | // cluster, adding extra restrictions to resources created by non-administrative |
| 4 | // users. |
| 5 | // |
| 6 | // For more information about admitomatic , see //cluster/admitomatic . |
| 7 | // |
| 8 | // As with every Kubernetes admission webhook, the Kubernetes control plane |
| 9 | // (ie. apiserver) needs to be able to dial the deployed admitomatic service. |
| 10 | // The authentication story for this is unfortunately quite sad and requires |
| 11 | // the use of a pre-generated one-shot CA and certificate. |
| 12 | // |
| 13 | // .---- self-signed -. |
| 14 | // v | |
| 15 | // Admitomatic CA ----------' <-- caBundle used by apiserver, |
| 16 | // | set in ValidatingWebhookConfiguration |
| 17 | // v |
| 18 | // Admitomatic Cert <-- admitomatic_tls_cert used by admitomatic |
| 19 | // |
| 20 | // This CA needs to be provisioned ahead of time by ourselves. In order to keep |
| 21 | // things simple (as admitomatic being an admission webhook becomes a core |
| 22 | // component of the k8s control plane), we generate this CA as plain text |
| 23 | // secrets, and store them with secretstore in git. This is done via clustercfg. |
| 24 | |
| 25 | local kube = import "../../../kube/kube.libsonnet"; |
| 26 | local prototext = import "../../../kube/prototext.libsonnet"; |
| 27 | |
| 28 | { |
| 29 | Environment: { |
| 30 | local env = self, |
| 31 | local cfg = env.cfg, |
| 32 | |
| 33 | cfg:: { |
| 34 | namespace: "admitomatic", |
| 35 | image: "registry.k0.hswaw.net/q3k/admitomatic:1612618063-0b68e233116f733fb3ec9016c9d3b7decb86f192", |
| 36 | |
| 37 | proto: {}, |
| 38 | }, |
| 39 | |
| 40 | namespace: kube.Namespace(cfg.namespace), |
| 41 | local ns = self.namespace, |
| 42 | |
| 43 | config: ns.Contain(kube.ConfigMap("admitomatic")) { |
| 44 | data: { |
| 45 | "config.pb.text": prototext.manifestProtoText(cfg.proto), |
| 46 | }, |
| 47 | }, |
| 48 | |
| 49 | secret: ns.Contain(kube.Secret("admitomatic")) { |
| 50 | data_: { |
| 51 | "webhook.key": importstr "../../secrets/plain/admitomatic-webhook.key", |
| 52 | "webhook.crt": importstr "../../certs/admitomatic-webhook.cert", |
| 53 | }, |
| 54 | }, |
| 55 | |
| 56 | daemonset: ns.Contain(kube.DaemonSet("admitomatic")) { |
| 57 | spec+: { |
| 58 | template+: { |
| 59 | spec+: { |
| 60 | containers_: { |
| 61 | default: kube.Container("default") { |
| 62 | image: cfg.image, |
| 63 | args: [ |
| 64 | "/cluster/admitomatic/admitomatic", |
| 65 | "-admitomatic_config", "/admitomatic/config/config.pb.text", |
| 66 | "-admitomatic_listen", "0.0.0.0:8443", |
| 67 | "-admitomatic_tls_cert", "/admitomatic/secret/webhook.crt", |
| 68 | "-admitomatic_tls_key", "/admitomatic/secret/webhook.key", |
| 69 | // doesn't serve anything over gRPC. |
| 70 | "-hspki_disable" |
| 71 | ], |
| 72 | volumeMounts_: { |
| 73 | config: { mountPath: "/admitomatic/config" }, |
| 74 | secret: { mountPath: "/admitomatic/secret" }, |
| 75 | }, |
| 76 | ports_: { |
| 77 | public: { containerPort: 8443 }, |
| 78 | }, |
| 79 | }, |
| 80 | }, |
| 81 | volumes_: { |
| 82 | config: kube.ConfigMapVolume(env.config), |
| 83 | secret: kube.SecretVolume(env.secret), |
| 84 | }, |
| 85 | }, |
| 86 | }, |
| 87 | }, |
| 88 | }, |
| 89 | |
| 90 | svc: ns.Contain(kube.Service("admitomatic")) { |
| 91 | target_pod:: env.daemonset.spec.template, |
| 92 | }, |
| 93 | }, |
| 94 | } |