Merge pull request 'Remove GCP stage environment' (#7) from chore/remove-gcp-stage into main
This commit is contained in:
@@ -357,111 +357,3 @@ resource "google_cloud_run_v2_service" "prod_apac" {
|
||||
depends_on = [google_project_iam_member.marketing_secret_accessor]
|
||||
}
|
||||
|
||||
# ── Stage — us-central1 ───────────────────────────────────────────────────────
|
||||
# min_instances=0 to save cost on staging.
|
||||
# Cloudflare Access handles auth in front; Cloud Run itself is open so the LB
|
||||
# health checks pass without credentials.
|
||||
|
||||
resource "google_cloud_run_v2_service" "stage" {
|
||||
name = "marketing-stage"
|
||||
location = "us-central1"
|
||||
project = var.project_id
|
||||
|
||||
ingress = "INGRESS_TRAFFIC_ALL"
|
||||
|
||||
labels = merge(local.run_labels, {
|
||||
"environment" = "stage"
|
||||
})
|
||||
|
||||
template {
|
||||
service_account = google_service_account.marketing.email
|
||||
|
||||
scaling {
|
||||
min_instance_count = 0
|
||||
max_instance_count = 10
|
||||
}
|
||||
|
||||
containers {
|
||||
image = local.image
|
||||
|
||||
resources {
|
||||
limits = {
|
||||
cpu = "1"
|
||||
memory = "512Mi"
|
||||
}
|
||||
cpu_idle = true
|
||||
}
|
||||
|
||||
env {
|
||||
name = "NODE_ENV"
|
||||
value = "production"
|
||||
}
|
||||
env {
|
||||
name = "NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY"
|
||||
value = local.stripe_publishable_key
|
||||
}
|
||||
|
||||
env {
|
||||
name = "STRIPE_SECRET_KEY"
|
||||
value_source {
|
||||
secret_key_ref {
|
||||
secret = "stripe-secret-key"
|
||||
version = "latest"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "STRIPE_WEBHOOK_SECRET"
|
||||
value_source {
|
||||
secret_key_ref {
|
||||
secret = "stripe-webhook-secret"
|
||||
version = "latest"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "STRIPE_PRICE_PROFESSIONAL"
|
||||
value_source {
|
||||
secret_key_ref {
|
||||
secret = "stripe-price-professional"
|
||||
version = "latest"
|
||||
}
|
||||
}
|
||||
}
|
||||
env {
|
||||
name = "STRIPE_PRICE_FOUNDING"
|
||||
value_source {
|
||||
secret_key_ref {
|
||||
secret = "stripe-price-founding"
|
||||
version = "latest"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ports {
|
||||
container_port = 3000
|
||||
name = "http1"
|
||||
}
|
||||
|
||||
startup_probe {
|
||||
http_get {
|
||||
path = "/api/health"
|
||||
port = 3000
|
||||
}
|
||||
initial_delay_seconds = 10
|
||||
timeout_seconds = 5
|
||||
period_seconds = 10
|
||||
failure_threshold = 5
|
||||
}
|
||||
}
|
||||
|
||||
max_instance_request_concurrency = 1000
|
||||
}
|
||||
|
||||
traffic {
|
||||
type = "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST"
|
||||
percent = 100
|
||||
}
|
||||
|
||||
depends_on = [google_project_iam_member.marketing_secret_accessor]
|
||||
}
|
||||
|
||||
@@ -35,17 +35,6 @@ resource "google_compute_region_network_endpoint_group" "prod_apac" {
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_region_network_endpoint_group" "stage" {
|
||||
name = "marketing-neg-stage"
|
||||
network_endpoint_type = "SERVERLESS"
|
||||
region = "us-central1"
|
||||
project = var.project_id
|
||||
|
||||
cloud_run {
|
||||
service = google_cloud_run_v2_service.stage.name
|
||||
}
|
||||
}
|
||||
|
||||
# ── Cloud Armor Security Policy ───────────────────────────────────────────────
|
||||
# Applied to the backend service. Rules evaluated top-down (lowest priority wins).
|
||||
|
||||
@@ -173,30 +162,6 @@ resource "google_compute_backend_service" "prod" {
|
||||
}
|
||||
}
|
||||
|
||||
# ── Stage Backend Service ─────────────────────────────────────────────────────
|
||||
|
||||
resource "google_compute_backend_service" "stage" {
|
||||
name = "marketing-backend-stage"
|
||||
project = var.project_id
|
||||
load_balancing_scheme = "EXTERNAL_MANAGED"
|
||||
protocol = "HTTPS"
|
||||
timeout_sec = 30
|
||||
|
||||
# Cloud Armor on stage too
|
||||
security_policy = google_compute_security_policy.marketing.self_link
|
||||
|
||||
enable_cdn = false # CDN off for stage — we want fresh responses always
|
||||
|
||||
backend {
|
||||
group = google_compute_region_network_endpoint_group.stage.self_link
|
||||
}
|
||||
|
||||
log_config {
|
||||
enable = true
|
||||
sample_rate = 1.0
|
||||
}
|
||||
}
|
||||
|
||||
# ── SSL Certificates ──────────────────────────────────────────────────────────
|
||||
# google_compute_managed_ssl_certificate — Google-managed, auto-renewed.
|
||||
# Provisioning requires DNS A records pointing to the LB IP (chicken-and-egg:
|
||||
@@ -214,15 +179,6 @@ resource "google_compute_managed_ssl_certificate" "prod" {
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_managed_ssl_certificate" "stage" {
|
||||
name = "marketing-cert-stage"
|
||||
project = var.project_id
|
||||
|
||||
managed {
|
||||
domains = ["stage.neurontechnologies.ai"]
|
||||
}
|
||||
}
|
||||
|
||||
# ── Prod URL Map — host-based routing ────────────────────────────────────────
|
||||
# One global IP handles all three services via Host header routing.
|
||||
# - neurontechnologies.ai / www. → marketing (default)
|
||||
@@ -324,64 +280,3 @@ resource "google_compute_global_forwarding_rule" "prod_http" {
|
||||
load_balancing_scheme = "EXTERNAL_MANAGED"
|
||||
}
|
||||
|
||||
# ── Stage URL Map ─────────────────────────────────────────────────────────────
|
||||
|
||||
resource "google_compute_url_map" "stage" {
|
||||
name = "marketing-urlmap-stage"
|
||||
project = var.project_id
|
||||
default_service = google_compute_backend_service.stage.self_link
|
||||
}
|
||||
|
||||
# ── Stage HTTPS Target Proxy ──────────────────────────────────────────────────
|
||||
|
||||
resource "google_compute_target_https_proxy" "stage" {
|
||||
name = "marketing-https-proxy-stage"
|
||||
project = var.project_id
|
||||
url_map = google_compute_url_map.stage.self_link
|
||||
ssl_certificates = [google_compute_managed_ssl_certificate.stage.self_link]
|
||||
}
|
||||
|
||||
# ── Stage HTTP → HTTPS redirect ───────────────────────────────────────────────
|
||||
|
||||
resource "google_compute_url_map" "stage_http_redirect" {
|
||||
name = "marketing-urlmap-stage-http-redirect"
|
||||
project = var.project_id
|
||||
|
||||
default_url_redirect {
|
||||
https_redirect = true
|
||||
redirect_response_code = "MOVED_PERMANENTLY_DEFAULT"
|
||||
strip_query = false
|
||||
}
|
||||
}
|
||||
|
||||
resource "google_compute_target_http_proxy" "stage" {
|
||||
name = "marketing-http-proxy-stage"
|
||||
project = var.project_id
|
||||
url_map = google_compute_url_map.stage_http_redirect.self_link
|
||||
}
|
||||
|
||||
# ── Stage Global Forwarding Rules ─────────────────────────────────────────────
|
||||
# Separate global IP for stage so DNS is independent.
|
||||
|
||||
resource "google_compute_global_address" "stage" {
|
||||
name = "marketing-ip-stage"
|
||||
project = var.project_id
|
||||
}
|
||||
|
||||
resource "google_compute_global_forwarding_rule" "stage_https" {
|
||||
name = "marketing-fwd-stage-https"
|
||||
project = var.project_id
|
||||
target = google_compute_target_https_proxy.stage.self_link
|
||||
ip_address = google_compute_global_address.stage.address
|
||||
port_range = "443"
|
||||
load_balancing_scheme = "EXTERNAL_MANAGED"
|
||||
}
|
||||
|
||||
resource "google_compute_global_forwarding_rule" "stage_http" {
|
||||
name = "marketing-fwd-stage-http"
|
||||
project = var.project_id
|
||||
target = google_compute_target_http_proxy.stage.self_link
|
||||
ip_address = google_compute_global_address.stage.address
|
||||
port_range = "80"
|
||||
load_balancing_scheme = "EXTERNAL_MANAGED"
|
||||
}
|
||||
|
||||
@@ -7,19 +7,12 @@
|
||||
# www.neurontechnologies.ai → prod_lb_ip
|
||||
# api.neurontechnologies.ai → prod_lb_ip
|
||||
# accounts.neurontechnologies.ai → prod_lb_ip
|
||||
#
|
||||
# Stage: stage.neurontechnologies.ai → stage_lb_ip (separate IP)
|
||||
|
||||
output "prod_lb_ip" {
|
||||
description = "Global anycast IP for all prod services (marketing, accounts, api)"
|
||||
value = google_compute_global_address.prod.address
|
||||
}
|
||||
|
||||
output "stage_lb_ip" {
|
||||
description = "Global anycast IP for the staging load balancer"
|
||||
value = google_compute_global_address.stage.address
|
||||
}
|
||||
|
||||
output "prod_ssl_cert_name" {
|
||||
description = "Marketing SSL cert (check provisioning status in GCP console)"
|
||||
value = google_compute_managed_ssl_certificate.prod.name
|
||||
@@ -35,11 +28,6 @@ output "api_ssl_cert_name" {
|
||||
value = google_compute_managed_ssl_certificate.api.name
|
||||
}
|
||||
|
||||
output "stage_ssl_cert_name" {
|
||||
description = "Stage SSL cert"
|
||||
value = google_compute_managed_ssl_certificate.stage.name
|
||||
}
|
||||
|
||||
output "marketing_service_account_email" {
|
||||
description = "Marketing Cloud Run SA"
|
||||
value = google_service_account.marketing.email
|
||||
@@ -76,7 +64,6 @@ output "cloud_run_services" {
|
||||
marketing_us = google_cloud_run_v2_service.prod_us.uri
|
||||
marketing_eu = google_cloud_run_v2_service.prod_eu.uri
|
||||
marketing_apac = google_cloud_run_v2_service.prod_apac.uri
|
||||
marketing_stage = google_cloud_run_v2_service.stage.uri
|
||||
accounts_us = google_cloud_run_v2_service.accounts_us.uri
|
||||
accounts_eu = google_cloud_run_v2_service.accounts_eu.uri
|
||||
accounts_apac = google_cloud_run_v2_service.accounts_apac.uri
|
||||
|
||||
@@ -79,15 +79,6 @@ resource "google_cloud_run_v2_service_iam_member" "prod_apac_public" {
|
||||
member = "allUsers"
|
||||
}
|
||||
|
||||
resource "google_cloud_run_v2_service_iam_member" "stage_public" {
|
||||
project = var.project_id
|
||||
location = "us-central1"
|
||||
name = google_cloud_run_v2_service.stage.name
|
||||
role = "roles/run.invoker"
|
||||
member = "allUsers"
|
||||
# Note: Cloudflare Access enforces auth in front of stage.
|
||||
}
|
||||
|
||||
# Accounts
|
||||
resource "google_cloud_run_v2_service_iam_member" "accounts_us_public" {
|
||||
project = var.project_id
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: neuron-swarm
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: http://10.43.1.53:3000/will/infrastructure.git
|
||||
targetRevision: main
|
||||
path: servers/legion/k8s/neuron-technologies/swarm
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
# No single namespace — resources span swarm-alpha/beta/gamma.
|
||||
# Each resource declares its own namespace.
|
||||
namespace: swarm-alpha
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
# Don't track Jobs created dynamically by swarm.sh
|
||||
ignoreDifferences:
|
||||
- group: batch
|
||||
kind: Job
|
||||
namespace: swarm-alpha
|
||||
jsonPointers: [""]
|
||||
- group: batch
|
||||
kind: Job
|
||||
namespace: swarm-beta
|
||||
jsonPointers: [""]
|
||||
- group: batch
|
||||
kind: Job
|
||||
namespace: swarm-gamma
|
||||
jsonPointers: [""]
|
||||
# Session ConfigMaps are created/deleted by swarm.sh — ignore drift
|
||||
- group: ""
|
||||
kind: ConfigMap
|
||||
name: swarm-alpha-session
|
||||
namespace: swarm-alpha
|
||||
jsonPointers: [""]
|
||||
- group: ""
|
||||
kind: ConfigMap
|
||||
name: swarm-beta-session
|
||||
namespace: swarm-beta
|
||||
jsonPointers: [""]
|
||||
- group: ""
|
||||
kind: ConfigMap
|
||||
name: swarm-gamma-session
|
||||
namespace: swarm-gamma
|
||||
jsonPointers: [""]
|
||||
@@ -0,0 +1,48 @@
|
||||
# Swarm variant ConfigMaps — base config per variant
|
||||
# The swarm-{variant}-session ConfigMap is created dynamically by swarm.sh
|
||||
# at session start and deleted at session end.
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: swarm-alpha-config
|
||||
namespace: swarm-alpha
|
||||
data:
|
||||
SPRING_PROFILES_ACTIVE: "swarm"
|
||||
NEURON_DATA_DIR: "/data"
|
||||
NEURON_DB_PATH: "/data/neuron.db"
|
||||
NEURON_STORAGE_PATH: "/data"
|
||||
SERVER_TOMCAT_ACCESSLOG_ENABLED: "true"
|
||||
MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: "health,info,metrics"
|
||||
MANAGEMENT_ENDPOINT_HEALTH_SHOW_DETAILS: "always"
|
||||
MANAGEMENT_OTLP_METRICS_EXPORT_ENABLED: "false"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: swarm-beta-config
|
||||
namespace: swarm-beta
|
||||
data:
|
||||
SPRING_PROFILES_ACTIVE: "swarm"
|
||||
NEURON_DATA_DIR: "/data"
|
||||
NEURON_DB_PATH: "/data/neuron.db"
|
||||
NEURON_STORAGE_PATH: "/data"
|
||||
SERVER_TOMCAT_ACCESSLOG_ENABLED: "true"
|
||||
MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: "health,info,metrics"
|
||||
MANAGEMENT_ENDPOINT_HEALTH_SHOW_DETAILS: "always"
|
||||
MANAGEMENT_OTLP_METRICS_EXPORT_ENABLED: "false"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: swarm-gamma-config
|
||||
namespace: swarm-gamma
|
||||
data:
|
||||
SPRING_PROFILES_ACTIVE: "swarm"
|
||||
NEURON_DATA_DIR: "/data"
|
||||
NEURON_DB_PATH: "/data/neuron.db"
|
||||
NEURON_STORAGE_PATH: "/data"
|
||||
SERVER_TOMCAT_ACCESSLOG_ENABLED: "true"
|
||||
MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE: "health,info,metrics"
|
||||
MANAGEMENT_ENDPOINT_HEALTH_SHOW_DETAILS: "always"
|
||||
MANAGEMENT_OTLP_METRICS_EXPORT_ENABLED: "false"
|
||||
@@ -0,0 +1,155 @@
|
||||
# Swarm variants share the same secrets as prod.
|
||||
# Each variant gets its own ExternalSecret object pointing at the same Vault paths.
|
||||
---
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: swarm-alpha-secrets
|
||||
namespace: swarm-alpha
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
name: vault
|
||||
kind: ClusterSecretStore
|
||||
target:
|
||||
name: swarm-alpha-secrets
|
||||
creationPolicy: Owner
|
||||
data:
|
||||
- secretKey: NEURON_API_KEY
|
||||
remoteRef:
|
||||
key: secret/data/neuron-technologies/prod
|
||||
property: api_key
|
||||
- secretKey: NEURON_WEBHOOK_SECRET
|
||||
remoteRef:
|
||||
key: secret/data/neuron-technologies/prod
|
||||
property: gitea_webhook_secret
|
||||
- secretKey: NEURON_LICENSE_ADMIN_TOKEN
|
||||
remoteRef:
|
||||
key: secret/data/neuron-technologies/license
|
||||
property: admin_token
|
||||
- secretKey: UNKEY_ROOT_KEY
|
||||
remoteRef:
|
||||
key: secret/data/neuron-technologies/unkey
|
||||
property: root_key
|
||||
- secretKey: UNKEY_API_ID
|
||||
remoteRef:
|
||||
key: secret/data/neuron-technologies/unkey
|
||||
property: api_id
|
||||
- secretKey: NEURON_R2_ENDPOINT
|
||||
remoteRef:
|
||||
key: secret/data/r2
|
||||
property: endpoint
|
||||
- secretKey: NEURON_R2_ACCESS_KEY
|
||||
remoteRef:
|
||||
key: secret/data/r2
|
||||
property: access_key_id
|
||||
- secretKey: NEURON_R2_SECRET_KEY
|
||||
remoteRef:
|
||||
key: secret/data/r2
|
||||
property: secret_access_key
|
||||
- secretKey: NEURON_R2_BUCKET
|
||||
remoteRef:
|
||||
key: secret/data/r2
|
||||
property: neuron_bucket
|
||||
---
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: swarm-beta-secrets
|
||||
namespace: swarm-beta
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
name: vault
|
||||
kind: ClusterSecretStore
|
||||
target:
|
||||
name: swarm-beta-secrets
|
||||
creationPolicy: Owner
|
||||
data:
|
||||
- secretKey: NEURON_API_KEY
|
||||
remoteRef:
|
||||
key: secret/data/neuron-technologies/prod
|
||||
property: api_key
|
||||
- secretKey: NEURON_WEBHOOK_SECRET
|
||||
remoteRef:
|
||||
key: secret/data/neuron-technologies/prod
|
||||
property: gitea_webhook_secret
|
||||
- secretKey: NEURON_LICENSE_ADMIN_TOKEN
|
||||
remoteRef:
|
||||
key: secret/data/neuron-technologies/license
|
||||
property: admin_token
|
||||
- secretKey: UNKEY_ROOT_KEY
|
||||
remoteRef:
|
||||
key: secret/data/neuron-technologies/unkey
|
||||
property: root_key
|
||||
- secretKey: UNKEY_API_ID
|
||||
remoteRef:
|
||||
key: secret/data/neuron-technologies/unkey
|
||||
property: api_id
|
||||
- secretKey: NEURON_R2_ENDPOINT
|
||||
remoteRef:
|
||||
key: secret/data/r2
|
||||
property: endpoint
|
||||
- secretKey: NEURON_R2_ACCESS_KEY
|
||||
remoteRef:
|
||||
key: secret/data/r2
|
||||
property: access_key_id
|
||||
- secretKey: NEURON_R2_SECRET_KEY
|
||||
remoteRef:
|
||||
key: secret/data/r2
|
||||
property: secret_access_key
|
||||
- secretKey: NEURON_R2_BUCKET
|
||||
remoteRef:
|
||||
key: secret/data/r2
|
||||
property: neuron_bucket
|
||||
---
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: swarm-gamma-secrets
|
||||
namespace: swarm-gamma
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
name: vault
|
||||
kind: ClusterSecretStore
|
||||
target:
|
||||
name: swarm-gamma-secrets
|
||||
creationPolicy: Owner
|
||||
data:
|
||||
- secretKey: NEURON_API_KEY
|
||||
remoteRef:
|
||||
key: secret/data/neuron-technologies/prod
|
||||
property: api_key
|
||||
- secretKey: NEURON_WEBHOOK_SECRET
|
||||
remoteRef:
|
||||
key: secret/data/neuron-technologies/prod
|
||||
property: gitea_webhook_secret
|
||||
- secretKey: NEURON_LICENSE_ADMIN_TOKEN
|
||||
remoteRef:
|
||||
key: secret/data/neuron-technologies/license
|
||||
property: admin_token
|
||||
- secretKey: UNKEY_ROOT_KEY
|
||||
remoteRef:
|
||||
key: secret/data/neuron-technologies/unkey
|
||||
property: root_key
|
||||
- secretKey: UNKEY_API_ID
|
||||
remoteRef:
|
||||
key: secret/data/neuron-technologies/unkey
|
||||
property: api_id
|
||||
- secretKey: NEURON_R2_ENDPOINT
|
||||
remoteRef:
|
||||
key: secret/data/r2
|
||||
property: endpoint
|
||||
- secretKey: NEURON_R2_ACCESS_KEY
|
||||
remoteRef:
|
||||
key: secret/data/r2
|
||||
property: access_key_id
|
||||
- secretKey: NEURON_R2_SECRET_KEY
|
||||
remoteRef:
|
||||
key: secret/data/r2
|
||||
property: secret_access_key
|
||||
- secretKey: NEURON_R2_BUCKET
|
||||
remoteRef:
|
||||
key: secret/data/r2
|
||||
property: neuron_bucket
|
||||
@@ -0,0 +1,30 @@
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
resources:
|
||||
# Namespaces
|
||||
- namespace-alpha.yaml
|
||||
- namespace-beta.yaml
|
||||
- namespace-gamma.yaml
|
||||
# Persistent volumes
|
||||
- pvc-alpha.yaml
|
||||
- pvc-beta.yaml
|
||||
- pvc-gamma.yaml
|
||||
# Base config
|
||||
- configmaps.yaml
|
||||
# Shared secrets from Vault
|
||||
- externalsecrets.yaml
|
||||
# MCP deployments
|
||||
- mcp-deployment-alpha.yaml
|
||||
- mcp-deployment-beta.yaml
|
||||
- mcp-deployment-gamma.yaml
|
||||
# REST deployments
|
||||
- rest-deployment-alpha.yaml
|
||||
- rest-deployment-beta.yaml
|
||||
- rest-deployment-gamma.yaml
|
||||
# Services
|
||||
- services.yaml
|
||||
# RBAC for CI runner
|
||||
- rbac.yaml
|
||||
# SQLite clone Jobs (applied by swarm.sh at session start, not auto-synced by ArgoCD)
|
||||
# These are listed here for reference but excluded from ArgoCD automated sync
|
||||
# via the ignoreDifferences config in the ArgoCD app.
|
||||
@@ -0,0 +1,121 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: neuron-mcp
|
||||
namespace: swarm-alpha
|
||||
labels:
|
||||
app: neuron-mcp
|
||||
env: swarm
|
||||
variant: alpha
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: neuron-mcp
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: neuron-mcp
|
||||
env: swarm
|
||||
variant: alpha
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 30
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
initContainers:
|
||||
- name: wait-for-sqlite-clone
|
||||
image: busybox:1.36
|
||||
command: ["sh", "-c", "until [ -f /data/neuron.db ]; do echo 'waiting for SQLite clone...'; sleep 2; done; echo 'SQLite ready'"]
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
containers:
|
||||
- name: neuron-mcp
|
||||
# Image is updated by swarm CI on each loop iteration
|
||||
image: registry.neuralplatform.ai/neuron-technologies/neuron-mcp:v0.15.3
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: false
|
||||
runAsNonRoot: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
env:
|
||||
- name: NEURON_SWARM_VARIANT
|
||||
value: "alpha"
|
||||
- name: NEURON_SWARM_SESSION
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-alpha-session
|
||||
key: session_id
|
||||
optional: true
|
||||
- name: NEURON_SWARM_GOAL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-alpha-session
|
||||
key: goal
|
||||
optional: true
|
||||
- name: NEURON_SWARM_LOOP_MAX
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-alpha-session
|
||||
key: loop_max
|
||||
optional: true
|
||||
- name: OTEL_EXPORTER_OTLP_ENDPOINT
|
||||
value: "http://alloy-otlp.monitoring.svc.cluster.local:4318"
|
||||
- name: JAVA_TOOL_OPTIONS
|
||||
value: "-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+ExitOnOutOfMemoryError"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: swarm-alpha-config
|
||||
- secretRef:
|
||||
name: swarm-alpha-secrets
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: 1500m
|
||||
memory: 1536Mi
|
||||
lifecycle:
|
||||
preStop:
|
||||
exec:
|
||||
command: ["sh", "-c", "sleep 5"]
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/liveness
|
||||
port: http
|
||||
failureThreshold: 30
|
||||
periodSeconds: 5
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/liveness
|
||||
port: http
|
||||
periodSeconds: 30
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/readiness
|
||||
port: http
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
failureThreshold: 3
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: swarm-alpha-data
|
||||
@@ -0,0 +1,120 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: neuron-mcp
|
||||
namespace: swarm-beta
|
||||
labels:
|
||||
app: neuron-mcp
|
||||
env: swarm
|
||||
variant: beta
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: neuron-mcp
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: neuron-mcp
|
||||
env: swarm
|
||||
variant: beta
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 30
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
initContainers:
|
||||
- name: wait-for-sqlite-clone
|
||||
image: busybox:1.36
|
||||
command: ["sh", "-c", "until [ -f /data/neuron.db ]; do echo 'waiting for SQLite clone...'; sleep 2; done; echo 'SQLite ready'"]
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
containers:
|
||||
- name: neuron-mcp
|
||||
image: registry.neuralplatform.ai/neuron-technologies/neuron-mcp:v0.15.3
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: false
|
||||
runAsNonRoot: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
env:
|
||||
- name: NEURON_SWARM_VARIANT
|
||||
value: "beta"
|
||||
- name: NEURON_SWARM_SESSION
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-beta-session
|
||||
key: session_id
|
||||
optional: true
|
||||
- name: NEURON_SWARM_GOAL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-beta-session
|
||||
key: goal
|
||||
optional: true
|
||||
- name: NEURON_SWARM_LOOP_MAX
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-beta-session
|
||||
key: loop_max
|
||||
optional: true
|
||||
- name: OTEL_EXPORTER_OTLP_ENDPOINT
|
||||
value: "http://alloy-otlp.monitoring.svc.cluster.local:4318"
|
||||
- name: JAVA_TOOL_OPTIONS
|
||||
value: "-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+ExitOnOutOfMemoryError"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: swarm-beta-config
|
||||
- secretRef:
|
||||
name: swarm-beta-secrets
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: 1500m
|
||||
memory: 1536Mi
|
||||
lifecycle:
|
||||
preStop:
|
||||
exec:
|
||||
command: ["sh", "-c", "sleep 5"]
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/liveness
|
||||
port: http
|
||||
failureThreshold: 30
|
||||
periodSeconds: 5
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/liveness
|
||||
port: http
|
||||
periodSeconds: 30
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/readiness
|
||||
port: http
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
failureThreshold: 3
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: swarm-beta-data
|
||||
@@ -0,0 +1,120 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: neuron-mcp
|
||||
namespace: swarm-gamma
|
||||
labels:
|
||||
app: neuron-mcp
|
||||
env: swarm
|
||||
variant: gamma
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: neuron-mcp
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: neuron-mcp
|
||||
env: swarm
|
||||
variant: gamma
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 30
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
initContainers:
|
||||
- name: wait-for-sqlite-clone
|
||||
image: busybox:1.36
|
||||
command: ["sh", "-c", "until [ -f /data/neuron.db ]; do echo 'waiting for SQLite clone...'; sleep 2; done; echo 'SQLite ready'"]
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
containers:
|
||||
- name: neuron-mcp
|
||||
image: registry.neuralplatform.ai/neuron-technologies/neuron-mcp:v0.15.3
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: false
|
||||
runAsNonRoot: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
env:
|
||||
- name: NEURON_SWARM_VARIANT
|
||||
value: "gamma"
|
||||
- name: NEURON_SWARM_SESSION
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-gamma-session
|
||||
key: session_id
|
||||
optional: true
|
||||
- name: NEURON_SWARM_GOAL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-gamma-session
|
||||
key: goal
|
||||
optional: true
|
||||
- name: NEURON_SWARM_LOOP_MAX
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-gamma-session
|
||||
key: loop_max
|
||||
optional: true
|
||||
- name: OTEL_EXPORTER_OTLP_ENDPOINT
|
||||
value: "http://alloy-otlp.monitoring.svc.cluster.local:4318"
|
||||
- name: JAVA_TOOL_OPTIONS
|
||||
value: "-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+ExitOnOutOfMemoryError"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: swarm-gamma-config
|
||||
- secretRef:
|
||||
name: swarm-gamma-secrets
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: 1500m
|
||||
memory: 1536Mi
|
||||
lifecycle:
|
||||
preStop:
|
||||
exec:
|
||||
command: ["sh", "-c", "sleep 5"]
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/liveness
|
||||
port: http
|
||||
failureThreshold: 30
|
||||
periodSeconds: 5
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/liveness
|
||||
port: http
|
||||
periodSeconds: 30
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/readiness
|
||||
port: http
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
failureThreshold: 3
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: swarm-gamma-data
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: swarm-alpha
|
||||
labels:
|
||||
app: neuron-technologies
|
||||
tier: swarm
|
||||
variant: alpha
|
||||
managed-by: argocd
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: swarm-beta
|
||||
labels:
|
||||
app: neuron-technologies
|
||||
tier: swarm
|
||||
variant: beta
|
||||
managed-by: argocd
|
||||
@@ -0,0 +1,9 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: swarm-gamma
|
||||
labels:
|
||||
app: neuron-technologies
|
||||
tier: swarm
|
||||
variant: gamma
|
||||
managed-by: argocd
|
||||
@@ -0,0 +1,12 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: swarm-alpha-data
|
||||
namespace: swarm-alpha
|
||||
spec:
|
||||
storageClassName: local-path
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 20Gi
|
||||
@@ -0,0 +1,12 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: swarm-beta-data
|
||||
namespace: swarm-beta
|
||||
spec:
|
||||
storageClassName: local-path
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 20Gi
|
||||
@@ -0,0 +1,12 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: swarm-gamma-data
|
||||
namespace: swarm-gamma
|
||||
spec:
|
||||
storageClassName: local-path
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 20Gi
|
||||
@@ -0,0 +1,97 @@
|
||||
# RBAC for swarm variant namespaces
|
||||
# Grants the CI runner ServiceAccount permission to deploy to swarm-* namespaces.
|
||||
# Mirrors the pattern used for neuron-dev/stage deployments.
|
||||
# The CI runner runs in the `ci` namespace as the `default` ServiceAccount.
|
||||
---
|
||||
# swarm-alpha
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: swarm-deployer
|
||||
namespace: swarm-alpha
|
||||
rules:
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["deployments"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch"]
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps", "services", "pods", "pods/log"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
- apiGroups: ["batch"]
|
||||
resources: ["jobs"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: ci-runner-swarm-alpha
|
||||
namespace: swarm-alpha
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: default
|
||||
namespace: ci
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: swarm-deployer
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
---
|
||||
# swarm-beta
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: swarm-deployer
|
||||
namespace: swarm-beta
|
||||
rules:
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["deployments"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch"]
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps", "services", "pods", "pods/log"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
- apiGroups: ["batch"]
|
||||
resources: ["jobs"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: ci-runner-swarm-beta
|
||||
namespace: swarm-beta
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: default
|
||||
namespace: ci
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: swarm-deployer
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
---
|
||||
# swarm-gamma
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: swarm-deployer
|
||||
namespace: swarm-gamma
|
||||
rules:
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["deployments"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch"]
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps", "services", "pods", "pods/log"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
- apiGroups: ["batch"]
|
||||
resources: ["jobs"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: ci-runner-swarm-gamma
|
||||
namespace: swarm-gamma
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: default
|
||||
namespace: ci
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: swarm-deployer
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
@@ -0,0 +1,99 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: neuron-rest
|
||||
namespace: swarm-alpha
|
||||
labels:
|
||||
app: neuron-rest
|
||||
env: swarm
|
||||
variant: alpha
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: neuron-rest
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: neuron-rest
|
||||
env: swarm
|
||||
variant: alpha
|
||||
spec:
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: neuron-rest
|
||||
image: registry.neuralplatform.ai/neuron-technologies/neuron-rest:v0.15.3
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8081
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: false
|
||||
runAsNonRoot: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
env:
|
||||
- name: NEURON_SWARM_VARIANT
|
||||
value: "alpha"
|
||||
- name: NEURON_SWARM_SESSION
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-alpha-session
|
||||
key: session_id
|
||||
optional: true
|
||||
- name: NEURON_SWARM_GOAL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-alpha-session
|
||||
key: goal
|
||||
optional: true
|
||||
- name: NEURON_SWARM_LOOP_MAX
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-alpha-session
|
||||
key: loop_max
|
||||
optional: true
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: swarm-alpha-config
|
||||
- secretRef:
|
||||
name: swarm-alpha-secrets
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/liveness
|
||||
port: http
|
||||
failureThreshold: 30
|
||||
periodSeconds: 5
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/liveness
|
||||
port: http
|
||||
periodSeconds: 30
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/readiness
|
||||
port: http
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
failureThreshold: 3
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: swarm-alpha-data
|
||||
@@ -0,0 +1,99 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: neuron-rest
|
||||
namespace: swarm-beta
|
||||
labels:
|
||||
app: neuron-rest
|
||||
env: swarm
|
||||
variant: beta
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: neuron-rest
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: neuron-rest
|
||||
env: swarm
|
||||
variant: beta
|
||||
spec:
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: neuron-rest
|
||||
image: registry.neuralplatform.ai/neuron-technologies/neuron-rest:v0.15.3
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8081
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: false
|
||||
runAsNonRoot: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
env:
|
||||
- name: NEURON_SWARM_VARIANT
|
||||
value: "beta"
|
||||
- name: NEURON_SWARM_SESSION
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-beta-session
|
||||
key: session_id
|
||||
optional: true
|
||||
- name: NEURON_SWARM_GOAL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-beta-session
|
||||
key: goal
|
||||
optional: true
|
||||
- name: NEURON_SWARM_LOOP_MAX
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-beta-session
|
||||
key: loop_max
|
||||
optional: true
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: swarm-beta-config
|
||||
- secretRef:
|
||||
name: swarm-beta-secrets
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/liveness
|
||||
port: http
|
||||
failureThreshold: 30
|
||||
periodSeconds: 5
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/liveness
|
||||
port: http
|
||||
periodSeconds: 30
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/readiness
|
||||
port: http
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
failureThreshold: 3
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: swarm-beta-data
|
||||
@@ -0,0 +1,99 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: neuron-rest
|
||||
namespace: swarm-gamma
|
||||
labels:
|
||||
app: neuron-rest
|
||||
env: swarm
|
||||
variant: gamma
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app: neuron-rest
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: neuron-rest
|
||||
env: swarm
|
||||
variant: gamma
|
||||
spec:
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: neuron-rest
|
||||
image: registry.neuralplatform.ai/neuron-technologies/neuron-rest:v0.15.3
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8081
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: false
|
||||
runAsNonRoot: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
env:
|
||||
- name: NEURON_SWARM_VARIANT
|
||||
value: "gamma"
|
||||
- name: NEURON_SWARM_SESSION
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-gamma-session
|
||||
key: session_id
|
||||
optional: true
|
||||
- name: NEURON_SWARM_GOAL
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-gamma-session
|
||||
key: goal
|
||||
optional: true
|
||||
- name: NEURON_SWARM_LOOP_MAX
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: swarm-gamma-session
|
||||
key: loop_max
|
||||
optional: true
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: swarm-gamma-config
|
||||
- secretRef:
|
||||
name: swarm-gamma-secrets
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 1Gi
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/liveness
|
||||
port: http
|
||||
failureThreshold: 30
|
||||
periodSeconds: 5
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/liveness
|
||||
port: http
|
||||
periodSeconds: 30
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/readiness
|
||||
port: http
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
failureThreshold: 3
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: swarm-gamma-data
|
||||
@@ -0,0 +1,103 @@
|
||||
# Services for swarm variants — ClusterIP only, no external exposure needed
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: neuron-mcp
|
||||
namespace: swarm-alpha
|
||||
labels:
|
||||
app: neuron-mcp
|
||||
variant: alpha
|
||||
spec:
|
||||
selector:
|
||||
app: neuron-mcp
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: neuron-rest
|
||||
namespace: swarm-alpha
|
||||
labels:
|
||||
app: neuron-rest
|
||||
variant: alpha
|
||||
spec:
|
||||
selector:
|
||||
app: neuron-rest
|
||||
ports:
|
||||
- name: http
|
||||
port: 8081
|
||||
targetPort: 8081
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: neuron-mcp
|
||||
namespace: swarm-beta
|
||||
labels:
|
||||
app: neuron-mcp
|
||||
variant: beta
|
||||
spec:
|
||||
selector:
|
||||
app: neuron-mcp
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: neuron-rest
|
||||
namespace: swarm-beta
|
||||
labels:
|
||||
app: neuron-rest
|
||||
variant: beta
|
||||
spec:
|
||||
selector:
|
||||
app: neuron-rest
|
||||
ports:
|
||||
- name: http
|
||||
port: 8081
|
||||
targetPort: 8081
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: neuron-mcp
|
||||
namespace: swarm-gamma
|
||||
labels:
|
||||
app: neuron-mcp
|
||||
variant: gamma
|
||||
spec:
|
||||
selector:
|
||||
app: neuron-mcp
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
type: ClusterIP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: neuron-rest
|
||||
namespace: swarm-gamma
|
||||
labels:
|
||||
app: neuron-rest
|
||||
variant: gamma
|
||||
spec:
|
||||
selector:
|
||||
app: neuron-rest
|
||||
ports:
|
||||
- name: http
|
||||
port: 8081
|
||||
targetPort: 8081
|
||||
type: ClusterIP
|
||||
@@ -0,0 +1,66 @@
|
||||
# SQLite clone Job for swarm-alpha
|
||||
# Creates a snapshot of the prod neuron.db into swarm-alpha's PVC.
|
||||
# This Job is created by swarm.sh at session start; it is NOT static.
|
||||
# This file is the template — swarm.sh applies it via kubectl after substituting SESSION_ID.
|
||||
#
|
||||
# The Job mounts both the prod PVC (read-only) and the variant PVC (read-write).
|
||||
# It uses a simple cp to snapshot the database before the variant MCP starts.
|
||||
#
|
||||
# NOTE: The prod MCP must be scaled down to 0 OR the Job must use SQLite's backup API
|
||||
# (via sqlite3 .backup command) to ensure consistency. swarm.sh handles the hot-backup
|
||||
# approach using the sqlite3 CLI, so the prod pod does NOT need to stop.
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: sqlite-clone-alpha
|
||||
namespace: swarm-alpha
|
||||
labels:
|
||||
app: swarm-clone
|
||||
variant: alpha
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 3600
|
||||
backoffLimit: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: swarm-clone
|
||||
variant: alpha
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
securityContext:
|
||||
runAsNonRoot: false # sqlite3 needs to run as root to access both PVCs
|
||||
containers:
|
||||
- name: sqlite-clone
|
||||
image: keinos/sqlite3:latest
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
set -e
|
||||
echo "Starting SQLite hot-backup from prod to swarm-alpha..."
|
||||
# Use SQLite's .backup command for a consistent online backup
|
||||
sqlite3 /prod-data/neuron.db ".backup /variant-data/neuron.db"
|
||||
echo "Backup complete. Verifying..."
|
||||
sqlite3 /variant-data/neuron.db "PRAGMA integrity_check;"
|
||||
echo "SQLite clone complete for swarm-alpha."
|
||||
volumeMounts:
|
||||
- name: prod-data
|
||||
mountPath: /prod-data
|
||||
readOnly: true
|
||||
- name: variant-data
|
||||
mountPath: /variant-data
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
volumes:
|
||||
- name: prod-data
|
||||
persistentVolumeClaim:
|
||||
claimName: neuron-prod-data
|
||||
readOnly: true
|
||||
- name: variant-data
|
||||
persistentVolumeClaim:
|
||||
claimName: swarm-alpha-data
|
||||
@@ -0,0 +1,54 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: sqlite-clone-beta
|
||||
namespace: swarm-beta
|
||||
labels:
|
||||
app: swarm-clone
|
||||
variant: beta
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 3600
|
||||
backoffLimit: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: swarm-clone
|
||||
variant: beta
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
securityContext:
|
||||
runAsNonRoot: false
|
||||
containers:
|
||||
- name: sqlite-clone
|
||||
image: keinos/sqlite3:latest
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
set -e
|
||||
echo "Starting SQLite hot-backup from prod to swarm-beta..."
|
||||
sqlite3 /prod-data/neuron.db ".backup /variant-data/neuron.db"
|
||||
echo "Backup complete. Verifying..."
|
||||
sqlite3 /variant-data/neuron.db "PRAGMA integrity_check;"
|
||||
echo "SQLite clone complete for swarm-beta."
|
||||
volumeMounts:
|
||||
- name: prod-data
|
||||
mountPath: /prod-data
|
||||
readOnly: true
|
||||
- name: variant-data
|
||||
mountPath: /variant-data
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
volumes:
|
||||
- name: prod-data
|
||||
persistentVolumeClaim:
|
||||
claimName: neuron-prod-data
|
||||
readOnly: true
|
||||
- name: variant-data
|
||||
persistentVolumeClaim:
|
||||
claimName: swarm-beta-data
|
||||
@@ -0,0 +1,54 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: sqlite-clone-gamma
|
||||
namespace: swarm-gamma
|
||||
labels:
|
||||
app: swarm-clone
|
||||
variant: gamma
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 3600
|
||||
backoffLimit: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: swarm-clone
|
||||
variant: gamma
|
||||
spec:
|
||||
restartPolicy: OnFailure
|
||||
securityContext:
|
||||
runAsNonRoot: false
|
||||
containers:
|
||||
- name: sqlite-clone
|
||||
image: keinos/sqlite3:latest
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
set -e
|
||||
echo "Starting SQLite hot-backup from prod to swarm-gamma..."
|
||||
sqlite3 /prod-data/neuron.db ".backup /variant-data/neuron.db"
|
||||
echo "Backup complete. Verifying..."
|
||||
sqlite3 /variant-data/neuron.db "PRAGMA integrity_check;"
|
||||
echo "SQLite clone complete for swarm-gamma."
|
||||
volumeMounts:
|
||||
- name: prod-data
|
||||
mountPath: /prod-data
|
||||
readOnly: true
|
||||
- name: variant-data
|
||||
mountPath: /variant-data
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
volumes:
|
||||
- name: prod-data
|
||||
persistentVolumeClaim:
|
||||
claimName: neuron-prod-data
|
||||
readOnly: true
|
||||
- name: variant-data
|
||||
persistentVolumeClaim:
|
||||
claimName: swarm-gamma-data
|
||||
@@ -50,3 +50,43 @@ resource "kubernetes_namespace" "neuron_tim" {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Swarm variant namespaces — isolated execution environments for swarm self-improvement loops
|
||||
resource "kubernetes_namespace" "swarm_alpha" {
|
||||
metadata {
|
||||
name = "swarm-alpha"
|
||||
labels = {
|
||||
managed-by = "terraform"
|
||||
tier = "swarm"
|
||||
environment = "swarm"
|
||||
app = "neuron-technologies"
|
||||
variant = "alpha"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_namespace" "swarm_beta" {
|
||||
metadata {
|
||||
name = "swarm-beta"
|
||||
labels = {
|
||||
managed-by = "terraform"
|
||||
tier = "swarm"
|
||||
environment = "swarm"
|
||||
app = "neuron-technologies"
|
||||
variant = "beta"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "kubernetes_namespace" "swarm_gamma" {
|
||||
metadata {
|
||||
name = "swarm-gamma"
|
||||
labels = {
|
||||
managed-by = "terraform"
|
||||
tier = "swarm"
|
||||
environment = "swarm"
|
||||
app = "neuron-technologies"
|
||||
variant = "gamma"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user