feat: upstream enterprise preview (#1841)

feat: upstream enterprise preview

---------

Signed-off-by: Oliver Baehler <oliver@sudo-i.net>
Co-authored-by: CorentinPtrl <pitrel.corentin@gmail.com>
This commit is contained in:
Oliver Bähler
2026-05-28 00:58:58 +02:00
committed by GitHub
co-authored by CorentinPtrl
parent 7a65ab7afc
commit cc4fb45d70
462 changed files with 48456 additions and 10529 deletions
+128
View File
@@ -220,6 +220,134 @@ spec:
return obj
resource.customizations.health.capsule.clastix.io_GlobalTenantResource: |
hs = {}
if obj.status ~= nil then
if obj.status.conditions ~= nil then
for i, condition in ipairs(obj.status.conditions) do
if condition.type == "Cordoned" and condition.status == "True" then
hs.status = "Suspended"
hs.message = condition.message
return hs
end
end
for i, condition in ipairs(obj.status.conditions) do
if condition.type == "Ready" and condition.status == "False" then
hs.status = "Degraded"
hs.message = condition.message
return hs
end
if condition.type == "Ready" and condition.status == "True" then
hs.status = "Healthy"
hs.message = condition.message
return hs
end
end
end
end
hs.status = "Progressing"
hs.message = "Waiting for Status"
return hs
resource.customizations.actions.capsule.clastix.io_GlobalTenantResource: |
mergeBuiltinActions: true
discovery.lua: |
actions = {}
actions["cordon"] = {
["iconClass"] = "fa fa-solid fa-pause",
["disabled"] = true,
}
actions["uncordon"] = {
["iconClass"] = "fa fa-solid fa-play",
["disabled"] = true,
}
actions["reconcile"] = {
["iconClass"] = "fa fa-solid fa-sync",
["disabled"] = false,
}
local suspend = false
if obj.spec ~= nil and obj.spec.cordoned ~= nil then
suspend = obj.spec.cordoned
end
if suspend then
actions["uncordon"]["disabled"] = false
else
actions["cordon"]["disabled"] = false
end
return actions
definitions:
- name: cordon
action.lua: |
if obj.spec == nil then
obj.spec = {}
end
obj.spec.cordoned = true
return obj
- name: uncordon
action.lua: |
if obj.spec ~= nil and obj.spec.cordoned ~= nil and obj.spec.cordoned then
obj.spec.cordoned = false
end
return obj
- name: reconcile
action.lua: |
if obj.metadata == nil then
obj.metadata = {}
end
if obj.metadata.annotations == nil then
obj.metadata.annotations = {}
end
local key = "reconcile.projectcapsule.dev/requested"
local ts = nil
if os ~= nil and os.time ~= nil then
ts = tostring(os.time())
else
ts = "true"
end
obj.metadata.annotations[key] = ts
return obj
resource.customizations.health.capsule.clastix.io_TenantResource: |
hs = {}
if obj.status ~= nil then
if obj.status.conditions ~= nil then
for i, condition in ipairs(obj.status.conditions) do
if condition.type == "Cordoned" and condition.status == "True" then
hs.status = "Suspended"
hs.message = condition.message
return hs
end
end
for i, condition in ipairs(obj.status.conditions) do
if condition.type == "Ready" and condition.status == "False" then
hs.status = "Degraded"
hs.message = condition.message
return hs
end
if condition.type == "Ready" and condition.status == "True" then
hs.status = "Healthy"
hs.message = condition.message
return hs
end
end
end
end
hs.status = "Progressing"
hs.message = "Waiting for Status"
return hs
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
@@ -0,0 +1,42 @@
---
apiVersion: capsule.clastix.io/v1beta2
kind: GlobalCustomQuota
metadata:
name: storage-aggregate
spec:
limit: 5Gi
namespaceSelectors:
- matchLabels:
capsule.clastix.io/tenant: wind
sources:
- apiVersion: v1
kind: Pod
op: add
path: ".spec.volumes[*].ephemeral.volumeClaimTemplate.spec.resources.requests.storage"
- apiVersion: v1
kind: PersistentVolumeClaim
op: add
path: ".spec.resources.requests.storage"
selectors:
- fieldSelectors:
- '.spec.accessModes[?(@=="ReadWriteOnce")]'
---
apiVersion: capsule.clastix.io/v1beta2
kind: GlobalCustomQuota
metadata:
name: cpu-limits
spec:
limit: 5
namespaceSelectors:
- matchLabels:
capsule.clastix.io/tenant: wind
sources:
- apiVersion: "v1"
kind: Pod
op: add
path: .spec.containers[*].resources.limits.cpu
- apiVersion: "v1"
kind: Pod
op: add
path: .spec.initContainers[*].resources.limits.cpu
@@ -5,3 +5,5 @@ resources:
- tenants.yaml
- resource.yaml
- pools.yaml
- rbac.yaml
- custom-quotas.yaml
@@ -0,0 +1,22 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: configmap-replicator
labels:
projectcapsule.dev/aggregate-to-controller: "true"
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "create", "patch", "watch", "list", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: secret-replicator
labels:
projectcapsule.dev/aggregate-to-controller: "true"
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "create", "patch", "watch", "list", "delete"]
@@ -0,0 +1,42 @@
---
apiVersion: capsule.clastix.io/v1beta2
kind: GlobalTenantResource
metadata:
name: custom-cm
spec:
resyncPeriod: 60s
resources:
- additionalMetadata:
labels:
"replicated-by": "capsule"
rawItems:
- apiVersion: v1
kind: ConfigMap
metadata:
name: game-demo
data:
# property-like keys; each key maps to a simple value
player_initial_lives: "3"
ui_properties_file_name: "user-interface.properties"
---
apiVersion: capsule.clastix.io/v1beta2
kind: GlobalTenantResource
metadata:
name: gitops-owners
spec:
resyncPeriod: 60s
resources:
- additionalMetadata:
labels:
"replicated-by": "capsule"
rawItems:
- apiVersion: capsule.clastix.io/v1beta2
kind: TenantOwner
metadata:
name: "{{tenant.name}}-{{namespace}}"
spec:
clusterRoles:
- capsule-namespace-deleter
- admin
kind: ServiceAccount
name: "system:serviceaccount:{{namespace}}:gitops-reconciler"
@@ -2,20 +2,45 @@
apiVersion: capsule.clastix.io/v1beta2
kind: GlobalTenantResource
metadata:
name: custom-cm
namespace: solar-system
name: gitops-owners
spec:
resyncPeriod: 60s
dependsOn:
- name: custom-cm-2
resources:
- additionalMetadata:
labels:
"replicated-by": "capsule"
rawItems:
- apiVersion: v1
kind: ConfigMap
- apiVersion: capsule.clastix.io/v1beta2
kind: TenantOwner
metadata:
name: game-demo
data:
# property-like keys; each key maps to a simple value
player_initial_lives: "3"
ui_properties_file_name: "user-interface.properties"
name: "{{tenant.name}}-{{namespace}}"
spec:
clusterRoles:
- capsule-namespace-deleter
- admin
kind: ServiceAccount
name: "system:serviceaccount:{{namespace}}:gitops-reconciler"
---
apiVersion: capsule.clastix.io/v1beta2
kind: GlobalTenantResource
metadata:
name: cluster-replication
spec:
resyncPeriod: 60s
scope: None
resources:
- generators:
- template: |
{{ $$key := generateAgeKey }}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: "cluster-replication"
namespace: "default"
data:
data: |
identity: {{ $$key.Identity | quote }}
recipient: {{ $$key.Recipient | quote }}
+41 -7
View File
@@ -9,6 +9,31 @@ spec:
owners:
- name: alice
kind: User
rules:
- permissions:
rules:
- clusterRoles:
- "configmap-replicator"
- namespaceSelector:
matchExpressions:
- key: env
operator: In
values:
- "test"
permissions:
rules:
- clusterRoles:
- "secret-replicator"
- namespaceSelector:
matchExpressions:
- key: env
operator: In
values:
- "prod"
permissions:
rules:
- clusterRoles:
- "sade-boi"
permissions:
matchOwners:
- matchLabels:
@@ -16,9 +41,6 @@ spec:
- matchLabels:
tenant: solar
namespaceOptions:
requiredMetadata:
labels:
env: "prod|test|dev"
additionalMetadata:
labels:
team: platform
@@ -33,6 +55,16 @@ spec:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: joe
resourceQuotas:
scope: Tenant
items:
- hard:
limits.cpu: "8"
limits.memory: 16Gi
requests.cpu: "8"
requests.memory: 16Gi
- hard:
pods: "10"
---
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
@@ -41,10 +73,6 @@ metadata:
labels:
customer: a
spec:
namespaceOptions:
requiredMetadata:
labels:
env: "prod|test|dev"
permissions:
matchOwners:
- matchLabels:
@@ -66,6 +94,12 @@ spec:
- url: "harbor/.*"
policy:
- "Never"
- enforce:
registries:
- url: "custom/.*"
policy:
- "Never"
- namespaceSelector:
matchExpressions:
- key: env
+1 -1
View File
@@ -1,7 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/fluxcd/flux2/releases/download/v2.4.0/install.yaml
- https://github.com/fluxcd/flux2/releases/download/v2.7.5/install.yaml
patches:
- patch: |
- op: add
+74
View File
@@ -0,0 +1,74 @@
#!/usr/bin/env bash
set -euo pipefail
CLUSTER_NAME="${1:-capsule}"
NAMESPACE="${2:-capsule-system}"
SA_NAME="${3:-capsule}"
TARGET="${4:-kubeconfig-${SA_NAME}.yaml}"
SECRET_NAME="${SA_NAME}-static-token"
echo "👉 Using cluster: $CLUSTER_NAME"
echo "👉 Namespace: $NAMESPACE"
echo "👉 ServiceAccount: $SA_NAME"
echo "👉 Target: $TARGET"
echo "📄 Exporting kubeconfig..."
TMP_KUBECONFIG=$(mktemp)
kind get kubeconfig --name "$CLUSTER_NAME" > "$TMP_KUBECONFIG"
echo "🔐 Creating static token secret..."
kubectl -n "$NAMESPACE" apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: ${SECRET_NAME}
annotations:
kubernetes.io/service-account.name: ${SA_NAME}
type: kubernetes.io/service-account-token
EOF
echo "⏳ Waiting for token to populate..."
sleep 2
TOKEN=$(kubectl -n "$NAMESPACE" get secret "$SECRET_NAME" \
-o jsonpath='{.data.token}' | base64 -d)
SERVER=$(kubectl config view --raw --kubeconfig "$TMP_KUBECONFIG" \
-o jsonpath='{.clusters[0].cluster.server}')
CA_DATA=$(kubectl config view --raw --kubeconfig "$TMP_KUBECONFIG" \
-o jsonpath='{.clusters[0].cluster.certificate-authority-data}')
mkdir -p "$(dirname "$TARGET")"
cat > "$TARGET" <<EOF
apiVersion: v1
kind: Config
clusters:
- name: kind
cluster:
certificate-authority-data: ${CA_DATA}
server: ${SERVER}
contexts:
- name: ${SA_NAME}-context
context:
cluster: kind
namespace: ${NAMESPACE}
user: ${SA_NAME}
current-context: ${SA_NAME}-context
users:
- name: ${SA_NAME}
user:
token: ${TOKEN}
EOF
rm -f "$TMP_KUBECONFIG"
echo "✅ Done!"
echo "👉 SA kubeconfig written to: $TARGET"
echo
echo "export SERVICE_ACCOUNT=$SA_NAME"
echo "export NAMESPACE=$NAMESPACE"
echo "export KUBECONFIG=$TARGET"