Skip to content

Commit

Permalink
feat(helm): Automatically create role & bindings for namespace contai…
Browse files Browse the repository at this point in the history
…ning platform secret
  • Loading branch information
Thomas Kosiewski committed Jul 16, 2024
1 parent 811a2dd commit 9957906
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 23 deletions.
1 change: 1 addition & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ generate-vcluster-images version="0.0.0":
generate-cli-docs:
go run -mod vendor -tags pro ./hack/docs/main.go

# Generate the vcluster.yaml config schema
generate-config-schema:
go run -mod vendor ./hack/schema/main.go

Expand Down
24 changes: 24 additions & 0 deletions chart/templates/_rbac.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,27 @@
{{- end }}
{{- end }}
{{- end -}}

{{/*
Whether to create a role and role binding to access the platform API key secret
*/}}
{{- define "vcluster.rbac.createPlatformSecretRole" -}}
{{- $createRBAC := dig "platform" "apiKey" "createRBAC" true .Values.external -}}
{{- if and $createRBAC (ne (include "vcluster.rbac.platformSecretNamespace" .) .Release.Namespace) }}
{{- true -}}
{{- end }}
{{- end -}}

{{/*
Namespace containing the vCluster platform secret
*/}}
{{- define "vcluster.rbac.platformSecretNamespace" -}}
{{- dig "platform" "apiKey" "namespace" .Release.Namespace .Values.external | default .Release.Namespace -}}
{{- end -}}

{{/*
Name specifies the secret name containing the vCluster platform licenses and tokens
*/}}
{{- define "vcluster.rbac.platformSecretName" -}}
{{- dig "platform" "apiKey" "secretName" "vcluster-platform-api-key" .Values.external | quote -}}
{{- end -}}
31 changes: 31 additions & 0 deletions chart/templates/platform-rbac.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{{- if include "vcluster.rbac.createPlatformSecretRole" . }}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: vcluster-platform-secret-role
namespace: {{ include "vcluster.rbac.platformSecretNamespace" .}}
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "patch"]
resourceNames:
- {{ include "vcluster.rbac.platformSecretName" . }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: vcluster-platform-secret-role-binding
namespace: {{ include "vcluster.rbac.platformSecretNamespace" .}}
subjects:
- kind: ServiceAccount
{{- if .Values.controlPlane.advanced.serviceAccount.name }}
name: {{ .Values.controlPlane.advanced.serviceAccount.name }}
{{- else }}
name: vc-{{ .Release.Name }}
{{- end }}
namespace: {{ include "vcluster.rbac.platformSecretNamespace" .}}
roleRef:
kind: Role
name: vcluster-platform-secret-role
apiGroup: rbac.authorization.k8s.io
{{- end }}
98 changes: 98 additions & 0 deletions chart/tests/platform-secret-role_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
suite: Platform Secret Role
templates:
- platform-rbac.yaml

tests:
- it: check explicitly disabled
set:
external:
platform:
apiKey:
namespace: "some-other-namespace"
createRBAC: false
asserts:
- hasDocuments:
count: 0

- it: check disabled on empty namespace
set:
external:
platform:
apiKey:
namespace: ""
asserts:
- hasDocuments:
count: 0

- it: check disabled on implicit same namespace
set:
external:
platform:
apiKey:
secretName: "some-other-secret"
asserts:
- hasDocuments:
count: 0

- it: automatically create role for specific secret for reading & patching
set:
external:
platform:
apiKey:
secretName: "my-secret-name"
namespace: "some-other-namespace"
asserts:
- hasDocuments:
count: 2
- documentIndex: 0
lengthEqual:
path: rules
count: 1
- documentIndex: 0
contains:
path: rules
count: 1
content:
apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "patch"]
resourceNames: ["my-secret-name"]
- documentIndex: 1
contains:
path: subjects
count: 1
content:
kind: ServiceAccount
name: vc-RELEASE-NAME
namespace: some-other-namespace

