Add dot-ai-stack
This commit is contained in:
parent
cf935551a8
commit
5d1a45feeb
24
argocd-apps/dot-ai-stack.yaml
Normal file
24
argocd-apps/dot-ai-stack.yaml
Normal 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
|
||||
@ -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`
|
||||
118
charts/dot-ai-stack/.claude/commands/doc-write.md
Normal file
118
charts/dot-ai-stack/.claude/commands/doc-write.md
Normal 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.
|
||||
@ -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."
|
||||
14
charts/dot-ai-stack/.claude/settings.json
Normal file
14
charts/dot-ai-stack/.claude/settings.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"hooks": {
|
||||
"UserPromptSubmit": [
|
||||
{
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": ".claude/hooks/prd-done-changelog-reminder.sh"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
|
||||
310
charts/dot-ai-stack/.claude/skills/dot-ai-generate-cicd/SKILL.md
Normal file
310
charts/dot-ai-stack/.claude/skills/dot-ai-generate-cicd/SKILL.md
Normal 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.
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
```
|
||||
@ -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
|
||||
```
|
||||
15
charts/dot-ai-stack/.claude/skills/dot-ai-operate/SKILL.md
Normal file
15
charts/dot-ai-stack/.claude/skills/dot-ai-operate/SKILL.md
Normal 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
|
||||
```
|
||||
154
charts/dot-ai-stack/.claude/skills/dot-ai-port-destroy/SKILL.md
Normal file
154
charts/dot-ai-stack/.claude/skills/dot-ai-port-destroy/SKILL.md
Normal 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
|
||||
|
||||
239
charts/dot-ai-stack/.claude/skills/dot-ai-port-setup/SKILL.md
Normal file
239
charts/dot-ai-stack/.claude/skills/dot-ai-port-setup/SKILL.md
Normal 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\""
|
||||
}
|
||||
```
|
||||
|
||||
284
charts/dot-ai-stack/.claude/skills/dot-ai-prd-close/SKILL.md
Normal file
284
charts/dot-ai-stack/.claude/skills/dot-ai-prd-close/SKILL.md
Normal 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
|
||||
|
||||
210
charts/dot-ai-stack/.claude/skills/dot-ai-prd-create/SKILL.md
Normal file
210
charts/dot-ai-stack/.claude/skills/dot-ai-prd-create/SKILL.md
Normal 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
|
||||
|
||||
342
charts/dot-ai-stack/.claude/skills/dot-ai-prd-done/SKILL.md
Normal file
342
charts/dot-ai-stack/.claude/skills/dot-ai-prd-done/SKILL.md
Normal 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.
|
||||
|
||||
264
charts/dot-ai-stack/.claude/skills/dot-ai-prd-next/SKILL.md
Normal file
264
charts/dot-ai-stack/.claude/skills/dot-ai-prd-next/SKILL.md
Normal 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.
|
||||
|
||||
188
charts/dot-ai-stack/.claude/skills/dot-ai-prd-start/SKILL.md
Normal file
188
charts/dot-ai-stack/.claude/skills/dot-ai-prd-start/SKILL.md
Normal 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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
---
|
||||
|
||||
49
charts/dot-ai-stack/.claude/skills/dot-ai-prds-get/SKILL.md
Normal file
49
charts/dot-ai-stack/.claude/skills/dot-ai-prds-get/SKILL.md
Normal 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.
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
```
|
||||
@ -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.
|
||||
|
||||
15
charts/dot-ai-stack/.claude/skills/dot-ai-query/SKILL.md
Normal file
15
charts/dot-ai-stack/.claude/skills/dot-ai-query/SKILL.md
Normal 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
|
||||
```
|
||||
15
charts/dot-ai-stack/.claude/skills/dot-ai-recommend/SKILL.md
Normal file
15
charts/dot-ai-stack/.claude/skills/dot-ai-recommend/SKILL.md
Normal 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
|
||||
```
|
||||
15
charts/dot-ai-stack/.claude/skills/dot-ai-remediate/SKILL.md
Normal file
15
charts/dot-ai-stack/.claude/skills/dot-ai-remediate/SKILL.md
Normal 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
|
||||
```
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
15
charts/dot-ai-stack/.claude/skills/dot-ai-version/SKILL.md
Normal file
15
charts/dot-ai-stack/.claude/skills/dot-ai-version/SKILL.md
Normal 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
|
||||
```
|
||||
@ -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
|
||||
|
||||
9
charts/dot-ai-stack/.claude/skills/dot-ai/SKILL.md
Normal file
9
charts/dot-ai-stack/.claude/skills/dot-ai/SKILL.md
Normal 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.
|
||||
95
charts/dot-ai-stack/.github/workflows/release.yaml
vendored
Normal file
95
charts/dot-ai-stack/.github/workflows/release.yaml
vendored
Normal 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"}'
|
||||
30
charts/dot-ai-stack/.helmignore
Normal file
30
charts/dot-ai-stack/.helmignore
Normal 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
|
||||
11
charts/dot-ai-stack/.mcp.json
Normal file
11
charts/dot-ai-stack/.mcp.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"coderabbitai": {
|
||||
"command": "npx",
|
||||
"args": ["coderabbitai-mcp@latest"],
|
||||
"env": {
|
||||
"GITHUB_PAT": "${GITHUB_TOKEN}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
charts/dot-ai-stack/Chart.lock
Normal file
12
charts/dot-ai-stack/Chart.lock
Normal 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"
|
||||
18
charts/dot-ai-stack/Chart.yaml
Normal file
18
charts/dot-ai-stack/Chart.yaml
Normal 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
|
||||
21
charts/dot-ai-stack/LICENSE
Normal file
21
charts/dot-ai-stack/LICENSE
Normal 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.
|
||||
41
charts/dot-ai-stack/README.md
Normal file
41
charts/dot-ai-stack/README.md
Normal file
@ -0,0 +1,41 @@
|
||||
# dot-ai-stack
|
||||
|
||||
[](LICENSE)
|
||||

|
||||
|
||||
**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.
|
||||
0
charts/dot-ai-stack/changelog.d/.gitkeep
Normal file
0
charts/dot-ai-stack/changelog.d/.gitkeep
Normal file
19
charts/dot-ai-stack/changelog.d/2.feature.md
Normal file
19
charts/dot-ai-stack/changelog.d/2.feature.md
Normal 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.
|
||||
5
charts/dot-ai-stack/changelog.d/3.bugfix.md
Normal file
5
charts/dot-ai-stack/changelog.d/3.bugfix.md
Normal 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.
|
||||
BIN
charts/dot-ai-stack/charts/dot-ai-1.12.0.tgz
Normal file
BIN
charts/dot-ai-stack/charts/dot-ai-1.12.0.tgz
Normal file
Binary file not shown.
BIN
charts/dot-ai-stack/charts/dot-ai-controller-0.48.1.tgz
Normal file
BIN
charts/dot-ai-stack/charts/dot-ai-controller-0.48.1.tgz
Normal file
Binary file not shown.
22
charts/dot-ai-stack/charts/dot-ai-controller/Chart.yaml
Normal file
22
charts/dot-ai-stack/charts/dot-ai-controller/Chart.yaml
Normal 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
|
||||
@ -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!
|
||||
@ -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 -}}
|
||||
@ -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
|
||||
@ -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: {}
|
||||
@ -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: {}
|
||||
@ -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: {}
|
||||
@ -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: {}
|
||||
@ -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: {}
|
||||
@ -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
|
||||
@ -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 }}
|
||||
25
charts/dot-ai-stack/charts/dot-ai-controller/values.yaml
Normal file
25
charts/dot-ai-stack/charts/dot-ai-controller/values.yaml
Normal 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
|
||||
BIN
charts/dot-ai-stack/charts/dot-ai-ui-0.15.0.tgz
Normal file
BIN
charts/dot-ai-stack/charts/dot-ai-ui-0.15.0.tgz
Normal file
Binary file not shown.
23
charts/dot-ai-stack/charts/dot-ai-ui/Chart.yaml
Normal file
23
charts/dot-ai-stack/charts/dot-ai-ui/Chart.yaml
Normal 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
|
||||
101
charts/dot-ai-stack/charts/dot-ai-ui/templates/_helpers.tpl
Normal file
101
charts/dot-ai-stack/charts/dot-ai-ui/templates/_helpers.tpl
Normal 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 -}}
|
||||
@ -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
|
||||
52
charts/dot-ai-stack/charts/dot-ai-ui/templates/gateway.yaml
Normal file
52
charts/dot-ai-stack/charts/dot-ai-ui/templates/gateway.yaml
Normal 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 }}
|
||||
@ -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 }}
|
||||
45
charts/dot-ai-stack/charts/dot-ai-ui/templates/ingress.yaml
Normal file
45
charts/dot-ai-stack/charts/dot-ai-ui/templates/ingress.yaml
Normal 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 }}
|
||||
33
charts/dot-ai-stack/charts/dot-ai-ui/templates/secret.yaml
Normal file
33
charts/dot-ai-stack/charts/dot-ai-ui/templates/secret.yaml
Normal 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 }}
|
||||
20
charts/dot-ai-stack/charts/dot-ai-ui/templates/service.yaml
Normal file
20
charts/dot-ai-stack/charts/dot-ai-ui/templates/service.yaml
Normal 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
|
||||
110
charts/dot-ai-stack/charts/dot-ai-ui/values.yaml
Normal file
110
charts/dot-ai-stack/charts/dot-ai-ui/values.yaml
Normal 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"
|
||||
9
charts/dot-ai-stack/charts/dot-ai/Chart.lock
Normal file
9
charts/dot-ai-stack/charts/dot-ai/Chart.lock
Normal 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"
|
||||
31
charts/dot-ai-stack/charts/dot-ai/Chart.yaml
Normal file
31
charts/dot-ai-stack/charts/dot-ai/Chart.yaml
Normal 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
|
||||
25
charts/dot-ai-stack/charts/dot-ai/charts/dex/.helmignore
Normal file
25
charts/dot-ai-stack/charts/dot-ai/charts/dex/.helmignore
Normal 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
|
||||
29
charts/dot-ai-stack/charts/dot-ai/charts/dex/Chart.yaml
Normal file
29
charts/dot-ai-stack/charts/dot-ai/charts/dex/Chart.yaml
Normal 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
|
||||
202
charts/dot-ai-stack/charts/dot-ai/charts/dex/LICENSE
Normal file
202
charts/dot-ai-stack/charts/dot-ai/charts/dex/LICENSE
Normal 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.
|
||||
193
charts/dot-ai-stack/charts/dot-ai/charts/dex/README.md
Normal file
193
charts/dot-ai-stack/charts/dot-ai/charts/dex/README.md
Normal file
@ -0,0 +1,193 @@
|
||||
# dex
|
||||
|
||||
    [](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.
|
||||
@ -0,0 +1,10 @@
|
||||
config:
|
||||
issuer: https://my-issuer.com
|
||||
|
||||
storage:
|
||||
type: memory
|
||||
|
||||
enablePasswordDB: true
|
||||
|
||||
configSecret:
|
||||
name: my-super-special-dex-secret
|
||||
@ -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
|
||||
@ -0,0 +1,10 @@
|
||||
config:
|
||||
issuer: https://my-issuer.com
|
||||
|
||||
storage:
|
||||
type: memory
|
||||
|
||||
enablePasswordDB: true
|
||||
|
||||
configSecret:
|
||||
create: false
|
||||
@ -0,0 +1,7 @@
|
||||
config:
|
||||
issuer: https://my-issuer.com
|
||||
|
||||
storage:
|
||||
type: memory
|
||||
|
||||
enablePasswordDB: true
|
||||
@ -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 }}
|
||||
@ -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 }}
|
||||
@ -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 }}
|
||||
@ -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 }}
|
||||
@ -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 }}
|
||||
@ -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 }}
|
||||
@ -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 }}
|
||||
@ -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 }}
|
||||
@ -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 }}
|
||||
@ -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 }}
|
||||
@ -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 }}
|
||||
@ -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 }}
|
||||
@ -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 }}
|
||||
345
charts/dot-ai-stack/charts/dot-ai/charts/dex/values.yaml
Normal file
345
charts/dot-ai-stack/charts/dot-ai/charts/dex/values.yaml
Normal 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
|
||||
@ -0,0 +1,2 @@
|
||||
.git
|
||||
.github
|
||||
@ -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
|
||||
|
||||
22
charts/dot-ai-stack/charts/dot-ai/charts/qdrant/Chart.yaml
Normal file
22
charts/dot-ai-stack/charts/dot-ai/charts/qdrant/Chart.yaml
Normal 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
|
||||
201
charts/dot-ai-stack/charts/dot-ai/charts/qdrant/LICENSE
Normal file
201
charts/dot-ai-stack/charts/dot-ai/charts/qdrant/LICENSE
Normal 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.
|
||||
157
charts/dot-ai-stack/charts/dot-ai/charts/qdrant/README.md
Normal file
157
charts/dot-ai-stack/charts/dot-ai/charts/qdrant/README.md
Normal 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.
|
||||
@ -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 }}
|
||||
@ -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 -}}
|
||||
@ -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 }}
|
||||
@ -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 }}
|
||||
|
||||
@ -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
Loading…
x
Reference in New Issue
Block a user