diff --git a/canary-checker/docs/concepts/request-chaining.mdx b/canary-checker/docs/concepts/request-chaining.mdx new file mode 100644 index 00000000..f1499fee --- /dev/null +++ b/canary-checker/docs/concepts/request-chaining.mdx @@ -0,0 +1,90 @@ +--- +title: Request Chaining +sidebar_position: 5 +--- + +Request chaining allows you to create dependencies between checks within the same Canary, enabling complex multi-step verification workflows. A check can depend on other checks and access their output data through templating. + +## Use Cases + +- **Authentication flows**: Login first, then use the token for subsequent API calls +- **Multi-step API workflows**: Create a resource, then verify its state +- **Data-dependent checks**: Fetch configuration from one endpoint, use it in another + +## How It Works + +1. Define checks with unique names +2. Use `dependsOn` to specify which checks must complete first +3. Access previous check outputs via `outputs..` + +Checks are executed in topological order based on their dependencies, ensuring dependent checks only run after their prerequisites complete successfully. + +## Example + +```yaml title="http-depends-on.yaml" file=/modules/canary-checker/fixtures/minimal/http_depends_on_pass.yaml + +``` + +## Fields + + + +## Accessing Outputs + +When a check has dependencies, it can access the outputs from those checks using the `outputs` object: + +| Expression | Description | +|------------|-------------| +| `outputs..json` | Parsed JSON response body | +| `outputs..code` | HTTP response code | +| `outputs..headers` | Response headers | +| `outputs..body` | Raw response body | + +### Example: Using Previous Check Output + +```yaml +apiVersion: canaries.flanksource.com/v1 +kind: Canary +metadata: + name: auth-flow +spec: + schedule: "@every 5m" + http: + - name: login + url: https://api.example.com/auth/login + method: POST + body: '{"username": "user", "password": "pass"}' + test: + expr: "code == 200 && json.token != ''" + + - name: get-profile + url: https://api.example.com/profile + dependsOn: + - login + headers: + - name: Authorization + # Use the token from the login check + value: "Bearer $(.outputs.login.json.token)" + test: + expr: "code == 200" +``` + +## Execution Order + +Checks are automatically sorted using topological ordering based on their dependencies. If check B depends on check A, then: + +1. Check A executes first +2. If Check A succeeds, Check B executes with access to A's outputs +3. If Check A fails, Check B is skipped + +## Limitations + +- Circular dependencies are not allowed +- `dependsOn` only works within the same Canary resource +- All referenced check names must exist in the same Canary diff --git a/canary-checker/docs/partials/_gotemplate.md b/canary-checker/docs/partials/_gotemplate.md index e4a4ec5a..334f5805 100644 --- a/canary-checker/docs/partials/_gotemplate.md +++ b/canary-checker/docs/partials/_gotemplate.md @@ -20,7 +20,7 @@ If you need to pass a template through a Helm Chart and prevent Helm from templa {{`{{ .secret }}`}} ``` -Alternatively [change the templating delimiters](#delimiters) +Alternatively change the templating delimiters (see below) diff --git a/common/snippets/_resource-selector.mdx b/common/snippets/_resource-selector.mdx index a3fcb178..b1afbf20 100644 --- a/common/snippets/_resource-selector.mdx +++ b/common/snippets/_resource-selector.mdx @@ -1,104 +1,114 @@ import Link from '@docusaurus/Link'; -Resource Selectors are used in multiple places including: +Resource Selectors are used throughout Mission Control for: - Creating relationships between configs and configs/components -- Finding resources to run health checks or playbooks on - -| Field | Description | Scheme | Required | -| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | -------- | -| `id` | ID of the component | `string` | No | -| `name` | Name of the component/config | `string` | No | -| `namespace` | Select resources in this namespace only, if empty find resources in all namespaces | `string` | No | -| `types` | Match any of the types specified | `[]string` | No | -| `statuses` | Match any of the statuses specified | `[]string` | No | -| `labelSelector` | Kubernetes Style Label Selector | [LabelSelector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) | No | -| `fieldSelector` | Kubernetes Style Field Selector Property fields of the component in kubernetes format (or database columns: owner, topology_id, parent_id) | [FieldSelector](https://kubernetes.io/docs/concepts/overview/working-with-objects/field-selectors/) | No | -| `agent` | Select resources created on this agent, Defaults to `local` | `uuid`, `{name}`, `local` or `all` | No | -| `cache` | Cache settings to use for the results, expensive selectors or selectors that are used often should be cached for longer periods. Defaults to `max-age=10m` | `no-cache`, `no-store` or `max-age={duration}` | No | -| `search` | Search for resources via key value pairs using parsing expression grammar | [Search](#search) | No | - -### Search - -The query syntax is `field1=value1 field2>value2 field3=value3* field4=*value4`. `*` is for prefix and suffix matching. - -Supported operators: - -| Operator | Syntax | Types | -| -------- | -------------------------------- | --------------------- | -| `=` | `field=value` | `string` `int` `json` | -| `!=` | `field!=value` | `string` `int` `json` | -| `*` | `field=*value` or `field=value*` | `string` `int` | -| `>` `<` | `field>value` or `field` (cache for duration) | `string` | | +| `limit` | Maximum number of resources to return | `int` | | +| `includeDeleted`| Include soft-deleted resources in results. Defaults to `false` | `bool` | | +| `search` | Full-text search across resource name, tags, and labels using parsing expression grammar. See [Search](#search) | `string` | | + +## Wildcards and Negation + +The `name`, `id`, `types`, `statuses`, and `health` fields support: + +- **Prefix matching**: `name=prod-*` matches names starting with `prod-` +- **Suffix matching**: `name=*-backend` matches names ending with `-backend` +- **Negation**: `health=!unhealthy` excludes unhealthy resources +- **Multiple values**: `types=Kubernetes::Pod,Kubernetes::Deployment` matches either type + +## Search + +The `search` field provides a powerful query language for filtering resources. + +### Syntax ``` -# Find all Kubernetes namespaces starting with "kube" -type=Kubernetes::Namespace name=kube* +field1=value1 field2>value2 field3=value3* field4=*value4 +``` -# Find unhealthy AWS EC2 instances -type=AWS::EC2::Instance health=unhealthy +Multiple conditions are combined with AND logic. -# Find critical severity changes for AWS resources -type=AWS::* severity=critical +### Operators -# Find configs created in the last 24 hours -created_at>now-24h +| Operator | Example | Description | Types | +| -------- | -------------------------------- | ---------------------------------------------- | --------------------- | +| `=` | `status=healthy` | Equals (exact match or wildcard) | `string` `int` `json` | +| `!=` | `health!=unhealthy` | Not equals | `string` `int` `json` | +| `=*` | `name=*-prod` or `name=api-*` | Prefix or suffix match | `string` `int` | +| `>` | `created_at>now-24h` | Greater than | `datetime` `int` | +| `<` | `updated_at<2025-01-01` | Less than | `datetime` `int` | -# Find nginx pods with prod cluster tag -type=Kubernetes::Pod label.app=nginx tags.cluster=prod +### Date Queries + +- **Absolute dates**: `2025-01-15`, `2025-01-15T10:30:00Z` +- **Relative dates**: `now-24h`, `now-7d`, `now+1w` +- **Supported units**: `s` (seconds), `m` (minutes), `h` (hours), `d` (days), `w` (weeks), `y` (years) + +### JSON Field Access + +Access nested fields in labels, tags, and config using dot notation: -# Complex query with date range -updated_at>2025-01-01 updated_at<2025-01-31 type=Kubernetes::Deployment +``` +labels.app=nginx +tags.env=production +config.spec.replicas>3 ``` +### Searchable Fields + +#### Catalog Items (Configs) + +| Field | Type | Description | +| ------------ | ---------- | ------------------------------------- | +| `name` | `string` | Resource name | +| `namespace` | `string` | Kubernetes namespace or equivalent | +| `type` | `string` | Resource type (e.g., `Kubernetes::Pod`)| +| `status` | `string` | Current status | +| `health` | `string` | Health status | +| `source` | `string` | Source identifier | +| `agent` | `string` | Agent that scraped this resource | +| `labels` | `json` | Kubernetes-style labels | +| `tags` | `json` | Scraper-assigned tags | +| `config` | `json` | Full configuration data | +| `created_at` | `datetime` | Creation timestamp | +| `updated_at` | `datetime` | Last update timestamp | +| `deleted_at` | `datetime` | Soft deletion timestamp | + +#### Config Changes + +| Field | Type | Description | +| ---------------- | ---------- | ------------------------------------- | +| `id` | `string` | Change ID | +| `config_id` | `string` | Parent config ID | +| `name` | `string` | Change name | +| `type` | `string` | Config type | +| `change_type` | `string` | Type of change (e.g., `diff`, `event`)| +| `severity` | `string` | Change severity | +| `summary` | `string` | Change summary | +| `count` | `int` | Occurrence count | +| `agent_id` | `string` | Agent ID | +| `tags` | `json` | Change tags | +| `details` | `json` | Additional details | +| `created_at` | `datetime` | Change timestamp | +| `first_observed` | `datetime` | First observation time | {!props.hideCheck && ( Health Checks @@ -106,17 +116,119 @@ updated_at>2025-01-01 updated_at<2025-01-31 type=Kubernetes::Deployment {!props.hideCheck && ( )} + +## Examples + +### Basic Selection + +```yaml +# Select by exact name +name: my-deployment + +# Select by ID +id: 3b1a2c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d + +# Select all pods in a namespace +types: + - Kubernetes::Pod +namespace: production +``` + +### Using Wildcards + +```yaml +# Select all resources with names starting with "prod-" +name: prod-* + +# Select all AWS resources +types: + - AWS::* + +# Select resources ending with "-backend" +name: "*-backend" +``` + +### Label and Tag Selectors + +```yaml +# Select by labels (Kubernetes-style) +labelSelector: app=nginx,env in (prod,staging) + +# Select by tags +tagSelector: team=platform,cost-center!=shared + +# Combine both +labelSelector: app=api +tagSelector: environment=production +``` + +### Health and Status Filtering + +```yaml +# Select only healthy resources +health: healthy + +# Exclude unhealthy resources +health: "!unhealthy" + +# Select resources with specific statuses +statuses: + - Running + - Pending +``` + +### Search Queries + +```yaml +# Find all Kubernetes namespaces starting with "kube" +search: type=Kubernetes::Namespace name=kube* + +# Find unhealthy AWS EC2 instances +search: type=AWS::EC2::Instance health=unhealthy + +# Find configs created in the last 24 hours +search: created_at>now-24h + +# Find nginx pods with specific tags +search: type=Kubernetes::Pod labels.app=nginx tags.cluster=prod + +# Complex query with date range +search: updated_at>2025-01-01 updated_at<2025-01-31 type=Kubernetes::Deployment +``` + +### Multi-Agent Selection + +```yaml +# Select from a specific agent +agent: production-cluster + +# Select from all agents +agent: all + +# Select only local (agentless) resources +agent: local +``` + +### Scoped Selection + +```yaml +# Select configs from a specific scraper +scope: namespace/my-scraper + +# Select checks from a specific canary +scope: canary-uuid-here +``` diff --git a/common/src/components/CapabilityBadges.jsx b/common/src/components/CapabilityBadges.jsx index e9670ab4..cb2ee1a2 100644 --- a/common/src/components/CapabilityBadges.jsx +++ b/common/src/components/CapabilityBadges.jsx @@ -5,6 +5,7 @@ const capabilities = { scraper: { icon: ConfigDb, label: 'Scraper', + anchor: 'catalog', color: '#2563eb', bg: '#dbeafe', border: '#93c5fd' @@ -12,6 +13,7 @@ const capabilities = { healthcheck: { icon: Health, label: 'Health Check', + anchor: 'health-checks', color: '#d97706', bg: '#fef3c7', border: '#fcd34d' @@ -19,6 +21,7 @@ const capabilities = { playbook: { icon: Playbook, label: 'Playbook', + anchor: 'playbooks', color: '#7c3aed', bg: '#ede9fe', border: '#c4b5fd' @@ -26,6 +29,7 @@ const capabilities = { notifications: { icon: Bell, label: 'Notifications', + anchor: 'notifications', color: '#16a34a', bg: '#dcfce7', border: '#86efac' @@ -33,6 +37,7 @@ const capabilities = { actions: { icon: Webhook, label: 'Actions', + anchor: 'actions', color: '#4f46e5', bg: '#e0e7ff', border: '#a5b4fc' @@ -40,6 +45,7 @@ const capabilities = { 'relationship': { icon: ConfigDb, label: 'Relationship', + anchor: 'relationship', color: '#d97706', bg: '#fef3c7', border: '#fcd34d' @@ -80,7 +86,7 @@ export function CapabilityHeading({ type }) { const Icon = cap.icon; return ( -

+

