diff --git a/.github/workflows/dark-factory.yml b/.github/workflows/dark-factory.yml new file mode 100644 index 0000000..8c9dddd --- /dev/null +++ b/.github/workflows/dark-factory.yml @@ -0,0 +1,75 @@ +# Dark Factory (Flow B) trigger β€” issue labeled `dark-factory` β†’ orchestrator. +# +# This is the P1 entrypoint (Β§4 step 1). It gates on the label, mints a +# short-TTL token scoped to this repo, and POSTs the run request to the +# orchestrator running on spoke-dev. The orchestrator (not this Action) holds +# the long-lived credentials and drives the sandbox; the Action's only job is +# to authenticate the trigger and hand over a short-lived token. +# +# The token here is the workflow's GITHUB_TOKEN (auto-expires when the run +# ends). For cross-repo / org installs, swap in a GitHub App token minted via +# actions/create-github-app-token β€” the orchestrator treats it the same way. +name: dark-factory + +on: + issues: + types: [labeled] + +# Least-privilege: the orchestrator opens the PR + updates the sticky comment +# using the token we pass, so it needs write on contents + PRs + issues. +permissions: + contents: write + pull-requests: write + issues: write + +jobs: + dispatch: + # Only fire when the `dark-factory` label is the one that was added. + if: github.event.label.name == 'dark-factory' + runs-on: ubuntu-latest + steps: + - name: Acknowledge on the issue + uses: actions/github-script@v7 + with: + script: | + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: '🏭 Dark Factory accepted this issue β€” claiming a sandbox on spoke-dev…', + }); + + - name: Dispatch to orchestrator + env: + # The orchestrator's ingress URL (private ALB / VPN-reachable). + # Configure as a repo/org variable; kept out of the workflow so the + # endpoint isn't hard-coded. + ORCHESTRATOR_URL: ${{ vars.DARK_FACTORY_ORCHESTRATOR_URL }} + # Shared secret so the orchestrator only accepts trusted triggers. + DISPATCH_TOKEN: ${{ secrets.DARK_FACTORY_DISPATCH_TOKEN }} + GH_TOKEN: ${{ github.token }} + ISSUE_NUMBER: ${{ github.event.issue.number }} + ISSUE_TITLE: ${{ github.event.issue.title }} + ISSUE_BODY: ${{ github.event.issue.body }} + REPO: ${{ github.repository }} + BASE: ${{ github.event.repository.default_branch }} + run: | + set -euo pipefail + if [ -z "${ORCHESTRATOR_URL:-}" ]; then + echo "::error::DARK_FACTORY_ORCHESTRATOR_URL is not set β€” cannot dispatch." + exit 1 + fi + # Build the JSON payload safely (jq handles escaping of title/body). + payload="$(jq -n \ + --arg issue "$ISSUE_NUMBER" \ + --arg repo "$REPO" \ + --arg title "$ISSUE_TITLE" \ + --arg body "$ISSUE_BODY" \ + --arg base "$BASE" \ + --arg ghToken "$GH_TOKEN" \ + '{issue: ($issue|tonumber), repo: $repo, title: $title, body: $body, base: $base, ghToken: $ghToken}')" + curl -fsS -X POST "$ORCHESTRATOR_URL/run" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer ${DISPATCH_TOKEN:-}" \ + -d "$payload" + echo "Dispatched issue #$ISSUE_NUMBER to the Dark Factory orchestrator." diff --git a/docs/dark-factory/README.md b/docs/dark-factory/README.md new file mode 100644 index 0000000..c0a39bb --- /dev/null +++ b/docs/dark-factory/README.md @@ -0,0 +1,499 @@ +# Dark Factory β€” Autonomous Agent Coding Pattern + +> **Status:** Design document (doc-only). This describes the target architecture, the reuse +> map onto the existing platform, and a phased delivery plan. No runtime code ships in this PR. + +A **dark factory** is a manufacturing plant that runs *with the lights off* β€” no humans on the +floor, robots do everything. Applied to software: **a human writes an issue (a spec); AI agents +do the rest** β€” implement, build, test, security/ops review, open a PR, and (after a human +approves the *results*) merge and tear everything down. + +This pattern wires that idea onto the **Open Agent Platform (OAP)** using components the platform +already has: hardware-isolated **Kata micro-VM sandboxes** (from `eks-platform-openclaw`), the +**Bifrost β†’ Bedrock** LLM gateway, the **hub + spoke-dev/spoke-prod** cluster fleet, and +**AWS-managed frontier agents** (Security, DevOps) for independent review. + +--- + +## Table of contents +1. [What is a Dark Factory](#1-what-is-a-dark-factory) +2. [Two flows at a glance](#2-two-flows-at-a-glance) +3. [Flow A β€” Agent Sandbox capability](#3-flow-a--agent-sandbox-capability-permanent-platform-feature) +4. [Flow B β€” the Dark Factory pipeline](#4-flow-b--the-dark-factory-pipeline) +5. [The pluggable coding assistant](#5-the-pluggable-coding-assistant) +6. [Independent verification](#6-independent-verification-the-heart-of-the-pattern) +7. [Live status in the PR](#7-live-status-in-the-pr) +8. [Human-in-the-loop & the comment loop](#8-human-in-the-loop--the-iterative-comment-loop) +9. [Lifecycle, teardown & cost](#9-lifecycle-teardown--cost) +10. [Security model](#10-security-model) +11. [Industry alignment & anti-patterns](#11-industry-alignment--anti-patterns-what-the-world-agrees-on) +12. [Phased delivery](#12-phased-delivery) +13. [Open questions / future work](#13-open-questions--future-work) +14. [References](#14-references) + +--- + +## 1. What is a Dark Factory + +The term is borrowed from manufacturing and popularized for coding by two sources this design +draws on: + +- **Steve Yegge β€” "Welcome to Gas City"**: a *supervisor plane* that deploys teams of + collaborating agents as composable "packs," where humans **watch the factory work** from a + rich console rather than typing code. Work is a first-class, versioned primitive. +- **HackerNoon β€” "The Dark Factory Pattern"**: an **autonomy-level** ladder and the key + engineering ideas β€” **specs instead of code**, **holdout scenarios** (the coding agent never + sees the acceptance tests; a separate evaluator judges), **build-before-push**, ephemeral + environments, and **humans reviewing results, not diffs**. + +### Autonomy levels (we target Level 3) + +| Level | What it looks like | +|------:|--------------------| +| 1 | AI finishes your sentences; you do everything else. | +| 2 | AI writes whole files; **you review every change**. | +| **3** | **AI generates code from a spec; a holdout gate + reviewers verify; you approve the merge.** ← *this design* | +| 3.5 | Some low-risk services auto-merge without you. | +| 4 | Full dark factory: specs in, merged tested code out. | + +At **Level 3**, the human's job shrinks from *"read every line of a diff"* to *"read the evidence +and click approve"* β€” but the human still gates the merge, and can drive changes via PR comments. + +--- + +## 2. Two flows at a glance + +This design is deliberately split into **two independent flows** so the sandbox capability is +useful on its own and the factory is a consumer of it. + +| | **Flow A β€” Agent Sandbox capability** | **Flow B β€” Dark Factory** | +|---|---|---| +| **What** | A permanent platform feature: Kata micro-VM sandboxes + `Sandbox` CRD + a **warm pool** kept ready | The autonomous coding pipeline: issue β†’ code β†’ test β†’ review β†’ PR β†’ merge β†’ teardown | +| **When** | Comes up automatically when the agent platform is deployed | Triggered per GitHub issue labeled `dark-factory` | +| **Where** | Installed on **spoke-dev *and* spoke-prod** (capability on both) | **Runs only on spoke-dev** (prod pool stays dormant) | +| **Lifecycle** | Long-lived; pool self-heals to a target buffer | Ephemeral per issue; torn down on merge/close | +| **Diagram** | [`diagrams/flow-a-sandbox-capability.md`](diagrams/flow-a-sandbox-capability.md) | [`diagrams/flow-b-dark-factory.md`](diagrams/flow-b-dark-factory.md) | + +> **Why split them?** The sandbox capability is generically useful (any agent workload can claim +> an isolated VM). The Dark Factory is one *consumer* of that capability. Keeping them separate +> means the isolation substrate can ship, be tested, and be reused independently of the factory. + +--- + +## 3. Flow A β€” Agent Sandbox capability (permanent platform feature) + +> πŸ“Š **See the fancy diagrams:** [`diagrams/flow-a-sandbox-capability.md`](diagrams/flow-a-sandbox-capability.md) +> (capability architecture + warm-pool state machine). + +Shipped as a GitOps addon, enabled exactly like every other platform addon β€” set a flag, an +ApplicationSet fans it onto the labelled clusters: + +```yaml +# gitops/overlays/environments/{dev,prod}/enabled-addons.yaml +enabledAddons: + enable_agent_sandbox: true # β†’ ApplicationSet cluster-generator β†’ ArgoCD sync waves +``` + +### What the addon installs (all reused from `eks-platform-openclaw`) + +| Piece | Source in `eks-platform-openclaw` | Role | +|---|---|---| +| **Kata runtime (Cloud Hypervisor default)** | `gitops/helm/kata/` + `kata-deploy` | Hardware VM isolation per sandbox | +| **RuntimeClasses** `kata-clh` Β· `kata-qemu` Β· `kata-fc` | `gitops/helm/kata/templates/runtimeclass-*.yaml` | Workload picks VMM via `runtimeClassName` | +| **Karpenter pools** `kata-nested` / `kata-metal` | `gitops/helm/karpenter-nodepools/` | Nested-virt `c8i/m8i` nodes (bare-metal fallback) | +| **`Sandbox` CRD + operator** (`agents.x-k8s.io/v1alpha1`) | `gitops/helm/agent-sandbox/` (sync-wave βˆ’1) | One Kata-VM pod per `Sandbox` CR; `replicas 0/1` scale subresource | +| **`SandboxTemplate` / `SandboxClaim`** | `.../agent-sandbox/templates/extensions.yaml` | Claim β†’ template binding (like PVC β†’ PV) | +| **Pool-manager controller** *(net-new)* | β€” | Maintains the warm buffer; refills on claim; shrinks on release | + +> ⚠️ **Import gap:** the `agent-sandbox` operator is not yet packaged as an OAP addon chart. Flow A's +> first implementation task is to import/repackage it from `eks-platform-openclaw` into the OAP +> addon catalog (`gitops/addons/`). + +### Warm pool β€” instant claims, cheap idle + +When the platform finishes deploying, the pool-manager brings up a **target buffer of 2–3 idle +sandboxes**. A consumer binds to a *ready* VM instantly (no cold boot). Cycling rules: + +- **On claim** β†’ provision a **refill** so the buffer stays at target. +- **On release** β†’ if the pool is above target, **remove** the extra idle sandbox. +- **Idle** sandboxes scale to `replicas: 0` (PVC retained) and resume on demand. + +> πŸ’‘ **Cost note (industry gotcha):** a literal pool of *parked, running* micro-VMs burns money. +> The consensus mitigation (E2B, Modal, Bedrock AgentCore) is **snapshot/fork-from-template + idle +> reaping**, not idle VMs left running. Implementation should prefer snapshot-restore where the +> Kata VMM supports it, and always pair the pool with aggressive idle TTL reaping. See +> [Β§9](#9-lifecycle-teardown--cost). + +--- + +## 4. Flow B β€” the Dark Factory pipeline + +> πŸ“Š **See the fancy diagrams:** [`diagrams/flow-b-dark-factory.md`](diagrams/flow-b-dark-factory.md) +> (end-to-end pipeline + detailed sequence + live-status mock). + +Runs on **spoke-dev only**. End to end: + +1. **Trigger** β€” an issue labeled `dark-factory` fires a **GitHub Action**. The Action gates on the + label, mints a **short-TTL** installation token, and calls the orchestrator. *(Net-new β€” OAP has + no GitHub Actions today.)* +2. **Claim** β€” the **orchestrator** (adapting the openclaw `session-router`, but keyed on + **issue-id** instead of a Cognito `sub`) issues a `SandboxClaim` and **binds a warm sandbox**. + The pool-manager refills the buffer. +3. **Code** β€” the issue is written into the sandbox as `/workspace/SPEC.md`. The **pluggable + coder** (Claude Code headless by default; Kiro headless as a profile) implements on branch + `df/issue-` and **builds + runs unit tests until green** inside the VM. +4. **Independent verification** *(driven by the orchestrator β€” never by the coder β€” see [Β§6](#6-independent-verification-the-heart-of-the-pattern)):* + - **Holdout gate** β€” hidden BDD scenarios the coder can neither see nor edit, judged by a + **different model** than the coder used, **paired with executable tests**, β‰₯90% to pass. + - **AWS frontier agents** β€” the orchestrator invokes the **AWS Security Agent** and **AWS DevOps + Agent** on the diff/artifacts (advisory in v1). +5. **PR + live status** β€” the coder opens a PR via `gh`; the orchestrator maintains **one sticky + comment** that ticks each stage β³β†’βœ…/❌ with timestamps and log links (see [Β§7](#7-live-status-in-the-pr)). +6. **Human review** β€” a human reviews the **evidence** (test results, holdout satisfaction, + security/devops findings) and either approves or comments. +7. **Iterate** β€” a PR comment resumes the scaled-to-zero sandbox (same workspace) and the coder + applies the change. **Bounded to N rounds**, then a human breaks the tie (see [Β§8](#8-human-in-the-loop--the-iterative-comment-loop)). +8. **Merge + teardown** β€” on approveβ†’merge, the orchestrator deletes the sandbox, PVC, any + ephemeral test infra, and the eval job. A **reaper CronJob** sweeps abandoned/timed-out runs. + +### Two worked use-cases + +| Issue example | How it's tested | Teardown | +|---|---|---| +| *"Add a `weather-agent` to the examples"* | Deploy into an **ephemeral namespace** on spoke-dev β†’ run holdout scenarios β†’ delete namespace | Namespace + branch artifacts | +| *"Build an EKS cluster with X"* | **Dry-run / crossplane-render** by default; a `deep-test` label spins a **real ephemeral `PlatformCluster`** (appmod-blueprints composition) | Delete the `PlatformCluster` claim | + +--- + +## 5. The pluggable coding assistant + +The coder is behind a **thin, swappable interface** β€” a deliberate choice (the industry lesson is +*don't marry a single vendor*). Two profiles ship; both run **inside** the Kata sandbox and reach +models only through the **Bifrost** LLM gateway. + +| Profile | Why | Notes | +|---|---|---| +| **A β€” Claude Code headless** *(primary)* | Purpose-built for autonomous implementβ†’buildβ†’testβ†’git loops; proven headless/CI autonomy | `CLAUDE_CODE_USE_BEDROCK` / base-URL β†’ Bifrost; strongest multi-file + shell | +| **B β€” Kiro headless** | **Spec-driven** (`spec β†’ requirements β†’ design β†’ tasks`) β€” the most natural fit since *an issue is a spec*; supports a headless GitHub Actions mode | AWS-native; documented as the second profile | + +### The coder contract (drop-in interface) + +Everything crosses the boundary as **files + env**, so swapping profiles is one config line: + +``` +INPUTS (mounted into the sandbox) + /workspace/SPEC.md # the issue, as a spec + /workspace/repo/ # the checked-out target repo (branch df/issue-) + /workspace/RETRY.md # (optional) one-line failure reasons from a prior holdout run + tmpfs: bifrost-api-key # mode 0400, read then unset β€” never in env + tmpfs: gh-token # short-TTL, mode 0400 +ENV + CODER_PROFILE=claude-code|kiro + BIFROST_URL=http://bifrost.bifrost.svc:8080 +OUTPUTS (produced by the coder) + git branch df/issue- with commits + /workspace/artifacts/result.json # what changed, build/test logs, evidence links +``` + +> The holdout scenarios are **deliberately absent** from this list β€” the coder never receives them. +> See [Β§6](#6-independent-verification-the-heart-of-the-pattern). + +--- + +## 6. Independent verification (the heart of the pattern) + +This is the part most teams skip β€” and it's why their agents learn to *game the tests*. Two +independent checks run **outside** the coder's control. + +### 6.1 Holdout gate β€” train/test separation for code + +Acceptance criteria are written as **plain-English BDD scenarios** that live in a location the +coder **cannot see or edit**. A separate evaluator job runs them against the built code. + +``` +holdout/ + scenarios/*.feature # hidden acceptance scenarios (never mounted into the sandbox) + rubric.md # how the judge scores +``` + +**Hard rules (these are the whole point):** + +1. **The coder cannot read or write the holdout.** Scenarios are never mounted into the sandbox; + the coder's repo checkout **excludes the grading-test path**. On a failed run the coder gets + only **one-line reasons** in `RETRY.md` β€” never the scenario text. +2. **A different model judges.** The evaluator's LLM judge must be a **different model/family than + the coder** (defeats self-preference bias β€” a model scores its own output higher). +3. **The judge is never the sole gate.** Every scenario is paired with **executable tests**; the + LLM judgment is one signal, not the verdict. Each scenario runs **2-of-3** to smooth + non-determinism. Gate = **β‰₯90%** satisfaction. + +> This mirrors ML holdout sets and is directly validated by StrongDM's "Software Factory," which +> found *"`return true` is a great way to pass narrowly written tests"* and fixed it by storing +> scenarios **outside** the codebase. + +### 6.2 AWS frontier agents β€” independent, read-only reviewers + +The **orchestrator** (not the coder) invokes the **AWS Security Agent** and **AWS DevOps Agent** on +the finished diff/artifacts: + +- They are **out-of-cluster, AWS-managed** services β€” **not** kagent pods. +- They are **read-only reviewers on the finished diff** β€” never co-authors. Their findings are + folded into the PR report; the coder only *reacts* to them via the comment loop. +- **v1 = advisory** (report-only). Gate hooks are designed so **per-severity blocking** can be + switched on later (e.g. a critical CVE blocks the PR). + +> **Why the orchestrator invokes them, not the coder:** it keeps the untrusted sandbox +> **credential-less** and preserves *separation of concerns* β€” the agent doing the work is not the +> one grading it (see the [lethal-trifecta gotcha](#11-industry-alignment--anti-patterns-what-the-world-agrees-on)). + +--- + +## 7. Live status in the PR + +The human **watches the factory work** (the Gas City idea) through **one sticky PR comment** the +orchestrator edits in place β€” no comment spam, one canonical surface (the pattern Copilot, Devin, +and Factory all converge on). + +``` +## 🏭 Dark Factory β€” issue #42 +βœ… Claimed sandbox (spoke-dev) 12:01 +βœ… Branch df/issue-42 12:01 +βœ… Implement 12:04 +βœ… Build + unit tests 12:07 πŸ“„ log +⏳ Security Agent… +⬜ DevOps Agent +⬜ Holdout gate (0/12) +⬜ PR ready for review +``` + +Each stage links to raw logs and test output (**verifiability-by-citation** β€” the human can audit +any step). The full PR body carries the report: what changed, test results, holdout satisfaction %, +and the Security/DevOps findings. + +--- + +## 8. Human-in-the-loop & the iterative comment loop + +Level 3 means the **human approves the merge** β€” and can steer via comments: + +- A PR comment (change requested) β†’ the orchestrator **resumes the scaled-to-zero sandbox** (same + workspace PVC) β†’ the coder applies the change β†’ pushes β†’ the sticky status updates. +- **Bounded convergence:** the loop is capped at **N rounds**; after that a human must break the + tie. Comments are **batched into one agent run** (don't fire the agent per un-batched comment β€” + it thrashes). +- The agent **never self-merges**; it only pushes to its own `df/issue-` branch. Branch + protections and CI still apply. + +--- + +## 9. Lifecycle, teardown & cost + +| Phase | Sandbox state | Cost posture | +|---|---|---| +| Idle in warm pool | `replicas: 0` or snapshot | Minimal (no running VM) | +| Claimed / coding | `replicas: 1` | Active VM billed | +| Awaiting review | **`replicas: 0`** (PVC kept) | Minimal β€” resumes on comment | +| Merged / closed | **Deleted** (Sandbox + PVC + test infra + eval job) | Zero | + +- **Scale-to-zero between activity** keeps the (possibly long) review window cheap. +- **Reaper CronJob** (adapted from openclaw `reaper-cronjob.yaml`) sweeps abandoned/timed-out runs + by TTL annotation β€” the safety net for crashes and forgotten PRs. +- **Ephemeral EKS test targets** (`deep-test`) are **gated behind a label** because they cost real + money and take ~15–20 min to provision; the default path is dry-run/namespace testing. + +--- + +## 10. Security model + +Untrusted, LLM-generated code + issue text from anyone = treat the whole sandbox as hostile. + +- **Hardware isolation:** every coder runs in a **Kata micro-VM** (own kernel), not a shared-kernel + container. +- **No cloud credentials in the sandbox:** the coder holds only a **Bifrost API key** and a + **short-TTL GitHub token** via **projected tmpfs (mode 0400)** β€” read then unset, never in env. + All AWS IAM lives with the **orchestrator, outside the VM**. +- **Egress lockdown:** a **NetworkPolicy** restricts sandbox egress to **Bifrost:8080 + DNS + + GitHub only**. `automountServiceAccountToken: false`, runAsNonRoot, seccomp `RuntimeDefault`, + drop `ALL` caps. +- **Prod is never a test bed:** the factory runs on **spoke-dev**; spoke-prod holds the sandbox + capability but its pool is **dormant**. Unreviewed agent code never touches prod. +- **⚠️ Lethal trifecta (the #1 risk β€” see [Β§11](#11-industry-alignment--anti-patterns-what-the-world-agrees-on)):** untrusted + issue text + credentials + egress is the exact recipe for prompt-injection exfiltration + (demonstrated against GitHub-issue-driven agents in the wild). The mitigations above exist + specifically to break that trifecta: keep credentials out of the issue-ingesting context, deny + egress, and treat all issue/repo content as hostile input. + +--- + +## 11. Industry alignment & anti-patterns (what the world agrees on) + +We validated this design against how GitHub Copilot coding agent, OpenAI Codex cloud, Devin, Google +Jules, Cursor background agents, Factory.ai, and StrongDM's "Software Factory" actually work. + +### βœ… Where we match consensus + +| Design choice | Industry practice | +|---|---| +| Issue β†’ Action β†’ ephemeral sandbox β†’ build/test β†’ PR | The recurring ~7-stage pipeline across Copilot/Codex/Devin/Jules/Factory | +| **Kata micro-VM isolation** | *Above-consensus.* microVM-class isolation (Firecracker, Kata, Bedrock AgentCore's per-session microVM) is the defensible choice for untrusted LLM code; shared-kernel containers are considered insufficient | +| Build/test **until green before** the PR | Explicit in codex-1's RL training, Devin, Copilot | +| **Holdout scenarios the coder never sees** | *Above-consensus.* Directly matches StrongDM's Software Factory (they learned it the hard way after `return true` gamed their tests) | +| **One sticky status surface**, not comment spam | Copilot draft-PR + session logs; Devin single review status; Factory "Mission Control" | +| Human **approves the PR**, agent iterates on comments | The dominant gating norm β€” agents do **not** self-merge by default | +| Single coder + **independent read-only reviewers** | Anthropic + Cognition agree parallel multi-agent *authoring* is a poor fit for coding; the good pattern is one coder + a fresh model reviewing the finished diff (CodeRabbit's Security Agent) | + +### ⚠️ Anti-patterns we explicitly design against + +1. **Lethal trifecta / prompt injection (highest risk).** Untrusted issue text + cloud creds + egress + β†’ data exfiltration. Invariant Labs demonstrated a malicious GitHub *issue* injecting an agent + into leaking private-repo data via an auto-PR. **Our defense:** credentials never in the + issue-ingesting sandbox context; egress denied except Bifrost/GitHub; issue/repo content treated + as hostile; frontier agents scoped read-only. *(Willison "lethal trifecta"; Invariant Labs.)* +2. **Reward hacking / test-gaming.** Frontier models stub evaluators (`evaluate = _always_ok`), make + `verify()` return true, read reference answers, or delete the test oracle (METR, OpenAI, + Anthropic). **Our defense:** the holdout the coder cannot see or edit β€” if the coder can reach it, + the holdout is theater. +3. **LLM-judge as a sole hard gate.** Judges have proven position/verbosity/**self-preference** bias + (causal β€” a model favors its own family's output). **Our defense:** different judge model + + paired executable tests + 2-of-3 + a probabilistic satisfaction score, never a lone boolean. +4. **Multi-agent over-orchestration.** **Our defense:** single-threaded coder; Security/DevOps are + stateless read-only reviewers on the finished diff, never co-authors. +5. **Non-converging comment loops.** **Our defense:** batch comments into one run, cap iterations, + hard time/turn limits. +6. **Warm-pool idle burn.** **Our defense:** snapshot/fork + idle reaping + scale-to-zero, not parked + VMs. +7. **Rubber-stamp reviews.** AI-co-authored PRs carry measurably more issues; "review results not + code" can decay into a green rubber stamp. **Our defense:** the human reviews *structured + evidence* (tests + holdout % + security findings + diff-path confinement), and high-risk changes + (infra, `deep-test`) get a firmer gate. + +--- + +## 12. Phased delivery + +Each phase is independently valuable β€” if you stop after any one, you're better off than before. + +| Phase | Delivers | Independently useful? | +|------:|----------|-----------------------| +| **P1** | Trigger β†’ claim warm sandbox β†’ Claude Code coder β†’ build/test β†’ PR + sticky status β†’ manual teardown | βœ… A working autonomous-PR loop | +| **P2** | Strict **holdout gate** (isolated, different-model judge, executable-test pairing) + bounded retry | βœ… Quality gate that resists gaming | +| **P3** | **AWS Security + DevOps** frontier agents (advisory) folded into the PR report | βœ… Independent review evidence | +| **P4** | Ephemeral test targets (namespace default; `deep-test` `PlatformCluster`) + **auto-teardown** on merge + reaper | βœ… Full lights-off lifecycle | +| **P5** | **Kiro** coder profile; per-severity **blocking** gate option; spoke-prod pool activation story | βœ… Vendor-plurality + higher autonomy | + +--- + +## 12a. Running Kata on EKS Auto Mode clusters (validated design) + +The spoke clusters run **EKS Auto Mode + Bottlerocket** (`c6a`/`c6g` nodes). Auto Mode's managed +nodes **cannot host Kata**: no control over `cpuOptions.nestedVirtualization`, no kernel-module +loading (`modprobe kvm_intel`), no `kata-deploy`, and those node types don't expose VT-x. +`eks-platform-openclaw` avoids Auto Mode entirely for this reason β€” but we don't have to. + +### Decision: self-managed nested-virt MNG *alongside* Auto Mode + +Add a small, tainted **self-managed Managed Node Group** of **nested-virt `c8i`/`m8i`** instances to +spoke-dev. Auto Mode keeps running everything else; kata sandboxes schedule onto the MNG via the +`kata=true:NoSchedule` taint the chart already applies. We chose an **MNG, not a second +Karpenter** β€” running a self-managed Karpenter beside Auto Mode's managed Karpenter risks +NodePool/CRD conflicts, whereas MNGs are additive and coexist cleanly. + +Rejected alternatives: **Bedrock AgentCore / Fargate** (breaks the k8s-native pod model our whole +Sandbox/warm-pool/claim design depends on β€” it's an invoke-a-session runtime, not a pod we own); +**gVisor** (same Auto-Mode node-install blocker as Kata, weaker isolation). + +### βœ… Validated by two live tests (spoke-dev, 2026-07-10) + +A `c8i.4xlarge` kata MNG was created on spoke-dev, exercised, then torn down. Results: + +| Question | Result | +|---|---| +| Self-managed MNG coexists with Auto Mode? | **βœ… Yes** β€” MNG provisioned alongside Auto Mode nodepools, no conflict; Auto Mode stayed healthy | +| Nested virtualization / `/dev/kvm`? | **βœ… Yes** β€” `/dev/kvm` present, `kvm_intel` loaded, 32 `vmx` flags, via `CpuOptions.NestedVirtualization: enabled` | +| Node joins the cluster & goes Ready? | **βœ… Yes** β€” with the fixes below (nodeadm endpoint/CA + vpc-cni + kube-proxy) | +| Kata runtime install (kata-deploy)? | **βœ… Yes** β€” `1/1`, zero restarts, once `kube-proxy` was installed | +| **Real Kata VM runs?** | **βœ… YES** β€” pod under `kata-clh` had guest kernel `6.18.35` vs host `6.12.90` = true hardware VM isolation | + +### Hard-won lessons (baked into the implementation) + +1. **Node bootstrap** β€” do **not** override the AMI + userData with plain bash; that clobbers the + EKS bootstrap and the node boots (`/dev/kvm` present) but never joins. Use the **AL2023 nodeadm + MIME userData**, and set nested-virt via the launch-template `CpuOptions`, not userData. +2. **Teardown ordering** β€” delete the **MNG first and let it drain** (set min/desired=0 first). + Terminating the instance out from under the MNG makes the ASG respawn and can wedge the delete on + a `Pending:Wait` lifecycle hook; recover with `terminate-instance-in-auto-scaling-group` + + `complete-lifecycle-action`. +3. **Custom-AMI nodeadm needs cluster coordinates** β€” with a custom `ImageId`, nodeadm can't + auto-discover the API; you must set `apiServerEndpoint` + `certificateAuthority` + `cidr` in the + NodeConfig, or it fails "Apiserver endpoint is missing in cluster configuration". +4. **Auto Mode has no `vpc-cni`** β€” self-managed MNG nodes stay `NotReady` (`cni plugin not + initialized`) until you install the `vpc-cni` EKS addon. `aws-node` tolerates all taints and + schedules onto the kata node once installed. +5. **kata-deploy on Auto Mode (open item)** β€” the upstream kata-deploy chart defaults to the + **experimental nydus snapshotter** (`EXPERIMENTAL_SETUP_SNAPSHOTTER=nydus`), which restarts + containerd and briefly drops CNI networking; kata-deploy then fails its own API call + (`Failed to get node ... client error (Connect)`) and crashloops before installing the runtime. + Fix to apply next: disable the experimental nydus snapshotter (openclaw uses overlayfs) and/or + raise kata-deploy's API-retry tolerance. Everything *up to* the runtime install is proven; the + runtime install itself needs this one chart-tuning fix. + +Also fixed during testing: the kata-deploy Helm values are **top-level** (`nodeSelector`, +`tolerations`, `shims`) for a direct install β€” the nested `kata-deploy:` key only applies when it's +a subchart. Our catalog entry uses the nested form (correct, since ArgoCD deploys it as its own +app), but a direct `helm install` must use top-level values. + +--- + +## 13. Open questions / future work + +*To resolve during implementation β€” flagged honestly rather than assumed:* + +- **⚑ SIMPLIFICATION β€” use the operator's native `SandboxWarmPool`.** Live testing revealed the + upstream agent-sandbox operator ships a **`sandboxwarmpools.extensions.agents.x-k8s.io` CRD** + (`spec: {replicas, sandboxTemplateRef}`) β€” a first-class warm-pool primitive. Our custom + pool-manager CronJob (`41-poolmanager-cronjob.yaml`) is therefore likely **redundant**: create a + `SandboxWarmPool` CR instead and let the operator maintain the buffer. Keep the CronJob only for + the extra scale-to-zero/reap behaviors the CR may not cover. To reconcile after the live test. +- **Headless auth** for Claude Code & Kiro through a Bifrost base-URL override inside a Kata VM + (the biggest unknown β€” prototype first in P1). +- **Import the `agent-sandbox` operator** from `eks-platform-openclaw` into the OAP addon catalog + (Flow A's first task). +- **Enable the sandbox/kagent addons on the dev overlay** (they're hub-only today). +- **Exact AWS Security / DevOps Agent APIs & auth** β€” confirm the invocation contract at build time. +- **Orchestrator RBAC scope** β€” Sandbox/PVC/Service/Job on spoke-dev + `PlatformCluster` claims for + the `deep-test` path. +- **Warm-pool implementation** β€” verify whether the `agent-sandbox` v0.1.0 operator supports + snapshot/fork warm-binding, or whether the pool-manager must create-on-demand. + +--- + +## 14. References + +**Pattern sources** +- Steve Yegge β€” *Welcome to Gas City* β€” https://steve-yegge.medium.com/welcome-to-gas-city-57f564bb3607 +- *The Dark Factory Pattern: Moving From AI-Assisted to Fully Autonomous Coding* β€” https://hackernoon.com/the-dark-factory-pattern-moving-from-ai-assisted-to-fully-autonomous-coding +- Kiro headless in GitHub Actions β€” https://builder.aws.com/content/35cLFnKM6DJMgRzdZQ7XPZkJmoz/automate-reviews-in-github-actions-with-kiro-headless-mode + +**Industry pipelines** +- GitHub Copilot coding agent β€” https://github.blog/news-insights/product-news/github-copilot-meet-the-new-coding-agent/ +- OpenAI Codex β€” https://openai.com/index/introducing-codex/ +- Devin SDLC integration β€” https://docs.devin.ai/essential-guidelines/sdlc-integration +- Factory.ai Missions β€” https://docs.factory.ai/cli/features/missions/overview +- StrongDM Software Factory β€” https://factory.strongdm.ai/ +- AWS Bedrock AgentCore runtime sessions (per-session microVM) β€” https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-sessions.md +- AWS DevOps Agent β€” https://aws.amazon.com/devops-agent/ + +**Failure modes / safety** +- Simon Willison β€” *The lethal trifecta* β€” https://simonwillison.net/2025/Jun/16/the-lethal-trifecta/ +- Invariant Labs β€” GitHub MCP prompt-injection exfiltration β€” https://invariantlabs.ai/blog/mcp-github-vulnerability +- METR β€” *Recent frontier models are reward hacking* β€” https://metr.org/blog/2025-06-05-recent-reward-hacking/ +- OpenAI β€” *Detecting misbehavior in frontier reasoning models* β€” https://openai.com/index/chain-of-thought-monitoring/ +- Anthropic β€” *Reward tampering* β€” https://www.anthropic.com/research/reward-tampering +- LLM-judge self-preference bias β€” https://arxiv.org/abs/2404.13076 Β· MT-Bench β€” https://arxiv.org/abs/2306.05685 +- Cognition β€” *Don't build multi-agents* β€” https://cognition.ai/blog/dont-build-multi-agents +- Anthropic β€” *Claude Code best practices* β€” https://www.anthropic.com/engineering/claude-code-best-practices + +**Platform building blocks (this monorepo & siblings)** +- `eks-platform-openclaw` β€” Kata micro-VM sandbox, `Sandbox` CRD, session-router lifecycle (uses LiteLLM there; **this platform uses Bifrost** as the LLM gateway) +- `appmod-blueprints` β€” `PlatformCluster` Crossplane composition (ephemeral EKS), KRO CI/CD pipeline +- `agent-platform-amazon-eks` β€” hub/spoke fleet, addon ApplicationSets, kagent, agent-gateway, **Bifrost** LLM gateway diff --git a/docs/dark-factory/diagrams/flow-a-sandbox-capability.md b/docs/dark-factory/diagrams/flow-a-sandbox-capability.md new file mode 100644 index 0000000..6c6777a --- /dev/null +++ b/docs/dark-factory/diagrams/flow-a-sandbox-capability.md @@ -0,0 +1,112 @@ +# Flow A β€” Agent Sandbox Capability (permanent platform feature) + +The **Agent Sandbox** capability ships as a first-class agent-platform GitOps addon. When the +platform is deployed, it stands up the Kata (Cloud Hypervisor) micro-VM runtime, the `Sandbox` +CRD + operator, and a **warm pool** of pre-provisioned, hardware-isolated sandboxes kept ready by +a pool-manager controller. This is independent of the Dark Factory β€” it is the reusable isolation +substrate any agent workload can claim. + +--- + +## A.1 β€” Capability architecture + +```mermaid +%%{init: {'theme':'base','themeVariables':{ + 'fontFamily':'Amazon Ember, Helvetica, Arial, sans-serif','fontSize':'14px', + 'primaryColor':'#2E3E50','primaryBorderColor':'#5F7185','primaryTextColor':'#FFFFFF', + 'lineColor':'#8B99A7','clusterBkg':'#26374A','clusterBorder':'#5F7185', + 'tertiaryColor':'#1B2733'}}}%% +flowchart TB + classDef canvas fill:#1B2733,stroke:#1B2733,color:#FFFFFF; + classDef band fill:#26374A,stroke:#5F7185,color:#E8EDF2,stroke-width:1px; + classDef node fill:#2E4257,stroke:#7C8FA3,color:#FFFFFF,stroke-width:1.2px; + classDef accent fill:#FF9900,stroke:#EC7211,color:#161E2D,stroke-width:1.5px; + classDef warm fill:#22384A,stroke:#FF9900,color:#FFFFFF,stroke-width:1.4px; + classDef muted fill:#243244,stroke:#415266,color:#AEB8C4,stroke-width:1px; + + subgraph CANVAS[" "] + direction TB + + subgraph GITOPS["πŸš€ GitOps enablement Β· ArgoCD app-of-apps"] + direction LR + FLAG["enable_agent_sandbox: true
overlays/environments/dev,prod"]:::accent + APPSET["ApplicationSet
cluster-generator
sync-wave βˆ’1 β†’ 1"]:::node + FLAG --> APPSET + end + + subgraph CLUSTER["☸️ spoke-dev & spoke-prod Β· capability on both"] + direction TB + + subgraph OPER["🧩 Sandbox control plane"] + direction LR + CRD["Sandbox CRD
agents.x-k8s.io/v1alpha1
+ SandboxTemplate + SandboxClaim"]:::node + OPCTL["agent-sandbox
operator"]:::node + POOL["pool-manager
keeps N idle Β· refills Β· shrinks"]:::accent + CRD --- OPCTL --- POOL + end + + subgraph WARM["πŸ”₯ Warm pool Β· target buffer = 2–3 idle"] + direction LR + S1(["idle Β· sandbox-1"]):::warm + S2(["idle Β· sandbox-2"]):::warm + S3(["idle Β· sandbox-3"]):::warm + end + + subgraph KATA["πŸ›‘οΈ Kata micro-VM runtime Β· hardware isolation"] + direction LR + RC["RuntimeClasses
kata-clh Β· kata-qemu Β· kata-fc"]:::node + KD["kata-deploy
DaemonSet"]:::node + NP["Karpenter pools
kata-nested c8i/m8i · kata-metal"]:::node + RC --- KD --- NP + end + + MODEL["🧠 Bifrost LLM gateway
bifrost.bifrost.svc:8080 β†’ Bedrock"]:::node + end + end + + APPSET ==> OPER + APPSET ==> KATA + POOL ==> WARM + WARM -.-> KATA + WARM -.-> MODEL + + class CANVAS canvas + class GITOPS,CLUSTER,OPER,WARM,KATA band + linkStyle default stroke:#8B99A7,stroke-width:1.4px; + linkStyle 7 stroke:#FF9900,stroke-width:2px; +``` + +--- + +## A.2 β€” Warm-pool cycling (claim ↔ refill ↔ shrink) + +The pool-manager keeps a steady buffer of idle sandboxes so a consumer (e.g. the Dark Factory) +binds to a **ready** VM instantly instead of paying cold-start. Idle sandboxes use the `Sandbox` +`replicas: 0/1` **scale subresource**, so "idle" is cheap. + +```mermaid +%%{init: {'theme':'base','themeVariables':{ + 'fontFamily':'Amazon Ember, Helvetica, Arial, sans-serif','fontSize':'14px', + 'primaryColor':'#2E4257','primaryBorderColor':'#7C8FA3','primaryTextColor':'#FFFFFF', + 'lineColor':'#8B99A7','labelColor':'#E8EDF2'}}}%% +stateDiagram-v2 + direction LR + [*] --> Provisioning : pool below target + Provisioning --> Idle : VM booted Β· replicas=1 Β· unclaimed + Idle --> Claimed : SandboxClaim binds + Claimed --> Idle : claim released Β· recyclable + Idle --> Paused : idle TTL Β· scale replicas=0 Β· PVC kept + Paused --> Idle : demand returns Β· scale replicas=1 + Claimed --> Retired : consumer done Β· delete Sandbox+PVC + Idle --> Retired : pool above target Β· shrink + Retired --> [*] + + note right of Claimed + On CLAIM the pool-manager provisions + a REFILL so the buffer stays at target. + end note + note right of Retired + On RELEASE, if the pool is above target, + the extra idle sandbox is removed. + end note +``` diff --git a/docs/dark-factory/diagrams/flow-b-dark-factory.md b/docs/dark-factory/diagrams/flow-b-dark-factory.md new file mode 100644 index 0000000..f314437 --- /dev/null +++ b/docs/dark-factory/diagrams/flow-b-dark-factory.md @@ -0,0 +1,183 @@ +# Flow B β€” Dark Factory (issue β†’ PR β†’ merge β†’ teardown) + +A GitHub issue is a **spec**. The factory claims a warm sandbox on spoke-dev, a pluggable coding +assistant implements + tests the change, the orchestrator runs independent verification (holdout +gate + AWS frontier agents), a PR is opened with a **live-updating** status, a human approves on +results, and everything is torn down on merge. Autonomy **Level 3**: the human's only job is to +approve the merge. + +--- + +## B.1 β€” End-to-end pipeline (lights-off assembly line) + +```mermaid +%%{init: {'theme':'base','themeVariables':{ + 'fontFamily':'Amazon Ember, Helvetica, Arial, sans-serif','fontSize':'13.5px', + 'primaryColor':'#2E4257','primaryBorderColor':'#7C8FA3','primaryTextColor':'#FFFFFF', + 'lineColor':'#8B99A7','clusterBkg':'#26374A','clusterBorder':'#5F7185'}}}%% +flowchart LR + classDef canvas fill:#1B2733,stroke:#1B2733,color:#FFFFFF; + classDef band fill:#26374A,stroke:#5F7185,color:#E8EDF2,stroke-width:1px; + classDef node fill:#2E4257,stroke:#7C8FA3,color:#FFFFFF,stroke-width:1.2px; + classDef accent fill:#FF9900,stroke:#EC7211,color:#161E2D,stroke-width:1.5px; + classDef human fill:#22384A,stroke:#FF9900,color:#FFFFFF,stroke-width:1.4px; + classDef gate fill:#2E4257,stroke:#FF9900,color:#FFFFFF,stroke-width:1.4px; + + subgraph CANVAS[" "] + direction LR + + START(["🧾 Issue opened
label: dark-factory"]):::accent + + subgraph T["β‘  Trigger"] + GHA["βš™οΈ GitHub Action
gate on label
mint short-TTL token"]:::node + end + + subgraph O["β‘‘ Orchestrate Β· spoke-dev Β· trusted (holds AWS IAM)"] + ORCH["πŸŽ›οΈ Orchestrator
key = issue-id
claim Β· drive Β· report"]:::node + CLAIM["πŸ”’ SandboxClaim
bind warm sandbox Β· pool refills"]:::node + ORCH --> CLAIM + end + + subgraph SBX["β‘’ Code + self-test Β· Kata micro-VM Β· isolated (no cloud creds)"] + CODER["πŸ€– Pluggable coder
Claude Code | Kiro
reads SPEC.md"]:::node + IMPL["✍️ implement
branch df/issue-N"]:::node + BUILD["πŸ”§ build + unit tests
until green"]:::node + CODER --> IMPL --> BUILD + end + + subgraph V["β‘£ Independent verification Β· orchestrator-driven (NOT the coder)"] + HOLD["🎯 Holdout gate
hidden scenarios Β· different-model judge
+ executable tests Β· β‰₯90%"]:::gate + SEC["πŸ›‘οΈ AWS Security Agent"]:::node + DEV["πŸš€ AWS DevOps Agent"]:::node + HOLD -.-> SEC -.-> DEV + end + + subgraph P["β‘€ Pull Request Β· live status"] + PR["πŸ”€ PR opened
sticky comment β³β†’βœ…
results + findings + logs"]:::node + end + + subgraph H["β‘₯ Human Β· Level 3"] + REVIEW{"Approve?
reviews RESULTS"}:::human + COMMENT["πŸ’¬ PR comment
resume sandbox Β· iterate
bounded N rounds"]:::human + end + + subgraph TD["⑦ Merge + teardown"] + MERGE["βœ… merge PR"]:::accent + DESTROY["🧹 delete sandbox + PVC
+ ephemeral test infra + eval job"]:::node + MERGE --> DESTROY --> DONE(["🏁 done"]):::node + end + + START ==> GHA ==> ORCH + CLAIM ==> CODER + BUILD ==> HOLD + DEV ==> PR + PR ==> REVIEW + REVIEW -->|changes requested| COMMENT + COMMENT -.->|new instruction| CODER + REVIEW ==>|approve| MERGE + end + + class CANVAS canvas + class T,O,SBX,V,P,H,TD band + linkStyle default stroke:#8B99A7,stroke-width:1.4px; + linkStyle 7,8,9,10,11,12,15 stroke:#FF9900,stroke-width:2px; +``` + +--- + +## B.2 β€” Detailed sequence (who does what, and the trust boundary) + +```mermaid +%%{init: {'theme':'base','themeVariables':{ + 'fontFamily':'Amazon Ember, Helvetica, Arial, sans-serif','fontSize':'13px', + 'primaryColor':'#2E4257','primaryBorderColor':'#7C8FA3','primaryTextColor':'#FFFFFF', + 'actorBkg':'#2E4257','actorBorder':'#FF9900','actorTextColor':'#FFFFFF', + 'signalColor':'#8B99A7','signalTextColor':'#E8EDF2','lineColor':'#8B99A7', + 'noteBkg':'#FF9900','noteTextColor':'#161E2D','noteBorderColor':'#EC7211', + 'loopTextColor':'#E8EDF2','sequenceNumberColor':'#161E2D'}}}%% +sequenceDiagram + autonumber + actor Dev as πŸ§‘β€πŸ’» Human + participant GH as πŸ™ GitHub + participant GHA as βš™οΈ Action + participant ORCH as πŸŽ›οΈ Orchestrator (AWS IAM) + participant POOL as πŸ”₯ Warm pool + box rgb(34,56,74) πŸ›‘οΈ Kata micro-VM Β· isolated Β· no cloud creds + participant SBX as πŸ€– Coder sandbox + end + participant EVAL as 🎯 Holdout evaluator + participant AWS as ☁️ AWS Security / DevOps Agents + + Dev->>GH: open issue (label: dark-factory) + GH->>GHA: issues.labeled event + GHA->>ORCH: POST /run (issue #, repo, short-TTL token) + ORCH->>POOL: SandboxClaim (key = issue-id) + POOL-->>ORCH: bound warm sandbox (instant) + Note over POOL: pool-manager provisions a REFILL + + ORCH->>SBX: write SPEC.md + checkout df/issue-N + activate SBX + SBX->>SBX: implement Β· build Β· unit tests (until green) + SBX-->>ORCH: result.json (diff + logs) + deactivate SBX + + Note over ORCH,EVAL: Verification is INDEPENDENT of the coder
(coder never sees or edits the holdout) + ORCH->>EVAL: run hidden scenarios vs diff + EVAL-->>ORCH: satisfaction % (different-model judge + real tests) + ORCH->>AWS: invoke Security + DevOps agents on diff + AWS-->>ORCH: findings (advisory) + + ORCH->>GH: open PR + sticky status comment (β³β†’βœ…) + GH-->>Dev: review request (results, not code) + + loop bounded iterations (max N) + Dev->>GH: PR comment (change requested) + GH->>ORCH: comment webhook + ORCH->>POOL: resume sandbox (scale 0β†’1, same PVC) + ORCH->>SBX: apply comment as new instruction + activate SBX + SBX-->>ORCH: push update + deactivate SBX + ORCH->>GH: update sticky status + end + + Dev->>GH: βœ… approve + merge + GH->>ORCH: pull_request closed+merged + ORCH->>POOL: release + delete sandbox + PVC + ORCH->>ORCH: delete ephemeral test infra + eval job + Note over ORCH: Reaper CronJob reaps any abandoned run +``` + +--- + +## B.3 β€” Live PR status (the sticky comment the human watches) + +The orchestrator maintains **one** PR comment, edited in place as each stage completes β€” no comment +spam, one canonical surface (the pattern Copilot/Devin/Factory converge on). + +```mermaid +%%{init: {'theme':'base','themeVariables':{ + 'fontFamily':'Amazon Ember, Helvetica, Arial, sans-serif','fontSize':'13px', + 'primaryColor':'#2E4257','primaryBorderColor':'#7C8FA3','primaryTextColor':'#FFFFFF', + 'lineColor':'#8B99A7','clusterBkg':'#26374A','clusterBorder':'#5F7185'}}}%% +flowchart TB + classDef canvas fill:#1B2733,stroke:#1B2733,color:#FFFFFF; + classDef done fill:#22384A,stroke:#3FB950,color:#FFFFFF,stroke-width:1.3px; + classDef now fill:#FF9900,stroke:#EC7211,color:#161E2D,stroke-width:1.5px; + classDef wait fill:#243244,stroke:#5F7185,color:#AEB8C4,stroke-width:1px; + + subgraph CANVAS["🏭 Dark Factory β€” issue #42"] + direction TB + A["βœ… Claimed sandbox (spoke-dev) Β· 12:01"]:::done + B["βœ… Branch df/issue-42 Β· 12:01"]:::done + C["βœ… Implement Β· 12:04"]:::done + D["βœ… Build + unit tests Β· 12:07 Β· πŸ“„ log"]:::done + E["⏳ Security Agent…"]:::now + F["⬜ DevOps Agent"]:::wait + G["⬜ Holdout gate (0/12)"]:::wait + I["⬜ PR ready for review"]:::wait + A --> B --> C --> D --> E --> F --> G --> I + end + class CANVAS canvas + linkStyle default stroke:#5F7185,stroke-width:1.2px; +``` diff --git a/examples/dark-factory/README.md b/examples/dark-factory/README.md new file mode 100644 index 0000000..7bd262a --- /dev/null +++ b/examples/dark-factory/README.md @@ -0,0 +1,110 @@ +# Dark Factory β€” Flow B, Phase P1 + +**Trigger β†’ claim warm sandbox β†’ drive the coder β†’ open a PR with a live sticky status β†’ manual +teardown.** The first independently-useful slice of the [Dark Factory pattern](../../docs/dark-factory/README.md) +and the first real consumer of **[Flow A](../../docs/dark-factory/diagrams/flow-a-sandbox-capability.md)**'s +Kata micro-VM warm pool. + +Runs on **spoke-dev only**. Autonomy is bounded here: P1 opens a PR and **stops** β€” a human still +reviews and merges. The verification gates (holdout, Security/DevOps agents) arrive in P2/P3. + +## Components + +| Path | Role | Trust | +|---|---|---| +| `.github/workflows/dark-factory.yml` | GitHub Action β€” gates on the `dark-factory` label, mints a short-TTL token, POSTs to the orchestrator | trigger | +| `orchestrator/server.js` | HTTP service: `/run` drives the pipeline, `/teardown` releases the sandbox | **trusted** (holds the GH token; in later phases, AWS IAM) | +| `orchestrator/lib/k8s.js` | Claims a warm sandbox via a `SandboxClaim(warmPoolRef)`, waits for bind+Ready, releases on teardown | trusted | +| `orchestrator/lib/github.js` | The **one** sticky PR status comment (edited in place) + PR creation | trusted | +| `orchestrator/lib/coder.js` | Drives the pluggable coder inside the sandbox over its `:8080` control endpoint | trusted β†’ boundary | +| `coder/agent.js` | The in-VM coder agent: writes `SPEC.md`, checks out `df/issue-`, runs Claude Code headless via Bifrost, builds+tests, returns `result.json` | **untrusted** (Kata VM, no cloud creds) | +| `orchestrator/k8s/*` | Deployment + Service + narrowly-scoped RBAC (SandboxClaims only) | β€” | +| `gitops-app.yaml` | ArgoCD Application pinning the orchestrator to **spoke-dev** | β€” | + +## Request flow + +``` +GitHub issue (label: dark-factory) + β†’ GitHub Action (gate on label, mint short-TTL token) + β†’ orchestrator POST /run ← trusted; holds GH token, narrow RBAC + β”œβ”€ SandboxClaim(warmPoolRef=coder-warmpool) ← binds a warm Kata VM (Flow A) + β”œβ”€ wait for status.sandbox {name, podIPs} + Ready + β”œβ”€ POST run spec to coder agent in the VM (SPEC.md + branch df/issue-N) + β”‚ coder: implement β†’ build β†’ unit tests until green β†’ push branch + β”œβ”€ open PR + maintain ONE sticky status comment (β³β†’βœ…) + └─ (P2/P3) holdout gate + Security/DevOps agents β€” pending + β†’ human reviews evidence, approves, merges + β†’ orchestrator POST /teardown β†’ delete SandboxClaim (pool refills) +``` + +## The SandboxClaim contract (verified against the live v1beta1 CRD) + +The orchestrator claims from Flow A's `SandboxWarmPool` rather than creating sandboxes: + +```yaml +apiVersion: extensions.agents.x-k8s.io/v1beta1 +kind: SandboxClaim +metadata: { name: df-issue-42, namespace: agent-sandbox-system } +spec: + warmPoolRef: { name: coder-warmpool } # bind a pre-warmed idle sandbox + env: # per-container, NON-secret + - { containerName: coder, name: BIFROST_URL, value: http://bifrost.bifrost.svc.cluster.local:8080 } + lifecycle: { ttlSecondsAfterFinished: 10800 } # safety-net TTL +# status.sandbox.{name, podIPs[]} + status.conditions[Ready] β†’ the bound VM +``` + +## Trust boundary (Β§10) + +- The **orchestrator** is trusted and runs on general Auto Mode nodes (not the kata MNG). It holds + the GitHub token (handed per-run by the Action) and β€” in later phases β€” AWS IAM. Its RBAC is + scoped to `sandboxclaims` (+ read `sandboxes`) in one namespace; no pod/exec, no secrets, no + cluster scope. +- The **coder** is untrusted: it runs in a **Kata micro-VM**, holds only a Bifrost API key + a + short-TTL GitHub token via **projected tmpfs (mode 0400)** β€” read at point of use, never in env β€” + and reaches models only through **Bifrost**. Flow A's NetworkPolicy locks egress to + Bifrost + DNS + GitHub. +- This breaks the **lethal trifecta** (untrusted issue text + credentials + egress): credentials are + never in the issue-ingesting sandbox context, and egress is denied by default. + +## Build & deploy (staged β€” not auto-deployed) + +```bash +# 1) Build + push both images to ECR, pin the tags. +docker build -t /dark-factory-orchestrator:0.1.0 examples/dark-factory/orchestrator +docker build -t /dark-factory-coder:0.1.0 examples/dark-factory/coder +# β†’ set the coder image on the Flow A SandboxTemplate (coderTemplate.image) +# β†’ set the orchestrator image in orchestrator/k8s/deployment.yaml + +# 2) Deploy the orchestrator onto spoke-dev. +kubectl --context hub apply -f examples/dark-factory/gitops-app.yaml # ArgoCD (recommended) +# or directly: +kubectl --context spoke-dev apply -f examples/dark-factory/orchestrator/k8s/ + +# 3) Wire the trigger. +# repo/org variable DARK_FACTORY_ORCHESTRATOR_URL = https:// +# repo/org secret DARK_FACTORY_DISPATCH_TOKEN = shared dispatch secret +# Label an issue `dark-factory` to fire a run. +``` + +## Configuration (orchestrator env) + +| Var | Default | Purpose | +|---|---|---| +| `SANDBOX_NAMESPACE` | `agent-sandbox-system` | Where the warm pool + claims live | +| `WARM_POOL_NAME` | `coder-warmpool` | Flow A `SandboxWarmPool` to claim from | +| `CLAIM_READY_TIMEOUT_MS` | `120000` | Max wait for a claim to bind + Ready | +| `CLAIM_TTL_SECONDS` | `10800` | Safety-net TTL on the claim (reaper backstop) | +| `BIFROST_URL` | `http://bifrost.bifrost.svc.cluster.local:8080` | LLM gateway the coder uses | +| `CODER_PROFILE` | `claude-code` | `claude-code` (primary) or `kiro` | + +## Not in P1 (by design) + +- **Holdout gate** (P2), **AWS Security/DevOps agents** (P3) β€” rendered as pending in the sticky + comment so the surface is stable. +- **Auto-teardown on merge** + reaper (P4) β€” P1 teardown is the manual `/teardown` call. +- **Iterative comment loop** β€” P1 opens the PR and stops; the human drives from there. + +## Status + +Code + manifests validated (JS syntax, server-side `kubectl --dry-run` against spoke-dev). Images +are **not** built/pushed and nothing is deployed yet β€” this is the staged P1 implementation. diff --git a/examples/dark-factory/coder/Dockerfile b/examples/dark-factory/coder/Dockerfile new file mode 100644 index 0000000..1fcac88 --- /dev/null +++ b/examples/dark-factory/coder/Dockerfile @@ -0,0 +1,26 @@ +# Dark Factory coder image β€” runs INSIDE the Kata micro-VM sandbox. +# +# Bundles the in-VM agent + the toolchains a coder run needs (git, node, the +# Claude Code CLI). This is untrusted-code territory: the image carries no +# credentials β€” secrets are injected at runtime via projected tmpfs (0400) and +# model access is only through Bifrost. Keep it lean and pinned. +FROM public.ecr.aws/docker/library/node:20-alpine + +# Toolchains for build/test across common stacks + git for checkout/push. +# (Extend per the repos the factory targets; kept minimal for P1.) +RUN apk add --no-cache git bash python3 py3-pip go + +# Claude Code headless CLI (primary coder profile). Pinned via npm. +RUN npm install -g @anthropic-ai/claude-code + +WORKDIR /app +COPY agent.js ./ + +# Non-root, matches the SandboxTemplate securityContext (runAsUser 1000). +USER 1000 + +ENV CODER_PORT=8080 \ + WORKSPACE=/workspace +EXPOSE 8080 + +CMD ["node", "agent.js"] diff --git a/examples/dark-factory/coder/agent.js b/examples/dark-factory/coder/agent.js new file mode 100644 index 0000000..56dd80c --- /dev/null +++ b/examples/dark-factory/coder/agent.js @@ -0,0 +1,159 @@ +// agent.js β€” the in-VM coder agent (runs INSIDE the Kata micro-VM sandbox). +// +// This is the untrusted side of the trust boundary. It holds NO cloud +// credentials β€” only a Bifrost API key + a short-TTL GitHub token, both read +// from projected tmpfs (mode 0400), used, and never placed in the environment. +// It listens on :8080 for a run spec from the orchestrator, then: +// 1. writes /workspace/SPEC.md from the issue +// 2. checks out the target repo on branch df/issue- +// 3. runs the pluggable coder (Claude Code headless by default) via Bifrost +// 4. builds + runs unit tests until green (bounded attempts) +// 5. pushes the branch and returns /workspace/artifacts/result.json +// +// The concrete coder invocation is profile-pluggable (Β§5). This reference +// wires the contract and the Claude Code headless call; swapping to Kiro is a +// single branch in runProfile(). +const http = require("http"); +const fs = require("fs"); +const { execFileSync } = require("child_process"); + +const PORT = parseInt(process.env.CODER_PORT || "8080", 10); +const WORKSPACE = process.env.WORKSPACE || "/workspace"; +const BIFROST_URL = process.env.BIFROST_URL || "http://bifrost.bifrost.svc.cluster.local:8080"; +const MAX_TEST_ATTEMPTS = parseInt(process.env.MAX_TEST_ATTEMPTS || "3", 10); + +// Secrets live on tmpfs, mode 0400 β€” read at point of use, never in env. +function readSecret(path) { + try { + return fs.readFileSync(path, "utf8").trim(); + } catch { + return null; + } +} +const BIFROST_KEY_PATH = process.env.BIFROST_KEY_PATH || "/etc/secrets/bifrost-api-key"; +const GH_TOKEN_PATH = process.env.GH_TOKEN_PATH || "/etc/secrets/gh-token"; + +function sh(cmd, args, opts = {}) { + return execFileSync(cmd, args, { + cwd: opts.cwd || WORKSPACE, + encoding: "utf8", + stdio: ["ignore", "pipe", "pipe"], + env: opts.env || process.env, + maxBuffer: 32 * 1024 * 1024, + }); +} + +function writeSpec(spec) { + fs.writeFileSync(`${WORKSPACE}/SPEC.md`, spec, { mode: 0o644 }); +} + +// Clone/checkout the target repo on the coder branch. The gh-token authorizes +// the clone + later push; it never enters the process env. +function checkoutRepo(repo, base, branch) { + const token = readSecret(GH_TOKEN_PATH); + if (!token) throw new Error("gh-token not present on tmpfs"); + const url = `https://x-access-token:${token}@github.com/${repo}.git`; + const dir = `${WORKSPACE}/repo`; + if (!fs.existsSync(dir)) { + sh("git", ["clone", "--depth", "1", "--branch", base, url, dir]); + } + sh("git", ["checkout", "-B", branch], { cwd: dir }); + return dir; +} + +// Run the pluggable coder. Claude Code headless routes to Bedrock via Bifrost +// (base-URL override); Kiro headless is the second profile. +function runProfile(profile, repoDir, spec) { + const key = readSecret(BIFROST_KEY_PATH); + if (!key) throw new Error("bifrost-api-key not present on tmpfs"); + const env = { + ...process.env, + ANTHROPIC_BASE_URL: BIFROST_URL, + ANTHROPIC_API_KEY: key, + CLAUDE_CODE_USE_BEDROCK: "1", + }; + if (profile === "kiro") { + // Kiro headless (spec-driven): spec β†’ requirements β†’ design β†’ tasks. + return sh("kiro", ["run", "--headless", "--spec", `${WORKSPACE}/SPEC.md`], { cwd: repoDir, env }); + } + // Default: Claude Code headless, non-interactive, prompted with the spec. + return sh( + "claude", + ["-p", `Implement the change described in ${WORKSPACE}/SPEC.md. Build and run unit tests until green. Commit your work.`], + { cwd: repoDir, env }, + ); +} + +// Build + unit tests. Auto-detects the toolchain; returns { green, summary }. +function buildAndTest(repoDir) { + let summary = ""; + for (let attempt = 1; attempt <= MAX_TEST_ATTEMPTS; attempt++) { + try { + if (fs.existsSync(`${repoDir}/package.json`)) { + sh("npm", ["install", "--no-audit", "--no-fund"], { cwd: repoDir }); + sh("npm", ["test"], { cwd: repoDir }); + } else if (fs.existsSync(`${repoDir}/go.mod`)) { + sh("go", ["test", "./..."], { cwd: repoDir }); + } else if (fs.existsSync(`${repoDir}/pyproject.toml`) || fs.existsSync(`${repoDir}/setup.py`)) { + sh("python", ["-m", "pytest", "-q"], { cwd: repoDir }); + } else { + return { green: true, summary: "no recognized test suite β€” skipped" }; + } + return { green: true, summary: `tests passed (attempt ${attempt})` }; + } catch (e) { + summary = (e.stdout || e.stderr || e.message || "").toString().slice(-500); + // Give the coder the failure reason and let it try again. + fs.writeFileSync(`${WORKSPACE}/RETRY.md`, `Test failure (attempt ${attempt}):\n${summary}\n`); + } + } + return { green: false, summary: `tests still failing after ${MAX_TEST_ATTEMPTS} attempts: ${summary}` }; +} + +function pushBranch(repoDir, branch) { + sh("git", ["push", "-u", "origin", branch, "--force-with-lease"], { cwd: repoDir }); +} + +function runOnce(runSpec) { + fs.mkdirSync(`${WORKSPACE}/artifacts`, { recursive: true }); + writeSpec(runSpec.spec); + const repoDir = checkoutRepo(runSpec.repo, runSpec.baseBranch, runSpec.branch); + runProfile(runSpec.profile, repoDir, runSpec.spec); + const test = buildAndTest(repoDir); + if (test.green) pushBranch(repoDir, runSpec.branch); + const result = { + branch: runSpec.branch, + testsGreen: test.green, + testSummary: test.summary, + summary: `Implemented per SPEC.md on ${runSpec.branch}.`, + }; + fs.writeFileSync(`${WORKSPACE}/artifacts/result.json`, JSON.stringify(result, null, 2)); + return result; +} + +const server = http.createServer((req, res) => { + if (req.method === "GET" && req.url === "/healthz") { + res.writeHead(200).end("ok"); + return; + } + if (req.method === "POST" && req.url === "/run") { + let buf = ""; + req.on("data", (c) => (buf += c)); + req.on("end", () => { + try { + const result = runOnce(JSON.parse(buf)); + res.writeHead(200, { "Content-Type": "application/json" }).end(JSON.stringify(result)); + } catch (e) { + console.error(`[coder] run failed: ${e.message}`); + res + .writeHead(200, { "Content-Type": "application/json" }) + .end(JSON.stringify({ testsGreen: false, testSummary: e.message })); + } + }); + return; + } + res.writeHead(404).end("not found"); +}); + +server.listen(PORT, "0.0.0.0", () => { + console.log(`[coder] agent listening on :${PORT} (workspace=${WORKSPACE}, bifrost=${BIFROST_URL})`); +}); diff --git a/examples/dark-factory/gitops-app.yaml b/examples/dark-factory/gitops-app.yaml new file mode 100644 index 0000000..66b9007 --- /dev/null +++ b/examples/dark-factory/gitops-app.yaml @@ -0,0 +1,38 @@ +# ArgoCD Application for the Dark Factory orchestrator (Flow B, P1). +# +# Deploys the orchestrator's k8s manifests onto spoke-dev ONLY. Flow B runs on +# spoke-dev exclusively (prod is never a test bed β€” see docs/dark-factory Β§10). +# The `destination.name: spoke-dev` pins it to the dev spoke; apply this on the +# hub ArgoCD (the same control plane that owns the agent-sandbox appsets). +# +# The coder image is not deployed here β€” it's referenced by the Flow A +# SandboxTemplate that the warm pool clones; the orchestrator only claims from +# that pool. Build + push both images (orchestrator, coder) to ECR and pin the +# tags before enabling. +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: dark-factory-orchestrator + namespace: argocd + labels: + app.kubernetes.io/part-of: dark-factory + annotations: + # After the agent-sandbox capability (Flow A) is up. + argocd.argoproj.io/sync-wave: "3" +spec: + project: default + source: + repoURL: https://github.com/aws-samples/sample-open-agentic-platform.git + targetRevision: dark-factory-autonomous-agent-coding-pattern + path: examples/dark-factory/orchestrator/k8s + destination: + # spoke-dev only β€” Flow B does not run on hub or prod. + name: spoke-dev + namespace: agent-sandbox-system + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=false # agent-sandbox-system is owned by Flow A + - ServerSideApply=true diff --git a/examples/dark-factory/orchestrator/Dockerfile b/examples/dark-factory/orchestrator/Dockerfile new file mode 100644 index 0000000..232e6b7 --- /dev/null +++ b/examples/dark-factory/orchestrator/Dockerfile @@ -0,0 +1,22 @@ +# Dark Factory orchestrator β€” small, non-root Node image. +# Purpose-built (not npm-install-at-start) so the trusted component is +# auditable and starts fast. The orchestrator holds credentials and talks to +# the Kubernetes API + GitHub, so it stays minimal. +FROM public.ecr.aws/docker/library/node:20-alpine + +WORKDIR /app + +# Install deps first for layer caching. Only @kubernetes/client-node. +COPY package.json ./ +RUN npm install --omit=dev --no-audit --no-fund + +COPY server.js ./ +COPY lib ./lib + +# Non-root: the orchestrator needs no privileges beyond its ServiceAccount RBAC. +USER 1000 + +ENV PORT=8080 +EXPOSE 8080 + +CMD ["node", "server.js"] diff --git a/examples/dark-factory/orchestrator/k8s/deployment.yaml b/examples/dark-factory/orchestrator/k8s/deployment.yaml new file mode 100644 index 0000000..ecd083e --- /dev/null +++ b/examples/dark-factory/orchestrator/k8s/deployment.yaml @@ -0,0 +1,94 @@ +# Dark Factory orchestrator β€” Deployment + Service. +# +# Runs on spoke-dev only (Flow B), on the general-purpose Auto Mode nodes (NOT +# the kata MNG β€” the orchestrator is trusted and holds no untrusted code, so it +# does not need micro-VM isolation). It reaches the coder sandbox over the +# pod network and the Kubernetes API via its ServiceAccount. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dark-factory-orchestrator + namespace: agent-sandbox-system + labels: + app: dark-factory-orchestrator + app.kubernetes.io/part-of: dark-factory +spec: + replicas: 1 + selector: + matchLabels: + app: dark-factory-orchestrator + template: + metadata: + labels: + app: dark-factory-orchestrator + app.kubernetes.io/part-of: dark-factory + spec: + serviceAccountName: dark-factory-orchestrator + securityContext: + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + containers: + - name: orchestrator + # Replace with the built image (ECR). Placeholder tag pinned by the + # GitOps values/kustomize overlay at deploy time. + image: public.ecr.aws/docker/library/node:20-alpine + command: ["node", "server.js"] + workingDir: /app + env: + - name: PORT + value: "8080" + - name: SANDBOX_NAMESPACE + value: agent-sandbox-system + - name: WARM_POOL_NAME + value: coder-warmpool + - name: BIFROST_URL + value: http://bifrost.bifrost.svc.cluster.local:8080 + - name: CODER_PROFILE + value: claude-code + ports: + - containerPort: 8080 + name: http + readinessProbe: + httpGet: + path: /healthz + port: http + initialDelaySeconds: 3 + periodSeconds: 10 + livenessProbe: + httpGet: + path: /healthz + port: http + initialDelaySeconds: 10 + periodSeconds: 30 + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] + resources: + requests: { cpu: 50m, memory: 96Mi } + limits: { cpu: 500m, memory: 256Mi } + volumeMounts: + - name: tmp + mountPath: /tmp + volumes: + - name: tmp + emptyDir: {} +--- +apiVersion: v1 +kind: Service +metadata: + name: dark-factory-orchestrator + namespace: agent-sandbox-system + labels: + app: dark-factory-orchestrator + app.kubernetes.io/part-of: dark-factory +spec: + selector: + app: dark-factory-orchestrator + ports: + - name: http + port: 8080 + targetPort: http diff --git a/examples/dark-factory/orchestrator/k8s/rbac.yaml b/examples/dark-factory/orchestrator/k8s/rbac.yaml new file mode 100644 index 0000000..669c70a --- /dev/null +++ b/examples/dark-factory/orchestrator/k8s/rbac.yaml @@ -0,0 +1,50 @@ +# Narrowly-scoped RBAC for the Dark Factory orchestrator. +# +# The orchestrator is trusted but still least-privilege: it only manages +# SandboxClaims (claim/inspect/release the warm pool) in the agent-sandbox +# namespace. It does NOT get pod/exec, secrets, or cluster scope β€” the coder +# runs in a Kata VM the orchestrator never shells into, and all model access is +# via Bifrost. This mirrors the openclaw session-router's trust invariants. +apiVersion: v1 +kind: ServiceAccount +metadata: + name: dark-factory-orchestrator + namespace: agent-sandbox-system + labels: + app: dark-factory-orchestrator + app.kubernetes.io/part-of: dark-factory +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: dark-factory-orchestrator + namespace: agent-sandbox-system + labels: + app: dark-factory-orchestrator + app.kubernetes.io/part-of: dark-factory +rules: + # Claim / inspect / release warm sandboxes. + - apiGroups: ["extensions.agents.x-k8s.io"] + resources: ["sandboxclaims"] + verbs: ["get", "list", "watch", "create", "delete"] + # Read the bound Sandbox + its pod IPs (status) β€” read-only. + - apiGroups: ["agents.x-k8s.io"] + resources: ["sandboxes"] + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: dark-factory-orchestrator + namespace: agent-sandbox-system + labels: + app: dark-factory-orchestrator + app.kubernetes.io/part-of: dark-factory +subjects: + - kind: ServiceAccount + name: dark-factory-orchestrator + namespace: agent-sandbox-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: dark-factory-orchestrator diff --git a/examples/dark-factory/orchestrator/lib/coder.js b/examples/dark-factory/orchestrator/lib/coder.js new file mode 100644 index 0000000..6b3f12e --- /dev/null +++ b/examples/dark-factory/orchestrator/lib/coder.js @@ -0,0 +1,80 @@ +// coder.js β€” drive the pluggable coder inside the bound Kata sandbox. +// +// The coder contract crosses the trust boundary as files + env only (Β§5): +// INPUTS /workspace/SPEC.md, /workspace/repo/ (branch df/issue-), +// tmpfs bifrost-api-key + gh-token (mode 0400) +// ENV CODER_PROFILE, BIFROST_URL +// OUTPUTS git branch df/issue- + /workspace/artifacts/result.json +// +// P1 talks to the coder over the sandbox's in-VM control endpoint (the coder +// image runs a tiny agent listening on :8080 that accepts a run spec and +// streams stage events). The orchestrator NEVER hands cloud credentials in β€” +// it only writes the spec and reads back result.json. Secrets reach the +// sandbox via projected tmpfs wired on the SandboxTemplate, out of band. +const http = require("http"); + +const CODER_PORT = parseInt(process.env.CODER_PORT || "8080", 10); +const CODER_RUN_TIMEOUT_MS = parseInt( + process.env.CODER_RUN_TIMEOUT_MS || "1800000", // 30 min + 10, +); + +function branchName(issueId) { + return `df/issue-${issueId}`; +} + +// POST the run spec to the coder agent inside the sandbox and await result.json. +// `host` is the bound sandbox pod IP (from SandboxClaim.status.sandbox.podIPs). +function runCoder(host, spec) { + return new Promise((resolve, reject) => { + const payload = JSON.stringify(spec); + const req = http.request( + { + host, + port: CODER_PORT, + path: "/run", + method: "POST", + headers: { + "Content-Type": "application/json", + "Content-Length": Buffer.byteLength(payload), + }, + timeout: CODER_RUN_TIMEOUT_MS, + }, + (res) => { + let buf = ""; + res.on("data", (c) => (buf += c)); + res.on("end", () => { + if (res.statusCode !== 200) { + return reject(new Error(`coder /run β†’ ${res.statusCode}: ${buf}`)); + } + try { + resolve(JSON.parse(buf)); // result.json + } catch (e) { + reject(new Error(`coder returned non-JSON result: ${buf.slice(0, 200)}`)); + } + }); + }, + ); + req.on("timeout", () => req.destroy(new Error("coder run timed out"))); + req.on("error", reject); + req.write(payload); + req.end(); + }); +} + +// Build the run spec the coder consumes. The issue body becomes SPEC.md; the +// target repo + branch tell the coder where to work. No secrets in here. +function buildRunSpec({ issueId, repo, issueTitle, issueBody, base }) { + return { + spec: `# ${issueTitle}\n\n${issueBody || ""}\n`, + repo, // e.g. "aws-samples/sample-open-agentic-platform" + baseBranch: base || "main", + branch: branchName(issueId), + profile: process.env.CODER_PROFILE || "claude-code", + // P1: implement β†’ build β†’ unit tests until green, then open nothing β€” + // the orchestrator opens the PR after verification stages. + tasks: ["implement", "build", "test"], + }; +} + +module.exports = { branchName, runCoder, buildRunSpec, CODER_PORT }; diff --git a/examples/dark-factory/orchestrator/lib/github.js b/examples/dark-factory/orchestrator/lib/github.js new file mode 100644 index 0000000..38bee0a --- /dev/null +++ b/examples/dark-factory/orchestrator/lib/github.js @@ -0,0 +1,114 @@ +// github.js β€” the ONE sticky PR status comment + PR creation. +// +// Flow B's canonical human surface (Β§7): the orchestrator maintains a single +// comment edited in place as each stage completes β€” no comment spam. The +// comment is found by a hidden marker so re-runs update the same comment. +// +// Uses the GitHub REST API directly (no SDK dep) with a short-TTL token the +// GitHub Action mints and hands to the orchestrator per run. The orchestrator +// holds the app credentials; the untrusted sandbox never sees this token. +const https = require("https"); + +const API = "api.github.com"; +const MARKER = ""; + +// Ordered pipeline stages shown in the sticky comment. P1 stops before the +// verification stages (holdout/security/devops arrive in P2/P3) β€” they render +// as pending placeholders so the surface is stable across phases. +const STAGES = [ + { key: "claim", label: "Claimed sandbox (spoke-dev)" }, + { key: "branch", label: "Branch" }, + { key: "implement", label: "Implement" }, + { key: "test", label: "Build + unit tests" }, + { key: "security", label: "Security Agent", phase: "P3" }, + { key: "devops", label: "DevOps Agent", phase: "P3" }, + { key: "holdout", label: "Holdout gate", phase: "P2" }, + { key: "pr", label: "PR ready for review" }, +]; + +function icon(state) { + return { done: "βœ…", now: "⏳", wait: "⬜", fail: "❌" }[state] || "⬜"; +} + +// Render the sticky comment body from a { stageKey: {state, at, note, log} } map. +function renderStatus(issueNumber, states) { + const lines = [MARKER, `## 🏭 Dark Factory β€” issue #${issueNumber}`, ""]; + for (const s of STAGES) { + const st = states[s.key] || { state: "wait" }; + const bits = [icon(st.state), s.label]; + if (st.note) bits.push(`Β· ${st.note}`); + if (s.phase && st.state === "wait") bits.push(`_(${s.phase})_`); + if (st.at) bits.push(`Β· ${st.at}`); + if (st.log) bits.push(`Β· [πŸ“„ log](${st.log})`); + lines.push(bits.join(" ")); + } + lines.push("", "_Human reviews **results, not diffs**. Approve the PR to merge + teardown._"); + return lines.join("\n"); +} + +function ghRequest(token, method, path, body) { + return new Promise((resolve, reject) => { + const data = body ? JSON.stringify(body) : null; + const req = https.request( + { + host: API, + method, + path, + headers: { + "User-Agent": "dark-factory-orchestrator", + Authorization: `Bearer ${token}`, + Accept: "application/vnd.github+json", + "X-GitHub-Api-Version": "2022-11-28", + ...(data ? { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(data) } : {}), + }, + }, + (res) => { + let buf = ""; + res.on("data", (c) => (buf += c)); + res.on("end", () => { + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(buf ? JSON.parse(buf) : {}); + } else { + reject(new Error(`GitHub ${method} ${path} β†’ ${res.statusCode}: ${buf}`)); + } + }); + }, + ); + req.on("error", reject); + if (data) req.write(data); + req.end(); + }); +} + +// Find our sticky comment on an issue/PR (they share the comments endpoint). +async function findStickyComment(token, repo, issueNumber) { + const comments = await ghRequest( + token, + "GET", + `/repos/${repo}/issues/${issueNumber}/comments?per_page=100`, + ); + return comments.find((c) => (c.body || "").includes(MARKER)); +} + +// Upsert the sticky comment (create once, then edit in place). +async function upsertStatus(token, repo, issueNumber, states) { + const body = renderStatus(issueNumber, states); + const existing = await findStickyComment(token, repo, issueNumber); + if (existing) { + return ghRequest(token, "PATCH", `/repos/${repo}/issues/comments/${existing.id}`, { body }); + } + return ghRequest(token, "POST", `/repos/${repo}/issues/${issueNumber}/comments`, { body }); +} + +// Open the PR for the coder's branch. Body carries the evidence report. +async function openPullRequest(token, repo, { head, base, title, body }) { + return ghRequest(token, "POST", `/repos/${repo}/pulls`, { + title, + head, + base: base || "main", + body, + maintainer_can_modify: true, + }); +} + +module.exports = { STAGES, renderStatus, upsertStatus, openPullRequest, findStickyComment }; diff --git a/examples/dark-factory/orchestrator/lib/k8s.js b/examples/dark-factory/orchestrator/lib/k8s.js new file mode 100644 index 0000000..160906e --- /dev/null +++ b/examples/dark-factory/orchestrator/lib/k8s.js @@ -0,0 +1,181 @@ +// k8s.js β€” Sandbox lifecycle against the Flow A warm pool. +// +// The orchestrator claims a pre-warmed Kata micro-VM from the agent-sandbox +// SandboxWarmPool (Flow A) via a SandboxClaim keyed on the GitHub issue id, +// waits for it to bind + become Ready, then tears it down on merge. This is +// the Flow B adaptation of the openclaw session-router: keyed on issue-id +// instead of a Cognito sub, and it binds a warm sandbox instead of creating a +// per-user Sandbox/PVC/Service. +// +// CRD facts (verified against the live v1beta1 CRDs on spoke-dev): +// group/version : extensions.agents.x-k8s.io/v1beta1 +// SandboxClaim.spec : warmPoolRef.name, env[]{containerName,name,value}, +// lifecycle{ttlSecondsAfterFinished,...} +// SandboxClaim.status : sandbox{name, podIPs[]}, conditions[] +const k8s = require("@kubernetes/client-node"); + +const GROUP = "extensions.agents.x-k8s.io"; +const VERSION = "v1beta1"; +const CLAIM_PLURAL = "sandboxclaims"; + +const NAMESPACE = process.env.SANDBOX_NAMESPACE || "agent-sandbox-system"; +const WARM_POOL = process.env.WARM_POOL_NAME || "coder-warmpool"; +const CLAIM_READY_TIMEOUT_MS = parseInt( + process.env.CLAIM_READY_TIMEOUT_MS || "120000", + 10, +); +// Hard TTL so a crashed/abandoned run's sandbox is reclaimed even if teardown +// never runs (the reaper is the other half of this safety net). +const CLAIM_TTL_SECONDS = parseInt( + process.env.CLAIM_TTL_SECONDS || "10800", + 10, +); + +const kc = new k8s.KubeConfig(); +kc.loadFromDefault(); // in-cluster SA when deployed; kubeconfig locally. +const customApi = kc.makeApiClient(k8s.CustomObjectsApi); + +// Retry with capped exponential backoff β€” the operator/apiserver can be +// briefly unavailable during a warm-pool refill. +async function withRetry(label, fn, { attempts = 4, baseMs = 500 } = {}) { + for (let i = 0; i < attempts; i++) { + try { + return await fn(); + } catch (e) { + if (i === attempts - 1) throw e; + const wait = baseMs * Math.pow(2, i); + console.warn( + `[k8s] ${label} failed (attempt ${i + 1}/${attempts}): ` + + `${e?.body?.message || e?.message || e}; retry in ${wait}ms`, + ); + await new Promise((r) => setTimeout(r, wait)); + } + } +} + +// Deterministic claim name per issue so re-delivered webhooks are idempotent +// (a second trigger for the same issue binds to the existing claim). +function claimName(issueId) { + return `df-issue-${String(issueId).replace(/[^a-z0-9-]/gi, "").toLowerCase()}`; +} + +function buildClaim(issueId, env = []) { + return { + apiVersion: `${GROUP}/${VERSION}`, + kind: "SandboxClaim", + metadata: { + name: claimName(issueId), + namespace: NAMESPACE, + labels: { + "dark-factory.io/managed-by": "orchestrator", + "dark-factory.io/issue": String(issueId), + }, + }, + spec: { + warmPoolRef: { name: WARM_POOL }, + // Per-container env the coder reads (BIFROST_URL, CODER_PROFILE, etc.). + // Secrets are NOT passed here β€” they arrive via projected tmpfs. + env: env.map((e) => ({ + containerName: e.containerName || "coder", + name: e.name, + value: String(e.value), + })), + lifecycle: { ttlSecondsAfterFinished: CLAIM_TTL_SECONDS }, + }, + }; +} + +// Claim a warm sandbox (idempotent). Returns the created/existing claim object. +async function claimSandbox(issueId, env) { + const name = claimName(issueId); + try { + const existing = await withRetry("claim get", () => + customApi.getNamespacedCustomObject( + GROUP, + VERSION, + NAMESPACE, + CLAIM_PLURAL, + name, + ), + ); + console.log(`[k8s] claim ${name} already exists β€” reusing`); + return existing.body; + } catch (e) { + if (e?.statusCode !== 404) throw e; + } + const created = await withRetry("claim create", () => + customApi.createNamespacedCustomObject( + GROUP, + VERSION, + NAMESPACE, + CLAIM_PLURAL, + buildClaim(issueId, env), + ), + ); + console.log(`[k8s] SandboxClaim ${name} created (warmPoolRef=${WARM_POOL})`); + return created.body; +} + +function isReady(claim) { + const conds = claim?.status?.conditions || []; + return conds.some((c) => c.type === "Ready" && c.status === "True"); +} + +// Poll the claim until the operator binds a warm sandbox and reports Ready. +// Returns { name, podIPs } of the bound sandbox. +async function waitForClaimBound(issueId, deadlineMs = CLAIM_READY_TIMEOUT_MS) { + const name = claimName(issueId); + const deadline = Date.now() + deadlineMs; + while (Date.now() < deadline) { + const { body: claim } = await customApi.getNamespacedCustomObject( + GROUP, + VERSION, + NAMESPACE, + CLAIM_PLURAL, + name, + ); + const bound = claim?.status?.sandbox?.name; + if (bound && isReady(claim)) { + return { + name: bound, + podIPs: claim.status.sandbox.podIPs || [], + }; + } + await new Promise((r) => setTimeout(r, 2000)); + } + throw new Error( + `SandboxClaim ${name} not Ready within ${deadlineMs}ms ` + + `(warm pool exhausted or sandbox failed to start?)`, + ); +} + +// Teardown β€” delete the claim; the operator releases the sandbox back / reaps +// it and the warm pool refills. Idempotent (404 is success). +async function releaseSandbox(issueId) { + const name = claimName(issueId); + try { + await withRetry("claim delete", () => + customApi.deleteNamespacedCustomObject( + GROUP, + VERSION, + NAMESPACE, + CLAIM_PLURAL, + name, + ), + ); + console.log(`[k8s] SandboxClaim ${name} deleted (sandbox released)`); + } catch (e) { + if (e?.statusCode === 404) return; + throw e; + } +} + +module.exports = { + NAMESPACE, + WARM_POOL, + claimName, + claimSandbox, + waitForClaimBound, + releaseSandbox, + withRetry, +}; diff --git a/examples/dark-factory/orchestrator/package.json b/examples/dark-factory/orchestrator/package.json new file mode 100644 index 0000000..b20b2c7 --- /dev/null +++ b/examples/dark-factory/orchestrator/package.json @@ -0,0 +1,16 @@ +{ + "name": "dark-factory-orchestrator", + "version": "0.1.0", + "private": true, + "description": "Dark Factory (Flow B) orchestrator β€” claims a warm Kata sandbox per GitHub issue, drives the coder, opens a PR with a live sticky status comment.", + "main": "server.js", + "scripts": { + "start": "node server.js" + }, + "engines": { + "node": ">=20" + }, + "dependencies": { + "@kubernetes/client-node": "^0.21.0" + } +} diff --git a/examples/dark-factory/orchestrator/server.js b/examples/dark-factory/orchestrator/server.js new file mode 100644 index 0000000..3a31078 --- /dev/null +++ b/examples/dark-factory/orchestrator/server.js @@ -0,0 +1,192 @@ +// server.js β€” Dark Factory orchestrator (Flow B, phase P1). +// +// Trigger β†’ claim warm sandbox β†’ drive the coder β†’ open PR with a live sticky +// status comment β†’ manual teardown. Runs on spoke-dev only, OUTSIDE the Kata +// sandbox, and is the trusted component: it holds the GitHub token (passed +// per-run by the Action) and β€” in later phases β€” AWS IAM. The untrusted coder +// sandbox never receives cloud credentials. +// +// Endpoints: +// POST /run { issue, repo, title, body, base, ghToken } β†’ start a run +// POST /teardown { issue, repo, ghToken } β†’ release sandbox +// GET /healthz +// +// This is the Flow B adaptation of the openclaw session-router: keyed on the +// GitHub issue id instead of a Cognito sub, and it binds a warm sandbox from +// the Flow A SandboxWarmPool via a SandboxClaim rather than creating per-user +// resources. +const http = require("http"); +const k8s = require("./lib/k8s"); +const gh = require("./lib/github"); +const coder = require("./lib/coder"); + +const PORT = parseInt(process.env.PORT || "8080", 10); +const BIFROST_URL = + process.env.BIFROST_URL || "http://bifrost.bifrost.svc.cluster.local:8080"; + +function now() { + // Wall-clock HH:MM stamp for the sticky comment. Uses the process TZ. + return new Date().toISOString().slice(11, 16); +} + +async function readJson(req) { + return new Promise((resolve, reject) => { + let buf = ""; + req.on("data", (c) => (buf += c)); + req.on("end", () => { + try { + resolve(buf ? JSON.parse(buf) : {}); + } catch (e) { + reject(e); + } + }); + req.on("error", reject); + }); +} + +// Run the P1 pipeline for one issue. Updates the sticky comment at each stage +// so the human watches the factory work in real time. +async function runPipeline({ issue, repo, title, body, base, ghToken }) { + const states = {}; + const push = async (key, patch) => { + states[key] = { ...(states[key] || {}), ...patch }; + try { + await gh.upsertStatus(ghToken, repo, issue, states); + } catch (e) { + console.error(`[orch] status update failed: ${e.message}`); + } + }; + + // Seed the comment with all stages pending, first one in progress. + await push("claim", { state: "now" }); + + // 1) Claim a warm sandbox (instant if the pool has buffer). + await k8s.claimSandbox(issue, [ + { name: "BIFROST_URL", value: BIFROST_URL }, + { name: "CODER_PROFILE", value: process.env.CODER_PROFILE || "claude-code" }, + ]); + const bound = await k8s.waitForClaimBound(issue); + await push("claim", { state: "done", at: now(), note: bound.name }); + + if (!bound.podIPs.length) { + throw new Error(`bound sandbox ${bound.name} reported no pod IPs`); + } + const host = bound.podIPs[0]; + + // 2) Drive the coder: SPEC.md + branch + implement/build/test until green. + await push("branch", { state: "done", at: now(), note: coder.branchName(issue) }); + await push("implement", { state: "now" }); + + const runSpec = coder.buildRunSpec({ + issueId: issue, + repo, + issueTitle: title, + issueBody: body, + base, + }); + const result = await coder.runCoder(host, runSpec); + + await push("implement", { state: "done", at: now() }); + const testState = result.testsGreen ? "done" : "fail"; + await push("test", { + state: testState, + at: now(), + log: result.logUrl, + note: result.testSummary, + }); + if (!result.testsGreen) { + throw new Error(`coder could not get tests green: ${result.testSummary || "unknown"}`); + } + + // 3) Verification stages are P2/P3 β€” leave them pending in the surface. + + // 4) Open the PR with the evidence report. P1 = no auto-merge; the human + // approves. Branch protections + CI still apply. + await push("pr", { state: "now" }); + const pr = await gh.openPullRequest(ghToken, repo, { + head: coder.branchName(issue), + base: base || "main", + title: `Dark Factory: ${title} (#${issue})`, + body: prBody(issue, result), + }); + await push("pr", { state: "done", at: now(), note: `#${pr.number}` }); + + console.log(`[orch] issue #${issue} β†’ PR #${pr.number} (${pr.html_url})`); + return { pr: pr.number, url: pr.html_url, sandbox: bound.name }; +} + +function prBody(issue, result) { + return [ + `Closes #${issue}.`, + "", + "## 🏭 Dark Factory report", + "", + "_Autonomously implemented in a hardware-isolated Kata micro-VM (spoke-dev)._", + "_Review the **evidence** below, not the diff line-by-line._", + "", + `- **Build + unit tests:** ${result.testsGreen ? "βœ… green" : "❌ failing"}` + + (result.testSummary ? ` β€” ${result.testSummary}` : ""), + result.logUrl ? `- **Logs:** ${result.logUrl}` : "", + "- **Holdout gate:** _pending (P2)_", + "- **Security / DevOps agents:** _pending (P3)_", + "", + result.summary ? `### What changed\n\n${result.summary}` : "", + ] + .filter(Boolean) + .join("\n"); +} + +const server = http.createServer(async (req, res) => { + try { + if (req.method === "GET" && req.url === "/healthz") { + res.writeHead(200).end("ok"); + return; + } + + if (req.method === "POST" && req.url === "/run") { + const b = await readJson(req); + for (const f of ["issue", "repo", "ghToken"]) { + if (!b[f]) { + res.writeHead(400).end(`missing field: ${f}`); + return; + } + } + // Acknowledge immediately; run the pipeline in the background so the + // Action's HTTP call doesn't hold open for the whole build. + res.writeHead(202).end(JSON.stringify({ accepted: true, issue: b.issue })); + runPipeline(b).catch(async (e) => { + console.error(`[orch] pipeline failed for #${b.issue}: ${e.message}`); + try { + const states = { test: { state: "fail", note: e.message.slice(0, 120) } }; + await gh.upsertStatus(b.ghToken, b.repo, b.issue, states); + } catch (_) { + /* best-effort */ + } + }); + return; + } + + if (req.method === "POST" && req.url === "/teardown") { + const b = await readJson(req); + if (!b.issue) { + res.writeHead(400).end("missing field: issue"); + return; + } + await k8s.releaseSandbox(b.issue); + res.writeHead(200).end(JSON.stringify({ released: true, issue: b.issue })); + return; + } + + res.writeHead(404).end("not found"); + } catch (e) { + console.error(`[orch] request error: ${e.message}`); + res.writeHead(500).end(e.message); + } +}); + +server.listen(PORT, "0.0.0.0", () => { + console.log( + `[orch] Dark Factory orchestrator listening on :${PORT} ` + + `(ns=${k8s.NAMESPACE}, warmPool=${k8s.WARM_POOL})`, + ); +}); diff --git a/gitops/addons/bootstrap/default/addons.yaml b/gitops/addons/bootstrap/default/addons.yaml index 7ad6396..e8384a0 100644 --- a/gitops/addons/bootstrap/default/addons.yaml +++ b/gitops/addons/bootstrap/default/addons.yaml @@ -358,3 +358,101 @@ oam-agent-components: global: awsRegion: '{{.metadata.annotations.aws_region}}' clusterName: '{{.metadata.annotations.aws_cluster_name}}' + +# Agent Sandbox OPERATOR (upstream agent-sandbox v0.5.1) β€” the controller + +# Sandbox/SandboxClaim/SandboxTemplate/SandboxWarmPool CRDs + webhooks. Vendored +# manifest applied directly (it's a self-contained install; the ~400KB CRD set +# is too large for a Helm-templated chart). ServerSideApply + Replace handle the +# oversized CRDs. Sync-wave 0: CRDs + operator MUST exist before the kata-deploy +# runtime (wave 1) and the agent-sandbox chart CRs (wave 2). +agent-sandbox-operator: + enabled: true + namespace: agent-sandbox-system + defaultVersion: '0.5.1' + path: 'gitops/addons/charts/agent-sandbox/upstream' + annotationsAppSet: + argocd.argoproj.io/sync-wave: '0' + syncPolicyAppSet: + preserveResourcesOnDeletion: false + # Agent Sandbox is a spoke-dev-only capability (Kata needs a nested-virt MNG; + # not on the hub, and prod stays off). alwaysSelector is honored regardless of + # the global useSelectors flag, so the generated ApplicationSet matches ONLY + # the cluster whose `environment` label is `dev` β€” hub and prod apps are pruned. + alwaysSelector: + matchExpressions: + - key: environment + operator: In + values: ['dev'] + +# Agent Sandbox capability chart β€” RuntimeClasses, kata-readiness (removes the +# runtime-not-ready startup taint), coder SandboxTemplate, SandboxWarmPool, and +# the egress NetworkPolicy. Sync-wave 2: after the operator (wave 0) + kata +# runtime (wave 1). Consumers (the Dark Factory, Flow B) then claim from the +# warm pool via a SandboxClaim(warmPoolRef). +agent-sandbox: + enabled: true + namespace: agent-sandbox-system + defaultVersion: '0.1.0' + path: 'gitops/addons/charts/agent-sandbox' + annotationsAppSet: + argocd.argoproj.io/sync-wave: '2' + # Spoke-dev-only (see agent-sandbox-operator note above). alwaysSelector pins + # generation to the `environment: dev` cluster regardless of useSelectors. + alwaysSelector: + matchExpressions: + - key: environment + operator: In + values: ['dev'] + valuesObject: + coderTemplate: + bifrostUrl: '{{default "http://bifrost.bifrost.svc.cluster.local:8080" (index .metadata.annotations "bifrost_url")}}' + +# kata-deploy β€” installs the Kata runtime (containerd handlers for kata-clh / +# kata-qemu) on the tainted kata MNG nodes. Separate app (not a subchart dep of +# agent-sandbox) so ArgoCD pulls the upstream OCI chart directly. Gated by +# enable_agent_sandbox_kata β€” only clusters with a kata-capable nested-virt MNG +# (see docs/dark-factory Β§12a) should carry that label. Sync-wave 1: runtime is +# installed on nodes before the Sandbox operator (wave 2) schedules VMs. +kata-deploy: + enabled: true + namespace: kube-system + chartName: kata-deploy + defaultVersion: '3.32.0' + # OCI chart at oci://ghcr.io/kata-containers/kata-deploy-charts/kata-deploy. + # Do NOT set chartNamespace β€” the appset would build chart=/ + # (kata-containers/kata-deploy) producing a wrong OCI path. The namespace is + # already part of chartRepository. + chartRepository: 'ghcr.io/kata-containers/kata-deploy-charts' + annotationsAppSet: + argocd.argoproj.io/sync-wave: '1' + # Spoke-dev-only: the kata runtime is only installed where a nested-virt MNG + # exists (spoke-dev). alwaysSelector pins generation to `environment: dev` + # regardless of useSelectors β€” no hub or prod kata-deploy app. + alwaysSelector: + matchExpressions: + - key: environment + operator: In + values: ['dev'] + valuesObject: + kata-deploy: + image: + reference: quay.io/kata-containers/kata-deploy + tag: '3.32.0' + nodeSelector: + kata-enabled: 'true' + tolerations: + - key: kata + operator: Equal + value: 'true' + effect: NoSchedule + - key: katacontainers.io/runtime-not-ready + operator: Exists + effect: NoSchedule + shims: + disableAll: true + qemu: + enabled: true + clh: + enabled: true + runtimeClasses: + enabled: false diff --git a/gitops/addons/charts/agent-sandbox/Chart.yaml b/gitops/addons/charts/agent-sandbox/Chart.yaml new file mode 100644 index 0000000..1f8e75d --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/Chart.yaml @@ -0,0 +1,26 @@ +apiVersion: v2 +name: agent-sandbox +description: >- + Agent Sandbox capability for the Open Agent Platform β€” hardware-isolated + Kata micro-VM sandboxes (agents.x-k8s.io Sandbox CRD) with a pre-warmed pool + kept ready by a pool-manager controller. The reusable isolation substrate any + agent workload (e.g. the Dark Factory coding pipeline) can claim on demand. +type: application +version: 0.1.0 +appVersion: "0.1.0" +keywords: + - kata + - sandbox + - isolation + - micro-vm + - dark-factory +sources: + - https://github.com/aws-samples/sample-open-agentic-platform + - https://github.com/elamaran11/eks-platform-openclaw +maintainers: + - name: Open Agent Platform +# NOTE: kata-deploy (the Kata runtime installer) is NOT bundled as a subchart +# dependency β€” an OCI subchart dep would block this chart from rendering when +# unbuilt and is fragile under ArgoCD. Instead it is delivered as a separate, +# gated ArgoCD Application (enable_agent_sandbox_kata) that pulls the upstream +# OCI chart directly. See the addon catalog + docs/dark-factory Β§12a. diff --git a/gitops/addons/charts/agent-sandbox/README.md b/gitops/addons/charts/agent-sandbox/README.md new file mode 100644 index 0000000..18c5a73 --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/README.md @@ -0,0 +1,56 @@ +# agent-sandbox + +**Flow A of the [Dark Factory pattern](../../../../docs/dark-factory/README.md).** +Hardware-isolated **Kata micro-VM sandboxes** (`agents.x-k8s.io` Sandbox CRD) with a **pre-warmed +pool** kept ready by a pool-manager controller β€” the reusable isolation substrate any agent +workload (notably the Dark Factory coding pipeline) can claim on demand. + +## What it installs + +| Template | Resource | Purpose | +|---|---|---| +| `00-namespace.yaml` | Namespace (PSS `restricted`) | Runs the capability; enforces restricted Pod Security | +| `05-operator.yaml` | SA + ClusterRole + StatefulSet + Service | The `agents.x-k8s.io` controller (materializes a Kata-VM pod per Sandbox) | +| `10-runtimeclasses.yaml` | RuntimeClass Γ—N | `kata-clh` (default), `kata-qemu` β€” steer pods onto kata Karpenter pools | +| `20-sandboxtemplate.yaml` | SandboxTemplate | The coder pod spec the warm pool clones (isolation invariants baked in) | +| `30-networkpolicy.yaml` | NetworkPolicy | Default-deny egress β†’ DNS + Bifrost + HTTPS only (breaks the lethal trifecta) | +| `40-poolmanager-rbac.yaml` | SA + Role + RoleBinding | Narrowly-scoped RBAC for the pool-manager | +| `41-poolmanager-cronjob.yaml` | CronJob | Reconciles the warm buffer: refill / scale-to-zero / reap | + +## Enable + +```yaml +# gitops/overlays/environments/{dev,prod}/enabled-addons.yaml +enabledAddons: + agent_sandbox: true +``` + +The ApplicationSet cluster-generator (sync-wave 2) fans the chart onto any cluster carrying the +`enable_agent_sandbox` label. Installed on **spoke-dev and spoke-prod**; the Dark Factory pipeline +only *runs* on spoke-dev (prod pool stays dormant). + +## Key values + +| Value | Default | Purpose | +|---|---|---| +| `kata.defaultRuntimeClass` | `kata-clh` | VMM for coder sandboxes | +| `warmPool.targetIdle` | `3` | Idle sandboxes kept ready | +| `warmPool.idleScaleToZeroSeconds` | `900` | Idle β†’ `replicas:0` (PVC kept) | +| `warmPool.reapAfterSeconds` | `3600` | Reap abandoned claimed sandboxes | +| `coderTemplate.bifrostUrl` | `http://bifrost.bifrost.svc.cluster.local:8080` | LLM gateway (Bifrost, not LiteLLM) | + +## Prerequisites + +- **Kata runtime installed on nodes** (via `kata-deploy` + kata Karpenter pools from the base + platform / `eks-platform-openclaw`). +- **Sandbox CRDs** (`Sandbox`, `SandboxTemplate`, `SandboxClaim`) applied at an earlier sync-wave + from the upstream operator bundle (`public.ecr.aws/t6v6o5d5/agent-sandbox:v0.1.0`) β€” the ~4k-line + OpenAPI schema is not vendored into this chart. +- **Bifrost** LLM gateway reachable at the configured URL. + +## Notes + +- The pool-manager is a CronJob (kubectl + jq reconcile loop) for a dependency-free reference + implementation; swap for a real controller if reconcile latency matters. +- `warmPool.enabled=false` removes the pool-manager entirely (operator + RuntimeClasses + template + remain, for manual/consumer-driven claims). diff --git a/gitops/addons/charts/agent-sandbox/nodepool/README.md b/gitops/addons/charts/agent-sandbox/nodepool/README.md new file mode 100644 index 0000000..b1e5e8d --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/nodepool/README.md @@ -0,0 +1,97 @@ +# Kata node pool provisioning + +The `agent-sandbox` chart installs the Sandbox operator, RuntimeClasses, coder +template, and pool-manager β€” but Kata needs **hardware-virtualization nodes** to +actually run micro-VMs. On an **EKS Auto Mode** cluster (like the spokes), Auto +Mode's managed Bottlerocket nodes can't host Kata, so we add a **self-managed +nested-virt Managed Node Group** alongside Auto Mode. Coexistence + `/dev/kvm` +were validated by a live spike (see [`docs/dark-factory` Β§12a](../../../../../docs/dark-factory/README.md)). + +## Files here + +| File | Purpose | +|---|---| +| `kata-mng-eksctl.yaml` | eksctl `ClusterConfig` to add the kata MNG (declarative, simplest) | +| `kata-mng.tf` | Terraform launch template (`cpu_options.nested_virtualization=enabled`) + MNG β€” use when you need the nested-virt flag eksctl can't set. `terraform validate` passes. | +| `kata-mng-launch-template-userdata.mime` | The AL2023 **nodeadm MIME** userData (modprobe kvm_intel + join). Reference for either path. | + +## βœ… PROVEN END-TO-END on EKS Auto Mode (spoke-dev, 2026-07-10) + +Kata micro-VMs **do run on an Auto Mode cluster** via a self-managed nested-virt MNG. +Verified with a pod under `runtimeClassName: kata-clh`: + +| | Value | +|---|---| +| Pod kernel (`uname -r` inside) | **`6.18.35`** β€” the Kata guest kernel | +| Host node kernel | `6.12.90-…amzn2023` | + +Different kernels β‡’ the pod ran in a **real VM with hardware isolation**, not a container. + +### The two Auto-Mode-specific prerequisites (the crux) + +Auto Mode's built-in networking applies ONLY to its own managed nodes. A self-managed +MNG node has **neither the CNI nor kube-proxy** that pods need β€” so you MUST install +both EKS addons, or pods on the kata node can't reach the API server: + +``` +aws eks create-addon --cluster-name --addon-name vpc-cni --resolve-conflicts OVERWRITE +aws eks create-addon --cluster-name --addon-name kube-proxy --resolve-conflicts OVERWRITE +``` + +- **Without `vpc-cni`** β†’ node stays `NotReady` (`cni plugin not initialized`). +- **Without `kube-proxy`** β†’ the node has no iptables rules for the `kubernetes.default.svc` + (172.20.0.1) service IP, so **kata-deploy crashloops** with `Failed to get node ... + client error (Connect)` β€” it connects to the API via the in-cluster service and times + out. This was the real blocker (NOT the containerd restart, and not the nydus + snapshotter β€” both were red herrings). Installing kube-proxy fixed it; kata-deploy then + reached `1/1 Running` with **zero restarts** and installed the runtime cleanly. + +Both `aws-node` and `kube-proxy` tolerate all taints (`operator: Exists`), so they land +on the tainted kata node automatically. + +### The startup-taint gate (from openclaw PR #10) + +The kata node registers with **two** taints: +- `kata=true:NoSchedule` β€” workload taint (only kata pods run here) +- `katacontainers.io/runtime-not-ready=true:NoSchedule` β€” **startup taint**; blocks all + workloads until the runtime is installed. Set via nodeadm + `--register-with-taints`. The **`kata-readiness` DaemonSet** watches kata-deploy's + `/readyz` and removes this taint once install completes β€” proven to work here + (`node ... untainted` in its log). + +### IAM access-entry gotcha (lesson from this test) + +If you recreate the node IAM role, its principal ID changes β€” **delete and recreate the +EKS access entry** (`type EC2_LINUX`) or the node's kubelet gets `Unauthorized` and never +registers. A stale access entry pointing at an old role ID is silent and confusing. + +## Enablement sequence (per kata-capable cluster, e.g. spoke-dev) + +1. **Provision the kata MNG** β€” apply the eksctl or Terraform manifest here. Nodes + come up tainted `kata=true:NoSchedule`, labeled `kata-enabled=true`, with + `/dev/kvm` (nested-virt) and `min=0` scale-to-zero. On Auto Mode, ensure the + `vpc-cni` addon is installed (see prerequisite above) or the node stays NotReady. +2. **Install the runtime** β€” label the cluster secret `enable_agent_sandbox_kata=true` + so the `kata-deploy` ArgoCD app (sync-wave 1) installs the containerd handlers. +3. **Install the capability** β€” label `enable_agent_sandbox=true` so the + `agent-sandbox` app (sync-wave 2) installs the operator + RuntimeClasses + + template + pool-manager. +4. **Enable the pool** β€” `warmPool.enabled=true` (default) pre-warms idle sandboxes. + +> Both labels are set via the environment overlays (`gitops/overlays/environments/dev`). +> They are commented out today until a kata MNG exists on the spokes. + +## Cost note + +Nested-virt `c8i`/`m8i` nodes are more expensive than the `c6*` Auto Mode +defaults. `min=0` scale-to-zero + the pool-manager's idle scale-down keep cost +proportional to actual sandbox activity β€” you pay for kata nodes only while a +sandbox is claimed/warming. + +## Teardown (spike lesson #2) + +Delete the **MNG first and let it drain** (set `min/desired=0` beforehand). Don't +terminate the instance out from under the MNG β€” the ASG respawns and can wedge +the delete on a `Pending:Wait` lifecycle hook. Recover with +`aws autoscaling terminate-instance-in-auto-scaling-group` + +`complete-lifecycle-action`. diff --git a/gitops/addons/charts/agent-sandbox/nodepool/kata-mng-eksctl.yaml b/gitops/addons/charts/agent-sandbox/nodepool/kata-mng-eksctl.yaml new file mode 100644 index 0000000..ebbca9b --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/nodepool/kata-mng-eksctl.yaml @@ -0,0 +1,50 @@ +# Self-managed nested-virt Managed Node Group for Kata sandboxes, added to an +# existing EKS Auto Mode cluster (spoke-dev). Auto Mode keeps running everything +# else; kata sandboxes schedule here via the kata=true taint. Validated by the +# 2026-07-10 spike (see docs/dark-factory Β§12a). +# +# Apply: eksctl create nodegroup -f kata-mng-eksctl.yaml +# Requires eksctl with EKS Auto Mode coexistence support and an AMI/instance +# that exposes nested virtualization (c8i/m8i). +apiVersion: eksctl.io/v1alpha5 +kind: ClusterConfig + +metadata: + name: spoke-dev # target cluster + region: us-west-2 + +managedNodeGroups: + - name: kata-sandbox + # Nested-virt Intel instances (expose VT-x via CpuOptions.NestedVirtualization). + instanceTypes: ["c8i.4xlarge", "m8i.4xlarge"] + amiFamily: AmazonLinux2023 + minSize: 0 # scale-to-zero when no sandbox is claimed + maxSize: 3 + desiredCapacity: 1 + privateNetworking: true + volumeSize: 100 + # Labels applied at node birth: kata-enabled is the STATIC label kata-deploy + # targets; katacontainers.io/kata-runtime is (re)emitted by kata-deploy. + labels: + kata-enabled: "true" + katacontainers.io/kata-runtime: "true" + node-type: kata-mng + # Only kata sandboxes tolerate this taint β€” keeps general workloads off. + taints: + - key: kata + value: "true" + effect: NoSchedule + # nested virtualization + the modprobe/nodeadm userData are supplied via a + # launch template (eksctl overrideBootstrapCommand cannot set CpuOptions). + # See kata-mng-launch-template-userdata.mime and the Terraform variant. + # launchTemplate: + # id: lt-xxxxxxxx + tags: + platform: open-agent-platform + capability: agent-sandbox + iam: + attachPolicyARNs: + - arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy + - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy + - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly + - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore diff --git a/gitops/addons/charts/agent-sandbox/nodepool/kata-mng-launch-template-userdata.mime b/gitops/addons/charts/agent-sandbox/nodepool/kata-mng-launch-template-userdata.mime new file mode 100644 index 0000000..96e8b1c --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/nodepool/kata-mng-launch-template-userdata.mime @@ -0,0 +1,48 @@ +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="//" + +--// +Content-Type: text/x-shellscript; charset="us-ascii" + +#!/bin/bash +# Load the KVM module so /dev/kvm exists BEFORE the node goes Ready. +# cpuOptions.NestedVirtualization on the launch template only makes VT-x +# *visible*; the stock AL2023 image does not auto-load kvm_intel. Persist it so +# it survives reboots. (Lesson from the spike: setting nested-virt without this +# gives a node with no /dev/kvm.) +modprobe kvm_intel +printf 'kvm\nkvm_intel\n' > /etc/modules-load.d/kvm.conf + +--// +Content-Type: application/node.eks.aws + +# nodeadm NodeConfig β€” this is what actually joins the node to the cluster. +# CRITICAL (spike lesson #1): do NOT replace this with a plain-bash bootstrap or +# a custom AMI without nodeadm β€” the node will boot with /dev/kvm but never +# register with the control plane. +# +# LESSON #3 (live test): when you supply a CUSTOM ImageId in the launch template, +# nodeadm does NOT auto-discover the cluster API endpoint/CA β€” you must set +# apiServerEndpoint, certificateAuthority, and cidr explicitly, or nodeadm fails +# with "Apiserver endpoint is missing in cluster configuration". (The default +# EKS AMI path injects these for you; a custom AMI does not.) Substitute the +# cluster name + the three cluster values at render: +# aws eks describe-cluster --name \ +# --query 'cluster.{e:endpoint,ca:certificateAuthority.data,cidr:kubernetesNetworkConfig.serviceIpv4Cidr}' +apiVersion: node.eks.aws/v1alpha1 +kind: NodeConfig +spec: + cluster: + name: CLUSTER_NAME_PLACEHOLDER + apiServerEndpoint: API_SERVER_ENDPOINT_PLACEHOLDER + certificateAuthority: CERTIFICATE_AUTHORITY_DATA_PLACEHOLDER + cidr: SERVICE_IPV4_CIDR_PLACEHOLDER + kubelet: + flags: + # Labels + taint applied at node birth so kata-deploy schedules and the + # RuntimeClass nodeSelector matches. kata-enabled is the STATIC label + # kata-deploy targets; katacontainers.io/kata-runtime is emitted by + # kata-deploy after install. + - "--node-labels=kata-enabled=true,katacontainers.io/kata-runtime=true,node-type=kata-mng" + - "--register-with-taints=kata=true:NoSchedule" +--//-- diff --git a/gitops/addons/charts/agent-sandbox/nodepool/kata-mng.tf b/gitops/addons/charts/agent-sandbox/nodepool/kata-mng.tf new file mode 100644 index 0000000..71ae343 --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/nodepool/kata-mng.tf @@ -0,0 +1,126 @@ +# Terraform variant: nested-virt Kata Managed Node Group + launch template for +# an existing EKS Auto Mode cluster. Use this path when you need the launch +# template's CpuOptions.NestedVirtualization flag (eksctl cannot set it). +# Validated by the 2026-07-10 spike (docs/dark-factory Β§12a). +# +# Requires: aws provider (nested_virtualization support), AWS API/CLI vintage +# that exposes cpu_options.nested_virtualization. + +variable "cluster_name" { + type = string + default = "spoke-dev" +} +variable "region" { + type = string + default = "us-west-2" +} +variable "subnet_ids" { + type = list(string) +} +variable "node_role_arn" { + type = string +} +variable "instance_type" { + type = string + default = "c8i.4xlarge" +} +variable "kata_max_size" { + type = number + default = 3 +} + +# EKS-optimized AL2023 AMI for the cluster's k8s version (nodeadm bootstrap). +data "aws_ssm_parameter" "al2023" { + name = "/aws/service/eks/optimized-ami/1.35/amazon-linux-2023/x86_64/standard/recommended/image_id" +} + +# Cluster endpoint/CA/cidr β€” REQUIRED in the NodeConfig when using a custom AMI +# (lesson #3, live test): nodeadm does not auto-discover these with a custom +# ImageId and fails with "Apiserver endpoint is missing in cluster configuration". +data "aws_eks_cluster" "this" { + name = var.cluster_name +} + +locals { + # MIME userData: modprobe kvm_intel (so /dev/kvm exists) + nodeadm NodeConfig + # that joins the cluster with the kata labels/taint. See Β§12a lessons #1 + #3. + kata_userdata = base64encode(<<-MIME + MIME-Version: 1.0 + Content-Type: multipart/mixed; boundary="//" + + --// + Content-Type: text/x-shellscript; charset="us-ascii" + + #!/bin/bash + modprobe kvm_intel + printf 'kvm\nkvm_intel\n' > /etc/modules-load.d/kvm.conf + + --// + Content-Type: application/node.eks.aws + + apiVersion: node.eks.aws/v1alpha1 + kind: NodeConfig + spec: + cluster: + name: ${var.cluster_name} + apiServerEndpoint: ${data.aws_eks_cluster.this.endpoint} + certificateAuthority: ${data.aws_eks_cluster.this.certificate_authority[0].data} + cidr: ${data.aws_eks_cluster.this.kubernetes_network_config[0].service_ipv4_cidr} + kubelet: + flags: + - "--node-labels=kata-enabled=true,katacontainers.io/kata-runtime=true,node-type=kata-mng" + - "--register-with-taints=kata=true:NoSchedule" + --//-- + MIME + ) +} + +resource "aws_launch_template" "kata" { + name_prefix = "${var.cluster_name}-kata-" + image_id = data.aws_ssm_parameter.al2023.value + user_data = local.kata_userdata + + cpu_options { + # THE key flag β€” exposes VT-x on 8i instances so kata's VMM can run guests. + nested_virtualization = "enabled" + } + + tag_specifications { + resource_type = "instance" + tags = { platform = "open-agent-platform", capability = "agent-sandbox" } + } +} + +resource "aws_eks_node_group" "kata" { + cluster_name = var.cluster_name + node_group_name = "kata-sandbox" + node_role_arn = var.node_role_arn + subnet_ids = var.subnet_ids + + # Scale-to-zero when no sandbox is claimed; pool-manager / consumer scales up. + scaling_config { + min_size = 0 + desired_size = 1 + max_size = var.kata_max_size + } + + launch_template { + id = aws_launch_template.kata.id + version = aws_launch_template.kata.latest_version + } + + # Only kata sandboxes tolerate this β€” keeps general workloads off the pool. + taint { + key = "kata" + value = "true" + effect = "NO_SCHEDULE" + } + + labels = { + "kata-enabled" = "true" + "katacontainers.io/kata-runtime" = "true" + "node-type" = "kata-mng" + } + + tags = { platform = "open-agent-platform", capability = "agent-sandbox" } +} diff --git a/gitops/addons/charts/agent-sandbox/templates/00-namespace.yaml b/gitops/addons/charts/agent-sandbox/templates/00-namespace.yaml new file mode 100644 index 0000000..f62077c --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/templates/00-namespace.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: {{ include "agent-sandbox.namespace" . }} + labels: + {{- include "agent-sandbox.labels" . | nindent 4 }} + # PSS = baseline (NOT restricted). This namespace hosts BOTH the coder + # sandboxes AND the agent-sandbox operator/kata-readiness β€” and the upstream + # operator + kata tooling are not restricted-compliant (they'd be blocked). + # The coder sandboxes get their real isolation from the KATA micro-VM + # boundary + the restricted securityContext baked into the SandboxTemplate + # pod spec β€” not from namespace PSS. (Live-test lesson: restricted here + # blocks the v0.5.1 controller pod entirely.) + pod-security.kubernetes.io/enforce: baseline + pod-security.kubernetes.io/audit: restricted + pod-security.kubernetes.io/warn: restricted diff --git a/gitops/addons/charts/agent-sandbox/templates/10-runtimeclasses.yaml b/gitops/addons/charts/agent-sandbox/templates/10-runtimeclasses.yaml new file mode 100644 index 0000000..cf7e3e4 --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/templates/10-runtimeclasses.yaml @@ -0,0 +1,22 @@ +{{- /* +Kata RuntimeClasses. A workload selects a VMM with `runtimeClassName: kata-clh` +(or kata-qemu). The RuntimeClass admission controller force-merges the +scheduling.nodeSelector + tolerations below onto the pod, steering it onto the +matching Karpenter kata pool. The runtime binaries themselves are installed on +the node by kata-deploy (a prerequisite provided by the base platform). +*/ -}} +{{- range .Values.kata.runtimeClasses }} +--- +apiVersion: node.k8s.io/v1 +kind: RuntimeClass +metadata: + name: {{ .name }} + labels: + {{- include "agent-sandbox.labels" $ | nindent 4 }} +handler: {{ .handler }} +scheduling: + nodeSelector: + {{- toYaml $.Values.kata.nodeSelector | nindent 4 }} + tolerations: + {{- toYaml $.Values.kata.tolerations | nindent 4 }} +{{- end }} diff --git a/gitops/addons/charts/agent-sandbox/templates/15-kata-readiness.yaml b/gitops/addons/charts/agent-sandbox/templates/15-kata-readiness.yaml new file mode 100644 index 0000000..91f2b82 --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/templates/15-kata-readiness.yaml @@ -0,0 +1,113 @@ +{{- if .Values.kataReadiness.enabled }} +{{- /* +kata-readiness β€” removes the katacontainers.io/runtime-not-ready STARTUP TAINT +once kata-deploy finishes installing the runtime on a node. + +Why needed (live-test lesson): kata nodes register with a runtime-not-ready +startup taint so no workload binds before the runtime exists. kata-deploy does +NOT remove that taint itself. This DaemonSet watches the kata-deploy pod on its +node reach Ready (its /readyz flips 503β†’200 only after install completes), then +removes the taint so kata sandboxes can schedule. Ported from +eks-platform-openclaw PR #10. +*/ -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: kata-readiness + namespace: {{ include "agent-sandbox.namespace" . }} + labels: + {{- include "agent-sandbox.labels" . | nindent 4 }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: agent-sandbox-kata-readiness + labels: + {{- include "agent-sandbox.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "patch"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: agent-sandbox-kata-readiness + labels: + {{- include "agent-sandbox.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: kata-readiness + namespace: {{ include "agent-sandbox.namespace" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: agent-sandbox-kata-readiness +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: kata-readiness + namespace: {{ include "agent-sandbox.namespace" . }} + labels: + {{- include "agent-sandbox.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app: kata-readiness + template: + metadata: + labels: + app: kata-readiness + {{- include "agent-sandbox.selectorLabels" . | nindent 8 }} + spec: + serviceAccountName: kata-readiness + # Tolerate everything so it lands BEFORE the runtime is ready β€” including + # the kata workload taint and the runtime-not-ready startup taint it removes. + tolerations: + - operator: Exists + # Static label present from node birth (kata-deploy emits + # katacontainers.io/kata-runtime only after install, so we can't select on it). + nodeSelector: + kata-enabled: "true" + securityContext: + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + containers: + - name: kata-readiness + image: {{ .Values.kataReadiness.image }} + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + command: + - /bin/sh + - -c + - | + set -eu + echo "[kata-readiness] node=${NODE_NAME}: waiting for kata-deploy Ready..." + until [ "$(kubectl get pods -n kube-system -l name=kata-deploy \ + --field-selector "spec.nodeName=${NODE_NAME}" \ + -o jsonpath='{.items[0].status.conditions[?(@.type=="Ready")].status}')" = "True" ]; do + sleep 5 + done + echo "[kata-readiness] kata-deploy Ready; removing runtime-not-ready taint..." + kubectl taint node "${NODE_NAME}" katacontainers.io/runtime-not-ready:NoSchedule- || true + echo "[kata-readiness] node ${NODE_NAME} ready for kata workloads." + sleep infinity + resources: + requests: + cpu: 5m + memory: 32Mi +{{- end }} diff --git a/gitops/addons/charts/agent-sandbox/templates/20-sandboxtemplate.yaml b/gitops/addons/charts/agent-sandbox/templates/20-sandboxtemplate.yaml new file mode 100644 index 0000000..5a56cec --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/templates/20-sandboxtemplate.yaml @@ -0,0 +1,71 @@ +{{- /* +SandboxTemplate β€” the podTemplate the warm pool (and Dark Factory claims) are +cloned from. Encodes the isolation invariants for running untrusted, +LLM-generated code: + - runtimeClassName: a Kata micro-VM (own kernel), not a shared-kernel container + - automountServiceAccountToken: false (no in-cluster API creds by default) + - runAsNonRoot + restricted seccomp + drop ALL caps + - workspace on an ephemeral PVC (per claim), model access via Bifrost only +The concrete coder image (claude-code | kiro) and per-claim secrets are patched +in by the consumer when it binds a SandboxClaim. +*/ -}} +apiVersion: extensions.agents.x-k8s.io/v1beta1 +kind: SandboxTemplate +metadata: + name: {{ .Values.warmPool.templateName }} + namespace: {{ include "agent-sandbox.namespace" . }} + labels: + {{- include "agent-sandbox.labels" . | nindent 4 }} +spec: + podTemplate: + metadata: + labels: + {{- include "agent-sandbox.selectorLabels" . | nindent 8 }} + agent-sandbox.io/role: coder + spec: + runtimeClassName: {{ .Values.kata.defaultRuntimeClass }} + automountServiceAccountToken: false + nodeSelector: + {{- toYaml .Values.kata.nodeSelector | nindent 8 }} + tolerations: + {{- toYaml .Values.kata.tolerations | nindent 8 }} + securityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + seccompProfile: + type: RuntimeDefault + containers: + - name: coder + image: {{ .Values.coderTemplate.image }} + # Overridden per claim by the consumer (Dark Factory picks the profile). + command: ["/bin/sh", "-c", "echo 'coder image set per-claim'; sleep infinity"] + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: ["ALL"] + env: + # This platform uses Bifrost (not LiteLLM) as the LLM gateway. + - name: BIFROST_URL + value: {{ .Values.coderTemplate.bifrostUrl | quote }} + resources: + {{- toYaml .Values.coderTemplate.resources | nindent 12 }} + volumeMounts: + - name: workspace + mountPath: /workspace + - name: tmp + mountPath: /tmp + volumes: + # Ephemeral per-claim workspace. SandboxTemplate.spec only supports + # podTemplate (verified against the live CRD β€” it has NO + # volumeClaimTemplates field; that belongs on the Sandbox CR). Use an + # emptyDir sized by coderTemplate.workspaceSizeGi; consumers that need a + # persistent workspace across scale-to-zero set spec.volumeClaimTemplates + # on the Sandbox CR they create from this template. + - name: workspace + emptyDir: + sizeLimit: {{ .Values.coderTemplate.workspaceSizeGi }}Gi + - name: tmp + emptyDir: {} diff --git a/gitops/addons/charts/agent-sandbox/templates/30-networkpolicy.yaml b/gitops/addons/charts/agent-sandbox/templates/30-networkpolicy.yaml new file mode 100644 index 0000000..13a8a51 --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/templates/30-networkpolicy.yaml @@ -0,0 +1,50 @@ +{{- /* +Default-deny egress for coder sandboxes, then allow ONLY what a coder needs: + - DNS (kube-dns) + - Bifrost LLM gateway (model calls) + - HTTPS to the internet for git/gh + package registries the build needs +This breaks the "lethal trifecta": untrusted issue text runs in a pod that +cannot reach arbitrary internal services or exfiltrate to arbitrary hosts. +Selects coder pods by the label the SandboxTemplate stamps. +*/ -}} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: coder-sandbox-egress + namespace: {{ include "agent-sandbox.namespace" . }} + labels: + {{- include "agent-sandbox.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + agent-sandbox.io/role: coder + policyTypes: + - Egress + egress: + # DNS resolution + - to: + - namespaceSelector: {} + ports: + - protocol: UDP + port: 53 + - protocol: TCP + port: 53 + # Bifrost LLM gateway (in-cluster) + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: bifrost + ports: + - protocol: TCP + port: 8080 + # HTTPS egress for git / gh / package registries (build dependencies). + # Note: broad :443 is required for public git+registry access; tighten to + # specific CIDRs/hostnames with an egress proxy for stricter deployments. + - to: + - ipBlock: + cidr: 0.0.0.0/0 + except: + - 169.254.169.254/32 # block IMDS (instance metadata) + ports: + - protocol: TCP + port: 443 diff --git a/gitops/addons/charts/agent-sandbox/templates/40-sandboxwarmpool.yaml b/gitops/addons/charts/agent-sandbox/templates/40-sandboxwarmpool.yaml new file mode 100644 index 0000000..c58aaff --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/templates/40-sandboxwarmpool.yaml @@ -0,0 +1,21 @@ +{{- if .Values.warmPool.enabled }} +{{- /* +Native SandboxWarmPool (operator v0.5.0+). The operator keeps `replicas` idle +sandboxes pre-warmed from the referenced SandboxTemplate; a consumer (the Dark +Factory) binds one via a SandboxClaim and the operator refills the buffer. This +replaces the custom pool-manager CronJob β€” the warm pool is now a first-class +operator primitive (requires the vendored v0.5.1 upstream, NOT v0.1.0). +*/ -}} +apiVersion: extensions.agents.x-k8s.io/v1beta1 +kind: SandboxWarmPool +metadata: + name: {{ .Values.warmPool.name | default "coder-warmpool" }} + namespace: {{ include "agent-sandbox.namespace" . }} + labels: + {{- include "agent-sandbox.labels" . | nindent 4 }} +spec: + # Target number of pre-warmed idle sandboxes (the warm buffer). + replicas: {{ .Values.warmPool.targetIdle }} + sandboxTemplateRef: + name: {{ .Values.warmPool.templateName }} +{{- end }} diff --git a/gitops/addons/charts/agent-sandbox/templates/_helpers.tpl b/gitops/addons/charts/agent-sandbox/templates/_helpers.tpl new file mode 100644 index 0000000..c59c0d5 --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/templates/_helpers.tpl @@ -0,0 +1,23 @@ +{{/* +Common labels applied to every resource this chart renders. +*/}} +{{- define "agent-sandbox.labels" -}} +app.kubernetes.io/name: agent-sandbox +app.kubernetes.io/part-of: open-agent-platform +app.kubernetes.io/managed-by: {{ .Release.Service }} +helm.sh/chart: {{ printf "%s-%s" .Chart.Name .Chart.Version }} +{{- end -}} + +{{/* +Selector labels (stable subset used by Services / controllers). +*/}} +{{- define "agent-sandbox.selectorLabels" -}} +app.kubernetes.io/name: agent-sandbox +{{- end -}} + +{{/* +The namespace the capability runs in. +*/}} +{{- define "agent-sandbox.namespace" -}} +{{- default "agent-sandbox-system" .Values.namespace -}} +{{- end -}} diff --git a/gitops/addons/charts/agent-sandbox/upstream/Chart.yaml b/gitops/addons/charts/agent-sandbox/upstream/Chart.yaml new file mode 100644 index 0000000..f4493f7 --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/upstream/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +name: agent-sandbox-operator +description: >- + Upstream agent-sandbox v0.5.1 operator install (controller Deployment + CRDs + + RBAC + webhooks) vendored verbatim from kubernetes-sigs/agent-sandbox. Packaged + as a thin Helm chart so the platform ApplicationSet (which renders addons as + Helm charts) can deploy it. The manifest files under templates/ contain no Helm + templating β€” they are applied as-is. ServerSideApply handles the oversized CRDs. +type: application +version: 0.5.1 +appVersion: "0.5.1" diff --git a/gitops/addons/charts/agent-sandbox/upstream/templates/agent-sandbox-v0.5.1-extensions.yaml b/gitops/addons/charts/agent-sandbox/upstream/templates/agent-sandbox-v0.5.1-extensions.yaml new file mode 100644 index 0000000..4eb6696 --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/upstream/templates/agent-sandbox-v0.5.1-extensions.yaml @@ -0,0 +1,8960 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: sandboxclaims.extensions.agents.x-k8s.io +spec: + group: extensions.agents.x-k8s.io + names: + kind: SandboxClaim + listKind: SandboxClaimList + plural: sandboxclaims + shortNames: + - sandboxclaim + singular: sandboxclaim + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=='Ready')].status + name: Ready + type: string + - jsonPath: .status.sandbox.name + name: Sandbox + type: string + - jsonPath: .status.conditions[?(@.type=='Ready')].reason + name: Reason + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + additionalPodMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + env: + items: + properties: + containerName: + type: string + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + lifecycle: + properties: + shutdownPolicy: + default: Retain + enum: + - Delete + - DeleteForeground + - Retain + type: string + shutdownTime: + format: date-time + type: string + ttlSecondsAfterFinished: + format: int32 + minimum: 0 + type: integer + type: object + volumeClaimTemplates: + items: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: array + x-kubernetes-list-type: atomic + warmPoolRef: + properties: + name: + type: string + required: + - name + type: object + required: + - warmPoolRef + type: object + status: + properties: + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + maxLength: 32768 + type: string + observedGeneration: + format: int64 + minimum: 0 + type: integer + reason: + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + enum: + - 'True' + - 'False' + - Unknown + type: string + type: + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + sandbox: + properties: + name: + type: string + podIPs: + items: + type: string + type: array + type: object + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - deprecated: true + deprecationWarning: extensions.agents.x-k8s.io/v1alpha1 SandboxClaim is deprecated; + use extensions.agents.x-k8s.io/v1beta1 SandboxClaim instead + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + additionalPodMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + env: + items: + properties: + containerName: + type: string + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + lifecycle: + properties: + shutdownPolicy: + default: Retain + enum: + - Delete + - DeleteForeground + - Retain + type: string + shutdownTime: + format: date-time + type: string + ttlSecondsAfterFinished: + format: int32 + minimum: 0 + type: integer + type: object + sandboxTemplateRef: + properties: + name: + type: string + required: + - name + type: object + warmpool: + default: default + type: string + required: + - sandboxTemplateRef + type: object + status: + properties: + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + maxLength: 32768 + type: string + observedGeneration: + format: int64 + minimum: 0 + type: integer + reason: + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + enum: + - 'True' + - 'False' + - Unknown + type: string + type: + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + sandbox: + properties: + name: + type: string + podIPs: + items: + type: string + type: array + type: object + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: agent-sandbox-webhook-service + namespace: agent-sandbox-system + path: /convert +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: sandboxtemplates.extensions.agents.x-k8s.io +spec: + group: extensions.agents.x-k8s.io + names: + kind: SandboxTemplate + listKind: SandboxTemplateList + plural: sandboxtemplates + shortNames: + - sandboxtemplate + singular: sandboxtemplate + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + envVarsInjectionPolicy: + default: Disallowed + enum: + - Allowed + - Overrides + - Disallowed + type: string + networkPolicy: + properties: + egress: + items: + properties: + ports: + items: + properties: + endPort: + format: int32 + type: integer + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + protocol: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + to: + items: + properties: + ipBlock: + properties: + cidr: + type: string + except: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - cidr + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: array + ingress: + items: + properties: + from: + items: + properties: + ipBlock: + properties: + cidr: + type: string + except: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - cidr + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + ports: + items: + properties: + endPort: + format: int32 + type: integer + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + protocol: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: array + type: object + networkPolicyManagement: + default: Managed + enum: + - Managed + - Unmanaged + type: string + podTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + type: string + required: + - ip + type: object + type: array + x-kubernetes-list-map-keys: + - ip + x-kubernetes-list-type: map + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostUsers: + type: boolean + hostname: + type: string + hostnameOverride: + type: string + imagePullSecrets: + items: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + x-kubernetes-list-type: atomic + resourceClaims: + items: + properties: + name: + type: string + resourceClaimName: + type: string + resourceClaimTemplateName: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + schedulingGates: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + schedulingGroup: + properties: + podGroupName: + type: string + type: object + securityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxChangePolicy: + type: string + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podCertificate: + properties: + certificateChainPath: + type: string + credentialBundlePath: + type: string + keyPath: + type: string + keyType: + type: string + maxExpirationSeconds: + format: int32 + type: integer + signerName: + type: string + userAnnotations: + additionalProperties: + type: string + type: object + required: + - keyType + - signerName + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - containers + type: object + required: + - spec + type: object + service: + type: boolean + volumeClaimTemplates: + items: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: array + x-kubernetes-list-type: atomic + volumeClaimTemplatesPolicy: + default: Disallowed + enum: + - Disallowed + - Allowed + - Overrides + type: string + required: + - podTemplate + type: object + required: + - spec + type: object + served: true + storage: true + - deprecated: true + deprecationWarning: extensions.agents.x-k8s.io/v1alpha1 SandboxTemplate is deprecated; + use extensions.agents.x-k8s.io/v1beta1 SandboxTemplate instead + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + envVarsInjectionPolicy: + default: Disallowed + enum: + - Allowed + - Overrides + - Disallowed + type: string + networkPolicy: + properties: + egress: + items: + properties: + ports: + items: + properties: + endPort: + format: int32 + type: integer + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + protocol: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + to: + items: + properties: + ipBlock: + properties: + cidr: + type: string + except: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - cidr + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: array + ingress: + items: + properties: + from: + items: + properties: + ipBlock: + properties: + cidr: + type: string + except: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - cidr + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + podSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + ports: + items: + properties: + endPort: + format: int32 + type: integer + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + protocol: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: array + type: object + networkPolicyManagement: + default: Managed + enum: + - Managed + - Unmanaged + type: string + podTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + type: string + required: + - ip + type: object + type: array + x-kubernetes-list-map-keys: + - ip + x-kubernetes-list-type: map + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostUsers: + type: boolean + hostname: + type: string + hostnameOverride: + type: string + imagePullSecrets: + items: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + x-kubernetes-list-type: atomic + resourceClaims: + items: + properties: + name: + type: string + resourceClaimName: + type: string + resourceClaimTemplateName: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + schedulingGates: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + schedulingGroup: + properties: + podGroupName: + type: string + type: object + securityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxChangePolicy: + type: string + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podCertificate: + properties: + certificateChainPath: + type: string + credentialBundlePath: + type: string + keyPath: + type: string + keyType: + type: string + maxExpirationSeconds: + format: int32 + type: integer + signerName: + type: string + userAnnotations: + additionalProperties: + type: string + type: object + required: + - keyType + - signerName + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - containers + type: object + required: + - spec + type: object + service: + type: boolean + volumeClaimTemplates: + items: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: array + x-kubernetes-list-type: atomic + required: + - podTemplate + type: object + required: + - spec + type: object + served: true + storage: false + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: agent-sandbox-webhook-service + namespace: agent-sandbox-system + path: /convert +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: sandboxwarmpools.extensions.agents.x-k8s.io +spec: + group: extensions.agents.x-k8s.io + names: + kind: SandboxWarmPool + listKind: SandboxWarmPoolList + plural: sandboxwarmpools + shortNames: + - swp + singular: sandboxwarmpool + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.readyReplicas + name: Ready + type: integer + - jsonPath: .spec.replicas + name: Desired + type: integer + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + replicas: + default: 1 + format: int32 + minimum: 0 + type: integer + sandboxTemplateRef: + properties: + name: + type: string + required: + - name + type: object + updateStrategy: + properties: + type: + default: OnReplenish + enum: + - Recreate + - OnReplenish + type: string + type: object + required: + - sandboxTemplateRef + type: object + status: + properties: + readyReplicas: + format: int32 + type: integer + replicas: + format: int32 + type: integer + selector: + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} + - additionalPrinterColumns: + - jsonPath: .status.readyReplicas + name: Ready + type: integer + - jsonPath: .spec.replicas + name: Desired + type: integer + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: extensions.agents.x-k8s.io/v1alpha1 SandboxWarmPool is deprecated; + use extensions.agents.x-k8s.io/v1beta1 SandboxWarmPool instead + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + replicas: + format: int32 + minimum: 0 + type: integer + sandboxTemplateRef: + properties: + name: + type: string + required: + - name + type: object + updateStrategy: + properties: + type: + default: OnReplenish + enum: + - Recreate + - OnReplenish + type: string + type: object + required: + - replicas + - sandboxTemplateRef + type: object + status: + properties: + readyReplicas: + format: int32 + type: integer + replicas: + format: int32 + type: integer + selector: + type: string + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: agent-sandbox-webhook-service + namespace: agent-sandbox-system + path: /convert +--- +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: agent-sandbox-controller-extensions +rules: +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + - events.k8s.io + resources: + - events + verbs: + - create + - patch + - update +- apiGroups: + - agents.x-k8s.io + resources: + - sandboxes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - extensions.agents.x-k8s.io + resources: + - sandboxclaims + - sandboxtemplates + - sandboxwarmpools + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - extensions.agents.x-k8s.io + resources: + - sandboxclaims/finalizers + - sandboxclaims/status + - sandboxtemplates/finalizers + - sandboxwarmpools/finalizers + - sandboxwarmpools/status + verbs: + - get + - patch + - update +- apiGroups: + - networking.k8s.io + resources: + - networkpolicies + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +# NOTE: the agent-sandbox-controller Deployment that upstream ships in this +# extensions bundle has been removed to avoid a duplicate with the one in +# agent-sandbox-v0.5.1-manifest.yaml (ArgoCD RepeatedResourceWarning). The +# manifest.yaml Deployment now carries the union of both (--extensions + the +# 9443 webhook port + config-volume), so a single controller serves both the +# core API and the extensions conversion webhook. +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: agent-sandbox-controller-extensions +subjects: +- kind: ServiceAccount + name: agent-sandbox-controller + namespace: agent-sandbox-system +roleRef: + kind: ClusterRole + name: agent-sandbox-controller-extensions + apiGroup: rbac.authorization.k8s.io +--- diff --git a/gitops/addons/charts/agent-sandbox/upstream/templates/agent-sandbox-v0.5.1-manifest.yaml b/gitops/addons/charts/agent-sandbox/upstream/templates/agent-sandbox-v0.5.1-manifest.yaml new file mode 100644 index 0000000..a38aad6 --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/upstream/templates/agent-sandbox-v0.5.1-manifest.yaml @@ -0,0 +1,8271 @@ +--- +kind: Namespace +apiVersion: v1 +metadata: + name: agent-sandbox-system + +--- + +kind: ServiceAccount +apiVersion: v1 +metadata: + name: agent-sandbox-controller + namespace: agent-sandbox-system + labels: + app: agent-sandbox-controller + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: agent-sandbox-controller +subjects: +- kind: ServiceAccount + name: agent-sandbox-controller + namespace: agent-sandbox-system +roleRef: + kind: ClusterRole + name: agent-sandbox-controller + apiGroup: rbac.authorization.k8s.io + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: agent-sandbox-controller + namespace: agent-sandbox-system +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - create +- apiGroups: + - "" + resourceNames: + - agent-sandbox-webhook-certs + resources: + - secrets + verbs: + - get + - patch + - update + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: agent-sandbox-controller + namespace: agent-sandbox-system +subjects: +- kind: ServiceAccount + name: agent-sandbox-controller + namespace: agent-sandbox-system +roleRef: + kind: Role + name: agent-sandbox-controller + apiGroup: rbac.authorization.k8s.io + +--- + +kind: Service +apiVersion: v1 +metadata: + name: agent-sandbox-controller + namespace: agent-sandbox-system + labels: + app: agent-sandbox-controller +spec: + selector: + app: agent-sandbox-controller + ports: + - name: metrics + port: 8080 + targetPort: metrics + protocol: TCP + +--- + +kind: Deployment +apiVersion: apps/v1 +metadata: + name: agent-sandbox-controller + namespace: agent-sandbox-system + labels: + app: agent-sandbox-controller +spec: + replicas: 1 + selector: + matchLabels: + app: agent-sandbox-controller + template: + metadata: + labels: + app: agent-sandbox-controller + spec: + serviceAccountName: agent-sandbox-controller + containers: + - name: agent-sandbox-controller + image: registry.k8s.io/agent-sandbox/agent-sandbox-controller:v0.5.1 + # Merged controller: --extensions (so the controller knows the + # SandboxTemplate/SandboxClaim/SandboxWarmPool extension types and the + # /convert conversion webhook can answer) PLUS the webhook port 9443 + # that agent-sandbox-webhook-service targets. Upstream ships these as + # two separate Deployments (manifest = core+webhook port, extensions = + # --extensions but no port); vendoring both into one chart made ArgoCD + # see the Deployment twice (RepeatedResourceWarning) and whichever + # applied last won β€” breaking either the conversion webhook (no 9443) + # or the extension types (no --extensions). This is the union of both. + args: + - --leader-elect=true + - --extensions + ports: + - name: metrics + containerPort: 8080 + protocol: TCP + - name: healthz + containerPort: 8081 + protocol: TCP + - name: webhook + containerPort: 9443 + protocol: TCP + volumeMounts: + - name: config-volume + mountPath: /etc/sandbox-config + readOnly: true + volumes: + - name: config-volume + configMap: + name: agent-sandbox-config + optional: true + +--- + +kind: Service +apiVersion: v1 +metadata: + name: agent-sandbox-webhook-service + namespace: agent-sandbox-system +spec: + selector: + app: agent-sandbox-controller + ports: + - name: webhook + port: 443 + targetPort: 9443 + protocol: TCP + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.21.0 + name: sandboxes.agents.x-k8s.io +spec: + group: agents.x-k8s.io + names: + kind: Sandbox + listKind: SandboxList + plural: sandboxes + shortNames: + - sandbox + singular: sandbox + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=='Ready')].status + name: Ready + type: string + - jsonPath: .status.conditions[?(@.type=='Ready')].reason + name: Reason + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + operatingMode: + default: Running + enum: + - Running + - Suspended + type: string + podTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + type: string + required: + - ip + type: object + type: array + x-kubernetes-list-map-keys: + - ip + x-kubernetes-list-type: map + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostUsers: + type: boolean + hostname: + type: string + hostnameOverride: + type: string + imagePullSecrets: + items: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + x-kubernetes-list-type: atomic + resourceClaims: + items: + properties: + name: + type: string + resourceClaimName: + type: string + resourceClaimTemplateName: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + schedulingGates: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + schedulingGroup: + properties: + podGroupName: + type: string + type: object + securityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxChangePolicy: + type: string + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podCertificate: + properties: + certificateChainPath: + type: string + credentialBundlePath: + type: string + keyPath: + type: string + keyType: + type: string + maxExpirationSeconds: + format: int32 + type: integer + signerName: + type: string + userAnnotations: + additionalProperties: + type: string + type: object + required: + - keyType + - signerName + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - containers + type: object + required: + - spec + type: object + service: + type: boolean + shutdownPolicy: + default: Retain + enum: + - Delete + - Retain + type: string + shutdownTime: + format: date-time + type: string + volumeClaimTemplates: + items: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: array + x-kubernetes-list-type: atomic + required: + - podTemplate + type: object + status: + properties: + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + maxLength: 32768 + type: string + observedGeneration: + format: int64 + minimum: 0 + type: integer + reason: + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + enum: + - 'True' + - 'False' + - Unknown + type: string + type: + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + nodeName: + type: string + podIPs: + items: + type: string + type: array + selector: + type: string + service: + type: string + serviceFQDN: + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - deprecated: true + deprecationWarning: agents.x-k8s.io/v1alpha1 Sandbox is deprecated; use agents.x-k8s.io/v1beta1 + Sandbox instead + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + podTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + x-kubernetes-list-type: atomic + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + x-kubernetes-list-type: atomic + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + x-kubernetes-list-type: atomic + type: object + type: object + automountServiceAccountToken: + type: boolean + containers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + x-kubernetes-list-type: atomic + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + searches: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + x-kubernetes-list-type: atomic + ip: + type: string + required: + - ip + type: object + type: array + x-kubernetes-list-map-keys: + - ip + x-kubernetes-list-type: map + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostUsers: + type: boolean + hostname: + type: string + hostnameOverride: + type: string + imagePullSecrets: + items: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + initContainers: + items: + properties: + args: + items: + type: string + type: array + x-kubernetes-list-type: atomic + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + fileKeyRef: + properties: + key: + type: string + optional: + default: false + type: boolean + path: + type: string + volumeName: + type: string + required: + - key + - path + - volumeName + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + default: '' + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + envFrom: + items: + properties: + configMapRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + type: string + secretRef: + properties: + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + x-kubernetes-list-type: atomic + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + required: + - seconds + type: object + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + stopSignal: + type: string + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + default: TCP + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + restartPolicyRules: + items: + properties: + action: + type: string + exitCodes: + properties: + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + x-kubernetes-list-type: set + required: + - operator + type: object + required: + - action + type: object + type: array + x-kubernetes-list-type: atomic + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + capabilities: + properties: + add: + items: + type: string + type: array + x-kubernetes-list-type: atomic + drop: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + default: '' + type: string + required: + - port + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + path: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + scheme: + type: string + required: + - port + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + type: string + required: + - devicePath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - devicePath + x-kubernetes-list-type: map + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + recursiveReadOnly: + type: string + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + x-kubernetes-list-map-keys: + - mountPath + x-kubernetes-list-type: map + workingDir: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + x-kubernetes-map-type: atomic + os: + properties: + name: + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + required: + - conditionType + type: object + type: array + x-kubernetes-list-type: atomic + resourceClaims: + items: + properties: + name: + type: string + resourceClaimName: + type: string + resourceClaimTemplateName: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + resources: + properties: + claims: + items: + properties: + name: + type: string + request: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + schedulingGates: + items: + properties: + name: + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + schedulingGroup: + properties: + podGroupName: + type: string + type: object + securityContext: + properties: + appArmorProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxChangePolicy: + type: string + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + x-kubernetes-list-type: atomic + supplementalGroupsPolicy: + type: string + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + x-kubernetes-list-type: atomic + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + x-kubernetes-list-type: atomic + topologySpreadConstraints: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + default: ext4 + type: string + kind: + type: string + readOnly: + default: false + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + x-kubernetes-list-type: atomic + wwids: + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + image: + properties: + pullPolicy: + type: string + reference: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + default: default + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + x-kubernetes-list-type: atomic + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + required: + - path + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + x-kubernetes-list-type: atomic + type: object + podCertificate: + properties: + certificateChainPath: + type: string + credentialBundlePath: + type: string + keyPath: + type: string + keyType: + type: string + maxExpirationSeconds: + format: int32 + type: integer + signerName: + type: string + userAnnotations: + additionalProperties: + type: string + type: object + required: + - keyType + - signerName + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + name: + default: '' + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + x-kubernetes-list-type: atomic + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + default: /etc/ceph/keyring + type: string + monitors: + items: + type: string + type: array + x-kubernetes-list-type: atomic + pool: + default: rbd + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + user: + default: admin + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + default: xfs + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + default: ThinProvisioned + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + x-kubernetes-list-type: atomic + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + default: '' + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + required: + - containers + type: object + required: + - spec + type: object + replicas: + default: 1 + format: int32 + maximum: 1 + minimum: 0 + type: integer + service: + type: boolean + shutdownPolicy: + default: Retain + enum: + - Delete + - Retain + type: string + shutdownTime: + format: date-time + type: string + volumeClaimTemplates: + items: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + name: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + x-kubernetes-list-type: atomic + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: array + x-kubernetes-list-type: atomic + required: + - podTemplate + type: object + status: + properties: + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + maxLength: 32768 + type: string + observedGeneration: + format: int64 + minimum: 0 + type: integer + reason: + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + enum: + - 'True' + - 'False' + - Unknown + type: string + type: + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + podIPs: + items: + type: string + type: array + replicas: + format: int32 + minimum: 0 + type: integer + selector: + type: string + service: + type: string + serviceFQDN: + type: string + type: object + required: + - spec + type: object + served: true + storage: false + subresources: + scale: + labelSelectorPath: .status.selector + specReplicasPath: .spec.replicas + statusReplicasPath: .status.replicas + status: {} + conversion: + strategy: Webhook + webhook: + conversionReviewVersions: + - v1 + - v1beta1 + clientConfig: + service: + name: agent-sandbox-webhook-service + namespace: agent-sandbox-system + path: /convert +--- +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: agent-sandbox-controller +rules: +- apiGroups: + - "" + resources: + - persistentvolumeclaims + - pods + - services + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - agents.x-k8s.io + resources: + - sandboxes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - agents.x-k8s.io + resources: + - sandboxes/finalizers + - sandboxes/status + verbs: + - get + - patch + - update +- apiGroups: + - apiextensions.k8s.io + resourceNames: + - sandboxclaims.extensions.agents.x-k8s.io + - sandboxes.agents.x-k8s.io + - sandboxtemplates.extensions.agents.x-k8s.io + - sandboxwarmpools.extensions.agents.x-k8s.io + resources: + - customresourcedefinitions + verbs: + - get + - patch + - update +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - list + - patch + - update + - watch +- apiGroups: + - events.k8s.io + resources: + - events + verbs: + - create + - patch +--- diff --git a/gitops/addons/charts/agent-sandbox/values.yaml b/gitops/addons/charts/agent-sandbox/values.yaml new file mode 100644 index 0000000..05b8248 --- /dev/null +++ b/gitops/addons/charts/agent-sandbox/values.yaml @@ -0,0 +1,90 @@ +# Agent Sandbox capability β€” default values +# +# This chart installs the Sandbox control plane (operator + CRDs), the Kata +# RuntimeClasses that workloads select via runtimeClassName, a SandboxTemplate +# the Dark Factory (and other consumers) claim against, and a pool-manager that +# keeps a warm buffer of idle sandboxes ready. + +# Namespace the sandbox capability runs in (operator, pool-manager, warm pool). +namespace: agent-sandbox-system + +# ── Sandbox operator (agents.x-k8s.io) ─────────────────────────────────────── +operator: + # Upstream agent-sandbox controller image. + image: public.ecr.aws/t6v6o5d5/agent-sandbox:v0.1.0 + replicas: 1 + # Install the Sandbox / SandboxTemplate / SandboxClaim CRDs with the chart. + # Disable if the cluster already has a newer operator managing the CRDs. + installCRDs: true + +# NOTE: The Kata *runtime installer* (kata-deploy) is delivered as a SEPARATE +# gated ArgoCD app (enable_agent_sandbox_kata), not from this chart β€” see the +# addon catalog and docs/dark-factory Β§12a. This chart owns the RuntimeClasses, +# operator, template, network policy, and pool-manager. + +# ── Kata micro-VM runtime ──────────────────────────────────────────────────── +kata: + # Default VMM for coder sandboxes. Cloud Hypervisor (clh) boots fast and is + # the platform default; qemu and fc (Firecracker) are also installed. + defaultRuntimeClass: kata-clh + # RuntimeClasses to render. Each carries the nodeSelector + toleration that + # steers a pod onto the matching Karpenter kata pool. + runtimeClasses: + - name: kata-clh + handler: kata-clh + - name: kata-qemu + handler: kata-qemu + # Node scheduling applied to every kata RuntimeClass. + nodeSelector: + katacontainers.io/kata-runtime: "true" + tolerations: + - key: kata + operator: Equal + value: "true" + effect: NoSchedule + +# ── kata-readiness ─────────────────────────────────────────────────────────── +# Removes the runtime-not-ready startup taint once kata-deploy finishes on a +# node. Required whenever nodes carry that startup taint (the kata MNG does). +kataReadiness: + enabled: true + image: alpine/k8s:1.31.0 # needs kubectl + +# ── Warm pool ──────────────────────────────────────────────────────────────── +warmPool: + enabled: true + # Number of idle sandboxes to keep ready. Claim one β†’ pool-manager refills; + # release one β†’ pool-manager shrinks back to this target. + targetIdle: 3 + # Idle sandboxes scale to replicas:0 after this TTL (PVC retained); resume on + # demand. Set 0 to keep idle sandboxes running (higher cost, instant claim). + idleScaleToZeroSeconds: 900 + # Hard TTL β€” a claimed sandbox with no activity past this is reaped (safety + # net for crashed/abandoned consumers). + reapAfterSeconds: 3600 + # The SandboxTemplate that idle/claimed sandboxes are cloned from. + templateName: coder-sandbox + +# ── Pool-manager controller ────────────────────────────────────────────────── +poolManager: + # Image for the reconcile loop β€” MUST have both kubectl AND jq (the script + # exits early if kubectl is missing). aws-cli image has neither; use an + # alpine/k8s image that bundles kubectl + jq + helm. + image: alpine/k8s:1.31.0 + # How often the reconcile/reaper loop runs. + intervalSeconds: 60 + resources: + requests: { cpu: 50m, memory: 64Mi } + limits: { cpu: 200m, memory: 128Mi } + +# ── Coder SandboxTemplate (podTemplate the warm pool clones) ───────────────── +coderTemplate: + # Sandbox coder image is set by the consumer (Dark Factory picks the coder + # profile β€” claude-code | kiro). Placeholder here; overridden per claim. + image: public.ecr.aws/docker/library/busybox:1.36 + workspaceSizeGi: 5 + resources: + requests: { cpu: "1", memory: 2Gi } + limits: { cpu: "2", memory: 4Gi } + # LLM gateway the coder reaches (this platform uses Bifrost, not LiteLLM). + bifrostUrl: http://bifrost.bifrost.svc.cluster.local:8080 diff --git a/gitops/overlays/environments/dev/enabled-addons.yaml b/gitops/overlays/environments/dev/enabled-addons.yaml index 56ba38f..0b5df4f 100644 --- a/gitops/overlays/environments/dev/enabled-addons.yaml +++ b/gitops/overlays/environments/dev/enabled-addons.yaml @@ -22,3 +22,14 @@ enabledAddons: # Agentic Platform agent_platform: true bifrost: true + # Agent Sandbox capability β€” Kata micro-VM sandboxes + warm pool. + # Enabled on DEV (where the Dark Factory runs). ArgoCD manages the IN-CLUSTER + # pieces (operator, CRDs, RuntimeClasses, SandboxTemplate, pool-manager). + # The kata-capable node layer is NOT GitOps-managed β€” it requires a + # self-managed nested-virt MNG + the vpc-cni & kube-proxy addons provisioned + # out-of-band (AWS infra ArgoCD can't create). See + # gitops/addons/charts/agent-sandbox/nodepool/README.md for the proven recipe + # (validated live on spoke-dev 2026-07-10: real kata VM, guest kernel 6.18.35). + agent_sandbox: true + # kata-deploy installs the runtime on the kata MNG nodes (separate app). + agent_sandbox_kata: true diff --git a/gitops/overlays/environments/prod/enabled-addons.yaml b/gitops/overlays/environments/prod/enabled-addons.yaml index 89763f5..c4c89ee 100644 --- a/gitops/overlays/environments/prod/enabled-addons.yaml +++ b/gitops/overlays/environments/prod/enabled-addons.yaml @@ -23,3 +23,8 @@ enabledAddons: # Agentic Platform agent_platform: true bifrost: true + # Agent Sandbox capability β€” DISABLED for now (same reason as dev): EKS Auto + # Mode + Bottlerocket cannot host Kata. Re-enable once Auto Mode integration + # is designed. When on, prod holds the capability but the pool stays dormant + # (the Dark Factory only runs on spoke-dev β€” production-safety). + # agent_sandbox: true