split infrastructure by cluster

This commit is contained in:
2025-11-07 13:56:32 -06:00
parent 3dce69bb4b
commit 827e417129
19 changed files with 608 additions and 2 deletions

View File

@@ -0,0 +1,34 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: cert-manager
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
name: cert-manager
namespace: cert-manager
spec:
interval: 5m0s
url: oci://quay.io/jetstack/charts/cert-manager
layerSelector:
mediaType: "application/vnd.cncf.helm.chart.content.v1.tar+gzip"
operation: copy
ref:
tag: "v1.19.1"
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: cert-manager
namespace: cert-manager
spec:
interval: 30m
chartRef:
kind: OCIRepository
name: cert-manager
namespace: cert-manager
values:
crds:
enabled: true

View File

@@ -0,0 +1,38 @@
---
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: ingress-nginx
namespace: ingress-nginx
spec:
interval: 24h
url: https://kubernetes.github.io/ingress-nginx
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: ingress-nginx
namespace: ingress-nginx
spec:
interval: 30m
chart:
spec:
chart: ingress-nginx
version: "4.13.3"
sourceRef:
kind: HelmRepository
name: ingress-nginx
namespace: ingress-nginx
interval: 12h
values:
controller:
service:
type: "LoadBalancer"
externalTrafficPolicy: Local
admissionWebhooks:
enabled: false

View File

