From acd4ef81a06dfbc999a524f57dac5cfbd2a31e5e Mon Sep 17 00:00:00 2001 From: Jacob Weinstock Date: Fri, 25 Oct 2024 08:22:05 -0600 Subject: [PATCH 1/2] Simplify the JSON schema files: Only add validations for RBAC and trusted proxies. Signed-off-by: Jacob Weinstock --- tinkerbell/hegel/values.schema.json | 81 +-------- tinkerbell/rufio/values.schema.json | 69 -------- tinkerbell/smee/values.schema.json | 264 +--------------------------- tinkerbell/stack/values.schema.json | 209 +--------------------- tinkerbell/tink/values.schema.json | 141 --------------- 5 files changed, 15 insertions(+), 749 deletions(-) diff --git a/tinkerbell/hegel/values.schema.json b/tinkerbell/hegel/values.schema.json index 7369b429..dc290ef8 100644 --- a/tinkerbell/hegel/values.schema.json +++ b/tinkerbell/hegel/values.schema.json @@ -2,67 +2,6 @@ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { - "deploy": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "image": { - "type": "string" - }, - "imagePullPolicy": { - "type": "string" - }, - "replicas": { - "type": "integer" - }, - "service": { - "type": "object", - "properties": { - "port": { - "type": "integer" - } - } - }, - "deployment": { - "type": "object", - "properties": { - "port": { - "type": "integer" - }, - "portName": { - "type": "string" - } - } - }, - "resources": { - "type": "object", - "properties": { - "limits": { - "type": "object", - "properties": { - "cpu": { - "type": "string" - }, - "memory": { - "type": "string" - } - } - }, - "requests": { - "type": "object", - "properties": { - "cpu": { - "type": "string" - }, - "memory": { - "type": "string" - } - } - } - } - }, "rbac": { "type": "object", "properties": { @@ -78,23 +17,13 @@ } } }, - "nodeSelector": { - "type": "object" - }, "trustedProxies": { "type": "array", - "items": {} - }, - "singleNodeClusterConfig": { - "type": "object", - "properties": { - "controlPlaneTolerationsEnabled": { - "type": "boolean" - }, - "nodeAffinityWeight": { - "type": "integer" - } - } + "items": { + "type": "string", + "description": "Specifies one or more IPv4 addresses expressed using CIDR notation.", + "pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$" + } } } } diff --git a/tinkerbell/rufio/values.schema.json b/tinkerbell/rufio/values.schema.json index 57cdb74f..995856cf 100644 --- a/tinkerbell/rufio/values.schema.json +++ b/tinkerbell/rufio/values.schema.json @@ -2,75 +2,6 @@ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { - "deploy": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "image": { - "type": "string" - }, - "imagePullPolicy": { - "type": "string" - }, - "resources": { - "type": "object", - "properties": { - "requests": { - "type": "object", - "properties": { - "cpu": { - "type": "string" - }, - "memory": { - "type": "string" - } - } - }, - "limits": { - "type": "object", - "properties": { - "cpu": { - "type": "string" - }, - "memory": { - "type": "string" - } - } - } - } - }, - "additionalArgs": { - "type": "array", - "items": {} - }, - "serviceAccountName": { - "type": "string" - }, - "rufioLeaderElectionRoleName": { - "type": "string" - }, - "rufioLeaderElectionRoleBindingName": { - "type": "string" - }, - "nodeSelector": { - "type": "object" - }, - "hostNetwork": { - "type": "boolean" - }, - "singleNodeClusterConfig": { - "type": "object", - "properties": { - "controlPlaneTolerationsEnabled": { - "type": "boolean" - }, - "nodeAffinityWeight": { - "type": "integer" - } - } - }, "rbac": { "type": "object", "properties": { diff --git a/tinkerbell/smee/values.schema.json b/tinkerbell/smee/values.schema.json index 9aa663d8..75ae1d97 100644 --- a/tinkerbell/smee/values.schema.json +++ b/tinkerbell/smee/values.schema.json @@ -2,273 +2,19 @@ "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { - "deploy": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "image": { - "type": "string" - }, - "imagePullPolicy": { - "type": "string" - }, - "replicas": { - "type": "integer" - }, - "resources": { - "type": "object", - "properties": { - "limits": { - "type": "object", - "properties": { - "cpu": { - "type": "string" - }, - "memory": { - "type": "string" - } - } - }, - "requests": { - "type": "object", - "properties": { - "cpu": { - "type": "string" - }, - "memory": { - "type": "string" - } - } - } - } - }, - "deployment": { - "type": "object", - "properties": { - "strategy": { - "type": "object", - "properties": { - "type": { - "type": "string" - } - } - } - } - }, - "logLevel": { - "type": "string" - }, - "hostNetwork": { - "type": "boolean" - }, - "nodeSelector": { - "type": "object" - }, - "publicIP": { - "type": "string" - }, - "dhcp": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "mode": { - "type": "string" - }, - "ip": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "ipForPacket": { - "type": "string" - }, - "tftpIp": { - "type": "string" - }, - "tftpPort": { - "type": "integer" - }, - "syslogIp": { - "type": "string" - }, - "httpIPXE": { - "type": "object", - "properties": { - "binaryUrl": { - "type": "object", - "properties": { - "scheme": { - "type": "string" - }, - "host": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "path": { - "type": "string" - } - } - }, - "scriptUrl": { - "type": "object", - "properties": { - "scheme": { - "type": "string" - }, - "host": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "path": { - "type": "string" - } - } - } - } - } - } - }, - "tftp": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "ip": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "timeout": { - "type": "string" - } - } - }, "http": { "type": "object", "properties": { - "enabled": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "ip": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "tinkServer": { - "type": "object", - "properties": { - "ip": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "tls": { - "type": "boolean" - } - } - }, - "osieUrl": { - "type": "object", - "properties": { - "scheme": { - "type": "string" - }, - "host": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "path": { - "type": "string" - } - } - }, - "additionalKernelArgs": { - "type": "array", - "items": {} - }, - "ipxeBinaryEnabled": { - "type": "boolean" - }, - "ipxeScriptEnabled": { - "type": "boolean" - }, "trustedProxies": { "type": "array", - "items": {} - } - } - }, - "syslog": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "ip": { - "type": "string" - }, - "port": { - "type": "integer" - } - } - }, - "tinkWorkerImage": { - "type": "string" - }, - "additionalArgs": { - "type": "array", - "items": {} - }, - "additionalEnv": { - "type": "array", - "items": {} - }, - "singleNodeClusterConfig": { - "type": "object", - "properties": { - "controlPlaneTolerationsEnabled": { - "type": "boolean" - }, - "nodeAffinityWeight": { - "type": "integer" + "items": { + "type": "string", + "description": "Specifies one or more IPv4 addresses expressed using CIDR notation.", + "pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$" + } } } }, - "additionalVolumes": { - "type": "array", - "items": {} - }, - "additionalVolumeMounts": { - "type": "array", - "items": {} - }, "rbac": { "type": "object", "properties": { diff --git a/tinkerbell/stack/values.schema.json b/tinkerbell/stack/values.schema.json index 1b8afc07..739fd365 100644 --- a/tinkerbell/stack/values.schema.json +++ b/tinkerbell/stack/values.schema.json @@ -1,155 +1,7 @@ { - "$schema": "http://json-schema.org/draft-04/schema#", + "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { - "stack": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "service": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "type": { - "type": "string" - } - } - }, - "selector": { - "type": "object", - "properties": { - "app": { - "type": "string" - } - } - }, - "nodeSelector": { - "type": "object" - }, - "deployment": { - "type": "object", - "properties": { - "strategy": { - "type": "object", - "properties": { - "type": { - "type": "string" - } - } - } - } - }, - "clusterDomain": { - "type": "string" - }, - "loadBalancerIP": { - "type": "string" - }, - "lbClass": { - "type": "string" - }, - "image": { - "type": "string" - }, - "hook": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "port": { - "type": "integer" - }, - "image": { - "type": "string" - }, - "downloadsDest": { - "type": "string" - }, - "downloadURL": { - "type": "string" - } - } - }, - "kubevip": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "image": { - "type": "string" - }, - "imagePullPolicy": { - "type": "string" - }, - "roleName": { - "type": "string" - }, - "roleBindingName": { - "type": "string" - }, - "additionalEnv": { - "type": "array", - "items": {} - } - } - }, - "relay": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "enabled": { - "type": "boolean" - }, - "image": { - "type": "string" - }, - "initImage": { - "type": "string" - }, - "maxHopCount": { - "type": "integer" - }, - "presentGiaddrAction": { - "type": "string" - }, - "listenBroadcastTraffic": { - "type": "boolean" - }, - "interfaceMode": { - "type": "string" - } - } - }, - "singleNodeClusterConfig": { - "type": "object", - "properties": { - "controlPlaneTolerationsEnabled": { - "type": "boolean" - }, - "nodeAffinityWeight": { - "type": "integer" - } - } - } - } - }, "global": { "type": "object", "properties": { @@ -164,64 +16,13 @@ "enum": ["Role", "ClusterRole"] } } - } - } - }, - "smee": { - "type": "object", - "properties": { - "image": { - "type": "string" - }, - "tinkWorkerImage": { - "type": "string" }, "trustedProxies": { "type": "array", - "items": {} - }, - "publicIP": { - "type": "string" - } - } - }, - "hegel": { - "type": "object", - "properties": { - "image": { - "type": "string" - }, - "trustedProxies": { - "type": "array", - "items": {} - } - } - }, - "rufio": { - "type": "object", - "properties": { - "image": { - "type": "string" - } - } - }, - "tink": { - "type": "object", - "properties": { - "controller": { - "type": "object", - "properties": { - "image": { - "type": "string" - } - } - }, - "server": { - "type": "object", - "properties": { - "image": { - "type": "string" - } + "items": { + "type": "string", + "description": "Specifies one or more IPv4 addresses expressed using CIDR notation.", + "pattern": "^([0-9]{1,3}\\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$" } } } diff --git a/tinkerbell/tink/values.schema.json b/tinkerbell/tink/values.schema.json index 2f2f0756..a9323b36 100644 --- a/tinkerbell/tink/values.schema.json +++ b/tinkerbell/tink/values.schema.json @@ -6,72 +6,6 @@ "controller": { "type": "object", "properties": { - "deploy": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "image": { - "type": "string" - }, - "imagePullPolicy": { - "type": "string" - }, - "replicas": { - "type": "integer" - }, - "args": { - "type": "array", - "items": {} - }, - "resources": { - "type": "object", - "properties": { - "limits": { - "type": "object", - "properties": { - "cpu": { - "type": "string" - }, - "memory": { - "type": "string" - } - } - }, - "requests": { - "type": "object", - "properties": { - "cpu": { - "type": "string" - }, - "memory": { - "type": "string" - } - } - } - } - }, - "tinkLeaderElectionRoleName": { - "type": "string" - }, - "tinkLeaderElectionRoleBindingName": { - "type": "string" - }, - "nodeSelector": { - "type": "object" - }, - "singleNodeClusterConfig": { - "type": "object", - "properties": { - "controlPlaneTolerationsEnabled": { - "type": "boolean" - }, - "weight": { - "type": "integer" - } - } - }, "rbac": { "type": "object", "properties": { @@ -92,81 +26,6 @@ "server": { "type": "object", "properties": { - "deploy": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "image": { - "type": "string" - }, - "imagePullPolicy": { - "type": "string" - }, - "replicas": { - "type": "integer" - }, - "service": { - "type": "object", - "properties": { - "port": { - "type": "integer" - } - } - }, - "deployment": { - "type": "object", - "properties": { - "port": { - "type": "integer" - }, - "portName": { - "type": "string" - } - } - }, - "resources": { - "type": "object", - "properties": { - "limits": { - "type": "object", - "properties": { - "cpu": { - "type": "string" - }, - "memory": { - "type": "string" - } - } - }, - "requests": { - "type": "object", - "properties": { - "cpu": { - "type": "string" - }, - "memory": { - "type": "string" - } - } - } - } - }, - "nodeSelector": { - "type": "object" - }, - "singleNodeClusterConfig": { - "type": "object", - "properties": { - "controlPlaneTolerationsEnabled": { - "type": "boolean" - }, - "nodeAffinityWeight": { - "type": "integer" - } - } - }, "rbac": { "type": "object", "properties": { From 1ace57a32bc424bb5675a9370a2bbdd35f283d04 Mon Sep 17 00:00:00 2001 From: Jacob Weinstock Date: Fri, 25 Oct 2024 08:22:45 -0600 Subject: [PATCH 2/2] Update readme: Add details on rbac, json schema, and persistence. Signed-off-by: Jacob Weinstock --- tinkerbell/stack/README.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tinkerbell/stack/README.md b/tinkerbell/stack/README.md index 75947770..ac9e815f 100644 --- a/tinkerbell/stack/README.md +++ b/tinkerbell/stack/README.md @@ -23,11 +23,11 @@ This chart boootraps a full Tinkerbell stack on a Kubernetes cluster using the H - Reverse proxy server - DHCP relay agent -This chart also installs a load balancer ([kube-vip](https://kube-vip.io/)) in order to be able to provide a service type loadBalancer IP for the Tinkerbell stack services and an Nginx server for handling proxying to the Tinkerbell service and for serving the Hook artifacts. +This chart also installs a load balancer ([kube-vip](https://kube-vip.io/)) in order to be able to provide a service type loadBalancer IP for the Nginx server that handles proxying to all the Tinkerbell services and for serving the Hook artifacts. This kube-vip load balancer is the default but can be disabled if another load balancer is preferred. ## Design details -The stack chart does not use an ingress object and controller. This is because most ingress controllers do not support UDP. Smee uses UDP for DHCP, TFTP, and Syslog services. The ingress controllers that do support UDP require a lot of extra configuration, custom resources, etc. The stack chart deploys a very light weight Nginx deployment with a straightforward configuration that accommodates all the Tinkerbell stack services and serving Hook artifacts. +The stack chart does not use an ingress object and controller. This is because most ingress controllers do not support multi-protocol (UDP, TCP, and gRPC in the Tinkerbell case). Smee uses UDP for DHCP, TFTP, and Syslog services. The ingress controllers that do support UDP require a lot of extra configuration, custom resources, etc. The Tinkerbell stack (Hegel and Smee) also needs the source IP or X-ForwardFor enabled to provide the appropriate data to clients. This is not generally available in an ingress controller. As such, the stack chart deploys a very light weight Nginx deployment with a straightforward configuration that accommodates all the Tinkerbell stack services and serving Hook artifacts. As [Gateway API](https://gateway-api.sigs.k8s.io/) (and the implementations of it) matures there is hope that it will be possible to use it to deploy the Tinkerbell stack instead. ## Prerequisites @@ -37,7 +37,7 @@ The stack chart does not use an ingress object and controller. This is because m ## Installing the Chart -Before installing the chart you'll want to customize the IP used for the load balancer (`global.publicIP`). This IP provides ingress for Hegel, Tink, and Smee (TFTP, HTTP, and SYSLOG endpoints as well as unicast DHCP requests). +Before installing the chart you'll want to customize the IP used for the load balancer (`global.publicIP`). This IP provides ingress for Hegel, Tink, and Smee (TFTP, HTTP, and SYSLOG endpoints as well as unicast DHCP requests). You'll also need to provide the trusted proxies for the Tinkerbell services. The trusted proxies are the IP addresses of the nodes in the cluster. The trusted proxies are used to set the `X-Forwarded-For` header in the Nginx configuration. This is necessary for the Tinkerbell services to get the correct client IP address. The `kubectl.go-template` file is provided to get the IP addresses of the nodes in the cluster. `kubectl get nodes -o go-template-file=stack/kubectl.go-template` Now, deploy the chart. @@ -130,3 +130,15 @@ hegel: | Name | Description | Value | | ---- | ----------- | ----- | | `smee.hostNetwork` | Whether to deploy Smee using `hostNetwork` on the pod spec. When `true` Smee will be able to receive DHCP broadcast messages. If `false`, Smee will be behind the load balancer VIP and will need to receive DHCP requests via unicast. | `true` | + +### JSON Schema + +Helm has the ability to validate a `values.yaml` file via a JSON schema (`values.schema.json`). See the [Helm documentation](https://helm.sh/docs/topics/charts/#schema-files) for more details. Each chart in the Tinkerbell stack has a very basic schema file that is used to validate either RBAC and/or trusted proxies. Each schema file is located next to the `values.yaml` file for each respective chart. + +### RBAC + +All Tinkerbell services need RBAC permissions to run in a Kubernetes cluster. There are two options for the type of RBAC that can be used. `Role` or `ClusterRole`. Each chart has its own way to toggle between the two. Most of them are located in their `values.yaml` file under `rbac.type`. There is also a global value in the Stack chart that can be used to set the RBAC type for all services. The global value is `global.rbac.type`. The default for all services and for the global value is `Role`. + +### Persistence + +The only persistence needed for the Tinkerbell stack is if you are downloading HookOS. By default HookOS is downloaded and stored in a local Persistent Volume. If you're cluster has a different storage class you want ot use, can override the default persistent volume claim by setting the `stack.hook.persistence.existingClaim` value.