Add dot-ai-stack

This commit is contained in:
dvirlabs 2026-03-26 05:32:52 +02:00
parent cf935551a8
commit 5d1a45feeb
140 changed files with 13131 additions and 0 deletions

View File

@ -0,0 +1,24 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: dot-ai-stack
namespace: argocd
spec:
project: ai-stack
destination:
server: https://kubernetes.default.svc
namespace: ai-stack
source:
repoURL: ssh://git@gitea-ssh.dev-tools.svc.cluster.local.:2222/dvirlabs/ai-stack.git
targetRevision: HEAD
path: charts/dot-ai-stack
helm:
releaseName: dot-ai
valueFiles:
- ../../manifests/dot-ai-stack/values.yaml
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

View File

@ -0,0 +1,51 @@
# Create Architecture Diagram
Create a detailed architecture diagram for the **$ARGUMENTS** tool/feature.
## Instructions
1. **Research the feature** from source code in the parent directory projects:
- `../dot-ai/` - MCP Server (main tools in `src/tools/`)
- `../dot-ai-controller/` - Kubernetes Controller
- `../dot-ai-ui/` - Web UI
- Documentation at https://devopstoolkit.ai/
2. **Create the architecture document** at `docs/architecture/{feature-name}.md` with:
### High-Level Architecture (Mermaid)
- Show components as subgraphs: User/Agent, MCP Server, External Services, Kubernetes, Web UI
- Use "etc." for non-exhaustive lists (agents, LLMs, resources)
- Arrow from Agent to the specific tool via MCP Protocol
- Show internal tool dependencies (AI Provider, Vector DB Client, Discovery Engine)
- Show external connections (LLM APIs, Qdrant with embeddings, K8s API)
- Controller syncs data to Qdrant with embeddings
- User opens Visualization URL in Web UI (dotted arrow from Agent)
### Workflow Stages (Mermaid)
- Show the complete workflow with all stages
- Include decision points and branching logic
- Show retry loops where applicable
- Group related steps in subgraphs
3. **Include supporting sections**:
- Component Details (table with files and descriptions)
- Integration Points (Mermaid diagram + bullet points)
- Session Management (if applicable)
- Output Formats (if applicable)
- Error Handling
- See Also (links to related docs)
4. **Diagram guidelines**:
- Use Mermaid `flowchart` (TB for vertical, LR for horizontal)
- Use subgraphs to group related components
- Use decision nodes `{}` for branching
- Keep labels concise, use `<br/>` for line breaks
- Avoid redundancy between diagrams
## Usage
```
Create architecture diagram for {tool-name}
```
Example: `Create architecture diagram for remediate`

View File

@ -0,0 +1,118 @@
---
description: Write or update documentation with validated examples using execute-then-document workflow
---
# Documentation Writing Workflow
Write documentation with real, validated examples by executing commands and capturing actual outputs.
## Workflow Overview
1. **Phase 1: Setup Validation** - You set up the project following quickstart/setup docs, fixing any issues found
2. **Phase 2: Documentation Task** - Update existing guide or create new one with validated examples
3. **Phase 3: Cleanup** - Tear down test infrastructure when complete
## Phase 1: Setup Validation
**MANDATORY: You must complete this phase before ANY documentation work. Do not skip to Phase 2.**
**Purpose**: Validate the quickstart and setup docs are accurate while preparing the environment.
**Key Rule**: You execute ALL setup commands using the Bash tool. The user only executes examples that will appear in the final documentation.
### Step 1.1: Identify Setup Documentation
Locate the project's **user-facing** setup documentation:
- Look for `docs/quick-start.md`, `docs/setup/`, `README.md`, or similar
- Identify the recommended setup method for documentation work
- **IMPORTANT**: Follow only user-facing docs, not internal test infrastructure or developer scripts (unless the user-facing docs explicitly reference them)
### Step 1.2: Execute Setup Steps
**You must execute each setup step exactly as written** in the documentation:
1. Run each command from the setup docs in order using the Bash tool
2. If the docs reference a script, run that script
3. Verify output matches expected behavior
4. If a prerequisite is missing (e.g., no Kubernetes cluster):
- **Stop and inform the user** what prerequisite is needed
- **Wait for user** to set it up or provide guidance
- **Do not improvise** alternative setup methods
5. If a step fails or is unclear:
- **Stop and explain** what failed to the user
- **Propose a fix** to the documentation
- **Get user approval** before updating the docs
- **Continue** only after the docs are fixed and the step succeeds
Continue until setup is complete and verified.
### Step 1.3: Verify Environment Ready
Before proceeding to Phase 2, you must verify:
- [ ] All setup commands executed successfully
- [ ] Environment is verified working (run a simple test command from the docs)
- [ ] The features to be documented are accessible and functional
**Only proceed to Phase 2 after all checks pass.**
## Phase 2: Documentation Task
### Determine Task Type
If the documentation task is clear from context (e.g., from a PRD, previous conversation, or user's initial request), proceed directly. Otherwise, ask: "What documentation do you need to write?"
**Task types:**
1. **New guide** - Create a new guide file (write in chunks)
2. **Update existing guide** - Modify an existing doc with new sections
3. **Cross-reference updates** - Update multiple docs to reference new features
### For New Guides: Chunked Writing
**CRITICAL**: Write new guides in small chunks for easier review.
**Before writing**: Read existing guides in the same directory to understand the format, structure, and style. New guides should be consistent with existing documentation (headings, code block formatting, section order, etc.).
**Chunk Order:**
1. **Chunk 1: Header + Overview** (Title, summary, prerequisites, overview)
2. **Chunk 2: First major section** (e.g., basic usage, first workflow)
3. **Chunk 3: Second major section** (e.g., advanced usage, second workflow)
4. **Continue** with remaining sections, one at a time
**For each chunk:**
1. Tell user what to execute (these are the examples being documented)
2. Wait for them to paste actual output
3. Write the chunk using real output
4. Ask for review before proceeding to next chunk
### For Existing Guide Updates
1. Read the existing guide
2. Identify where new content should go
3. Tell user what to execute for documented examples
4. Write the update using real outputs
5. Show the diff/changes for review
### Execute-Then-Document Pattern
**User executes only what gets documented:**
1. **Tell user exactly what to run** - These are the examples that will appear in the docs
2. **Wait for actual output** - Never guess or fabricate outputs
3. **Use real output in docs** - Trim long outputs to show only the relevant parts; the goal is clarity, not completeness
4. **Note any variations** - If output varies, document what to expect
### Cross-Reference Updates
When a new feature is documented, search for related docs that may need updates (e.g., overviews, indexes, READMEs, related guides). For each file, show the specific edit and ask for confirmation.
## Phase 3: Cleanup
After documentation is complete:
1. **Tear down infrastructure** - If test environment was created and is no longer needed
2. **Suggest commit** - Remind user to commit changes
## Key Principle
You execute setup; user executes only the examples that will appear in the documentation.

View File

@ -0,0 +1,13 @@
#!/bin/bash
# Hook: Remind about changelog fragment when starting /prd-done workflow
# Read all of stdin (JSON may be multiline)
INPUT=$(cat)
# Check if prompt contains prd-done
if ! echo "$INPUT" | grep -q "prd-done"; then
exit 0
fi
# For UserPromptSubmit, plain text stdout is added to Claude's context
echo "🛑 CHANGELOG CHECK: Run /changelog-fragment BEFORE any commits if there are user-facing changes."

View File

@ -0,0 +1,14 @@
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": ".claude/hooks/prd-done-changelog-reminder.sh"
}
]
}
]
}
}

View File

@ -0,0 +1,100 @@
---
name: dot-ai-changelog-fragment
description: Create changelog fragment for release notes. Invoke during /prd-done workflow during the first push to the PR.
user-invocable: true
---
# Create Changelog Fragment
Create a towncrier changelog fragment for release notes when completing PRD work. This should be included in the PR so the fragment is reviewed along with the code changes.
## Workflow
### Step 1: Identify the PRD
If not already known from context, ask: "Which PRD should I create release notes for?"
Look for:
- PRD mentioned in recent conversation
- PRD referenced in current branch name (e.g., `feature/prd-320-*`)
- PRD file path provided by user
### Step 2: Read the PRD Thoroughly
Read the entire PRD file to extract:
- **Problem Statement**: What user pain point was solved, why it mattered
- **Solution Overview**: What the feature does, how it works
- **User Impact**: Specific benefits, what users can now do
- **Key Capabilities**: Individual features, options, or modes added
- **Technical Details**: Configuration options, environment variables, commands
- **Documentation Updates**: Which docs were added or updated (check Milestones section)
### Step 3: Determine Fragment Type
Read `pyproject.toml` to see the available fragment types. Each `[[tool.towncrier.type]]` section has:
- A comment above it describing when to use that type
- A `directory` field (the type identifier used in the filename, e.g., `feature` for `.feature.md`)
Choose the type that best matches the PRD based on those descriptions.
### Step 4: Write the Fragment
Create file: `changelog.d/[issue-id].[type].md`
**IMPORTANT: Use flat structure, NOT subdirectories!**
- ✅ Correct: `changelog.d/329.feature.md`
- ❌ Wrong: `changelog.d/feature/329.md`
**Naming convention:**
- `issue-id`: GitHub issue number from PRD (e.g., `320`)
- `type`: Type identifier from step 3 (e.g., `feature`, `bugfix`, `misc`)
**Content format:**
```markdown
## [Feature Title]
[Opening sentence: What this feature is and the problem it solves]
[Key capabilities paragraph: Specific things users can now do, with concrete examples]
[Configuration/usage paragraph if applicable: How to enable or use the feature]
[Documentation link if docs were updated]
```
**Documentation links:**
If the PRD includes documentation updates, link to the relevant page on devopstoolkit.ai. The URL pattern is:
- `https://devopstoolkit.ai/docs/{project}/{path}`
- Where `{project}` is: `mcp` (dot-ai), `controller` (dot-ai-controller), `ui` (dot-ai-ui), or `stack` (dot-ai-stack)
- And `{path}` maps from the docs folder (e.g., `docs/guides/mcp-recommendation-guide.md``guides/mcp-recommendation-guide`)
**Example: `changelog.d/142.feature.md`**
```markdown
## Multi-Cluster Management
Manage multiple Kubernetes clusters from a single dot-ai instance. Previously, each cluster required its own dot-ai deployment, making it difficult to compare configurations or apply consistent patterns across environments.
The `query` tool now accepts a `--cluster` flag to target specific clusters, and results indicate which cluster each resource belongs to. The `recommend` tool can generate manifests targeting different clusters with environment-specific customizations. Cross-cluster searches let you find resources across all connected clusters simultaneously—useful for tracking down where a particular workload is deployed. Cluster health aggregation shows a unified view of all clusters in the `version` output.
Configure additional clusters by adding kubeconfig contexts to `ADDITIONAL_KUBECONFIGS` (comma-separated paths). Each context becomes available as a cluster target. The default cluster remains the current kubeconfig context when no `--cluster` flag is specified.
See the [Multi-Cluster Setup Guide](https://devopstoolkit.ai/docs/mcp/setup/multi-cluster-setup) for configuration details and examples.
```
### Step 5: Confirm Creation
Show the user:
1. The fragment file path created
2. The content written
3. Reminder to commit and push with the PR
## Guidelines
- **User-focused**: Describe what users gain, not implementation details
- **Specific**: Include concrete examples of what each capability does
- **Complete**: Cover all major features added, not just the headline
- **Present tense**: "Tools now return..." not "Added support for..."
- **No diary style**: "Multi-Cluster Management" not "Added multi-cluster support"
- **Include configuration**: Mention environment variables, commands, or setup steps
- **Link to docs**: If PRD updated documentation, link to the specific page on devopstoolkit.ai

View File

@ -0,0 +1,310 @@
---
name: dot-ai-generate-cicd
description: Generate intelligent CI/CD workflows through interactive conversation by analyzing repository structure and user preferences
user-invocable: true
---
# Generate CI/CD Workflows
Generate appropriate CI/CD workflows for the current project through an interactive conversation. This prompt analyzes your entire repository, presents findings, asks about workflow preferences, and generates workflows based on your confirmed choices.
## Instructions
You are helping a developer set up CI/CD workflows for their project. Unlike template-based generators, you will:
1. **Analyze** the entire repository - source code, automation, configs, docs, existing CI
2. **Present findings** and workflow options to the user for decision-making
3. **Generate** workflows based on confirmed user choices
This interactive model is essential because CI/CD workflows involve **policy decisions** (PR vs direct push, release triggers, deployment strategy) that cannot be deduced from code alone—they reflect team preferences and organizational policies.
### Key Rules
**Verify everything**: Before adding any step, secret, or configuration, verify it by examining the actual codebase. Never assume. Ask when uncertain.
**Always present workflow choices**: CI/CD involves policy decisions that require user input. Even if you detect tests and a Dockerfile, you cannot know whether tests should run on PR or main, what triggers releases, which registry to use, or how to deploy. These are workflow choices that require user input.
---
## Best Practices
Apply these practices when generating workflows.
### Use Project Automation, Not Inline Commands
CI workflows should call project automation, not contain inline command logic.
```yaml
# ❌ BAD - Logic in CI, can't run locally the same way
- run: |
jest --coverage --ci
eslint src/ --format=stylish
# ✅ GOOD - CI calls project automation
- run: npm test
- run: npm run lint
```
**Why**: Local/CI parity, CI platform portability, easier debugging, single source of truth.
**When project automation doesn't exist**, ask the user:
```text
I didn't find automation for [operation]. Would you like me to:
1. Add it to the project (recommended for local/CI parity)
2. Use inline command in workflow
```
### Actions for Infrastructure, Project Commands for Logic
| Category | Examples | Approach |
|----------|----------|----------|
| **CI Infrastructure** | checkout, setup runtime, cache, registry login | ✅ Use actions |
| **Project Logic** | build, test, lint, docker build, deploy | ✅ Use project automation |
### Secret Handling
Secrets are only accessible from the org/owner that has them configured. Fork PRs cannot access base repo secrets.
Use conditional to skip steps when secrets unavailable:
```yaml
- name: Run integration tests
if: secrets.API_KEY != ''
run: npm run test:integration
env:
API_KEY: ${{ secrets.API_KEY }}
```
When the generated workflow requires secrets, document them clearly:
```markdown
## Required Secrets
| Secret Name | Description | How to Create |
|-------------|-------------|---------------|
| `REGISTRY_USERNAME` | Container registry username | Your registry account username |
| `REGISTRY_TOKEN` | Container registry access token | Registry settings > Access Tokens |
**To create secrets via CLI:**
gh secret set REGISTRY_USERNAME
gh secret set REGISTRY_TOKEN
```
Show the `gh secret set` commands as guidance, but do NOT execute them.
### Security
| Practice | Description |
|----------|-------------|
| **Minimal permissions** | Use `permissions:` block, grant only what's needed |
| **OIDC over long-lived tokens** | For cloud providers, prefer OIDC federation |
| **Pin action versions** | Use SHA or version tags, never `@latest` |
| **Disable credential persistence** | Use `persist-credentials: false` on `actions/checkout` |
| **Prevent script injection** | Never interpolate untrusted inputs (branch names, PR titles) directly into `run:` commands |
| **Avoid `pull_request_target`** | This trigger has access to secrets but can checkout fork code - dangerous combination |
| **Environment protection** | Use GitHub environments with required reviewers for production deployments |
### Testing
| Practice | Description |
|----------|-------------|
| **Fail fast** | Run quick checks (lint) before slow ones (tests) |
| **Test before build** | Don't waste time building if tests fail |
| **Parallel jobs** | Run independent checks concurrently |
| **Test matrix** | Consider multiple versions/platforms if relevant |
### Caching
Implement appropriate caching based on detected package manager and lock files.
---
## Process
**IMPORTANT**: Execute this process SEQUENTIALLY. Each step may change the direction of the conversation. Do NOT batch all questions upfront - ask questions one phase at a time and wait for user responses before proceeding.
The workflow follows three phases:
```text
┌─────────────────────────────────────────────────────────────────┐
│ PHASE 1: ANALYZE │
│ Discover what CAN be built/tested/deployed │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ PHASE 2: PRESENT & ASK │
│ Show findings + present workflow choices for user decision │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ PHASE 3: GENERATE │
│ Create workflows based on confirmed user choices │
└─────────────────────────────────────────────────────────────────┘
```
### Step 0: Determine CI Platform (BLOCKING GATE)
**CRITICAL**: This is a blocking gate. Ask about CI platform FIRST and ALONE. Do NOT ask any other questions or perform any analysis until the user confirms they want GitHub Actions.
Ask the user which CI/CD platform they use. Present ONLY these options:
1. **GitHub Actions**
2. **Other**
**If GitHub Actions** → Proceed to Step 1 (analysis)
**If Other** → STOP. Ask which platform they use, then respond:
```text
[Platform] is not yet supported. Would you like me to open a feature
request issue at https://github.com/dot-ai-app/dot-ai/issues so we
can prioritize adding it?
1. Yes, open a feature request
2. No, I'll use a different approach
```
Then handle the user's response (create issue or end conversation). Do NOT proceed to repository analysis for unsupported platforms.
### Step 1: Comprehensive Repository Analysis
**Analyze everything. The entire repository is context.**
#### 1.1 Language and Framework Detection
- Identify primary language(s) from source files and dependency manifests
- Detect frameworks from dependencies
- Note version requirements
#### 1.2 Discover and Understand Existing Automation
Find what automation exists and **read scripts to understand how they work** - what arguments they accept, what they handle internally, how they should be called. Don't just note that a script exists; understand it.
- If automation exists for a task → use it in the generated workflow
- Only generate raw commands if no existing automation found
- When multiple automation options exist → ask the user
**Why this matters**: Existing automation often handles setup, fixtures, environment variables, and cleanup that raw commands would miss. The maintainers chose their build system for a reason.
#### 1.3 Existing CI Analysis
Check for existing CI configuration. If found:
- Analyze what's already configured and why
- During Step 2, ask user whether to update existing workflows or create new ones
#### 1.4 Container and Registry Detection
- Check for Dockerfile and container configuration
- Search for registry references in existing CI, automation, or docs
- If no Dockerfile but project could benefit from containerization, suggest using `/generate-dockerfile` prompt
#### 1.5 Branching and Release Strategy
- Check for patterns in existing CI triggers
- Look at git tags for versioning patterns
- Check documentation for workflow hints
#### 1.6 Environment and Secrets
- Find environment variable documentation or examples
- Search code for required environment variables
- Identify what secrets the workflow will need
#### 1.7 App Definition Detection
Identify how the application is packaged for deployment:
- Helm charts
- Kustomize configurations
- Plain Kubernetes manifests
- Container-only (no K8s deployment)
#### 1.8 Deployment Mechanism Detection
Identify how the application is deployed:
- GitOps (ArgoCD, Flux)
- Direct deployment (Helm, kubectl)
- Manual deployment
- External system
**For GitOps**:
- CI must NOT deploy directly - it updates manifests, GitOps controller syncs
- Determine if GitOps resources (ArgoCD Application, Flux Kustomization) exist
- If not, may need to create them (same repo or separate cluster-config repo)
- Determine where manifests live for image tag updates
If unclear, ask user during Step 2.
#### 1.9 Tool Manager Detection
Check for existing tool/environment managers (DevBox, mise, asdf, etc.). If found, use them automatically. If none, will ask user during interactive Q&A.
### Step 2: Present Findings for Confirmation
**Before generating workflows, present analysis summary.** Include only what's relevant to this project - the example below is illustrative, not a template to fill out:
```markdown
## Analysis Summary
I analyzed your repository and found:
**Language/Framework**: Node.js 20 with Express
**Build Command**: `npm run build` (from package.json)
**Test Command**: `npm test` (from package.json)
**Existing CI**: GitHub Actions workflow found (ci.yml)
**App Definition**: Helm chart in `charts/myapp/`
**Deployment Mechanism**: GitOps with ArgoCD
Is this correct? Would you like to change anything?
```
**User can**:
- Confirm findings → proceed to workflow choices
- Correct mistakes
- Clarify ambiguities
### Step 3: Present Workflow Choices
**Present choices relevant to this project based on analysis.** These are policy decisions that require user input. Only ask about what's applicable - for example, don't ask about container registry if there's no Dockerfile, or deployment strategy if it's a library.
Common choices include:
- **PR Workflow**: What should run on pull requests?
- **Release Trigger**: What triggers a release build?
- **Release Validation**: Should release workflow re-run checks that already passed in PR? (Re-run all = safest/slowest, Skip validation = fastest, Security scans only = compromise)
- **Container Registry**: Where to push images? (if containerized)
- **Environment Setup**: Native GitHub Actions or DevBox?
- **Deployment Strategy**: GitOps, direct, or manual? (if deployed)
Ask clarifying questions as needed:
- If branching strategy unclear: "Do you use feature branches with pull requests, or push directly to main?"
- If multiple automation options exist: "I found multiple ways to run tests. Which is the primary test command?"
- If GitOps detected but repo location unclear: "Where are your GitOps manifests stored - same repository or separate?"
### Step 4: Generate Workflow(s)
Generate appropriate workflow(s) based on analysis and confirmed user choices.
### Step 5: Validate Generated Workflow
Before presenting to user:
1. **Syntax validation**: Ensure valid YAML and GitHub Actions syntax
2. **Reference check**: Verify referenced automation exists
3. **Secret documentation**: List required secrets clearly
4. **Permission check**: Ensure permissions block is minimal
5. **Deployment check**: Verify deployment steps match selected mechanism
### Step 6: Present to User
Provide:
1. **Generated workflow file(s)** with explanatory comments
2. **Summary** of what was detected and decisions made
3. **Required secrets** to configure (with setup guidance)
4. **Required permissions and settings** - Based on what the workflow does, identify what permissions or repository settings are needed and provide instructions to configure them. Don't wait for the workflow to fail - tell users upfront what to configure.
### Step 7: Validate
After user approves, commit the workflows following the project's established process. Trigger the workflows, monitor runs, and iterate on any failures until they pass.

View File