- it: automatically create role for default secret for reading & patching
set:
external:
platform:
apiKey:
namespace: "some-other-namespace"
asserts:
- hasDocuments:
count: 2
- documentIndex: 0
lengthEqual:
path: rules
count: 1
- documentIndex: 0
contains:
path: rules
count: 1
content:
apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "watch", "patch"]
resourceNames: ["vcluster-platform-api-key"]
- documentIndex: 1
contains:
path: subjects
count: 1
content:
kind: ServiceAccount
name: vc-RELEASE-NAME
namespace: some-other-namespace
44 changes: 22 additions & 22 deletions chart/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ sync:
# PersistentVolumes defines if persistent volumes created within the virtual cluster should get synced to the host cluster.
persistentVolumes:
enabled: false

# Configure what resources vCluster should sync from the host cluster to the virtual cluster.
fromHost:
# Events defines if events should get synced from the host cluster to the virtual cluster, but not back.
Expand Down Expand Up @@ -318,7 +318,7 @@ controlPlane:
requests:
cpu: 40m
memory: 64Mi

# BackingStore defines which backing store to use for virtual cluster. If not defined will use embedded database as a default backing store.
backingStore:
# Database defines that a database backend should be used as the backend for the virtual cluster. This uses a project called kine under the hood which is a shim for bridging Kubernetes and relational databases.
Expand Down Expand Up @@ -439,7 +439,7 @@ controlPlane:
headlessService:
enabled: true
annotations: {}

# Proxy defines options for the virtual cluster control plane proxy that is used to do authentication and intercept requests.
proxy:
# BindAddress under which vCluster will expose the proxy.
Expand All @@ -448,7 +448,7 @@ controlPlane:
port: 8443
# ExtraSANs are extra hostnames to sign the vCluster proxy certificate for.
extraSANs: []

# CoreDNS defines everything related to the coredns that is deployed and used within the vCluster.
coredns:
# Enabled defines if coredns is enabled
Expand Down Expand Up @@ -500,7 +500,7 @@ controlPlane:
labelSelector:
matchLabels:
k8s-app: kube-dns

# Service defines options for vCluster service deployed by Helm.
service:
# Enabled defines if the control plane service should be enabled
Expand All @@ -514,7 +514,7 @@ controlPlane:
# Spec allows you to configure extra service options.
spec:
type: ClusterIP

# Ingress defines options for vCluster ingress deployed by Helm.
ingress:
# Enabled defines if the control plane ingress should be enabled
Expand All @@ -531,7 +531,7 @@ controlPlane:
# Spec allows you to configure extra ingress options.
spec:
tls: []

# StatefulSet defines options for vCluster statefulSet deployed by Helm.
statefulSet:
labels: {}
Expand Down Expand Up @@ -645,14 +645,14 @@ controlPlane:
# StartupProbe specifies if the startup probe for the container should be enabled
startupProbe:
enabled: true

# ServiceMonitor can be used to automatically create a service monitor for vCluster deployment itself.
serviceMonitor:
# Enabled configures if Helm should create the service monitor.
enabled: false
labels: {}
annotations: {}

# Advanced holds additional configuration for the vCluster control plane.
advanced:
# DefaultImageRegistry will be used as a prefix for all internal images deployed by vCluster or Helm. This makes it easy to
Expand Down Expand Up @@ -699,7 +699,7 @@ integrations:
nodes: true
# Pods defines if metrics-server pods api should get proxied from host to virtual cluster.
pods: true

# KubeVirt reuses a host kubevirt and makes certain CRDs from it available inside the vCluster
kubeVirt:
# Enabled signals if the integration should be enabled
Expand Down Expand Up @@ -738,7 +738,7 @@ rbac:
overwriteRules: []
# ExtraRules will add rules to the role.
extraRules: []

# ClusterRole holds virtual cluster cluster role configuration
clusterRole:
# Enabled defines if the cluster role should be enabled or disabled. If auto, vCluster automatically determines whether the virtual cluster requires a cluster role.
Expand All @@ -758,10 +758,10 @@ networking:
toHost: []
# FromHost defines the services that should get synced from the host to the virtual cluster.
fromHost: []

