blob: d4a27667214711a77f3fbf7be2225338fe61f2c2 [file] [log] [blame]
Serge Bazanski3c5d8362021-02-06 17:27:02 +00001// 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
25local kube = import "../../../kube/kube.libsonnet";
26local prototext = import "../../../kube/prototext.libsonnet";
27
28{
29 Environment: {
30 local env = self,
31 local cfg = env.cfg,
32
33 cfg:: {
34 namespace: "admitomatic",
Serge Bazanskic1f37252023-06-19 21:56:29 +000035 image: "registry.k0.hswaw.net/cluster/admitomatic:315532800-418f1b77968ac843af2e48cd414c2f8eb19653ba",
Serge Bazanski3c5d8362021-02-06 17:27:02 +000036
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 },
Serge Bazanski41bbf142021-02-06 18:12:52 +000093
94 webhook: kube.ValidatingWebhookConfiguration("admitomatic") {
95 webhooks_: {
96 "admitomatic.hswaw.net": {
97 rules: [
98 {
99 apiGroups: ["networking.k8s.io"],
100 apiVersions: ["v1", "v1beta1"],
101 operations: ["CREATE", "UPDATE"],
102 resources: ["ingresses"],
103 scope: "Namespaced",
104 }
105 ],
106 clientConfig: {
107 service: {
108 namespace: env.svc.metadata.namespace,
109 name: env.svc.metadata.name,
110 port: 8443,
111 path: "/webhook",
112 },
113 caBundle: std.base64(importstr "../../certs/ca-admitomatic.crt"),
114 },
115 failurePolicy: "Ignore",
116 matchPolicy: "Equivalent",
117 admissionReviewVersions: ["v1", "v1beta1"],
118 sideEffects: "None",
119 timeoutSeconds: 5,
120 },
121 },
122 },
Serge Bazanski3c5d8362021-02-06 17:27:02 +0000123 },
124}