All the deploy
This commit is contained in:
112
deploy/helm/pieced-operator/templates/catalog-cm.yaml
Normal file
112
deploy/helm/pieced-operator/templates/catalog-cm.yaml
Normal file
@@ -0,0 +1,112 @@
|
||||
# The package catalog is deployed as a ConfigMap in the operator namespace.
|
||||
# To update packages, edit the catalog data below and upgrade the Helm release.
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: pieced-package-catalog
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: pieced-operator
|
||||
data:
|
||||
catalog.yaml: |
|
||||
packages:
|
||||
telegram:
|
||||
name: Telegram
|
||||
category: channel
|
||||
description: Telegram bot messaging channel
|
||||
channels:
|
||||
telegram:
|
||||
enabled: true
|
||||
env_vars:
|
||||
- name: TELEGRAM_BOT_TOKEN
|
||||
secret_key: bot-token
|
||||
vault_path_suffix: telegram
|
||||
required: true
|
||||
bindings:
|
||||
- match:
|
||||
channel: telegram
|
||||
egress_rules:
|
||||
- host: api.telegram.org
|
||||
port: 443
|
||||
customer_instructions: |
|
||||
1. Open Telegram and message @BotFather
|
||||
2. Send /newbot and follow the prompts
|
||||
3. Copy the bot token
|
||||
disclaimer: >
|
||||
Messages are relayed through Telegram servers outside Switzerland.
|
||||
|
||||
discord:
|
||||
name: Discord
|
||||
category: channel
|
||||
description: Discord bot messaging channel
|
||||
channels:
|
||||
discord:
|
||||
enabled: true
|
||||
env_vars:
|
||||
- name: DISCORD_BOT_TOKEN
|
||||
secret_key: bot-token
|
||||
vault_path_suffix: discord
|
||||
- name: DISCORD_APP_ID
|
||||
secret_key: app-id
|
||||
vault_path_suffix: discord
|
||||
bindings:
|
||||
- match:
|
||||
channel: discord
|
||||
egress_rules:
|
||||
- host: discord.com
|
||||
port: 443
|
||||
- host: gateway.discord.gg
|
||||
port: 443
|
||||
customer_instructions: |
|
||||
1. Go to https://discord.com/developers/applications
|
||||
2. Create app, add bot, copy token and app ID
|
||||
3. Invite bot to server with messages scope
|
||||
|
||||
email:
|
||||
name: Email (Gmail)
|
||||
category: channel
|
||||
description: Email integration via Gmail IMAP/SMTP
|
||||
channels:
|
||||
email:
|
||||
enabled: true
|
||||
settings:
|
||||
provider: gmail
|
||||
env_vars:
|
||||
- name: EMAIL_ADDRESS
|
||||
secret_key: address
|
||||
vault_path_suffix: email
|
||||
- name: EMAIL_APP_PASSWORD
|
||||
secret_key: app-password
|
||||
vault_path_suffix: email
|
||||
bindings:
|
||||
- match:
|
||||
channel: email
|
||||
egress_rules:
|
||||
- host: imap.gmail.com
|
||||
port: 993
|
||||
- host: smtp.gmail.com
|
||||
port: 465
|
||||
|
||||
web-search:
|
||||
name: Web Search
|
||||
category: skill
|
||||
description: Web search via internal SearXNG
|
||||
skills:
|
||||
- "pack:openclaw/skills/web-search@latest"
|
||||
env_vars:
|
||||
- name: SEARXNG_URL
|
||||
default: "http://searxng.searxng.svc.cluster.local:8080"
|
||||
egress_rules: []
|
||||
|
||||
document-processing:
|
||||
name: Document Processing
|
||||
category: skill
|
||||
description: PDF, DOCX, spreadsheet processing
|
||||
skills:
|
||||
- "pack:openclaw/skills/document-processing@latest"
|
||||
init_deps:
|
||||
apt:
|
||||
- pandoc
|
||||
- libreoffice-writer-nogui
|
||||
- ffmpeg
|
||||
egress_rules: []
|
||||
13
deploy/helm/pieced-operator/templates/crds/_.yaml
Normal file
13
deploy/helm/pieced-operator/templates/crds/_.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
spec:
|
||||
group: ""
|
||||
names:
|
||||
kind: ""
|
||||
plural: ""
|
||||
scope: ""
|
||||
versions: null
|
||||
@@ -0,0 +1,116 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: piecedtenants.pieced.ch
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.17.2
|
||||
spec:
|
||||
group: pieced.ch
|
||||
names:
|
||||
kind: PiecedTenant
|
||||
listKind: PiecedTenantList
|
||||
plural: piecedtenants
|
||||
singular: piecedtenant
|
||||
shortNames:
|
||||
- pt
|
||||
scope: Cluster
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
additionalPrinterColumns:
|
||||
- name: Display Name
|
||||
type: string
|
||||
jsonPath: .spec.displayName
|
||||
- name: Phase
|
||||
type: string
|
||||
jsonPath: .status.phase
|
||||
- name: Namespace
|
||||
type: string
|
||||
jsonPath: .status.tenantNamespace
|
||||
- name: Age
|
||||
type: date
|
||||
jsonPath: .metadata.creationTimestamp
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
description: PiecedTenant represents a customer tenant on the PieCed IT multi-tenant platform.
|
||||
properties:
|
||||
apiVersion:
|
||||
type: string
|
||||
kind:
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
type: object
|
||||
required:
|
||||
- displayName
|
||||
properties:
|
||||
displayName:
|
||||
type: string
|
||||
description: Human-readable tenant name.
|
||||
packages:
|
||||
type: array
|
||||
description: Enabled package IDs from the catalog.
|
||||
items:
|
||||
type: string
|
||||
agentId:
|
||||
type: string
|
||||
description: OpenClaw agent identifier. Defaults to "assistant".
|
||||
agentName:
|
||||
type: string
|
||||
description: Display name of the agent. Defaults to "Assistant".
|
||||
storageSize:
|
||||
type: string
|
||||
description: PVC size for OpenClaw workspace. Defaults to "5Gi".
|
||||
workspaceFiles:
|
||||
type: object
|
||||
description: >
|
||||
MD files seeded into the agent workspace on first boot.
|
||||
Keys are filenames (SOUL.md, AGENTS.md, TOOLS.md), values are content.
|
||||
Seeded once — runtime mutations persist on PVC.
|
||||
additionalProperties:
|
||||
type: string
|
||||
suspend:
|
||||
type: boolean
|
||||
description: Stops reconciliation without deleting resources.
|
||||
status:
|
||||
type: object
|
||||
properties:
|
||||
conditions:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
type:
|
||||
type: string
|
||||
status:
|
||||
type: string
|
||||
lastTransitionTime:
|
||||
type: string
|
||||
format: date-time
|
||||
reason:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
required:
|
||||
- type
|
||||
- status
|
||||
- lastTransitionTime
|
||||
- reason
|
||||
phase:
|
||||
type: string
|
||||
tenantNamespace:
|
||||
type: string
|
||||
litellmTeamId:
|
||||
type: string
|
||||
enabledPackages:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
observedGeneration:
|
||||
type: integer
|
||||
format: int64
|
||||
64
deploy/helm/pieced-operator/templates/deployment.yaml
Normal file
64
deploy/helm/pieced-operator/templates/deployment.yaml
Normal file
@@ -0,0 +1,64 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: pieced-operator
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: pieced-operator
|
||||
spec:
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: pieced-operator
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: pieced-operator
|
||||
spec:
|
||||
serviceAccountName: {{ .Values.serviceAccount.name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 8 }}
|
||||
automountServiceAccountToken: true # Required for K8s API + Vault K8s auth
|
||||
containers:
|
||||
- name: operator
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
args:
|
||||
- --vault-addr={{ .Values.config.vault.address }}
|
||||
- --vault-role={{ .Values.config.vault.role }}
|
||||
- --vault-auth-path={{ .Values.config.vault.authPath }}
|
||||
- --litellm-url={{ .Values.config.litellm.url }}
|
||||
- --metrics-bind-address=:8080
|
||||
- --health-probe-bind-address=:8081
|
||||
{{- if .Values.leaderElection.enabled }}
|
||||
# Leader election is built into the manager
|
||||
{{- end }}
|
||||
env:
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
ports:
|
||||
- name: metrics
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
- name: health
|
||||
containerPort: 8081
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: health
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: health
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
securityContext:
|
||||
{{- toYaml .Values.containerSecurityContext | nindent 12 }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
terminationGracePeriodSeconds: 10
|
||||
62
deploy/helm/pieced-operator/templates/network-policy.yaml
Normal file
62
deploy/helm/pieced-operator/templates/network-policy.yaml
Normal file
@@ -0,0 +1,62 @@
|
||||
{{- if .Values.networkPolicy.enabled }}
|
||||
# Network isolation for the operator itself.
|
||||
# Restricts egress to only the services it needs: K8s API, OpenBao, LiteLLM, DNS.
|
||||
# No ingress is needed except for metrics scraping (optional).
|
||||
apiVersion: cilium.io/v2
|
||||
kind: CiliumNetworkPolicy
|
||||
metadata:
|
||||
name: pieced-operator-egress
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: pieced-operator
|
||||
spec:
|
||||
endpointSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: pieced-operator
|
||||
egress:
|
||||
# DNS resolution
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name: kube-system
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "53"
|
||||
protocol: UDP
|
||||
- port: "53"
|
||||
protocol: TCP
|
||||
|
||||
# Kubernetes API server (for controller-runtime)
|
||||
- toEntities:
|
||||
- kube-apiserver
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "6443"
|
||||
protocol: TCP
|
||||
|
||||
# OpenBao (policy/role management, secret read/write)
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name: openbao
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8200"
|
||||
protocol: TCP
|
||||
|
||||
# LiteLLM (team/key provisioning)
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name: inference
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "4000"
|
||||
protocol: TCP
|
||||
ingress:
|
||||
# Allow Prometheus scraping metrics (optional, from monitoring namespace)
|
||||
- fromEndpoints:
|
||||
- matchLabels:
|
||||
k8s:io.cilium.k8s.namespace.labels.kubernetes.io/metadata.name: monitoring
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8080"
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
80
deploy/helm/pieced-operator/templates/rbac.yaml
Normal file
80
deploy/helm/pieced-operator/templates/rbac.yaml
Normal file
@@ -0,0 +1,80 @@
|
||||
# RBAC: Minimal permissions for the pieced-operator.
|
||||
# Each rule is scoped to only what the controller actually needs.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: pieced-operator
|
||||
labels:
|
||||
app.kubernetes.io/name: pieced-operator
|
||||
rules:
|
||||
# --- PiecedTenant CRD ---
|
||||
- apiGroups: ["pieced.ch"]
|
||||
resources: ["piecedtenants"]
|
||||
verbs: ["get", "list", "watch", "update", "patch"]
|
||||
- apiGroups: ["pieced.ch"]
|
||||
resources: ["piecedtenants/status"]
|
||||
verbs: ["get", "update", "patch"]
|
||||
- apiGroups: ["pieced.ch"]
|
||||
resources: ["piecedtenants/finalizers"]
|
||||
verbs: ["update"]
|
||||
|
||||
# --- Namespaces (tenant namespaces) ---
|
||||
- apiGroups: [""]
|
||||
resources: ["namespaces"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "delete"]
|
||||
|
||||
# --- ConfigMaps (workspace seed + catalog) ---
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "delete"]
|
||||
|
||||
# --- Events (controller status reporting) ---
|
||||
- apiGroups: [""]
|
||||
resources: ["events"]
|
||||
verbs: ["create", "patch"]
|
||||
|
||||
# --- Capsule Tenant ---
|
||||
- apiGroups: ["capsule.clastix.io"]
|
||||
resources: ["tenants"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "delete"]
|
||||
|
||||
# --- ESO SecretStore ---
|
||||
- apiGroups: ["external-secrets.io"]
|
||||
resources: ["secretstores"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "delete"]
|
||||
|
||||
# --- ESO ExternalSecret ---
|
||||
- apiGroups: ["external-secrets.io"]
|
||||
resources: ["externalsecrets"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "delete"]
|
||||
|
||||
# --- Cilium CiliumNetworkPolicy ---
|
||||
- apiGroups: ["cilium.io"]
|
||||
resources: ["ciliumnetworkpolicies"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "delete"]
|
||||
|
||||
# --- OpenClaw OpenClawInstance ---
|
||||
- apiGroups: ["openclaw.rocks"]
|
||||
resources: ["openclawinstances"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "delete"]
|
||||
|
||||
# --- Leader election (coordination) ---
|
||||
- apiGroups: ["coordination.k8s.io"]
|
||||
resources: ["leases"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: pieced-operator
|
||||
labels:
|
||||
app.kubernetes.io/name: pieced-operator
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: pieced-operator
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .Values.serviceAccount.name }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
12
deploy/helm/pieced-operator/templates/serviceaccount.yaml
Normal file
12
deploy/helm/pieced-operator/templates/serviceaccount.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .Values.serviceAccount.name }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: pieced-operator
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
Reference in New Issue
Block a user