# ResolveDNS allows to define extra DNS rules. This only works if embedded coredns is configured.
resolveDNS: []

# Advanced holds advanced network options.
advanced:
# ClusterDomain is the Kubernetes cluster domain to use within the virtual cluster.
Expand Down Expand Up @@ -809,7 +809,7 @@ policies:
matchExpressions: []
# Scopes are the resource quota scopes
scopes: []

# LimitRange specifies limit range options.
limitRange:
# Enabled defines if the limit range should be deployed by vCluster.
Expand All @@ -826,7 +826,7 @@ policies:
ephemeral-storage: 3Gi
memory: 128Mi
cpu: 100m

# NetworkPolicy specifies network policy options.
networkPolicy:
# Enabled defines if the network policy should be deployed by vCluster.
Expand All @@ -852,7 +852,7 @@ policies:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16

# CentralAdmission defines what validating or mutating webhooks should be enforced within the virtual cluster.
centralAdmission:
# ValidatingWebhooks are validating webhooks that should be enforced in the virtual cluster
Expand All @@ -864,10 +864,10 @@ policies:
exportKubeConfig:
# Context is the name of the context within the generated kubeconfig to use.
context: ""

# Override the default https://localhost:8443 and specify a custom hostname for the generated kubeconfig.
server: ""

# Declare in which host cluster secret vCluster should store the generated virtual cluster kubeconfig.
# If this is not defined, vCluster create it with `vc-NAME`. If you specify another name,
# vCluster creates the config in this other secret.
Expand All @@ -890,7 +890,7 @@ experimental:
multiNamespaceMode:
# Enabled specifies if multi namespace mode should get enabled
enabled: false

# SyncSettings are advanced settings for the syncer controller.
syncSettings:
# DisableSync will not sync any resources and disable most control plane functionality.
Expand All @@ -903,12 +903,12 @@ experimental:
targetNamespace: ""
# SetOwner specifies if vCluster should set an owner reference on the synced objects to the vCluster service. This allows for easy garbage collection.
setOwner: true

# IsolatedControlPlane is a feature to run the vCluster control plane in a different Kubernetes cluster than the workloads themselves.
isolatedControlPlane:
# Headless states that Helm should deploy the vCluster in headless mode for the isolated control plane.
headless: false

# Deploy allows you to configure manifests and Helm charts to deploy within the virtual cluster.
deploy:
# Host defines what manifests to deploy into the host cluster
Expand All @@ -925,7 +925,7 @@ experimental:
manifestsTemplate: ""
# Helm are Helm charts that should get deployed into the virtual cluster
helm: []

# GenericSync holds options to generically sync resources from virtual cluster to host.
genericSync:
clusterRole:
Expand Down
6 changes: 5 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -1795,7 +1795,6 @@ type ExperimentalDeployHelmChart struct {

type PlatformConfig struct {
// APIKey defines where to find the platform access key and host. By default, vCluster will search in the following locations in this precedence:
// * platform.api.accessKey
// * environment variable called LICENSE
// * secret specified under external.platform.apiKey.secretName
// * secret called "vcluster-platform-api-key" in the vCluster namespace
Expand All @@ -1810,6 +1809,11 @@ type PlatformAPIKey struct {
// Namespace defines the namespace where the access key secret should be retrieved from. If this is not equal to the namespace
// where the vCluster instance is deployed, you need to make sure vCluster has access to this other namespace.
Namespace string `json:"namespace,omitempty"`

// CreateRBAC will automatically create the necessary RBAC roles and role bindings to allow vCluster to read the secret specified
// in the above namespace, if specified.
// This defaults to true.
CreateRBAC *bool `json:"createRBAC,omitempty"`
}

type ExperimentalGenericSync struct {
Expand Down

0 comments on commit 9957906

Please sign in to comment.