@ -0,0 +1,581 @@
---
name: dot-ai-generate-dockerfile
description: Generate production-ready, secure, multi-stage Dockerfile and .dockerignore for any project
user-invocable: true
---
# Generate Production-Ready Dockerfile
Generate an optimized, secure, multi-stage Dockerfile and .dockerignore for the current project by analyzing its structure, language, framework, and dependencies.
## Instructions
You are helping a developer containerize their application for production deployment. Your task is to analyze the project structure and generate two files:
1. **Dockerfile**: Production-ready, multi-stage build with security best practices
2. **.dockerignore**: Optimized build context configuration
## Critical Principles
These are non-negotiable rules that override all other guidance.
### Verify Everything Before Adding It
**ABSOLUTE RULE**: Before adding ANY instruction, configuration, or feature to the Dockerfile, verify it by examining the actual codebase.
**Required Process**:
1. **Identify** what you think should be added
2. **Search the codebase** to verify it exists or is actually needed
3. **Only add if verified** - if you can't find evidence in the code, don't add it
4. **When uncertain, ask the user** - if you cannot deduce something from the codebase analysis, ask the user rather than guessing
**Never assume. Always verify. Ask when uncertain. Evidence-based Dockerfiles only.**
**Thoroughness over speed**: Shallow analysis leads to broken Dockerfiles. Before generating anything:
- Read the actual source files, not just file names or directory listings
- Search for patterns multiple times with different queries if needed
- Trace the application entry point through its imports and dependencies
- Don't stop at the first search result - investigate thoroughly
- If analysis feels quick, you probably missed something
A correct Dockerfile that took longer to generate is far better than a fast but broken one. Spend the time upfront.
### Multi-Architecture Support
**REQUIREMENT**: Ensure all Dockerfile instructions support multiple architectures (amd64, arm64, etc.).
**Apply to**:
- Base image selection: Use multi-arch official images
- Binary downloads: Detect architecture dynamically, never hardcode (amd64, x86_64, etc.)
- System package installation: Use package manager (automatically handles architecture)
- Build commands: Ensure cross-platform compatibility
**The Dockerfile must build successfully on different CPU architectures without modification.**
### NEVER Add HEALTHCHECK
**ABSOLUTE PROHIBITION**: DO NOT add HEALTHCHECK instruction under ANY circumstances.
**Why**:
- Health endpoints are application-specific and cannot be verified from codebase analysis
- Adding unverified health checks will cause containers to be marked unhealthy incorrectly
- Users will add their own HEALTHCHECK if their application has health endpoints
**If you add HEALTHCHECK, you are violating the "verify everything" principle.**
---
## Best Practices Reference
These are best practices to consider when generating the Dockerfile. **Apply them when relevant to the project** - not every practice applies to every situation:
- Package manager flags depend on which package manager is used (apt-get vs apk vs others)
- Language-specific guidance applies only to that language
- The "verify everything" principle overrides all: if a practice doesn't fit the project, skip it
Use this section as guidance during generation and a reference for validation.
### Security
| Practice | Description |
|----------|-------------|
| **Non-root user** | Create and run as a dedicated user (UID 10001+), never run as root |
| **Pin image versions** | Use specific tags like `node:20-alpine`, never `:latest` |
| **Official images** | Prefer Docker Official Images or Verified Publishers from trusted sources |
| **No secrets in image** | Never embed credentials, API keys, or passwords in Dockerfile or ENV instructions |
| **No sudo** | Don't use sudo in containers; switch USER explicitly when root access is needed |
| **Minimal packages** | Only install packages that are actually required for the application |
| **--no-install-recommends** | Use this flag with apt-get to prevent installing optional packages |
| **COPY over ADD** | Always use COPY unless you specifically need ADD's tar extraction; never use ADD with URLs |
| **No debugging tools** | Avoid installing curl, wget, vim, netcat in production images unless required by the application |
| **Clean in same layer** | Remove package manager caches in the same RUN command as installation |
| **Executables owned by root** | Application binaries should be owned by root but executed by non-root user |
### Image Selection
| Practice | Description |
|----------|-------------|
| **Minimal base images** | Prefer alpine, slim, distroless, or scratch over full distribution images |
| **Multi-stage builds** | Always separate build dependencies from runtime; build stage → runtime stage |
| **Match language needs** | Compiled languages → distroless/scratch; Interpreted → slim/alpine with runtime |
| **Derive version from project** | Get language version from project files (package.json engines, go.mod, etc.) |
### Build Optimization
| Practice | Description |
|----------|-------------|
| **Layer caching** | Copy dependency manifests (package.json, go.mod) before source code |
| **Combine RUN commands** | Chain related commands with `&&` to reduce layers and enable cleanup |
| **Explicit COPY** | Never use `COPY . .`; explicitly copy only required files and directories |
| **Order by change frequency** | Place stable instructions first (base image, deps) and volatile ones last (source code) |
| **Production dependencies only** | Install only production dependencies, not devDependencies |
### Maintainability
| Practice | Description |
|----------|-------------|
| **Sort arguments** | Alphabetize multi-line package lists for easier maintenance and review |
| **Use WORKDIR** | Always use WORKDIR to change directories, never `RUN cd` |
| **Exec form for CMD** | Use JSON array format: `CMD ["executable", "arg1"]` for proper signal handling |
| **Comment non-obvious decisions** | Explain why certain choices were made, not what the command does |
| **OCI labels** (optional) | Add metadata labels for image management (org.opencontainers.image.*) |
---
## Process
### Step 0: Check for Existing Dockerfile
**Before generating anything, check if the project already has a Dockerfile.**
1. Look for `Dockerfile` in the project root (also check for variants like `Dockerfile.prod`)
2. If found, read and store its contents for Step 2
3. Similarly, check for `.dockerignore` and read it if present
This determines whether Step 2 will generate new files or improve existing ones.
### Step 1: Analyze Project Structure
**Identify the project characteristics through exploration, not pattern matching.**
These are analysis goals, not lookup tables. The examples below are illustrative - apply the same analytical approach to ANY language, framework, or toolchain you encounter.
1. **Language Detection**: Explore the project to identify its programming language(s).
- Look for dependency manifest files (e.g., `package.json`, `go.mod`, `requirements.txt`, `Cargo.toml`, `Gemfile`, `composer.json`, `mix.exs`, `build.sbt`, etc.)
- Examine source file extensions
- Read manifest contents to understand the ecosystem
- **Principle**: Every language has some form of dependency declaration - find it and read it
2. **Version Detection**: Find the required language/runtime version.
- Search manifest files for version constraints or engine requirements
- Look for version files (e.g., `.node-version`, `.python-version`, `.ruby-version`, `.tool-versions`)
- Check CI configuration files which often specify versions
- **If project specifies a version** → use that exact version
- **If no version specified** → search online for the current LTS/stable version of that language/runtime
- **Principle**: Use the project's required version if specified, otherwise look up the current recommended version - never guess
3. **Framework Detection**: Identify frameworks from dependencies and project structure.
- Read the dependency list in manifest files
- Look for framework-specific configuration files
- Examine the project structure for framework conventions
- **Principle**: Frameworks leave fingerprints - configuration files, directory structures, dependencies
4. **Application Type**: Determine what kind of application this is by examining entry points and configuration.
- Web server/API: Look for HTTP server setup, route definitions, port binding
- CLI tool: Look for argument parsing, command definitions, bin entries
- Worker/background job: Look for queue consumers, scheduled tasks
- Static site: Look for build output configuration, no server code
- **Principle**: The entry point and its imports reveal the application's purpose
5. **Port Detection**: Search for port configuration in source code and configuration files.
- Look for environment variable usage (e.g., `PORT`, `HTTP_PORT`)
- Search for hardcoded port numbers in server initialization
- Check configuration files for port settings
- **Only add EXPOSE if you find concrete evidence**
6. **Build Requirements**: Identify how the project is built.
- Read the manifest file for build scripts/commands
- Identify the build tool (could be language-standard or third-party)
- Determine build outputs (compiled binaries, transpiled code, bundled assets)
- **Principle**: Every project that needs building has build instructions - find them
7. **System Dependencies**: Critical step - missing runtime binaries cause silent failures.
- Search the codebase for code that executes external commands or binaries
- Common patterns: shell execution, subprocess calls, exec functions, system calls
- For each binary found, verify it's needed at runtime (not just build time)
- Consider what the application actually does - does it need CLI tools, database clients, image processors?
- **When uncertain whether something is a runtime dependency, ask the user**
8. **Environment Variable Detection**: Critical step - missing env vars cause runtime failures.
- Search the codebase for environment variable access (every language has a way to read env vars)
- Look for `.env.example`, `.env.sample`, or similar files that document required variables
- Check configuration and startup code for env var usage
- Determine which vars are required (no default, app fails without) vs optional (has default)
- For required vars, set sensible defaults in the Dockerfile
- **Principle**: If the code reads an env var, the container probably needs it configured
### Step 2: Generate or Improve Dockerfile
**If no existing Dockerfile** → Generate a new multi-stage Dockerfile using the patterns below.
**If existing Dockerfile found** → Analyze it against the best practices and checklists below, then improve:
1. **Evaluate against checklists** - Check each item in the Builder and Runtime checklists
2. **Identify issues** - Security problems (running as root, :latest tags), missing optimizations (no multi-stage, COPY . .), maintainability issues
3. **Preserve intentional customizations** - Comments explaining decisions, custom configurations, environment-specific settings
4. **Edit to fix issues** - Apply best practices while keeping the existing structure where it's already correct
5. **Explain changes** - When presenting the improved Dockerfile, briefly note what was changed and why
Use the patterns and checklists below for both generation and validation.
**The examples below show structural patterns, not copy-paste templates.** Adapt the pattern to whatever language, package manager, and build tool the project uses.
#### Stage 1: Builder
```dockerfile
# Build stage - use an image with build tools for this language
FROM <language-image>:<version>-<variant> AS builder
WORKDIR /app
# PATTERN: Copy dependency manifests FIRST for layer caching
# Examples: package.json, go.mod, requirements.txt, Gemfile, Cargo.toml, pom.xml
COPY <dependency-manifest-files> ./
# PATTERN: Install dependencies, clean cache in same layer
# Use whatever package manager the project uses
RUN <install-dependencies-command> && \
<clean-cache-command>
# PATTERN: Copy only the source files needed for build
# Never use "COPY . ." - be explicit about what's needed
COPY <source-directories> ./
COPY <config-files-needed-for-build> ./
# PATTERN: Run the project's build command
RUN <build-command>
```
**Builder stage checklist**:
- [ ] Named stage (`AS builder`)
- [ ] Base image appropriate for the language (with build tools)
- [ ] Version derived from project files (not assumed)
- [ ] Dependency manifests copied before source code
- [ ] Dependencies installed with cache cleanup in same RUN
- [ ] Only required files copied (never `COPY . .`)
- [ ] Build command matches what the project actually uses
#### Stage 2: Runtime
```dockerfile
# Runtime stage - use minimal image appropriate for the language
# Compiled languages: consider distroless, scratch, or alpine
# Interpreted languages: use slim or alpine variant with runtime only
FROM <minimal-runtime-image>:<version>
WORKDIR /app
# PATTERN: Create non-root user (syntax varies by base image)
# Alpine uses addgroup/adduser, Debian uses groupadd/useradd
RUN <create-group-command> && \
<create-user-command>
# PATTERN: Copy ONLY runtime artifacts from builder
# What you copy depends on the language:
# - Compiled: just the binary
# - Interpreted: built output + runtime dependencies + minimal config
COPY --from=builder <build-outputs> ./
COPY --from=builder <runtime-dependencies> ./
# PATTERN: Set ownership to non-root user
RUN chown -R <user>:<group> /app
# Switch to non-root user BEFORE exposing ports or setting CMD
USER <non-root-user>
# Only if port was verified during analysis
EXPOSE <port>
# PATTERN: Use exec form for proper signal handling
# The command depends on how this application runs
CMD ["<executable>", "<args>"]
```
**Runtime stage checklist**:
- [ ] Minimal base image (alpine/slim/distroless/scratch as appropriate)
- [ ] Non-root user created (UID 10001+)
- [ ] Only runtime artifacts copied from builder
- [ ] No source code, tests, build tools, or dev dependencies
- [ ] Proper ownership set
- [ ] USER directive before CMD
- [ ] EXPOSE only if port was verified in analysis
- [ ] CMD in exec form (JSON array)
#### System Package Installation Pattern
When system packages are required, use the package manager appropriate for your base image. The principle is always the same: **install only what's needed and clean the cache in the same layer**.
Common examples (adapt to your base image's package manager):
```dockerfile
# apt-get (Debian, Ubuntu)
RUN apt-get update && \
apt-get install -y --no-install-recommends \
package1 \
package2 && \
rm -rf /var/lib/apt/lists/*
# apk (Alpine)
RUN apk add --no-cache \
package1 \
package2
# yum/dnf (RHEL, Fedora, CentOS)
RUN yum install -y \
package1 \
package2 && \
yum clean all && \
rm -rf /var/cache/yum
```
**Package installation checklist**:
- [ ] Used the correct package manager for the base image
- [ ] Used flags to skip optional/recommended packages where available
- [ ] Packages sorted alphabetically for maintainability
- [ ] Cache cleaned in same RUN command
- [ ] Only packages actually required by the application
### Step 3: Create or Improve .dockerignore
**If no existing .dockerignore** → Generate a minimal one based on the Dockerfile.
**If existing .dockerignore found** → Review it against the Dockerfile's COPY commands:
1. Remove redundant exclusions (directories not copied by Dockerfile anyway)
2. Add missing security exclusions (secrets inside copied directories)
3. Keep it minimal (~10-15 lines)
**Generate a MINIMAL .dockerignore file based on the Dockerfile.**
Since the Dockerfile uses **explicit COPY commands** (not `COPY . .`), .dockerignore serves a limited purpose:
1. **Security** - Exclude secret patterns that could exist INSIDE directories being copied
2. **Performance** - Exclude large directories that slow down build context transfer
#### Process
1. Review your Dockerfile's COPY commands - what directories does it copy?
2. Identify security risks inside those directories (secret files that could accidentally exist)
3. Identify large directories in the project (>1MB) that slow context transfer
4. Exclude ONLY those items
#### What NOT To Exclude
**DO NOT exclude directories that aren't copied by your Dockerfile!**
If your Dockerfile doesn't copy a directory, excluding it in .dockerignore is pointless redundancy.
#### Target Size
**~10-15 lines maximum.** If your .dockerignore exceeds 20 lines, you're likely adding unnecessary exclusions.
### Step 4: Build, Test, and Iterate
**Purpose**: Verify the Dockerfile works before presenting to user. A Dockerfile isn't done until it's validated.
#### 4.1 Build
Build the image to verify the Dockerfile syntax and instructions are correct:
```bash
docker build -t [project-name]-validation .
```
- If build succeeds → proceed to run
- If build fails → analyze the error, fix Dockerfile, retry
#### 4.2 Run
Start a container to verify the application runs:
```bash
docker run -d --name [project-name]-test [project-name]-validation
sleep 5 # Allow startup time
```
Check container state:
```bash
docker inspect --format='{{.State.Status}}' [project-name]-test
docker inspect --format='{{.State.ExitCode}}' [project-name]-test
```
**Expected behavior depends on application type** (determined in Step 1):
- **Services** (web servers, APIs, workers): Container should still be running
- **CLI tools / one-shot commands**: Container should have exited with code 0
If container crashed or exited unexpectedly → proceed to log analysis to understand why.
#### 4.3 Log Analysis
Capture and analyze container logs:
```bash
docker logs [project-name]-test 2>&1
```
**Analyze logs using your knowledge of the project from Step 1.** You know:
- What language and framework this is
- What the application is supposed to do
- What dependencies it requires
- What a successful startup looks like for this type of application
Use this context to determine if the logs indicate:
- The application started correctly, OR
- Something is wrong (errors, crashes, missing dependencies, permission issues, etc.)
If logs indicate a problem → identify root cause, fix Dockerfile or .dockerignore, retry.
#### 4.4 Linting (if available)
If `hadolint` is installed, run it to catch Dockerfile best practice issues:
```bash
hadolint Dockerfile
```
- If hadolint is not installed → skip this check
- If hadolint reports issues → evaluate each issue, fix if appropriate, retry
- Some hadolint warnings may be intentional (use judgment based on project context)
#### 4.5 Security Scan (if available)
If `trivy` is installed, scan the built image for vulnerabilities:
```bash
trivy image --severity HIGH,CRITICAL [project-name]-validation
```
- If trivy is not installed → skip this check
- If trivy reports HIGH/CRITICAL vulnerabilities in the base image → consider if a different base image version or variant would help
- If vulnerabilities are in application dependencies → note them for the user but don't block (dependency updates are outside Dockerfile scope)
#### 4.6 Iterate
If any validation step fails:
1. **Analyze** the specific error message or behavior
2. **Identify root cause** - common issues include:
- Missing file → incorrect COPY command or overly aggressive .dockerignore
- Missing dependency → system package not installed
- Permission denied → ownership or USER directive issue
- Module not found → build step incomplete or wrong files copied
- Hadolint warning → Dockerfile best practice issue
3. **Fix** the appropriate file (Dockerfile or .dockerignore)
4. **Retry** from step 4.1
**Maximum 5 iterations.** If still failing after 5 attempts:
- Stop and present current state to user
- Explain what's failing and what fixes were attempted
- Ask for guidance
#### 4.7 Cleanup
**Always clean up after validation**, whether successful or not:
```bash
docker stop [project-name]-test 2>/dev/null || true
docker rm [project-name]-test 2>/dev/null || true
docker rmi [project-name]-validation 2>/dev/null || true
```
Only proceed to present the Dockerfile to user after:
- All validation steps pass, AND
- Cleanup is complete
---
## Output Format
### For New Dockerfiles (no existing file)
**Present both files to the user:**
1. **Dockerfile** with clear comments explaining each section
2. **.dockerignore** with organized sections
**After generating, provide:**
- Brief explanation of design choices (base images, build stages, security measures)
- Build command: `docker build -t [project-name] .`
- Run command: `docker run -p [port]:[port] [project-name]`
- Image size expectations
### For Improved Dockerfiles (existing file found)
**Present the improved files with a summary of changes:**
1. **Dockerfile** - the improved version
2. **Changes made** - brief list of what was changed and why:
- Security fixes (e.g., "Added non-root user - was running as root")
- Optimization improvements (e.g., "Added multi-stage build to reduce image size")
- Best practice updates (e.g., "Changed CMD to exec form for signal handling")
3. **Preserved** - note any intentional customizations that were kept
4. **.dockerignore** - improved version if changes were needed
### For Both Cases
**Recommended next steps** (the Dockerfile has already been validated):
- Integrate into CI/CD pipeline
- Commit to version control
---
## Success Criteria
### Dockerfile Checklist
- [ ] Builds successfully without errors
- [ ] Uses multi-stage build (builder → runtime)
- [ ] Runs as non-root user (UID 10001+)
- [ ] Uses pinned version tags (no `:latest`)
- [ ] Uses minimal base images (alpine/slim/distroless)
- [ ] Copies dependency manifests before source (layer caching)
- [ ] Uses explicit COPY (no `COPY . .`)
- [ ] Combines RUN commands with `&&`
- [ ] Cleans package manager caches in same layer
- [ ] Uses `--no-install-recommends` (if apt-get used)
- [ ] Uses exec form for CMD (`["executable", "arg"]`)
- [ ] No debugging tools unless required
- [ ] No secrets or credentials embedded
### .dockerignore Checklist
- [ ] Minimal size (~10-15 lines)
- [ ] Excludes secrets inside copied directories
- [ ] Excludes large unnecessary directories
- [ ] Does NOT exclude directories not copied by Dockerfile
### Validation Checklist (Step 4)
- [ ] Image builds successfully
- [ ] Container starts without crashing
- [ ] Logs show no errors indicating application failure
- [ ] Hadolint passes (if installed)
- [ ] Trivy shows no critical base image vulnerabilities (if installed)
- [ ] Test container and image cleaned up
**Do not present Dockerfile to user until all validation checks pass.**
---
## Example Workflows
### New Dockerfile (no existing file)
1. **Check**: "No existing Dockerfile found. Will generate new one."
2. **Explore**: "Let me find the dependency manifest... found `<manifest-file>`. Reading it to understand the ecosystem."
3. **Identify**: "This is a `<language>` project using `<framework/tool>`. The manifest indicates version `<X>`."
4. **Trace**: "The entry point is `<file>`. Following imports to understand runtime needs."
5. **Structure**: "Multi-stage build: builder stage needs `<build-tools>`, runtime stage needs only `<runtime-artifacts>`."
6. **Dependencies**: "Searching for external binary usage... found `<binary>`. This needs to be in the runtime image."
7. **Generate**: "Create Dockerfile and .dockerignore. Check against best practices checklists."
8. **Build & Test**: "Building image... Running container... Checking logs..."
9. **Iterate** (if needed): "Build failed due to missing package. Adding to Dockerfile and retrying..."
10. **Cleanup & Present**: "Validation passed. Removing test artifacts. Here's your Dockerfile."
### Improving Existing Dockerfile
1. **Check**: "Found existing Dockerfile. Reading it to analyze..."
2. **Analyze project**: Same exploration as above to understand what the Dockerfile should do.
3. **Evaluate**: "Checking existing Dockerfile against best practices checklists..."
- "❌ Running as root - no USER directive"
- "❌ Using :latest tag instead of pinned version"
- "✅ Multi-stage build already in place"
- "✅ Dependency manifests copied first"
4. **Preserve**: "Keeping custom ENV variables and the specific port configuration - these appear intentional."
5. **Improve**: "Adding non-root user, pinning image version to match project requirements."
6. **Build & Test**: "Building improved image... Running container... Checking logs..."
7. **Iterate** (if needed): "Container crashed - logs show permission error. Fixing ownership and retrying..."
8. **Cleanup & Present**: "Validation passed. Removing test artifacts. Here are the improvements."
**Key mindset**: Investigate the actual project rather than matching against templates. Every project is unique. Don't present until validated.

View File

@ -0,0 +1,15 @@
---
name: dot-ai-manageKnowledge
description: "Manage the knowledge base: ingest documents, search with natural language, or delete chunks. Use \"ingest\" to store organizational documentation, \"search\" to find relevant content semantically, or \"deleteByUri\" to remove all chunks for a document. TIP: For complex questions, you can call search multiple times with different phrasings to gather comprehensive information before synthesizing your answer."
user-invocable: true
---
# dot-ai manageKnowledge
Manage the knowledge base: ingest documents, search with natural language, or delete chunks. Use "ingest" to store organizational documentation, "search" to find relevant content semantically, or "deleteByUri" to remove all chunks for a document. TIP: For complex questions, you can call search multiple times with different phrasings to gather comprehensive information before synthesizing your answer.
## Usage
```bash
dot-ai manageKnowledge
```

View File

@ -0,0 +1,15 @@
---
name: dot-ai-manageOrgData
description: "Unified tool for managing cluster data: organizational patterns, policy intents, and resource capabilities. For patterns and policies: supports create, list, get, delete, deleteAll, and search operations (patterns also support step-by-step creation workflow). For capabilities: supports scan, list, get, delete, deleteAll, and progress operations for cluster resource capability discovery and management. Use dataType parameter to specify what to manage: \"pattern\" for organizational patterns, \"policy\" for policy intents, \"capabilities\" for resource capabilities."
user-invocable: true
---
# dot-ai manageOrgData
Unified tool for managing cluster data: organizational patterns, policy intents, and resource capabilities. For patterns and policies: supports create, list, get, delete, deleteAll, and search operations (patterns also support step-by-step creation workflow). For capabilities: supports scan, list, get, delete, deleteAll, and progress operations for cluster resource capability discovery and management. Use dataType parameter to specify what to manage: "pattern" for organizational patterns, "policy" for policy intents, "capabilities" for resource capabilities.
## Usage
```bash
dot-ai manageOrgData
```

View File

@ -0,0 +1,15 @@
---
name: dot-ai-operate
description: AI-powered Kubernetes application operations tool for Day 2 operations. Handles updates, scaling, enhancements, rollbacks, and deletions through natural language intents. Analyzes current state, applies organizational patterns and policies, validates changes via dry-run, and executes approved operations safely.
user-invocable: true
---
# dot-ai operate
AI-powered Kubernetes application operations tool for Day 2 operations. Handles updates, scaling, enhancements, rollbacks, and deletions through natural language intents. Analyzes current state, applies organizational patterns and policies, validates changes via dry-run, and executes approved operations safely.
## Usage
```bash
dot-ai operate
```

View File

@ -0,0 +1,154 @@
---
name: dot-ai-port-destroy
description: Remove all Port integrations, Kubernetes resources, and local files created by /port-setup
user-invocable: true
---
# Destroy Port Integrations
Remove all Port integrations, Kubernetes resources, and local files created by `/port-setup`.
## Prerequisites
Check the following and instruct the user to install/configure if missing:
- **kubectl** - installed and configured with cluster access
- **helm** - installed
- **gh** - GitHub CLI installed and authenticated
- **Environment variables** set:
- `PORT_CLIENT_ID`
- `PORT_CLIENT_SECRET`
## General Guidelines
- **Confirm with user** before proceeding with deletion
- **Order matters** - stop syncing FIRST, then delete Port resources
- **Check existence** before attempting deletion to avoid errors
- **Consult Port MCP tools** to discover what was created
- **User actions vs automated**: Some steps require user action (marked with "User action required") - present these as instructions, then **STOP and wait for user confirmation** before proceeding to the next step.
---
# Step 0: Discover Environment
Before destroying, discover what exists and how it was deployed:
1. **GitOps Tool**: Check for ArgoCD (`argocd` namespace) or Flux (`flux-system` namespace)
2. **Manifest directory**: Check for Port-related manifests (e.g., `apps/port-*.yaml`)
3. **Port resources**: Use Port MCP tools to list blueprints, entities, actions, integrations
4. **GitHub resources**: Check for workflows (`.github/workflows/port-*.yaml`) and repository secrets
## GitOps Workflow Rules
**IMPORTANT: When ArgoCD or Flux is detected, deletions must go through Git first.**
1. **Delete manifests from Git** - Remove the YAML files from the manifest directory
2. **Commit and push** - The GitOps tool will detect changes and delete resources automatically
3. **Wait for sync** - Verify the resources are deleted before proceeding to Port cleanup
4. **Then delete Port resources** - Only after syncing stops, delete blueprints/entities/actions
This order ensures the exporter stops syncing before you delete resources in Port.
---
# Part 1: Delete Kubernetes Resources (FIRST - stops syncing)
**Critical:** Delete the K8s exporter FIRST to stop new entities from being synced to Port.
## Uninstall Port K8s Exporter
Check deployment method and delete accordingly:
**With ArgoCD/Flux (GitOps):**
1. Delete the manifest file from Git:
```bash
rm <manifest-dir>/port-k8s-exporter.yaml
git add -A && git commit -m "Remove port-k8s-exporter" && git push
```
2. Wait for ArgoCD/Flux to sync and delete the resources
3. Verify: `kubectl get ns port-k8s-exporter` should return not found
4. If namespace still exists after sync, delete it manually: `kubectl delete ns port-k8s-exporter`
**With Helm directly (non-GitOps):**
```bash
helm uninstall port-k8s-exporter -n port-k8s-exporter
kubectl delete secret port-credentials -n port-k8s-exporter
kubectl delete externalsecret port-credentials -n port-k8s-exporter # if using ESO
kubectl delete namespace port-k8s-exporter
```
---
# Part 2: Delete Port Self-Service Actions
Delete all self-service actions created for CRDs. Do this BEFORE deleting blueprints since actions reference blueprints.
1. Use `mcp__port-vscode-eu__list_actions` to find actions with identifiers matching patterns:
- `create_*`, `update_*`, `delete_*`
2. For each action, use `mcp__port-vscode-eu__delete_action`
---
# Part 3: Delete Port Blueprints and Entities (User Action Required)
Delete the blueprints created during setup from the Data Model page.
**Steps:**
1. Use `mcp__port-vscode-eu__list_blueprints` to discover which blueprints exist
2. Identify blueprints that were created by `/port-setup` (exclude system blueprints starting with `_` and the defaults: `cluster`, `namespace`, `workload`)
3. Present the list to the user
4. Instruct the user to:
- Go to [Data Model](https://app.getport.io/settings/data-model)
- **Tip:** Switch to **Cards** view (top-right toggle) to make it easier to find and delete blueprints
- For each blueprint, click the "..." menu -> **Delete All [Blueprint Name]**
- This deletes all entities AND the blueprint in one action
**STOP and wait for user confirmation before proceeding.**
---
# Part 4: Delete GitHub Workflows and Secrets
## Delete Workflow Files
Look for Port-related workflows and delete them:
```bash
rm .github/workflows/port-*.yaml
```
## Delete Repository Secrets
```bash
gh secret delete PORT_CLIENT_ID
gh secret delete PORT_CLIENT_SECRET
gh secret delete KUBE_CONFIG # if created
```
Commit and push the deletions:
```bash
git add -A && git commit -m "Remove Port self-service workflows" && git push
```
---
# Part 5: Delete GitHub Integration Mapping (Optional)
If user wants to remove GitHub integration:
1. Go to Port Data Sources: https://app.port.io/settings/data-sources
2. Find the GitHub integration
3. Either:
- Remove specific resource mappings (User action required)
- Or uninstall the entire GitHub App (User action required)
---
# Verification
After cleanup, verify:
1. **Kubernetes**: `kubectl get ns port-k8s-exporter` returns not found
2. **Port**: No custom blueprints, entities, or actions remain
3. **GitHub**: No Port-related workflows or secrets
4. **Local**: No Port manifests in the repository

View File

@ -0,0 +1,239 @@
---
name: dot-ai-port-setup
description: Set up Port integrations to sync Kubernetes resources and GitHub Actions to Port.io
user-invocable: true
---
# Setup Port Integrations
Set up Port integrations to sync Kubernetes resources and GitHub Actions to Port.io.
## Prerequisites
Check the following and instruct the user to install/configure if missing:
- **kubectl** - installed and configured with cluster access
- **helm** - installed (for checking chart versions)
- **gh** - GitHub CLI installed and authenticated
- **Environment variables** set:
- `PORT_CLIENT_ID`
- `PORT_CLIENT_SECRET`
## General Guidelines
- **Always check latest versions** of third-party tools (Helm charts, GitHub Actions, etc.) before creating manifests. Use `helm search repo` or check the official documentation.
- **Consult Port MCP tools** when in doubt - use them to explore existing blueprints, entities, actions, and integrations.
- **Validate each step** before moving to the next - verify resources are created, synced, and working as expected.
- **User actions vs automated**: Some steps require user action (marked with "User action required") - present these as instructions, then **STOP and wait for user confirmation** before proceeding to the next step.
---
# Step 0: Discover Environment
Before starting, discover what tools are available and gather configuration:
1. **GitOps Tool**: Check for ArgoCD (`argocd` namespace) or Flux (`flux-system` namespace)
2. **ESO**: Check for External Secrets Operator CRD and available ClusterSecretStores
3. **Manifest directory**: Ask the user where manifests should be stored (e.g., `apps/`, `manifests/`, `k8s/`)
| GitOps Tool | Deployment Method | Self-Service Actions |
|-------------|-------------------|---------------------|
| ArgoCD | ArgoCD Application manifests in Git | Commit YAML to Git → ArgoCD syncs |
| Flux | Flux HelmRelease/Kustomization in Git | Commit YAML to Git → Flux syncs |
| Neither | Manifests in Git + `kubectl apply` | Commit YAML to Git → `kubectl apply` |
| ESO Status | Secrets Method |
|------------|----------------|
| Installed with ClusterSecretStore | Use ExternalSecret to pull from secret manager |
| Not installed | Create Secret directly with `kubectl create secret` |
**Note:** Always store manifests in Git for auditability, regardless of GitOps availability.
## GitOps Workflow Rules
**IMPORTANT: When ArgoCD or Flux is detected, NEVER run `kubectl apply` on application manifests.**
Instead, follow this workflow:
1. **Write manifests to Git** - Create the YAML files in the manifest directory
2. **Commit and push** - The GitOps tool will detect changes and sync automatically
3. **Verify sync status** - Use `kubectl get applications -n argocd` (ArgoCD) or `flux get all` (Flux)
For **GitOps resources** (ArgoCD Applications, Flux Kustomizations/HelmReleases):
- Discover the deployment pattern by examining existing resources in the cluster
- Add new manifests to the appropriate watched directory so GitOps syncs them automatically
For **Secrets without ESO**:
- Use `kubectl create secret` directly (secrets cannot be stored unencrypted in Git)
---
# Part 1: Kubernetes Exporter
## Step 1: Create Port Credentials Secret
Create a Secret named `port-credentials` in the `port-k8s-exporter` namespace with keys `PORT_CLIENT_ID` and `PORT_CLIENT_SECRET`.
- **With ESO**: Create an ExternalSecret referencing the available ClusterSecretStore
- **Without ESO**: Create the Secret directly with `kubectl create secret`
## Step 2: Deploy the K8s Exporter
Deploy the `port-k8s-exporter` Helm chart from `https://port-labs.github.io/helm-charts`.
Key Helm values:
- `secret.useExistingSecret: true` and `secret.name: port-credentials`
- `overwriteConfigurationOnRestart: true` (forces use of configMap config)
- `stateKey` and `extraEnv[].CLUSTER_NAME` set to cluster identifier
- `configMap.config` with resource mappings (see Step 4)
Deployment method based on discovery:
- **ArgoCD**: Create ArgoCD Application manifest
- **Flux**: Create HelmRepository + HelmRelease manifests
- **Neither**: Run `helm install` then commit values to Git
## Step 3: Create Blueprints in Port
**Default blueprints** (always created by the exporter):
- `cluster` (Port concept, not a K8s resource)
- `namespace` (from namespaces)
- `workload` (from deployments, daemonsets, statefulsets)
**Discover and recommend:**
1. Run `kubectl api-resources` to list all available resources
2. Exclude resources already covered by defaults (namespaces, deployments, daemonsets, statefulsets)
3. Present findings to the user with recommendations
4. Let user select which additional resources to track
Create selected blueprints using Port MCP tools. All blueprints should have:
- Relation to `namespace` blueprint
- `creationTimestamp` property
## Step 4: Configure Resource Mappings
In the Helm values `configMap.config`, define mappings for the resources selected in Step 3.
**For nested resources** (arrays inside a resource spec), use `itemsToParse`:
```yaml
- kind: your.api/v1/yourresource
selector:
query: "true"
port:
itemsToParse: .spec.items
entity:
mappings:
- identifier: .item.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME
blueprint: '"child-blueprint"'
properties:
name: .item.name
relations:
Parent: .metadata.name + "-" + .metadata.namespace + "-" + env.CLUSTER_NAME
```
## Step 5: Configure Blueprint Relations
Analyze exported resources and establish relations:
- Examine ownerReferences to link child → parent resources
- Use selector labels to connect Services → Workloads
- Link Ingress/HTTPRoute → Services via backend references
For each relation:
1. Add the relation to the blueprint in Port
2. Add the corresponding JQ mapping in the exporter config
---
# Part 2: GitHub Integration
Sync GitHub workflows, workflow runs, and pull requests to Port.
## Step 1: Install Port's GitHub App (User action required)
1. Go to Port's Data Sources: https://app.port.io/settings/data-sources
2. Click "+ Data source" → select "GitHub"
3. Install the GitHub App on your account/organization
4. Select repositories to sync
5. Ensure permissions for: actions, checks, pull requests, repository metadata
## Step 2: Create GitHub Blueprints
Create blueprints for `githubWorkflow`, `githubWorkflowRun`, and `githubPullRequest` (if not exists) using Port MCP tools. Inspect integration kinds to determine appropriate properties.
## Step 3: Configure GitHub Integration Mapping
Use Port REST API to update the integration config with mappings for `pull-request`, `workflow`, and `workflow-run` kinds.
## Step 4: Trigger Integration Resync
After creating blueprints, trigger a resync so the integration populates them with data. Use the Port API:
```bash
# Get access token
curl -s -X POST 'https://api.getport.io/v1/auth/access_token' \
-H 'Content-Type: application/json' \
-d '{"clientId": "'"$PORT_CLIENT_ID"'", "clientSecret": "'"$PORT_CLIENT_SECRET"'"}' \
| jq -r '.accessToken' > ./port_access_token.txt
# Trigger resync (replace INTEGRATION_ID with actual ID)
curl -s -X PATCH 'https://api.getport.io/v1/integration/INTEGRATION_ID' \
-H "Authorization: Bearer $(cat ./port_access_token.txt)" \
-H 'Content-Type: application/json' \
-d '{}'
# Cleanup
rm -f ./port_access_token.txt
```
Get the integration ID from `mcp__port-vscode-eu__list_integrations`.
---
# Part 3: Self-Service Actions for CRDs
Create Port self-service actions that trigger GitHub workflows to manage CRD manifests.
## Step 0: Configure GitHub Repository Secrets
Use `gh secret set` to add required secrets:
- `PORT_CLIENT_ID` - Port client ID
- `PORT_CLIENT_SECRET` - Port client secret
- `KUBE_CONFIG` - (Only for non-GitOps) Base64-encoded kubeconfig
## Step 1: Create GitHub Workflows
Create workflow for each CRD with `workflow_dispatch` trigger accepting:
- `action` (create/update/delete)
- `name`, `namespace`
- Resource-specific inputs
- `port_run_id`
**Workflow steps:**
1. Checkout repository
2. Report "RUNNING" status to Port using `port-labs/port-github-action@v1`
3. Create/update/delete manifest in the configured manifest directory
4. Commit and push to Git
5. **Non-GitOps only**: Run `kubectl apply` or `kubectl delete`
6. Report "SUCCESS" or "FAILURE" to Port
## Step 2: Create Port Self-Service Actions
Create 3 actions per CRD using Port MCP tools:
- **CREATE** - Creates new resources (no entity context)
- **DAY-2** - Updates existing resources (has entity context)
- **DELETE** - Deletes resources (has entity context)
**Key template expressions:**
- `{{ .inputs.fieldName }}` - User input value
- `{{ .run.id }}` - Port action run ID
- `{{ .entity.identifier }}` - Entity identifier (for DAY-2/DELETE)
- `{{ .entity.identifier | split("-") | last }}` - Extract resource name from identifier
**For DAY-2 actions**, pre-populate inputs with current entity values:
```json
"default": {
"jqQuery": ".entity.properties.someField // \"default_value\""
}
```

View File

@ -0,0 +1,284 @@
---
name: dot-ai-prd-close
description: Close a PRD that is already implemented or no longer needed
user-invocable: true
---
# Close PRD
Close a PRD that is already implemented (in previous work or external projects) or is no longer needed. This workflow updates the PRD status, archives it, updates the GitHub issue, and commits directly to main without triggering CI.
## When to Use This Command
**Use `/prd-close` when:**
- ✅ PRD functionality is already implemented in a separate project or previous work
- ✅ PRD is no longer relevant (superseded, requirements changed, out of scope)
- ✅ PRD requirements are satisfied by existing functionality
- ✅ No new code implementation is needed in this repository
**DO NOT use `/prd-close` when:**
- ❌ You just finished implementing the PRD (use `/prd-done` instead)
- ❌ PRD has active implementation work in progress
- ❌ There are uncommitted code changes that need to be part of a PR
## Usage
```bash
# Interactive mode - will prompt for PRD number and closure reason
/prd-close
# With PRD number
/prd-close 20
# With PRD number and reason
/prd-close 20 "Already implemented by dot-ai-controller"
```
**Note**: If any `gh` command fails with "command not found", inform the user that GitHub CLI is required and provide the installation link: https://cli.github.com/
## Workflow Steps
### Step 1: Identify PRD and Reason
**If PRD number not provided:**
- Check conversation context for recent PRD discussion
- Check git branch for PRD indicators (e.g., `feature/prd-X`)
- If unclear, prompt user for PRD number
**Closure Reason Categories:**
- **Already Implemented**: Functionality exists in external project or previous work
- **No Longer Needed**: Requirements changed, out of scope, or superseded
- **Duplicate**: Another PRD covers the same functionality
- **Deferred**: Moved to future version or different project
**Required Information:**
- PRD number
- Closure reason (brief description)
- Implementation reference (if already implemented): link to repo, PR, or documentation
### Step 2: Read and Validate PRD
Read the current PRD file from `prds/[number]-*.md`:
**Validation checks:**
- [ ] PRD file exists and is readable
- [ ] Confirm with user that this PRD should be closed
- [ ] Verify closure reason makes sense given PRD content
- [ ] Ask user for implementation evidence (if "already implemented")
**Present PRD summary to user:**
```markdown
## PRD #X: [Title]
**Status**: [Current Status]
**Created**: [Date]
**Summary**: [Brief description of what PRD requested]
**Proposed Action**: Close as [reason]
**Implementation Reference**: [If applicable]
Proceed with closure? (yes/no)
```
### Step 3: Update PRD File
Update the PRD metadata:
**Metadata Updates:**
```markdown
**Status**: Complete [or] No Longer Needed [or] Duplicate
**Last Updated**: [Current Date]
**Completed**: [Current Date] [or] **Closed**: [Current Date]
```
### Step 4: Move PRD to Archive
Move the PRD file to the done directory and update roadmap:
```bash
git mv prds/[number]-[name].md prds/done/
```
**Note**: If the move fails because `prds/done/` doesn't exist, create it with `mkdir -p prds/done` and retry.
**Update ROADMAP.md (if it exists):**
- [ ] Check if `docs/ROADMAP.md` exists
- [ ] Remove the closed PRD from the roadmap (search for "PRD #[number]")
- [ ] Remove the entire line that references this PRD
- [ ] Closed PRDs should not appear in future roadmap as they're no longer being worked on
### Step 5: Update GitHub Issue
**Reopen issue temporarily to update:**
```bash
gh issue reopen [number]
```
**Update issue description with new PRD path and status:**
```bash
gh issue edit [number] --body "$(cat <<'EOF'
## PRD: [Title]
**Problem**: [Original problem statement]
**Solution**: [Original solution statement]
**Detailed PRD**: See [prds/done/[number]-[name].md](./prds/done/[number]-[name].md)
**Priority**: [Original Priority]
**Status**: ✅ **[COMPLETE/CLOSED]** - [Brief reason]
EOF
)"
```
### Step 6: Close GitHub Issue
Close the issue with comprehensive closure comment:
```bash
gh issue close [number] --comment "$(cat <<'EOF'
## ✅ PRD #[number] Closed - [Reason Category]
[Detailed explanation of why PRD is being closed]
### [If "Already Implemented"]
**Implementation Details**
This PRD requested [functionality]. **All core requirements are satisfied** by [implementation reference].
| Requirement | Implementation | Status |
|-------------|----------------|--------|
| [Requirement 1] | [Where implemented] | ✅ Complete |
| [Requirement 2] | [Where implemented] | ✅ Complete |
**Implementation Reference**: [Link to project/repo/PR]
[If there are gaps]
**Not Implemented** (deferred or out of scope):
- [Feature X] - [Why not needed or deferred]
### [If "No Longer Needed"]
**Reason for Closure**
[Explain why requirements changed, what superseded this, or why it's out of scope]
**Alternative Approach**: [If applicable]
[What replaced this PRD or how needs are met differently]
### Files
**PRD Location**: `prds/done/[number]-[name].md`
**Status**: [Complete/Closed]
**Closed**: [Date]
EOF
)"
```
### Step 7: Commit and Push
**Commit changes directly to main with skip CI:**
```bash
# Stage all changes
git add .
# Verify what will be committed
git status
# Commit with skip CI flag
git commit -m "docs(prd-[number]): close PRD #[number] - [brief reason] [skip ci]
- Moved PRD to prds/done/ directory
- Updated PRD status to [Complete/Closed]
- Updated GitHub issue description with new path
- [Implementation details or reason]
Closes #[number]"
# Pull latest and push to remote
git pull --rebase origin main && git push origin main
```
**Important**:
- Always use `[skip ci]` flag to avoid unnecessary CI runs for documentation changes
- Include issue reference (`Closes #[number]`) to link commit to issue
## Example Scenarios
### Example 1: Already Implemented in External Project
```bash
/prd-close 20 "Implemented by dot-ai-controller"
```
**Closure Comment:**
```markdown
## ✅ PRD #20 Closed - Already Implemented
This PRD requested proactive Kubernetes cluster monitoring with AI-powered remediation.
**Core functionality (60-80%) is already implemented** by the separate
[dot-ai-controller](https://github.com/vfarcic/dot-ai-controller) project.
| Requirement | Implementation | Status |
|-------------|----------------|--------|
| Continuous health checks | Event-based monitoring via K8s events | ✅ Complete |
| Intelligent alerting | Slack notifications with AI analysis | ✅ Complete |
| Automated remediation | Automatic/manual modes with confidence thresholds | ✅ Complete |
| Anomaly detection | AI-powered event analysis | ✅ Complete |
**Not Implemented** (advanced features, may be future PRD):
- Continuous metrics monitoring (Prometheus-style)
- Predictive analytics with baseline learning
- Multi-channel alerting (email, PagerDuty)
```
### Example 2: Duplicate PRD
```bash
/prd-close 45 "Duplicate of PRD #44"
```
**Closure Comment:**
```markdown
## 🔄 PRD #45 Closed - Duplicate
This PRD covers the same functionality as PRD #44. Consolidating all work
under PRD #44 to avoid fragmentation.
**Action**: Continue work on PRD #44 instead.
```
### Example 3: No Longer Needed
```bash
/prd-close 12 "Requirements changed, out of scope"
```
**Closure Comment:**
```markdown
## ⏸️ PRD #12 Closed - No Longer Needed
After discussion, this approach no longer aligns with project direction.
Requirements have evolved and this PRD is out of scope.
**Alternative Approach**: Using [different solution/approach] instead.
```
## Success Criteria
**PRD file updated** with completion/closure metadata
**PRD archived** to `prds/done/` directory
**GitHub issue updated** with new PRD path
**GitHub issue closed** with comprehensive closure comment
**Changes committed to main** with skip CI flag
**Changes pushed to remote** repository
## Notes
- **No PR required**: This workflow commits directly to main for documentation-only changes
- **Skip CI**: Always include `[skip ci]` to avoid unnecessary CI runs
- **Comprehensive documentation**: Ensure issue comment clearly explains closure reason
- **Implementation references**: Link to external projects, repos, or PRs where functionality exists
- **Gap acknowledgment**: Be honest about what's implemented vs. what's missing

View File

@ -0,0 +1,210 @@
---
name: dot-ai-prd-create
description: Create documentation-first PRDs that guide development through user-facing content
user-invocable: true
---
# PRD Creation Slash Command
## Instructions
You are helping create a Product Requirements Document (PRD) for a new feature. This process involves two main components:
1. **GitHub Issue**: Short, immutable concept description that links to the detailed PRD
2. **PRD File**: Project management document with milestone tracking and implementation plan
## Process
### Step 1: Understand the Feature Concept
Ask the user to describe the feature idea to understand the core concept and scope.
### Step 2: Create GitHub Issue FIRST
Create the GitHub issue immediately to get the issue ID. This ID is required for proper PRD file naming.
**IMPORTANT: Add the "PRD" label to the issue for discoverability.**
### Step 3: Create PRD File with Correct Naming
Create the PRD file using the actual GitHub issue ID: `prds/[issue-id]-[feature-name].md`
### Step 4: Update GitHub Issue with PRD Link
Add the PRD file link to the GitHub issue description now that the filename is known.
### Step 5: Create PRD as a Project Management Document
Work through the PRD template focusing on project management, milestone tracking, and implementation planning. Documentation updates should be included as part of the implementation milestones.
**Key Principle**: Focus on 5-10 major milestones rather than exhaustive task lists. Each milestone should represent meaningful progress that can be clearly validated.
**Consider Including** (when applicable to the project/feature):
- **Tests** - If the project has tests, include a milestone for test coverage of new functionality
- **Documentation** - If the feature is user-facing, include a milestone for docs following existing project patterns
**Good Milestones Examples:**
- [ ] Core functionality implemented and working
- [ ] Tests passing for new functionality (if project has test suite)
- [ ] Documentation complete following existing patterns (if user-facing feature)
- [ ] Integration with existing systems working
- [ ] Feature ready for user testing
**Avoid Micro-Tasks:**
- ❌ Update README.md file
- ❌ Write test for function X
- ❌ Fix typo in documentation
- ❌ Individual file modifications
**Milestone Characteristics:**
- **Meaningful**: Represents significant progress toward completion
- **Testable**: Clear success criteria that can be validated
- **User-focused**: Relates to user value or feature capability
- **Manageable**: Can be completed in reasonable timeframe
## GitHub Issue Template (Keep Short & Stable)
**Initial Issue Creation (without PRD link):**
```markdown
## PRD: [Feature Name]
**Problem**: [1-2 sentence problem description]
**Solution**: [1-2 sentence solution overview]
**Detailed PRD**: Will be added after PRD file creation
**Priority**: [High/Medium/Low]
```
**Don't forget to add the "PRD" label to the issue after creation.**
**Issue Update (after PRD file created):**
```markdown
## PRD: [Feature Name]
**Problem**: [1-2 sentence problem description]
**Solution**: [1-2 sentence solution overview]
**Detailed PRD**: See [prds/[actual-issue-id]-[feature-name].md](https://github.com/vfarcic/dot-ai/blob/main/prds/[actual-issue-id]-[feature-name].md)
**Priority**: [High/Medium/Low]
```
## Discussion Guidelines
### PRD Planning Questions
1. **Problem Understanding**: "What specific problem does this feature solve for users?"
2. **User Impact**: "Walk me through the complete user journey — what will change for them?"
3. **Technical Scope**: "What are the core technical changes required?"
4. **Documentation Impact**: "Which existing docs need updates? What new docs are needed?"
5. **Integration Points**: "How does this feature integrate with existing systems?"
6. **Success Criteria**: "How will we know this feature is working well?"
7. **Implementation Phases**: "How can we deliver value incrementally?"
8. **Risk Assessment**: "What are the main risks and how do we mitigate them?"
9. **Dependencies**: "What other systems or features does this depend on?"
10. **Validation Strategy**: "How will we test and validate the implementation?"
### Discussion Tips:
- **Clarify ambiguity**: If something isn't clear, ask follow-up questions until you understand
- **Challenge assumptions**: Help the user think through edge cases, alternatives, and unintended consequences
- **Prioritize ruthlessly**: Help distinguish between must-have and nice-to-have based on user impact
- **Think about users**: Always bring the conversation back to user value, experience, and outcomes
- **Consider feasibility**: While not diving into implementation details, ensure scope is realistic
- **Focus on major milestones**: Create 5-10 meaningful milestones rather than exhaustive micro-tasks
- **Think cross-functionally**: Consider impact on different teams, systems, and stakeholders
**Note**: If any `gh` command fails with "command not found", inform the user that GitHub CLI is required and provide the installation link: https://cli.github.com/
**Note**: If creating the GitHub issue fails because the "PRD" label does not exist, create the label first (`gh label create "PRD" --description "Product Requirements Document" --color 0052CC`) and then retry creating the issue.
## Workflow
1. **Concept Discussion**: Get the basic idea and validate the need
2. **Create GitHub Issue FIRST**: Short, stable concept description to get issue ID
3. **Create PRD File**: Detailed document using actual issue ID: `prds/[issue-id]-[feature-name].md`
4. **Update GitHub Issue**: Add link to PRD file now that filename is known
5. **Section-by-Section Discussion**: Work through each template section systematically
6. **Milestone Definition**: Define 5-10 major milestones that represent meaningful progress
7. **Review & Validation**: Ensure completeness and clarity
**CRITICAL**: Steps 2-4 must happen in this exact order to avoid the chicken-and-egg problem of needing the issue ID for the filename.
## Update ROADMAP.md (If It Exists)
After creating the PRD, check if `docs/ROADMAP.md` exists. If it does, add the new feature to the appropriate timeframe section based on PRD priority:
- **High Priority** → Short-term section
- **Medium Priority** → Medium-term section
- **Low Priority** → Long-term section
Format: `- [Brief feature description] (PRD #[issue-id])`
The ROADMAP.md update will be included in the commit at the end of the workflow (Option 2).
## Next Steps After PRD Creation
After completing the PRD, present the user with numbered options:
```
✅ PRD Created Successfully!
**PRD File**: prds/[issue-id]-[feature-name].md
**GitHub Issue**: #[issue-id]
What would you like to do next?
**1. Start working on this PRD now**
Begin implementation immediately (recommended if you're ready to start)
**2. Commit and push PRD for later**
Save the PRD and work on it later (will use [skip ci] flag)
Please enter 1 or 2:
```
### Option 1: Start Working Now
If user chooses option 1, first commit and push the PRD (same as Option 2), then instruct them:
---
**PRD committed and pushed.**
To start working on this PRD, run `/prd-start [issue-id]`
---
### Option 2: Commit and Push for Later
If user chooses option 2:
```bash
# Stage the PRD file (and ROADMAP.md if it was updated)
git add prds/[issue-id]-[feature-name].md
# If docs/ROADMAP.md exists and was updated, include it:
# git add docs/ROADMAP.md
# Commit with skip CI flag to avoid unnecessary CI runs
git commit -m "docs(prd-[issue-id]): create PRD #[issue-id] - [feature-name] [skip ci]
- Created PRD for [brief feature description]
- Defined [X] major milestones
- Documented problem, solution, and success criteria
- Added to ROADMAP.md ([timeframe] section)
- Ready for implementation"
# Pull latest and push to main
git pull --rebase origin main && git push origin main
```
**Confirmation Message:**
```
✅ PRD committed and pushed to main
The PRD is now available in the repository. To start working on it later, execute:
prd-start [issue-id]
```
## Important Notes
- **Option 1**: Best when you have time to begin implementation immediately
- **Option 2**: Best when creating multiple PRDs or planning future work
- **Skip CI flag**: Always use `[skip ci]` when committing PRD-only changes
- **Issue reference**: Include issue number in commit message for traceability

View File

@ -0,0 +1,342 @@
---
name: dot-ai-prd-done
description: Complete PRD implementation workflow - create branch, push changes, create PR, merge, and close issue
user-invocable: true
---
# Complete PRD Implementation
Complete the PRD implementation workflow including branch management, pull request creation, and issue closure.
**Note**: If any `gh` command fails with "command not found", inform the user that GitHub CLI is required and provide the installation link: https://cli.github.com/
## Workflow Steps
### 0. Implementation Type Detection
**FIRST: Determine the type of PRD completion to choose the appropriate workflow**
**Documentation-Only Completion** (Skip PR workflow):
- ✅ Changes are only to PRD files or project management documents
- ✅ No source code changes
- ✅ No configuration changes
- ✅ Feature was already implemented in previous work
- → **Use Simplified Workflow** (Steps 1, 2-simplified, 5 only)
**Code Implementation Completion** (Full PR workflow):
- ✅ Contains source code changes
- ✅ Contains configuration changes
- ✅ Contains new functionality or modifications
- ✅ Requires testing and integration
- → **Use Full Workflow** (Steps 1-6)
### 1. Pre-Completion Validation
- [ ] **All PRD checkboxes completed**: Verify every requirement is implemented and tested
- [ ] **Documentation updated**: All user-facing docs reflect implemented functionality
- [ ] **No outstanding blockers**: All dependencies resolved and technical debt addressed
- [ ] **Update PRD status**: Mark PRD as "Complete" with completion date
- [ ] **Archive PRD file**: Move completed PRD to `./prds/done/` directory to maintain project organization
- [ ] **Update ROADMAP.md (if it exists)**: Remove the completed feature from `docs/ROADMAP.md` roadmap if the file exists
**Note**: Tests will run automatically in the CI/CD pipeline when the PR is created. Do not run tests locally during the completion workflow.
### 2. Branch and Commit Management
**For Documentation-Only Completions:**
- [ ] **Commit directly to main**: `git add [prd-files]` and commit with skip CI flag
- [ ] **Use skip CI commit message**: Include CI skip pattern in commit message to avoid unnecessary CI runs
- Common patterns: `[skip ci]`, `[ci skip]`, `***NO_CI***`, `[skip actions]`
- Check project's CI configuration for the correct pattern
- [ ] **Push to remote**: `git pull --rebase origin main && git push origin main` to sync changes
**For Code Implementation Completions:**
- [ ] **Create feature branch**: `git checkout -b feature/prd-[issue-id]-[feature-name]`
- [ ] **Commit all changes**: Ensure all implementation work is committed
- [ ] **Clean commit history**: Squash or organize commits for clear history
- [ ] **Push to remote**: `git push -u origin feature/prd-[issue-id]-[feature-name]`
### 3. Pull Request Creation
**IMPORTANT: Always check for and use PR template if available**
#### 3.1. PR Template Detection and Parsing
- [ ] **Check for PR template** in common locations:
- `.github/PULL_REQUEST_TEMPLATE.md`
- `.github/pull_request_template.md`
- `.github/PULL_REQUEST_TEMPLATE/` (directory with multiple templates)
- `docs/pull_request_template.md`
- [ ] **Read and parse template comprehensively**: If found, analyze the template to extract:
- **Structural elements**: Required sections, checklists, format requirements
- **Content requirements**: What information needs to be provided in each section
- **Process instructions**: Any workflow enhancements or prerequisites specified in the template
- **Validation requirements**: Any checks, sign-offs, or verifications mentioned
- [ ] **Extract actionable instructions from template**:
- **Commit requirements**: Look for DCO sign-off, commit message format, commit signing requirements
- **Pre-submission actions**: Build commands, test commands, linting, format checks
- **Documentation requirements**: Which docs must be updated, links that must be added
- **Review requirements**: Required reviewers, approval processes, special considerations
**Examples of template instructions to identify and execute:**
- "All commits must include a `Signed-off-by` line" → Validate commits have DCO sign-off, amend if missing
- "Run `npm test` before submitting" → Execute test command
- "PR title follows Conventional Commits format" → Validate title format
- "Update CHANGELOG.md" → Check if changelog was updated
- Any bash commands shown in code blocks → Consider if they should be executed
#### 3.2. Analyze Changes for PR Content
- [ ] **Review git diff**: Analyze `git diff main...HEAD` to understand scope of changes
- [ ] **Review commit history**: Use `git log main..HEAD` to understand implementation progression
- [ ] **Identify change types**: Determine if changes include:
- New features, bug fixes, refactoring, documentation, tests, configuration, dependencies
- Breaking changes or backward-compatible changes
- Performance improvements or security fixes
- [ ] **Check modified files**: Identify which areas of codebase were affected
- Source code files
- Test files
- Documentation files
- Configuration files
#### 3.3. Auto-Fill PR Information
Automatically populate what can be deduced from analysis:
- [ ] **PR Title**:
- Follow template title format if specified (e.g., Conventional Commits: `feat(scope): description`)
- Extract from PRD title/description and commit messages
- Include issue reference if required by template
- [ ] **Description sections**:
- **What/Why**: Extract from PRD objectives and implementation details
- **Related issues**: Automatically link using `Closes #[issue-id]` or `Fixes #[issue-id]`
- **Type of change**: Check appropriate boxes based on file analysis
- [ ] **Testing checklist**:
- Mark "Tests added/updated" if test files were modified
- Note: Tests run in CI/CD automatically
- [ ] **Documentation checklist**:
- Mark items based on which docs were updated (README, API docs, code comments)
- Check if CONTRIBUTING.md guidelines followed
- [ ] **Security checklist**:
- Scan commits for potential secrets or credentials
- Flag if authentication/authorization code changed
- Note any dependency updates
#### 3.4. Prompt User for Information That Cannot Be Deduced
**IMPORTANT: Don't just ask - analyze and propose answers, then let user confirm or correct**
For each item, use available context to propose an answer, then present it to the user for confirmation:
- [ ] **Manual testing results**:
- **Analyze PRD testing strategy section** to understand what testing was planned
- **Check git commits** for testing-related messages
- **Propose testing approach** based on change type (e.g., "Documentation reviewed for accuracy and clarity, cross-references validated")
- Present proposal and ask: "Is this accurate, or would you like to modify?"
- [ ] **Breaking changes**:
- **Scan commits and PRD** for breaking change indicators
- If detected, **propose migration guidance** based on PRD content
- If not detected, **confirm**: "No breaking changes detected. Correct?"
- [ ] **Performance implications**:
- **Analyze change type**: Documentation/config changes typically have no performance impact
- **Propose answer** based on analysis (e.g., "No performance impact - documentation only")
- Ask: "Correct, or are there performance considerations?"
- [ ] **Security considerations**:
- **Check if security-sensitive files** were modified (auth, credentials, API keys)
- **Scan commits** for security-related keywords
- **Propose security status** (e.g., "No security implications - documentation changes only")
- Ask: "Accurate, or are there security considerations to document?"
- [ ] **Reviewer focus areas**:
- **Analyze PRD objectives** and **git changes** to identify key areas
- **Propose specific focus areas** (e.g., "Verify documentation accuracy, check cross-reference links, confirm workflow examples match implementation")
- Present list and ask: "Are these the right focus areas, or should I adjust?"
- [ ] **Follow-up work**:
- **Check PRD for "Future Enhancements" or "Out of Scope" sections**
- **Analyze other PRDs** in `prds/` directory for related work
- **Propose follow-up items** if any (e.g., "Future enhancements listed in PRD: template validation, AI-powered descriptions")
- Ask: "Should I list these, or is there other follow-up work?"
- [ ] **Additional context**:
- **Review PRD for special considerations**
- **Check if this is a dogfooding/testing PR**
- **Propose any relevant context** (e.g., "This PR itself tests the enhanced workflow it documents")
- Ask: "Anything else reviewers should know?"
**Presentation Format:**
Present all proposed answers together in a summary format:
```markdown
📋 **Proposed PR Information** (based on analysis)
**Manual Testing:** [proposed answer]
**Breaking Changes:** [proposed answer]
**Performance Impact:** [proposed answer]
**Security Considerations:** [proposed answer]
**Reviewer Focus:** [proposed list]
**Follow-up Work:** [proposed items or "None"]
**Additional Context:** [proposed context or "None"]
Please review and respond:
- Type "yes" or "confirm" to accept all
- Specify corrections for any items that need changes
```
#### 3.5. Execute Template Requirements
**IMPORTANT: Before creating the PR, identify and execute any actionable requirements from the template**
- [ ] **Analyze template for actionable instructions**:
- Scan template content for imperative statements, requirements, or commands
- Look for patterns like "must", "should", "run", "execute", "ensure", "verify"
- Identify bash commands in code blocks that appear to be prerequisites
- Extract any validation requirements mentioned in checklists
- [ ] **Categorize identified requirements**:
- **Commit-level actions**: Sign-offs, formatting, validation
- **Pre-submission commands**: Tests, builds, lints, format checks
- **Validation checks**: File existence, format compliance, content requirements
- **Documentation actions**: Required updates, links to add
- [ ] **Propose and execute requirements**:
- Present identified requirements to user: "Template specifies these actions: [list]"
- For each requirement, determine if it can be automated
- Propose execution: "Should I execute these now?"
- Execute confirmed actions and report results
- Handle failures gracefully and ask user how to proceed
- [ ] **Summary before PR creation**:
```markdown
✅ Template Requirements Status:
[List each requirement with status: executed/validated/skipped/failed]
Ready to create PR? (yes/no)
```
#### 3.6. Detect and Apply PR Label (if release.yml exists)
**IMPORTANT: Only apply labels if `.github/release.yml` exists - fully dynamic based on that file**
- [ ] **Check for `.github/release.yml`**:
- If file exists → Proceed with label detection
- If file doesn't exist → Skip label detection, proceed to create PR without labels
- [ ] **If release.yml exists, parse it to understand available categories and labels**:
- Read the YAML file
- Extract all category definitions with their associated labels
- Build a mapping of: category → list of labels
- Note the category order (categories listed first are typically more important)
- [ ] **Analyze PR characteristics**:
- **Primary change type**: What is the MAIN purpose of this PR?
- **File changes**: Types of files modified (extensions, paths, purposes)
- **Change scope**: Which areas of codebase affected
- **Commit messages**: Keywords, patterns, prefixes
- **PR title and description**: Keywords indicating change type
- **PRD context**: Original problem/solution description
- [ ] **Select the SINGLE best-matching label**:
- For each category in release.yml, score how well it matches the PR's PRIMARY purpose
- Consider the importance hierarchy from release.yml:
- Breaking changes > New features > Bug fixes > Documentation > Dependencies > Other
- Select ONE label from the category that BEST represents the main change
- **Why single label?**: Prevents PRs from appearing in multiple release note categories
- **Selection priority**:
1. If any breaking changes → use `breaking-change` or `breaking`
2. If primarily new functionality → use `feat`, `feature`, or `enhancement`
3. If primarily fixing bugs → use `fix`, `bug`, or `bugfix`
4. If primarily documentation → use `documentation` or `docs`
5. If primarily dependencies → use `dependencies`, `deps`, or `dependency`
6. Otherwise → no specific label needed (will appear in "Other Changes")
- [ ] **Apply detected label**: Add the single best-matching label to the PR creation command
- Example: `gh pr create --title "..." --body "..." --label "fix"`
#### 3.7. Create Pull Request
- [ ] **Construct PR body**: Combine auto-filled and user-provided information following template structure
- [ ] **Create PR**:
- If label detected: `gh pr create --title "[title]" --body "[body]" --label "[single-label]"`
- If no release.yml or no matching label: `gh pr create --title "[title]" --body "[body]"`
- [ ] **Verify PR created**: Confirm PR was created successfully, template populated correctly, and label applied (if applicable)
- [ ] **Request reviews**: Assign appropriate team members for code review if specified
#### 3.8. Fallback for Projects Without Templates
If no PR template is found, create a sensible default structure:
```markdown
## Description
[What this PR does and why]
## Related Issues
Closes #[issue-id]
## Changes Made
- [List key changes]
## Testing
- [Testing approach and results]
## Documentation
- [Documentation updates made]
```
### 4. Review and Merge Process
- [ ] **Check ongoing processes**: Use `gh pr checks [pr-number]` to check for any ongoing CI/CD, security analysis, or automated reviews (CodeRabbit, CodeQL, etc.)
- [ ] **Check PR details**: Use `gh pr view [pr-number]` to check for human review comments and PR metadata
- [ ] **Review all automated feedback**: Check PR comments section for automated code review feedback (bots, linters, analyzers)
- **Use multiple methods to capture all feedback**:
- **MCP servers** (preferred when available): Use any available MCP servers for comprehensive review data
- Code review MCPs (e.g., CodeRabbit, custom review servers) for detailed AI code reviews
- Check available MCP tools/functions related to code reviews, pull requests, or automated feedback
- CLI commands: `gh pr view [pr-number]`, `gh pr checks [pr-number]`, `gh api repos/owner/repo/pulls/[pr-number]/comments`
- **Web interface inspection**: Fetch the PR URL directly to capture all comments, including inline code suggestions that CLI tools may miss
- Look for comments from automated tools (usernames ending in 'ai', 'bot', or known review tools)
- [ ] **Present ALL code review findings**: ALWAYS present every review comment to the user, regardless of severity
- **Show ALL comments**: Present every suggestion, nitpick, and recommendation - do not filter or omit any
- **Categorize findings**: Critical, Important, Optional/Nitpick based on impact
- **Provide specific examples**: Quote actual suggestions and their locations
- **Explain assessment**: Why each category was assigned
- **User decision**: Let user decide which improvements to implement before merge (critical items must be addressed, others are user's choice)
- [ ] **Assess feedback priority**: Categorize review feedback
- **Critical**: Security issues, breaking changes, test failures - MUST address before merge
- **Important**: Code quality, maintainability, performance - SHOULD address for production readiness
- **Optional**: Style preferences, minor optimizations - MAY address based on project standards
- [ ] **Wait for ALL reviews to complete**: Do NOT merge if any reviews are pending or in progress, including:
- **Automated code reviews** (CodeRabbit, CodeQL, etc.) - Must wait until complete even if CI passes
- **Security analysis** - Must complete and pass
- **CI/CD processes** - All builds and tests must pass
- **Human reviews** - If requested reviewers haven't approved
- **CRITICAL**: Never skip automated code reviews - they provide valuable feedback even when CI passes
- [ ] **Address review feedback**: Make required changes from code review (both automated and human)
- Create additional commits on the feature branch to address feedback
- Update tests if needed to cover suggested improvements
- Document any feedback that was intentionally not addressed and why
- [ ] **Verify all checks pass**: Ensure all CI/CD, tests, security analysis, and automated processes are complete and passing
- [ ] **Final review**: Confirm the PR addresses the original PRD requirements and maintains code quality
- [ ] **Merge to main**: Complete the pull request merge only after all feedback addressed and processes complete
- [ ] **Verify deployment**: Ensure feature works in production environment
- [ ] **Monitor for issues**: Watch for any post-deployment problems
### 5. Issue Closure
- [ ] **Update issue PRD link**: Update the GitHub issue description to reference the new PRD path in `./prds/done/` directory
- [ ] **Close GitHub issue**: Add final completion comment and close
- [ ] **Archive artifacts**: Save any temporary files or testing data if needed
- [ ] **Team notification**: Announce feature completion to relevant stakeholders
### 6. Branch Cleanup
- [ ] **Switch to main branch**: `git checkout main`
- [ ] **Pull latest changes**: `git pull origin main` to ensure local main is up to date
- [ ] **Delete local feature branch**: `git branch -d feature/prd-[issue-id]-[feature-name]`
- [ ] **Delete remote feature branch**: `git push origin --delete feature/prd-[issue-id]-[feature-name]`
## Success Criteria
**Feature is live and functional**
**All tests passing in production**
**Documentation is accurate and complete**
**PRD issue is closed with completion summary**
✅ **Team is notified of feature availability**
The PRD implementation is only considered done when users can successfully use the feature as documented.

View File

@ -0,0 +1,264 @@
---
name: dot-ai-prd-next
description: Analyze existing PRD to identify and recommend the single highest-priority task to work on next
user-invocable: true
---
# PRD Next - Work On the Next Task
## Instructions
You are helping analyze an existing Product Requirements Document (PRD) to suggest the single highest-priority task to work on next, then discuss its design if the user confirms they want to work on it.
## Process Overview
1. **Check Context Clarity** - Determine if PRD is obvious from recent conversation
2. **Auto-Detect Target PRD** - If context unclear, intelligently determine which PRD to analyze
3. **Analyze Current Implementation** - Understand what's implemented vs what's missing (skip if recent context available)
4. **Identify the Single Best Next Task** - Find the one task that should be worked on next
5. **Present Recommendation** - Give clear rationale and wait for confirmation
6. **Design Discussion** - If confirmed, dive into implementation design details
7. **Implementation** - User implements the task
8. **Update Progress** - Prompt user to run /prd-update-progress
## Step 0: Context Awareness Check
**FIRST: Check if PRD context is already clear from recent conversation:**
**Skip detection/analysis if recent conversation shows:**
- **Recent PRD work discussed** - "We just worked on PRD 29", "Just completed PRD update", etc.
- **Specific PRD mentioned** - "PRD #X", "MCP Prompts PRD", etc.
- **PRD-specific commands used** - Recent use of `/prd-update-progress`, `/prd-start` with specific PRD
- **Clear work context** - Discussion of specific features, tasks, or requirements for a known PRD
**If context is clear:**
- Skip to Step 6 (Single Task Recommendation) using the known PRD
- Use conversation history to understand current state and recent progress
- Proceed directly with task recommendation based on known PRD status
**If context is unclear:**
- Continue to Step 1 (PRD Detection) for full analysis
## Step 1: Smart PRD Detection (Only if Context Unclear)
**Auto-detect the target PRD using these context clues (in priority order):**
1. **Git Branch Analysis** - Check current branch name for PRD patterns:
- `feature/prd-12-*` → PRD 12
- `prd-13-*` → PRD 13
- `feature/prd-*` → Extract PRD number
2. **Recent Git Commits** - Look at recent commit messages for PRD references:
- "fix: PRD 12 documentation" → PRD 12
- "feat: implement prd-13 features" → PRD 13
3. **Git Status Analysis** - Check modified/staged files for PRD clues:
- Modified `prds/12-*.md` → PRD 12
- Changes in feature-specific directories
4. **Available PRDs Discovery** - List all PRDs in `prds/` directory:
- `prds/12-documentation-testing.md`
- `prds/13-cicd-documentation-testing.md`
5. **Fallback to User Choice** - Only if context detection fails, ask user to specify
**PRD Detection Implementation:**
```bash
# Use these tools to gather context:
# 1. Check git branch: gitStatus shows current branch
# 2. Check git status: Look for modified PRD files
# 3. List PRDs: Use LS or Glob to find prds/*.md files
# 4. Recent commits: Use Bash 'git log --oneline -n 5' for recent context
```
**Detection Logic:**
- **High Confidence**: Branch name matches PRD pattern (e.g., `feature/prd-12-documentation-testing`)
- **Medium Confidence**: Modified PRD files in git status or recent commits mention PRD
- **Low Confidence**: Multiple PRDs available, use heuristics (most recent, largest)
- **No Context**: Present available options to user
**Example Detection Outputs:**
```markdown
🎯 **Auto-detected PRD 12** (Documentation Testing)
- Branch: `feature/prd-12-documentation-testing`
- Modified files: `prds/12-documentation-testing.md`
- Recent commits mention PRD 12 features ✅
```
**Once PRD is identified:**
- Read the PRD file from `prds/[issue-id]-[feature-name].md`
- Analyze completion status across all sections
- Identify patterns in completed vs remaining work
## Step 2: Documentation & Implementation Analysis (Only if Context Unclear)
Before assessing task priorities, analyze both the documented specifications and current implementation state:
### Documentation Analysis (Documentation-First PRDs)
For PRDs using the documentation-first approach:
- **Read referenced documentation**: Check the "Content Location Map" in PRD to find where feature specs live
- **Understand target state**: What functionality is documented but not yet implemented
- **Check documentation completeness**: Are all user workflows and examples fully documented
- **Validate cross-references**: Do all documentation links and references work correctly
### Code Discovery
- **Search for related files**: Use Grep/Glob to find files related to the feature
- **Identify key modules**: Locate main implementation files mentioned in PRD
- **Find test files**: Discover existing test coverage for the feature
- **Check dependencies**: Review imports and module relationships
### Implementation vs Documentation Gap Analysis
- **Compare docs vs code**: What's documented vs actually implemented
- **Partial implementations**: Identify half-finished features or TODO comments
- **Documentation validation**: Can documented examples and commands actually work
- **Architecture alignment**: Does current code match documented behavior and PRD architecture decisions
- **Quality assessment**: Code style, error handling, test coverage gaps
### Technical Feasibility Analysis
- **Dependency conflicts**: Are PRD requirements compatible with existing code
- **Breaking changes**: Will remaining tasks require refactoring existing code
- **Integration points**: How new work connects with current implementation
- **Technical debt**: Issues that might block or slow future work
## Step 3: Completion Assessment (Only if Context Unclear)
### Analyze Checkbox States
Count and categorize all checkboxes:
- **Completed**: `[x]` items
- **Pending**: `[ ]` items
- **Deferred**: `[~]` items
- **Blocked**: `[!]` items
### Phase Analysis
For each implementation phase:
- Calculate completion percentage
- Identify bottlenecks or stalled work
- Assess readiness to move to next phase
### Requirement Coverage
Review requirement categories:
- **Functional Requirements**: Core feature completion
- **Non-Functional Requirements**: Quality and performance aspects
- **Success Criteria**: Measurable outcomes
- **Dependencies**: External requirements
- **Risk Mitigation**: Risk management progress
## Step 4: Dependency Analysis (Only if Context Unclear)
### Identify Critical Path Items
Look for items that:
- **Block other work** - Must be completed before others can start
- **Enable major capabilities** - Unlock significant value when completed
- **Resolve current blockers** - Remove impediments to progress
### Dependency Patterns
#### PRD-Level Dependencies
- **Sequential dependencies** - A must be done before B
- **Parallel opportunities** - Multiple items that can be worked simultaneously
- **Foundation requirements** - Core capabilities needed by multiple features
- **Integration points** - Items that connect different parts of the system
#### Code-Level Dependencies
- **Import dependencies** - Modules that depend on others being implemented first
- **Interface contracts** - APIs/types that must be defined before consumers
- **Database schema** - Data model changes needed before business logic
- **Test dependencies** - Tests that require certain infrastructure or mocks
- **Build/deployment** - Configuration changes that affect multiple components
## Step 5: Strategic Value Assessment (Only if Context Unclear)
### High-Value Next Steps
Prioritize items that:
- **Unblock multiple other items** - High leverage impact
- **Deliver user-visible value** - Direct user benefit
- **Reduce technical risk** - Address major uncertainties
- **Enable validation** - Allow testing of key assumptions
- **Provide learning** - Generate insights for future work
### Low-Priority Items
Identify items that:
- **Have many dependencies** - Can't be started yet
- **Are nice-to-have** - Don't impact core value proposition
- **Are optimization-focused** - Improve existing working features
- **Require external dependencies** - Waiting on others
## Step 6: Single Task Recommendation
**Note**: If you arrived here from Step 0 (clear context), use the conversation history and known PRD state to make your recommendation. If you came through the full analysis, use your detailed findings.
Present findings in this focused format:
```markdown
# Next Task Recommendation: [Feature Name]
## Recommended Task: [Specific Task Name]
**Why this task**: [2-3 sentences explaining why this is the highest priority right now]
**What it unlocks**: [What becomes possible after completing this]
**Dependencies**: [What's already complete that makes this ready to work on]
**Success criteria**: [How you'll know it's done]
---
**Do you want to work on this task?**
If yes, I'll help you design the implementation approach. If no, let me know what you'd prefer to work on instead.
```
## Step 7: Design Discussion (If Confirmed)
If the user confirms they want to work on the recommended task, then dive into:
### Implementation Planning
- **Architecture approach**: How this fits into existing codebase
- **Key components**: What needs to be built/modified
- **Integration points**: How it connects with existing code
- **Testing strategy**: How to validate the implementation
### Design Decisions
- **Technical choices**: Framework/library decisions to make
- **Interface design**: APIs, data structures, user interfaces
- **Error handling**: How to handle failure cases
- **Performance considerations**: Scalability and optimization needs
### Implementation Steps
- **Step-by-step breakdown**: Logical sequence of implementation
- **Quick wins**: Parts that can be completed first for validation
- **Risk mitigation**: Addressing the biggest uncertainties first
- **Testing checkpoints**: When and how to validate progress
### Questions to Resolve
- **Open decisions**: Design choices that need to be made
- **Clarifications needed**: Requirements that need more detail
- **Assumptions to validate**: Things we're assuming that should be confirmed
## Success Criteria
This command should:
- ✅ Identify the single highest-value task to work on next based on current PRD state
- ✅ Provide clear, compelling rationale for why this specific task should be prioritized
- ✅ Wait for user confirmation before proceeding
- ✅ If confirmed, provide detailed implementation design guidance
- ✅ Keep teams focused on the most important work rather than overwhelming them with options
- ✅ Enable immediate action by transitioning from recommendation to design discussion
## Step 8: Update Progress After Completion
**CRITICAL: Do NOT update the PRD yourself. Do NOT edit PRD files directly. Your job is to prompt the user to run the update command.**
After the user completes the task implementation, output ONLY this message:
---
**Task implementation complete.**
To update PRD progress and commit your work, run `/prd-update-progress`.
---
Then STOP. Do not proceed further. The `/prd-update-progress` command handles PRD updates, progress tracking, and commits. This separation ensures proper workflow and avoids duplicate/conflicting updates.

View File

@ -0,0 +1,188 @@
---
name: dot-ai-prd-start
description: Start working on a PRD implementation
user-invocable: true
---
# PRD Start - Begin Implementation Work
## Instructions
You are helping initiate active implementation work on a specific Product Requirements Document (PRD). This command sets up the implementation context (validates readiness, creates branch, prepares environment) then hands off to `/prd-next` for task identification.
**IMPORTANT**: Do NOT include time estimates or effort estimates in your responses. Focus on setup and readiness without speculating on duration.
## Process Overview
1. **Select Target PRD** - Identify which PRD to implement
2. **Validate PRD Readiness** - Ensure the PRD is ready for implementation
3. **Set Up Implementation Context** - Create branch and prepare environment
4. **Hand Off to prd-next** - Delegate task identification to the appropriate prompt
## Step 0: Check for PRD Argument
**If `prdNumber` argument is provided ({{prdNumber}}):**
- Skip context check and auto-detection
- Use PRD #{{prdNumber}} directly
- Proceed to Step 2 (PRD Readiness Validation)
**If `prdNumber` argument is NOT provided:**
- Continue to context awareness check below
## Step 0b: Context Awareness Check
**Check if PRD context is already clear from recent conversation:**
**Skip detection if recent conversation shows:**
- **Recent PRD work discussed** - "We just worked on PRD 29", "Just completed PRD update", etc.
- **Specific PRD mentioned** - "PRD #X", "MCP Prompts PRD", etc.
- **PRD-specific commands used** - Recent use of `/prd-update-progress`, `/prd-start` with specific PRD
- **Clear work context** - Discussion of specific features, tasks, or requirements for a known PRD
**If context is clear:**
- Skip to Step 2 (PRD Readiness Validation) using the known PRD
**If context is unclear:**
- Continue to Step 1 (PRD Detection)
## Step 1: Smart PRD Detection (Only if Context Unclear)
**Auto-detect the target PRD using these context clues (in priority order):**
1. **Git Branch Analysis** - Check current branch name for PRD patterns:
- `feature/prd-12-*` → PRD 12
- `prd-13-*` → PRD 13
- `feature/prd-*` → Extract PRD number
2. **Recent Git Commits** - Look at recent commit messages for PRD references:
- "fix: PRD 12 documentation" → PRD 12
- "feat: implement prd-13 features" → PRD 13
3. **Git Status Analysis** - Check modified/staged files for PRD clues:
- Modified `prds/12-*.md` → PRD 12
- Changes in feature-specific directories
4. **Available PRDs Discovery** - List all PRDs in `prds/` directory
5. **Fallback to User Choice** - Only if context detection fails, ask user to specify
**Detection Logic:**
- **High Confidence**: Branch name matches PRD pattern (e.g., `feature/prd-12-documentation-testing`)
- **Medium Confidence**: Modified PRD files in git status or recent commits mention PRD
- **Low Confidence**: Multiple PRDs available, use heuristics (most recent, largest)
- **No Context**: Present available options to user
**If context detection fails, ask the user:**
```markdown
## Which PRD would you like to start implementing?
Please provide the PRD number (e.g., "12", "PRD 12", or "36").
**Not sure which PRD to work on?**
Execute `dot-ai:prds-get` prompt to see all available PRDs organized by priority and readiness.
**Your choice**: [Wait for user input]
```
**Once PRD is identified:**
- Read the PRD file from `prds/[issue-id]-[feature-name].md`
## Step 2: PRD Readiness Validation
Before starting implementation, validate that the PRD is ready:
### Requirements Validation
- **Functional Requirements**: Are core requirements clearly defined and complete?
- **Success Criteria**: Are measurable success criteria established?
- **Dependencies**: Are all external dependencies identified and available?
- **Risk Assessment**: Have major risks been identified and mitigation plans created?
### Documentation Analysis
For documentation-first PRDs:
- **Specification completeness**: Is the feature fully documented with user workflows?
- **Integration points**: Are connections with existing features documented?
- **API/Interface definitions**: Are all interfaces and data structures specified?
- **Examples and usage**: Are concrete usage examples provided?
### Implementation Readiness Checklist
```markdown
## PRD Readiness Check
- [ ] All functional requirements defined
- [ ] Success criteria measurable
- [ ] Dependencies available
- [ ] Documentation complete
- [ ] Integration points clear
- [ ] Implementation approach decided
```
**If PRD is not ready:** Inform the user what's missing and suggest they complete PRD planning first.
## Step 3: Implementation Context Setup
**⚠️ MANDATORY: Complete this step BEFORE proceeding to Step 4**
### Git Branch Management
1. **Check current branch**: Run `git branch --show-current`
2. **If on `main` or `master`**: Create and switch to feature branch:
```bash
git checkout -b feature/prd-[issue-id]-[feature-name]
```
3. **If already on a feature branch**: Verify it's the correct branch for this PRD
### Development Environment Setup
- **Dependencies**: Install any new dependencies required by the PRD
- **Configuration**: Set up any configuration needed for development
- **Test data**: Prepare test data or mock services
### Step 3 Checkpoint (REQUIRED)
**You MUST display this confirmation before proceeding to Step 4:**
```markdown
## Environment Setup ✅
- **Branch**: `[current-branch-name]`
- **Status**: [Created new branch / Already on correct branch / Staying on main (reason)]
```
**DO NOT proceed to Step 4 until branch setup is confirmed.**
## Step 4: Hand Off to prd-next
Once the implementation context is set up, present this message to the user:
```markdown
## Ready for Implementation 🚀
**PRD**: [PRD Name] (#[PRD Number])
**Branch**: `[branch-name]`
**Status**: Ready for development
---
To identify and start working on your first task, run `/prd-next`.
```
**⚠️ STOP HERE - DO NOT:**
- Identify or recommend tasks to work on
- Analyze implementation priorities or critical paths
- Start any implementation work
- Continue beyond presenting the handoff message
`/prd-next` handles all task identification and implementation guidance.
## Success Criteria
This command should:
- ✅ Successfully identify the target PRD for implementation
- ✅ Validate that the PRD is ready for development work
- ✅ Set up proper implementation context (branch, environment)
- ✅ Hand off to `/prd-next` for task identification
- ✅ Bridge the gap between PRD planning and development setup
## Notes
- This command focuses on **setup only** - it validates readiness, creates the branch, and prepares the environment
- Once setup is complete, `/prd-next` handles all task identification, implementation guidance, and progress tracking

View File

@ -0,0 +1,99 @@
---
name: dot-ai-prd-update-decisions
description: Update PRD based on design decisions and strategic changes made during conversations
user-invocable: true
---
# PRD Update Decisions Slash Command
## Instructions
You are updating a PRD based on design decisions, strategic changes, and architectural choices made during conversations. This command captures conceptual changes that may not yet be reflected in code but affect requirements, approach, or scope.
## Process Overview
1. **Identify Target PRD** - Determine which PRD to update
2. **Analyze Conversation Context** - Review discussions for design decisions and strategic changes
3. **Identify Decision Points** - Find architecture, workflow, requirement, or scope changes
4. **Map to PRD Sections** - Determine which parts of the PRD need updates
5. **Propose Updates** - Suggest changes to requirements, approaches, and constraints
6. **Update Decision Log** - Record new decisions with rationale and impact
## Step 1: PRD Analysis
Ask the user which PRD to update, then:
- Read the PRD file from `prds/[issue-id]-[feature-name].md`
- Understand current requirements, approach, and constraints
- Identify areas most likely to be affected by design decisions
## Step 2: Conversation Analysis
Review the conversation context for decision-making patterns:
### Design Decision Indicators
Look for conversation elements that suggest strategic changes:
- **Workflow changes**: "Let's simplify this to..." "What if we instead..."
- **Architecture decisions**: "I think we should use..." "The better approach would be..."
- **Requirement modifications**: "Actually, we don't need..." "We should also include..."
- **Scope adjustments**: "Let's defer this..." "This is more complex than we thought..."
- **User experience pivots**: "Users would prefer..." "This workflow makes more sense..."
### Specific Decision Types
- **Technical Architecture**: Framework choices, design patterns, data structures
- **User Experience**: Workflow changes, interface decisions, interaction models
- **Requirements**: New requirements, modified requirements, removed requirements
- **Scope Management**: Features added, deferred, or eliminated
- **Implementation Strategy**: Phasing changes, priority adjustments, approach modifications
## Step 3: Decision Impact Assessment
For each identified decision, assess:
### Impact Categories
- **Requirements Impact**: What requirements need to be added, modified, or removed?
- **Scope Impact**: Does this expand or contract the project scope?
- **Timeline Impact**: Does this affect project phases or delivery dates?
- **Architecture Impact**: Does this change technical constraints or approaches?
- **Code Example Impact**: Which examples, interfaces, or snippets become outdated?
- **Risk Impact**: Does this introduce new risks or mitigate existing ones?
### Decision Documentation Format
For each decision, record:
- **Decision**: What was decided
- **Date**: When the decision was made
- **Rationale**: Why this approach was chosen
- **Impact**: How this affects the PRD requirements, scope, or approach
- **Code Impact**: Which code examples, interfaces, or snippets need updating
- **Owner**: Who made or approved the decision
## Step 4: PRD Updates
Update the appropriate PRD sections:
### Decision Log Updates
- Add new resolved decisions with date and rationale
- Mark open questions as resolved if decisions were made
- Update decision impact on requirements and scope
### Requirements Updates
- Modify functional requirements based on design changes
- Update non-functional requirements if performance/quality criteria changed
- Adjust success criteria if measurements or targets changed
### Implementation Approach Updates
- Update phases if sequencing or priorities changed
- Modify architecture decisions if technical approach evolved
- Adjust scope management if features were added, deferred, or removed
### Code Example Validation and Updates
- **Identify Outdated Examples**: Scan PRD for code snippets that may be affected by design decisions
- **Interface Changes**: Update examples when function signatures, parameter types, or return values change
- **API Modifications**: Revise examples when method names, class structures, or data formats evolve
- **Workflow Updates**: Update process examples when user interaction patterns or step sequences change
- **Mark for Verification**: Flag code examples that need manual testing to ensure they still work
### Risk and Dependency Updates
- Add new risks introduced by design decisions
- Update mitigation strategies if approach changed
- Modify dependencies if architectural changes affect integrations

View File

@ -0,0 +1,320 @@
---
name: dot-ai-prd-update-progress
description: Update PRD progress based on git commits and code changes, enhanced by conversation context
user-invocable: true
---
# PRD Update Progress Slash Command
## Instructions
You are helping update an existing Product Requirements Document (PRD) based on implementation work completed. This command analyzes git commits and code changes, enhanced by conversation context, to track PRD completion progress and propose evidence-based updates.
## Process Overview
1. **Identify Target PRD** - Determine which PRD to update
2. **Context-First Progress Analysis** - Use conversation context first, Git analysis as fallback
3. **Map Changes to PRD Items** - Intelligently connect work to requirements
4. **Propose Updates** - Suggest checkbox completions and requirement changes
5. **User Confirmation** - Verify proposals and handle edge cases
6. **Update PRD** - Apply changes to checkboxes and status
7. **Flag Divergences** - Alert when actual work differs from planned work
8. **Commit Progress Updates** - Preserve progress checkpoint
9. **Continue to Next Task** - Prompt user to run /prd-next
## Step 1: Smart PRD Identification
**Automatically detect target PRD using conversation context:**
1. **Current Work Context**: Look for recent conversation about specific PRD work, features, or issues
2. **Git Branch Analysis**: Check current git branch for PRD indicators (feature/prd-*, issue numbers)
3. **Recent File Activity**: Identify recently modified PRD files in `prds/` directory
4. **Todo List Context**: Check if TodoWrite tool shows PRD-specific tasks in progress
**Detection Priority Order:**
- If conversation explicitly mentions "PRD #X" or specific PRD file → Use that PRD
- If git branch contains PRD reference (e.g., "feature/prd-12-*") → Use PRD #12
- If TodoWrite shows PRD-specific tasks → Use that PRD context
- If only one PRD file recently modified → Use that PRD
- If multiple PRDs possible → Ask user to clarify
## Step 2: Context-First Progress Analysis
**PRIORITY: Use conversation context first before Git analysis**
### Conversation Context Analysis (FAST - Use First)
**If recent conversation shows clear work completion:**
- **Recently discussed implementations**: "Just completed X", "Implemented Y", "Built Z"
- **Todo list context**: Check TodoWrite tool for completed/in-progress items
- **File creation mentions**: "Created file X", "Added Y functionality"
- **Test completion references**: "Tests passing", "All X tests complete"
- **User confirmations**: "That works", "Implementation complete", "Ready for next step"
**Use conversation context when available - it's faster and more accurate than Git parsing**
### Git Change Analysis (FALLBACK - Use Only If Context Unclear)
**Only use git tools when conversation context is insufficient:**
### Commit Analysis
```bash
# Get recent commits (last 10-20 commits)
git log --oneline -n 20
# Get detailed changes since last PRD update
git log --since="1 week ago" --pretty=format:"%h %an %ad %s" --date=short
```
### File Change Analysis
```bash
# See what files were modified recently
git diff --name-status HEAD~10..HEAD
# Get specific changes in key directories
git diff --stat HEAD~10..HEAD
```
### Change Categorization
Identify different types of changes:
- **New files**: Indicates new functionality or components
- **Modified files**: Shows updates to existing functionality
- **Test files**: Evidence of testing implementation
- **Documentation files**: Shows documentation updates
- **Configuration files**: Indicates setup or deployment changes
## Step 3: Comprehensive PRD Structure Analysis
### **CRITICAL**: Systematic Checkbox Scanning
**MUST perform this step to avoid missing requirements:**
1. **Scan ALL unchecked items** in the PRD using grep or search
2. **Categorize each unchecked requirement** by type:
- **Implementation** (code, features, technical tasks)
- **Documentation** (guides, examples, cross-references)
- **Validation** (testing examples work, user journeys)
- **User Acceptance** (real-world usage, cross-client testing)
- **Launch Activities** (training, deployment, rollout)
- **Success Metrics** (adoption, analytics, support impact)
3. **Map git changes to appropriate categories only**
4. **Be conservative** - only mark items complete with direct evidence
### Evidence-Based Completion Criteria
**Implementation Requirements** - Mark complete when:
- **Code files**: Show functionality is implemented
- **Test files**: Demonstrate comprehensive testing
- **Integration**: Components properly connected
**Documentation Requirements** - Mark complete when:
- **Files created**: Documentation files exist
- **Examples validated**: Commands/examples have been tested
- **Cross-references work**: Internal links verified
**Validation Requirements** - Mark complete when:
- **Manual testing done**: Workflows tested end-to-end
- **Examples verified**: All documented examples work
- **User journeys confirmed**: Complete workflows validated
**Launch Activities** - Mark complete when:
- **Training delivered**: Team has been trained
- **Deployment done**: Feature is live and accessible
- **Rollout complete**: Users are actively using the feature
### Conservative Completion Policy
**DO NOT mark complete unless there is direct evidence:**
- ❌ Don't assume documentation is "good enough" without validation
- ❌ Don't mark testing complete without evidence of actual testing
- ❌ Don't mark launch items complete without proof of rollout
- ❌ Don't mark success criteria complete without metrics
### Gap Analysis
Systematically identify:
- **Requirements without evidence** (what still needs work)
- **Evidence without requirements** (work done outside scope)
- **Missing validation** (implemented but not tested)
- **Missing rollout** (ready but not deployed/adopted)
## Step 4: Comprehensive Progress Report
### **REQUIRED**: Complete Status Analysis
Present a comprehensive breakdown:
```markdown
## PRD Progress Analysis: [PRD Name]
### ✅ COMPLETED (with evidence):
**Implementation** (X/Y items):
- [x] Item name - Evidence: specific files/changes
- [x] Item name - Evidence: specific files/changes
**Documentation** (X/Y items):
- [x] Item name - Evidence: docs created, examples tested
- [x] Item name - Evidence: cross-references verified
### ⏳ REMAINING WORK:
**Validation** (X items unchecked):
- [ ] Item name - Reason: needs manual testing/validation
- [ ] Item name - Reason: examples not tested
**User Acceptance** (X items unchecked):
- [ ] Item name - Reason: no cross-client testing done
- [ ] Item name - Reason: no user feedback collected
**Launch Activities** (X items unchecked):
- [ ] Item name - Reason: team not trained
- [ ] Item name - Reason: not deployed to production
**Success Metrics** (X items unchecked):
- [ ] Item name - Reason: no usage data available
- [ ] Item name - Reason: adoption not measured
### 🎯 COMPLETION STATUS:
- **Overall Progress**: X% complete (Y of Z total items)
- **Implementation Phase**: 100% complete ✅
- **Validation Phase**: X% complete (what's missing)
- **Launch Phase**: X% complete (what's missing)
```
### Conservative Recommendation Policy
**ONLY suggest marking items complete when you have direct evidence.**
**CLEARLY list what still needs to be done.**
**DO NOT claim "everything is done" unless ALL items are truly complete.**
## Step 5: Implementation vs Plan Analysis
### Divergence Detection
Flag when actual implementation differs from planned approach:
- **Architecture changes**: Different technical approach than originally planned
- **Scope changes**: Features added or removed during implementation
- **Requirement evolution**: User needs that became clearer during development
- **Technical discoveries**: Constraints or opportunities discovered during coding
### Update Recommendations
Suggest PRD updates when divergences are found:
- **Decision log updates**: Record why implementation approach changed
- **Requirement modifications**: Update requirements to match actual functionality
- **Architecture updates**: Revise technical approach documentation
- **Scope adjustments**: Move items between phases or update feature definitions
## Step 6: User Confirmation Process
Present proposed changes clearly with complete transparency:
1. **Evidence summary**: Show what work was detected
2. **Proposed completions**: List specific checkbox items to mark done with evidence
3. **Remaining work analysis**: Clearly show what's still unchecked and why
4. **Divergence alerts**: Highlight any plan vs reality differences
5. **Honest progress assessment**: Give realistic completion percentage
**Critical Requirements:**
- **Never claim "everything is done"** unless literally ALL checkboxes are complete
- **Be explicit about limitations** of git-based analysis
- **Acknowledge validation gaps** when you can't verify functionality works
- **Separate implementation from validation/rollout**
Wait for user confirmation before making changes, and handle:
- **Partial acceptance**: User agrees with some but not all suggestions
- **Additional context**: User provides information not visible in git history
- **Scope clarification**: User explains work that appears to be out of scope
- **Future planning**: User wants to adjust upcoming work based on current progress
## Step 7: Systematic Update Application
When applying updates:
1. **Update only confirmed items** - Don't make assumptions
2. **Update status sections** to reflect current phase
3. **Preserve unchecked items** that still need work
4. **Update completion percentages** realistically
## Step 7.5: Code Example Validation
When updating PRDs based on implementation progress:
**CRITICAL**: Always check if code examples in PRD match current implementation
### Example Impact Detection
1. **Interface Changes**: Function signatures, parameter types, return formats
2. **API Evolution**: Method names, class structures, data models
3. **Workflow Updates**: User interaction patterns, step sequences
4. **Integration Changes**: How components connect and communicate
### Code Example Update Process
1. **Scan PRD**: Identify all code snippets and examples
2. **Cross-reference Implementation**: Compare examples with actual code
3. **Mark Outdated**: Flag examples that no longer match
4. **Priority Assessment**: Determine which examples need immediate updates
5. **Update Examples**: Revise code snippets to match current implementation
6. **Validate Examples**: Test updated examples to ensure they work
### Example Categories to Check
- **Function calls**: Parameter order, types, names
- **Interface definitions**: TypeScript interfaces, class structures
- **API responses**: Data formats, field names, response structures
- **Workflow steps**: User interaction sequences, tool usage patterns
- **Configuration**: Setup examples, environment variables, config files
### When to Update Examples
- **Immediately**: When interface changes break existing examples
- **Before completion**: When marking implementation milestones complete
- **During reviews**: When validating PRD accuracy
- **User feedback**: When someone reports examples don't work
## Step 8: Commit Progress Updates
After successfully updating the PRD, commit all changes to preserve the progress checkpoint:
### Commit Implementation Work
```bash
# MANDATORY: Stage ALL files - implementation work AND PRD updates together
# DO NOT selectively add only PRD files - commit everything as one atomic unit
git add .
# Verify what will be committed
git status
# Create comprehensive commit with PRD reference
git commit -m "feat(prd-X): implement [brief description of completed work]
- [Brief list of key implementation achievements]
- Updated PRD checkboxes for completed items
Progress: X% complete - [next major milestone]"
```
### Commit Message Guidelines
- **Reference PRD number**: Always include `prd-X` in commit message
- **Descriptive summary**: Brief but clear description of what was implemented
- **Progress indication**: Include completion status and next steps
- **Evidence-based**: Only commit when there's actual implementation progress
**Note**: Do NOT push commits unless explicitly requested by the user. Commits preserve local progress checkpoints without affecting remote branches.
## Step 9: Next Steps Based on PRD Status
After completing the PRD update and committing changes, guide the user based on completion status:
### If PRD has remaining tasks
---
**PRD progress updated and committed.**
To continue working on this PRD:
1. Clear/reset the conversation context
2. Run `/prd-next` to get the next task
---
### If PRD is 100% complete
---
**PRD #X is complete!**
To finalize:
1. Clear/reset the conversation context
2. Run `/prd-done` to move the PRD to the done folder and close the GitHub issue
---

View File

@ -0,0 +1,49 @@
---
name: dot-ai-prds-get
description: "Fetch all open GitHub issues from this project that have the 'PRD' label"
user-invocable: true
---
# Get All PRDs
Fetch all open GitHub issues from this project that have the 'PRD' label.
**Note**: If any `gh` command fails with "command not found", inform the user that GitHub CLI is required and provide the installation link: https://cli.github.com/
## Process
1. **Fetch Issues**: Use GitHub CLI to get all open issues with PRD label
```bash
gh issue list --label PRD --state open --json number,title,url,labels,assignees,createdAt,updatedAt
```
2. **Format Results**: Present the issues in a clear, organized format showing:
- Issue number and title
- Creation and last update dates
- Current assignees (if any)
- Direct link to the issue
- PRD file link (if available in issue description)
3. **Meaningful Categorization**: Group PRDs by their actual purpose and impact, not generic labels:
- **Architecture & Infrastructure**: Core system changes, API designs, major refactors
- **User Experience**: Features that directly impact how users interact with the system
- **Developer Experience**: Tools, workflows, testing, documentation that help developers
- **AI & Intelligence**: Machine learning, AI-powered features, recommendation engines
- **Operations & Monitoring**: Deployment, scaling, observability, performance
- **Integration & Extensibility**: Third-party integrations, plugin systems, APIs
Each category should briefly explain what the PRDs in that group will accomplish for users or the system.
4. **Priority Analysis**: If multiple PRDs exist, help identify:
- Which PRDs are most recently updated or have active discussion
- Which PRDs have dependencies on other PRDs
- Which PRDs are foundational vs. incremental improvements
- Which PRDs might be blocked or need clarification
5. **Next Steps Suggestion**: Based on the PRD list, suggest logical next actions:
- Which PRD to work on next based on dependencies and impact
- PRDs that need attention, updates, or clarification
- Opportunities for parallel work on independent PRDs
This provides a complete view of all active product requirements and helps with project planning and prioritization.

View File

@ -0,0 +1,55 @@
---
name: dot-ai-process-feature-request
description: Process a feature request or response from another dot-ai project. Reads from tmp directory, implements/integrates, and writes response if needed.
user-invocable: true
---
# Process Feature Request/Response
Read and process a feature request or response from another dot-ai project.
## Process
1. Check for `tmp/feature-request.md` (incoming request from another project)
2. If not found, check for `tmp/feature-response.md` (response to a request we made)
3. If neither exists, tell the user there's nothing pending
### For Incoming Request (feature-request.md)
1. Present the request to the user and confirm they want to proceed
2. Implement the requested feature
3. Write a response file to the requesting project (path specified in the request)
4. **Delete the feature-request.md file** after implementation is complete
### For Response (feature-response.md)
1. Read and present the response
2. Use the information to continue integrating the feature
3. **Delete the feature-response.md file** after integration is complete
## Response File Format (for incoming requests only)
```markdown
# Feature Response from [THIS_PROJECT]
## What Was Implemented
[Brief description of what was built]
## How to Use It
[API signatures, endpoints, types, parameters]
## Examples
[Code examples showing how to call/use the feature]
## Notes
[Any caveats, limitations, or additional context]
```
## Guidelines
1. Read and understand the full request/response before proceeding
2. For requests: use your judgment on the best approach
3. Write clear documentation in responses so the requesting project can integrate easily

View File

@ -0,0 +1,15 @@
---
name: dot-ai-projectSetup
description: "Setup project, audit repository, or generate repository files. Use this when user wants to: setup project, audit repo, check missing files, create README, add LICENSE, generate CONTRIBUTING.md, add CI/CD workflows, initialize documentation, setup governance files. Analyzes local repositories and generates missing configuration, documentation, and governance files. Does NOT handle Kubernetes deployments - use recommend for those."
user-invocable: true
---
# dot-ai projectSetup
Setup project, audit repository, or generate repository files. Use this when user wants to: setup project, audit repo, check missing files, create README, add LICENSE, generate CONTRIBUTING.md, add CI/CD workflows, initialize documentation, setup governance files. Analyzes local repositories and generates missing configuration, documentation, and governance files. Does NOT handle Kubernetes deployments - use recommend for those.
## Usage
```bash
dot-ai projectSetup
```

View File

@ -0,0 +1,42 @@
---
name: dot-ai-query-dot-ai
description: "Query sibling dot-ai projects to verify features are USABLE (not just defined). IMPORTANT: When calling this skill, explain HOW you plan to use the feature (e.g., 'I need to call X via REST API from the UI' or 'I need to import Y function'). This helps verify the full chain from definition to exposure."
user-invocable: true
---
# Query dot-ai Projects
Explore the dot-ai ecosystem codebases to find the requested information.
## Project Locations
Sibling projects are located in the parent directory of the current working directory (`../`):
- **dot-ai** - Main MCP server (API endpoints, tools, handlers)
- **dot-ai-ui** - Web UI for visualizations and dashboard
- **dot-ai-controller** - Kubernetes controller
- **dot-ai-stack** - Stack deployment configs
- **dot-ai-website** - Documentation website
Default to **dot-ai** (MCP server) if the target project is unclear.
**Important:** Do NOT use this skill to query the project you're currently working in. Use local tools (Read, Grep, Glob) instead.
## Excluded
**dot-ai-infra** - Production infrastructure. Only query if user explicitly requests it.
## Verification Mindset
**Don't just find that something EXISTS - prove it's USABLE.**
- Finding a type/interface is NOT enough
- Finding internal code is NOT enough
- You must trace from definition → implementation → exposure
When asked "does X exist?", answer:
- "Yes, and here's how to use it: [concrete usage]" OR
- "It exists internally but is NOT exposed for external use"
**Go deep, not wide.** Follow the code path until you can prove how the caller would actually use the feature.

View File

@ -0,0 +1,15 @@
---
name: dot-ai-query
description: "Natural language query interface for Kubernetes cluster intelligence. Ask any questions about your cluster resources, capabilities, and status in plain English. Examples: \"What databases are running?\", \"Describe the nginx deployment\", \"Show me pods in the kube-system namespace\", \"What operators are installed?\", \"Is my-postgres healthy?\""
user-invocable: true
---
# dot-ai query
Natural language query interface for Kubernetes cluster intelligence. Ask any questions about your cluster resources, capabilities, and status in plain English. Examples: "What databases are running?", "Describe the nginx deployment", "Show me pods in the kube-system namespace", "What operators are installed?", "Is my-postgres healthy?"
## Usage
```bash
dot-ai query
```

View File

@ -0,0 +1,15 @@
---
name: dot-ai-recommend
description: Deploy applications, infrastructure, and services using Kubernetes resources with AI recommendations. Supports cloud resources via operators like Crossplane, cluster management via CAPI, and traditional Kubernetes workloads. Describe what you want to deploy. Does NOT handle policy creation, organizational patterns, or resource capabilities - use manageOrgData for those.
user-invocable: true
---
# dot-ai recommend
Deploy applications, infrastructure, and services using Kubernetes resources with AI recommendations. Supports cloud resources via operators like Crossplane, cluster management via CAPI, and traditional Kubernetes workloads. Describe what you want to deploy. Does NOT handle policy creation, organizational patterns, or resource capabilities - use manageOrgData for those.
## Usage
```bash
dot-ai recommend
```

View File

@ -0,0 +1,15 @@
---
name: dot-ai-remediate
description: "AI-powered Kubernetes issue analysis that provides root cause identification and actionable remediation steps. Unlike basic kubectl commands, this tool performs multi-step investigation, correlates cluster data, and generates intelligent solutions. Use when users want to understand WHY something is broken, not just see raw status. Ideal for: troubleshooting failures, diagnosing performance issues, analyzing pod problems, investigating networking/storage issues, or any \"what's wrong\" questions."
user-invocable: true
---
# dot-ai remediate
AI-powered Kubernetes issue analysis that provides root cause identification and actionable remediation steps. Unlike basic kubectl commands, this tool performs multi-step investigation, correlates cluster data, and generates intelligent solutions. Use when users want to understand WHY something is broken, not just see raw status. Ideal for: troubleshooting failures, diagnosing performance issues, analyzing pod problems, investigating networking/storage issues, or any "what's wrong" questions.
## Usage
```bash
dot-ai remediate
```

View File

@ -0,0 +1,73 @@
---
name: dot-ai-request-dot-ai-feature
description: Generate a feature request prompt for another dot-ai project. Use when you need a feature implemented in a sibling project (MCP server, controller, etc.) to unblock work in the current project.
user-invocable: true
---
# Request Feature in dot-ai Project
Write a feature request to a file in the target dot-ai project's tmp directory. The user will review and approve the write operation.
## Projects
| Project | Directory | Description |
|---------|-----------|-------------|
| dot-ai | `../dot-ai` | Main MCP server (API endpoints, tools, handlers) |
| dot-ai-ui | `../dot-ai-ui` | Web UI for visualizations and dashboard |
| dot-ai-controller | `../dot-ai-controller` | Kubernetes controller |
| dot-ai-stack | `../dot-ai-stack` | Stack deployment configs |
| dot-ai-website | `../dot-ai-website` | Documentation website |
**Important:** Do NOT use this skill to request features in the project you're currently working in. Just implement them directly.
## Process
1. Determine the target project from the user's request
2. Determine the current project name from the directory name: `basename $(git rev-parse --show-toplevel)`
3. **Delete any existing feature-request.md** in the target project's tmp directory (so the diff only shows new content)
4. Write the feature request to: `../[target-project]/tmp/feature-request.md`
5. Tell the user to open the target project and run `/process-feature-request`
## File Format
Write the feature request file with this content (replace `[CURRENT_PROJECT]` with the actual project name from step 2):
```markdown
# Feature Request from [CURRENT_PROJECT]
**Requesting project directory:** ../[CURRENT_PROJECT]
## What We Need
[DESCRIPTION OF WHAT WE NEED AND WHY]
## Our Suggestion
(You decide the best approach)
- [Suggested approach or implementation idea]
## Context
[What this unblocks in our project]
## Notes
You're the expert on this codebase. Feel free to implement this differently if there's a better approach, or push back if this doesn't make sense.
## Response Instructions
After implementing this feature, write a response file to help the requesting project integrate:
1. Write to: `../[CURRENT_PROJECT]/tmp/feature-response.md`
2. Include: what was implemented, how to use it (API signatures, endpoints, types), and any usage examples
```
## Guidelines
1. Describe what you need and why, not how to implement it
2. Suggestions are just suggestions - the receiving agent decides the approach
3. The receiving agent is the authority on their codebase
4. Keep the request focused on the problem, not the solution
5. The user will review the write operation before it's accepted

View File

@ -0,0 +1,98 @@
---
name: dot-ai-tag-release
description: Create a release tag based on accumulated changelog fragments. Run when ready to cut a release.
user-invocable: true
---
# Create Release Tag
Create a semantic version tag based on accumulated changelog fragments. This aggregates all pending fragments to determine the appropriate version bump and creates an annotated tag.
## When to Use
Run this skill when:
- Multiple PRs have been merged with changelog fragments
- You're ready to cut a release
- After the /prd-done workflow completes (not during it)
## Workflow
### Step 1: Check for Pending Fragments
List all files in `changelog.d/` directory:
```bash
ls -la changelog.d/
```
If no fragments exist (only `.gitkeep` or empty), inform the user there's nothing to release.
### Step 2: Get Current Version
Find the latest tag:
```bash
git tag --sort=-v:refname | head -1
```
If no tags exist, start from `v0.0.0`.
### Step 3: Analyze Fragments for Version Bump
Examine all fragment files to determine the highest-impact change type:
**Priority order**: `breaking` > `feature` > `bugfix` > `doc` = `misc`
The highest-priority fragment type determines the version bump:
- Any `.breaking.md` exists → bump **major** (e.g., v1.2.3 → v2.0.0)
- Any `.feature.md` exists → bump **minor** (e.g., v1.2.3 → v1.3.0)
- Only `.bugfix.md`, `.doc.md`, or `.misc.md` → bump **patch** (e.g., v1.2.3 → v1.2.4)
### Step 4: Propose Version
Show the user:
1. Current version
2. Fragments found (list them with their types)
3. Proposed next version based on the analysis
4. Ask for confirmation or allow override
### Step 5: Check for [skip ci] in HEAD
**IMPORTANT**: Tags pointing to commits with `[skip ci]` in the message will NOT trigger the release workflow.
Check the HEAD commit message:
```bash
git log -1 --format="%s" HEAD
```
If the message contains `[skip ci]`, `[ci skip]`, or `[no ci]`:
1. Inform the user that tagging this commit would prevent the release workflow from running
2. Create a release preparation commit:
```bash
git commit --allow-empty -m "chore: prepare release [version]"
git push origin HEAD
```
This empty commit gives us a clean commit to tag that will trigger CI.
### Step 6: Create and Push Tag
If confirmed (and after Step 5 if needed):
```bash
git tag -a [version] -m "[Brief description summarizing the fragments]"
git push origin [version]
```
### Step 7: Confirm Success
Show the user:
1. The tag created
2. The tag URL on GitHub (if applicable)
3. Note that CI/CD will generate release notes from the fragments
## Guidelines
- **Don't run during PR workflow**: This is a separate release activity
- **Review fragments first**: Make sure all fragments are accurate before tagging
- **Use semantic versioning**: Follow semver strictly based on fragment types
- **Brief tag message**: Summarize the release in 1-2 sentences
- **Never tag [skip ci] commits**: Tags on commits with `[skip ci]` won't trigger CI - always create a preparation commit first

View File

@ -0,0 +1,15 @@
---
name: dot-ai-version
description: Get comprehensive system health and diagnostics
user-invocable: true
---
# dot-ai version
Get comprehensive system health and diagnostics
## Usage
```bash
dot-ai version
```

View File

@ -0,0 +1,84 @@
---
name: dot-ai-worktree-prd
description: Create a git worktree for PRD work with a descriptive branch name. Infers PRD from context or asks user.
user-invocable: true
---
# Create Git Worktree for PRD
Create a git worktree with a descriptive branch name based on the PRD title. This ensures feature branches have human-readable names that describe what the work is about.
## Workflow
### Step 1: Identify the PRD
Try to infer the PRD number from the current conversation. Look for PRD references like "PRD 353", "PRD #353", or "prd-353".
If not found in context, ask the user: "Which PRD should I create a worktree for? (e.g., 353)"
### Step 2: Get the PRD Title
If the PRD content is already in the conversation context, extract the title from there.
Otherwise, read the PRD file. PRD files are in the `prds/` directory with naming pattern `[number]-[slug].md`:
```bash
ls prds/ | grep "^[PRD_NUMBER]-"
```
The title is on the first line in format: `# PRD #[number]: [Title]`
### Step 3: Generate Descriptive Branch Name
Convert the PRD title to a branch-friendly name:
1. Start with `prd-[number]-`
2. Extract the title after the colon (e.g., "Update to Kimi K2.5 Model Support")
3. Convert to lowercase
4. Replace spaces with hyphens
5. Remove special characters except hyphens and dots
6. Keep it concise (truncate if very long)
**Examples:**
- "PRD #353: Update to Kimi K2.5 Model Support" → `prd-353-kimi-k2.5-support`
- "PRD #290: Skills Distribution System" → `prd-290-skills-distribution`
- "PRD #264: GitOps Tool ArgoCD Integration" → `prd-264-gitops-argocd-integration`
### Step 4: Create the Worktree
Run the following commands directly. Replace `[branch-name]` with the name generated in Step 3.
1. **Get the repo name and compute the worktree path:**
```bash
repo_name=$(basename "$(git rev-parse --show-toplevel)")
worktree_path="../${repo_name}-[branch-name]"
```
2. **Validate** — check that the branch, worktree path, and worktree registration don't already exist:
```bash
git show-ref --verify --quiet "refs/heads/[branch-name]" && echo "ERROR: Branch already exists"
test -d "${worktree_path}" && echo "ERROR: Worktree path already exists"
git worktree list | grep -q "[branch-name]" && echo "ERROR: Worktree already registered"
```
If any check fails, inform the user and ask how to proceed.
3. **Create the worktree** branching from `main`:
```bash
git worktree add "${worktree_path}" -b [branch-name] main
```
4. **Initialize submodules** in the new worktree:
```bash
cd "${worktree_path}" && git submodule update --init --recursive
```
5. **Report** the result to the user:
- Worktree path: `${worktree_path}`
- Branch: `[branch-name]`
- Next step: `cd ${worktree_path}`
## Guidelines
- **Descriptive names**: Branch names should describe the feature, not just the PRD number
- **Consistent format**: Always prefix worktree directory with the repository name
- **Base on main**: Always branch from `main` for new feature work
- **Clean names**: Keep branch names concise but descriptive

View File

@ -0,0 +1,9 @@
---
name: dot-ai
description: "Kubernetes cluster operations via dot-ai CLI - natural language cluster queries, AI-powered deployment recommendations, issue troubleshooting and remediation, Day 2 operations (scale, update, rollback, delete), resources, namespaces, events, logs, organizational knowledge base (ingest, search, query), organizational patterns/policies/capabilities management, project scaffolding and repo audit, and session history and visualization. Run `dot-ai --help` for commands."
---
This project uses the dot-ai CLI for Kubernetes and DevOps operations.
Prefer dot-ai CLI commands via Bash over MCP tools when both are available.
Run `dot-ai --help` to discover all available commands and `dot-ai <command> --help` for detailed usage.

View File

@ -0,0 +1,95 @@
name: Release Helm Chart
on:
push:
branches:
- main
permissions:
contents: write
packages: write
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
submodules: true
- name: Set up Helm
uses: azure/setup-helm@v4
with:
version: v3.14.0
- name: Bump chart version
id: bump
run: |
# Read current version
CURRENT_VERSION=$(grep '^version:' Chart.yaml | awk '{print $2}')
echo "Current version: $CURRENT_VERSION"
# Parse version components
MAJOR=$(echo $CURRENT_VERSION | cut -d. -f1)
MINOR=$(echo $CURRENT_VERSION | cut -d. -f2)
PATCH=$(echo $CURRENT_VERSION | cut -d. -f3)
# Increment minor, reset patch
NEW_MINOR=$((MINOR + 1))
NEW_VERSION="${MAJOR}.${NEW_MINOR}.0"
echo "New version: $NEW_VERSION"
# Update Chart.yaml
sed -i "s/^version: .*/version: $NEW_VERSION/" Chart.yaml
sed -i "s/^appVersion: .*/appVersion: \"$NEW_VERSION\"/" Chart.yaml
echo "version=$NEW_VERSION" >> $GITHUB_OUTPUT
- name: Commit version bump
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add Chart.yaml
git commit -m "chore: bump chart version to ${{ steps.bump.outputs.version }} [skip ci]"
git push
- name: Login to GHCR
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Update dependencies
run: helm dependency update
- name: Package chart
run: helm package .
- name: Push to GHCR
run: |
helm push dot-ai-stack-*.tgz oci://ghcr.io/vfarcic/dot-ai-stack/charts
- name: Check if docs changed
id: docs-check
run: |
if git rev-parse HEAD~2 >/dev/null 2>&1; then
# Check the commit before the version bump (HEAD~1) against HEAD~2
DOCS_CHANGED=$(git diff --name-only HEAD~2 HEAD~1 -- README.md docs/ | wc -l)
else
DOCS_CHANGED=1 # First commit or second commit, trigger rebuild
fi
if [ "$DOCS_CHANGED" -gt 0 ]; then
echo "docs-changed=true" >> $GITHUB_OUTPUT
else
echo "docs-changed=false" >> $GITHUB_OUTPUT
fi
- name: Trigger Website Rebuild
if: steps.docs-check.outputs.docs-changed == 'true'
uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.WEBSITE_DISPATCH_TOKEN }}
repository: vfarcic/dot-ai-website
event-type: upstream-release
client-payload: '{"source": "dot-ai-stack"}'

View File

@ -0,0 +1,30 @@
# Patterns to ignore when building packages.
.DS_Store
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
*.swp
*.bak
*.tmp
*.orig
*~
.project
.idea/
*.tmproj
.vscode/
# Devbox
.devbox/
devbox.json
devbox.lock
# PRDs
prds/
# Environment files
.env*
kubeconfig.yaml

View File

@ -0,0 +1,11 @@
{
"mcpServers": {
"coderabbitai": {
"command": "npx",
"args": ["coderabbitai-mcp@latest"],
"env": {
"GITHUB_PAT": "${GITHUB_TOKEN}"
}
}
}
}

View File

@ -0,0 +1,12 @@
dependencies:
- name: dot-ai
repository: oci://ghcr.io/vfarcic/dot-ai/charts
version: 1.12.0
- name: dot-ai-controller
repository: oci://ghcr.io/vfarcic/dot-ai-controller/charts
version: 0.48.1
- name: dot-ai-ui
repository: oci://ghcr.io/vfarcic/dot-ai-ui/charts
version: 0.15.0
digest: sha256:2a839c436806060f27d64d9a49c7cb66193cebd8077f73d8a053e4e43300f772
generated: "2026-03-21T16:18:35.4252363Z"

View File

@ -0,0 +1,18 @@
apiVersion: v2
appVersion: 0.78.0
dependencies:
- name: dot-ai
repository: oci://ghcr.io/vfarcic/dot-ai/charts
version: 1.12.0
- condition: dot-ai-controller.enabled
name: dot-ai-controller
repository: oci://ghcr.io/vfarcic/dot-ai-controller/charts
version: 0.48.1
- condition: dot-ai-ui.enabled
name: dot-ai-ui
repository: oci://ghcr.io/vfarcic/dot-ai-ui/charts
version: 0.15.0
description: Complete dot-ai stack - MCP server, controller, and UI
name: dot-ai-stack
type: application
version: 0.78.0

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Viktor Farcic
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,41 @@
# dot-ai-stack
[![License](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
![Project Status](https://img.shields.io/badge/status-beta-orange)
**Deploy the complete DevOps AI Toolkit stack with a single Helm command.**
---
<div align="center">
## [Read the Documentation](https://devopstoolkit.ai/docs/stack/)
</div>
---
## Overview
dot-ai-stack is an umbrella Helm chart that aggregates all DevOps AI Toolkit components for simplified deployment. Instead of installing multiple charts separately, deploy everything with one command.
**What's included:**
- **DevOps AI Toolkit** - MCP server for AI-powered Kubernetes operations
- **DevOps AI Toolkit Controller** - Kubernetes controller for intelligent resource management and autonomous operations
- **DevOps AI Toolkit Web UI** - Web interface for visual cluster management
- **Qdrant** - Vector database for pattern and policy storage
- **ResourceSyncConfig** - Pre-configured resource discovery
- **CapabilityScanConfig** - Pre-configured capability scanning
[Read the Documentation](https://devopstoolkit.ai/docs/stack/)
## Documentation
- **[Setup Guide](https://devopstoolkit.ai/docs/stack/)** - Get up and running in minutes
- **[DevOps AI Toolkit Docs](https://devopstoolkit.ai/docs/mcp/)** - MCP server documentation
- **[Controller Docs](https://devopstoolkit.ai/docs/controller/)** - Controller documentation
- **[Web UI Docs](https://devopstoolkit.ai/docs/ui/)** - Web interface documentation
## License
MIT License - see [LICENSE](LICENSE) file for details.

View File

View File

@ -0,0 +1,19 @@
**Configurable Timing Parameters for Resource Sync and Capability Scan**
Control how frequently dot-ai synchronizes resources and scans cluster capabilities. Previously, these operations used fixed timing intervals, which could be too frequent for large clusters or too slow for rapidly changing environments.
ResourceSyncConfig now supports `debounceWindowSeconds` (default: 10s, max: 300s) to control how long to wait after a change before syncing, and `resyncIntervalMinutes` (default: 60m, max: 1440m) to set the interval between full resyncs. CapabilityScanConfig supports `debounceWindowSeconds` with the same defaults. Both parameters are optional—omit them to use the defaults.
Configure these values in your Helm values file:
```yaml
resourceSync:
enabled: true
debounceWindowSeconds: 30
resyncIntervalMinutes: 120
capabilityScan:
enabled: true
debounceWindowSeconds: 30
```
See the [Resource Sync Guide](https://devopstoolkit.ai/docs/controller/resource-sync-guide) and [Capability Scan Guide](https://devopstoolkit.ai/docs/controller/capability-scan-guide) for more details.

View File

@ -0,0 +1,5 @@
**Optional Component Disabling Now Works Correctly**
Setting `dot-ai-controller.enabled: false` or `dot-ai-ui.enabled: false` now properly prevents those components from being rendered. Previously, the Helm chart dependencies lacked `condition` fields, so these settings had no effect and all resources were always deployed.
This fix resolves drift detection issues in GitOps tools like Flux and ArgoCD, which would report removed resources when users attempted to disable components that were previously deployed. Both components default to `enabled: true`, so existing deployments are unaffected.

Binary file not shown.

View File

@ -0,0 +1,22 @@
annotations:
category: Infrastructure
apiVersion: v2
appVersion: v0.48.1
description: A Kubernetes controller that watches cluster events and forwards them
to the dot-ai MCP remediate tool for AI-powered analysis and remediation
home: https://github.com/vfarcic/dot-ai-controller
keywords:
- kubernetes
- controller
- events
- remediation
- mcp
- ai
maintainers:
- name: Viktor Farcic
url: https://github.com/vfarcic
name: dot-ai-controller
sources:
- https://github.com/vfarcic/dot-ai-controller
type: application
version: 0.48.1

View File

@ -0,0 +1,24 @@
🎉 dot-ai-controller has been installed!
📋 WHAT'S INSTALLED:
• RemediationPolicy CRD for configuring event watching
• Controller deployment ({{ include "dot-ai-controller.fullname" . }}-manager)
• RBAC permissions for event monitoring
🚀 NEXT STEPS:
1. Verify the controller is running:
kubectl get pods -l app.kubernetes.io/name={{ include "dot-ai-controller.name" . }} -n {{ .Release.Namespace }}
2. Check controller logs:
kubectl logs -l app.kubernetes.io/name={{ include "dot-ai-controller.name" . }} -n {{ .Release.Namespace }}
3. Create a RemediationPolicy to start watching events - see repository for configuration examples
4. Monitor RemediationPolicy status:
kubectl get remediationpolicies -o wide
📖 DOCUMENTATION:
Repository: https://github.com/vfarcic/dot-ai-controller
⚡ The controller will automatically start processing events that match your RemediationPolicy selectors!

View File

@ -0,0 +1,86 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "dot-ai-controller.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "dot-ai-controller.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "dot-ai-controller.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "dot-ai-controller.labels" -}}
helm.sh/chart: {{ include "dot-ai-controller.chart" . }}
{{ include "dot-ai-controller.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "dot-ai-controller.selectorLabels" -}}
app.kubernetes.io/name: {{ include "dot-ai-controller.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "dot-ai-controller.serviceAccountName" -}}
{{- printf "%s-manager" (include "dot-ai-controller.fullname" .) }}
{{- end }}
{{/*
Create the name of the cluster role to use
*/}}
{{- define "dot-ai-controller.clusterRoleName" -}}
{{- printf "%s-manager-role" (include "dot-ai-controller.fullname" .) }}
{{- end }}
{{/*
Create the name of the cluster role binding to use
*/}}
{{- define "dot-ai-controller.clusterRoleBindingName" -}}
{{- printf "%s-manager-rolebinding" (include "dot-ai-controller.fullname" .) }}
{{- end }}
{{/*
Merge global annotations with resource-specific annotations.
Resource-specific annotations take precedence over global annotations.
Usage: include "dot-ai-controller.annotations" (dict "global" .Values.annotations "local" .Values.ingress.annotations)
*/}}
{{- define "dot-ai-controller.annotations" -}}
{{- $global := .global | default dict -}}
{{- $local := .local | default dict -}}
{{- $merged := merge $local $global -}}
{{- if $merged -}}
{{- toYaml $merged -}}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,72 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "dot-ai-controller.fullname" . }}-manager
namespace: {{ .Release.Namespace }}
labels:
{{- include "dot-ai-controller.labels" . | nindent 4 }}
control-plane: controller-manager
{{- $annotations := include "dot-ai-controller.annotations" (dict "global" .Values.annotations "local" nil) -}}
{{- if $annotations }}
annotations:
{{- $annotations | nindent 4 }}
{{- end }}
spec:
replicas: 1
selector:
matchLabels:
{{- include "dot-ai-controller.selectorLabels" . | nindent 6 }}
control-plane: controller-manager
template:
metadata:
{{- $podAnnotations := include "dot-ai-controller.annotations" (dict "global" .Values.annotations "local" (dict "kubectl.kubernetes.io/default-container" "manager")) -}}
{{- if $podAnnotations }}
annotations:
{{- $podAnnotations | nindent 8 }}
{{- end }}
labels:
{{- include "dot-ai-controller.selectorLabels" . | nindent 8 }}
control-plane: controller-manager
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: manager
image: {{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
command:
- /manager
args:
- --leader-elect
- --health-probe-bind-address=:8081
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- "ALL"
livenessProbe:
httpGet:
path: /healthz
port: 8081
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /readyz
port: 8081
initialDelaySeconds: 5
periodSeconds: 10
resources:
{{- toYaml .Values.resources | nindent 10 }}
volumeMounts:
- name: tmp-dir
mountPath: /tmp
volumes:
- name: tmp-dir
emptyDir: {}
serviceAccountName: {{ include "dot-ai-controller.serviceAccountName" . }}
terminationGracePeriodSeconds: 1260

View File

@ -0,0 +1,224 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.18.0
name: capabilityscanconfigs.dot-ai.devopstoolkit.live
spec:
group: dot-ai.devopstoolkit.live
names:
kind: CapabilityScanConfig
listKind: CapabilityScanConfigList
plural: capabilityscanconfigs
singular: capabilityscanconfig
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Ready status
jsonPath: .status.conditions[?(@.type=='Ready')].status
name: Ready
type: string
- description: Initial scan completed
jsonPath: .status.initialScanComplete
name: Initial Scan
type: boolean
- description: Last scan time
jsonPath: .status.lastScanTime
name: Last Scan
type: date
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: |-
CapabilityScanConfig is the Schema for the capabilityscanconfigs API
It configures the controller to watch CRDs and trigger capability scans via MCP
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: spec defines the desired state of CapabilityScanConfig
properties:
debounceWindowSeconds:
default: 10
description: |-
DebounceWindowSeconds is the time window to collect CRD events before sending to MCP
When a CRD event is received, the controller waits for this duration to collect
more events, then sends them all in a single batched request.
This reduces HTTP requests when operators are installed (many CRDs at once).
maximum: 300
minimum: 1
type: integer
excludeResources:
description: |-
ExcludeResources specifies patterns for resources to exclude from scanning
Applied after includeResources filtering
Patterns support wildcards: "*.internal.example.com", "events.*"
items:
type: string
type: array
includeResources:
description: |-
IncludeResources specifies patterns for resources to include in scanning
Patterns support wildcards: "*.crossplane.io", "deployments.apps", "Service"
Format: "Kind.group" for grouped resources, "Kind" for core resources
If empty, all resources are included (subject to excludeResources)
items:
type: string
type: array
mcp:
description: MCP configuration for capability scanning
properties:
authSecretRef:
description: |-
AuthSecretRef references a Kubernetes Secret containing the MCP authentication token
The Secret must exist in the same namespace as the CapabilityScanConfig
properties:
key:
description: Key within the secret containing the value
type: string
name:
description: Name of the secret in the same namespace as the
resource
type: string
required:
- key
- name
type: object
collection:
default: capabilities
description: Collection is the Qdrant collection name for storing
capabilities
type: string
endpoint:
description: Endpoint is the MCP server URL
type: string
required:
- authSecretRef
- endpoint
type: object
retry:
description: Retry configuration for MCP API calls
properties:
backoffSeconds:
default: 5
description: |-
BackoffSeconds is the initial backoff duration in seconds
Subsequent retries use exponential backoff (backoff * 2^attempt)
maximum: 300
minimum: 1
type: integer
maxAttempts:
default: 3
description: MaxAttempts is the maximum number of retry attempts
(including initial attempt)
maximum: 10
minimum: 1
type: integer
maxBackoffSeconds:
default: 300
description: MaxBackoffSeconds is the maximum backoff duration
in seconds
maximum: 3600
minimum: 1
type: integer
type: object
required:
- mcp
type: object
status:
description: status defines the observed state of CapabilityScanConfig
properties:
conditions:
description: Current conditions of the config
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
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
initialScanComplete:
description: Whether the initial scan has been completed
type: boolean
lastError:
description: Last error message if any
type: string
lastScanTime:
description: Timestamp of last successful scan trigger
format: date-time
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -0,0 +1,326 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.18.0
name: gitknowledgesources.dot-ai.devopstoolkit.live
spec:
group: dot-ai.devopstoolkit.live
names:
kind: GitKnowledgeSource
listKind: GitKnowledgeSourceList
plural: gitknowledgesources
shortNames:
- gks
singular: gitknowledgesource
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Current sync phase
jsonPath: .status.phase
name: Phase
type: string
- description: Whether sync is active
jsonPath: .status.active
name: Active
type: boolean
- description: Number of synced documents
jsonPath: .status.documentCount
name: Documents
type: integer
- description: Time of last sync
jsonPath: .status.lastSyncTime
name: Last Sync
type: date
- description: Sync error count
jsonPath: .status.syncErrors
name: Errors
type: integer
- description: Time since creation
jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: |-
GitKnowledgeSource is the Schema for the gitknowledgesources API
It defines a Git repository to sync documents from into the MCP knowledge base
Works with any Git provider: GitHub, GitLab, Bitbucket, Gitea, self-hosted
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: GitKnowledgeSourceSpec defines the desired state of GitKnowledgeSource
properties:
deletionPolicy:
default: Delete
description: |-
DeletionPolicy specifies what happens to ingested documents when this CR is deleted.
Delete (default): Documents are removed from MCP knowledge base.
Retain: Documents remain in MCP knowledge base.
enum:
- Delete
- Retain
type: string
exclude:
description: |-
Exclude specifies glob patterns for files to exclude
Example: ["docs/internal/**"]
items:
type: string
type: array
maxFileSizeBytes:
description: |-
MaxFileSizeBytes limits the maximum file size to process
Files larger than this are skipped and reported in status
format: int64
type: integer
mcpServer:
description: McpServer configures the MCP server endpoint for knowledge
ingestion
properties:
authSecretRef:
description: AuthSecretRef references a Secret containing the
MCP authentication token
properties:
key:
description: Key within the secret containing the value
type: string
name:
description: Name of the secret in the same namespace as the
resource
type: string
required:
- key
- name
type: object
httpTimeoutSeconds:
default: 120
description: |-
HttpTimeoutSeconds is the HTTP timeout in seconds for MCP API calls
Increase this if syncing large documents that take longer to process
maximum: 600
minimum: 5
type: integer
url:
description: |-
URL is the MCP server endpoint
Example: "http://mcp-server.dot-ai.svc:3456"
pattern: ^https?://.*
type: string
required:
- authSecretRef
- url
type: object
metadata:
additionalProperties:
type: string
description: Metadata contains key-value pairs attached to all ingested
documents
type: object
paths:
description: |-
Paths specifies glob patterns for files to include
Example: ["docs/**/*.md", "README.md"]
items:
type: string
minItems: 1
type: array
repository:
description: Repository defines the Git repository to sync documents
from
properties:
branch:
default: main
description: Branch is the Git branch to sync from
type: string
depth:
default: 1
description: |-
Depth is the shallow clone depth for the initial sync
Subsequent syncs use --shallow-since to fetch only recent commits
minimum: 1
type: integer
secretRef:
description: |-
SecretRef references a Secret containing the Git authentication token
The token should be in the specified key within the Secret
properties:
key:
description: Key within the secret containing the value
type: string
name:
description: Name of the secret in the same namespace as the
resource
type: string
required:
- key
- name
type: object
url:
description: |-
URL is the Git repository URL (HTTPS only)
Example: "https://github.com/acme/platform.git"
pattern: ^https://.*
type: string
required:
- url
type: object
schedule:
default: '@every 24h'
description: |-
Schedule specifies when to sync using cron syntax or interval format
Supports standard cron (e.g., "0 3 * * *") or intervals (e.g., "@every 24h")
Default: "@every 24h" (once per day, staggered based on CR creation time)
type: string
required:
- mcpServer
- paths
- repository
type: object
status:
description: GitKnowledgeSourceStatus defines the observed state of GitKnowledgeSource
properties:
active:
description: Active indicates whether the controller is actively syncing
this source
type: boolean
conditions:
description: Conditions represent the latest available observations
of the GitKnowledgeSource's state
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
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
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
documentCount:
description: DocumentCount is the number of documents currently synced
type: integer
lastError:
description: LastError contains the most recent error message
type: string
lastSyncTime:
description: LastSyncTime is the timestamp of the last successful
sync
format: date-time
type: string
lastSyncedCommit:
description: LastSyncedCommit is the Git commit SHA of the last successful
sync
type: string
nextScheduledSync:
description: NextScheduledSync is the timestamp of the next scheduled
sync
format: date-time
type: string
observedGeneration:
description: ObservedGeneration reflects the generation most recently
observed by the controller
format: int64
type: integer
phase:
description: Phase indicates the current sync phase (Syncing, Synced,
Error)
type: string
skippedDocuments:
description: SkippedDocuments is the count of documents skipped due
to filters
type: integer
skippedFiles:
description: SkippedFiles lists files that were skipped with reasons
items:
description: |-
SkippedFile represents a file or document that was skipped during sync
Used by knowledge source CRDs to report skipped items in status
properties:
path:
description: Path is the file path or identifier relative to
the source
type: string
reason:
description: Reason explains why the file was skipped
type: string
required:
- path
- reason
type: object
type: array
syncErrors:
description: SyncErrors is the count of errors in the last sync
type: integer
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -0,0 +1,377 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.18.0
name: remediationpolicies.dot-ai.devopstoolkit.live
spec:
group: dot-ai.devopstoolkit.live
names:
kind: RemediationPolicy
listKind: RemediationPolicyList
plural: remediationpolicies
singular: remediationpolicy
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Whether the policy is ready
jsonPath: .status.conditions[?(@.type=='Ready')].status
name: Ready
type: string
- description: Total events processed
jsonPath: .status.totalEventsProcessed
name: Events
type: integer
- description: Successful remediations
jsonPath: .status.successfulRemediations
name: Successful
type: integer
- description: Failed remediations
jsonPath: .status.failedRemediations
name: Failed
type: integer
- description: Remediation mode
jsonPath: .spec.mode
name: Mode
type: string
- description: Number of event selectors
jsonPath: .spec.eventSelectors
name: Selectors
priority: 1
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: RemediationPolicy is the Schema for the remediationpolicies API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: spec defines the desired state of RemediationPolicy
properties:
confidenceThreshold:
default: 0.8
description: Minimum confidence required for automatic execution (0.0-1.0)
maximum: 1
minimum: 0
type: number
eventSelectors:
description: Event selection criteria
items:
description: EventSelector defines criteria for selecting Kubernetes
events
properties:
confidenceThreshold:
description: |-
Minimum confidence required for automatic execution (0.0-1.0)
Overrides the global policy confidenceThreshold when specified
maximum: 1
minimum: 0
type: number
involvedObjectKind:
description: Kind of the involved object
type: string
maxRiskLevel:
description: |-
Maximum risk level allowed for automatic execution
Overrides the global policy maxRiskLevel when specified
enum:
- low
- medium
- high
type: string
message:
description: |-
Message pattern to match against event message (supports regex)
If specified, only events whose message matches this regex pattern will be selected
Empty string acts as wildcard (matches all messages)
type: string
mode:
description: |-
Remediation mode for this specific selector: "manual" or "automatic"
Overrides the global policy mode when specified
enum:
- manual
- automatic
type: string
namespace:
description: Namespace selector
type: string
reason:
description: Reason for the event
type: string
type:
description: Type of event (Warning, Normal)
type: string
type: object
type: array
maxRiskLevel:
default: low
description: Maximum risk level allowed for automatic execution
enum:
- low
- medium
- high
type: string
mcpAuthSecretRef:
description: |-
McpAuthSecretRef references a Kubernetes Secret containing the MCP authentication token
The controller will include "Authorization: Bearer <token>" header in MCP requests
The Secret must exist in the same namespace as the RemediationPolicy
properties:
key:
description: Key within the secret containing the value
type: string
name:
description: Name of the secret in the same namespace as the resource
type: string
required:
- key
- name
type: object
mcpEndpoint:
description: MCP endpoint URL
type: string
mcpTool:
default: remediate
description: MCP tool name (always "remediate")
type: string
mode:
default: manual
description: 'Remediation mode: "manual" or "automatic"'
enum:
- manual
- automatic
type: string
notifications:
description: Notification configuration
properties:
googleChat:
description: Google Chat notification configuration
properties:
enabled:
default: false
description: Enable Google Chat notifications
type: boolean
notifyOnComplete:
default: true
description: Notify when remediation completes (default true)
type: boolean
notifyOnStart:
default: false
description: Notify when remediation starts (optional, default
false)
type: boolean
webhookUrl:
description: |-
WebhookUrl - DEPRECATED: Use webhookUrlSecretRef instead
Plain text webhook URL (discouraged for security reasons)
Must start with https://chat.googleapis.com/
type: string
webhookUrlSecretRef:
description: |-
WebhookUrlSecretRef - Kubernetes Secret reference (recommended)
References a Secret in the same namespace as the RemediationPolicy
properties:
key:
description: Key within the secret containing the value
type: string
name:
description: Name of the secret in the same namespace
as the resource
type: string
required:
- key
- name
type: object
type: object
slack:
description: Slack notification configuration
properties:
channel:
description: Slack channel (for display purposes only)
type: string
enabled:
default: false
description: Enable Slack notifications
type: boolean
notifyOnComplete:
default: true
description: Notify when remediation completes (default true)
type: boolean
notifyOnStart:
default: false
description: Notify when remediation starts (optional, default
false)
type: boolean
webhookUrl:
description: |-
WebhookUrl - DEPRECATED: Use webhookUrlSecretRef instead
Plain text webhook URL (discouraged for security reasons)
type: string
webhookUrlSecretRef:
description: |-
WebhookUrlSecretRef - Kubernetes Secret reference (recommended)
References a Secret in the same namespace as the RemediationPolicy
properties:
key:
description: Key within the secret containing the value
type: string
name:
description: Name of the secret in the same namespace
as the resource
type: string
required:
- key
- name
type: object
type: object
type: object
persistence:
description: |-
Persistence configuration for cooldown state
When not specified, persistence is enabled by default
properties:
enabled:
default: true
description: |-
Enable cooldown state persistence for this policy
When enabled, cooldown state survives pod restarts via ConfigMap storage
type: boolean
type: object
rateLimiting:
description: Rate limiting configuration
properties:
cooldownMinutes:
default: 5
description: Cooldown period in minutes after processing
type: integer
eventsPerMinute:
default: 10
description: Maximum events per minute
type: integer
type: object
required:
- eventSelectors
- mcpAuthSecretRef
- mcpEndpoint
type: object
status:
description: status defines the observed state of RemediationPolicy
properties:
conditions:
description: Current conditions of the policy
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
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
failedRemediations:
description: Number of failed remediation calls
format: int64
type: integer
lastMcpMessageGenerated:
description: Timestamp of last MCP message generated
format: date-time
type: string
lastProcessedEvent:
description: Timestamp of last processed event
format: date-time
type: string
lastRateLimitedEvent:
description: Timestamp of last rate limited event
format: date-time
type: string
rateLimitedEvents:
description: Number of events that were rate limited
format: int64
type: integer
successfulRemediations:
description: Number of successful remediation calls
format: int64
type: integer
totalEventsProcessed:
description: Total number of events processed
format: int64
type: integer
totalMcpMessagesGenerated:
description: Total number of MCP messages generated
format: int64
type: integer
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -0,0 +1,199 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.18.0
name: resourcesyncconfigs.dot-ai.devopstoolkit.live
spec:
group: dot-ai.devopstoolkit.live
names:
kind: ResourceSyncConfig
listKind: ResourceSyncConfigList
plural: resourcesyncconfigs
singular: resourcesyncconfig
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Whether sync is active
jsonPath: .status.active
name: Active
type: boolean
- description: Resource types being watched
jsonPath: .status.watchedResourceTypes
name: Watched
type: integer
- description: Total resources synced
jsonPath: .status.totalResourcesSynced
name: Synced
type: integer
- description: Last sync time
jsonPath: .status.lastSyncTime
name: Last Sync
type: date
- description: Sync errors
jsonPath: .status.syncErrors
name: Errors
type: integer
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: |-
ResourceSyncConfig is the Schema for the resourcesyncconfigs API
It configures the controller to watch cluster resources and sync them to MCP
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: spec defines the desired state of ResourceSyncConfig
properties:
debounceWindowSeconds:
default: 10
description: |-
DebounceWindowSeconds is the time window to collect changes before sending to MCP
Multiple changes to the same resource within this window are batched together
maximum: 300
minimum: 1
type: integer
mcpAuthSecretRef:
description: |-
McpAuthSecretRef references a Kubernetes Secret containing the MCP authentication token
The controller will include "Authorization: Bearer <token>" header in MCP requests
The Secret must exist in the same namespace as the ResourceSyncConfig
properties:
key:
description: Key within the secret containing the value
type: string
name:
description: Name of the secret in the same namespace as the resource
type: string
required:
- key
- name
type: object
mcpEndpoint:
description: MCP endpoint URL for resource sync
type: string
resyncIntervalMinutes:
default: 60
description: |-
ResyncIntervalMinutes is how often to perform a full resync with MCP
This ensures eventual consistency by reconciling any missed changes
maximum: 1440
minimum: 1
type: integer
required:
- mcpAuthSecretRef
- mcpEndpoint
type: object
status:
description: status defines the observed state of ResourceSyncConfig
properties:
active:
description: Whether resource syncing is currently active
type: boolean
conditions:
description: Current conditions of the config
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
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
lastError:
description: Last error message if any
type: string
lastResyncTime:
description: Timestamp of last full resync
format: date-time
type: string
lastSyncTime:
description: Timestamp of last successful sync to MCP
format: date-time
type: string
syncErrors:
description: Number of sync errors
format: int64
type: integer
totalResourcesSynced:
description: Total resources synced to MCP
format: int64
type: integer
watchedResourceTypes:
description: Number of resource types being watched
type: integer
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -0,0 +1,222 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.18.0
name: solutions.dot-ai.devopstoolkit.live
spec:
group: dot-ai.devopstoolkit.live
names:
kind: Solution
listKind: SolutionList
plural: solutions
shortNames:
- sol
singular: solution
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Original user intent
jsonPath: .spec.intent
name: Intent
type: string
- description: Solution state
jsonPath: .status.state
name: State
type: string
- description: Ready resources
jsonPath: .status.resources.ready
name: Resources
type: string
- description: Time since creation
jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: Solution is the Schema for the solutions API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: SolutionSpec defines the desired state of Solution
properties:
context:
description: Context contains solution-level information not available
in individual resources
properties:
createdBy:
description: CreatedBy identifies the tool or user that created
this solution
type: string
patterns:
description: Patterns lists the organizational patterns applied
to this solution
items:
type: string
type: array
policies:
description: Policies lists the policies applied to this solution
items:
type: string
type: array
rationale:
description: Rationale explains why this solution was deployed
this way
type: string
type: object
documentationURL:
description: |-
DocumentationURL points to documentation for this solution
This field is populated by external tools (e.g., dot-ai PRD #228)
pattern: ^https?://.*
type: string
intent:
description: |-
Intent describes the original user intent that led to this deployment
Example: "Deploy Go microservice with PostgreSQL database and Redis cache"
minLength: 1
type: string
resources:
description: Resources lists all Kubernetes resources that compose
this solution
items:
description: ResourceReference identifies a Kubernetes resource
that is part of this solution
properties:
apiVersion:
description: APIVersion of the resource
type: string
kind:
description: Kind of the resource
type: string
name:
description: Name of the resource
type: string
namespace:
description: Namespace of the resource (if namespaced)
type: string
required:
- apiVersion
- kind
- name
type: object
minItems: 1
type: array
required:
- intent
- resources
type: object
status:
description: SolutionStatus defines the observed state of Solution
properties:
conditions:
description: Conditions represent the latest available observations
of the solution's state
items:
description: Condition contains details for one aspect of the current
state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
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
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
observedGeneration:
description: ObservedGeneration reflects the generation most recently
observed by the controller
format: int64
type: integer
resources:
description: Resources provides a summary of resource health
properties:
failed:
description: Failed number of resources that have failed
type: integer
ready:
description: Ready number of resources that are ready
type: integer
total:
description: Total number of resources in this solution
type: integer
type: object
state:
description: State represents the overall state of the solution
enum:
- pending
- deployed
- degraded
- failed
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}

View File

@ -0,0 +1,113 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
{{- include "dot-ai-controller.labels" . | nindent 4 }}
name: {{ include "dot-ai-controller.clusterRoleName" . }}
rules:
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- apiGroups:
- ""
resources:
- events
verbs:
- create
- get
- list
- patch
- watch
- apiGroups:
- ""
resources:
- pods
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- '*'
resources:
- '*'
verbs:
- get
- list
- patch
- update
- watch
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- get
- list
- watch
- apiGroups:
- batch
resources:
- cronjobs
- jobs
verbs:
- get
- list
- watch
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- create
- get
- list
- update
- apiGroups:
- dot-ai.devopstoolkit.live
resources:
- capabilityscanconfigs
- gitknowledgesources
- resourcesyncconfigs
- solutions
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- dot-ai.devopstoolkit.live
resources:
- capabilityscanconfigs/finalizers
- gitknowledgesources/finalizers
- resourcesyncconfigs/finalizers
- solutions/finalizers
verbs:
- update
- apiGroups:
- dot-ai.devopstoolkit.live
resources:
- capabilityscanconfigs/status
- gitknowledgesources/status
- remediationpolicies/status
- resourcesyncconfigs/status
- solutions/status
verbs:
- get
- patch
- update
- apiGroups:
- dot-ai.devopstoolkit.live
resources:
- remediationpolicies
verbs:
- get
- list
- watch

View File

@ -0,0 +1,33 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "dot-ai-controller.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
labels:
{{- include "dot-ai-controller.labels" . | nindent 4 }}
{{- $annotations := include "dot-ai-controller.annotations" (dict "global" .Values.annotations "local" nil) -}}
{{- if $annotations }}
annotations:
{{- $annotations | nindent 4 }}
{{- end }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "dot-ai-controller.clusterRoleBindingName" . }}
labels:
{{- include "dot-ai-controller.labels" . | nindent 4 }}
{{- $annotations := include "dot-ai-controller.annotations" (dict "global" .Values.annotations "local" nil) -}}
{{- if $annotations }}
annotations:
{{- $annotations | nindent 4 }}
{{- end }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "dot-ai-controller.clusterRoleName" . }}
subjects:
- kind: ServiceAccount
name: {{ include "dot-ai-controller.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}

View File

@ -0,0 +1,25 @@
# Default values for dot-ai-controller
# Global annotations applied to ALL Kubernetes resources
# Use for tools like Reloader, compliance requirements, or consistent metadata
annotations: {}
# Example: Reloader integration
# reloader.stakater.com/auto: "true"
# Example: Compliance/audit
# company.com/managed-by: "platform-team"
# Image configuration
image:
repository: ghcr.io/vfarcic/dot-ai-controller
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion
tag: ""
# Resource limits and requests
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 10m
memory: 128Mi

Binary file not shown.

View File

@ -0,0 +1,23 @@
annotations:
category: Developer Tools
apiVersion: v2
appVersion: 0.15.0
description: Web UI visualization companion for dot-ai MCP server - renders Mermaid
diagrams, cards, code blocks, and tables
home: https://github.com/vfarcic/dot-ai-ui
keywords:
- devops
- ai
- kubernetes
- visualization
- mcp
- mermaid
- web-ui
maintainers:
- email: viktor@farcic.com
name: Viktor Farcic
name: dot-ai-ui
sources:
- https://github.com/vfarcic/dot-ai-ui
type: application
version: 0.15.0

View File

@ -0,0 +1,101 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "dot-ai-ui.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "dot-ai-ui.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "dot-ai-ui.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "dot-ai-ui.labels" -}}
helm.sh/chart: {{ include "dot-ai-ui.chart" . }}
{{ include "dot-ai-ui.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "dot-ai-ui.selectorLabels" -}}
app.kubernetes.io/name: {{ include "dot-ai-ui.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the secret to use for auth token
*/}}
{{- define "dot-ai-ui.secretName" -}}
{{- if .Values.dotAi.auth.secretRef.name }}
{{- .Values.dotAi.auth.secretRef.name }}
{{- else }}
{{- include "dot-ai-ui.fullname" . }}-auth
{{- end }}
{{- end }}
{{/*
Create the key name for auth token in secret
*/}}
{{- define "dot-ai-ui.secretKey" -}}
{{- default "auth-token" .Values.dotAi.auth.secretRef.key }}
{{- end }}
{{/*
Create the name of the secret to use for UI auth token
*/}}
{{- define "dot-ai-ui.uiAuthSecretName" -}}
{{- if .Values.uiAuth.secretRef.name }}
{{- .Values.uiAuth.secretRef.name }}
{{- else }}
{{- include "dot-ai-ui.fullname" . }}-ui-auth
{{- end }}
{{- end }}
{{/*
Create the key name for UI auth token in secret
*/}}
{{- define "dot-ai-ui.uiAuthSecretKey" -}}
{{- default "ui-auth-token" .Values.uiAuth.secretRef.key }}
{{- end }}
{{/*
Merge global annotations with resource-specific annotations.
Resource-specific annotations take precedence over global annotations.
Usage: include "dot-ai-ui.annotations" (dict "global" .Values.annotations "local" .Values.ingress.annotations)
*/}}
{{- define "dot-ai-ui.annotations" -}}
{{- $global := .global | default dict -}}
{{- $local := .local | default dict -}}
{{- $merged := merge $local $global -}}
{{- if $merged -}}
{{- toYaml $merged -}}
{{- end -}}
{{- end -}}

View File

@ -0,0 +1,75 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "dot-ai-ui.fullname" . }}
labels:
{{- include "dot-ai-ui.labels" . | nindent 4 }}
{{- $annotations := include "dot-ai-ui.annotations" (dict "global" .Values.annotations "local" nil) -}}
{{- if $annotations }}
annotations:
{{- $annotations | nindent 4 }}
{{- end }}
spec:
replicas: 1
selector:
matchLabels:
{{- include "dot-ai-ui.selectorLabels" . | nindent 6 }}
template:
metadata:
labels:
{{- include "dot-ai-ui.selectorLabels" . | nindent 8 }}
{{- $podAnnotations := include "dot-ai-ui.annotations" (dict "global" .Values.annotations "local" nil) -}}
{{- if $podAnnotations }}
annotations:
{{- $podAnnotations | nindent 8 }}
{{- end }}
spec:
containers:
- name: web-ui
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy | default "IfNotPresent" }}
ports:
- containerPort: 3000
name: http
protocol: TCP
env:
- name: NODE_ENV
value: "production"
- name: PORT
value: "3000"
- name: DOT_AI_MCP_URL
value: {{ .Values.dotAi.url | quote }}
{{- if or .Values.dotAi.auth.secretRef.name .Values.dotAi.auth.token }}
- name: DOT_AI_AUTH_TOKEN
valueFrom:
secretKeyRef:
name: {{ include "dot-ai-ui.secretName" . }}
key: {{ include "dot-ai-ui.secretKey" . }}
optional: true
{{- end }}
{{- if or .Values.uiAuth.secretRef.name .Values.uiAuth.token }}
- name: DOT_AI_UI_AUTH_TOKEN
valueFrom:
secretKeyRef:
name: {{ include "dot-ai-ui.uiAuthSecretName" . }}
key: {{ include "dot-ai-ui.uiAuthSecretKey" . }}
optional: true
{{- end }}
{{- with .Values.extraEnv }}
{{- toYaml . | nindent 8 }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 10 }}
livenessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
terminationGracePeriodSeconds: 30

View File

@ -0,0 +1,52 @@
{{- if .Values.gateway.create }}
{{- if not .Values.gateway.className }}
{{- fail "gateway.className is required when gateway.create is true" }}
{{- end }}
{{- if not (or .Values.gateway.listeners.http.enabled .Values.gateway.listeners.https.enabled) }}
{{- fail "At least one listener (http or https) must be enabled when gateway.create is true" }}
{{- end }}
{{- if .Values.gateway.name }}
{{- fail "gateway.name and gateway.create cannot both be set; disable gateway.create when using an existing gateway.name" }}
{{- end }}
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: {{ include "dot-ai-ui.fullname" . }}-http
labels:
{{- include "dot-ai-ui.labels" . | nindent 4 }}
{{- $annotations := include "dot-ai-ui.annotations" (dict "global" .Values.annotations "local" .Values.gateway.annotations) -}}
{{- if $annotations }}
annotations:
{{- $annotations | nindent 4 }}
{{- end }}
spec:
gatewayClassName: {{ .Values.gateway.className }}
listeners:
{{- if .Values.gateway.listeners.http.enabled }}
- name: http
protocol: HTTP
port: 80
{{- if .Values.gateway.listeners.http.hostname }}
hostname: {{ .Values.gateway.listeners.http.hostname }}
{{- end }}
allowedRoutes:
namespaces:
from: Same
{{- end }}
{{- if .Values.gateway.listeners.https.enabled }}
- name: https
protocol: HTTPS
port: 443
{{- if .Values.gateway.listeners.https.hostname }}
hostname: {{ .Values.gateway.listeners.https.hostname }}
{{- end }}
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: {{ .Values.gateway.listeners.https.secretName | default (printf "%s-tls" (include "dot-ai-ui.fullname" .)) }}
allowedRoutes:
namespaces:
from: Same
{{- end }}
{{- end }}

View File

@ -0,0 +1,46 @@
{{- if or .Values.gateway.name .Values.gateway.create }}
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: {{ include "dot-ai-ui.fullname" . }}
labels:
{{- include "dot-ai-ui.labels" . | nindent 4 }}
{{- $annotations := include "dot-ai-ui.annotations" (dict "global" .Values.annotations "local" nil) -}}
{{- if $annotations }}
annotations:
{{- $annotations | nindent 4 }}
{{- end }}
spec:
parentRefs:
- name: {{ if .Values.gateway.name }}{{ .Values.gateway.name }}{{ else }}{{ include "dot-ai-ui.fullname" . }}-http{{ end }}
kind: Gateway
{{- if and .Values.gateway.name .Values.gateway.namespace }}
namespace: {{ .Values.gateway.namespace }}
{{- end }}
{{- if or .Values.gateway.listeners.http.hostname .Values.gateway.listeners.https.hostname }}
hostnames:
{{- if .Values.gateway.listeners.http.hostname }}
- {{ .Values.gateway.listeners.http.hostname }}
{{- end }}
{{- if and .Values.gateway.listeners.https.hostname (ne .Values.gateway.listeners.http.hostname .Values.gateway.listeners.https.hostname) }}
- {{ .Values.gateway.listeners.https.hostname }}
{{- end }}
{{- end }}
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: {{ include "dot-ai-ui.fullname" . }}
port: 3000
{{- if and .Values.gateway.timeouts (or .Values.gateway.timeouts.request .Values.gateway.timeouts.backendRequest) }}
timeouts:
{{- if .Values.gateway.timeouts.request }}
request: {{ .Values.gateway.timeouts.request }}
{{- end }}
{{- if .Values.gateway.timeouts.backendRequest }}
backendRequest: {{ .Values.gateway.timeouts.backendRequest }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,45 @@
{{- if and .Values.ingress.enabled (or .Values.gateway.name .Values.gateway.create) }}
{{- fail "Cannot enable both ingress.enabled and Gateway API usage (gateway.name or gateway.create). Please choose one ingress method." }}
{{- end }}
{{- if and .Values.ingress.tls.clusterIssuer (not .Values.ingress.tls.enabled) }}
{{- fail "ingress.tls.clusterIssuer is set but ingress.tls.enabled is false. Enable TLS or remove clusterIssuer." }}
{{- end }}
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "dot-ai-ui.fullname" . }}
labels:
{{- include "dot-ai-ui.labels" . | nindent 4 }}
{{- $annotations := include "dot-ai-ui.annotations" (dict "global" .Values.annotations "local" .Values.ingress.annotations) -}}
{{- if or $annotations .Values.ingress.tls.clusterIssuer }}
annotations:
{{- if $annotations }}
{{- $annotations | nindent 4 }}
{{- end }}
{{- if .Values.ingress.tls.clusterIssuer }}
cert-manager.io/cluster-issuer: {{ .Values.ingress.tls.clusterIssuer | quote }}
{{- end }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls.enabled }}
tls:
- hosts:
- {{ .Values.ingress.host }}
secretName: {{ .Values.ingress.tls.secretName | default (printf "%s-tls" (include "dot-ai-ui.fullname" .)) }}
{{- end }}
rules:
- host: {{ .Values.ingress.host }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: {{ include "dot-ai-ui.fullname" . }}
port:
number: 3000
{{- end }}

View File

@ -0,0 +1,33 @@
{{- if and .Values.dotAi.auth.token (not .Values.dotAi.auth.secretRef.name) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "dot-ai-ui.fullname" . }}-auth
labels:
{{- include "dot-ai-ui.labels" . | nindent 4 }}
{{- $annotations := include "dot-ai-ui.annotations" (dict "global" .Values.annotations "local" nil) -}}
{{- if $annotations }}
annotations:
{{- $annotations | nindent 4 }}
{{- end }}
type: Opaque
stringData:
auth-token: {{ .Values.dotAi.auth.token | quote }}
{{- end }}
---
{{- if and .Values.uiAuth.token (not .Values.uiAuth.secretRef.name) }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "dot-ai-ui.fullname" . }}-ui-auth
labels:
{{- include "dot-ai-ui.labels" . | nindent 4 }}
{{- $annotations := include "dot-ai-ui.annotations" (dict "global" .Values.annotations "local" nil) -}}
{{- if $annotations }}
annotations:
{{- $annotations | nindent 4 }}
{{- end }}
type: Opaque
stringData:
ui-auth-token: {{ .Values.uiAuth.token | quote }}
{{- end }}

View File

@ -0,0 +1,20 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "dot-ai-ui.fullname" . }}
labels:
{{- include "dot-ai-ui.labels" . | nindent 4 }}
{{- $annotations := include "dot-ai-ui.annotations" (dict "global" .Values.annotations "local" nil) -}}
{{- if $annotations }}
annotations:
{{- $annotations | nindent 4 }}
{{- end }}
spec:
type: ClusterIP
selector:
{{- include "dot-ai-ui.selectorLabels" . | nindent 4 }}
ports:
- port: 3000
targetPort: 3000
protocol: TCP
name: http

View File

@ -0,0 +1,110 @@
# Global annotations applied to ALL Kubernetes resources
# Use for tools like Reloader, compliance requirements, or consistent metadata
annotations: {}
# Example: Reloader integration
# reloader.stakater.com/auto: "true"
# Example: Compliance/audit
# company.com/managed-by: "platform-team"
# Application image configuration
image:
repository: ghcr.io/vfarcic/dot-ai-ui # Container image repository
tag: "0.15.0" # Container image tag - set by CI pipeline during release
pullPolicy: IfNotPresent # Image pull policy
# Resource configuration
resources:
requests:
memory: "128Mi" # Minimum memory required
cpu: "50m" # Minimum CPU required
limits:
memory: "256Mi" # Maximum memory allowed
cpu: "200m" # Maximum CPU allowed
# dot-ai MCP server connection
dotAi:
# URL of the dot-ai MCP server API
# Required: The Web UI proxies visualization requests to this endpoint
url: "http://dot-ai:3456"
# Authentication configuration for MCP server
auth:
# Option 1: Reference existing secret (recommended for production)
secretRef:
name: "dot-ai-secrets" # Secret name (matches dot-ai MCP server default)
key: "auth-token" # Key within the secret
# Option 2: Let chart create secret (for development/testing)
token: "" # Auth token value (only if secretRef.name is empty)
# UI Authentication - protects dashboard access
# Required: Auth is always enabled; token auto-generated if not provided
uiAuth:
# Option 1: Reference existing secret (recommended for production)
secretRef:
name: "" # Secret name containing UI auth token
key: "ui-auth-token" # Key within the secret
# Option 2: Provide token directly (for development/testing)
# If neither secretRef.name nor token is set, a random token is generated at startup
# (check pod logs for the generated token)
token: "" # UI auth token value
# Ingress configuration
# NOTE: Mutually exclusive with gateway - only one can be enabled
ingress:
enabled: false # Create Ingress resource
className: nginx # Ingress class name
host: dot-ai-ui.127.0.0.1.nip.io # Ingress hostname
# Timeout annotations for long-running AI requests (query, remediate, operate, etc.)
# If using different className, update annotations for your ingress controller:
# - Traefik: traefik.ingress.kubernetes.io/service.sticky.cookie.httponly: "true"
# - HAProxy: haproxy.org/timeout-http-request: "600s"
# - AWS ALB: alb.ingress.kubernetes.io/target-group-attributes: idle_timeout.timeout_seconds=600
annotations:
nginx.ingress.kubernetes.io/proxy-read-timeout: "600" # 10 min for AI responses
nginx.ingress.kubernetes.io/proxy-send-timeout: "600" # 10 min for AI responses
tls:
enabled: false # Enable TLS/HTTPS
secretName: "" # TLS secret name (generated if empty when enabled)
clusterIssuer: "" # cert-manager ClusterIssuer name (e.g., "letsencrypt")
# Gateway API configuration (Kubernetes 1.26+)
# NOTE: Mutually exclusive with ingress.enabled - only one can be enabled
# Requires Gateway API CRDs pre-installed in cluster
gateway:
# Reference mode: Specify name of existing Gateway resource (RECOMMENDED)
name: "" # Gateway name to reference (e.g., "cluster-gateway")
# Optional: Gateway namespace for cross-namespace references
namespace: "" # Gateway namespace (e.g., "gateway-system")
# Creation mode: Create a new Gateway resource (for development/testing only)
create: false # Create Gateway resource (false = reference mode)
# GatewayClass name - REQUIRED when create=true
className: "" # GatewayClass name (e.g., "istio", "envoy-gateway")
# Annotations for Gateway (only used when create=true)
annotations: {}
# HTTPRoute timeouts (Gateway API)
# Values are durations (e.g., "3600s", "60m", "1h")
timeouts:
request: "600s" # Max time for entire request (default: 10 min)
backendRequest: "600s" # Max time waiting for backend response (default: 10 min)
# Listener configuration - only used when create=true
listeners:
http:
enabled: true # Enable HTTP listener on port 80
hostname: "" # Optional: hostname for HTTP listener
https:
enabled: false # Enable HTTPS listener on port 443
hostname: "" # Optional: hostname for HTTPS listener
secretName: "" # TLS secret name
# Additional environment variables (optional)
extraEnv: []
# - name: NODE_ENV
# value: "production"

View File

@ -0,0 +1,9 @@
dependencies:
- name: qdrant
repository: https://qdrant.github.io/qdrant-helm
version: 1.15.5
- name: dex
repository: https://charts.dexidp.io
version: 0.24.0
digest: sha256:5e70a00728a97f1b2f129e41bb1a274280ac3c4bf1fcd5e98f18277ecb66048e
generated: "2026-03-01T21:15:39.594662+01:00"

View File

@ -0,0 +1,31 @@
annotations:
category: Developer Tools
apiVersion: v2
appVersion: 1.12.0
dependencies:
- condition: qdrant.enabled
name: qdrant
repository: https://qdrant.github.io/qdrant-helm
version: 1.15.5
- condition: dex.enabled
name: dex
repository: https://charts.dexidp.io
version: 0.24.0
description: DevOps AI Toolkit - Intelligent Kubernetes deployment agent with AI-powered
recommendations
home: https://github.com/vfarcic/dot-ai
keywords:
- devops
- ai
- kubernetes
- deployment
- mcp
- gateway-api
maintainers:
- email: viktor@farcic.com
name: Viktor Farcic
name: dot-ai
sources:
- https://github.com/vfarcic/dot-ai
type: application
version: 1.12.0

View File

@ -0,0 +1,25 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
README.md.gotmpl

View File

@ -0,0 +1,29 @@
annotations:
artifacthub.io/changes: |
- kind: changed
description: "Update Dex to 2.44.0"
artifacthub.io/images: |
- name: dex
image: ghcr.io/dexidp/dex:v2.44.0
apiVersion: v2
appVersion: 2.44.0
description: OpenID Connect (OIDC) identity and OAuth 2.0 provider with pluggable
connectors.
home: https://dexidp.io/
icon: https://dexidp.io/favicons/favicon.png
keywords:
- oidc
- oauth
- identity-provider
- saml
kubeVersion: '>=1.14.0-0'
maintainers:
- email: mark.sagikazar@gmail.com
name: sagikazarmark
url: https://sagikazarmark.com
name: dex
sources:
- https://github.com/dexidp/dex
- https://github.com/dexidp/helm-charts/tree/master/charts/dex
type: application
version: 0.24.0

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,193 @@
# dex
![version: 0.24.0](https://img.shields.io/badge/version-0.24.0-informational?style=flat-square) ![type: application](https://img.shields.io/badge/type-application-informational?style=flat-square) ![app version: 2.44.0](https://img.shields.io/badge/app%20version-2.44.0-informational?style=flat-square) ![kube version: >=1.14.0-0](https://img.shields.io/badge/kube%20version->=1.14.0--0-informational?style=flat-square) [![artifact hub](https://img.shields.io/badge/artifact%20hub-dex-informational?style=flat-square)](https://artifacthub.io/packages/helm/dex/dex)
OpenID Connect (OIDC) identity and OAuth 2.0 provider with pluggable connectors.
**Homepage:** <https://dexidp.io/>
## TL;DR;
```bash
helm repo add dex https://charts.dexidp.io
helm install --generate-name --wait dex/dex
```
## Getting started
### Minimal configuration
Dex requires a minimal configuration in order to work.
You can pass configuration to Dex using Helm values:
```yaml
config:
# Set it to a valid URL
issuer: http://my-issuer-url.com
# See https://dexidp.io/docs/storage/ for more options
storage:
type: memory
# Enable at least one connector
# See https://dexidp.io/docs/connectors/ for more options
enablePasswordDB: true
```
The above configuration won't make Dex automatically available on the configured URL.
One (and probably the easiest) way to achieve that is configuring ingress:
```yaml
ingress:
enabled: true
hosts:
- host: my-issuer-url.com
paths:
- path: /
```
### Minimal TLS configuration
HTTPS is basically mandatory these days, especially for authentication and authorization services.
There are several solutions for protecting services with TlS in Kubernetes,
but by far the most popular and portable is undoubtedly [Cert Manager](https://cert-manager.io).
Cert Manager can be [installed](https://cert-manager.io/docs/installation/kubernetes) with a few steps:
```shell
helm repo add jetstack https://charts.jetstack.io
helm repo update
kubectl create namespace cert-manager
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--set installCRDs=true
```
The next step is setting up an [issuer](https://cert-manager.io/docs/concepts/issuer/) (eg. [Let's Encrypt](https://letsencrypt.org/)):
```shell
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: acme
spec:
acme:
email: YOUR@EMAIL_ADDRESS
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: acme-account-key
solvers:
- http01:
ingress:
class: YOUR_INGRESS_CLASS
EOF
```
Finally, change the ingress config to use TLS:
```yaml
ingress:
enabled: true
annotations:
cert-manager.io/cluster-issuer: acme
hosts:
- host: my-issuer-url.com
paths:
- path: /
tls:
- hosts:
- my-issuer-url.com
secretName: dex-cert
```
## Values
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| replicaCount | int | `1` | Number of replicas (pods) to launch. |
| commonLabels | object | `{}` | Labels to apply to all resources and selectors. |
| image.repository | string | `"ghcr.io/dexidp/dex"` | Name of the image repository to pull the container image from. |
| image.pullPolicy | string | `"IfNotPresent"` | [Image pull policy](https://kubernetes.io/docs/concepts/containers/images/#updating-images) for updating already existing images on a node. |
| image.tag | string | `""` | Image tag override for the default value (chart appVersion). |
| image.digest | string | `""` | When digest is set to a non-empty value, images will be pulled by digest (regardless of tag value). |
| imagePullSecrets | list | `[]` | Reference to one or more secrets to be used when [pulling images](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#create-a-pod-that-uses-your-secret) (from private registries). |
| namespaceOverride | string | `""` | A namespace in place of the release namespace for all resources. |
| nameOverride | string | `""` | A name in place of the chart name for `app:` labels. |
| fullnameOverride | string | `""` | A name to substitute for the full names of resources. |
| hostAliases | list | `[]` | A list of hosts and IPs that will be injected into the pod's hosts file if specified. See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#hostname-and-name-resolution) |
| https.enabled | bool | `false` | Enable the HTTPS endpoint. |
| grpc.enabled | bool | `false` | Enable the gRPC endpoint. Read more in the [documentation](https://dexidp.io/docs/api/). |
| configSecret.create | bool | `true` | Enable creating a secret from the values passed to `config`. If set to false, name must point to an existing secret. |
| configSecret.name | string | `""` | The name of the secret to mount as configuration in the pod. If not set and create is true, a name is generated using the fullname template. Must point to secret that contains at least a `config.yaml` key. |
| config | object | `{}` | Application configuration. See the [official documentation](https://dexidp.io/docs/). |
| volumes | list | `[]` | Additional storage [volumes](https://kubernetes.io/docs/concepts/storage/volumes/). See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#volumes-1) for details. |
| volumeMounts | list | `[]` | Additional [volume mounts](https://kubernetes.io/docs/tasks/configure-pod-container/configure-volume-storage/). See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#volumes-1) for details. |
| envFrom | list | `[]` | Additional environment variables mounted from [secrets](https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables) or [config maps](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#configure-all-key-value-pairs-in-a-configmap-as-container-environment-variables). See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#environment-variables) for details. |
| env | object | `{}` | Additional environment variables passed directly to containers. See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#environment-variables) for details. |
| envVars | list | `[]` | Similar to env but with support for all possible configurations. See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#environment-variables) for details. |
| serviceAccount.create | bool | `true` | Enable service account creation. |
| serviceAccount.annotations | object | `{}` | Annotations to be added to the service account. |
| serviceAccount.name | string | `""` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template. |
| rbac.create | bool | `true` | Specifies whether RBAC resources should be created. If disabled, the operator is responsible for creating the necessary resources based on the templates. |
| rbac.createClusterScoped | bool | `true` | Specifies which RBAC resources should be created. If disabled, the operator is responsible for creating the necessary resources (ClusterRole and RoleBinding or CRD's) |
| deploymentAnnotations | object | `{}` | Annotations to be added to deployment. |
| deploymentLabels | object | `{}` | Labels to be added to deployment. |
| podAnnotations | object | `{}` | Annotations to be added to pods. |
| podLabels | object | `{}` | Labels to be added to pods. |
| podDisruptionBudget.enabled | bool | `false` | Enable a [pod distruption budget](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) to help dealing with [disruptions](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/). It is **highly recommended** for webhooks as disruptions can prevent launching new pods. |
| podDisruptionBudget.minAvailable | int/percentage | `nil` | Number or percentage of pods that must remain available. |
| podDisruptionBudget.maxUnavailable | int/percentage | `nil` | Number or percentage of pods that can be unavailable. |
| priorityClassName | string | `""` | Specify a priority class name to set [pod priority](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#pod-priority). |
| podSecurityContext | object | `{}` | Pod [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod). See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context) for details. |
| revisionHistoryLimit | int | `10` | Define the [count of deployment revisions](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#clean-up-policy) to be kept. May be set to 0 in case of GitOps deployment approach. |
| securityContext | object | `{}` | Container [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container). See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) for details. |
| service.annotations | object | `{}` | Annotations to be added to the service. |
| service.type | string | `"ClusterIP"` | Kubernetes [service type](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types). |
| service.clusterIP | string | `""` | Internal cluster service IP (when applicable) |
| service.loadBalancerIP | string | `""` | Load balancer service IP (when applicable) |
| service.ports.http.port | int | `5556` | HTTP service port |
| service.ports.http.nodePort | int | `nil` | HTTP node port (when applicable) |
| service.ports.https.port | int | `5554` | HTTPS service port |
| service.ports.https.nodePort | int | `nil` | HTTPS node port (when applicable) |
| service.ports.grpc.port | int | `5557` | gRPC service port |
| service.ports.grpc.nodePort | int | `nil` | gRPC node port (when applicable) |
| ingress.enabled | bool | `false` | Enable [ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/). |
| ingress.className | string | `""` | Ingress [class name](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class). |
| ingress.annotations | object | `{}` | Annotations to be added to the ingress. |
| ingress.hosts | list | See [values.yaml](values.yaml). | Ingress host configuration. |
| ingress.tls | list | See [values.yaml](values.yaml). | Ingress TLS configuration. |
| serviceMonitor.enabled | bool | `false` | Enable Prometheus ServiceMonitor. See the [documentation](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/design.md#servicemonitor) and the [API reference](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#servicemonitor) for details. |
| serviceMonitor.namespace | string | Release namespace. | Namespace where the ServiceMonitor resource should be deployed. |
| serviceMonitor.interval | duration | `nil` | Prometheus scrape interval. |
| serviceMonitor.scrapeTimeout | duration | `nil` | Prometheus scrape timeout. |
| serviceMonitor.labels | object | `{}` | Labels to be added to the ServiceMonitor. |
| serviceMonitor.annotations | object | `{}` | Annotations to be added to the ServiceMonitor. |
| serviceMonitor.scheme | string | `""` | HTTP scheme to use for scraping. Can be used with `tlsConfig` for example if using istio mTLS. |
| serviceMonitor.path | string | `"/metrics"` | HTTP path to scrape for metrics. |
| serviceMonitor.tlsConfig | object | `{}` | TLS configuration to use when scraping the endpoint. For example if using istio mTLS. |
| serviceMonitor.bearerTokenFile | string | `nil` | Prometheus scrape bearerTokenFile |
| serviceMonitor.honorLabels | bool | `false` | HonorLabels chooses the metric's labels on collisions with target labels. |
| serviceMonitor.metricRelabelings | list | `[]` | Prometheus scrape metric relabel configs to apply to samples before ingestion. |
| serviceMonitor.relabelings | list | `[]` | Relabel configs to apply to samples before ingestion. |
| resources | object | No requests or limits. | Container resource [requests and limits](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/). See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) for details. |
| autoscaling | object | Disabled by default. | Autoscaling configuration (see [values.yaml](values.yaml) for details). |
| nodeSelector | object | `{}` | [Node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) configuration. |
| tolerations | list | `[]` | [Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) for node taints. See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) for details. |
| affinity | object | `{}` | [Affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) configuration. See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) for details. |
| topologySpreadConstraints | list | `[]` | [TopologySpreadConstraints](https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/) configuration. See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) for details. |
| strategy | object | `{}` | Deployment [strategy](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy) configuration. |
| networkPolicy.enabled | bool | `false` | Create [Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/) |
| networkPolicy.egressRules | list | `[]` | A list of network policy egress rules |
## Migrating from stable/dex (or banzaicloud-stable/dex) chart
This chart is not backwards compatible with the `stable/dex` (or `banzaicloud-stable/dex`) chart.
However, Dex itself remains backwards compatible, so you can easily install the new chart in place of the old one
and continue using Dex with a minimal downtime.

View File

@ -0,0 +1,10 @@
config:
issuer: https://my-issuer.com
storage:
type: memory
enablePasswordDB: true
configSecret:
name: my-super-special-dex-secret

View File

@ -0,0 +1,19 @@
config:
issuer: https://my-issuer.com
storage:
type: memory
enablePasswordDB: true
deploymentAnnotations:
reloader.stakater.com/auto: "true"
podAnnotations:
vault.security.banzaicloud.io/vault-addr: "https://vault.vault:8200"
deploymentLabels:
hello: world
podLabels:
hello: world

View File

@ -0,0 +1,10 @@
config:
issuer: https://my-issuer.com
storage:
type: memory
enablePasswordDB: true
configSecret:
create: false

View File

@ -0,0 +1,7 @@
config:
issuer: https://my-issuer.com
storage:
type: memory
enablePasswordDB: true

View File

@ -0,0 +1,26 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ include "dex.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "dex.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ include "dex.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ include "dex.namespace" . }} svc -w {{ include "dex.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ include "dex.namespace" . }} {{ include "dex.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- if .Values.service.loadBalancerIP }}
WARNING: The.spec.loadBalancerIP field for a Service was deprecated in Kubernetes v1.24.
{{- end }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ include "dex.namespace" . }} -l "app.kubernetes.io/name={{ include "dex.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ include "dex.namespace" . }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ include "dex.namespace" . }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}

View File

@ -0,0 +1,101 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "dex.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Namespace for all resources to be installed into
If not defined in values file then the helm release namespace is used
By default this is not set so the helm release namespace will be used
This gets around an problem within helm discussed here
https://github.com/helm/helm/issues/5358
*/}}
{{- define "dex.namespace" -}}
{{ .Values.namespaceOverride | default (.Release.Namespace | trunc 63 | trimSuffix "-") }}
{{- end -}}
{{/*
Override the namespace for the serviceMonitor
Fallback to the namespaceOverride if serviceMonitor.namespace is not set
*/}}
{{- define "dex.serviceMonitor.namespace" -}}
{{- if .Values.serviceMonitor.namespace }}
{{- .Values.serviceMonitor.namespace -}}
{{- else }}
{{- template "dex.namespace" . -}}
{{- end }}
{{- end -}}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "dex.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "dex.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "dex.labels" -}}
helm.sh/chart: {{ include "dex.chart" . }}
{{ include "dex.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- if .Values.commonLabels}}
{{ toYaml .Values.commonLabels }}
{{- end }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "dex.selectorLabels" -}}
app.kubernetes.io/name: {{ include "dex.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "dex.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "dex.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Create the name of the secret containing the config file to use
*/}}
{{- define "dex.configSecretName" -}}
{{- if .Values.configSecret.create }}
{{- default (include "dex.fullname" .) .Values.configSecret.name }}
{{- else }}
{{- default "default" .Values.configSecret.name }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,150 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "dex.fullname" . }}
namespace: {{ include "dex.namespace" . }}
labels:
{{- include "dex.labels" . | nindent 4 }}
{{ with .Values.deploymentLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{ with .Values.deploymentAnnotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
{{- with .Values.strategy }}
strategy:
{{- toYaml . | nindent 4 }}
{{- end }}
selector:
matchLabels:
{{- include "dex.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{ if .Values.configSecret.create }}
checksum/config: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- end }}
labels:
{{- include "dex.selectorLabels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "dex.serviceAccountName" . }}
{{- with .Values.priorityClassName }}
priorityClassName: {{ . | quote }}
{{- end }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- with .Values.hostAliases }}
hostAliases:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
{{- if .Values.image.digest }}
image: "{{ tpl .Values.image.repository . }}@{{ tpl .Values.image.digest . }}"
{{- else }}
image: "{{ tpl .Values.image.repository . }}:{{ tpl .Values.image.tag . | default (printf "v%s" .Chart.AppVersion) }}"
{{- end }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
args:
- dex
- serve
- --web-http-addr
- 0.0.0.0:5556
{{- if .Values.https.enabled }}
- --web-https-addr
- 0.0.0.0:5554
{{- end }}
{{- if .Values.grpc.enabled }}
- --grpc-addr
- 0.0.0.0:5557
{{- end }}
- --telemetry-addr
- 0.0.0.0:5558
- /etc/dex/config.yaml
env:
{{- range $key, $value := .Values.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
{{- with .Values.envVars }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.envFrom }}
envFrom:
{{- toYaml . | nindent 12 }}
{{- end }}
ports:
- name: http
containerPort: 5556
protocol: TCP
{{- if .Values.https.enabled }}
- name: https
containerPort: 5554
protocol: TCP
{{- end }}
{{- if .Values.grpc.enabled }}
- name: grpc
containerPort: 5557
protocol: TCP
{{- end }}
- name: telemetry
containerPort: 5558
protocol: TCP
livenessProbe:
httpGet:
path: /healthz/live
port: telemetry
readinessProbe:
httpGet:
path: /healthz/ready
port: telemetry
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumeMounts:
- name: config
mountPath: /etc/dex
readOnly: true
{{- with .Values.volumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
volumes:
- name: config
secret:
secretName: {{ include "dex.configSecretName" . }}
{{- with .Values.volumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.topologySpreadConstraints }}
topologySpreadConstraints:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@ -0,0 +1,51 @@
{{- if .Values.autoscaling.enabled }}
{{- if semverCompare ">=1.23-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: autoscaling/v2
{{- else -}}
apiVersion: autoscaling/v2beta1
{{- end }}
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "dex.fullname" . }}
namespace: {{ include "dex.namespace" . }}
labels:
{{- include "dex.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "dex.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- if semverCompare ">=1.23-0" .Capabilities.KubeVersion.GitVersion }}
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- else }}
- type: Resource
resource:
name: cpu
targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- if semverCompare ">=1.23-0" .Capabilities.KubeVersion.GitVersion }}
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- else }}
- type: Resource
resource:
name: memory
targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,62 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "dex.fullname" . -}}
{{- $svcPort := .Values.service.ports.http.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}
namespace: {{ include "dex.namespace" . }}
labels:
{{- include "dex.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ tpl . $ | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ tpl .host $ | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $fullName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,36 @@
{{- if .Values.networkPolicy.enabled }}
{{- if semverCompare "<1.7-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: extensions/v1beta1
{{- else -}}
apiVersion: networking.k8s.io/v1
{{- end }}
kind: NetworkPolicy
metadata:
name: {{ include "dex.fullname" . }}
namespace: {{ include "dex.namespace" . }}
labels:
{{- include "dex.labels" . | nindent 4 }}
spec:
policyTypes:
{{- if .Values.networkPolicy.egressRules }}
- Egress
{{- end }}
- Ingress
podSelector:
matchLabels:
{{- include "dex.selectorLabels" . | nindent 6 }}
ingress:
- ports:
- port: http
{{- if .Values.https.enabled }}
- port: https
{{- end }}
{{- if .Values.grpc.enabled }}
- port: grpc
{{- end }}
- port: telemetry
{{- with .Values.networkPolicy.egressRules }}
egress:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,23 @@
{{- if .Values.podDisruptionBudget.enabled }}
{{- if semverCompare ">=1.21-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: policy/v1
{{- else -}}
apiVersion: policy/v1beta1
{{- end }}
kind: PodDisruptionBudget
metadata:
name: {{ template "dex.fullname" . }}
namespace: {{ include "dex.namespace" . }}
labels:
{{ include "dex.labels" . | indent 4 }}
spec:
{{- with .Values.podDisruptionBudget.minAvailable }}
minAvailable: {{ . }}
{{- end }}
{{- with .Values.podDisruptionBudget.maxUnavailable }}
maxUnavailable: {{ . }}
{{- end }}
selector:
matchLabels:
{{- include "dex.selectorLabels" . | nindent 6 }}
{{- end }}

View File

@ -0,0 +1,57 @@
{{- if .Values.rbac.create }}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "dex.fullname" . }}
namespace: {{ include "dex.namespace" . }}
labels:
{{- include "dex.labels" . | nindent 4 }}
rules:
- apiGroups: ["dex.coreos.com"]
resources: ["*"]
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "dex.fullname" . }}
namespace: {{ include "dex.namespace" . }}
labels:
{{- include "dex.labels" . | nindent 4 }}
roleRef:
kind: Role
apiGroup: rbac.authorization.k8s.io
name: {{ include "dex.fullname" . }}
subjects:
- kind: ServiceAccount
namespace: {{ include "dex.namespace" . }}
name: {{ include "dex.serviceAccountName" . }}
{{- if .Values.rbac.createClusterScoped }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "dex.fullname" . }}
labels:
{{- include "dex.labels" . | nindent 4 }}
rules:
- apiGroups: ["apiextensions.k8s.io"]
resources: ["customresourcedefinitions"]
verbs: ["list", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "dex.fullname" . }}-cluster
labels:
{{- include "dex.labels" . | nindent 4 }}
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: {{ include "dex.fullname" . }}
subjects:
- kind: ServiceAccount
namespace: {{ include "dex.namespace" . }}
name: {{ include "dex.serviceAccountName" . }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,12 @@
{{- if .Values.configSecret.create -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "dex.configSecretName" . }}
namespace: {{ include "dex.namespace" . }}
labels:
{{- include "dex.labels" . | nindent 4 }}
type: Opaque
data:
config.yaml: {{ .Values.config | toYaml | b64enc | quote }}
{{- end }}

View File

@ -0,0 +1,65 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "dex.fullname" . }}
namespace: {{ include "dex.namespace" . }}
labels:
{{- include "dex.labels" . | nindent 4 }}
{{- with .Values.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
{{- with .Values.service.clusterIP }}
clusterIP: {{ . }}
{{- end }}
{{- if eq .Values.service.type "LoadBalancer" }}
{{- with .Values.service.loadBalancerIP }}
loadBalancerIP: {{ . }}
{{- end }}
{{- end }}
ports:
- name: http
port: {{ .Values.service.ports.http.port }}
{{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) .Values.service.ports.http.nodePort }}
nodePort: {{ .Values.service.ports.http.nodePort }}
{{- end }}
targetPort: http
protocol: TCP
{{- if semverCompare ">=1.20-0" .Capabilities.KubeVersion.GitVersion }}
appProtocol: http
{{- end }}
{{- if .Values.https.enabled }}
- name: https
port: {{ .Values.service.ports.https.port }}
{{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) .Values.service.ports.https.nodePort }}
nodePort: {{ .Values.service.ports.https.nodePort }}
{{- end }}
targetPort: https
protocol: TCP
{{- if semverCompare ">=1.20-0" .Capabilities.KubeVersion.GitVersion }}
appProtocol: https
{{- end }}
{{- end }}
{{- if .Values.grpc.enabled }}
- name: grpc
port: {{ .Values.service.ports.grpc.port }}
{{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) .Values.service.ports.grpc.nodePort }}
nodePort: {{ .Values.service.ports.grpc.nodePort }}
{{- end }}
targetPort: grpc
protocol: TCP
{{- if semverCompare ">=1.20-0" .Capabilities.KubeVersion.GitVersion }}
appProtocol: http
{{- end }}
{{- end }}
- name: telemetry
port: 5558
targetPort: telemetry
protocol: TCP
{{- if semverCompare ">=1.20-0" .Capabilities.KubeVersion.GitVersion }}
appProtocol: http
{{- end }}
selector:
{{- include "dex.selectorLabels" . | nindent 4 }}

View File

@ -0,0 +1,13 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "dex.serviceAccountName" . }}
namespace: {{ include "dex.namespace" . }}
labels:
{{- include "dex.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,52 @@
{{- if .Values.serviceMonitor.enabled }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
{{- with .Values.serviceMonitor.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
name: {{ include "dex.fullname" . }}
namespace: {{ include "dex.serviceMonitor.namespace" . }}
labels:
{{- include "dex.labels" . | nindent 4 }}
{{- with .Values.serviceMonitor.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
endpoints:
- port: telemetry
{{- with .Values.serviceMonitor.interval }}
interval: {{ . }}
{{- end }}
{{- with .Values.serviceMonitor.scheme }}
scheme: {{ . }}
{{- end }}
{{- with .Values.serviceMonitor.bearerTokenFile }}
bearerTokenFile: {{ . }}
{{- end }}
{{- with .Values.serviceMonitor.tlsConfig }}
tlsConfig:
{{- toYaml .| nindent 6 }}
{{- end }}
{{- with .Values.serviceMonitor.scrapeTimeout }}
scrapeTimeout: {{ . }}
{{- end }}
path: {{ .Values.serviceMonitor.path }}
honorLabels: {{ .Values.serviceMonitor.honorLabels }}
{{- with .Values.serviceMonitor.metricRelabelings }}
metricRelabelings:
{{- tpl (toYaml . | nindent 6) $ }}
{{- end }}
{{- with .Values.serviceMonitor.relabelings }}
relabelings:
{{- toYaml . | nindent 6 }}
{{- end }}
jobLabel: {{ include "dex.fullname" . }}
selector:
matchLabels:
{{- include "dex.selectorLabels" . | nindent 6 }}
namespaceSelector:
matchNames:
- {{ include "dex.namespace" . }}
{{- end }}

View File

@ -0,0 +1,13 @@
{{- if not .Values.configSecret.create -}}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "dex.configSecretName" . }}-test-no-create
labels:
{{- include "dex.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
type: Opaque
data:
config.yaml: {{ .Values.config | toYaml | b64enc | quote }}
{{- end }}

View File

@ -0,0 +1,345 @@
# Default values for dex.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
# -- Number of replicas (pods) to launch.
replicaCount: 1
# -- Labels to apply to all resources and selectors.
commonLabels: {}
# team_name: dev
image:
# -- Name of the image repository to pull the container image from.
repository: ghcr.io/dexidp/dex
# -- [Image pull policy](https://kubernetes.io/docs/concepts/containers/images/#updating-images) for updating already existing images on a node.
pullPolicy: IfNotPresent
# -- Image tag override for the default value (chart appVersion).
tag: ""
# -- When digest is set to a non-empty value, images will be pulled by digest (regardless of tag value).
digest: ""
# -- Reference to one or more secrets to be used when [pulling images](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#create-a-pod-that-uses-your-secret) (from private registries).
imagePullSecrets: []
# -- A namespace in place of the release namespace for all resources.
namespaceOverride: ""
# -- A name in place of the chart name for `app:` labels.
nameOverride: ""
# -- A name to substitute for the full names of resources.
fullnameOverride: ""
# -- A list of hosts and IPs that will be injected into the pod's hosts file if specified.
# See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#hostname-and-name-resolution)
hostAliases: []
https:
# -- Enable the HTTPS endpoint.
enabled: false
grpc:
# -- Enable the gRPC endpoint.
# Read more in the [documentation](https://dexidp.io/docs/api/).
enabled: false
configSecret:
# -- Enable creating a secret from the values passed to `config`.
# If set to false, name must point to an existing secret.
create: true
# -- The name of the secret to mount as configuration in the pod.
# If not set and create is true, a name is generated using the fullname template.
# Must point to secret that contains at least a `config.yaml` key.
name: ""
# -- Application configuration.
# See the [official documentation](https://dexidp.io/docs/).
config: {}
# -- Additional storage [volumes](https://kubernetes.io/docs/concepts/storage/volumes/).
# See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#volumes-1) for details.
volumes: []
# -- Additional [volume mounts](https://kubernetes.io/docs/tasks/configure-pod-container/configure-volume-storage/).
# See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#volumes-1) for details.
volumeMounts: []
# -- Additional environment variables mounted from [secrets](https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables) or [config maps](https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#configure-all-key-value-pairs-in-a-configmap-as-container-environment-variables).
# See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#environment-variables) for details.
envFrom: []
# -- Additional environment variables passed directly to containers.
# See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#environment-variables) for details.
env: {}
# -- Similar to env but with support for all possible configurations.
# See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#environment-variables) for details.
envVars: []
# - name: SOME_ENV_VAR
# value: value
# - name: SOME_ENV_VAR2
# valueFrom:
# secretKeyRef:
# name: secret-name
# key: secret-key
# - name: SOME_ENV_VAR3
# valueFrom:
# configMapKeyRef:
# name: config-map-name
# key: config-map-key
serviceAccount:
# -- Enable service account creation.
create: true
# -- Annotations to be added to the service account.
annotations: {}
# -- The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template.
name: ""
rbac:
# -- Specifies whether RBAC resources should be created.
# If disabled, the operator is responsible for creating the necessary resources based on the templates.
create: true
# -- Specifies which RBAC resources should be created.
# If disabled, the operator is responsible for creating the necessary resources (ClusterRole and RoleBinding or CRD's)
createClusterScoped: true
# -- Annotations to be added to deployment.
deploymentAnnotations: {}
# -- Labels to be added to deployment.
deploymentLabels: {}
# -- Annotations to be added to pods.
podAnnotations: {}
# -- Labels to be added to pods.
podLabels: {}
podDisruptionBudget:
# -- Enable a [pod distruption budget](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) to help dealing with [disruptions](https://kubernetes.io/docs/concepts/workloads/pods/disruptions/).
# It is **highly recommended** for webhooks as disruptions can prevent launching new pods.
enabled: false
# -- (int/percentage) Number or percentage of pods that must remain available.
minAvailable:
# -- (int/percentage) Number or percentage of pods that can be unavailable.
maxUnavailable:
# -- Specify a priority class name to set [pod priority](https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/#pod-priority).
priorityClassName: ""
# -- Pod [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod).
# See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context) for details.
podSecurityContext: {}
# fsGroup: 2000
# -- Define the [count of deployment revisions](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#clean-up-policy) to be kept.
# May be set to 0 in case of GitOps deployment approach.
revisionHistoryLimit: 10
# -- Container [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container).
# See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context-1) for details.
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
# -- Annotations to be added to the service.
annotations: {}
# -- Kubernetes [service type](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types).
type: ClusterIP
# -- Internal cluster service IP (when applicable)
clusterIP: ""
# -- Load balancer service IP (when applicable)
loadBalancerIP: ""
ports:
http:
# -- HTTP service port
port: 5556
# -- (int) HTTP node port (when applicable)
nodePort:
https:
# -- HTTPS service port
port: 5554
# -- (int) HTTPS node port (when applicable)
nodePort:
grpc:
# -- gRPC service port
port: 5557
# -- (int) gRPC node port (when applicable)
nodePort:
ingress:
# -- Enable [ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/).
enabled: false
# -- Ingress [class name](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class).
className: ""
# -- Annotations to be added to the ingress.
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
# -- Ingress host configuration.
# @default -- See [values.yaml](values.yaml).
hosts:
- host: chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
# -- Ingress TLS configuration.
# @default -- See [values.yaml](values.yaml).
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
serviceMonitor:
# -- Enable Prometheus ServiceMonitor.
# See the [documentation](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/design.md#servicemonitor) and the [API reference](https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#servicemonitor) for details.
enabled: false
# -- Namespace where the ServiceMonitor resource should be deployed.
# @default -- Release namespace.
namespace: ""
# -- (duration) Prometheus scrape interval.
interval:
# -- (duration) Prometheus scrape timeout.
scrapeTimeout:
# -- Labels to be added to the ServiceMonitor.
## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#prometheusspec
labels: {}
# -- Annotations to be added to the ServiceMonitor.
## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#prometheusspec
annotations: {}
# -- HTTP scheme to use for scraping.
# Can be used with `tlsConfig` for example if using istio mTLS.
scheme: ""
# -- HTTP path to scrape for metrics.
path: /metrics
# -- TLS configuration to use when scraping the endpoint.
# For example if using istio mTLS.
## Of type: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#tlsconfig
tlsConfig: {}
# -- Prometheus scrape bearerTokenFile
bearerTokenFile:
# -- HonorLabels chooses the metric's labels on collisions with target labels.
honorLabels: false
# -- Prometheus scrape metric relabel configs
# to apply to samples before ingestion.
## [Metric Relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs)
metricRelabelings: []
# - action: keep
# regex: 'kube_(daemonset|deployment|pod|namespace|node|statefulset).+'
# sourceLabels: [__name__]
# -- Relabel configs to apply
# to samples before ingestion.
## [Relabeling](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config)
relabelings: []
# - sourceLabels: [__meta_kubernetes_pod_node_name]
# separator: ;
# regex: ^(.*)$
# targetLabel: nodename
# replacement: $1
# action: replace
# -- Container resource [requests and limits](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/).
# See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#resources) for details.
# @default -- No requests or limits.
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
# -- Autoscaling configuration (see [values.yaml](values.yaml) for details).
# @default -- Disabled by default.
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
# -- [Node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) configuration.
nodeSelector: {}
# -- [Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) for node taints.
# See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) for details.
tolerations: []
# -- [Affinity](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) configuration.
# See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) for details.
affinity: {}
# -- [TopologySpreadConstraints](https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/) configuration.
# See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) for details.
topologySpreadConstraints: []
# -- Deployment [strategy](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy) configuration.
strategy: {}
# rollingUpdate:
# maxUnavailable: 1
# type: RollingUpdate
networkPolicy:
# -- Create [Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/)
enabled: false
# -- A list of network policy egress rules
egressRules: []
# Allow DNS egress traffic
# - ports:
# - port: 53
# protocol: UDP
# - port: 53
# protocol: TCP
# Example to allow LDAP connector to reach LDAPs port on 1.2.3.4 server
# - to:
# - ipBlock
# cidr: 1.2.3.4/32
# ports:
# - port: 636
# protocol: TCP

View File

@ -0,0 +1,2 @@
.git
.github

View File

@ -0,0 +1,6 @@
# Changelog
## [qdrant-1.15.5](https://github.com/qdrant/qdrant-helm/tree/qdrant-1.15.4) (2025-09-30)
- Update Qdrant to v1.15.5

View File

@ -0,0 +1,22 @@
annotations:
artifacthub.io/category: database
artifacthub.io/changes: |
- kind: added
description: Update Qdrant to v1.15.5
apiVersion: v2
appVersion: v1.15.5
description: Qdrant - Vector Database for the next generation of AI applications.
home: https://qdrant.tech
icon: https://qdrant.github.io/qdrant-helm/logo_with_text.svg
keywords:
- vector database
maintainers:
- email: info@qdrant.com
name: qdrant
url: https://github.com/qdrant
name: qdrant
sources:
- https://github.com/qdrant/qdrant
- https://github.com/qdrant/qdrant-helm
type: application
version: 1.15.5

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,157 @@
# Qdrant helm chart
[Qdrant documentation](https://qdrant.tech/documentation/)
## TLDR
```bash
helm repo add qdrant https://qdrant.github.io/qdrant-helm
helm repo update
helm upgrade -i your-qdrant-installation-name qdrant/qdrant
```
## Description
This chart installs and bootstraps a Qdrant instance.
## Prerequisites
- Kubernetes v1.24+ (as you need grpc probe)
- Helm
- PV provisioner (by the infrastructure)
## Installation & Setup
You can install the chart from source via:
```bash
helm upgrade -i your-qdrant-installation-name charts/qdrant
```
Uninstall via:
```bash
helm uninstall your-qdrant-installation-name
```
Delete the volume with
```bash
kubectl delete pvc -l app.kubernetes.io/instance=your-qdrant-installation-name
```
## Configuration
For documentation of the settings please refer to [Qdrant Configuration File](https://github.com/qdrant/qdrant/blob/master/config/config.yaml)
All of these configuration options could be overwritten under config in `values.yaml`.
A modification example is provided there.
### Overrides
You can override any value in the Qdrant configuration by setting the Helm values under the key `config`. Those settings get included verbatim in a file called `config/production.yml` which is explained further here [Qdrant Order and Priority](https://qdrant.tech/documentation/guides/configuration/#order-and-priority) as well as an [example](https://github.com/qdrant/qdrant-helm/blob/b0bb6fc6d3eb9c0813c79bb5a78dc21aebc2b81d/charts/qdrant/values.yaml#L140).
### Distributed setup
Running a distributed cluster just needs a few changes in your `values.yaml` file.
Increase the number of replicas to the desired number of nodes and set `config.cluster.enabled` to true.
Depending on your environment or cloud provider you might need to change the service in the `values.yaml` as well.
For example on AWS EKS you would need to change the `cluster.type` to `NodePort`.
## Updating StatefulSets
This Helm chart uses a Kubernetes [StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/) to manage your Qdrant cluster. StatefulSets have many fields that are immutable, meaning that you cannot change these fields without deleting and recreating the StatefulSet. If you try to change these fields, you will get an error like this:
```
Error: UPGRADE FAILED: cannot patch "qdrant" with kind StatefulSet: StatefulSet.apps "qdrant" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'ordinals', 'template', 'updateStrategy', 'persistentVolumeClaimRetentionPolicy' and 'minReadySeconds' are forbidden
```
If you need to change any immutable field, the process is described below, using the most common example of expanding a PVC volume.
1. Delete the StatefulSet while leaving the Pods running:
```bash
kubectl delete statefulset --cascade=orphan qdrant
```
2. Manually edit all PersistentVolumeClaims to increase their sizes:
```bash
# For each PersistentVolumeClaim:
kubectl edit pvc qdrant-storage-qdrant-0
```
3. Update your Helm values to match the new PVC size.
4. Reinstall the Helm chart using your updated values:
```bash
helm upgrade --install qdrant qdrant/qdrant -f my-values.yaml
```
Some storage providers allow resizing volumes in-place, but most require a pod restart before the new size will take effect:
```bash
kubectl rollout restart statefulset qdrant
```
### Immutable Pod fields
In addition to immutable fields on StatefulSets, Pods also have some fields which are immutable, which means the above method may not work for some changes, such as setting `snapshotPersistence.enabled: true`. In that case, after following the above method, you'll see an error like this when you `kubectl describe` your StatefulSet:
```
pod updates may not change fields other than `spec.containers[*].image`,
`spec.initContainers[*].image`,`spec.activeDeadlineSeconds`,
`spec.tolerations` (only additions to existing tolerations),
`spec.terminationGracePeriodSeconds` (allow it to be set to 1 if it was previously negative)
```
To fix this, you must manually delete all of your Qdrant pods, starting with node-0. This will cause your cluster to go down, but will allow the StatefulSet to recreate your Pods with the correct configuration.
## Restoring from Snapshots
This helm chart allows you to restore a snapshot into your Qdrant cluster either from an internal or external PersistentVolumeClaim.
### Restoring from the built-in PVC
If you have set `snapshotPersistence.enabled: true` (recommended for production), this helm chart will create a separate PersistentVolume for snapshots, and any snapshots you create will be stored in that PersistentVolume.
To restore from one of these snapshots, set the following values:
```yaml
snapshotRestoration:
enabled: true
# Set blank to indicate we are not using an external PVC
pvcName: ""
snapshots:
- /qdrant/snapshots/<collection_name>/<filename>/:<collection_name>
```
And run "helm upgrade". This will restart your cluster and restore the specified collection from the snapshot. Qdrant will refuse to overwrite an existing collection, so ensure the collection is deleted before restoring.
After the snapshot is restored, remove the above values and run "helm upgrade" again to trigger another rolling restart. Otherwise, the snapshot restore will be attempted again if your cluster ever restarts.
### Restoring from an external PVC
If you wish to restore from an externally-created snapshot, using the API is recommended: https://qdrant.github.io/qdrant/redoc/index.html#tag/collections/operation/recover_from_uploaded_snapshot
If the file is too large, you can separately create a PersistentVolumeClaim, store your data in there, and refer to this separate PersistentVolumeClaim in this helm chart.
Once you have created this PersistentVolumeClaim (must be in the same namespace as your Qdrant cluster), set the following values:
```yml
snapshotRestoration:
enabled: true
pvcName: "<the name of your PVC>"
snapshots:
- /qdrant/snapshots/<collection_name>/<filename>/:<collection_name>
```
And run "helm upgrade". This will restart your cluster and restore the specified collection from the snapshot. Qdrant will refuse to overwrite an existing collection, so ensure the collection is deleted before restoring.
After the snapshot is restored, remove the above values and run "helm upgrade" again to trigger another rolling restart. Otherwise, the snapshot restore will be attempted again if your cluster ever restarts.
## Metrics endpoints
Metrics are available through rest api (default port set to 6333) at `/metrics`
Refer to [qdrant metrics configuration](https://qdrant.tech/documentation/telemetry/#metrics) for more information.

View File

@ -0,0 +1,24 @@
Qdrant {{ .Chart.AppVersion }} has been deployed successfully.
The full Qdrant documentation is available at https://qdrant.tech/documentation/.
To forward Qdrant's ports execute one of the following commands:
export POD_NAME=$(kubectl get pods --namespace {{ $.Release.Namespace }} -l "app.kubernetes.io/name={{ include "qdrant.name" . }},app.kubernetes.io/instance={{ $.Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
{{- if contains "ClusterIP" .Values.service.type }}
{{- range .Values.service.ports }}
If you want to use Qdrant via {{ .name }} execute the following commands
kubectl --namespace {{ $.Release.Namespace }} port-forward $POD_NAME {{ .targetPort }}:{{ .targetPort }}
{{- end }}
{{- end }}
{{- if .Values.ingress.enabled }}
If you want to access Qdrant through the ingress controller
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,134 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "qdrant.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "qdrant.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "qdrant.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "qdrant.labels" -}}
helm.sh/chart: {{ include "qdrant.chart" . }}
{{ include "qdrant.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "qdrant.selectorLabels" -}}
app: {{ include "qdrant.name" . }}
app.kubernetes.io/name: {{ include "qdrant.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "qdrant.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "qdrant.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Create secret
*/}}
{{- define "qdrant.secret" -}}
{{- $readOnlyApiKey := false }}
{{- $apiKey := false }}
{{- if kindIs "map" .Values.apiKey -}}
{{- if .Values.apiKey.valueFrom -}}
{{- /* Retrieve the value from the secret as specified in valueFrom */ -}}
{{- $secretName := .Values.apiKey.valueFrom.secretKeyRef.name -}}
{{- $secretKey := .Values.apiKey.valueFrom.secretKeyRef.key -}}
{{- $secretObj := (lookup "v1" "Secret" .Release.Namespace $secretName) | default dict -}}
{{- $secretData := (get $secretObj "data") | default dict -}}
{{- $apiKey = (get $secretData $secretKey | b64dec) -}}
{{- end -}}
{{- else if .Values.apiKey | toJson | eq "true" -}}
{{- /* Retrieve existing randomly generated api key or create a new one */ -}}
{{- $secretObj := (lookup "v1" "Secret" .Release.Namespace (printf "%s-apikey" (include "qdrant.fullname" . ))) | default dict -}}
{{- $secretData := (get $secretObj "data") | default dict -}}
{{- $apiKey = (get $secretData "api-key" | b64dec) | default (randAlphaNum 32) -}}
{{- else if .Values.apiKey -}}
{{- $apiKey = .Values.apiKey -}}
{{- end -}}
{{- if kindIs "map" .Values.readOnlyApiKey -}}
{{- if .Values.readOnlyApiKey.valueFrom -}}
{{- /* Retrieve the value from the secret as specified in valueFrom */ -}}
{{- $secretName := .Values.readOnlyApiKey.valueFrom.secretKeyRef.name -}}
{{- $secretKey := .Values.readOnlyApiKey.valueFrom.secretKeyRef.key -}}
{{- $secretObj := (lookup "v1" "Secret" .Release.Namespace $secretName) | default dict -}}
{{- $secretData := (get $secretObj "data") | default dict -}}
{{- $readOnlyApiKey = (get $secretData $secretKey | b64dec) -}}
{{- end -}}
{{- else if eq (.Values.readOnlyApiKey | toJson) "true" -}}
{{- /* retrieve existing randomly generated api key or create new one */ -}}
{{- $secretObj := (lookup "v1" "Secret" .Release.Namespace (printf "%s-apikey" (include "qdrant.fullname" . ))) | default dict -}}
{{- $secretData := (get $secretObj "data") | default dict -}}
{{- $readOnlyApiKey = (get $secretData "read-only-api-key" | b64dec) | default (randAlphaNum 32) -}}
{{- else if .Values.readOnlyApiKey -}}
{{- $readOnlyApiKey = .Values.readOnlyApiKey -}}
{{- end -}}
{{- if and $apiKey $readOnlyApiKey -}}
api-key: {{ $apiKey | b64enc }}
read-only-api-key: {{ $readOnlyApiKey | b64enc }}
local.yaml: {{ printf "service:\n api_key: %s\n read_only_api_key: %s" $apiKey $readOnlyApiKey | b64enc }}
{{- else if $apiKey -}}
api-key: {{ $apiKey | b64enc }}
local.yaml: {{ printf "service:\n api_key: %s" $apiKey | b64enc }}
{{- else if $readOnlyApiKey -}}
read-only-api-key: {{ $readOnlyApiKey | b64enc }}
local.yaml: {{ printf "service:\n read_only_api_key: %s" $readOnlyApiKey | b64enc }}
{{- end -}}
{{- end -}}
{{/*
Protocol to use for inter cluster communication
*/}}
{{- define "qdrant.p2p.protocol" -}}
{{ if eq (.Values.config.cluster.p2p.enable_tls | toJson) "true" -}}
https
{{- else -}}
http
{{- end -}}
{{- end -}}
{{/*
Port to use for inter cluster communication
*/}}
{{- define "qdrant.p2p.port" -}}
{{- default 6335 .Values.config.cluster.p2p.port -}}
{{- end -}}

View File

@ -0,0 +1,32 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "qdrant.fullname" . }}
labels:
{{- include "qdrant.labels" . | nindent 4 }}
{{- with .Values.additionalAnnotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
data:
initialize.sh: |
#!/bin/sh
echo "Soft limits"
ulimit -a -S
echo "Hard limits"
ulimit -a -H
ulimit -n $(ulimit -Hn)
SET_INDEX=${HOSTNAME##*-}
{{- if and (.Values.snapshotRestoration.enabled) (eq (.Values.replicaCount | quote) (1 | quote)) }}
echo "Starting initializing for pod $SET_INDEX and snapshots restoration"
exec ./entrypoint.sh --uri '{{ include "qdrant.p2p.protocol" . }}://{{ include "qdrant.fullname" . }}-0.{{ include "qdrant.fullname" . }}-headless:{{ include "qdrant.p2p.port" . }}' {{ range .Values.snapshotRestoration.snapshots }} --snapshot {{ . }} {{ end }}
{{- else }}
echo "Starting initializing for pod $SET_INDEX"
if [ "$SET_INDEX" = "0" ]; then
exec ./entrypoint.sh --uri '{{ include "qdrant.p2p.protocol" . }}://{{ include "qdrant.fullname" . }}-0.{{ include "qdrant.fullname" . }}-headless:{{ include "qdrant.p2p.port" . }}'
else
exec ./entrypoint.sh --bootstrap '{{ include "qdrant.p2p.protocol" . }}://{{ include "qdrant.fullname" . }}-0.{{ include "qdrant.fullname" . }}-headless:{{ include "qdrant.p2p.port" . }}' --uri '{{ include "qdrant.p2p.protocol" . }}://{{ include "qdrant.fullname" . }}-'"$SET_INDEX"'.{{ include "qdrant.fullname" . }}-headless:{{ include "qdrant.p2p.port" . }}'
fi
{{ end }}
production.yaml: |
{{- tpl (toYaml .Values.config) . | nindent 4 }}

View File

@ -0,0 +1,52 @@
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "qdrant.fullname" . }}
labels:
{{- include "qdrant.labels" . | nindent 4 }}
{{- with .Values.ingress.additionalLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- if or .Values.ingress.annotations .Values.additionalAnnotations }}
annotations:
{{- with .Values.additionalAnnotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- with .Values.ingress.annotations }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
spec:
{{- if .Values.ingress.ingressClassName }}
ingressClassName: {{ .Values.ingress.ingressClassName }}
{{- end }}
{{- with .Values.ingress.hosts }}
rules:
{{- range . }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path | quote }}
pathType: {{ .pathType | default "Prefix" | quote }}
backend:
service:
name: {{ default .serviceName (include "qdrant.fullname" $) }}
port:
number: {{ .servicePort }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls}}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName | quote }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,25 @@
{{- if .Values.podDisruptionBudget.enabled }}
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ include "qdrant.fullname" . }}
labels:
{{- include "qdrant.labels" . | nindent 4 }}
{{- with .Values.additionalAnnotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.podDisruptionBudget.maxUnavailable}}
maxUnavailable: {{ . }}
{{- end }}
{{- with .Values.podDisruptionBudget.minAvailable }}
minAvailable: {{ . }}
{{- end }}
{{- with .Values.podDisruptionBudget.unhealthyPodEvictionPolicy }}
unhealthyPodEvictionPolicy: {{ . }}
{{- end }}
selector:
matchLabels:
{{- include "qdrant.selectorLabels" . | nindent 6 }}
{{- end }}

Some files were not shown because too many files have changed in this diff Show More