@@ -0,0 +1,34 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: edit-namespaces
rules:
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["create", "get", "list", "watch", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: edit-stages-clusterrolebinding
subjects:
- kind: ServiceAccount
name: stage-editor
namespace: ontime-operator
roleRef:
kind: ClusterRole
name: ontime-operator-stage-editor-role
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: edit-namespaces-clusterrolebinding
subjects:
- kind: ServiceAccount
name: stage-editor
namespace: ontime-operator
roleRef:
kind: ClusterRole
name: edit-namespaces
apiGroup: rbac.authorization.k8s.io

View File

@@ -0,0 +1,390 @@
apiVersion: v1
kind: Namespace
metadata:
labels:
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: ontime-operator
control-plane: controller-manager
name: ontime-operator
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: stages.cloud.getontime.no
spec:
group: cloud.getontime.no
names:
kind: Stage
listKind: StageList
plural: stages
singular: stage
scope: Namespaced
versions:
- name: v1
schema:
openAPIV3Schema:
description: Stage is the Schema for the stages API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: Spec defines the desired state of Stage
type: object
x-kubernetes-preserve-unknown-fields: true
status:
description: Status defines the observed state of Stage
type: object
x-kubernetes-preserve-unknown-fields: true
type: object
served: true
storage: true
subresources:
status: {}
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: ontime-operator
name: ontime-operator-controller-manager
namespace: ontime-operator
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: ontime-operator
name: ontime-operator-leader-election-role
namespace: ontime-operator
rules:
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ontime-operator-manager-role
rules:
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- apiGroups:
- ""
resources:
- secrets
verbs:
- '*'
- apiGroups:
- ""
resources:
- events
verbs:
- create
- apiGroups:
- cloud.getontime.no
resources:
- stages
- stages/status
- stages/finalizers
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- services
- persistentvolumeclaims
verbs:
- '*'
- apiGroups:
- apps
resources:
- deployments
verbs:
- '*'
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- '*'
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ontime-operator-metrics-auth-role
rules:
- apiGroups:
- authentication.k8s.io
resources:
- tokenreviews
verbs:
- create
- apiGroups:
- authorization.k8s.io
resources:
- subjectaccessreviews
verbs:
- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ontime-operator-metrics-reader
rules:
- nonResourceURLs:
- /metrics
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: ontime-operator
name: ontime-operator-stage-admin-role
rules:
- apiGroups:
- cloud.getontime.no
resources:
- stages
verbs:
- '*'
- apiGroups:
- cloud.getontime.no
resources:
- stages/status
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: ontime-operator
name: ontime-operator-stage-editor-role
rules:
- apiGroups:
- cloud.getontime.no
resources:
- stages
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- cloud.getontime.no
resources:
- stages/status
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: ontime-operator
name: ontime-operator-stage-viewer-role
rules:
- apiGroups:
- cloud.getontime.no
resources:
- stages
verbs:
- get
- list
- watch
- apiGroups:
- cloud.getontime.no
resources:
- stages/status
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: ontime-operator
name: ontime-operator-leader-election-rolebinding
namespace: ontime-operator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ontime-operator-leader-election-role
subjects:
- kind: ServiceAccount
name: ontime-operator-controller-manager
namespace: ontime-operator
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: ontime-operator
name: ontime-operator-manager-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ontime-operator-manager-role
subjects:
- kind: ServiceAccount
name: ontime-operator-controller-manager
namespace: ontime-operator
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ontime-operator-metrics-auth-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ontime-operator-metrics-auth-role
subjects:
- kind: ServiceAccount
name: ontime-operator-controller-manager
namespace: ontime-operator
---
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: ontime-operator
control-plane: controller-manager
name: ontime-operator-controller-manager-metrics-service
namespace: ontime-operator
spec:
ports:
- name: https
port: 8443
protocol: TCP
targetPort: 8443
selector:
app.kubernetes.io/name: ontime-operator
control-plane: controller-manager
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/name: ontime-operator
control-plane: controller-manager
name: ontime-operator-controller-manager
namespace: ontime-operator
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ontime-operator
control-plane: controller-manager
template:
metadata:
annotations:
kubectl.kubernetes.io/default-container: manager
labels:
app.kubernetes.io/name: ontime-operator
control-plane: controller-manager
spec:
containers:
- args:
- --metrics-require-rbac
- --metrics-secure
- --metrics-bind-address=:8443
- --leader-elect
- --leader-election-id=ontime-operator
- --health-probe-bind-address=:8081
image: git.jwetzell.com/jwetzell/ontime-operator:v1.4.0
livenessProbe:
httpGet:
path: /healthz
port: 8081
initialDelaySeconds: 15
periodSeconds: 20
name: manager
ports: []
readinessProbe:
httpGet:
path: /readyz
port: 8081
initialDelaySeconds: 5
periodSeconds: 10
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 10m
memory: 64Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
volumeMounts: []
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
serviceAccountName: ontime-operator-controller-manager
terminationGracePeriodSeconds: 10
volumes: []

View File

@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ./cluster-role-binding.yaml
- ./deploy.yaml
- ./namespace-prefix-policy.yaml
- ./service-account.yaml

View File

@@ -0,0 +1,98 @@
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "force-ns-prefix-for-stage-editor"
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["namespaces"]
matchConditions:
- name: 'only-stage-editor'
expression: "request.userInfo.username == 'system:serviceaccount:ontime-operator:stage-editor'"
validations:
- expression: "object.metadata.name.startsWith('team-')"
message: "All namespaces managed by stage-editor must start with 'team-'"
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: "force-ns-prefix-for-stage-editor-binding"
spec:
policyName: "force-ns-prefix-for-stage-editor"
validationActions: [Deny]
matchResources:
resourceRules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["namespaces"]
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "force-ns-prefix-for-stage-create-update"
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: ["cloud.getontime.no"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["stages"]
matchConditions:
- name: 'only-stage-editor'
expression: "request.userInfo.username == 'system:serviceaccount:ontime-operator:stage-editor'"
validations:
- expression: "object.metadata.namespace.startsWith('team-')"
message: "Stages must be managed in namespaces starting with 'team-'"
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: "force-ns-prefix-for-stage-create-update-binding"
spec:
policyName: "force-ns-prefix-for-stage-create-update"
validationActions: [Deny]
matchResources:
resourceRules:
- apiGroups: ["cloud.getontime.no"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["stages"]
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: "force-ns-prefix-for-stage-editor-delete"
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: ["cloud.getontime.no"]
apiVersions: ["v1"]
operations: ["DELETE"]
resources: ["stages"]
matchConditions:
- name: 'only-stage-editor'
expression: "request.userInfo.username == 'system:serviceaccount:ontime-operator:stage-editor'"
validations:
- expression: "request.namespace.startsWith('team-')"
message: "Stages must be managed in namespaces starting with 'team-'"
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: "force-ns-prefix-for-stage-editor-delete-binding"
spec:
policyName: "force-ns-prefix-for-stage-editor-delete"
validationActions: [Deny]
matchResources:
resourceRules:
- apiGroups: ["cloud.getontime.no"]
apiVersions: ["v1"]
operations: ["DELETE"]
resources: ["stages"]

View File

@@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: stage-editor
namespace: ontime-operator