{
Get Started @@ -375,7 +375,7 @@ const MissionControlPage = () => { image="flanksource/self-hosted.svg" title="Self-Hosted First" subtitle="SECURITY & CONTROL" - url="/docs/mission-control/installation" + url="/docs/installation" left={false} > Mission Control is self-hosted first, and easy to install using a Helm Chart. Self-Hosted, SaaS or Hybrid Deployment Models with no network or proxy access required and no secrets stored in the SaaS. @@ -385,7 +385,7 @@ const MissionControlPage = () => { image="flanksource/playbooks.svg" title="Playbooks & Automation" subtitle="DEVELOPER ENABLEMENT" - url="/docs/mission-control/playbooks" + url="/docs/guide/playbooks" left={true} > Empower developers to be more self-sufficient without the need to become experts in the Cloud and Kubernetes. Run playbooks automatically on failing health checks/alerts, implement security best practices of least privilege and just in time (JIT) access, and use the built-in library of actions. @@ -395,7 +395,7 @@ const MissionControlPage = () => { image="flanksource/status_pages.png" title="Deep Health Monitoring" subtitle="PROACTIVE OPERATIONS" - url="/docs/mission-control/canary-checker" + url="/docs/guide/canary-checker" left={false} > Understand the health of complex services at a glance with red, amber, green statuses which leverage active/passive health checks and consolidated alerts from Prometheus, AWS, Dynatrace, and more. @@ -706,7 +706,7 @@ const MissionControlPage = () => {
Read the Docs diff --git a/common/src/css/custom.css b/common/src/css/custom.css index 25b8b031..34013d22 100644 --- a/common/src/css/custom.css +++ b/common/src/css/custom.css @@ -79,7 +79,7 @@ li::marker { } li { - font: var(--ifm-font-sans) !important; + font-family: var(--ifm-font-sans) !important; } li > svg { @@ -573,7 +573,7 @@ pre { .navbar__link--active { color: var(--ifm-color-primary-light); - font: bold; + font-weight: bold; } a { diff --git a/mission-control-chart b/mission-control-chart index 2a91080d..ec6f642a 160000 --- a/mission-control-chart +++ b/mission-control-chart @@ -1 +1 @@ -Subproject commit 2a91080def4f14679f38331c6b0fe05f610380cd +Subproject commit ec6f642a3ac1ffcd18b9de323db9d5cd7eda949b diff --git a/mission-control/blog/control-plane-testing/index.mdx b/mission-control/blog/control-plane-testing/index.mdx index a1b5173c..1d8b2fbc 100644 --- a/mission-control/blog/control-plane-testing/index.mdx +++ b/mission-control/blog/control-plane-testing/index.mdx @@ -81,7 +81,7 @@ To follow this tutorial, you need: :::info Helm Installation - This tutorial uses the CLI for faster feedback, in production we recommend installing `canary-checker` as an operator using the [helm chart](https://canarychecker.io/getting-started) or as part of the full Mission Control [platform](/docs/installation/self-hosted/getting-started). + This tutorial uses the CLI for faster feedback, in production we recommend installing `canary-checker` as an operator using the [helm chart](https://canarychecker.io/getting-started) or as part of the full Mission Control [platform](/docs/installation/self-hosted). 1. Next create a `Canary` CustomResourceDefinition (CRD) using the `kubernetesResource` check type, the layout of the canary is as follows: ```yaml title=basic-canary.yaml file=template.yaml diff --git a/mission-control/blog/rust-ffi/index.mdx b/mission-control/blog/rust-ffi/index.mdx index 84d49927..c44289f5 100644 --- a/mission-control/blog/rust-ffi/index.mdx +++ b/mission-control/blog/rust-ffi/index.mdx @@ -11,6 +11,8 @@ For the past few years at [Flanksource](https://flanksource.com/), I've helped b One Tuesday afternoon, one of our pods started crashing with an OOM (OutOfMemory) error. +{/* truncate */} + > When a container exceeds its memory limit in Kubernetes, the system restarts it with an OutOfMemory message. Memory leaks can trigger a crash loop cycle. This issue occurred frequently enough to raise concerns, particularly since it only affected one customer's environment. diff --git a/mission-control/docs/guide/config-db/concepts/access-logs.mdx b/mission-control/docs/guide/config-db/concepts/access-logs.mdx new file mode 100644 index 00000000..c0ea5161 --- /dev/null +++ b/mission-control/docs/guide/config-db/concepts/access-logs.mdx @@ -0,0 +1,130 @@ +--- +title: Access Logs +sidebar_position: 6 +sidebar_custom_props: + icon: mdi:account-clock +--- + +Access logs track who accessed configuration items and when. This enables compliance auditing, security monitoring, and access reviews for your infrastructure. + +## Overview + +When scraping configurations from external systems, you can also capture access logs that record: + +- **Who** accessed a resource (external user) +- **What** was accessed (config item) +- **When** the access occurred +- **How** they authenticated (MFA status, properties) + +Access logs are stored separately from configuration data and can be queried independently for audit purposes. + +## Enabling Access Log Scraping + +To scrape access logs, set `full: true` on your scraper configuration: + +```yaml +apiVersion: configs.flanksource.com/v1 +kind: ScrapeConfig +metadata: + name: database-config +spec: + # highlight-next-line + full: true + # ... scraper configuration +``` + +When `full` mode is enabled, the scraper expects each configuration item to potentially include an `access_logs` field containing access records. + +## Access Log Schema + +Each access log entry should include: + + + +## Example: Custom Scraper with Access Logs + +```json title="config-with-access-logs.json" +{ + "id": "db-prod-001", + "config": { + "name": "production-database", + "engine": "postgres", + "version": "15.2" + }, + "access_logs": [ + { + "config_id": "db-prod-001", + "external_user_id": "user-123", + "created_at": "2025-01-08T10:30:00Z", + "mfa": true, + "properties": { + "ip_address": "192.168.1.100", + "client": "psql" + } + }, + { + "config_id": "db-prod-001", + "external_user_id": "user-456", + "created_at": "2025-01-08T11:45:00Z", + "mfa": false + } + ] +} +``` + +## Scrapers with Access Log Support + +The following scrapers support access log extraction when `full: true` is enabled: + +| Scraper | Use Case | +|---------|----------| +| [SQL](/docs/guide/config-db/scrapers/sql) | Database access logs from audit tables | +| [PostgreSQL](/docs/guide/config-db/scrapers/postgres) | PostgreSQL connection and query logs | +| [SQL Server](/docs/guide/config-db/scrapers/mssql) | SQL Server audit events | +| [Clickhouse](/docs/guide/config-db/scrapers/clickhouse) | Clickhouse query logs and S3 access | +| [HTTP](/docs/guide/config-db/scrapers/http) | API access logs from external systems | +| [File](/docs/guide/config-db/scrapers/file) | Access logs from log files | +| [Exec](/docs/guide/config-db/scrapers/exec) | Custom scripts that output access data | + +## External Users and Groups + +Access logs reference external users and groups that are also scraped from your systems. These entities enable: + +- **User identification**: Track individual user access across configs +- **Group membership**: Understand access patterns by team or role +- **Access reviews**: Audit who has access to what resources + +See the [SQL scraper](/docs/guide/config-db/scrapers/sql) for examples of scraping users, groups, and roles alongside access logs. + +## Related + +- [Config Access Reference](/docs/reference/config-db/config_access) - Access log schema details +- [Retention](/docs/guide/config-db/concepts/retention) - Configure access log retention policies diff --git a/mission-control/docs/guide/config-db/concepts/changes.md b/mission-control/docs/guide/config-db/concepts/changes.md index d2406e96..632a838b 100644 --- a/mission-control/docs/guide/config-db/concepts/changes.md +++ b/mission-control/docs/guide/config-db/concepts/changes.md @@ -24,3 +24,86 @@ External sources like Kubernetes Events and AWS CloudTrail provide these changes ![Event-based config changes of a Kubernetes Pod](/img/event-based-config-changes.png) See [Transformation Changes](./transform#changes). + +## Extracting Changes + +Custom scrapers can ingest changes from external systems when you enable the `full` option. This separates config data from change events in your source. + +When `full: true` is set, the scraper expects each config item to have these top-level fields: + +- `config` - The actual configuration data to store +- `changes` - An array of change events +- `access_logs` - Access log entries (see [Access Logs](/docs/guide/config-db/concepts/access-logs)) + +:::note +Fields other than these are ignored. Missing fields are treated as empty. +::: + +### Example + +Consider a file containing: + +```json title="fixtures/data/car.json" +{ + "reg_no": "A123", + "config": { + "meta": "this is the actual config that'll be stored." + }, + "changes": [ + { + "change_type": "drive", + "summary": "car color changed to blue", + "created_at": "2025-01-01T10:00:00Z" + } + ], + "access_logs": [ + { + "external_user_id": "user-123", + "created_at": "2025-01-01" + } + ] +} +``` + +With `full: true`: + +```yaml +apiVersion: configs.flanksource.com/v1 +kind: ScrapeConfig +metadata: + name: file-scraper +spec: + full: true + file: + - type: Car + id: $.reg_no + paths: + - fixtures/data/car.json +``` + +The scraper stores only the `config` object: + +```json +{ + "meta": "this is the actual config that'll be stored." +} +``` + +And records the change event separately on that config item. + +### Change Schema + +| Field | Description | Scheme | +| -------------------- | --------------------------------------- | -------------------- | +| `change_type` | Type of the change | `string` | +| `action` | Action of the change | `delete` or `ignore` | +| `summary` | Summary of the change | `string` | +| `severity` | Severity of the change | `string` | +| `source` | Source of the change | `string` | +| `created_at` | Creation time of the change | `time.Time` | +| `created_by` | User who created the change | `string` | +| `external_change_id` | ID of the change in the external system | `string` | +| `external_id` | ID of the change | `string` | +| `details` | Additional details | `map[string]any` | +| `diff` | Diff of the change | `string` | +| `patches` | Patches of the change | `string` | diff --git a/mission-control/docs/guide/config-db/concepts/plugins.mdx b/mission-control/docs/guide/config-db/concepts/plugins.mdx index 01df678f..d81f93c0 100644 --- a/mission-control/docs/guide/config-db/concepts/plugins.mdx +++ b/mission-control/docs/guide/config-db/concepts/plugins.mdx @@ -37,8 +37,12 @@ For example, if you want to exclude all events with severity="info", a scrape pl field: 'changes.mapping', description: 'Categorize changes', scheme: '[Mapping](#mapping)' + }, + { + field: 'retention', + description: 'Global retention settings for config items and changes', + scheme: '[Retention](./retention)' } - ]} /> @@ -74,3 +78,27 @@ For example, the change 'status.images' might not be self-explanatory. To clarif } ]} /> + +### Retention + +Scrape plugins can define global retention policies that are merged with individual scraper retention settings. This is useful for enforcing organization-wide retention policies. + +```yaml +apiVersion: configs.flanksource.com/v1 +kind: ScrapePlugin +metadata: + name: global-retention +spec: + retention: + changes: + - name: PullSucceeded + age: 7d + - name: diff + age: 30d + types: + - name: Kubernetes::Pod + deletedAge: 7d + staleItemAge: 24h +``` + +When a scraper runs, retention settings from all applicable plugins are merged with the scraper's own retention configuration. See [Retention](./retention) for the full schema. diff --git a/mission-control/docs/guide/config-db/scrapers/_custom.mdx b/mission-control/docs/guide/config-db/scrapers/_custom.mdx index 05352cca..eb8c245b 100644 --- a/mission-control/docs/guide/config-db/scrapers/_custom.mdx +++ b/mission-control/docs/guide/config-db/scrapers/_custom.mdx @@ -95,97 +95,4 @@ The UI formats and renders XML appropriately. ## Extracting Changes & Access Logs -Custom scrapers ingest changes & access logs from external systems when you enable the `full` option. - -Every single config is expected to have at these 3 top-level fields - -- `config` -- `changes` -- `access_logs` - -:::note info -They could have more fields or even missing some of these fields. -The point is that only these fields are extracted. -::: - -Consider a file that contains the following json data. - -```json title=fixtures/data/car.json {3,6,13} -{ - "reg_no": "A123", - "config": { - "meta": "this is the actual config that'll be stored." - }, - "changes": [ - { - "action": "drive", - "summary": "car color changed to blue", - "unrelated_stuff": 123 - } - ], - "access_logs": [ - { - "config_id": "99024949-9118-4dcb-a3a0-b8f1536bebd0", - "external_user_id": "a3542241-4750-11f0-8000-e0146ce375e6", - "created_at": "2025-01-01" - }, - { - "config_id": "9d9e51a7-6956-413e-a07e-a6aeb3f4877f", - "external_user_id": "a5c2e8e3-4750-11f0-8000-f4eaacabd632", - "created_at": "2025-01-02" - } - ] -} -``` - -A regular scraper saves the entire json as a config. -However, with the `full` option, the scraper extracts the config, changes and access logs. - -```yaml {6} -apiVersion: configs.flanksource.com/v1 -kind: ScrapeConfig -metadata: - name: file-scraper -spec: - full: true - file: - - type: Car - id: $.reg_no - paths: - - fixtures/data/car_changes.json -``` - -The resulting config is: - -```json -{ - "meta": "this is the actual config that'll be stored." -} -``` - -and the scraper records the following new config change on that config: - -```json -{ - "action": "drive", - "summary": "car color changed to blue", - "unrelated_stuff": 123 -} -``` - -and the access logs will be saved to - -```json -[ - { - "config_id": "99024949-9118-4dcb-a3a0-b8f1536bebd0", - "external_user_id": "a3542241-4750-11f0-8000-e0146ce375e6", - "created_at": "2025-01-01" - }, - { - "config_id": "9d9e51a7-6956-413e-a07e-a6aeb3f4877f", - "external_user_id": "a5c2e8e3-4750-11f0-8000-f4eaacabd632", - "created_at": "2025-01-02" - } -] -``` +When you enable `full: true`, custom scrapers can ingest [changes](/docs/guide/config-db/concepts/changes#extracting-changes) and [access logs](/docs/guide/config-db/concepts/access-logs) from external systems by separating the config data from change events in your source. diff --git a/mission-control/docs/guide/config-db/scrapers/aws.mdx b/mission-control/docs/guide/config-db/scrapers/aws.mdx index 865657c7..281554de 100644 --- a/mission-control/docs/guide/config-db/scrapers/aws.mdx +++ b/mission-control/docs/guide/config-db/scrapers/aws.mdx @@ -1,6 +1,6 @@ --- title: AWS -sidebar_position: 1 +sidebar_position: 2 sidebar_custom_props: icon: aws --- diff --git a/mission-control/docs/guide/config-db/scrapers/azure-devops.mdx b/mission-control/docs/guide/config-db/scrapers/azure-devops.mdx index 58162ffe..2bd77af6 100644 --- a/mission-control/docs/guide/config-db/scrapers/azure-devops.mdx +++ b/mission-control/docs/guide/config-db/scrapers/azure-devops.mdx @@ -1,6 +1,6 @@ --- title: Azure Devops -sidebar_position: 3 +sidebar_position: 4 sidebar_custom_props: icon: azure-devops --- diff --git a/mission-control/docs/guide/config-db/scrapers/azure.md b/mission-control/docs/guide/config-db/scrapers/azure.md index bbf2ca6d..0a86cb04 100644 --- a/mission-control/docs/guide/config-db/scrapers/azure.md +++ b/mission-control/docs/guide/config-db/scrapers/azure.md @@ -1,6 +1,6 @@ --- title: Azure -sidebar_position: 2 +sidebar_position: 3 sidebar_custom_props: icon: azure --- diff --git a/mission-control/docs/guide/config-db/scrapers/clickhouse.mdx b/mission-control/docs/guide/config-db/scrapers/clickhouse.mdx index 5aa8a08a..81e73832 100644 --- a/mission-control/docs/guide/config-db/scrapers/clickhouse.mdx +++ b/mission-control/docs/guide/config-db/scrapers/clickhouse.mdx @@ -1,14 +1,14 @@ --- title: Clickhouse -sidebar_position: 7 +sidebar_position: 5 show_title: false sidebar_custom_props: - icon: clickhouse-icon + icon: simple-icons:clickhouse --- import Custom from './_custom.mdx' -# Clickhouse +# Clickhouse @@ -299,7 +299,7 @@ spec: ## Query Log for Access Tracking -Use the system.query_log table to track who accessed what data: +Use the system.query_log table to track who accessed what data. See [Access Logs](/docs/guide/config-db/concepts/access-logs) for more details on the access log schema. ```yaml title="clickhouse-access-logs.yaml" apiVersion: configs.flanksource.com/v1 diff --git a/mission-control/docs/guide/config-db/scrapers/exec.mdx b/mission-control/docs/guide/config-db/scrapers/exec.mdx new file mode 100644 index 00000000..0c46681e --- /dev/null +++ b/mission-control/docs/guide/config-db/scrapers/exec.mdx @@ -0,0 +1,124 @@ +--- +title: Exec +sidebar_position: 6 +sidebar_custom_props: + icon: console + +--- + +import Custom from './_custom.mdx' + + + +The `exec` scraper runs a script and scrapes the output as configuration items. This is useful for custom integrations where you need to fetch configuration from external systems using scripts. + +```yaml title='exec-scraper.yaml' +apiVersion: configs.flanksource.com/v1 +kind: ScrapeConfig +metadata: + name: exec-scraper +spec: + schedule: "@every 1h" + exec: + - type: $.type + id: $.id + name: $.name + script: | + #!/bin/bash + curl -s https://api.example.com/configs | jq '[.[] | {id: .id, type: "API::Config", name: .name, config: .}]' +``` + +
+ +```yaml title='exec-backstage-catalog.yaml' file=/modules/config-db/fixtures/exec-backstage-catalog.yaml + +``` + +
+ +## Scraper + +| Field | Description | Scheme | Required | +| ----------- | ---------------------------------------------------------------------------------- | -------------------------------------------- | -------- | +| `schedule` | Specify the interval to scrape in cron format. Defaults to every 60 minutes. | `string` | | +| `full` | Set to `true` to extract [changes](/docs/guide/config-db/concepts/changes#extracting-changes) and [access logs](/docs/guide/config-db/concepts/access-logs) from scraped configurations. Defaults to `false`. | `bool` | | +| `retention` | Settings for retaining changes, analysis and scraped items | [`Retention`](/docs/guide/config-db/concepts/retention) | | +| `exec` | Specifies the list of Exec configurations to scrape. | [`[]Exec`](#exec) | | +| `logLevel` | Specify the level of logging. | `string` | | + +### Exec + + + +## Setup + +The `setup` field allows you to automatically install runtime environments before executing your script. This is useful when your script requires specific versions of Bun or Python. + + + +### RuntimeSetup + + + +### Python with Inline Dependencies + +For Python scripts, you can declare dependencies inline using [PEP 723 inline script metadata](https://packaging.python.org/en/latest/specifications/inline-script-metadata/). The `uv` package manager is used to manage Python environments. + +```yaml +exec: + - script: | + #!/usr/bin/env python3 + # /// script + # dependencies = [ + # "pyyaml", + # "requests", + # ] + # /// + + import yaml + import json + # Your script logic here + print(json.dumps([{"id": "1", "type": "Example", "name": "test"}])) + setup: + python: + version: "3.10.19" +``` + + diff --git a/mission-control/docs/guide/config-db/scrapers/file.mdx b/mission-control/docs/guide/config-db/scrapers/file.mdx index fc29e3cd..85342e14 100644 --- a/mission-control/docs/guide/config-db/scrapers/file.mdx +++ b/mission-control/docs/guide/config-db/scrapers/file.mdx @@ -1,5 +1,6 @@ --- title: File +sidebar_position: 7 sidebar_custom_props: icon: pepicons-pencil:file-loop @@ -34,7 +35,7 @@ spec: | Field | Description | Scheme | Required | | ----------- | ---------------------------------------------------------------------------------- | -------------------------------------------- | -------- | | `schedule` | Specify the interval to scrape in cron format. Defaults to every 60 minutes. | `string` | | -| `full` | Set to `true` to extract changes & access logs from scraped configurations. Defaults to `false`. | `bool` | | +| `full` | Set to `true` to extract [changes](/docs/guide/config-db/concepts/changes#extracting-changes) and [access logs](/docs/guide/config-db/concepts/access-logs) from scraped configurations. Defaults to `false`. | `bool` | | | `retention` | Settings for retaining changes, analysis and scraped items | [`Retention`](/docs/guide/config-db/concepts/retention) | | | `file` | Specifies the list of File configurations to scrape. | [`[]File`](#file) | | | `logLevel` | Specify the level of logging. | `string` | | diff --git a/mission-control/docs/guide/config-db/scrapers/gcp.mdx b/mission-control/docs/guide/config-db/scrapers/gcp.mdx index daf8b99f..3fde2a08 100644 --- a/mission-control/docs/guide/config-db/scrapers/gcp.mdx +++ b/mission-control/docs/guide/config-db/scrapers/gcp.mdx @@ -1,6 +1,6 @@ --- title: GCP -sidebar_position: 2 +sidebar_position: 8 sidebar_custom_props: icon: google-cloud --- diff --git a/mission-control/docs/guide/config-db/scrapers/github.md b/mission-control/docs/guide/config-db/scrapers/github.md index aa5a771e..6284ee1a 100644 --- a/mission-control/docs/guide/config-db/scrapers/github.md +++ b/mission-control/docs/guide/config-db/scrapers/github.md @@ -1,7 +1,7 @@ --- title: Github show_title: false -sidebar_position: 4 +sidebar_position: 9 sidebar_custom_props: icon: github --- diff --git a/mission-control/docs/guide/config-db/scrapers/http.mdx b/mission-control/docs/guide/config-db/scrapers/http.mdx index c1589f07..9f669198 100644 --- a/mission-control/docs/guide/config-db/scrapers/http.mdx +++ b/mission-control/docs/guide/config-db/scrapers/http.mdx @@ -1,6 +1,6 @@ --- title: HTTP -sidebar_position: 4 +sidebar_position: 10 sidebar_custom_props: icon: http --- @@ -22,7 +22,7 @@ The HTTP scraper allows you to collect data from HTTP endpoints and APIs. It sup | `retention` | Settings for retaining changes, analysis and scraped items | [`Retention`](/docs/guide/config-db/concepts/retention) | | | `http` | Specifies the list of HTTP configurations to scrape. | [`[]HTTP`](#http-configuration) | | | `logLevel` | Specify the level of logging. | `string` | | -| `full` | Set to `true` to extract changes & access logs from scraped configurations. Defaults to `false`. | `bool` | | +| `full` | Set to `true` to extract [changes](/docs/guide/config-db/concepts/changes#extracting-changes) and [access logs](/docs/guide/config-db/concepts/access-logs) from scraped configurations. Defaults to `false`. | `bool` | | ## HTTP Configuration diff --git a/mission-control/docs/guide/config-db/scrapers/index.mdx b/mission-control/docs/guide/config-db/scrapers/index.mdx index 57f32ad5..9b937baf 100644 --- a/mission-control/docs/guide/config-db/scrapers/index.mdx +++ b/mission-control/docs/guide/config-db/scrapers/index.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 3 +sidebar_position: 1 title: Scrapers sidebar_custom_props: icon: scraper diff --git a/mission-control/docs/guide/config-db/scrapers/kubernetes-file.mdx b/mission-control/docs/guide/config-db/scrapers/kubernetes-file.mdx index ede7ce00..836f92d8 100644 --- a/mission-control/docs/guide/config-db/scrapers/kubernetes-file.mdx +++ b/mission-control/docs/guide/config-db/scrapers/kubernetes-file.mdx @@ -1,5 +1,6 @@ --- title: Kubernetes File +sidebar_position: 12 sidebar_custom_props: icon: k8s-pod --- diff --git a/mission-control/docs/guide/config-db/scrapers/kubernetes.mdx b/mission-control/docs/guide/config-db/scrapers/kubernetes.mdx index fda21439..3b50476f 100644 --- a/mission-control/docs/guide/config-db/scrapers/kubernetes.mdx +++ b/mission-control/docs/guide/config-db/scrapers/kubernetes.mdx @@ -1,6 +1,6 @@ --- title: Kubernetes -sidebar_position: 4 +sidebar_position: 11 sidebar_custom_props: icon: k8s --- diff --git a/mission-control/docs/guide/config-db/scrapers/logs.mdx b/mission-control/docs/guide/config-db/scrapers/logs.mdx index 6027866c..5144e391 100644 --- a/mission-control/docs/guide/config-db/scrapers/logs.mdx +++ b/mission-control/docs/guide/config-db/scrapers/logs.mdx @@ -1,12 +1,10 @@ --- title: Logs -sidebar_position: 8 +sidebar_position: 13 sidebar_custom_props: icon: logs --- -import Custom from './_custom.mdx' - # Logs @@ -32,89 +30,149 @@ The Logs scraper queries log aggregation systems to extract configuration change ### Logs - -### LokiConfig +## Field Mapping + +Different log systems use different field names for the same data. For example: +- **Timestamp**: Elasticsearch uses `@timestamp`, Loki uses `ts`, CloudWatch uses `timestamp` +- **Message**: Some systems use `message`, others use `msg`, `log`, or `text` +- **Severity**: Could be `level`, `severity`, `log_level`, or `priority` + +Field mapping normalizes these differences so your transform expressions work consistently regardless of the log source. + +### How It Works - + +```yaml +apiVersion: configs.flanksource.com/v1 +kind: ScrapeConfig +metadata: + name: unified-app-logs +spec: + logs: + # OpenSearch/Elasticsearch logs use @timestamp and message + - openSearch: + url: https://elasticsearch:9200 + index: app-logs-* + fieldMapping: + timestamp: ['@timestamp'] + message: ['message'] + severity: ['level', 'log.level'] + id: ['trace.id', 'request_id'] + + # Loki logs use different field names + - loki: + url: http://loki:3100 + query: '{app="myservice"}' + fieldMapping: + timestamp: ['ts', 'timestamp'] + message: ['line', 'msg'] + severity: ['level', 'detected_level'] + id: ['traceID'] +``` + + + +### BigQuery + + -### GCPCloudLoggingConfig +
-/modules/config-db/fixtures/bigquery-logs.yaml +``` + +
+ +### GCPCloudLogging + + -### OpenSearchConfig +
+ +```yaml +apiVersion: configs.flanksource.com/v1 +kind: ScrapeConfig +metadata: + name: gcp-audit-logs +spec: + logs: + - gcpCloudLogging: + project: my-gcp-project + filter: | + protoPayload.serviceName="compute.googleapis.com" + protoPayload.methodName:"compute.instances" + orderBy: timestamp desc + pageSize: 100 + transform: + expr: | + dyn(config.logs).map(line, { + "changes": [{ + "change_type": "GCPResourceChange", + "external_id": line.resource.labels.instance_id, + "config_type": "GCP::Instance", + "created_at": line.timestamp, + "summary": line.protoPayload.methodName + }] + }).toJSON() +``` + +
+ +### Loki - -### BigQueryConfig +
-/modules/config-db/fixtures/logs-app-config-changes.yaml +``` + +
+ +### OpenSearch + + - -### FieldMappingConfig - - - - -## Configuration Examples - -### Loki Integration - -```yaml title="loki-config-changes.yaml" file=/modules/config-db/fixtures/logs-app-config-changes.yaml -``` - -### BigQuery Log Analysis - -```yaml title="bigquery-github-commits.yaml" file=/modules/config-db/fixtures/bigquery-logs.yaml -``` - -### GCP Cloud Logging - -```yaml -apiVersion: configs.flanksource.com/v1 -kind: ScrapeConfig -metadata: - name: gcp-audit-logs -spec: - logs: - - gcpCloudLogging: - project: my-gcp-project - filter: | - protoPayload.serviceName="compute.googleapis.com" - protoPayload.methodName:"compute.instances" - orderBy: timestamp desc - pageSize: 100 - transform: - expr: | - dyn(config.logs).map(line, { - "changes": [{ - "change_type": "GCPResourceChange", - "external_id": line.resource.labels.instance_id, - "config_type": "GCP::Instance", - "created_at": line.timestamp, - "summary": line.protoPayload.methodName - }] - }).toJSON() -``` - -### OpenSearch Log Mining +
```yaml apiVersion: configs.flanksource.com/v1 @@ -324,4 +359,4 @@ spec: id: ['event_id', 'transaction_id'] ``` -The Logs scraper provides powerful integration with various log aggregation systems, enabling you to transform log data into actionable configuration insights and change tracking. +
diff --git a/mission-control/docs/guide/config-db/scrapers/mssql.mdx b/mission-control/docs/guide/config-db/scrapers/mssql.mdx index 5c4f0e4b..8a608b39 100644 --- a/mission-control/docs/guide/config-db/scrapers/mssql.mdx +++ b/mission-control/docs/guide/config-db/scrapers/mssql.mdx @@ -1,6 +1,6 @@ --- title: SQL Server -sidebar_position: 6.2 +sidebar_position: 14 sidebar_custom_props: icon: sqlserver --- @@ -461,7 +461,7 @@ spec: ## SQL Server Audit Logs -If SQL Server Audit is configured, scrape audit events: +If SQL Server Audit is configured, scrape audit events. See [Access Logs](/docs/guide/config-db/concepts/access-logs) for more details on the access log schema. ```yaml title="mssql-audit.yaml" apiVersion: configs.flanksource.com/v1 diff --git a/mission-control/docs/guide/config-db/scrapers/postgres.mdx b/mission-control/docs/guide/config-db/scrapers/postgres.mdx index 7d4c6240..39fdf366 100644 --- a/mission-control/docs/guide/config-db/scrapers/postgres.mdx +++ b/mission-control/docs/guide/config-db/scrapers/postgres.mdx @@ -1,6 +1,6 @@ --- title: PostgreSQL -sidebar_position: 6.1 +sidebar_position: 15 sidebar_custom_props: icon: postgres --- @@ -405,7 +405,7 @@ spec: ## Audit with pg_audit -If you have pg_audit installed, scrape audit logs: +If you have pg_audit installed, scrape audit logs. See [Access Logs](/docs/guide/config-db/concepts/access-logs) for more details on the access log schema. ```yaml title="postgres-audit.yaml" apiVersion: configs.flanksource.com/v1 diff --git a/mission-control/docs/guide/config-db/scrapers/pubsub.mdx b/mission-control/docs/guide/config-db/scrapers/pubsub.mdx index 315c2960..2789be33 100644 --- a/mission-control/docs/guide/config-db/scrapers/pubsub.mdx +++ b/mission-control/docs/guide/config-db/scrapers/pubsub.mdx @@ -1,13 +1,13 @@ --- title: PubSub -sidebar_position: 9 +sidebar_position: 16 sidebar_custom_props: - icon: pubsub + icon: gcp-pubsub --- import Custom from './_custom.mdx' -# PubSub +# PubSub diff --git a/mission-control/docs/guide/config-db/scrapers/slack.mdx b/mission-control/docs/guide/config-db/scrapers/slack.mdx index ad46c7bd..3824d8a2 100644 --- a/mission-control/docs/guide/config-db/scrapers/slack.mdx +++ b/mission-control/docs/guide/config-db/scrapers/slack.mdx @@ -1,6 +1,6 @@ --- title: Slack -sidebar_position: 6 +sidebar_position: 17 sidebar_custom_props: icon: slack --- diff --git a/mission-control/docs/guide/config-db/scrapers/sql.mdx b/mission-control/docs/guide/config-db/scrapers/sql.mdx index 23eb50ed..ecaf9a7c 100644 --- a/mission-control/docs/guide/config-db/scrapers/sql.mdx +++ b/mission-control/docs/guide/config-db/scrapers/sql.mdx @@ -1,6 +1,6 @@ --- title: SQL -sidebar_position: 6 +sidebar_position: 18 sidebar_custom_props: icon: database --- @@ -47,9 +47,9 @@ The SQL scraper executes queries against relational databases and creates config | ----------- | ---------------------------------------------------------------------------------- | -------------------------------------------------- | -------- | | `logLevel` | Specify the level of logging | `string` | | | `schedule` | Scrape interval in cron format. Defaults to every 60 minutes | [Cron](/docs/reference/types#cron) | | -| `full` | Extract changes, access logs, users, groups from scraped configurations | `bool` | | +| `full` | Extract [changes](/docs/guide/config-db/concepts/changes#extracting-changes), [access logs](/docs/guide/config-db/concepts/access-logs), users, groups from scraped configurations | `bool` | | | `retention` | Settings for retaining changes, analysis and scraped items | [`Retention`](/docs/guide/config-db/concepts/retention) | | -| `sql` | List of SQL configurations to scrape | [`[]SQL`](#sql-1) | | +| `sql` | List of SQL configurations to scrape | [`[]SQL`](#sql) | | ### SQL diff --git a/mission-control/docs/guide/config-db/scrapers/terraform.mdx b/mission-control/docs/guide/config-db/scrapers/terraform.mdx index 35df2573..cbfdcf38 100644 --- a/mission-control/docs/guide/config-db/scrapers/terraform.mdx +++ b/mission-control/docs/guide/config-db/scrapers/terraform.mdx @@ -1,6 +1,6 @@ --- title: Terraform -sidebar_position: 10 +sidebar_position: 19 sidebar_custom_props: icon: terraform --- diff --git a/mission-control/docs/guide/config-db/scrapers/trivy.mdx b/mission-control/docs/guide/config-db/scrapers/trivy.mdx index f1dba7d9..4dfb4273 100644 --- a/mission-control/docs/guide/config-db/scrapers/trivy.mdx +++ b/mission-control/docs/guide/config-db/scrapers/trivy.mdx @@ -1,6 +1,6 @@ --- title: Trivy -sidebar_position: 5 +sidebar_position: 20 sidebar_custom_props: icon: trivy --- diff --git a/mission-control/docs/guide/notifications/channels/index.md b/mission-control/docs/guide/notifications/channels/index.md index 6345d410..0a475310 100644 --- a/mission-control/docs/guide/notifications/channels/index.md +++ b/mission-control/docs/guide/notifications/channels/index.md @@ -23,7 +23,6 @@ When creating a notification you can either specify a connection or a custom URL | [Mattermost](./mattermost) | _mattermost://[__`username`__@]**`mattermost-host`**/**`token`**[/__`channel`__]_ | | [Matrix](./matrix) | _matrix://**`username`**:**`password`**@**`host`**:**`port`**/[?rooms=**`!roomID1`**[,__`roomAlias2`__]]_ | | [Ntfy](./ntfy) | _ntfy://**`username`**:**`password`**@ntfy.sh/**`topic`**_ | -| [OpsGenie](./opsgenie) | _opsgenie://**`host`**/token?responders=**`responder1`**[,__`responder2`__]_ | | [Pushbullet](./pushbullet) | _pushbullet://**`api-token`**[/__`device`__/#__`channel`__/__`email`__]_ | | [Pushover](./pushover) | _pushover://shoutrrr:**`apiToken`**@**`userKey`**/?devices=**`device1`**[,__`device2`__, ...]_ | | [Rocketchat](./rocketchat) | _rocketchat://[__`username`__@]**`rocketchat-host`**/**`token`**[/__`channel`|`@recipient`__]_ | diff --git a/mission-control/docs/guide/notifications/channels/opsgenie.mdx b/mission-control/docs/guide/notifications/channels/opsgenie.mdx deleted file mode 100644 index b39c4eea..00000000 --- a/mission-control/docs/guide/notifications/channels/opsgenie.mdx +++ /dev/null @@ -1,112 +0,0 @@ ---- -sidebar_custom_props: - icon: logos:opsgenie ---- - - - -# OpsGenie - -:::info URL Format - opsgenie://api.opsgenie.com/**`apiKey`** -::: - - -import Fields from '@site/src/components/Fields'; - - - - - -## Creating an API Key - -1. Navigate to **Settings** → **Integration List** - -2. Click **API** → **Add** - -3. Check *Create and Update Access* and *Enabled* - -3. Click **Save Integration** - -4. Copy the *API Key* - - diff --git a/mission-control/docs/guide/permissions/actions.mdx b/mission-control/docs/guide/permissions/actions.mdx new file mode 100644 index 00000000..f35adf80 --- /dev/null +++ b/mission-control/docs/guide/permissions/actions.mdx @@ -0,0 +1,144 @@ +--- +title: Actions +sidebar_position: 4 +sidebar_custom_props: + icon: cog +--- + +Actions define what operations a subject can perform on the target objects. The `actions` field is required and accepts a list of action strings. + +## Available Actions + +| Action | Description | +|--------|-------------| +| `read` | Allows reading/viewing resources | +| `write` | Allows creating or modifying resources | +| `delete` | Allows deleting resources | +| `playbook:run` | Allows running playbooks | +| `playbook:approve` | Allows approving playbook runs that require approval | +| `playbook:cancel` | Allows canceling playbook runs | + +## Wildcards + +You can use wildcards to grant multiple permissions at once: + +| Wildcard | Description | +|----------|-------------| +| `playbook:*` | Grants all playbook-related permissions (run, approve, cancel) | +| `*` | Grants all permissions (use with caution) | + +## Examples + +
+
+ +```yaml title="read-only-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: viewer-access +spec: + description: Read-only access to configs + subject: + team: viewers + actions: + - read + object: + configs: + - name: "*" +``` + +
+
+ +
+
+ +```yaml title="playbook-full-access.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: playbook-admin +spec: + description: Full playbook management access + subject: + team: platform-team + actions: + - playbook:* + object: + playbooks: + - name: "*" +``` + +
+
+ +
+
+ +```yaml title="multiple-actions.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: editor-access +spec: + description: Read and write access to configs + subject: + person: editor@example.com + actions: + - read + - write + object: + configs: + - namespace: production +``` + +
+
+ +
+
+ +```yaml title="run-approve-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: playbook-operator +spec: + description: Allow running and approving playbooks + subject: + team: operators + actions: + - playbook:run + - playbook:approve + object: + playbooks: + - labels: + category: maintenance +``` + +
+
+ +
+
+ +```yaml title="admin-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: admin-all-access +spec: + description: Full admin access (use sparingly) + subject: + team: admins + actions: + - "*" +``` + +:::warning +Using `*` (all permissions) should be limited to administrative roles. Always prefer granting the minimum necessary permissions. +::: + +
+
diff --git a/mission-control/docs/guide/permissions/concepts/abac.md b/mission-control/docs/guide/permissions/concepts/abac.md deleted file mode 100644 index 8c1a741d..00000000 --- a/mission-control/docs/guide/permissions/concepts/abac.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: ABAC -sidebar_position: 2 ---- - -Attribute-Based Access Control (ABAC) is another security model you can use in Mission Control when RBAC falls short. -It is a security model that conditionally grants access to resources based on attributes. -In Mission Control, these attributes relate to the resource that the user accesses: example: - -- the tags -- the namespace -- name patterns (example: begins with test-) - -:::info -The models are not mutually exclusive. Mission Control supports both RBAC and ABAC. -::: - -Example use cases: - -- Allow a person to run a playbook but only if the playbook is on a certain namespace -- Deny a person from running a playbook in the Kubernetes category -- Allow a notification to run a particular playbook. - -```yaml title="deny-person-playbook.yaml" file=/modules/mission-control/fixtures/permissions/deny-person-playbook.yaml - -``` diff --git a/mission-control/docs/guide/permissions/concepts/index.md b/mission-control/docs/guide/permissions/concepts/index.md deleted file mode 100644 index ceff60ec..00000000 --- a/mission-control/docs/guide/permissions/concepts/index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -sidebar_position: 3 -title: Concepts -sidebar_custom_props: - icon: concepts ---- - -import DocCardList from '@theme/DocCardList'; - - diff --git a/mission-control/docs/guide/permissions/concepts/multi-tenancy.md b/mission-control/docs/guide/permissions/concepts/multi-tenancy.md deleted file mode 100644 index 34923693..00000000 --- a/mission-control/docs/guide/permissions/concepts/multi-tenancy.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: Multi Tenancy -sidebar_position: 3 ---- - -Mission Control provides sophisticated access control mechanisms for complex deployment scenarios, particularly in Software-as-a-Service (SaaS) environments where multiple tenants or organizations share the same infrastructure. -Two key features enable fine-grained access control in these scenarios: Agent-based permissions and Tag-based permissions. - -### Agent based permission - -Mission Control often acts as a central hub receiving data from multiple agents deployed across different environments. Each agent pushes its own set of resources, including catalogs and topologies, to the central Mission Control instance. While all these resources are accessible through a unified UI portal, organizations frequently need to restrict user access to specific agent-sourced data. -Agent-based ABAC addresses this requirement by allowing administrators to create permissions that reference specific agents. -For example, you might have: - -- Development teams that should only access resources from their development environment agents -- Regional teams that should only see resources from agents in their geographic location -- Client-specific teams that should only interact with agents deployed in their infrastructure - -```yaml - -``` - -### Tag based permission - -Tag-based permissions provide another layer of access control granularity by allowing administrators to restrict access based on resource tags. -This approach is particularly powerful for managing access in multi-cluster Kubernetes environments. -Tags can represent various attributes such as: - -- Environment (production, staging, development) -- Geographic region (us-east, eu-west, asia-pacific) -- Business unit (finance, marketing, operations) -- Client identifier (client-a, client-b) -- Clusters - -```yaml - -``` - -:::info -Tag-based and agent-based permissions can be combined to create sophisticated access control policies that precisely match organizational requirements and security boundaries. -::: diff --git a/mission-control/docs/guide/permissions/groups.mdx b/mission-control/docs/guide/permissions/groups.mdx new file mode 100644 index 00000000..00d198ba --- /dev/null +++ b/mission-control/docs/guide/permissions/groups.mdx @@ -0,0 +1,63 @@ +--- +title: Groups +sidebar_position: 5 +sidebar_custom_props: + icon: group +--- + +Permission Groups let you group subjects (people, teams, or system services) under one name for simpler permission setup. +The subjects included in the group then inherit the permissions applied to it. + +Permission Groups are particularly useful when: +- You need to manage permissions for many users with similar roles +- You want to grant the same permissions to multiple system services +- You need to update permissions for a set of users all at once + +## Example + +```yaml title="permission-group.yaml" file=/modules/mission-control/fixtures/permissions/config-notification-group-playbook-permission.yaml +``` + +## Schema + +/`', + scheme: '`[]string`', + }, + { + field: 'playbooks', + description: 'List of playbook `/`', + scheme: '`[]string`', + }, + ]} +/> + +## Using Permission Groups + +Once a Permission Group is created, you can reference it in the `subject` field of a Permission: + +```yaml +subject: + group: system-administrators +``` + +All members of the group will inherit the permissions defined in the Permission resource. diff --git a/mission-control/docs/guide/permissions/index.mdx b/mission-control/docs/guide/permissions/index.mdx index 5ce5a6c7..3fd25532 100644 --- a/mission-control/docs/guide/permissions/index.mdx +++ b/mission-control/docs/guide/permissions/index.mdx @@ -3,262 +3,76 @@ slug: /guide/permission title: Permissions sidebar_position: 6 hide_title: true -# hide_table_of_contents: true pagination_prev: guide/mcp/index sidebar_custom_props: icon: shield-user --- -## Permission +## Permissions -In Mission Control, Permission provides a flexible and strong security model that combines two powerful methods: +Mission Control provides a flexible and strong security model that combines two powerful methods: Role-Based Access Control (RBAC) and Attribute-Based Access Control (ABAC). + This combined permission system helps you set up detailed access rules. For instance, while RBAC can control if a user can run any playbooks in the system, detailed ABAC rules let you define exactly which playbooks specific users or teams can access. -You can manage Permissions through the UI and using CRDs. - -```yaml title="permission.yaml" file=/modules/mission-control/fixtures/permissions/deny-person-playbook.yaml -``` - -A Permission has 4 parts: - -- **Subject**: The user or service requesting access. -- **Object**: The resources this permission affects (playbooks, connections or configs). -- **Effect**: Whether to allow or deny access (Default: allow). -- **Actions**: The [list of allowed actions](/docs/reference/permissions/actions). - -:::info -Deny rules always override Allow rules. -::: - -## CRD - -/` of the notification', - scheme: 'string', - }, - { - field: 'subject.playbook', - description: '`/` of the playbook', - scheme: 'string', - }, - { - field: 'object.playbooks', - description: 'List of playbook resource selectors', - scheme: 'resourceselectors', - }, - { - field: 'object.configs', - description: 'List of config resource selectors', - scheme: 'resourceselectors', - }, - - { - field: 'object.connections', - description: 'List of connection resource selectors', - scheme: 'resourceselectors', - }, - { - field: 'deny', - description: 'Specifies if this is a deny rule. _(Default: False)_', - scheme: 'bool', - }, - ]} -/> - -Additionally, for [tag-agent based ABAC](./concepts/multi-tenancy.md), you can also use these fields. - - - -## Subjects - -Subjects define WHO or WHAT gets the permission. The `subject` field can contain **only one** of the following: - -### Individual User - -Specify a human user by their email address or name (if the name is unique) to grant permission. - -```yaml -subject: - person: jane.doe@example.com -``` - -OR - -```yaml -subject: - person: "Jane Doe" -``` - -### Team - -Specify a team by its name to grant permission to all its members. - -```yaml -subject: - team: sre-team -``` - -### Group +## Key Concepts -Specify a defined `PermissionGroup` to grant permission. Groups bundle different items (like specific playbooks, notifications) or lists of users/teams. +| Concept | Description | +|---------|-------------| +| [Permission](./permissions/permission) | A rule that grants or denies specific actions to a subject on target objects | +| [Subject](./permissions/subjects) | WHO or WHAT gets the permission (person, team, group, or system service) | +| [Actions](./permissions/actions) | WHAT operations are allowed (read, write, delete, playbook:run, etc.) | +| [Groups](./permissions/groups) | Groups of subjects for easier permission management | -```yaml -subject: - group: system-administrators -``` - -### System Services - -Sometimes, a specific system service needs permission to act *for* a particular resource instance. Mission Control often uses this for automation or to allow one part of Mission Control to interact with another. The service gains permission only when it acts for the specified resource, identified by its `/`. - -- **Notification Service**: - - Specify a notification to grant permission to the notification service when it processes that notification. - Example: A notification might need access to read a connection or trigger a playbook run. - - ```yaml - subject: - notification: monitoring/critical-alerts - ``` +## Access Control Models -- **Playbook Service**: +| Model | Description | +|-------|-------------| +| [Roles](./permissions/roles) | Role-Based Access Control using built-in roles (admin, editor, viewer, guest) | +| [ABAC](./permissions/multi-tenancy) | Attribute-Based Access Control based on resource attributes (tags, namespace, name) | +| [Multi-Tenancy](./permissions/multi-tenancy) | Agent and tag-based permissions for SaaS environments | - Specify a playbook to grant permission to the playbook runner service when it runs that playbook. - Example: A playbook needs access to a specific resource it acts on. +## Quick Example - ```yaml +```yaml title="permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: sre-playbook-access +spec: + description: Allow SRE team to run playbooks on production configs subject: - playbook: automation/cleanup-pods - ``` - -## Objects - -Objects define the resources the permission targets. You can define Objects using [Resource Selectors](/docs/reference/resource-selector). -There are 4 types of objects: - -- **Playbooks** - Automation playbooks in the system -- **Configs** - Configuration items in the catalog -- **Connections** - Connection configurations for external systems - -A permission can target multiple objects, while a subject can only target one. -If you define multiple objects, Mission Control grants the permission only if the request matches all defined objects. -In other words, Mission Control applies an AND condition to the objects. - -```yaml - -``` - -This permission object allows running all playbooks but **only on configs in the "mission-control" namespace**. - -```yaml file=/modules/mission-control/fixtures/permissions/notification-playbook-permission.yaml {14-22} + team: sre-team + actions: + - playbook:run + object: + playbooks: + - name: "*" + configs: + - labels: + environment: production ``` -This permission, on the other hand, allows running the "echo-config" playbook on all configs & components. - -## Permission Actions - -The following actions can be used in the `actions` field of a Permission: - -- **`read`** - Allows reading resources -- **`write`** - Allows creating or modifying resources -- **`delete`** - Allows deleting resources -- **`playbook:run`** - Allows running playbooks -- **`playbook:approve`** - Allows approving playbook runs that require approval -- **`playbook:cancel`** - Allows canceling playbook runs - -You can also use wildcards to grant multiple permissions at once: - -- **`playbook:*`** - Grants all playbook-related permissions -- **`*`** - Grants all permissions (use with caution) - -## Permission Groups - -Permission Groups let you group subjects (people, teams, or system services) under one name for simpler permission setup. -The subjects included in the group then inherit the permissions applied to it. - -Permission Groups are particularly useful when: -- You need to manage permissions for many users with similar roles -- You want to grant the same permissions to multiple system services -- You need to update permissions for a set of users all at once -### CRD +:::info +Deny rules always override Allow rules. +::: -```yaml title="permission.yaml" file=/modules/mission-control/fixtures/permissions/config-notification-group-playbook-permission.yaml -``` +## Getting Started -/`', - scheme: '`[]string`', - }, - { - field: 'playbooks', - description: 'List of playbook `/`', - scheme: '`[]string`', - }, - ]} -/> +1. **[Quickstart](./permissions/quickstart)** - Learn about default permissions and how to enable strict mode +2. **[Permission](./permissions/permission)** - Understand the Permission CRD schema +3. **[Subjects](./permissions/subjects)** - Learn about different subject types +4. **[Actions](./permissions/actions)** - Understand available permission actions +## See Also +- [Quickstart](./permissions/quickstart) - Get started with permissions, including Helm configuration +- [Permission](./permissions/permission) - Permission CRD schema and examples +- [Subjects](./permissions/subjects) - Define who gets the permission +- [Actions](./permissions/actions) - Define what operations are allowed +- [Permission Groups](./permissions/groups) - Group subjects for simpler permission management +- [Roles](./permissions/roles) - Role-Based Access Control +- [ABAC](./permissions/multi-tenancy) - Attribute-Based Access Control +- [Multi-Tenancy](./permissions/multi-tenancy) - Agent and tag-based permissions for SaaS environments diff --git a/mission-control/docs/guide/permissions/multi-tenancy.md b/mission-control/docs/guide/permissions/multi-tenancy.md new file mode 100644 index 00000000..5ab863c9 --- /dev/null +++ b/mission-control/docs/guide/permissions/multi-tenancy.md @@ -0,0 +1,257 @@ +--- +title: Multi Tenancy / ABAC +sidebar_position: 7 +sidebar_custom_props: + icon: data-center +--- + +Mission Control provides sophisticated access control mechanisms for complex deployment scenarios, particularly in Software-as-a-Service (SaaS) environments where multiple tenants or organizations share the same infrastructure. +Two key features enable fine-grained access control in these scenarios: Agent-based permissions and Tag-based permissions. + +## Agent-Based Permissions + +Mission Control often acts as a central hub receiving data from multiple agents deployed across different environments. Each agent pushes its own set of resources, including catalogs and topologies, to the central Mission Control instance. While all these resources are accessible through a unified UI portal, organizations frequently need to restrict user access to specific agent-sourced data. + +Agent-based ABAC addresses this requirement by allowing administrators to create permissions that reference specific agents. + +For example, you might have: + +- Development teams that should only access resources from their development environment agents +- Regional teams that should only see resources from agents in their geographic location +- Client-specific teams that should only interact with agents deployed in their infrastructure + +### Examples + +
+
+ +```yaml title="dev-team-agent-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: dev-team-dev-agent-only +spec: + description: Allow dev team to only access resources from the development agent + subject: + team: development + actions: + - read + - playbook:run + agents: + - dev-cluster-agent +``` + +
+
+ +
+
+ +```yaml title="eu-team-agent-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: eu-team-regional-access +spec: + description: Restrict EU team to EU region agents only + subject: + team: eu-operations + actions: + - read + - write + - playbook:* + agents: + - eu-west-agent + - eu-central-agent +``` + +
+
+ +
+
+ +```yaml title="client-agent-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: acme-client-access +spec: + description: Restrict ACME client team to their dedicated agent + subject: + team: acme-support + actions: + - read + - playbook:run + agents: + - acme-corp-agent +``` + +
+
+ +## Tag-Based Permissions + +Tag-based permissions provide another layer of access control granularity by allowing administrators to restrict access based on resource tags. +This approach is particularly powerful for managing access in multi-cluster Kubernetes environments. + +Tags can represent various attributes such as: + +- Environment (production, staging, development) +- Geographic region (us-east, eu-west, asia-pacific) +- Business unit (finance, marketing, operations) +- Client identifier (client-a, client-b) +- Clusters + +### Examples + +
+
+ +```yaml title="prod-readonly-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: prod-readonly +spec: + description: Allow SRE team read-only access to production resources + subject: + team: sre + actions: + - read + tags: + environment: production +``` + +
+
+ +
+
+ +```yaml title="cluster-access-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: allow-playbooks-on-demo-cluster +spec: + description: Allow user to run playbooks only on demo and staging clusters + subject: + person: john@example.com + actions: + - playbook:run + object: + playbooks: + - name: "*" + configs: + - tagSelector: cluster=demo + - tagSelector: cluster=staging +``` + +
+
+ +
+
+ +```yaml title="finance-team-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: finance-business-unit +spec: + description: Restrict finance team to finance business unit resources + subject: + team: finance-ops + actions: + - read + - write + tags: + business-unit: finance +``` + +
+
+ +
+
+ +```yaml title="client-tenant-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: client-a-tenant-access +spec: + description: Isolate Client A to their tenant resources only + subject: + team: client-a-admins + actions: + - read + - write + - playbook:* + tags: + tenant: client-a +``` + +
+
+ +## Combined Agent and Tag Permissions + +Agent-based and tag-based permissions can be combined to create sophisticated access control policies that precisely match organizational requirements and security boundaries. + +:::info +When both `agents` and `tags` are specified, the permission applies only to resources that match **both** criteria (AND condition). +::: + +### Examples + +
+
+ +```yaml title="combined-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: us-prod-access +spec: + description: Allow US SRE team to manage production resources from US agents only + subject: + team: us-sre + actions: + - read + - write + - playbook:run + agents: + - us-east-agent + - us-west-agent + tags: + environment: production +``` + +
+
+ +
+
+ +```yaml title="client-env-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: acme-staging-access +spec: + description: Allow ACME support team to access only their staging environment + subject: + team: acme-support + actions: + - read + - playbook:run + agents: + - acme-corp-agent + tags: + environment: staging +``` + +
+
diff --git a/mission-control/docs/guide/permissions/permission.mdx b/mission-control/docs/guide/permissions/permission.mdx new file mode 100644 index 00000000..247a50e6 --- /dev/null +++ b/mission-control/docs/guide/permissions/permission.mdx @@ -0,0 +1,322 @@ +--- +title: Permission +sidebar_position: 2 +sidebar_custom_props: + icon: shield +--- + +A Permission defines access control rules that grant or deny specific actions to subjects on target objects. + +## Overview + +A Permission has 4 parts: + +- **[Subject](./subjects)**: The user or service requesting access +- **[Object](#objects)**: The resources this permission affects (playbooks, connections, or configs) +- **Effect**: Whether to allow or deny access (Default: allow) +- **[Actions](./actions)**: The list of allowed actions + +:::info +Deny rules always override Allow rules. +::: + +## Example + +```yaml title="permission.yaml" file=/modules/mission-control/fixtures/permissions/deny-person-playbook.yaml +``` + +## Schema + +/` of the notification', + scheme: 'string', + }, + { + field: 'subject.playbook', + description: '`/` of the playbook', + scheme: 'string', + }, + { + field: 'object.playbooks', + description: 'List of playbook resource selectors', + scheme: '[ResourceSelector](/docs/reference/resource-selector)', + }, + { + field: 'object.configs', + description: 'List of config resource selectors', + scheme: '[ResourceSelector](/docs/reference/resource-selector)', + }, + { + field: 'object.connections', + description: 'List of connection resource selectors', + scheme: '[ResourceSelector](/docs/reference/resource-selector)', + }, + { + field: 'object.components', + description: 'List of component resource selectors', + scheme: '[ResourceSelector](/docs/reference/resource-selector)', + }, + { + field: 'deny', + description: 'Specifies if this is a deny rule. _(Default: false)_', + scheme: 'bool', + }, + ]} +/> + +### Multi-Tenancy Fields + +For [agent and tag-based permissions](./multi-tenancy), you can also use these fields: + + + +## Objects + +Objects define the resources the permission targets. You can define Objects using [Resource Selectors](/docs/reference/resource-selector). + +| Object Type | Description | +|-------------|-------------| +| `playbooks` | Automation playbooks in the system | +| `configs` | Configuration items in the catalog | +| `connections` | Connection configurations for external systems | +| `components` | Topology components | + +A permission can target multiple object types. If you define multiple objects, Mission Control grants the permission only if the request matches **all** defined objects (AND condition). + +### Object Examples + +
+
+ +```yaml +object: + playbooks: + - name: "*" +``` + +
+
+ +
+
+ +```yaml +object: + playbooks: + - namespace: production +``` + +
+
+ +
+
+ +```yaml +object: + configs: + - labels: + environment: production +``` + +
+
+ +
+
+ +```yaml +object: + connections: + - name: aws-production +``` + +
+
+ +
+
+ +This permission allows running playbooks **only on configs in the specified namespace**: + +```yaml file=/modules/mission-control/fixtures/permissions/notification-playbook-permission.yaml {14-22} +``` + +
+
+ +## Examples + +
+
+ +```yaml title="team-playbook-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: sre-run-playbooks +spec: + description: Allow SRE team to run any playbook + subject: + team: sre-team + actions: + - playbook:run + object: + playbooks: + - name: "*" +``` + +
+
+ +
+
+ +```yaml title="deny-delete-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: deny-john-delete +spec: + description: Deny John from deleting any configs + deny: true + subject: + person: john@example.com + actions: + - delete + object: + configs: + - name: "*" +``` + +
+
+ +
+
+ +```yaml title="notification-connection-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: alerts-slack-access +spec: + description: Allow alerts notification to use Slack connection + subject: + notification: monitoring/critical-alerts + actions: + - read + object: + connections: + - name: slack-alerts +``` + +
+
+ +
+
+ +```yaml title="playbook-aws-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: cleanup-aws-access +spec: + description: Allow cleanup playbook to use AWS connection + subject: + playbook: automation/cleanup-resources + actions: + - read + object: + connections: + - name: aws-production +``` + +
+
+ +
+
+ +```yaml title="agent-restricted-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: dev-team-dev-agent +spec: + description: Allow dev team to access only dev agent resources + subject: + team: developers + actions: + - read + - playbook:run + agents: + - dev-cluster-agent +``` + +
+
+ +
+
+ +```yaml title="tag-restricted-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: prod-readonly +spec: + description: Read-only access to production resources + subject: + team: viewers + actions: + - read + tags: + environment: production +``` + +
+
diff --git a/mission-control/docs/guide/permissions/quickstart.mdx b/mission-control/docs/guide/permissions/quickstart.mdx new file mode 100644 index 00000000..f0412028 --- /dev/null +++ b/mission-control/docs/guide/permissions/quickstart.mdx @@ -0,0 +1,234 @@ +--- +title: Quickstart +sidebar_position: 1 +sidebar_custom_props: + icon: rocket +--- + +This guide helps you get started with Mission Control permissions, including understanding default permissions and how to customize them. + +## Default Behavior + +By default, Mission Control operates in a permissive mode where: + +- **Editors** can run any playbook and read any connection +- **Notifications** can run any playbook and read configs/components +- **System services** (canaries, scrapers, playbooks, topologies, notifications) can read all connections, configs, and components + +This default behavior is suitable for small teams or development environments where fine-grained access control isn't required. + +## Enabling Strict Permissions + +For production environments or multi-tenant setups, you should enable strict permission mode via Helm values: + +```yaml title="values.yaml" +permissions: + # Require explicit permissions to run playbooks + playbooks: true + # Require explicit permissions to read connections + connections: true + # Require explicit permissions for system services to read configs + configs: true + # Require explicit permissions for system services to read components + components: true +``` + +When these are set to `true`, the default permissive rules are disabled and you must explicitly grant permissions. + +## Helm Values Reference + +| Value | Default | Description | +|-------|---------|-------------| +| `permissions.playbooks` | `false` | When `true`, users need explicit permission to run playbooks | +| `permissions.connections` | `false` | When `true`, users need explicit permission to read connections | +| `permissions.configs` | `false` | When `true`, system services need explicit permission to read configs | +| `permissions.components` | `false` | When `true`, system services need explicit permission to read components | + +## Default Permission Groups + +Mission Control creates a `system` permission group that includes all system services: + +```yaml +apiVersion: mission-control.flanksource.com/v1 +kind: PermissionGroup +metadata: + name: system +spec: + canaries: + - name: "*" + scrapers: + - name: "*" + playbooks: + - name: "*" + topologies: + - name: "*" + notifications: + - name: "*" +``` + +This group is used to grant system-wide permissions to Mission Control's internal services. + +## Quick Setup Examples + +### Allow a Team to Run Playbooks + +```yaml title="team-playbook-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: sre-team-playbooks +spec: + description: Allow SRE team to run all playbooks + subject: + team: sre-team + actions: + - playbook:run + object: + playbooks: + - name: "*" +``` + +### Allow a Notification to Use a Connection + +When strict permissions are enabled, notifications need explicit access to connections: + +```yaml title="notification-connection-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: alert-notification-slack +spec: + description: Allow alert notification to use Slack connection + subject: + notification: monitoring/critical-alerts + actions: + - read + object: + connections: + - name: slack-alerts +``` + +### Allow a Playbook to Access AWS Connection + +```yaml title="playbook-aws-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: cleanup-playbook-aws +spec: + description: Allow cleanup playbook to use AWS connection + subject: + playbook: automation/cleanup-resources + actions: + - read + object: + connections: + - name: aws-production +``` + +### Restrict Access by Namespace + +```yaml title="namespace-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: dev-team-dev-namespace +spec: + description: Allow dev team to run playbooks only in dev namespace + subject: + team: developers + actions: + - playbook:run + object: + playbooks: + - namespace: development + configs: + - namespace: development +``` + +## Migration from Permissive to Strict Mode + +When transitioning to strict permissions: + +1. **Audit current usage** - Review which users, teams, and services are running playbooks and accessing connections + +2. **Create permissions incrementally** - Start by creating permissions for the most critical workflows: + ```yaml + # First, ensure system services still work + apiVersion: mission-control.flanksource.com/v1 + kind: Permission + metadata: + name: system-connections + spec: + subject: + group: system + actions: + - read + object: + connections: + - name: "*" + ``` + +3. **Enable strict mode one feature at a time**: + ```yaml title="values.yaml" + permissions: + playbooks: true # Enable first + connections: false # Enable after playbook permissions are tested + configs: false + components: false + ``` + +4. **Test thoroughly** - Verify that notifications, playbooks, and scrapers continue to function + +5. **Monitor for permission errors** - Check logs for access denied errors and create missing permissions + +## Common Issues + +### Notification Fails to Send + +If notifications fail after enabling strict permissions, ensure the notification has read access to any connections it uses: + +```yaml +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: notification-connection-access +spec: + subject: + notification: / + actions: + - read + object: + connections: + - name: +``` + +### Playbook Cannot Access Resources + +If a playbook fails with permission errors, grant it access to required connections and configs: + +```yaml +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: playbook-resource-access +spec: + subject: + playbook: / + actions: + - read + object: + connections: + - name: + configs: + - name: "*" +``` + +## Next Steps + +- [Roles](./roles) - Understand built-in roles +- [Subjects](./subjects) - Learn about different subject types +- [Actions](./actions) - Understand available permission actions +- [Permission Groups](./groups) - Group subjects for easier management +- [Multi-Tenancy](./multi-tenancy) - Set up agent and tag-based permissions for SaaS environments +- [ABAC](./multi-tenancy) - Attribute-based access control for fine-grained permissions diff --git a/mission-control/docs/guide/permissions/concepts/rbac.md b/mission-control/docs/guide/permissions/roles.md similarity index 84% rename from mission-control/docs/guide/permissions/concepts/rbac.md rename to mission-control/docs/guide/permissions/roles.md index c3334a35..af58edcf 100644 --- a/mission-control/docs/guide/permissions/concepts/rbac.md +++ b/mission-control/docs/guide/permissions/roles.md @@ -1,9 +1,11 @@ --- -title: RBAC -sidebar_position: 1 +title: Roles +sidebar_position: 6 +sidebar_custom_props: + icon: lock --- -Role-Based Access Control (RBAC) is a security model that manages access to Mission Control resources based on the roles assigned to users. +Mission Control uses Role-Based Access Control (RBAC) to manage access to resources based on the roles assigned to users. Mission Control provides a collection of built-in roles to accommodate common organizational needs and security requirements. Users receive a role when joining the system, which sets their base access level. @@ -20,4 +22,4 @@ This system enables precise control over who views, modifies, and manages resour ## Custom Roles -If you require more specialized access configurations, [PermissionGroups](../index.mdx#permission-groups) offer functionality similar to custom roles. +If you require more specialized access configurations, [Permission Groups](./groups) offer functionality similar to custom roles. diff --git a/mission-control/docs/guide/permissions/subjects.mdx b/mission-control/docs/guide/permissions/subjects.mdx new file mode 100644 index 00000000..99e9fa69 --- /dev/null +++ b/mission-control/docs/guide/permissions/subjects.mdx @@ -0,0 +1,166 @@ +--- +title: Subjects +sidebar_position: 3 +sidebar_custom_props: + icon: user +--- + +Subjects define WHO or WHAT gets the permission. The `subject` field can contain **only one** of the following: + +## Individual User + +Specify a human user by their email address or name (if the name is unique) to grant permission. + +```yaml +subject: + person: jane.doe@example.com +``` + +OR + +```yaml +subject: + person: "Jane Doe" +``` + +## Team + +Specify a team by its name to grant permission to all its members. + +```yaml +subject: + team: sre-team +``` + +## Group + +Specify a defined [Permission Group](./groups) to grant permission. Groups bundle different items (like specific playbooks, notifications) or lists of users/teams. + +```yaml +subject: + group: system-administrators +``` + +## System Services + +Sometimes, a specific system service needs permission to act *for* a particular resource instance. Mission Control often uses this for automation or to allow one part of Mission Control to interact with another. The service gains permission only when it acts for the specified resource, identified by its `/`. + +### Notification Service + +Specify a notification to grant permission to the notification service when it processes that notification. +Example: A notification might need access to read a connection or trigger a playbook run. + +```yaml +subject: + notification: monitoring/critical-alerts +``` + +### Playbook Service + +Specify a playbook to grant permission to the playbook runner service when it runs that playbook. +Example: A playbook needs access to a specific resource it acts on. + +```yaml +subject: + playbook: automation/cleanup-pods +``` + +## Schema + +/` of the notification', + scheme: 'string', + }, + { + field: 'playbook', + description: '`/` of the playbook', + scheme: 'string', + }, + ]} +/> + +## Examples + +
+
+ +```yaml title="user-playbook-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: jane-playbook-access +spec: + description: Allow Jane to run playbooks + subject: + person: jane.doe@example.com + actions: + - playbook:run + object: + playbooks: + - name: "*" +``` + +
+
+ +
+
+ +```yaml title="team-read-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: sre-read-access +spec: + description: Allow SRE team to read all configs + subject: + team: sre-team + actions: + - read + object: + configs: + - name: "*" +``` + +
+
+ +
+
+ +```yaml title="playbook-connection-permission.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Permission +metadata: + name: cleanup-playbook-aws-access +spec: + description: Allow cleanup playbook to use AWS connection + subject: + playbook: automation/cleanup-pods + actions: + - read + object: + connections: + - name: aws-production +``` + +
+
diff --git a/mission-control/docs/guide/playbooks/actions/exec.mdx b/mission-control/docs/guide/playbooks/actions/exec.mdx index 8500c27c..5303cce7 100644 --- a/mission-control/docs/guide/playbooks/actions/exec.mdx +++ b/mission-control/docs/guide/playbooks/actions/exec.mdx @@ -31,7 +31,8 @@ Exec action allows you to executes a command or a script file on the target host {field: 'env', scheme: '[[]EnvVar](/docs/reference/env-var)', description: 'Environment variables to set during execution'}, {field: 'checkout', scheme: '[Checkout](#git-checkout)', description: 'Checkout a git repository before running the script'}, {field: 'artifacts', scheme: '[Artifacts](#artifacts)', description: 'Artifacts produced by the action'}, - {field: 'connections', scheme: '[Connections](#connections)', description: 'Connections used by the action'} + {field: 'connections', scheme: '[Connections](#connections)', description: 'Connections used by the action'}, + {field: 'setup', scheme: '[Setup](#setup)', description: 'Install runtime dependencies (Bun, Python) before execution'} ]}/> ## Output @@ -126,10 +127,40 @@ will be setup on the host running the script. ``` +### Setup + +The `setup` field allows you to automatically install runtime environments before executing your script. This is useful when your script requires specific versions of Bun or Python that may not be available in the base image. + +#### Bun + +```yaml title="exec-deps-pkgs-bun.yaml" file=/modules/mission-control/fixtures/playbooks/exec-deps-pkgs-bun.yaml + +``` + +#### Python + +For Python scripts, you can declare dependencies inline using [PEP 723 inline script metadata](https://packaging.python.org/en/latest/specifications/inline-script-metadata/). The `uv` package manager is used to manage Python environments. + +```yaml title="exec-deps-pkgs-python.yaml" file=/modules/mission-control/fixtures/playbooks/exec-deps-pkgs-python.yaml + +``` + + + +#### RuntimeSetup + + + ### Action Result | Field | Description | Schema | diff --git a/mission-control/docs/guide/playbooks/actions/gitops.mdx b/mission-control/docs/guide/playbooks/actions/gitops.mdx index e676496f..2a243164 100644 --- a/mission-control/docs/guide/playbooks/actions/gitops.mdx +++ b/mission-control/docs/guide/playbooks/actions/gitops.mdx @@ -92,11 +92,12 @@ Common use cases: Patches modify existing files on the git repo. You can either use `yq` to modify yaml files or `jq` to modify json files. -| Field | Description | Scheme | Required | Templatable | -| ------ | ------------- | -------- | -------- | ----------- | -| `path` | Path to patch | `string` | `true` | `true` | -| `yq` | yq query | `string` | `false` | `true` | -| `jq` | jq query | `string` | `false` | `true` | +| Field | Description | Scheme | Required | Templatable | +| ------ | -------------------------------------------------------- | -------- | -------- | ----------- | +| `path` | Path to patch | `string` | `true` | `true` | +| `yq` | yq query | `string` | `false` | `true` | +| `jq` | jq query | `string` | `false` | `true` | +| `if` | CEL expression to conditionally apply the patch | `string` | `false` | | ### File diff --git a/mission-control/docs/guide/playbooks/actions/logs.mdx b/mission-control/docs/guide/playbooks/actions/logs.mdx index a3290d52..4dca5d43 100644 --- a/mission-control/docs/guide/playbooks/actions/logs.mdx +++ b/mission-control/docs/guide/playbooks/actions/logs.mdx @@ -10,7 +10,32 @@ import Templating from "@site/docs/reference/playbooks/context.mdx" # Logs Action -Logs action allows you to fetch and query logs from various backends including Loki, CloudWatch, OpenSearch, and Kubernetes. +The Logs action fetches and queries logs from various backends. Use it to retrieve logs for debugging, analysis, or to pass to downstream actions like AI analysis. + +```yaml title="fetch-pod-logs.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Playbook +metadata: + name: analyze-pod-errors +spec: + on: + config: + - types: + - Kubernetes::Pod + actions: + - name: fetch-logs + logs: + kubernetes: + namespace: '{{.config.tags.namespace}}' + pod: '{{.config.name}}' + since: 1h + tailLines: 500 + - name: analyze + ai: + prompt: | + Analyze these logs and identify any errors or issues: + {{.actions.fetch-logs.result.logs | toJSON}} +``` -### Loki +### CloudWatch + +Query logs from [AWS CloudWatch Logs](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/). -### CloudWatch +
- +```yaml title="cloudwatch-lambda-logs.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Playbook +metadata: + name: fetch-lambda-errors +spec: + parameters: + - name: function_name + label: Lambda Function + actions: + - name: get-logs + logs: + cloudwatch: + connection: connection://aws/production + region: us-east-1 + logGroup: '/aws/lambda/{{.params.function_name}}' + filterPattern: 'ERROR' + startTime: 6h + limit: 200 +``` -### OpenSearch +
+ +### Kubernetes + +Fetch logs directly from Kubernetes pods using the Kubernetes API. -### Kubernetes +
+ +```yaml title="k8s-pod-logs.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Playbook +metadata: + name: get-pod-logs +spec: + on: + config: + - types: + - Kubernetes::Pod + actions: + - name: fetch-logs + logs: + kubernetes: + namespace: '{{.config.tags.namespace}}' + pod: '{{.config.name}}' + since: 1h + tailLines: 1000 + timestamps: true +``` + +
+ +
+ +```yaml title="k8s-crashloop-logs.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Playbook +metadata: + name: debug-crashloop +spec: + on: + config: + - types: + - Kubernetes::Pod + filter: config.status == "CrashLoopBackOff" + actions: + - name: current-logs + logs: + kubernetes: + namespace: '{{.config.tags.namespace}}' + pod: '{{.config.name}}' + tailLines: 200 + - name: previous-logs + logs: + kubernetes: + namespace: '{{.config.tags.namespace}}' + pod: '{{.config.name}}' + previous: true + tailLines: 200 +``` + +
+ +
+ +```yaml title="k8s-label-selector-logs.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Playbook +metadata: + name: service-logs +spec: + parameters: + - name: service + label: Service Name + actions: + - name: fetch-all-pods + logs: + kubernetes: + namespace: production + labelSelector: 'app={{.params.service}}' + since: 30m + tailLines: 100 +``` + +
+ +### Loki + +Query logs from [Grafana Loki](https://grafana.com/oss/loki/) using LogQL. -### Dedupe +
+ +```yaml title="loki-error-logs.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Playbook +metadata: + name: fetch-loki-errors +spec: + actions: + - name: get-errors + logs: + loki: + url: http://loki.monitoring:3100 + query: '{namespace="production"} |= "error" | json' + start: 1h + limit: 100 + direction: backward + match: + - 'severity in ["error", "fatal"]' +``` + +
-Log deduplication removes duplicate log entries based on specified fields. +### OpenSearch + +Query logs from [OpenSearch](https://opensearch.org/) or Elasticsearch clusters. +
+ +```yaml title="opensearch-app-logs.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Playbook +metadata: + name: search-opensearch +spec: + actions: + - name: search-errors + logs: + opensearch: + connection: connection://opensearch/logs + index: 'app-logs-*' + query: 'level:error AND service:{{.config.name}}' + from: 24h + size: 500 + sort: + - '@timestamp': desc + mapping: + timestamp: ['@timestamp'] + message: ['message', 'msg'] + severity: ['level', 'log_level'] +``` + +
+ ## Output +The action returns a structured result containing the retrieved logs. + +### Using Results in Subsequent Actions + +```yaml +actions: + - name: fetch-logs + logs: + kubernetes: + namespace: production + labelSelector: app=api + since: 1h + - name: analyze + if: actions.fetch-logs.result.count > 0 + ai: + prompt: | + Analyze these {{.actions.fetch-logs.result.count}} log entries: + {{.actions.fetch-logs.result.logs | toJSON}} +``` + ## Templating - \ No newline at end of file + diff --git a/mission-control/docs/how-it-works.mdx b/mission-control/docs/how-it-works.mdx index 2830ee1e..6635c57a 100644 --- a/mission-control/docs/how-it-works.mdx +++ b/mission-control/docs/how-it-works.mdx @@ -39,7 +39,7 @@ Mission Control uses Kubernetes Custom Resources Definitions as the underlying c | [Notification](/docs/guide/notifications) | Sends notifications based on events | Email, Slack, etc | |
[NotificationSilences](/docs/guide/notifications/concepts/silences)
| Silences notifications based on rules | Silence notifications | | [Permissions](/docs/guide/permission) | Configure RBAC and ABAC rules for users and agents | Create permissions for user | -| [PermissionGroups](/docs/guide/permission#permission-groups) | Group subjects (people, teams, or system services) under one name for simpler permission setup | Create permissions for group | +| [PermissionGroups](/docs/guide/permissions/groups) | Group subjects (people, teams, or system services) under one name for simpler permission setup | Create permissions for group | | [ScrapeConfig](/docs/guide/config-db) | Configures scrapers to run periodically | Config items, analysis, change, cost | | [ScrapePlugins](/docs/guide/config-db/concepts/plugins) | Modify scraper behaviour (eg. transform changes, add properties to configs, set up relationships | Modify scraper behaviour | diff --git a/mission-control/docs/installation/index.mdx b/mission-control/docs/installation/index.mdx index f74eefe1..630c67ad 100644 --- a/mission-control/docs/installation/index.mdx +++ b/mission-control/docs/installation/index.mdx @@ -5,48 +5,6 @@ hide_title: true sidebar_position: 1 --- -export const toc = [ - { - value: "Deployment Model", - id: "deployment-model", - level: 2, - }, - { - value: "SaaS + Agent (Hybrid)", - id: "agent", - level: 3, - }, - { - value: "Self Hosted", - id: "self-hosted", - level: 3, - }, - - { - value: "SaaS Only", - id: "hosted", - level:3, - }, - { - value: "Ingestion Model", - id: "ingestion-model", - level: 2, - }, - - { - value: "Hub and Spoke", - id: "hub-and-spoke", - level:3, - }, - - { - value: "Multi Agent", - id: "multi-agent", - level:3, - }, - -] - ## Deployment Model @@ -85,7 +43,7 @@ Mission Control is designed to be self-hosted first, i.e the functionality avail -See [Self-Hosted](/docs/installation/self-hosted/getting-started) +See [Self-Hosted](/docs/installation/self-hosted) diff --git a/mission-control/docs/installation/saas/getting-started.mdx b/mission-control/docs/installation/saas/getting-started.mdx index d59b0aae..284a4715 100644 --- a/mission-control/docs/installation/saas/getting-started.mdx +++ b/mission-control/docs/installation/saas/getting-started.mdx @@ -22,7 +22,7 @@ The agent based approach has the following benefits: - **Local Playbook Execution** on agents, reusing existing secrets or IAM roles. -See [Installation](/docs/installation) for other deployment models including [Self Hosted](/docs/installation/self-hosted/getting-started) +See [Installation](/docs/installation) for other deployment models including [Self Hosted](/docs/installation/self-hosted) --- ### Signup diff --git a/mission-control/docs/installation/self-hosted/getting-started.mdx b/mission-control/docs/installation/self-hosted/getting-started.mdx index 88d549f4..7a4a3674 100644 --- a/mission-control/docs/installation/self-hosted/getting-started.mdx +++ b/mission-control/docs/installation/self-hosted/getting-started.mdx @@ -1,6 +1,6 @@ --- title: Getting Started -slug: /installation/self-hosted/getting-started +slug: /installation/self-hosted show_title: true sidebar_custom_props: icon: getting-started @@ -54,12 +54,12 @@ To install and run Mission Control you need the following: 1. Choose a routable `DOMAIN` for Mission Control

> See [Ingress](/docs/reference/helm/mission-control#ingress) for more options on configuring the ingress including generating certs with cert-manager - >

See [Local Testing](../local-testing) for testing using a kind or minikube without a routable domain

+ >

See [Local Testing](/docs/installation/local-testing) for testing using a kind or minikube without a routable domain

1. Install Mission Control

:::tip - If you are installing on EKS and plan to scrape AWS resources use the method described in [EKS](./eks) instead + If you are installing on EKS and plan to scrape AWS resources use the method described in [EKS](/docs/installation/self-hosted/eks) instead ::: - + - - + + diff --git a/mission-control/docs/integrations/_template.mdx b/mission-control/docs/integrations/_template.mdx index b3e042b8..3f564126 100644 --- a/mission-control/docs/integrations/_template.mdx +++ b/mission-control/docs/integrations/_template.mdx @@ -9,13 +9,6 @@ import { Card, Cards } from '@site/../common/src/components/Card' import Helm from '@site/../common/src/components/Helm.jsx' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Catalog', id: 'catalog', level: 2 }, - { value: 'Health Checks', id: 'health-checks', level: 2 }, - { value: 'Playbooks', id: 'playbooks', level: 2 }, - { value: 'Notifications', id: 'notifications', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/argo.mdx b/mission-control/docs/integrations/argo.mdx index 73ed2124..61de2964 100644 --- a/mission-control/docs/integrations/argo.mdx +++ b/mission-control/docs/integrations/argo.mdx @@ -10,10 +10,6 @@ import Schema from '@site/modules/mission-control-registry/charts/argocd/values. import Prereqs from '@site/docs/partials/_integration_prereqs.mdx' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Catalog', id: 'catalog', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/aws/index.mdx b/mission-control/docs/integrations/aws/index.mdx index f6a1d46f..05ab55dd 100644 --- a/mission-control/docs/integrations/aws/index.mdx +++ b/mission-control/docs/integrations/aws/index.mdx @@ -8,13 +8,6 @@ import DocCardList from '@theme/DocCardList'; import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' import { Card, Cards } from '@site/../common/src/components/Card' -export const toc = [ - { value: 'Catalog', id: 'catalog', level: 2 }, - { value: 'Health Checks', id: 'health-checks', level: 2 }, - { value: 'Playbooks', id: 'playbooks', level: 2 }, - { value: 'Notifications', id: 'notifications', level: 2 }, -]; - @@ -53,8 +46,8 @@ Monitor AWS services and endpoints with automated health checks. - Test Lambda function invocations and response times - - + + --- @@ -70,7 +63,6 @@ Automate AWS operations and incident remediation with playbooks. - Trigger AWS Lambda functions for custom remediation - @@ -87,7 +79,7 @@ Send alerts to AWS notification services. - Trigger Step Functions for complex alerting pipelines - + --- diff --git a/mission-control/docs/integrations/azure-ad.mdx b/mission-control/docs/integrations/azure-ad.mdx index 39b3265b..eff664a1 100644 --- a/mission-control/docs/integrations/azure-ad.mdx +++ b/mission-control/docs/integrations/azure-ad.mdx @@ -7,10 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Catalog', id: 'catalog', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/azure-devops.mdx b/mission-control/docs/integrations/azure-devops.mdx index 0c6c4a38..17c5bd1a 100644 --- a/mission-control/docs/integrations/azure-devops.mdx +++ b/mission-control/docs/integrations/azure-devops.mdx @@ -7,12 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Health Checks', id: 'health-checks', level: 2 }, - { value: 'Playbooks', id: 'playbooks', level: 2 }, - { value: 'Catalog', id: 'catalog', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/azure.mdx b/mission-control/docs/integrations/azure.mdx index c1a12b1d..f037095c 100644 --- a/mission-control/docs/integrations/azure.mdx +++ b/mission-control/docs/integrations/azure.mdx @@ -7,10 +7,6 @@ sidebar_custom_props: import Schema from '@site/modules/mission-control-registry/charts/azure/values.schema.json' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Catalog', id: 'catalog', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/clickhouse.mdx b/mission-control/docs/integrations/clickhouse.mdx index 23ba6563..69b7e0ca 100644 --- a/mission-control/docs/integrations/clickhouse.mdx +++ b/mission-control/docs/integrations/clickhouse.mdx @@ -8,10 +8,6 @@ import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' import Icon from '@site/../common/src/components/Icon' -export const toc = [ - { value: 'Catalog', id: 'catalog', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/crossplane.mdx b/mission-control/docs/integrations/crossplane.mdx index a78a4f86..cf26d949 100644 --- a/mission-control/docs/integrations/crossplane.mdx +++ b/mission-control/docs/integrations/crossplane.mdx @@ -1,5 +1,4 @@ --- -draft: true sidebar_custom_props: icon: crossplane title: Crossplane diff --git a/mission-control/docs/integrations/email.mdx b/mission-control/docs/integrations/email.mdx index 869e7935..445db214 100644 --- a/mission-control/docs/integrations/email.mdx +++ b/mission-control/docs/integrations/email.mdx @@ -7,10 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Notifications', id: 'notifications', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/flux/index.mdx b/mission-control/docs/integrations/flux/index.mdx index e04626c8..72c533f6 100644 --- a/mission-control/docs/integrations/flux/index.mdx +++ b/mission-control/docs/integrations/flux/index.mdx @@ -8,11 +8,6 @@ import DocCardList from '@theme/DocCardList'; import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Catalog', id: 'catalog', level: 2 }, - { value: 'Playbooks', id: 'playbooks', level: 2 }, -]; - @@ -50,7 +45,6 @@ Automate Flux operations and GitOps workflows with playbooks. - --- diff --git a/mission-control/docs/integrations/gcp.mdx b/mission-control/docs/integrations/gcp.mdx index 3036d9e8..36cb7d2f 100644 --- a/mission-control/docs/integrations/gcp.mdx +++ b/mission-control/docs/integrations/gcp.mdx @@ -7,11 +7,6 @@ sidebar_custom_props: import Schema from '@site/modules/mission-control-registry/charts/gcp/values.schema.json' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Catalog', id: 'catalog', level: 2 }, - { value: 'Health Checks', id: 'health-checks', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/github.mdx b/mission-control/docs/integrations/github.mdx index 457b565c..feb39b90 100644 --- a/mission-control/docs/integrations/github.mdx +++ b/mission-control/docs/integrations/github.mdx @@ -7,12 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Health Checks', id: 'health-checks', level: 2 }, - { value: 'Playbooks', id: 'playbooks', level: 2 }, - { value: 'Catalog', id: 'catalog', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/gitlab.mdx b/mission-control/docs/integrations/gitlab.mdx index b0602770..4c374c40 100644 --- a/mission-control/docs/integrations/gitlab.mdx +++ b/mission-control/docs/integrations/gitlab.mdx @@ -7,10 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Playbooks', id: 'playbooks', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/grafana.mdx b/mission-control/docs/integrations/grafana.mdx index 8dbd466c..ad4dccdc 100644 --- a/mission-control/docs/integrations/grafana.mdx +++ b/mission-control/docs/integrations/grafana.mdx @@ -7,11 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Health Checks', id: 'health-checks', level: 2 }, - { value: 'Dashboards', id: 'dashboards', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/helm.mdx b/mission-control/docs/integrations/helm.mdx index be908116..098b7fc2 100644 --- a/mission-control/docs/integrations/helm.mdx +++ b/mission-control/docs/integrations/helm.mdx @@ -10,11 +10,6 @@ import Schema from '@site/modules/mission-control-registry/charts/helm/values.sc import Prereqs from '@site/docs/partials/_integration_prereqs.mdx' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Health Checks', id: 'health-checks', level: 2 }, - { value: 'Playbooks', id: 'playbooks', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/http.mdx b/mission-control/docs/integrations/http.mdx index 83d7b398..18f1d2f3 100644 --- a/mission-control/docs/integrations/http.mdx +++ b/mission-control/docs/integrations/http.mdx @@ -7,12 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Health Checks', id: 'health-checks', level: 2 }, - { value: 'Playbooks', id: 'playbooks', level: 2 }, - { value: 'Catalog', id: 'catalog', level: 2 }, -]; - @@ -128,6 +122,18 @@ spec: ``` +

+ +Chain multiple HTTP requests together using `dependsOn`. This is useful for authentication flows where you need to login first and use the token in subsequent requests. + +```yaml title="http-depends-on.yaml" file=/modules/canary-checker/fixtures/minimal/http_depends_on_pass.yaml + +``` + +See [Request Chaining](/docs/guide/canary-checker/concepts/request-chaining) for more details. + +
+ --- diff --git a/mission-control/docs/integrations/kubernetes/index.mdx b/mission-control/docs/integrations/kubernetes/index.mdx index 62b8d8ae..51f705cd 100644 --- a/mission-control/docs/integrations/kubernetes/index.mdx +++ b/mission-control/docs/integrations/kubernetes/index.mdx @@ -8,13 +8,6 @@ import DocCardList from '@theme/DocCardList'; import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Catalog', id: 'catalog', level: 2 }, - { value: 'Health Checks', id: 'health-checks', level: 2 }, - { value: 'Playbooks', id: 'playbooks', level: 2 }, - { value: 'Notifications', id: 'notifications', level: 2 }, -]; - @@ -70,7 +63,6 @@ Automate Kubernetes operations and incident remediation with playbooks. - Delete stuck resources or force reconciliation - diff --git a/mission-control/docs/integrations/kustomize/index.mdx b/mission-control/docs/integrations/kustomize/index.mdx index d086e52f..57f0e413 100644 --- a/mission-control/docs/integrations/kustomize/index.mdx +++ b/mission-control/docs/integrations/kustomize/index.mdx @@ -8,10 +8,6 @@ import { Card, Cards } from '@site/../common/src/components/Card' import Prereqs from '@site/docs/partials/_integration_prereqs.mdx' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Playbooks', id: 'playbooks', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/ldap.mdx b/mission-control/docs/integrations/ldap.mdx index 21819131..ed5cc413 100644 --- a/mission-control/docs/integrations/ldap.mdx +++ b/mission-control/docs/integrations/ldap.mdx @@ -7,10 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Health Checks', id: 'health-checks', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/loki.mdx b/mission-control/docs/integrations/loki.mdx index 5895dd7f..3d676c38 100644 --- a/mission-control/docs/integrations/loki.mdx +++ b/mission-control/docs/integrations/loki.mdx @@ -7,10 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Playbooks', id: 'playbooks', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/mcp.mdx b/mission-control/docs/integrations/mcp.mdx index feca2da7..1ffcfdf3 100644 --- a/mission-control/docs/integrations/mcp.mdx +++ b/mission-control/docs/integrations/mcp.mdx @@ -7,10 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'MCP Server', id: 'mcp-server', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/opensearch.mdx b/mission-control/docs/integrations/opensearch.mdx index bb7990fa..d8b8153e 100644 --- a/mission-control/docs/integrations/opensearch.mdx +++ b/mission-control/docs/integrations/opensearch.mdx @@ -7,10 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Health Checks', id: 'health-checks', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/postgres.mdx b/mission-control/docs/integrations/postgres.mdx index 5779ed9d..8a57ebb0 100644 --- a/mission-control/docs/integrations/postgres.mdx +++ b/mission-control/docs/integrations/postgres.mdx @@ -7,11 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Health Checks', id: 'health-checks', level: 2 }, - { value: 'Catalog', id: 'catalog', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/prometheus.mdx b/mission-control/docs/integrations/prometheus.mdx index 22a24058..e3c77a41 100644 --- a/mission-control/docs/integrations/prometheus.mdx +++ b/mission-control/docs/integrations/prometheus.mdx @@ -7,11 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Health Checks', id: 'health-checks', level: 2 }, - { value: 'Exposed Metrics', id: 'exposed-metrics', level: 2 }, -]; - @@ -116,7 +111,7 @@ Labels: `canary_name`, `key`, `name`, `namespace`, `owner`, `severity`, `type` Labels: `scraper_id`, `kind`, `config_type` -For the complete metrics reference, see the [Canary Checker metrics documentation](/canary-checker/concepts/metrics). +For the complete metrics reference, see the [Canary Checker metrics documentation](/docs/guide/canary-checker/concepts/metrics). ## Next Steps diff --git a/mission-control/docs/integrations/slack.mdx b/mission-control/docs/integrations/slack.mdx index 5428bcfe..8589deb5 100644 --- a/mission-control/docs/integrations/slack.mdx +++ b/mission-control/docs/integrations/slack.mdx @@ -7,11 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Notifications', id: 'notifications', level: 2 }, - { value: 'Catalog', id: 'catalog', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/sql-server.mdx b/mission-control/docs/integrations/sql-server.mdx index 8d7a023e..3a4e69b5 100644 --- a/mission-control/docs/integrations/sql-server.mdx +++ b/mission-control/docs/integrations/sql-server.mdx @@ -7,11 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Health Checks', id: 'health-checks', level: 2 }, - { value: 'Catalog', id: 'catalog', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/teams.mdx b/mission-control/docs/integrations/teams.mdx index ff2f181a..5694757c 100644 --- a/mission-control/docs/integrations/teams.mdx +++ b/mission-control/docs/integrations/teams.mdx @@ -7,10 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Notifications', id: 'notifications', level: 2 }, -]; - diff --git a/mission-control/docs/integrations/terraform.mdx b/mission-control/docs/integrations/terraform.mdx index 4155efaf..519bd089 100644 --- a/mission-control/docs/integrations/terraform.mdx +++ b/mission-control/docs/integrations/terraform.mdx @@ -1,5 +1,4 @@ --- -draft: true title: Terraform sidebar_custom_props: icon: terraform diff --git a/mission-control/docs/integrations/trivy.mdx b/mission-control/docs/integrations/trivy.mdx index b22c652e..b799724c 100644 --- a/mission-control/docs/integrations/trivy.mdx +++ b/mission-control/docs/integrations/trivy.mdx @@ -7,10 +7,6 @@ sidebar_custom_props: import { Card, Cards } from '@site/../common/src/components/Card' import { CapabilityBadges, CapabilityBadge, CapabilityHeading } from '@site/../common/src/components/CapabilityBadges' -export const toc = [ - { value: 'Catalog', id: 'catalog', level: 2 }, -]; - diff --git a/mission-control/docs/reference/config_access.mdx b/mission-control/docs/reference/config-db/config_access.mdx similarity index 100% rename from mission-control/docs/reference/config_access.mdx rename to mission-control/docs/reference/config-db/config_access.mdx diff --git a/mission-control/docs/reference/connections/Notifications/discord.mdx b/mission-control/docs/reference/connections/Notifications/discord.mdx deleted file mode 100644 index ff62dcbb..00000000 --- a/mission-control/docs/reference/connections/Notifications/discord.mdx +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Discord ---- - -```yaml -apiVersion: mission-control.flanksource.com/v1 -kind: Connection -metadata: - name: discord-connection - namespace: default -spec: - discord: - token: your-discord-token - webhookID: your-webhook-id -``` - - diff --git a/mission-control/docs/reference/connections/Notifications/ntfy.mdx b/mission-control/docs/reference/connections/Notifications/ntfy.mdx deleted file mode 100644 index e01ed8f1..00000000 --- a/mission-control/docs/reference/connections/Notifications/ntfy.mdx +++ /dev/null @@ -1,38 +0,0 @@ -```yaml -apiVersion: mission-control.flanksource.com/v1 -kind: Connection -metadata: - name: ntfy-connection - namespace: default -spec: - ntfy: - topic: your-topic - host: your-host - username: - value: your-username - password: - value: your-password -``` - - diff --git a/mission-control/docs/reference/connections/Notifications/pushbullet.mdx b/mission-control/docs/reference/connections/Notifications/pushbullet.mdx deleted file mode 100644 index e619aeb2..00000000 --- a/mission-control/docs/reference/connections/Notifications/pushbullet.mdx +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Pushbullet ---- - -```yaml -apiVersion: mission-control.flanksource.com/v1 -kind: Connection -metadata: - name: pushbullet-connection - namespace: default -spec: - pushbullet: - token: - value: your-pushbullet-token - targets: - - target1 - - target2 -``` - - diff --git a/mission-control/docs/reference/connections/Notifications/pushover.mdx b/mission-control/docs/reference/connections/Notifications/pushover.mdx deleted file mode 100644 index 15470206..00000000 --- a/mission-control/docs/reference/connections/Notifications/pushover.mdx +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: Pushover ---- - -```yaml -apiVersion: mission-control.flanksource.com/v1 -kind: Connection -metadata: - name: pushover-connection - namespace: default -spec: - pushover: - token: - value: your-pushover-token - user: your-user-key -``` - - diff --git a/mission-control/docs/reference/connections/Notifications/slack.mdx b/mission-control/docs/reference/connections/Notifications/slack.mdx deleted file mode 100644 index 7fabbec5..00000000 --- a/mission-control/docs/reference/connections/Notifications/slack.mdx +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: Slack ---- - -```yaml title="Example Slack Connection" -apiVersion: mission-control.flanksource.com/v1 -kind: Connection -metadata: - name: slack-connection - namespace: default -spec: - slack: - token: - value: your-slack-token - channel: Cxxxxxxxxxx - botName: your-bot-name - color: "#36a64f" - icon: ":robot_face:" - title: "Notification Title" -``` - -This example: -1. Uses `token` to authenticate the Slack bot. -2. Sends messages to the specified `channel`. -3. Sets the `botName` to identify the bot. -4. Optionally sets the `color` of the message border. -5. Optionally sets the `icon` for the bot. -6. Optionally sends the message as a reply in a thread using `threadTS`. -7. Optionally prepends a `title` above the message. - - diff --git a/mission-control/docs/reference/connections/Notifications/smtp.mdx b/mission-control/docs/reference/connections/Notifications/smtp.mdx deleted file mode 100644 index 40cdffef..00000000 --- a/mission-control/docs/reference/connections/Notifications/smtp.mdx +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: SMTP ---- - -```yaml -apiVersion: mission-control.flanksource.com/v1 -kind: Connection -metadata: - name: smtp-connection - namespace: default -spec: - smtp: - host: your-smtp-host - username: - value: your-username - password: - value: your-password - insecureTLS: true - encryption: auto - port: 587 - fromAddress: your-from-address - toAddresses: - - recipient1@example.com - - recipient2@example.com - subject: your-email-subject - auth: Plain -``` - - diff --git a/mission-control/docs/reference/connections/Notifications/telegram.mdx b/mission-control/docs/reference/connections/Notifications/telegram.mdx deleted file mode 100644 index ef31e712..00000000 --- a/mission-control/docs/reference/connections/Notifications/telegram.mdx +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Telegram ---- - -```yaml -apiVersion: mission-control.flanksource.com/v1 -kind: Connection -metadata: - name: telegram-connection - namespace: default -spec: - telegram: - token: - value: your-telegram-token - chats: - value: your-chat-id -``` - - diff --git a/mission-control/docs/reference/connections/anthropic.mdx b/mission-control/docs/reference/connections/anthropic.mdx index fa0242b0..61ece7e0 100644 --- a/mission-control/docs/reference/connections/anthropic.mdx +++ b/mission-control/docs/reference/connections/anthropic.mdx @@ -1,9 +1,16 @@ --- title: Anthropic +description: Connect to Anthropic's Claude API for AI-powered playbook actions and analysis sidebar_custom_props: - icon: anthropic + icon: anthropic --- +Anthropic connections enable integration with Anthropic's Claude API for AI-powered playbook actions, automated analysis, and intelligent response generation. + +## Used By + +- [AI Action](/docs/guide/playbooks/actions/ai) - Use AI for complex reasoning, code analysis, and technical explanations + ## Example @@ -13,13 +20,12 @@ apiVersion: mission-control.flanksource.com/v1 kind: Connection metadata: name: anthropic-claude - namespace: default spec: anthropic: - model: llama3.1:8b - apikey: - valueFrom: - secretKeyRef: - name: anthropic - key: api - ``` + model: claude-3-5-sonnet-20241022 + apiKey: + valueFrom: + secretKeyRef: + name: anthropic-credentials + key: API_KEY +``` diff --git a/mission-control/docs/reference/connections/aws.mdx b/mission-control/docs/reference/connections/aws.mdx index fa37ea8f..1b224a86 100644 --- a/mission-control/docs/reference/connections/aws.mdx +++ b/mission-control/docs/reference/connections/aws.mdx @@ -1,25 +1,34 @@ --- title: AWS - +description: Connect to Amazon Web Services for health checks, config scraping, and playbook actions sidebar_custom_props: icon: aws --- - +AWS connections enable integration with Amazon Web Services for health checks, configuration scraping, and playbook automation. - +## Used By +- [AWS Config Scraper](/docs/guide/config-db/scrapers/aws) - Scrape AWS resource configurations +- [CloudWatch Health Check](/docs/reference/canary-checker) - Monitor CloudWatch metrics +- [S3 Folder Check](/docs/reference/canary-checker) - Check S3 bucket contents +- [Playbook Actions](/docs/guide/playbooks/actions) - Execute AWS-related automation + + -There are 3 options when connecting to AWS: +## Authentication Methods -By using the AWS [Instance Profile](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html) or [Pod Identity](https://docs.aws.amazon.com/eks/latest/userguide/pod-configuration.html) (the default if no `connection` or `accessKey` is specified) +Use the AWS [Instance Profile](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html) or [Pod Identity](https://docs.aws.amazon.com/eks/latest/userguide/pod-configuration.html). This is the default when no `connection` or `accessKey` is specified and the recommended approach for workloads running on AWS infrastructure. + - -Using a shared Connection -```yaml title="aws-connection.yaml" + + +Reference a shared Connection for reusable credentials: + +```yaml title="using-connection-reference.yaml" apiVersion: canaries.flanksource.com/v1 kind: Canary metadata: @@ -27,13 +36,17 @@ metadata: spec: interval: 30 cloudwatch: - - connection: connection://aws/internal - region: us-east-1 # optional if specified in the connection + - connection: connection://aws/production + region: us-east-1 ``` + - -```yaml title="inline.yaml" + + +Specify credentials directly using Kubernetes secrets: + +```yaml title="inline-credentials.yaml" apiVersion: canaries.flanksource.com/v1 kind: Canary metadata: @@ -53,7 +66,65 @@ spec: key: AWS_SECRET_ACCESS_KEY region: us-east-1 ``` + +## Examples +
+
+ +Create a reusable AWS connection: + +```yaml title="aws-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: aws-production + namespace: default +spec: + aws: + region: us-east-1 + accessKey: + valueFrom: + secretKeyRef: + name: aws-credentials + key: AWS_ACCESS_KEY_ID + secretKey: + valueFrom: + secretKeyRef: + name: aws-credentials + key: AWS_SECRET_ACCESS_KEY +``` + +
+
+ +
+
+ +Access resources in another AWS account: + +```yaml title="aws-assume-role.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: aws-cross-account +spec: + aws: + region: us-east-1 + accessKey: + valueFrom: + secretKeyRef: + name: aws-credentials + key: AWS_ACCESS_KEY_ID + secretKey: + valueFrom: + secretKeyRef: + name: aws-credentials + key: AWS_SECRET_ACCESS_KEY + assumeRole: arn:aws:iam::123456789012:role/CrossAccountAccess +``` +
+
diff --git a/mission-control/docs/reference/connections/azure-devops.mdx b/mission-control/docs/reference/connections/azure-devops.mdx index 39a3c43d..5f78c20d 100644 --- a/mission-control/docs/reference/connections/azure-devops.mdx +++ b/mission-control/docs/reference/connections/azure-devops.mdx @@ -1,9 +1,63 @@ --- -title: Azure Devops +title: Azure DevOps +description: Connect to Azure DevOps for repository access, pipeline automation, and work item management sidebar_custom_props: icon: azure-devops --- -import AzureDevops from '@site/docs/partials/_azureDevops.mdx' +Azure DevOps connections enable integration with Azure DevOps Services and Server for Git repository access, pipeline automation, and work item management. - +## Used By + +- [Azure DevOps Config Scraper](/docs/guide/config-db/scrapers/azure-devops) - Scrape Azure DevOps configurations +- [Azure DevOps Pipeline Action](/docs/guide/playbooks/actions/azure_devops_pipeline) - Trigger pipelines +- [GitOps Action](/docs/guide/playbooks/actions/gitops) - Commit changes to repositories + + + +## Examples + +
+
+ +```yaml title="azure-devops-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: azure-devops +spec: + azureDevops: + url: https://dev.azure.com/my-organization + personalAccessToken: + valueFrom: + secretKeyRef: + name: azure-devops-credentials + key: token +``` + +
+
+ +
+
+ +```yaml title="azure-devops-server.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: azure-devops-server +spec: + azureDevops: + url: https://tfs.mycompany.com/tfs/DefaultCollection + personalAccessToken: + valueFrom: + secretKeyRef: + name: tfs-credentials + key: token +``` + +
+
diff --git a/mission-control/docs/reference/connections/azure.mdx b/mission-control/docs/reference/connections/azure.mdx index 6da11e9f..8d22927a 100644 --- a/mission-control/docs/reference/connections/azure.mdx +++ b/mission-control/docs/reference/connections/azure.mdx @@ -1,29 +1,81 @@ --- title: Azure +description: Connect to Microsoft Azure for health checks, config scraping, and playbook actions sidebar_custom_props: icon: azure --- - +Azure connections enable integration with Microsoft Azure for health checks, configuration scraping, and playbook automation. + +## Used By + +- [Azure Config Scraper](/docs/guide/config-db/scrapers/azure) - Scrape Azure resource configurations +- [Azure Blob Health Check](/docs/reference/canary-checker) - Check Azure Blob Storage +- [Azure DevOps Pipeline](/docs/guide/playbooks/actions/azure_devops_pipeline) - Trigger pipelines +- [Playbook Actions](/docs/guide/playbooks/actions) - Execute Azure-related automation -## Example +## Authentication + +Azure connections use service principal credentials (client ID and client secret) for authentication. + +## Examples + +
+
-This example demonstrates how to configure an Azure connection in Mission Control: +Create an Azure connection with service principal: ```yaml title="azure-connection.yaml" -apiVersion: v1 +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: azure-production + namespace: default +spec: + azure: + clientID: + valueFrom: + secretKeyRef: + name: azure-credentials + key: AZURE_CLIENT_ID + clientSecret: + valueFrom: + secretKeyRef: + name: azure-credentials + key: AZURE_CLIENT_SECRET + tenantID: your-tenant-id +``` + +
+
+ +
+
+ +Include subscription for resource access: + +```yaml title="azure-with-subscription.yaml" +apiVersion: mission-control.flanksource.com/v1 kind: Connection metadata: - name: azure-connection + name: azure-subscription spec: azure: clientID: - value: your-client-id + valueFrom: + secretKeyRef: + name: azure-credentials + key: AZURE_CLIENT_ID clientSecret: - value: your-client-secret + valueFrom: + secretKeyRef: + name: azure-credentials + key: AZURE_CLIENT_SECRET tenantID: your-tenant-id - subscriptionId: subscription-id + subscriptionID: your-subscription-id ``` +
+
diff --git a/mission-control/docs/reference/connections/discord.mdx b/mission-control/docs/reference/connections/discord.mdx new file mode 100644 index 00000000..567a43a0 --- /dev/null +++ b/mission-control/docs/reference/connections/discord.mdx @@ -0,0 +1,49 @@ +--- +title: Discord +description: Connect to Discord for sending notifications and alerts via webhooks +sidebar_custom_props: + icon: discord +--- + +Discord connections enable sending notifications and alerts to Discord channels via webhooks. + +## Used By + +- [Notifications](/docs/guide/notifications) - Send alerts to Discord channels +- [Notification Action](/docs/guide/playbooks/actions/notification) - Send messages from playbooks + + + +## Example + +```yaml title="discord-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: discord-alerts +spec: + discord: + webhookID: "1234567890123456789" + token: + valueFrom: + secretKeyRef: + name: discord-credentials + key: WEBHOOK_TOKEN +``` + +## Next Steps + +- [Discord Channel Guide](/docs/guide/notifications/channels/discord) - Configure Discord notifications diff --git a/mission-control/docs/reference/connections/gcp.mdx b/mission-control/docs/reference/connections/gcp.mdx index d8a0d087..925ff958 100644 --- a/mission-control/docs/reference/connections/gcp.mdx +++ b/mission-control/docs/reference/connections/gcp.mdx @@ -1,83 +1,116 @@ --- title: GCP +description: Connect to Google Cloud Platform for health checks, config scraping, and playbook actions sidebar_custom_props: icon: google-cloud --- - +GCP connections enable integration with Google Cloud Platform for health checks, configuration scraping, and playbook automation. - +## Used By +- [GCP Config Scraper](/docs/guide/config-db/scrapers/gcp) - Scrape GCP resource configurations +- [GCS Folder Check](/docs/reference/canary-checker) - Check Cloud Storage buckets +- [Playbook Actions](/docs/guide/playbooks/actions) - Execute GCP-related automation + +## Authentication Methods -There are 3 options when connecting to GCP: + - +Use GKE [workload identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity). This is the default when no `connection` or `credentials` is specified and the recommended approach for workloads running on GKE. -GKE [workload identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) (the default if no `connection` or `credentials` is specified) -## Example + -This example demonstrates how to configure a GCP connection using a YAML file. +Reference a shared connection: -```yaml title="gcp-connection-example.yaml" +```yaml title="using-connection.yaml" apiVersion: canaries.flanksource.com/v1 kind: Canary metadata: - name: example-gcp-connection + name: gcs-check spec: interval: 60 folder: - - name: gcs auth test - path: gcs://example-bucket + - name: GCS Backup Check + path: gcs://my-bucket gcpConnection: - connection: connection://gcp/example + connection: connection://gcp/production ``` -This example: -1. Configures a GCP connection to a bucket named `example-bucket`. -2. Uses the `connection://gcp/example` connection string. -3. Sets the interval to 60 seconds. + + + - +Specify service account credentials directly: -```yaml title="gcs-connection.yaml" +```yaml title="inline-credentials.yaml" apiVersion: canaries.flanksource.com/v1 kind: Canary metadata: - name: /docs/guide/canary-checker/reference/database-backup-check + name: gcs-check spec: interval: 60 folder: - - name: gcs auth test - path: gcs://somegcsbucket + - name: GCS Backup Check + path: gcs://my-bucket gcpConnection: - connection: connection://gcp/internal + credentials: + valueFrom: + secretKeyRef: + name: gcp-credentials + key: service-account.json ``` - +## Examples -```yaml title="gcp-inline.yaml" -apiVersion: canaries.flanksource.com/v1 -kind: Canary +
+
+ +Create a GCP connection with service account: + +```yaml title="gcp-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection metadata: - name: /docs/guide/canary-checker/reference/database-backup-check + name: gcp-production + namespace: default spec: - interval: 60 - folder: - - name: gcs auth test - path: gcs://somegcsbucket - gcpConnection: - credentials: - valueFrom: - secretKeyRef: - name: gcp-credentials - key: AUTH_ACCESS_TOKEN + gcp: + credentials: + valueFrom: + secretKeyRef: + name: gcp-credentials + key: service-account.json ``` - +
+
+ +
+
+ +Include project for resource access: + +```yaml title="gcp-with-project.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: gcp-project +spec: + gcp: + project: my-gcp-project + credentials: + valueFrom: + secretKeyRef: + name: gcp-credentials + key: service-account.json +``` +
+
diff --git a/mission-control/docs/reference/connections/git.mdx b/mission-control/docs/reference/connections/git.mdx index caa9f8ee..42c1dd77 100644 --- a/mission-control/docs/reference/connections/git.mdx +++ b/mission-control/docs/reference/connections/git.mdx @@ -1,12 +1,17 @@ --- title: Git +description: Connect to Git repositories for GitOps workflows, configuration management, and playbook actions sidebar_custom_props: icon: git --- - +Git connections enable integration with Git repositories for GitOps workflows, configuration management, and playbook automation. -Git connections enable integration with Git repositories across various platforms including GitHub, GitLab, Azure DevOps, and generic Git servers. +## Used By + +- [File Scraper](/docs/guide/config-db/scrapers/file) - Scrape configuration files from repositories +- [GitOps Action](/docs/guide/playbooks/actions/gitops) - Create commits and pull requests +- [Playbook Actions](/docs/guide/playbooks/actions) - Execute Git-related automation -## Example +## Authentication Methods ### HTTPS with Personal Access Token -```yaml title="git-https-connection.yaml" -apiVersion: v1 +```yaml title="https-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 kind: Connection metadata: name: github-repo - namespace: default spec: - type: git - url: https://github.com/organization/repository.git - username: github-user - password: - valueFrom: - secretKeyRef: - name: git-credentials - key: token - branch: main + git: + url: https://github.com/organization/repository.git + username: github-user + password: + valueFrom: + secretKeyRef: + name: git-credentials + key: token + branch: main ``` ### SSH with Private Key -```yaml title="git-ssh-connection.yaml" -apiVersion: v1 +```yaml title="ssh-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 kind: Connection metadata: name: gitlab-repo - namespace: default spec: - type: git - url: git@gitlab.com:organization/repository.git - certificate: - valueFrom: - secretKeyRef: - name: git-ssh-key - key: private-key - branch: develop -``` - -## Authentication Methods - -### 1. HTTPS with Username/Password -For HTTPS repositories using username and password or personal access tokens: - -```yaml -username: your-username -password: - valueFrom: - secretKeyRef: - name: git-credentials - key: password-or-token -``` - -### 2. SSH with Private Key -For SSH repositories using private key authentication: - -```yaml -certificate: - valueFrom: - secretKeyRef: - name: ssh-key - key: private-key -``` - -### 3. Connection Reference -Reference an existing connection for credentials: - -```yaml -connection: connection://git/my-git-connection + git: + url: git@gitlab.com:organization/repository.git + certificate: + valueFrom: + secretKeyRef: + name: git-ssh-key + key: private-key + branch: main ``` ## Supported Git Services -### GitHub -```yaml -type: github -url: https://github.com/owner/repo.git -``` - -### GitLab -```yaml -type: gitlab -url: https://gitlab.com/owner/repo.git -``` - -### Azure DevOps -```yaml -type: azure_devops -url: https://dev.azure.com/organization/project/_git/repository -``` - -### Generic Git -```yaml -type: git -url: https://git.example.com/repo.git -``` - -## Use Cases - -- **Source Code Access**: Clone repositories for configuration management -- **GitOps Workflows**: Sync configurations from Git repositories -- **CI/CD Integration**: Access repositories for build and deployment processes -- **Configuration Storage**: Store and retrieve configuration files from Git -- **Documentation**: Access documentation stored in Git repositories - -## Best Practices - -- **Access Tokens**: Use personal access tokens instead of passwords for better security -- **SSH Keys**: Prefer SSH keys for automated systems -- **Branch Strategy**: Specify explicit branches for predictable behavior -- **Credential Management**: Store credentials in Kubernetes secrets -- **Repository URLs**: Use consistent URL formats for your Git service \ No newline at end of file +| Service | Type | URL Format | +|---------|------|------------| +| GitHub | `github` | `https://github.com/owner/repo.git` | +| GitLab | `gitlab` | `https://gitlab.com/owner/repo.git` | +| Azure DevOps | `azure_devops` | `https://dev.azure.com/org/project/_git/repo` | +| Bitbucket | `git` | `https://bitbucket.org/owner/repo.git` | +| Generic Git | `git` | `https://git.example.com/repo.git` | diff --git a/mission-control/docs/reference/connections/github.mdx b/mission-control/docs/reference/connections/github.mdx index 08747f1b..287f6a3a 100644 --- a/mission-control/docs/reference/connections/github.mdx +++ b/mission-control/docs/reference/connections/github.mdx @@ -1,9 +1,62 @@ --- -title: Github +title: GitHub +description: Connect to GitHub for repository access, issue management, and workflow automation sidebar_custom_props: icon: github --- -import Github from '@site/docs/partials/_github.mdx' +GitHub connections enable integration with GitHub repositories and APIs for GitOps workflows, issue management, and pull request automation. - +## Used By + +- [GitHub Config Scraper](/docs/guide/config-db/scrapers/github) - Scrape GitHub resource configurations +- [GitHub Action](/docs/guide/playbooks/actions/github) - Create issues and pull requests +- [GitOps Action](/docs/guide/playbooks/actions/gitops) - Commit changes to repositories + + + +## Examples + +
+
+ +```yaml title="github-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: github +spec: + github: + personalAccessToken: + valueFrom: + secretKeyRef: + name: github-credentials + key: token +``` + +
+
+ +
+
+ +```yaml title="github-enterprise.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: github-enterprise +spec: + github: + url: https://github.mycompany.com/api/v3 + personalAccessToken: + valueFrom: + secretKeyRef: + name: github-enterprise-credentials + key: token +``` + +
+
diff --git a/mission-control/docs/reference/connections/gitlab.mdx b/mission-control/docs/reference/connections/gitlab.mdx index 06335872..9723fb9d 100644 --- a/mission-control/docs/reference/connections/gitlab.mdx +++ b/mission-control/docs/reference/connections/gitlab.mdx @@ -1,8 +1,61 @@ --- -title: Gitlab +title: GitLab +description: Connect to GitLab for repository access, issue management, and pipeline automation sidebar_custom_props: icon: gitlab --- -import Gitlab from '@site/docs/partials/_gitlab.mdx' - +GitLab connections enable integration with GitLab repositories and APIs for GitOps workflows, issue management, and merge request automation. + +## Used By + +- [GitOps Action](/docs/guide/playbooks/actions/gitops) - Create commits and merge requests +- [Playbook Actions](/docs/guide/playbooks/actions) - Execute GitLab-related automation + + + +## Examples + +
+
+ +```yaml title="gitlab-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: gitlab +spec: + gitlab: + personalAccessToken: + valueFrom: + secretKeyRef: + name: gitlab-credentials + key: token +``` + +
+
+ +
+
+ +```yaml title="gitlab-self-hosted.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: gitlab-self-hosted +spec: + gitlab: + url: https://gitlab.mycompany.com + personalAccessToken: + valueFrom: + secretKeyRef: + name: gitlab-credentials + key: token +``` + +
+
diff --git a/mission-control/docs/reference/connections/http.mdx b/mission-control/docs/reference/connections/http.mdx index 667dbbca..17bd94bc 100644 --- a/mission-control/docs/reference/connections/http.mdx +++ b/mission-control/docs/reference/connections/http.mdx @@ -1,67 +1,140 @@ --- title: HTTP +description: Connect to HTTP/HTTPS endpoints for API integrations, webhooks, and health checks sidebar_custom_props: icon: http --- - +HTTP connections enable integration with any HTTP/HTTPS endpoint for API access, webhook integrations, and health checks. -HTTP Connections are used to query data via any http/https compatible resource +## Used By -## Schema +- [HTTP Health Check](/docs/reference/canary-checker) - Monitor HTTP endpoints +- [HTTP Scraper](/docs/guide/config-db/scrapers/http) - Scrape configuration from APIs +- [HTTP Action](/docs/guide/playbooks/actions/http) - Make HTTP requests in playbooks +- [Notifications](/docs/guide/notifications) - Send webhook notifications -| Field | Description | Scheme | Required | -|--------------|-----------------|------------------------------------------------|----------| -| `url` | URL | string | `true` | -| `username` | Username | _EnvVar_ | | -| `password` | Password | _EnvVar_ | | -| `oauth` | OAuth | [OAuth](#oauth) | | -| `bearer` | Bearer | _EnvVar_ | | -| `tls` | TLS Config | [TLS](#tls) | | -| `connection` | Connection Name | string | | +## Schema -:::info -If connection is already created `connection` (Connection Name) can be used as a reference instead of redefining all fields. Read more on [connection referencing](/docs/reference/connections/#referencing-connections) -::: +| Field | Description | Scheme | Required | +|--------------|--------------------------------------------------------|------------------------------------------------|----------| +| `url` | Base URL for the HTTP endpoint | string | `true` | +| `username` | Username for basic authentication | _EnvVar_ | | +| `password` | Password for basic authentication | _EnvVar_ | | +| `oauth` | OAuth 2.0 client credentials configuration | [OAuth](#oauth) | | +| `bearer` | Bearer token for authentication | _EnvVar_ | | +| `tls` | TLS/SSL configuration for client certificates | [TLS](#tls) | | +| `connection` | Reference to an existing connection | string | | ### OAuth -| Field | Description | Scheme | Required | -|----------------|---------------|------------------------------------------------|----------| -| `tokenURL` | Token URL | string | `true` | -| `clientID` | Client ID | _EnvVar_ | `true` | -| `clientSecret` | Client Secret | _EnvVar_ | `true` | -| `scopes` | Scopes | []string | | -| `params` | Params | map[string]string | | +| Field | Description | Scheme | Required | +|----------------|--------------------------------------|------------------------------------------------|----------| +| `tokenURL` | OAuth token endpoint URL | string | `true` | +| `clientID` | OAuth client ID | _EnvVar_ | `true` | +| `clientSecret` | OAuth client secret | _EnvVar_ | `true` | +| `scopes` | OAuth scopes to request | []string | | +| `params` | Additional parameters for token request| map[string]string | | ### TLS -| Field | Description | Scheme | Required | -|----------------------|---------------------------------------------------------------------------------|------------------------------------------------|----------| -| `key` | PEM encoded client private key | _EnvVar_ | `true` | -| `ca` | PEM encoded certificate of the CA to verify the server certificate | _EnvVar_ | `true` | -| `cert` | PEM encoded client certificate | _EnvVar_ | `true` | -| `insecureSkipVerify` | controls whether a client verifies the server's certificate chain and host name | bool | | -| `handshakeTimeout` | Handshake timeout (Default: 10 seconds) | time.Duration | | +| Field | Description | Scheme | +|----------------------|---------------------------------------------------------------------------------|------------------------------------------------| +| `key` | PEM encoded client private key | _EnvVar_ | +| `ca` | PEM encoded certificate of the CA to verify the server certificate | _EnvVar_ | +| `cert` | PEM encoded client certificate | _EnvVar_ | +| `insecureSkipVerify` | Skip TLS certificate verification (not recommended for production) | bool | +| `handshakeTimeout` | TLS handshake timeout (default: 10 seconds) | time.Duration | +## Authentication Methods -## Example +### Basic Authentication -This example demonstrates how to configure an HTTP connection in Mission Control: - -```yaml title="http-connection.yaml" -apiVersion: v1 +```yaml title="basic-auth.yaml" +apiVersion: mission-control.flanksource.com/v1 kind: Connection metadata: - name: http-connection + name: api-basic spec: http: - url: https://example.com + url: https://api.example.com username: - value: user + value: api-user password: valueFrom: secretKeyRef: - name: credentials + name: api-credentials key: password ``` + +### Bearer Token + +```yaml title="bearer-token.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: api-bearer +spec: + http: + url: https://api.example.com + bearer: + valueFrom: + secretKeyRef: + name: api-credentials + key: token +``` + +### OAuth 2.0 Client Credentials + +```yaml title="oauth.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: api-oauth +spec: + http: + url: https://api.example.com + oauth: + tokenURL: https://auth.example.com/oauth/token + clientID: + valueFrom: + secretKeyRef: + name: oauth-credentials + key: client-id + clientSecret: + valueFrom: + secretKeyRef: + name: oauth-credentials + key: client-secret + scopes: + - read + - write +``` + +### Mutual TLS (mTLS) + +```yaml title="mtls.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: api-mtls +spec: + http: + url: https://secure-api.example.com + tls: + cert: + valueFrom: + secretKeyRef: + name: mtls-certs + key: client.crt + key: + valueFrom: + secretKeyRef: + name: mtls-certs + key: client.key + ca: + valueFrom: + secretKeyRef: + name: mtls-certs + key: ca.crt +``` diff --git a/mission-control/docs/reference/connections/index.mdx b/mission-control/docs/reference/connections/index.mdx index c97f7429..e852f44f 100644 --- a/mission-control/docs/reference/connections/index.mdx +++ b/mission-control/docs/reference/connections/index.mdx @@ -1,18 +1,40 @@ --- title: Connections +description: Secure credential management for integrating with external systems and services sidebar_position: 2 - sidebar_custom_props: icon: fluent:vault-24-filled --- -Connections are an easy way to authenticate against sources. It can be created via a CRD or by adding it in the settings page +Connections provide a secure, reusable way to authenticate against external systems and services. Instead of embedding credentials directly in your health checks, scrapers, and playbooks, you define connections once and reference them throughout your configuration. +## Benefits +- **Security**: Credentials are stored securely in Kubernetes secrets, not in plain text +- **Reusability**: Define once, use across multiple resources +- **Maintainability**: Update credentials in one place when they change +- **Auditability**: Track which resources use which connections -A sample connection CRD looks like: +## Connection Types -```yaml +| Category | Connections | +|----------|-------------| +| **Cloud Providers** | [AWS](./aws), [Azure](./azure), [GCP](./gcp) | +| **Kubernetes** | [Kubernetes](./kubernetes) | +| **Source Control** | [Git](./git), [GitHub](./github), [GitLab](./gitlab), [Azure DevOps](./azure-devops) | +| **Databases** | [Postgres](./postgres), [OpenSearch](./opensearch) | +| **File Storage** | [SFTP](./sftp), [SMB](./smb) | +| **AI Providers** | [OpenAI](./openai), [Anthropic](./anthropic), [Ollama](./ollama) | +| **Notifications** | [Slack](./slack), [Discord](./discord), [Telegram](./telegram), [SMTP](./smtp), [ntfy](./ntfy), [Pushbullet](./pushbullet), [Pushover](./pushover) | +| **Generic** | [HTTP](./http) | + +## Creating Connections + +Connections can be created via Kubernetes CRD or through the Mission Control UI. + +### Kubernetes CRD + +```yaml title="connection-example.yaml" apiVersion: mission-control.flanksource.com/v1 kind: Connection metadata: @@ -20,53 +42,125 @@ metadata: namespace: default spec: postgres: + host: + value: postgres.example.com database: value: payments - host: - value: postgres.host.com - insecureTLS: true username: valueFrom: secretKeyRef: - name: payments-database-credentials + name: postgres-credentials key: POSTGRES_USER password: valueFrom: secretKeyRef: - name: payments-database-credentials + name: postgres-credentials key: POSTGRES_PASSWORD ``` +### UI Configuration + +Connections can also be created through the Settings page in the Mission Control UI. This is useful for quick setup and for users who prefer a visual interface. + ## Referencing Connections -A connection string can be represented in the form of `namespace/connection_name` +Once created, connections can be referenced using the `connection://` URL scheme: -It can then be used in Health Checks, Playbooks, Notifications etc via the `connection` field. +``` +connection://[namespace]/[connection-name] +``` -```yaml +### Example Usage + +```yaml title="canary-with-connection.yaml" apiVersion: canaries.flanksource.com/v1 kind: Canary metadata: name: postgres-check spec: postgres: - - name: postgres schemas check + - name: Database Health Check connection: connection://default/payments-database - query: SELECT COUNT(*) FROM payments where state = 'pending' + query: SELECT 1 ``` -This allows us a safe and reusable way to handle authentication - :::tip -The connection string can also be found in the `status.ref` field of the connection kubernetes object. +The connection string can be found in the `status.ref` field of the Connection Kubernetes object. ::: -:::tip -If the entire URL is in the secrets and cannot be constructed like `scheme://$(username):$(password)@:` you can fetch that directly like +## Credential Sources + +Connection fields support multiple ways to specify values: + +### Direct Value + +```yaml +host: + value: postgres.example.com +``` + +### From Kubernetes Secret + ```yaml +password: + valueFrom: + secretKeyRef: + name: my-secret + key: password +``` + +### From ConfigMap + +```yaml +host: + valueFrom: + configMapKeyRef: + name: my-config + key: database-host +``` + +### From Helm Values + +```yaml +password: + valueFrom: + helmRef: + name: my-release + key: database.password +``` + +## URL Template Pattern + +For connections where all credentials are embedded in a URL, you can use variable substitution: + +```yaml title="connection-url-template.yaml" +apiVersion: mission-control.flanksource.com/v1 kind: Connection metadata: name: opensearch-global +spec: + type: opensearch + url: + value: "https://$(username):$(password)@opensearch.example.com:9200" + username: + valueFrom: + secretKeyRef: + name: opensearch-credentials + key: OPENSEARCH_USER + password: + valueFrom: + secretKeyRef: + name: opensearch-credentials + key: OPENSEARCH_PASSWORD +``` + +:::tip +If the entire URL is stored in a secret, you can fetch it directly: + +```yaml +kind: Connection +metadata: + name: opensearch-from-url spec: type: opensearch url: @@ -77,24 +171,24 @@ spec: name: opensearch-credentials key: OPENSEARCH_URL ``` - ::: ## Schema -| **Field** | **Description** | **Scheme** | **Required** | -|--------------|-------------------------------------------------------|------------------------------------------------|--------------| -| url | URL in templatable form | *EnvVar* | yes | -| port | Port number | *EnvVar* | | -| type | Type of datasource (postgres,mysql,elasticsearch ...) | string | | -| username | Username | *EnvVar* | | -| password | Password | *EnvVar* | | -| certificate | Certificate for verification | *EnvVar* | | -| properties | Property fields | map[string]string | | -| insecure_tls | Allow insecure tls | bool | | +| Field | Description | Scheme | Required | +|----------------|---------------------------------------------------|-------------------------------------------|----------| +| `url` | URL in templatable form | *EnvVar* | | +| `port` | Port number | *EnvVar* | | +| `type` | Type of datasource (postgres, mysql, etc.) | string | | +| `username` | Username for authentication | *EnvVar* | | +| `password` | Password for authentication | *EnvVar* | | +| `certificate` | Certificate for verification | *EnvVar* | | +| `properties` | Additional property fields | map[string]string | | +| `insecure_tls` | Skip TLS certificate verification | bool | | -## Permission +## Permissions -To use a connection, a principal needs to have the `read` permission on the connection. +To use a connection, a principal needs the `read` permission on the connection resource. -```yaml title="connection-permission.yaml" file=/modules/mission-control/fixtures/permissions/playbook-connection-read.yaml \ No newline at end of file +```yaml title="connection-permission.yaml" file=/modules/mission-control/fixtures/permissions/playbook-connection-read.yaml +``` diff --git a/mission-control/docs/reference/connections/kubernetes.mdx b/mission-control/docs/reference/connections/kubernetes.mdx index 0a905230..4f7873cf 100644 --- a/mission-control/docs/reference/connections/kubernetes.mdx +++ b/mission-control/docs/reference/connections/kubernetes.mdx @@ -1,67 +1,137 @@ --- title: Kubernetes +description: Connect to Kubernetes clusters for health checks, config scraping, and playbook actions sidebar_custom_props: icon: k8s --- - +Kubernetes connections enable integration with Kubernetes clusters for health checks, configuration scraping, and playbook automation. -Kubernetes connections enable integration with Kubernetes clusters across different cloud providers and environments. -You can configure connections to AWS EKS clusters, Google Cloud GKE instances, and Config Connector (CNRM) implementations. +## Used By + +- [Kubernetes Config Scraper](/docs/guide/config-db/scrapers/kubernetes) - Scrape Kubernetes resource configurations +- [Pod Exec Action](/docs/guide/playbooks/actions/exec) - Execute commands in pods +- [Playbook Actions](/docs/guide/playbooks/actions) - Execute Kubernetes automation :::note -One of the four sources of connection details must be provided. +One of the connection types must be provided: kubeconfig, EKS, GKE, or CNRM. ::: +## Connection Types + +### Kubeconfig + +Connect using a kubeconfig file: + +```yaml title="kubeconfig-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: remote-cluster +spec: + kubernetes: + kubeconfig: + valueFrom: + secretKeyRef: + name: cluster-credentials + key: kubeconfig +``` + ### EKS Connection +Connect to Amazon EKS clusters: + +```yaml title="eks-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: eks-production +spec: + kubernetes: + eks: + cluster: my-eks-cluster + region: us-east-1 + accessKey: + valueFrom: + secretKeyRef: + name: aws-credentials + key: AWS_ACCESS_KEY_ID + secretKey: + valueFrom: + secretKeyRef: + name: aws-credentials + key: AWS_SECRET_ACCESS_KEY +``` + ### GKE Connection +Connect to Google Kubernetes Engine clusters: + +```yaml title="gke-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: gke-production +spec: + kubernetes: + gke: + project: my-gcp-project + zone: us-central1-a + cluster: my-gke-cluster + credentials: + valueFrom: + secretKeyRef: + name: gcp-credentials + key: service-account.json +``` + ### CNRM Connection +Connect via Config Connector for GCP-managed clusters: + + +## Examples + +
+
+ +```yaml title="ntfy-public.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: ntfy-alerts +spec: + ntfy: + host: https://ntfy.sh + topic: my-alerts-topic +``` + +
+
+ +
+
+ +```yaml title="ntfy-self-hosted.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: ntfy-private +spec: + ntfy: + host: https://ntfy.internal.example.com + topic: infrastructure-alerts + username: + valueFrom: + secretKeyRef: + name: ntfy-credentials + key: username + password: + valueFrom: + secretKeyRef: + name: ntfy-credentials + key: password +``` + +
+
+ +## Next Steps + +- [ntfy Channel Guide](/docs/guide/notifications/channels/ntfy) - Configure ntfy notifications diff --git a/mission-control/docs/reference/connections/ollama.mdx b/mission-control/docs/reference/connections/ollama.mdx index 9c05fe55..2adfc342 100644 --- a/mission-control/docs/reference/connections/ollama.mdx +++ b/mission-control/docs/reference/connections/ollama.mdx @@ -1,9 +1,16 @@ --- title: Ollama +description: Connect to local Ollama instances for self-hosted AI-powered playbook actions sidebar_custom_props: icon: ollama --- +Ollama connections enable integration with locally hosted Ollama instances for AI-powered playbook actions without external API dependencies. + +## Used By + +- [AI Action](/docs/guide/playbooks/actions/ai) - Use self-hosted AI for log analysis and automation + ## Example @@ -12,10 +19,10 @@ sidebar_custom_props: apiVersion: mission-control.flanksource.com/v1 kind: Connection metadata: - name: ollama + name: ollama-local spec: ollama: model: llama3.1:8b url: - value: http://localhost:11434 + value: http://ollama.ollama-system.svc:11434 ``` diff --git a/mission-control/docs/reference/connections/openai.mdx b/mission-control/docs/reference/connections/openai.mdx index 9efa0d30..0c5d04e0 100644 --- a/mission-control/docs/reference/connections/openai.mdx +++ b/mission-control/docs/reference/connections/openai.mdx @@ -1,19 +1,28 @@ --- title: OpenAI +description: Connect to OpenAI API for AI-powered playbook actions and analysis sidebar_custom_props: icon: openai --- +OpenAI connections enable integration with OpenAI's API for AI-powered playbook actions, automated analysis, and intelligent response generation. + +## Used By + +- [AI Action](/docs/guide/playbooks/actions/ai) - Use AI for log analysis, incident summarization, and automated troubleshooting + -## Example +## Examples -```yaml +
+
+ +```yaml title="openai-connection.yaml" apiVersion: mission-control.flanksource.com/v1 kind: Connection metadata: name: openai-gpt4 - namespace: default spec: openai: model: @@ -21,6 +30,33 @@ spec: apiKey: valueFrom: secretKeyRef: - name: openai + name: openai-credentials key: API_KEY ``` + +
+
+ +
+
+ +```yaml title="azure-openai.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: azure-openai +spec: + openai: + model: + value: gpt-4 + apiKey: + valueFrom: + secretKeyRef: + name: azure-openai-credentials + key: API_KEY + baseURL: + value: https://my-resource.openai.azure.com/openai/deployments/gpt-4 +``` + +
+
diff --git a/mission-control/docs/reference/connections/opensearch.mdx b/mission-control/docs/reference/connections/opensearch.mdx new file mode 100644 index 00000000..74d76633 --- /dev/null +++ b/mission-control/docs/reference/connections/opensearch.mdx @@ -0,0 +1,69 @@ +--- +title: OpenSearch +description: Connect to OpenSearch clusters for log queries, search operations, and monitoring +sidebar_custom_props: + icon: opensearch +--- + +OpenSearch connections enable integration with OpenSearch and Elasticsearch clusters for log queries, search operations, and monitoring. + +## Used By + +- [Log Scraper](/docs/guide/config-db/scrapers/logs) - Scrape logs from OpenSearch +- [Logs Action](/docs/guide/playbooks/actions/logs) - Query logs in playbooks + + + +## Example + +```yaml title="opensearch-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: opensearch-logs + namespace: default +spec: + opensearch: + urls: + - https://opensearch-node1.example.com:9200 + - https://opensearch-node2.example.com:9200 + index: logs-* + username: + valueFrom: + secretKeyRef: + name: opensearch-credentials + key: OPENSEARCH_USER + password: + valueFrom: + secretKeyRef: + name: opensearch-credentials + key: OPENSEARCH_PASSWORD + insecureSkipVerify: false +``` diff --git a/mission-control/docs/reference/connections/postgres.mdx b/mission-control/docs/reference/connections/postgres.mdx index 4cd6c48b..31b13f1d 100644 --- a/mission-control/docs/reference/connections/postgres.mdx +++ b/mission-control/docs/reference/connections/postgres.mdx @@ -1,10 +1,58 @@ --- title: Postgres +description: Connect to PostgreSQL databases for health checks, queries, and playbook actions sidebar_custom_props: icon: postgres --- -```yaml +PostgreSQL connections enable integration with PostgreSQL databases for health checks, SQL queries in playbooks, and database monitoring. + +## Used By + +- [Postgres Health Check](/docs/reference/canary-checker) - Verify database connectivity and run health queries +- [SQL Action](/docs/guide/playbooks/actions/sql) - Execute SQL queries in playbooks +- [Postgres Scraper](/docs/guide/config-db/scrapers/postgres) - Scrape database configurations + + + +## Example + +```yaml title="postgres-connection.yaml" apiVersion: mission-control.flanksource.com/v1 kind: Connection metadata: @@ -12,43 +60,20 @@ metadata: namespace: default spec: postgres: + host: + value: postgres.example.com + port: 5432 database: value: payments - host: - value: postgres.host.com - insecureTLS: true username: valueFrom: secretKeyRef: - name: payments-database-credentials + name: postgres-credentials key: POSTGRES_USER password: valueFrom: secretKeyRef: - name: payments-database-credentials + name: postgres-credentials key: POSTGRES_PASSWORD + insecureTLS: false ``` - - diff --git a/mission-control/docs/reference/connections/pushbullet.mdx b/mission-control/docs/reference/connections/pushbullet.mdx new file mode 100644 index 00000000..f9032072 --- /dev/null +++ b/mission-control/docs/reference/connections/pushbullet.mdx @@ -0,0 +1,50 @@ +--- +title: Pushbullet +description: Connect to Pushbullet for push notifications across devices +sidebar_custom_props: + icon: pushbullet +--- + +Pushbullet connections enable sending push notifications to phones, tablets, and browsers via the Pushbullet service. + +## Used By + +- [Notifications](/docs/guide/notifications) - Send push notifications +- [Notification Action](/docs/guide/playbooks/actions/notification) - Send notifications from playbooks + + + +## Example + +```yaml title="pushbullet-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: pushbullet-alerts +spec: + pushbullet: + token: + valueFrom: + secretKeyRef: + name: pushbullet-credentials + key: ACCESS_TOKEN + targets: + - "" # Empty string sends to all devices +``` + +## Next Steps + +- [Pushbullet Channel Guide](/docs/guide/notifications/channels/pushbullet) - Configure Pushbullet notifications diff --git a/mission-control/docs/reference/connections/pushover.mdx b/mission-control/docs/reference/connections/pushover.mdx new file mode 100644 index 00000000..cf418500 --- /dev/null +++ b/mission-control/docs/reference/connections/pushover.mdx @@ -0,0 +1,68 @@ +--- +title: Pushover +description: Connect to Pushover for push notifications to mobile devices +sidebar_custom_props: + icon: pushover +--- + +Pushover connections enable sending push notifications to iOS and Android devices via the Pushover service. + +## Used By + +- [Notifications](/docs/guide/notifications) - Send push notifications +- [Notification Action](/docs/guide/playbooks/actions/notification) - Send notifications from playbooks + + + +## Example + +```yaml title="pushover-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: pushover-alerts +spec: + pushover: + token: + valueFrom: + secretKeyRef: + name: pushover-credentials + key: API_TOKEN + user: + valueFrom: + secretKeyRef: + name: pushover-credentials + key: USER_KEY +``` + +## Next Steps + +- [Pushover Channel Guide](/docs/guide/notifications/channels/pushover) - Configure Pushover notifications diff --git a/mission-control/docs/reference/connections/sftp.mdx b/mission-control/docs/reference/connections/sftp.mdx index cd53801d..dded71fa 100644 --- a/mission-control/docs/reference/connections/sftp.mdx +++ b/mission-control/docs/reference/connections/sftp.mdx @@ -1,52 +1,64 @@ --- title: SFTP +description: Connect to SFTP servers for file transfers and backup monitoring sidebar_custom_props: icon: sftp --- - +SFTP connections enable secure file transfer protocol integration for file operations, backup monitoring, and file-based health checks. + +## Used By + +- [Folder Health Check](/docs/reference/canary-checker) - Check file existence and age on SFTP servers +- [File Scraper](/docs/guide/config-db/scrapers/file) - Scrape configuration files from SFTP -## Example +## Authentication Methods -```yaml -apiVersion: v1 -kind: Secret -metadata: - name: sftp-connection -type: Opaque -data: - host: c3RlcC5leGFtcGxlLmNvbQ== # base64 encoded value of "step.example.com" - username: dXNlcm5hbWU= # base64 encoded value of "username" - password: cGFzc3dvcmQ= # base64 encoded value of "password" ---- -apiVersion: mission-control/v1 +### Password Authentication + +```yaml title="sftp-password.yaml" +apiVersion: mission-control.flanksource.com/v1 kind: Connection metadata: - name: example-sftp + name: sftp-backups spec: sftp: host: - valueFrom: - secretKeyRef: - name: sftp-connection - key: host + value: sftp.example.com + port: 22 username: valueFrom: secretKeyRef: - name: sftp-connection + name: sftp-credentials key: username password: valueFrom: secretKeyRef: - name: sftp-connection + name: sftp-credentials key: password - port: 22 - path: /upload + path: /backups ``` -This example: -1. Creates a Kubernetes Secret to store the SFTP connection details. -2. Defines a Connection resource that references the secret for the SFTP connection. -3. Specifies the SFTP server's host, username, password, port, and path. +### SSH Key Authentication + +```yaml title="sftp-ssh-key.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: sftp-ssh +spec: + sftp: + host: + value: sftp.example.com + port: 22 + username: + value: backup-user + certificate: + valueFrom: + secretKeyRef: + name: sftp-ssh-key + key: private-key + path: /data +``` diff --git a/mission-control/docs/reference/connections/slack.mdx b/mission-control/docs/reference/connections/slack.mdx new file mode 100644 index 00000000..337a31f7 --- /dev/null +++ b/mission-control/docs/reference/connections/slack.mdx @@ -0,0 +1,75 @@ +--- +title: Slack +description: Connect to Slack for sending notifications and alerts +sidebar_custom_props: + icon: slack +--- + +Slack connections enable sending notifications, alerts, and messages to Slack channels. + +## Used By + +- [Notifications](/docs/guide/notifications) - Send alerts to Slack channels +- [Notification Action](/docs/guide/playbooks/actions/notification) - Send messages from playbooks + + + +## Example + +```yaml title="slack-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: slack-alerts +spec: + slack: + token: + valueFrom: + secretKeyRef: + name: slack-credentials + key: BOT_TOKEN + channel: C0123456789 + botName: Mission Control + icon: ":robot_face:" +``` + +## Next Steps + +- [Slack Channel Guide](/docs/guide/notifications/channels/slack) - Configure Slack notifications diff --git a/mission-control/docs/reference/connections/smb.mdx b/mission-control/docs/reference/connections/smb.mdx index b77f66c8..0c1a2cd5 100644 --- a/mission-control/docs/reference/connections/smb.mdx +++ b/mission-control/docs/reference/connections/smb.mdx @@ -1,26 +1,41 @@ --- title: SMB / CIFS +description: Connect to Windows file shares for file operations and backup monitoring sidebar_custom_props: icon: microsoft --- - +SMB (Server Message Block) / CIFS (Common Internet File System) connections enable integration with Windows file shares and network-attached storage for file operations and backup monitoring. -```yaml -apiVersion: v1 +## Used By + +- [Folder Health Check](/docs/reference/canary-checker) - Check file existence and age on Windows shares +- [File Scraper](/docs/guide/config-db/scrapers/file) - Scrape configuration files from SMB shares + + + +## Example + +```yaml title="smb-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 kind: Connection metadata: - name: example-smb-connection + name: windows-share spec: smb: - server: "smb.example.com" - username: "exampleUser" - password: "examplePassword" + server: fileserver.example.com + share: backups port: 445 - share: "exampleShare" + username: + valueFrom: + secretKeyRef: + name: smb-credentials + key: username + password: + valueFrom: + secretKeyRef: + name: smb-credentials + key: password ``` - - - - +For domain authentication, use the format `DOMAIN\\username` for the username field. diff --git a/mission-control/docs/reference/connections/smtp.mdx b/mission-control/docs/reference/connections/smtp.mdx new file mode 100644 index 00000000..7eac123a --- /dev/null +++ b/mission-control/docs/reference/connections/smtp.mdx @@ -0,0 +1,100 @@ +--- +title: SMTP +description: Connect to SMTP servers for sending email notifications +sidebar_custom_props: + icon: email +--- + +SMTP connections enable sending email notifications via SMTP servers. + +## Used By + +- [Notifications](/docs/guide/notifications) - Send email alerts +- [Notification Action](/docs/guide/playbooks/actions/notification) - Send emails from playbooks + + + +## Example + +```yaml title="smtp-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: email-alerts +spec: + smtp: + host: smtp.example.com + port: 587 + username: + valueFrom: + secretKeyRef: + name: smtp-credentials + key: username + password: + valueFrom: + secretKeyRef: + name: smtp-credentials + key: password + fromAddress: alerts@example.com + encryption: Auto + auth: Plain +``` + +## Next Steps + +- [Email Channel Guide](/docs/guide/notifications/channels/email) - Configure email notifications diff --git a/mission-control/docs/reference/connections/telegram.mdx b/mission-control/docs/reference/connections/telegram.mdx new file mode 100644 index 00000000..b79970cd --- /dev/null +++ b/mission-control/docs/reference/connections/telegram.mdx @@ -0,0 +1,52 @@ +--- +title: Telegram +description: Connect to Telegram for sending notifications and alerts via bot +sidebar_custom_props: + icon: telegram +--- + +Telegram connections enable sending notifications and alerts to Telegram chats via a bot. + +## Used By + +- [Notifications](/docs/guide/notifications) - Send alerts to Telegram chats +- [Notification Action](/docs/guide/playbooks/actions/notification) - Send messages from playbooks + + + +## Example + +```yaml title="telegram-connection.yaml" +apiVersion: mission-control.flanksource.com/v1 +kind: Connection +metadata: + name: telegram-alerts +spec: + telegram: + token: + valueFrom: + secretKeyRef: + name: telegram-credentials + key: BOT_TOKEN + chats: + value: "-1001234567890" +``` + +Note: Group chat IDs start with `-100` prefix. + +## Next Steps + +- [Telegram Channel Guide](/docs/guide/notifications/channels/telegram) - Configure Telegram notifications diff --git a/mission-control/docs/reference/playbooks/events.md b/mission-control/docs/reference/playbooks/events.md index b44de5c4..07721165 100644 --- a/mission-control/docs/reference/playbooks/events.md +++ b/mission-control/docs/reference/playbooks/events.md @@ -18,6 +18,16 @@ Filters can give you fine-grained control over the events that can trigger the p Canary events relate to activities on health checks. +## Component + +Component events relate to changes in component health status. + +| Event | Description | +| ----------- | ---------------------------------------- | +| `healthy` | When a component becomes healthy | +| `unhealthy` | When a component becomes unhealthy | +| `warning` | When a component enters a warning state | + | Event | Description | | -------- | ------------------------------------- | | `passed` | When a previously failed check passes | diff --git a/mission-control/docusaurus.config.ts b/mission-control/docusaurus.config.ts index 466d55c1..3cee7193 100644 --- a/mission-control/docusaurus.config.ts +++ b/mission-control/docusaurus.config.ts @@ -52,24 +52,191 @@ export default async function createConfigAsync() { // } // ], + ['docusaurus-plugin-llms', + { + generateLLMsTxt: false, + generateLLMsFullTxt: true, + docsDir: 'docs', + title: 'Mission Control Documentation', + description: 'Flanksource Mission Control - Internal Developer Platform for Kubernetes', + excludeImports: true, + removeDuplicateHeadings: true, + customLLMFiles: [ + // Guide sections (full content only - index files generated by move-llms.js) + { + filename: 'llms-guide-full.txt', + includePatterns: ['docs/guide/**/*.md', 'docs/guide/**/*.mdx'], + fullContent: true, + title: 'Mission Control User Guide', + description: 'User guides for Flanksource Mission Control' + }, + { + filename: 'llms-guide-config-db-full.txt', + includePatterns: ['docs/guide/config-db/**/*.md', 'docs/guide/config-db/**/*.mdx'], + fullContent: true, + title: 'Config DB Guide', + description: 'Configuration database user guide' + }, + { + filename: 'llms-guide-notifications-full.txt', + includePatterns: ['docs/guide/notifications/**/*.md', 'docs/guide/notifications/**/*.mdx'], + fullContent: true, + title: 'Notifications Guide', + description: 'Notifications user guide' + }, + { + filename: 'llms-guide-playbooks-full.txt', + includePatterns: ['docs/guide/playbooks/**/*.md', 'docs/guide/playbooks/**/*.mdx'], + fullContent: true, + title: 'Playbooks Guide', + description: 'Playbooks user guide' + }, + { + filename: 'llms-guide-views-full.txt', + includePatterns: ['docs/guide/views/**/*.md', 'docs/guide/views/**/*.mdx'], + fullContent: true, + title: 'Views Guide', + description: 'Views user guide' + }, + { + filename: 'llms-guide-permissions-full.txt', + includePatterns: ['docs/guide/permissions/**/*.md', 'docs/guide/permissions/**/*.mdx'], + fullContent: true, + title: 'Permissions Guide', + description: 'Permissions user guide' + }, + // Reference sections (full content only) + { + filename: 'llms-reference-full.txt', + includePatterns: ['docs/reference/**/*.md', 'docs/reference/**/*.mdx'], + fullContent: true, + title: 'Mission Control Reference', + description: 'Reference documentation for Flanksource Mission Control' + }, + { + filename: 'llms-reference-canary-checker-full.txt', + includePatterns: ['docs/reference/canary-checker/**/*.md', 'docs/reference/canary-checker/**/*.mdx'], + fullContent: true, + title: 'Health Checks Reference', + description: 'Health checks (canary-checker) reference documentation' + }, + { + filename: 'llms-reference-config-db-full.txt', + includePatterns: ['docs/reference/config-db/**/*.md', 'docs/reference/config-db/**/*.mdx'], + fullContent: true, + title: 'Config DB Reference', + description: 'Configuration database reference documentation' + }, + { + filename: 'llms-reference-notifications-full.txt', + includePatterns: ['docs/reference/notifications/**/*.md', 'docs/reference/notifications/**/*.mdx'], + fullContent: true, + title: 'Notifications Reference', + description: 'Notifications reference documentation' + }, + { + filename: 'llms-reference-playbooks-full.txt', + includePatterns: ['docs/reference/playbooks/**/*.md', 'docs/reference/playbooks/**/*.mdx'], + fullContent: true, + title: 'Playbooks Reference', + description: 'Playbooks reference documentation' + }, + { + filename: 'llms-reference-permissions-full.txt', + includePatterns: ['docs/reference/permissions/**/*.md', 'docs/reference/permissions/**/*.mdx'], + fullContent: true, + title: 'Permissions Reference', + description: 'Permissions reference documentation' + }, + { + filename: 'llms-reference-connections-full.txt', + includePatterns: ['docs/reference/connections/**/*.md', 'docs/reference/connections/**/*.mdx'], + fullContent: true, + title: 'Connections Reference', + description: 'Connections reference documentation' + }, + // CEL and Go Template llms.txt files are generated by move-llms.js + // since the source files are symlinked from canary-checker + // Integrations + { + filename: 'llms-integrations-full.txt', + includePatterns: ['docs/integrations/**/*.md', 'docs/integrations/**/*.mdx'], + fullContent: true, + title: 'Mission Control Integrations', + description: 'Integration guides for Flanksource Mission Control' + }, + // Installation + { + filename: 'llms-installation-full.txt', + includePatterns: ['docs/installation/**/*.md', 'docs/installation/**/*.mdx'], + fullContent: true, + title: 'Mission Control Installation', + description: 'Installation guides for Flanksource Mission Control' + }, + ], + } + ], + ['@docusaurus/plugin-client-redirects', { fromExtensions: ['html', 'htm'], // /myPage.html -> /myPage toExtensions: ['exe', 'zip'], // /myAsset -> /myAsset.zip (if latter exists) redirects: [ - // /docs/oldDoc -> /docs/newDoc - // { - // to: '/docs/guide/canary-checker/reference/sql', - // from: ['/docs/guide/canary-checker/reference/postgres', '/docs/guide/canary-checker/reference/mysql', '/docs/guide/canary-checker/reference/mssql'], - // }, - - // { - // to: '/docs/guide/canary-checker/reference/folder#s3', - // from: '/docs/guide/canary-checker/reference/s3-bucket', - // }, - - // Redirects removed - marketing pages now at root, docs at /docs/ - + // Notification connections moved from Notifications/ to connections/ + { + to: '/docs/reference/connections/slack', + from: '/docs/reference/connections/Notifications/slack', + }, + { + to: '/docs/reference/connections/discord', + from: '/docs/reference/connections/Notifications/discord', + }, + { + to: '/docs/reference/connections/telegram', + from: '/docs/reference/connections/Notifications/telegram', + }, + { + to: '/docs/reference/connections/smtp', + from: '/docs/reference/connections/Notifications/smtp', + }, + { + to: '/docs/reference/connections/ntfy', + from: '/docs/reference/connections/Notifications/ntfy', + }, + { + to: '/docs/reference/connections/pushbullet', + from: '/docs/reference/connections/Notifications/pushbullet', + }, + { + to: '/docs/reference/connections/pushover', + from: '/docs/reference/connections/Notifications/pushover', + }, + // Permissions concepts moved up one level + { + to: '/docs/guide/permissions/roles', + from: '/docs/guide/permissions/concepts/rbac', + }, + { + to: '/docs/guide/permissions/multi-tenancy', + from: '/docs/guide/permissions/concepts/abac', + }, + { + to: '/docs/guide/permissions/multi-tenancy', + from: '/docs/guide/permissions/abac', + }, + { + to: '/docs/guide/permissions/multi-tenancy', + from: '/docs/guide/permissions/concepts/multi-tenancy', + }, + { + to: '/docs/guide/permissions/roles', + from: '/docs/guide/permissions/concepts', + }, + // RBAC renamed to Roles + { + to: '/docs/guide/permissions/roles', + from: '/docs/guide/permissions/rbac', + }, ], }], diff --git a/mission-control/package.json b/mission-control/package.json index d1db1a9a..a5e32e67 100644 --- a/mission-control/package.json +++ b/mission-control/package.json @@ -5,14 +5,14 @@ "scripts": { "docusaurus": "docusaurus", "start": "tailwindcss -i ./src/css/custom.css -o ./src/css/out.css && docusaurus start -p 3005", - "build": "tailwindcss -i ./src/css/custom.css -o ./src/css/out.css && docusaurus build", + "build": "tailwindcss -i ./src/css/custom.css -o ./src/css/out.css && docusaurus build && node scripts/move-llms.js", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", "clear": "docusaurus clear", "serve": "docusaurus serve", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", - "render-for-context7": "INIT_CWD=$(pwd) ../scripts/goja-mdx-renderer/run.sh" + "move-llms": "node scripts/move-llms.js" }, "dependencies": { "@docusaurus/core": "3.7.0", @@ -48,6 +48,7 @@ "util": "^0.12.5" }, "devDependencies": { + "docusaurus-plugin-llms": "^0.2.2", "@babel/core": "^7.28.5", "@babel/preset-env": "^7.28.5", "@babel/preset-react": "^7.28.5", diff --git a/mission-control/scripts/move-llms.js b/mission-control/scripts/move-llms.js new file mode 100644 index 00000000..4bc283ba --- /dev/null +++ b/mission-control/scripts/move-llms.js @@ -0,0 +1,269 @@ +#!/usr/bin/env node + +const fs = require('fs'); +const path = require('path'); + +const BUILD_DIR = path.join(__dirname, '..', 'build'); +const DOCS_DIR = path.join(__dirname, '..', 'docs'); +const CANARY_CHECKER_SCRIPTING = path.join(__dirname, '..', '..', 'canary-checker', 'docs', 'scripting'); +const BASE_URL = 'https://flanksource.com'; + +const MAPPINGS = [ + { pattern: /^llms-guide-config-db-full\.txt$/, dest: 'docs/guide/config-db' }, + { pattern: /^llms-guide-notifications-full\.txt$/, dest: 'docs/guide/notifications' }, + { pattern: /^llms-guide-playbooks-full\.txt$/, dest: 'docs/guide/playbooks' }, + { pattern: /^llms-guide-views-full\.txt$/, dest: 'docs/guide/views' }, + { pattern: /^llms-guide-permissions-full\.txt$/, dest: 'docs/guide/permissions' }, + { pattern: /^llms-guide-full\.txt$/, dest: 'docs/guide' }, + { pattern: /^llms-reference-canary-checker-full\.txt$/, dest: 'docs/reference/canary-checker' }, + { pattern: /^llms-reference-config-db-full\.txt$/, dest: 'docs/reference/config-db' }, + { pattern: /^llms-reference-notifications-full\.txt$/, dest: 'docs/reference/notifications' }, + { pattern: /^llms-reference-playbooks-full\.txt$/, dest: 'docs/reference/playbooks' }, + { pattern: /^llms-reference-permissions-full\.txt$/, dest: 'docs/reference/permissions' }, + { pattern: /^llms-reference-connections-full\.txt$/, dest: 'docs/reference/connections' }, + { pattern: /^llms-reference-full\.txt$/, dest: 'docs/reference' }, + { pattern: /^llms-integrations-full\.txt$/, dest: 'docs/integrations' }, + { pattern: /^llms-installation-full\.txt$/, dest: 'docs/installation' }, + { pattern: /^llms-full\.txt$/, dest: 'docs' }, +]; + +const SECTIONS_WITH_LLMS = [ + { path: '/docs', name: 'Documentation', description: 'Mission Control documentation' }, + { path: '/docs/guide', name: 'User Guide', description: 'User guides for Mission Control' }, + { path: '/docs/guide/config-db', name: 'Config DB Guide', description: 'Configuration database guide' }, + { path: '/docs/guide/notifications', name: 'Notifications Guide', description: 'Notifications guide' }, + { path: '/docs/guide/playbooks', name: 'Playbooks Guide', description: 'Playbooks guide' }, + { path: '/docs/guide/views', name: 'Views Guide', description: 'Views and dashboards guide' }, + { path: '/docs/guide/permissions', name: 'Permissions Guide', description: 'Permissions and access control guide' }, + { path: '/docs/reference', name: 'Reference', description: 'API and configuration reference' }, + { path: '/docs/reference/canary-checker', name: 'Health Checks Reference', description: 'Health checks reference' }, + { path: '/docs/reference/config-db', name: 'Config DB Reference', description: 'Config DB reference' }, + { path: '/docs/reference/notifications', name: 'Notifications Reference', description: 'Notifications reference' }, + { path: '/docs/reference/playbooks', name: 'Playbooks Reference', description: 'Playbooks reference' }, + { path: '/docs/reference/connections', name: 'Connections Reference', description: 'Connections reference' }, + { path: '/docs/reference/scripting/cel', name: 'CEL Reference', description: 'CEL expression language reference' }, + { path: '/docs/reference/scripting/gotemplate', name: 'Go Template Reference', description: 'Go template reference' }, + { path: '/docs/integrations', name: 'Integrations', description: 'Integration guides' }, + { path: '/docs/installation', name: 'Installation', description: 'Installation guides' }, +]; + +function parseSitemap() { + const sitemapPath = path.join(BUILD_DIR, 'sitemap.xml'); + if (!fs.existsSync(sitemapPath)) { + console.error('sitemap.xml not found'); + return []; + } + + const content = fs.readFileSync(sitemapPath, 'utf-8'); + const urls = []; + const regex = /([^<]+)<\/loc>/g; + let match; + + while ((match = regex.exec(content)) !== null) { + urls.push(match[1]); + } + + return urls; +} + +function stripMdxToLlms(content, title, description, sourcePath) { + const lines = content.split('\n'); + let frontmatterCount = 0; + const outputLines = [ + `# ${title}`, + '', + `> ${description}`, + '', + 'This file contains the full documentation content following the llmstxt.org standard.', + '', + `- Source: ${sourcePath}`, + '' + ]; + + for (const line of lines) { + if (line.trim() === '---') { + frontmatterCount++; + if (frontmatterCount <= 2) continue; + } + if (frontmatterCount < 2) continue; + if (line.startsWith('import ')) continue; + + let processedLine = line + .replace(/<[^>]*>/g, '') + .replace(/:::tip/g, '> **Tip:**') + .replace(/:::note/g, '> **Note:**') + .replace(/:::warning/g, '> **Warning:**') + .replace(/:::/g, '') + .replace(/```yaml title=[^`]*/g, '```yaml') + .replace(/```go title=[^`]*/g, '```go') + .replace(/\/\/highlight-next-line/g, ''); + + outputLines.push(processedLine); + } + + return outputLines.join('\n'); +} + +function generateScriptingLlms() { + const scriptingDir = path.join(BUILD_DIR, 'docs', 'reference', 'scripting'); + + const files = [ + { + src: path.join(CANARY_CHECKER_SCRIPTING, 'cel.mdx'), + dest: path.join(scriptingDir, 'cel', 'llms.txt'), + title: 'CEL Expression Language Reference', + description: 'Common Expression Language (CEL) reference for Flanksource Mission Control', + sourcePath: '/docs/reference/scripting/cel' + }, + { + src: path.join(CANARY_CHECKER_SCRIPTING, 'gotemplate.mdx'), + dest: path.join(scriptingDir, 'gotemplate', 'llms.txt'), + title: 'Go Template Reference', + description: 'Go template reference for Flanksource Mission Control', + sourcePath: '/docs/reference/scripting/gotemplate' + } + ]; + + for (const file of files) { + if (!fs.existsSync(file.src)) { + console.error(`Source file not found: ${file.src}`); + continue; + } + + const content = fs.readFileSync(file.src, 'utf-8'); + const llmsContent = stripMdxToLlms(content, file.title, file.description, file.sourcePath); + + fs.mkdirSync(path.dirname(file.dest), { recursive: true }); + fs.writeFileSync(file.dest, llmsContent); + console.log(`Generated: ${path.relative(BUILD_DIR, file.dest)}`); + } +} + +function generateRootLlmsTxt() { + const urls = parseSitemap(); + const docsUrls = urls.filter(u => u.includes('/docs/')); + + const sections = {}; + for (const url of docsUrls) { + const urlPath = url.replace(BASE_URL, '').replace(/\/$/, ''); + const parts = urlPath.split('/').filter(Boolean); + + if (parts.length >= 2 && parts[0] === 'docs') { + const section = parts.length > 2 ? parts.slice(0, 3).join('/') : parts.slice(0, 2).join('/'); + if (!sections[section]) { + sections[section] = []; + } + sections[section].push(urlPath); + } + } + + const lines = [ + '# Flanksource Mission Control', + '', + '> Internal Developer Platform for Kubernetes', + '', + 'Mission Control is an internal developer platform that helps teams manage, monitor, and automate their Kubernetes infrastructure.', + '', + '## Documentation Sections', + '', + ]; + + for (const section of SECTIONS_WITH_LLMS) { + const llmsPath = `${section.path}/llms.txt`; + const buildLlmsPath = path.join(BUILD_DIR, llmsPath.substring(1)); + + if (fs.existsSync(buildLlmsPath)) { + lines.push(`- [${section.name}](${BASE_URL}${llmsPath}): ${section.description}`); + } else { + lines.push(`- [${section.name}](${BASE_URL}${section.path}): ${section.description}`); + } + } + + lines.push(''); + lines.push('## All Documentation Pages'); + lines.push(''); + + const topLevelSections = {}; + for (const sectionPath of Object.keys(sections)) { + const parts = sectionPath.split('/').filter(Boolean); + const topLevel = parts.length > 1 ? parts[1] : parts[0]; + if (!topLevelSections[topLevel]) { + topLevelSections[topLevel] = {}; + } + topLevelSections[topLevel][sectionPath] = sections[sectionPath]; + } + + const sortedTopLevel = Object.keys(topLevelSections).sort(); + for (const topLevel of sortedTopLevel) { + const topLevelName = topLevel.replace(/-/g, ' ').replace(/\b\w/g, c => c.toUpperCase()); + const subSections = topLevelSections[topLevel]; + const subSectionKeys = Object.keys(subSections).sort(); + + const allUrls = []; + for (const key of subSectionKeys) { + allUrls.push(...subSections[key]); + } + const uniqueUrls = [...new Set(allUrls)].sort(); + + if (uniqueUrls.length === 1) { + const urlPath = uniqueUrls[0]; + const pageName = urlPath.split('/').pop() + .replace(/-/g, ' ') + .replace(/\b\w/g, c => c.toUpperCase()) || topLevelName; + lines.push(`- [${pageName}](${BASE_URL}${urlPath})`); + } else { + lines.push(`- ${topLevelName}`); + for (const urlPath of uniqueUrls) { + const pageName = urlPath.split('/').slice(2).join(' / ') + .replace(/-/g, ' ') + .replace(/\b\w/g, c => c.toUpperCase()) || 'Overview'; + lines.push(` - [${pageName}](${BASE_URL}${urlPath})`); + } + } + } + + const llmsTxtPath = path.join(BUILD_DIR, 'llms.txt'); + fs.writeFileSync(llmsTxtPath, lines.join('\n')); + console.log(`Generated root llms.txt with ${docsUrls.length} documentation pages`); +} + +function moveFiles() { + if (!fs.existsSync(BUILD_DIR)) { + console.error('Build directory does not exist. Run `yarn build` first.'); + process.exit(1); + } + + const files = fs.readdirSync(BUILD_DIR).filter(f => f.startsWith('llms') && f.endsWith('.txt')); + + let moved = 0; + for (const file of files) { + for (const { pattern, dest } of MAPPINGS) { + if (pattern.test(file)) { + const srcPath = path.join(BUILD_DIR, file); + const destDir = path.join(BUILD_DIR, dest); + const destPath = path.join(destDir, 'llms.txt'); + + fs.mkdirSync(destDir, { recursive: true }); + fs.renameSync(srcPath, destPath); + console.log(`${file} -> ${dest}/llms.txt`); + moved++; + break; + } + } + } + + const nonFullFiles = fs.readdirSync(BUILD_DIR).filter(f => + f.startsWith('llms') && f.endsWith('.txt') && !f.includes('-full') + ); + for (const file of nonFullFiles) { + fs.unlinkSync(path.join(BUILD_DIR, file)); + console.log(`Removed non-full file: ${file}`); + } + + console.log(`Moved ${moved} llms files.`); + + generateScriptingLlms(); + generateRootLlmsTxt(); +} + +moveFiles(); diff --git a/modules/canary-checker b/modules/canary-checker index bff5cca8..f8525c74 160000 --- a/modules/canary-checker +++ b/modules/canary-checker @@ -1 +1 @@ -Subproject commit bff5cca8f2fec464eed099c01f0b15f3602c802f +Subproject commit f8525c741329c19748b75dfeb59bf9dda4b5222c diff --git a/modules/config-db b/modules/config-db index 81e26eb1..38c47881 160000 --- a/modules/config-db +++ b/modules/config-db @@ -1 +1 @@ -Subproject commit 81e26eb1be71ea84a5b22261980eae58e82d9080 +Subproject commit 38c4788111ef84cde0d00468e3e5b3d2ad396c3d diff --git a/modules/duty b/modules/duty index 4a1e4765..7f12548a 160000 --- a/modules/duty +++ b/modules/duty @@ -1 +1 @@ -Subproject commit 4a1e4765072ce2ea1bea21298d85571fd3d91224 +Subproject commit 7f12548ab5137be9a37a7a8aa4b01f52bf107841 diff --git a/modules/mission-control b/modules/mission-control index 60cfeb20..0a1ba5c9 160000 --- a/modules/mission-control +++ b/modules/mission-control @@ -1 +1 @@ -Subproject commit 60cfeb200bec5b6d3be4e6598654f79c326d966e +Subproject commit 0a1ba5c9cf6f9985c6371533edffe3719ca1654c diff --git a/modules/mission-control-chart b/modules/mission-control-chart index 6ed80b8a..ec6f642a 160000 --- a/modules/mission-control-chart +++ b/modules/mission-control-chart @@ -1 +1 @@ -Subproject commit 6ed80b8a9bf48cec7bb7bf720186cfa94cffaa89 +Subproject commit ec6f642a3ac1ffcd18b9de323db9d5cd7eda949b diff --git a/modules/mission-control-registry b/modules/mission-control-registry index 31f6a244..3a476b92 160000 --- a/modules/mission-control-registry +++ b/modules/mission-control-registry @@ -1 +1 @@ -Subproject commit 31f6a244e8ba6e26e483afac42a64fe385a37810 +Subproject commit 3a476b92b302e92eb9fe28ed4bccc47d81afa136