From 8103ba4cbc38cf182689e79dfd2f0b8b2b10dc57 Mon Sep 17 00:00:00 2001 From: Alexey Kazakov Date: Wed, 20 May 2026 19:10:06 -0700 Subject: [PATCH 1/2] Add tier for -claw namespace --- .../nstemplatetiers/base1ns/ns_dev.yaml | 9 + .../base1ns/spacerole_admin.yaml | 31 ++++ .../nstemplatetiers/claw/cluster.yaml | 35 ++++ .../nstemplatetiers/claw/ns_claw.yaml | 171 ++++++++++++++++++ .../nstemplatetiers/claw/spacerole_admin.yaml | 82 +++++++++ .../templates/nstemplatetiers/claw/tier.yaml | 23 +++ .../nstemplatetier_generator_test.go | 3 + 7 files changed, 354 insertions(+) create mode 100644 deploy/templates/nstemplatetiers/claw/cluster.yaml create mode 100644 deploy/templates/nstemplatetiers/claw/ns_claw.yaml create mode 100644 deploy/templates/nstemplatetiers/claw/spacerole_admin.yaml create mode 100644 deploy/templates/nstemplatetiers/claw/tier.yaml diff --git a/deploy/templates/nstemplatetiers/base1ns/ns_dev.yaml b/deploy/templates/nstemplatetiers/base1ns/ns_dev.yaml index 490226284..f680ed892 100644 --- a/deploy/templates/nstemplatetiers/base1ns/ns_dev.yaml +++ b/deploy/templates/nstemplatetiers/base1ns/ns_dev.yaml @@ -120,6 +120,15 @@ objects: cpu: 10m memory: 64Mi +- apiVersion: v1 + kind: ResourceQuota + metadata: + name: compute-spacerequests + namespace: ${SPACE_NAME}-dev + spec: + hard: + count/spacerequests.toolchain.dev.openshift.com: "1" + - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: diff --git a/deploy/templates/nstemplatetiers/base1ns/spacerole_admin.yaml b/deploy/templates/nstemplatetiers/base1ns/spacerole_admin.yaml index 8f85b0407..1f60143bb 100644 --- a/deploy/templates/nstemplatetiers/base1ns/spacerole_admin.yaml +++ b/deploy/templates/nstemplatetiers/base1ns/spacerole_admin.yaml @@ -50,6 +50,37 @@ objects: - kind: User name: ${USERNAME} +- apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + name: spacerequest-manage + namespace: ${NAMESPACE} + rules: + - apiGroups: + - toolchain.dev.openshift.com + resources: + - spacerequests + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: ${USERNAME}-spacerequest-manage + namespace: ${NAMESPACE} + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: spacerequest-manage + subjects: + - kind: User + name: ${USERNAME} + parameters: - name: NAMESPACE required: true diff --git a/deploy/templates/nstemplatetiers/claw/cluster.yaml b/deploy/templates/nstemplatetiers/claw/cluster.yaml new file mode 100644 index 000000000..0f9fa85a6 --- /dev/null +++ b/deploy/templates/nstemplatetiers/claw/cluster.yaml @@ -0,0 +1,35 @@ +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: claw-cluster-resources +objects: +- apiVersion: quota.openshift.io/v1 + kind: ClusterResourceQuota + metadata: + name: for-${SPACE_NAME}-claw + spec: + quota: + hard: + count/deployments.apps: "5" + count/pods: "10" + count/routes.route.openshift.io: "3" + count/services: "5" + count/secrets: "50" + count/configmaps: "10" + selector: + annotations: null + labels: + matchLabels: + toolchain.dev.openshift.com/space: ${SPACE_NAME} +- apiVersion: toolchain.dev.openshift.com/v1alpha1 + kind: Idler + metadata: + name: ${SPACE_NAME}-claw + spec: + timeoutSeconds: ${{IDLER_TIMEOUT_SECONDS}} +parameters: +- name: SPACE_NAME + required: true +- name: IDLER_TIMEOUT_SECONDS + # 12 hours + value: "43200" diff --git a/deploy/templates/nstemplatetiers/claw/ns_claw.yaml b/deploy/templates/nstemplatetiers/claw/ns_claw.yaml new file mode 100644 index 000000000..ad14c259a --- /dev/null +++ b/deploy/templates/nstemplatetiers/claw/ns_claw.yaml @@ -0,0 +1,171 @@ +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: claw-claw +objects: +- apiVersion: v1 + kind: Namespace + metadata: + annotations: + openshift.io/description: ${SPACE_NAME}-claw + openshift.io/display-name: ${SPACE_NAME}-claw + openshift.io/requester: ${SPACE_NAME} + labels: + name: ${SPACE_NAME}-claw + name: ${SPACE_NAME}-claw + +# Role and RoleBindings for CRT administration (not associated with users) +- apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + name: exec-pods + namespace: ${SPACE_NAME}-claw + rules: + - apiGroups: + - "" + resources: + - pods/exec + verbs: + - get + - list + - watch + - create + - delete + - update +- apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: crtadmin-view + namespace: ${SPACE_NAME}-claw + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: view + subjects: + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: crtadmin-users-view +- apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: crtadmin-pods + namespace: ${SPACE_NAME}-claw + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: exec-pods + subjects: + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: crtadmin-users-view + +# ResourceQuota — sized for operator workloads (gateway, proxy, device-pairing) +# plus headroom for future components and rolling updates. +- apiVersion: v1 + kind: ResourceQuota + metadata: + name: compute-deploy + namespace: ${SPACE_NAME}-claw + spec: + hard: + limits.cpu: "8" + limits.memory: 10Gi + requests.cpu: "1" + requests.memory: 3Gi +- apiVersion: v1 + kind: ResourceQuota + metadata: + name: storage + namespace: ${SPACE_NAME}-claw + spec: + hard: + limits.ephemeral-storage: 5Gi + requests.storage: 15Gi + requests.ephemeral-storage: 5Gi + count/persistentvolumeclaims: "1" +# LimitRange — default resource requests/limits for containers +- apiVersion: v1 + kind: LimitRange + metadata: + name: resource-limits + namespace: ${SPACE_NAME}-claw + spec: + limits: + - type: "Container" + default: + cpu: 500m + memory: 512Mi + defaultRequest: + cpu: 10m + memory: 64Mi + +# NetworkPolicies — sandbox-standard ingress policies +- apiVersion: networking.k8s.io/v1 + kind: NetworkPolicy + metadata: + name: allow-same-namespace + namespace: ${SPACE_NAME}-claw + spec: + podSelector: {} + ingress: + - from: + - podSelector: {} +- apiVersion: networking.k8s.io/v1 + kind: NetworkPolicy + metadata: + name: allow-from-openshift-ingress + namespace: ${SPACE_NAME}-claw + spec: + ingress: + - from: + - namespaceSelector: + matchLabels: + network.openshift.io/policy-group: ingress + podSelector: {} + policyTypes: + - Ingress +- apiVersion: networking.k8s.io/v1 + kind: NetworkPolicy + metadata: + name: allow-from-openshift-monitoring + namespace: ${SPACE_NAME}-claw + spec: + ingress: + - from: + - namespaceSelector: + matchLabels: + network.openshift.io/policy-group: monitoring + podSelector: {} + policyTypes: + - Ingress +- apiVersion: networking.k8s.io/v1 + kind: NetworkPolicy + metadata: + name: allow-from-olm-namespaces + namespace: ${SPACE_NAME}-claw + spec: + ingress: + - from: + - namespaceSelector: + matchLabels: + openshift.io/scc: anyuid + podSelector: {} + policyTypes: + - Ingress +- apiVersion: networking.k8s.io/v1 + kind: NetworkPolicy + metadata: + name: allow-from-console-namespaces + namespace: ${SPACE_NAME}-claw + spec: + ingress: + - from: + - namespaceSelector: + matchLabels: + network.openshift.io/policy-group: console + podSelector: {} + policyTypes: + - Ingress +parameters: +- name: SPACE_NAME + required: true diff --git a/deploy/templates/nstemplatetiers/claw/spacerole_admin.yaml b/deploy/templates/nstemplatetiers/claw/spacerole_admin.yaml new file mode 100644 index 000000000..f5af08b14 --- /dev/null +++ b/deploy/templates/nstemplatetiers/claw/spacerole_admin.yaml @@ -0,0 +1,82 @@ +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: claw-spacerole-admin +objects: + +- apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + name: claw-user + namespace: ${NAMESPACE} + rules: + - apiGroups: + - "claw.sandbox.redhat.com" + resources: + - claws + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - pods/log + verbs: + - get + - list + - apiGroups: + - "" + resources: + - events + verbs: + - get + - list + - watch + - apiGroups: + - "route.openshift.io" + resources: + - routes + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - secrets + verbs: + - create + - update + - patch + - delete +- apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: ${USERNAME}-claw-user + namespace: ${NAMESPACE} + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: claw-user + subjects: + - kind: User + name: ${USERNAME} + +parameters: +- name: NAMESPACE + required: true +- name: USERNAME + required: true diff --git a/deploy/templates/nstemplatetiers/claw/tier.yaml b/deploy/templates/nstemplatetiers/claw/tier.yaml new file mode 100644 index 000000000..1915df4fd --- /dev/null +++ b/deploy/templates/nstemplatetiers/claw/tier.yaml @@ -0,0 +1,23 @@ +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: claw-tier +objects: +- kind: NSTemplateTier + apiVersion: toolchain.dev.openshift.com/v1alpha1 + metadata: + name: claw + namespace: ${NAMESPACE} + spec: + clusterResources: + templateRef: ${CLUSTER_TEMPL_REF} + namespaces: + - templateRef: ${CLAW_TEMPL_REF} + spaceRoles: + admin: + templateRef: ${ADMIN_TEMPL_REF} +parameters: +- name: NAMESPACE +- name: CLUSTER_TEMPL_REF +- name: CLAW_TEMPL_REF +- name: ADMIN_TEMPL_REF diff --git a/pkg/templates/nstemplatetiers/nstemplatetier_generator_test.go b/pkg/templates/nstemplatetiers/nstemplatetier_generator_test.go index 078bfd7ef..d3ed3743a 100644 --- a/pkg/templates/nstemplatetiers/nstemplatetier_generator_test.go +++ b/pkg/templates/nstemplatetiers/nstemplatetier_generator_test.go @@ -31,12 +31,15 @@ var expectedProdTiers = []string{ "base1ns", "base1nsnoidling", "base1ns6didler", + "claw", } func nsTypes(tier string) []string { switch tier { case "base": return []string{"dev", "stage"} + case "claw": + return []string{"claw"} default: return []string{"dev"} } From e75981c9e6acd82637456f59f367483d1ca3d42d Mon Sep 17 00:00:00 2001 From: Alexey Kazakov Date: Thu, 21 May 2026 11:16:19 -0700 Subject: [PATCH 2/2] Refactor manifests --- .../nstemplatetiers/base/ns_dev.yaml | 9 ++++ .../nstemplatetiers/base/ns_stage.yaml | 9 ++++ .../base1ns/spacerole_admin.yaml | 31 -------------- .../nstemplatetiers/claw/spacerole_admin.yaml | 42 ++++++++----------- 4 files changed, 36 insertions(+), 55 deletions(-) diff --git a/deploy/templates/nstemplatetiers/base/ns_dev.yaml b/deploy/templates/nstemplatetiers/base/ns_dev.yaml index 72e3be5c8..c4e944cba 100644 --- a/deploy/templates/nstemplatetiers/base/ns_dev.yaml +++ b/deploy/templates/nstemplatetiers/base/ns_dev.yaml @@ -76,6 +76,15 @@ objects: defaultRequest: cpu: 10m memory: 64Mi +- apiVersion: v1 + kind: ResourceQuota + metadata: + name: compute-spacerequests + namespace: ${SPACE_NAME}-dev + spec: + hard: + count/spacerequests.toolchain.dev.openshift.com: "1" + - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: diff --git a/deploy/templates/nstemplatetiers/base/ns_stage.yaml b/deploy/templates/nstemplatetiers/base/ns_stage.yaml index 6cbdc7238..c0573359f 100644 --- a/deploy/templates/nstemplatetiers/base/ns_stage.yaml +++ b/deploy/templates/nstemplatetiers/base/ns_stage.yaml @@ -76,6 +76,15 @@ objects: defaultRequest: cpu: 10m memory: 64Mi +- apiVersion: v1 + kind: ResourceQuota + metadata: + name: compute-spacerequests + namespace: ${SPACE_NAME}-stage + spec: + hard: + count/spacerequests.toolchain.dev.openshift.com: "1" + - apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: diff --git a/deploy/templates/nstemplatetiers/base1ns/spacerole_admin.yaml b/deploy/templates/nstemplatetiers/base1ns/spacerole_admin.yaml index 1f60143bb..8f85b0407 100644 --- a/deploy/templates/nstemplatetiers/base1ns/spacerole_admin.yaml +++ b/deploy/templates/nstemplatetiers/base1ns/spacerole_admin.yaml @@ -50,37 +50,6 @@ objects: - kind: User name: ${USERNAME} -- apiVersion: rbac.authorization.k8s.io/v1 - kind: Role - metadata: - name: spacerequest-manage - namespace: ${NAMESPACE} - rules: - - apiGroups: - - toolchain.dev.openshift.com - resources: - - spacerequests - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiVersion: rbac.authorization.k8s.io/v1 - kind: RoleBinding - metadata: - name: ${USERNAME}-spacerequest-manage - namespace: ${NAMESPACE} - roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: spacerequest-manage - subjects: - - kind: User - name: ${USERNAME} - parameters: - name: NAMESPACE required: true diff --git a/deploy/templates/nstemplatetiers/claw/spacerole_admin.yaml b/deploy/templates/nstemplatetiers/claw/spacerole_admin.yaml index f5af08b14..7adbd8a12 100644 --- a/deploy/templates/nstemplatetiers/claw/spacerole_admin.yaml +++ b/deploy/templates/nstemplatetiers/claw/spacerole_admin.yaml @@ -4,6 +4,21 @@ metadata: name: claw-spacerole-admin objects: +# RoleBinding to built-in view ClusterRole (read access to most resources, excludes secrets) +- apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: ${USERNAME}-view + namespace: ${NAMESPACE} + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: view + subjects: + - kind: User + name: ${USERNAME} + +# Custom Role for claw-specific permissions not covered by view - apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: @@ -25,39 +40,18 @@ objects: - apiGroups: - "" resources: - - pods + - pods/exec verbs: - get - - list - - watch - - apiGroups: - - "" - resources: - - pods/log - verbs: - - get - - list + - create - apiGroups: - "" resources: - - events - verbs: - - get - - list - - watch - - apiGroups: - - "route.openshift.io" - resources: - - routes + - secrets verbs: - get - list - watch - - apiGroups: - - "" - resources: - - secrets - verbs: - create - update - patch