diff --git a/k8s/magiclove/BUILD.bazel b/k8s/magiclove/BUILD.bazel index 7f5fb3fc2..9552c336a 100644 --- a/k8s/magiclove/BUILD.bazel +++ b/k8s/magiclove/BUILD.bazel @@ -56,6 +56,7 @@ cue_export( "//k8s/magiclove/smartctl_exporter:cue_smartctl_exporter_library", "//k8s/magiclove/snapshot_controller:cue_snapshot_controller_library", "//k8s/magiclove/speedtest_exporter:cue_speedtest_exporter_library", + "//k8s/magiclove/spire:cue_spire_library", "//k8s/magiclove/thomas:cue_thomas_library", "//k8s/magiclove/vector:cue_vector_library", "//k8s/magiclove/victoria_logs:cue_victoria_logs_library", diff --git a/k8s/magiclove/list.cue b/k8s/magiclove/list.cue index 7b3775be0..3033b282e 100644 --- a/k8s/magiclove/list.cue +++ b/k8s/magiclove/list.cue @@ -38,6 +38,7 @@ import ( "github.com/uhthomas/automata/k8s/magiclove/smartctl_exporter" "github.com/uhthomas/automata/k8s/magiclove/snapshot_controller" "github.com/uhthomas/automata/k8s/magiclove/speedtest_exporter" + "github.com/uhthomas/automata/k8s/magiclove/spire" "github.com/uhthomas/automata/k8s/magiclove/thomas" // "github.com/uhthomas/automata/k8s/magiclove/trivy_system" "github.com/uhthomas/automata/k8s/magiclove/vector" @@ -113,6 +114,7 @@ _items: [ smartctl_exporter.#List.items, snapshot_controller.#List.items, speedtest_exporter.#List.items, + spire.#List.items, thomas.#List.items, // trivy_system.#List.items, // vector.#List.items, @@ -124,56 +126,4 @@ _items: [ wireguard_operator.#List.items, ] -// _items: [ -// magiclove.#ApplySetList.items, -// magiclove.#ClusterIssuerList.items, -// magiclove.#ClusterSecretStoreList.items, -// magiclove.#CustomResourceDefinitionList.items, -// magiclove.#GatewayClassList.items, -// backup.#List.items, -// cert_manager_csi_driver.#List.items, -// cert_manager.#List.items, -// cilium.#List.items, -// cilium_secrets.#List.items, -// dcgm_exporter.#List.items, -// default.#List.items, -// emqx.#List.items, -// emqx_exporter.#List.items, -// external_dns.#List.items, -// external_secrets.#List.items, -// // fluent_bit.#List.items, -// frigate.#List.items, -// gateway_api.#List.items, -// grafana.#List.items, -// grafana_operator.#List.items, -// home_assistant.#List.items, -// karma.#List.items, -// kube_state_metrics.#List.items, -// kube_system.#List.items, -// media.#List.items, -// metrics_server.#List.items, -// minecraft.#List.items, -// node_exporter.#List.items, -// // node_feature_discovery.#List.items, -// node_problem_detector.#List.items, -// nvidia_device_plugin.#List.items, -// onepassword_connect.#List.items, -// ping_exporter.#List.items, -// rook_ceph.#List.items, -// scrutiny.#List.items, -// smartctl_exporter.#List.items, -// snapshot_controller.#List.items, -// speedtest_exporter.#List.items, -// tailscale.#List.items, -// thomas.#List.items, -// // trivy_system.#List.items, -// vector.#List.items, -// victoria_logs.#List.items, -// vm_operator.#List.items, -// vm.#List.items, -// volsync_system.#List.items, -// wireguard.#List.items, -// wireguard_operator.#List.items, -// ] - #List diff --git a/k8s/magiclove/spire/BUILD.bazel b/k8s/magiclove/spire/BUILD.bazel new file mode 100644 index 000000000..ece8b7cab --- /dev/null +++ b/k8s/magiclove/spire/BUILD.bazel @@ -0,0 +1,18 @@ +load("@com_github_tnarg_rules_cue//cue:cue.bzl", "cue_library") + +cue_library( + name = "cue_spire_library", + srcs = [ + "config_map_list.cue", + "list.cue", + "namespace_list.cue", + ], + importpath = "github.com/uhthomas/automata/k8s/magiclove/spire", + visibility = ["//visibility:public"], + deps = [ + "//cue.mod/gen/k8s.io/api/core/v1:cue_v1_library", + "//k8s/magiclove/spire/agent:cue_agent_library", + "//k8s/magiclove/spire/client:cue_client_library", + "//k8s/magiclove/spire/server:cue_server_library", + ], +) diff --git a/k8s/magiclove/spire/README.md b/k8s/magiclove/spire/README.md new file mode 100644 index 000000000..10c6f53d4 --- /dev/null +++ b/k8s/magiclove/spire/README.md @@ -0,0 +1,54 @@ +# Spire + +[https://spiffe.io/docs/latest/try/getting-started-k8s/](https://spiffe.io/docs/latest/try/getting-started-k8s/) + +The CSI driver would be nice. + +[https://github.com/spiffe/spiffe-csi](https://github.com/spiffe/spiffe-csi) + +```sh +❯ k exec -it sts/spire-server -- \ + /opt/spire/bin/spire-server entry create \ + -spiffeID spiffe://spire-magiclove.hipparcos.net/ns/spire/sa/spire-agent \ + -selector k8s_sat:cluster:magiclove \ + -selector k8s_sat:agent_ns:spire \ + -selector k8s_sat:agent_sa:spire-agent \ + -node +Entry ID : b313a13a-bf78-4c92-9dd7-e1eee47658f0 +SPIFFE ID : spiffe://spire-magiclove.hipparcos.net/ns/spire/sa/spire-agent +Parent ID : spiffe://spire-magiclove.hipparcos.net/spire/server +Revision : 0 +X509-SVID TTL : default +JWT-SVID TTL : default +Selector : k8s_sat:agent_ns:spire +Selector : k8s_sat:agent_sa:spire-agent +Selector : k8s_sat:cluster:magiclove +``` + +```sh +❯ k exec -it sts/spire-server -- \ + /opt/spire/bin/spire-server entry create \ + -spiffeID spiffe://spire-magiclove.hipparcos.net/ns/default/sa/default \ + -parentID spiffe://spire-magiclove.hipparcos.net/ns/spire/sa/spire-agent \ + -selector k8s:ns:spire \ + -selector k8s:sa:default +Entry ID : 95074358-a44a-4a66-9404-77a8fae994e2 +SPIFFE ID : spiffe://spire-magiclove.hipparcos.net/ns/default/sa/default +Parent ID : spiffe://spire-magiclove.hipparcos.net/ns/spire/sa/spire-agent +Revision : 0 +X509-SVID TTL : default +JWT-SVID TTL : default +Selector : k8s:ns:spire +Selector : k8s:sa:default +``` + +```sh +❯ k exec -it deploy/spire-client -- /opt/spire/bin/spire-agent api fetch -socketPath /run/spire/sockets/agent.sock +Received 1 svid after 87.184133ms + +SPIFFE ID: spiffe://spire-magiclove.hipparcos.net/ns/default/sa/default +SVID Valid After: 2025-01-16 01:31:24 +0000 UTC +SVID Valid Until: 2025-01-16 02:31:34 +0000 UTC +CA #1 Valid After: 2025-01-16 00:02:26 +0000 UTC +CA #1 Valid Until: 2025-01-17 00:02:36 +0000 UTC +``` diff --git a/k8s/magiclove/spire/agent/BUILD.bazel b/k8s/magiclove/spire/agent/BUILD.bazel new file mode 100644 index 000000000..919461a26 --- /dev/null +++ b/k8s/magiclove/spire/agent/BUILD.bazel @@ -0,0 +1,20 @@ +load("@com_github_tnarg_rules_cue//cue:cue.bzl", "cue_library") + +cue_library( + name = "cue_agent_library", + srcs = [ + "cluster_role_binding_list.cue", + "cluster_role_list.cue", + "config_map_list.cue", + "daemon_set_list.cue", + "list.cue", + "service_account_list.cue", + ], + importpath = "github.com/uhthomas/automata/k8s/magiclove/spire/agent", + visibility = ["//visibility:public"], + deps = [ + "//cue.mod/gen/k8s.io/api/apps/v1:cue_v1_library", + "//cue.mod/gen/k8s.io/api/core/v1:cue_v1_library", + "//cue.mod/gen/k8s.io/api/rbac/v1:cue_v1_library", + ], +) diff --git a/k8s/magiclove/spire/agent/cluster_role_binding_list.cue b/k8s/magiclove/spire/agent/cluster_role_binding_list.cue new file mode 100644 index 000000000..476e9dd5b --- /dev/null +++ b/k8s/magiclove/spire/agent/cluster_role_binding_list.cue @@ -0,0 +1,25 @@ +package agent + +import rbacv1 "k8s.io/api/rbac/v1" + +#ClusterRoleBindingList: rbacv1.#ClusterRoleBindingList & { + apiVersion: "rbac.authorization.k8s.io/v1" + kind: "ClusterRoleBindingList" + items: [...{ + apiVersion: "rbac.authorization.k8s.io/v1" + kind: "ClusterRoleBinding" + }] +} + +#ClusterRoleBindingList: items: [{ + subjects: [{ + kind: rbacv1.#ServiceAccountKind + name: #Name + namespace: #Namespace + }] + roleRef: { + apiGroup: rbacv1.#GroupName + kind: "ClusterRole" + name: #Name + } +}] diff --git a/k8s/magiclove/spire/agent/cluster_role_list.cue b/k8s/magiclove/spire/agent/cluster_role_list.cue new file mode 100644 index 000000000..46352a4d8 --- /dev/null +++ b/k8s/magiclove/spire/agent/cluster_role_list.cue @@ -0,0 +1,23 @@ +package agent + +import ( + "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" +) + +#ClusterRoleList: rbacv1.#ClusterRoleList & { + apiVersion: "rbac.authorization.k8s.io/v1" + kind: "ClusterRoleList" + items: [...{ + apiVersion: "rbac.authorization.k8s.io/v1" + kind: "ClusterRole" + }] +} + +#ClusterRoleList: items: [{ + rules: [{ + apiGroups: [v1.#GroupName] + resources: ["pods", "nodes", "nodes/proxy"] + verbs: ["get"] + }] +}] diff --git a/k8s/magiclove/spire/agent/config_map_list.cue b/k8s/magiclove/spire/agent/config_map_list.cue new file mode 100644 index 000000000..e573647c1 --- /dev/null +++ b/k8s/magiclove/spire/agent/config_map_list.cue @@ -0,0 +1,64 @@ +package agent + +import "k8s.io/api/core/v1" + +#ConfigMapList: v1.#ConfigMapList & { + apiVersion: "v1" + kind: "ConfigMapList" + items: [...{ + apiVersion: "v1" + kind: "ConfigMap" + }] +} + +#ConfigMapList: items: [{ + metadata: name: "spire-agent" + data: "agent.conf": """ + agent { + data_dir = "/run/spire" + log_level = "DEBUG" + server_address = "spire-server" + server_port = "8081" + socket_path = "/run/spire/sockets/agent.sock" + trust_bundle_path = "/run/spire/bundle/bundle.crt" + trust_domain = "spire-magiclove.hipparcos.net" + } + + plugins { + NodeAttestor "k8s_sat" { + plugin_data { + cluster = "magiclove" + } + } + + KeyManager "memory" { + plugin_data { + } + } + + WorkloadAttestor "k8s" { + plugin_data { + # Defaults to the secure kubelet port by default. + # Minikube does not have a cert in the cluster CA bundle that + # can authenticate the kubelet cert, so skip validation. + skip_kubelet_verification = true + node_name_env = "MY_NODE_NAME" + } + } + + WorkloadAttestor "unix" { + plugin_data { + } + } + } + + health_checks { + listener_enabled = true + bind_address = "0.0.0.0" + bind_port = "8080" + live_path = "/live" + ready_path = "/ready" + } + + """ +}] diff --git a/k8s/magiclove/spire/agent/daemon_set_list.cue b/k8s/magiclove/spire/agent/daemon_set_list.cue new file mode 100644 index 000000000..79f474484 --- /dev/null +++ b/k8s/magiclove/spire/agent/daemon_set_list.cue @@ -0,0 +1,85 @@ +package agent + +import ( + appsv1 "k8s.io/api/apps/v1" + "k8s.io/api/core/v1" +) + +#DaemonSetList: appsv1.#DaemonSetList & { + apiVersion: "apps/v1" + kind: "DaemonSetList" + items: [...{ + apiVersion: "apps/v1" + kind: "DaemonSet" + }] +} + +#DaemonSetList: items: [{ + spec: { + selector: matchLabels: "app.kubernetes.io/name": #Name + template: { + metadata: + labels: "app.kubernetes.io/name": #Name + spec: { + volumes: [{ + name: "spire-config" + configMap: name: #Name + }, { + name: "spire-bundle" + configMap: name: "spire-bundle" + }, { + name: "spire-agent-socket" + hostPath: { + path: "/run/spire/sockets" + type: v1.#HostPathDirectoryOrCreate + } + }] + containers: [{ + name: "spire-agent" + image: "ghcr.io/spiffe/spire-agent:\(#Version)" + args: ["-config", "/run/spire/config/agent.conf"] + ports: [{ + name: "healthz" + containerPort: 8080 + }] + env: [{ + name: "MY_NODE_NAME" + valueFrom: fieldRef: fieldPath: "status.hostIP" + }] + volumeMounts: [{ + name: "spire-config" + mountPath: "/run/spire/config" + readOnly: true + }, { + name: "spire-bundle" + mountPath: "/run/spire/bundle" + }, { + name: "spire-agent-socket" + mountPath: "/run/spire/sockets" + }] + livenessProbe: { + httpGet: { + path: "/live" + port: "healthz" + } + failureThreshold: 2 + initialDelaySeconds: 15 + periodSeconds: 60 + timeoutSeconds: 3 + } + readinessProbe: { + httpGet: { + path: "/ready" + port: "healthz" + } + initialDelaySeconds: 5 + periodSeconds: 5 + } + securityContext: privileged: true + }] + serviceAccountName: #Name + hostPID: true + } + } + } +}] diff --git a/k8s/magiclove/spire/agent/list.cue b/k8s/magiclove/spire/agent/list.cue new file mode 100644 index 000000000..384b4d820 --- /dev/null +++ b/k8s/magiclove/spire/agent/list.cue @@ -0,0 +1,37 @@ +package agent + +import ( + "list" + + "k8s.io/api/core/v1" +) + +#Name: "spire-agent" +#Namespace: "spire" + +// renovate: datasource=github-releases depName=spiffe/spire extractVersion=^v(?.*)$ +#Version: "1.5.1" + +#List: v1.#List & { + apiVersion: "v1" + kind: "List" + items: [...{ + metadata: { + name: #Name + labels: { + "app.kubernetes.io/name": #Name + "app.kubernetes.io/version": #Version + } + } + }] +} + +#List: items: list.Concat(_items) + +_items: [ + #ClusterRoleBindingList.items, + #ClusterRoleList.items, + #ConfigMapList.items, + #DaemonSetList.items, + #ServiceAccountList.items, +] diff --git a/k8s/magiclove/spire/agent/service_account_list.cue b/k8s/magiclove/spire/agent/service_account_list.cue new file mode 100644 index 000000000..f53feb2b9 --- /dev/null +++ b/k8s/magiclove/spire/agent/service_account_list.cue @@ -0,0 +1,14 @@ +package agent + +import "k8s.io/api/core/v1" + +#ServiceAccountList: v1.#ServiceAccountList & { + apiVersion: "v1" + kind: "ServiceAccountList" + items: [...{ + apiVersion: "v1" + kind: "ServiceAccount" + }] +} + +#ServiceAccountList: items: [{}] diff --git a/k8s/magiclove/spire/client/BUILD.bazel b/k8s/magiclove/spire/client/BUILD.bazel new file mode 100644 index 000000000..ae73a7890 --- /dev/null +++ b/k8s/magiclove/spire/client/BUILD.bazel @@ -0,0 +1,15 @@ +load("@com_github_tnarg_rules_cue//cue:cue.bzl", "cue_library") + +cue_library( + name = "cue_client_library", + srcs = [ + "deployment_list.cue", + "list.cue", + ], + importpath = "github.com/uhthomas/automata/k8s/magiclove/spire/client", + visibility = ["//visibility:public"], + deps = [ + "//cue.mod/gen/k8s.io/api/apps/v1:cue_v1_library", + "//cue.mod/gen/k8s.io/api/core/v1:cue_v1_library", + ], +) diff --git a/k8s/magiclove/spire/client/deployment_list.cue b/k8s/magiclove/spire/client/deployment_list.cue new file mode 100644 index 000000000..4be1c0d7e --- /dev/null +++ b/k8s/magiclove/spire/client/deployment_list.cue @@ -0,0 +1,46 @@ +package client + +import ( + appsv1 "k8s.io/api/apps/v1" + "k8s.io/api/core/v1" +) + +#DeploymentList: appsv1.#DeploymentList & { + apiVersion: "apps/v1" + kind: "DeploymentList" + items: [...{ + apiVersion: "apps/v1" + kind: "Deployment" + }] +} + +#DeploymentList: items: [{ + spec: { + selector: matchLabels: "app.kubernetes.io/name": #Name + template: { + metadata: labels: "app.kubernetes.io/name": #Name + spec: { + volumes: [{ + name: "spire-agent-socket" + hostPath: { + path: "/run/spire/sockets" + type: v1.#HostPathDirectory + } + }] + containers: [{ + name: "spire-client" + image: "ghcr.io/spiffe/spire-agent:\(#Version)" + command: ["/opt/spire/bin/spire-agent"] + args: ["api", "watch", "-socketPath", "/run/spire/sockets/agent.sock"] + volumeMounts: [{ + name: "spire-agent-socket" + mountPath: "/run/spire/sockets" + readOnly: true + }] + imagePullPolicy: v1.#PullIfNotPresent + }] + hostPID: true + } + } + } +}] diff --git a/k8s/magiclove/spire/client/list.cue b/k8s/magiclove/spire/client/list.cue new file mode 100644 index 000000000..abea9d47a --- /dev/null +++ b/k8s/magiclove/spire/client/list.cue @@ -0,0 +1,30 @@ +package client + +import ( + "list" + + "k8s.io/api/core/v1" +) + +#Name: "spire-client" + +// renovate: datasource=github-releases depName=spiffe/spire extractVersion=^v(?.*)$ +#Version: "1.5.1" + +#List: v1.#List & { + apiVersion: "v1" + kind: "List" + items: [...{ + metadata: { + name: #Name + labels: { + "app.kubernetes.io/name": #Name + "app.kubernetes.io/version": #Version + } + } + }] +} + +#List: items: list.Concat(_items) + +_items: [#DeploymentList.items] diff --git a/k8s/magiclove/spire/config_map_list.cue b/k8s/magiclove/spire/config_map_list.cue new file mode 100644 index 000000000..40c519e9b --- /dev/null +++ b/k8s/magiclove/spire/config_map_list.cue @@ -0,0 +1,14 @@ +package spire + +import "k8s.io/api/core/v1" + +#ConfigMapList: v1.#ConfigMapList & { + apiVersion: "v1" + kind: "ConfigMapList" + items: [...{ + apiVersion: "v1" + kind: "ConfigMap" + }] +} + +#ConfigMapList: items: [{metadata: name: "spire-bundle"}] diff --git a/k8s/magiclove/spire/list.cue b/k8s/magiclove/spire/list.cue new file mode 100644 index 000000000..393a9410a --- /dev/null +++ b/k8s/magiclove/spire/list.cue @@ -0,0 +1,41 @@ +package spire + +import ( + "list" + + "github.com/uhthomas/automata/k8s/magiclove/spire/agent" + "github.com/uhthomas/automata/k8s/magiclove/spire/client" + "github.com/uhthomas/automata/k8s/magiclove/spire/server" + "k8s.io/api/core/v1" +) + +#Name: "spire" +#Namespace: #Name + +// renovate: datasource=github-releases depName=spiffe/spire extractVersion=^v(?.*)$ +#Version: "1.5.1" + +#List: v1.#List & { + apiVersion: "v1" + kind: "List" + items: [...{ + metadata: { + name: string | *#Name + namespace: #Namespace + labels: { + "app.kubernetes.io/name": string | *#Name + "app.kubernetes.io/version": string | *#Version + } + } + }] +} + +#List: items: list.Concat(_items) + +_items: [ + #ConfigMapList.items, + #NamespaceList.items, + agent.#List.items, + client.#List.items, + server.#List.items, +] diff --git a/k8s/magiclove/spire/namespace_list.cue b/k8s/magiclove/spire/namespace_list.cue new file mode 100644 index 000000000..e3d51fde3 --- /dev/null +++ b/k8s/magiclove/spire/namespace_list.cue @@ -0,0 +1,14 @@ +package spire + +import "k8s.io/api/core/v1" + +#NamespaceList: v1.#NamespaceList & { + apiVersion: "v1" + kind: "NamespaceList" + items: [...{ + apiVersion: "v1" + kind: "Namespace" + }] +} + +#NamespaceList: items: [{metadata: labels: "pod-security.kubernetes.io/enforce": "privileged"}] diff --git a/k8s/magiclove/spire/server/BUILD.bazel b/k8s/magiclove/spire/server/BUILD.bazel new file mode 100644 index 000000000..d1ef28391 --- /dev/null +++ b/k8s/magiclove/spire/server/BUILD.bazel @@ -0,0 +1,23 @@ +load("@com_github_tnarg_rules_cue//cue:cue.bzl", "cue_library") + +cue_library( + name = "cue_server_library", + srcs = [ + "cluster_role_binding_list.cue", + "cluster_role_list.cue", + "config_map_list.cue", + "list.cue", + "role_binding_list.cue", + "role_list.cue", + "service_account_list.cue", + "service_list.cue", + "stateful_set_list.cue", + ], + importpath = "github.com/uhthomas/automata/k8s/magiclove/spire/server", + visibility = ["//visibility:public"], + deps = [ + "//cue.mod/gen/k8s.io/api/apps/v1:cue_v1_library", + "//cue.mod/gen/k8s.io/api/core/v1:cue_v1_library", + "//cue.mod/gen/k8s.io/api/rbac/v1:cue_v1_library", + ], +) diff --git a/k8s/magiclove/spire/server/cluster_role_binding_list.cue b/k8s/magiclove/spire/server/cluster_role_binding_list.cue new file mode 100644 index 000000000..669a849ce --- /dev/null +++ b/k8s/magiclove/spire/server/cluster_role_binding_list.cue @@ -0,0 +1,25 @@ +package server + +import rbacv1 "k8s.io/api/rbac/v1" + +#ClusterRoleBindingList: rbacv1.#ClusterRoleBindingList & { + apiVersion: "rbac.authorization.k8s.io/v1" + kind: "ClusterRoleBindingList" + items: [...{ + apiVersion: "rbac.authorization.k8s.io/v1" + kind: "ClusterRoleBinding" + }] +} + +#ClusterRoleBindingList: items: [{ + subjects: [{ + kind: rbacv1.#ServiceAccountKind + name: #Name + namespace: #Namespace + }] + roleRef: { + apiGroup: rbacv1.#GroupName + kind: "ClusterRole" + name: #Name + } +}] diff --git a/k8s/magiclove/spire/server/cluster_role_list.cue b/k8s/magiclove/spire/server/cluster_role_list.cue new file mode 100644 index 000000000..56825349a --- /dev/null +++ b/k8s/magiclove/spire/server/cluster_role_list.cue @@ -0,0 +1,20 @@ +package server + +import rbacv1 "k8s.io/api/rbac/v1" + +#ClusterRoleList: rbacv1.#ClusterRoleList & { + apiVersion: "rbac.authorization.k8s.io/v1" + kind: "ClusterRoleList" + items: [...{ + apiVersion: "rbac.authorization.k8s.io/v1" + kind: "ClusterRole" + }] +} + +#ClusterRoleList: items: [{ + rules: [{ + apiGroups: ["authentication.k8s.io"] + resources: ["tokenreviews"] + verbs: ["create"] + }] +}] diff --git a/k8s/magiclove/spire/server/config_map_list.cue b/k8s/magiclove/spire/server/config_map_list.cue new file mode 100644 index 000000000..7467efade --- /dev/null +++ b/k8s/magiclove/spire/server/config_map_list.cue @@ -0,0 +1,74 @@ +package server + +import "k8s.io/api/core/v1" + +#ConfigMapList: v1.#ConfigMapList & { + apiVersion: "v1" + kind: "ConfigMapList" + items: [...{ + apiVersion: "v1" + kind: "ConfigMap" + }] +} + +#ConfigMapList: items: [{ + data: "server.conf": """ + server { + bind_address = "0.0.0.0" + bind_port = "8081" + socket_path = "/tmp/spire-server/private/api.sock" + trust_domain = "spire-magiclove.hipparcos.net" + data_dir = "/run/spire/data" + log_level = "DEBUG" + #AWS requires the use of RSA. EC cryptography is not supported + ca_key_type = "rsa-2048" + + ca_subject = { + country = ["US"], + organization = ["SPIFFE"], + common_name = "", + } + } + + plugins { + DataStore "sql" { + plugin_data { + database_type = "sqlite3" + connection_string = "/run/spire/data/datastore.sqlite3" + } + } + + NodeAttestor "k8s_sat" { + plugin_data { + clusters = { + # NOTE: Change this to your cluster name + "magiclove" = { + use_token_review_api_validation = true + service_account_allow_list = ["spire:spire-agent"] + } + } + } + } + + KeyManager "disk" { + plugin_data { + keys_path = "/run/spire/data/keys.json" + } + } + + Notifier "k8sbundle" { + plugin_data { + } + } + } + + health_checks { + listener_enabled = true + bind_address = "0.0.0.0" + bind_port = "8080" + live_path = "/live" + ready_path = "/ready" + } + + """ +}] diff --git a/k8s/magiclove/spire/server/list.cue b/k8s/magiclove/spire/server/list.cue new file mode 100644 index 000000000..83569a8b0 --- /dev/null +++ b/k8s/magiclove/spire/server/list.cue @@ -0,0 +1,40 @@ +package server + +import ( + "list" + + "k8s.io/api/core/v1" +) + +#Name: "spire-server" +#Namespace: "spire" + +// renovate: datasource=github-releases depName=spiffe/spire extractVersion=^v(?.*)$ +#Version: "1.5.1" + +#List: v1.#List & { + apiVersion: "v1" + kind: "List" + items: [...{ + metadata: { + name: #Name + labels: { + "app.kubernetes.io/name": #Name + "app.kubernetes.io/version": #Version + } + } + }] +} + +#List: items: list.Concat(_items) + +_items: [ + #ClusterRoleBindingList.items, + #ClusterRoleList.items, + #ConfigMapList.items, + #RoleBindingList.items, + #RoleList.items, + #ServiceAccountList.items, + #ServiceList.items, + #StatefulSetList.items, +] diff --git a/k8s/magiclove/spire/server/role_binding_list.cue b/k8s/magiclove/spire/server/role_binding_list.cue new file mode 100644 index 000000000..566986e65 --- /dev/null +++ b/k8s/magiclove/spire/server/role_binding_list.cue @@ -0,0 +1,25 @@ +package server + +import rbacv1 "k8s.io/api/rbac/v1" + +#RoleBindingList: rbacv1.#RoleBindingList & { + apiVersion: "rbac.authorization.k8s.io/v1" + kind: "RoleBindingList" + items: [...{ + apiVersion: "rbac.authorization.k8s.io/v1" + kind: "RoleBinding" + }] +} + +#RoleBindingList: items: [{ + subjects: [{ + kind: rbacv1.#ServiceAccountKind + name: #Name + namespace: #Namespace + }] + roleRef: { + apiGroup: rbacv1.#GroupName + kind: "Role" + name: #Name + } +}] diff --git a/k8s/magiclove/spire/server/role_list.cue b/k8s/magiclove/spire/server/role_list.cue new file mode 100644 index 000000000..82a2d7011 --- /dev/null +++ b/k8s/magiclove/spire/server/role_list.cue @@ -0,0 +1,20 @@ +package server + +import rbacv1 "k8s.io/api/rbac/v1" + +#RoleList: rbacv1.#RoleList & { + apiVersion: "rbac.authorization.k8s.io/v1" + kind: "RoleList" + items: [...{ + apiVersion: "rbac.authorization.k8s.io/v1" + kind: "Role" + }] +} + +#RoleList: items: [{ + rules: [{ + apiGroups: [""] + resources: ["configmaps"] + verbs: ["patch", "get", "list"] + }] +}] diff --git a/k8s/magiclove/spire/server/service_account_list.cue b/k8s/magiclove/spire/server/service_account_list.cue new file mode 100644 index 000000000..ac7ed7789 --- /dev/null +++ b/k8s/magiclove/spire/server/service_account_list.cue @@ -0,0 +1,14 @@ +package server + +import "k8s.io/api/core/v1" + +#ServiceAccountList: v1.#ServiceAccountList & { + apiVersion: "v1" + kind: "ServiceAccountList" + items: [...{ + apiVersion: "v1" + kind: "ServiceAccount" + }] +} + +#ServiceAccountList: items: [{metadata: name: "spire-server"}] diff --git a/k8s/magiclove/spire/server/service_list.cue b/k8s/magiclove/spire/server/service_list.cue new file mode 100644 index 000000000..8393a5aec --- /dev/null +++ b/k8s/magiclove/spire/server/service_list.cue @@ -0,0 +1,23 @@ +package server + +import "k8s.io/api/core/v1" + +#ServiceList: v1.#ServiceList & { + apiVersion: "v1" + kind: "ServiceList" + items: [...{ + apiVersion: "v1" + kind: "Service" + }] +} + +#ServiceList: items: [{ + spec: { + ports: [{ + name: "grpc" + port: 8081 + targetPort: "grpc" + }] + selector: "app.kubernetes.io/name": #Name + } +}] diff --git a/k8s/magiclove/spire/server/stateful_set_list.cue b/k8s/magiclove/spire/server/stateful_set_list.cue new file mode 100644 index 000000000..6d2e87fed --- /dev/null +++ b/k8s/magiclove/spire/server/stateful_set_list.cue @@ -0,0 +1,85 @@ +package server + +import ( + appsv1 "k8s.io/api/apps/v1" + "k8s.io/api/core/v1" +) + +#StatefulSetList: appsv1.#StatefulSetList & { + apiVersion: "apps/v1" + kind: "StatefulSetList" + items: [...{ + apiVersion: "apps/v1" + kind: "StatefulSet" + }] +} + +#StatefulSetList: items: [{ + spec: { + selector: matchLabels: "app.kubernetes.io/name": #Name + template: { + metadata: { + namespace: "spire" + labels: "app.kubernetes.io/name": #Name + } + spec: { + volumes: [{ + name: "spire-config" + configMap: name: #Name + }] + containers: [{ + name: "spire-server" + image: "ghcr.io/spiffe/spire-server:1.5.1" + args: [ + "-config", + "/run/spire/config/server.conf", + ] + ports: [{ + name: "healthz" + containerPort: 8080 + }, { + name: "grpc" + containerPort: 8081 + }] + volumeMounts: [{ + name: "spire-config" + mountPath: "/run/spire/config" + readOnly: true + }, { + name: "data" + mountPath: "/run/spire/data" + }] + livenessProbe: { + httpGet: { + path: "/live" + port: "healthz" + } + failureThreshold: 2 + initialDelaySeconds: 15 + periodSeconds: 60 + timeoutSeconds: 3 + } + readinessProbe: { + httpGet: { + path: "/ready" + port: "healthz" + } + initialDelaySeconds: 5 + periodSeconds: 5 + } + imagePullPolicy: v1.#PullIfNotPresent + }] + serviceAccountName: #Name + } + } + volumeClaimTemplates: [{ + metadata: name: "data" + spec: { + accessModes: [v1.#ReadWriteOnce] + storageClassName: "rook-ceph-nvme" + resources: requests: (v1.#ResourceStorage): "64Mi" + } + }] + serviceName: #Name + } +}]