diff --git a/canary-checker/.gitignore b/canary-checker/.gitignore new file mode 100644 index 00000000..c2658d7d --- /dev/null +++ b/canary-checker/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/canary-checker/docs/cli.mdx b/canary-checker/docs/cli.mdx index 23191935..a719d4c7 100644 --- a/canary-checker/docs/cli.mdx +++ b/canary-checker/docs/cli.mdx @@ -4,13 +4,16 @@ hide: title: CLI description: Troubleshooting and/or running from CI/CD pipeline --- - -# Installation - +import { set } from "lodash" import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import ReactMarkdown from 'react-markdown'; + +# Installation + + + @@ -68,7 +71,9 @@ wget -nv -nc -O https://github.com/flanksource/canary-checker/releases/latest/do -# Run + + + ```yaml title="canary.yaml" apiVersion: canaries.flanksource.com/v1 @@ -85,8 +90,13 @@ spec: ``` + + + ```shell-session canary-checker run canary.yaml ``` + + diff --git a/canary-checker/docs/concepts/secret-management.md b/canary-checker/docs/concepts/secret-management.md index 440c0b67..723d8fc4 100644 --- a/canary-checker/docs/concepts/secret-management.md +++ b/canary-checker/docs/concepts/secret-management.md @@ -12,6 +12,10 @@ Whenever a field uses the `EnvVar` object type you have the option of specifying ## Static Values +:::warning +Avoid inlining secrets, use `valueFrom` and EnvVar +::: + Using a HTTP health check as an example for static values: ```yaml title="http-basic-auth-static.yaml" diff --git a/canary-checker/docs/concepts/stateful.md b/canary-checker/docs/concepts/stateful.md new file mode 100644 index 00000000..e69de29b diff --git a/canary-checker/docs/getting-started.md b/canary-checker/docs/getting-started.mdx similarity index 92% rename from canary-checker/docs/getting-started.md rename to canary-checker/docs/getting-started.mdx index 8771b55b..2cd910d6 100644 --- a/canary-checker/docs/getting-started.md +++ b/canary-checker/docs/getting-started.mdx @@ -1,14 +1,16 @@ + # Getting Started -## Install canary checker + ```bash helm repo add flanksource https://flanksource.github.io/charts helm repo update helm install canary-checker flanksource/canary-checker -n "canary-checker" --create-namespace ``` + + -## Create a new check ```yaml title="canary.yaml" apiVersion: canaries.flanksource.com/v1 @@ -30,7 +32,7 @@ And then apply it to the cluster: kubectl apply -f canary.yaml ``` - :::info +:::info You can also run the check locally to see its output by using the [cli](./cli) ```bash @@ -38,9 +40,10 @@ And then apply it to the cluster: ``` - ::: +::: -3. Check the status of the health check: + + ```shell kubectl get canary @@ -48,7 +51,8 @@ And then apply it to the cluster: -4. Check the Dashboard + + You can access the web dashboard by forwarding the port: @@ -70,6 +74,7 @@ The canary checker itself only presents an API. To view the data graphically, th More details regarding ingress configuration can be found in the [kubernetes documentation](https://kubernetes.io/docs/concepts/services-networking/ingress/) + ## Getting Help @@ -81,3 +86,4 @@ If you have any questions about canary checker: * [Flanksource](https://www.flanksource.com) provides both commercial support for canary checker and a SaaS offering called Mission Control. Your feedback is always welcome! + diff --git a/canary-checker/docs/health-checks.md b/canary-checker/docs/health-checks.md new file mode 100644 index 00000000..589dffab --- /dev/null +++ b/canary-checker/docs/health-checks.md @@ -0,0 +1,14 @@ +--- +pagination_next: notifications/overview +pagination_prev: topology/overview +--- +# Health Checks + +Health checks in mission control are implemented under the hood using the open-source [canary-checker](https://canarychecker.io) project. + + +![](./images/health-checks.svg) + + + +![](./images/health-check-snippet.png) diff --git a/canary-checker/docs/images/health-check-snippet.png b/canary-checker/docs/images/health-check-snippet.png new file mode 100644 index 00000000..4fdef21e Binary files /dev/null and b/canary-checker/docs/images/health-check-snippet.png differ diff --git a/canary-checker/docs/images/health-checks.svg b/canary-checker/docs/images/health-checks.svg new file mode 100644 index 00000000..af4ef89f --- /dev/null +++ b/canary-checker/docs/images/health-checks.svg @@ -0,0 +1,3 @@ + + +
Health Checks
Health Checks
Probes
Probes
Metrics
Metrics
Alerts
Alerts
Infra
Infra
Data Sources
Data Sources
Passive
Checks
Passiv...
SyntheticChecks
test
test
CELABCD
link
link
transform
transform
Metrics
Metrics
Status
Status
Alerts
Alerts
\ No newline at end of file diff --git a/canary-checker/docs/overview.md b/canary-checker/docs/overview.md index e69de29b..64b6b422 100644 --- a/canary-checker/docs/overview.md +++ b/canary-checker/docs/overview.md @@ -0,0 +1,9 @@ + +# Health Checks + + + +* [Health Checks](./canary-checker/overview) - RAG statuses across both cloud-native and legacy infrastructure/apps. + * Alert Aggregation + * Synthethic Tests + * Synthetic Infrastructure checks diff --git a/canary-checker/docs/reference/batch-files.mdx b/canary-checker/docs/reference/batch-files.mdx new file mode 100644 index 00000000..6ac95b85 --- /dev/null +++ b/canary-checker/docs/reference/batch-files.mdx @@ -0,0 +1,37 @@ +```yaml title="batch-files.yaml" + - name: Correspondence/OSC - Failed + path: /mnt/efs/{{.Values.efs.path}}/oipa/correspondence/out/failed + filter: + regex: ".*.err" + # use the last known max, or 60 days ago if no last known max + since: | + {{` + {{- if last_result.results.max }} + {{ last_result.results.max }} + {{- else}} + now-1d + {{- end}} + `}} + transform: + # Save the newest modified time to the results, overriding the full file listing that would normally be saved + # if no new files detected, use the last known max + expr: | + { + "detail": { + "max": string(results.?newest.modified.orValue(last_result().results.?max.orValue("now-60d"))), + } + }.toJSON() + display: + expr: results.?files.orValue([]).map(i, i.name).join(", ") + test: + expr: results.?files.orValue([]).size() == 0 + metrics: + - name: sybrin_xml_failed + value: results.?files.orValue([]).size() + type: counter + labels: + - name: folder + value: osc + - name: namespace + value: {{ .Release.Namespace }} + ``` diff --git a/canary-checker/docs/reference/canary-spec.mdx b/canary-checker/docs/reference/canary-spec.mdx index c227e2bd..af8fa1e1 100644 --- a/canary-checker/docs/reference/canary-spec.mdx +++ b/canary-checker/docs/reference/canary-spec.mdx @@ -2,11 +2,10 @@ | Field | Description | Type | Required | | ---------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------- | -------- | -| `env` | Environment variables. | `map[string]`[`VarSource`](#varsource) | | -| `schedule` | Schedule to run checks on.\Supports all cron expression.\Also supports golang duration. | `string` | | +| `env` | Environment variables. | `map[string]``EnvVar` | | +| `schedule` | Schedule to run checks on.\Supports all cron expression.\Also supports golang duration. | `cron` | | | `icon` | Icon to use for the check. | `string` | | | `severity` | Severity of the check. | `string` | | -| `owner` | Owner of the check. | `string` | | | `resultmode` | Result mode of the check. | `string` | | | `alertmanager` | List of AlertManager checks to run. | [`[]AlertManagerCheck`](alert-manager) | | | `awsConfig` | List of AWS Config checks to run. | [`[]AwsConfigCheck`](aws-config) | | @@ -41,36 +40,3 @@ | `s3` | List of S3 checks to run. | [`[]S3Check`](s3-bucket) | | | `tcp` | List of TCP checks to run. | [`[]TCPCheck`](./tcp) | | -## Scheme Reference - -### VarSource - -| Field | Description | Type | Required | -| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- | -------- | -| `value` | | `string` | | -| `fieldRef` | Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs. | [`ObjectFieldSelector`](#objectfieldselector) | | -| `configMapKeyRef` | Selects a key of a ConfigMap. | [`ConfigMapKeySelector`](#configmapkeyselector) | | -| `secretKeyRef` | Selects a key of a secret in the pod's namespace | [`SecretKeySelector`](#secretkeyselector) | | - -### ObjectFieldSelector - -| Field | Description | Type | Required | -| ------------ | ----------------------------------------------------------------------------- | -------- | -------- | -| `apiVersion` | Version of the schema the FieldPath is written in terms of, defaults to "v1". | `string` | | -| `fieldPath` | Path of the field to select in the specified API version. | `string` | | - -### ConfigMapKeySelector - -| Field | Description | Type | Required | -| ---------- | -------------------------------------------------------- | -------- | -------- | -| `name` | Name of the referent. | `string` | | -| `key` | The key to select. | `string` | | -| `optional` | Specify whether the ConfigMap or its key must be defined | `bool` | | - -### SecretKeySelector - -| Field | Description | Type | Required | -| ---------- | ----------------------------------------------------------------- | -------- | -------- | -| `name` | Name of the referent. | `string` | | -| `key` | The key of the secret to select from. Must be a valid secret key. | `string` | | -| `optional` | Specify whether the Secret or its key must be defined | `bool` | | diff --git a/canary-checker/docs/reference/cloudwatch.mdx b/canary-checker/docs/reference/cloudwatch.mdx index 163aaece..6703b474 100644 --- a/canary-checker/docs/reference/cloudwatch.mdx +++ b/canary-checker/docs/reference/cloudwatch.mdx @@ -55,40 +55,51 @@ spec: There are 3 options when connecting to AWS: -1. An 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) -2. `connection`, this is the recommended method, connections are reusable and secure + - ```yaml title="aws-connection.yaml" - apiVersion: canaries.flanksource.com/v1 - kind: Canary - metadata: - name: cloudwatch-check - spec: - interval: 30 - cloudwatch: - - connection: connection://aws/internal - region: us-east-1 # optional if specified in the connection - ``` +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) + + + +Using a shared Connection +```yaml title="aws-connection.yaml" +apiVersion: canaries.flanksource.com/v1 +kind: Canary +metadata: + name: cloudwatch-check +spec: + interval: 30 + cloudwatch: + - connection: connection://aws/internal + region: us-east-1 # optional if specified in the connection +``` + + + +```yaml title="inline.yaml" +apiVersion: canaries.flanksource.com/v1 +kind: Canary +metadata: + name: cloudwatch-check +spec: + interval: 30 + cloudwatch: + - accessKey: + valueFrom: + secretKeyRef: + name: aws-credentials + key: AWS_ACCESS_KEY_ID + secretKey: + valueFrom: + secretKeyRef: + name: aws-credentials + key: AWS_SECRET_ACCESS_KEY + region: us-east-1 +``` + +:::warning +Avoid inlining secrets, use `valueFrom` and EnvVar +::: + -3. `accessKey` and `secretKey` _EnvVar_ with the credentials stored in a secret. - ```yaml title="aws.yaml" - apiVersion: canaries.flanksource.com/v1 - kind: Canary - metadata: - name: cloudwatch-check - spec: - interval: 30 - cloudwatch: - - accessKey: - valueFrom: - secretKeyRef: - name: aws-credentials - key: AWS_ACCESS_KEY_ID - secretKey: - valueFrom: - secretKeyRef: - name: aws-credentials - key: AWS_SECRET_ACCESS_KEY - region: us-east-1 - ``` diff --git a/canary-checker/docs/reference/connections.mdx b/canary-checker/docs/reference/connections.mdx index e42bf797..b5b680c1 100644 --- a/canary-checker/docs/reference/connections.mdx +++ b/canary-checker/docs/reference/connections.mdx @@ -1,10 +1,14 @@ # Connections -### AWS Connection + + +## AWS + + | Field | Description | Type | Required | | ------------------------------- | --------------- | -------------------------------------------------------------------------- | -------- | -| `connection` | | _Connections_ | | +| `connection` | Mutually exclusive with `accessKey` and `secretKey` | _Connections_ | | | `accessKey` | Access key | _EnvVar_ | | | `secretKey` | Secret key | _EnvVar_ | | | `region` | Region | `string` | | @@ -13,15 +17,114 @@ | `objectPath` | Object path | `string` | | | `usePathStyle` | Use path style | `bool` | | -### GCP Connection + + +There are 3 options when connecting to AWS: + + + +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) + + + +Using a shared Connection +```yaml title="aws-connection.yaml" +apiVersion: canaries.flanksource.com/v1 +kind: Canary +metadata: + name: cloudwatch-check +spec: + interval: 30 + cloudwatch: + - connection: connection://aws/internal + region: us-east-1 # optional if specified in the connection +``` + + + +```yaml title="inline.yaml" +apiVersion: canaries.flanksource.com/v1 +kind: Canary +metadata: + name: cloudwatch-check +spec: + interval: 30 + cloudwatch: + - accessKey: + valueFrom: + secretKeyRef: + name: aws-credentials + key: AWS_ACCESS_KEY_ID + secretKey: + valueFrom: + secretKeyRef: + name: aws-credentials + key: AWS_SECRET_ACCESS_KEY + region: us-east-1 +``` + + + + +## GCP | Field | Description | Type | Required | | ------------------------------- | ----------- | -------------------------------------------------------------------------- | -------- | -| `connection` | | _Connections_ | | +| `connection` | Mutually exclusive with `credentials`4 | _Connections_ | | | `endpoint` | Endpoint | `string` | | -| `credentials` | Credentials | _EnvVar_ | | +| `credentials` | Credentials | _EnvVar_ to service account JSON | | + + + -### Azure Connection +There are 3 options when connecting to GCP: + + + +GKE [workload identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) (the default if no `connection` or `credentials` is specified) + + + + +```yaml title="gcs-connection.yaml" +apiVersion: canaries.flanksource.com/v1 +kind: Canary +metadata: + name: database-backup-check +spec: + interval: 60 + folder: + - name: gcs auth test + path: gcs://somegcsbucket + gcpConnection: + connection: connection://gcp/internal +``` + + + + + +```yaml title="gcp-inline.yaml" +apiVersion: canaries.flanksource.com/v1 +kind: Canary +metadata: + name: database-backup-check +spec: + interval: 60 + folder: + - name: gcs auth test + path: gcs://somegcsbucket + gcpConnection: + credentials: + valueFrom: + secretKeyRef: + name: gcp-credentials + key: AUTH_ACCESS_TOKEN +``` + + + +## Azure | Field | Description | Type | Required | | ------------------------------- | ------------- | -------------------------------------------------------------------------- | -------- | @@ -29,3 +132,26 @@ | `clientID` | Client ID | _EnvVar_ | | | `clientSecret` | Client Secret | _EnvVar_ | | | `tenantID` | Tenant ID | `string` | | + + +## SFTP + +| Field | Description | Scheme | +| ------------ | ------------------------------------------------------------ | ------------------------------------------------- | +| `connection` | Path of existing connection e.g. `connection://sftp/instance`
Mutually exclusive with `username`
| *Connection* | +| `username` | utually exclusive with `connection` | *EnvVar* | +| `password` | Mutually exclusive with `connection` | *EnvVar* | +| `host` | Custom AWS Cloudwatch endpoint | *string* | +| `port` | Default to `22` | int | + + + +## SMB + +| Field | Description | Scheme | +| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- | +| `connection` | Path of existing connection e.g. `connection://windows/svc-account`
Mutually exclusive with`username` and `password`
| _Connections_ | +| `username` | Mutually exclusive with `connection` | _EnvVar_ | +| `password` | Mutually exclusive with `connection` | _EnvVar_ | +| `domain` | Windows domain name | _string_ | +| `port` | Default to `445` | _int_ | diff --git a/canary-checker/docs/reference/container-log-metrics.mdx b/canary-checker/docs/reference/container-log-metrics.mdx new file mode 100644 index 00000000..dc1ed41f --- /dev/null +++ b/canary-checker/docs/reference/container-log-metrics.mdx @@ -0,0 +1,98 @@ +```yaml title="container-logs.yaml" +apiVersion: canaries.flanksource.com/v1 +kind: Canary +metadata: + name: "container-log-counts" + namespace: observability + schedule: "@every 5m" + http: + - name: containerlogvolume + endpoint: "https://vpc-oma-oipa-nonprod-hfmac7vkv4k5sdhyt3mnzr7xsy.eu-west-1.es.amazonaws.com/logstash-*/_search" + username: + valueFrom: + secretKeyRef: + name: elastic + key: ES_USERNAME + password: + valueFrom: + secretKeyRef: + name: elastic + key: ES_PASSWORD + headers: + - name: Content-Type + value: application/json + responseCodes: [200] + description: Increase in number of log entries generated per namespace + templateBody: true + test: + expr: json.?aggregations.logs.doc_count.orValue(0) > 0 + body: >- + { + "size": 0, + "aggs": { + "logs": { + "filter": { + "range": { + "@timestamp" : { + {{- if last_result.results.max }} + "gte": "{{ last_result.results.max }}" + {{- else }} + "gte": "now-5m" + {{- end }} + } + } + }, + "aggs": { + "age": { + "max": { + "field": "@timestamp" + } + }, + "labels": { + "multi_terms": { + "terms": [ + { "field": "kubernetes_namespace_name.keyword"}, + { "field": "kubernetes_container_name.keyword"}, + { "field": "kubernetes_pod_name.keyword"} + ], + "size": 1000 + } + } + } + } + } + } + display: + expr: | + 'count=' + string(json.?aggregations.logs.doc_count.orValue('error')) + ', max=' + json.aggregations.?logs.age.value_as_string.orValue('') + transform: + expr: | + json.orValue(null) != null ? + [{ + 'detail': { 'max': string(json.?aggregations.logs.age.value_as_string.orValue(last_result().?results.max.orValue(time.Now()))) }, + 'metrics': json.?aggregations.logs.labels.buckets.orValue([]).map(k, { + 'name': "namespace_log_count", + 'type': "counter", + 'value': double(k.doc_count), + 'labels': { + "namespace": k.key[0], + "container": k.key[1], + "pod": k.key[2] + } + }) + }].toJSON() + : '{}' + +``` + + +```go + "@timestamp" : { + {{- if last_result.results.max }} + "gte": "{{ last_result.results.max }}" + {{- else }} + "gte": "now-5m" + {{- end }} + } +``` + diff --git a/canary-checker/docs/reference/folder.mdx b/canary-checker/docs/reference/folder.mdx index 0d00c9aa..df67fd72 100644 --- a/canary-checker/docs/reference/folder.mdx +++ b/canary-checker/docs/reference/folder.mdx @@ -29,7 +29,11 @@ spec: | Field | Description | Scheme | Required | | ---------- | ------------------------------------------------------------ | ------------------------------- | -------- | -| **`path`** | A local folder path or a remote folder ([SMB](smb), [SFTP](sftp), [S3](s3-bucket), [GCS](gcs-bucket)) | string | Yes | +| **`path`** | A local folder path or a remote folder `smb://`, `sftp://`, `s3://` or `gcs://` | string | Yes | +| `sftpConnection` | Connection details | [SFTPConnection](./connections.mdx#sftp) | Yes | +| `gcpConnection` | Connection details for GCP | [GCPConnection](./connections.mdx#gcp) | | +| `awsConnection` | AWS Access credentials | [AWSConnection](./connections.mdx#aws) | | +| `smbConnection` | SMB connection details | [SMBConnection](./connections.mdx#smb) | | | `filter` | Filter objects out before checking if they are valid | [*FolderFilter*](#folderfilter) | | | `minCount` | The minimum number of files inside the `path` | int | | | `maxCount` | The maximum number of files inside the `path`, can be used in conjunction with `filter.regex` to detect error files | *int* | | @@ -106,3 +110,79 @@ The following fields are available in `test`, `display` and `transform` [express | `minSize` | | [`Size`](#size) | | | `maxSize` | | [`Size`](#size) | | | `regex` | | `string` | | + + +## Connection Types + +### SFTP + +```yaml title="sftp-check.yaml" +# ... +kind: Canary +spec: + folder: + //highlight-next-line + - path: folder + sftpConnection: + host: 192.168.1.9 + # ... +``` + +| Field | Description | Scheme | +| ------------ | ------------------------------------------------------------ | ------------------------------------------------- | +| `connection` | Path of existing connection e.g. `connection://sftp/instance`
Mutually exclusive with `username`
| *Connection* | +| `username` | utually exclusive with `connection` | *EnvVar* | +| `password` | Mutually exclusive with `connection` | *EnvVar* | +| `host` | Custom AWS Cloudwatch endpoint | *string* | +| `port` | Default to `22` | int | + + + + + +### S3 +```yaml title="s3-check.yaml" + # ... +kind: Canary +spec: + folder: + //highlight-next-line + - path: s3://bucket/folder + awsConnection: + # ... +``` + + +### SMB + +```yaml title="smb-check.yaml" +# ... +kind: Canary +spec: + folder: + //highlight-next-line + - path: smb:\\192.168.1.9\Some Public Folder\somedir + smbConnection: + #... +``` +| Field | Description | Scheme | +| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- | +| `connection` | Path of existing connection e.g. `connection://windows/svc-account`
Mutually exclusive with`username` and `password`
| _Connections_ | +| `username` | Mutually exclusive with `connection` | _EnvVar_ | +| `password` | Mutually exclusive with `connection` | _EnvVar_ | +| `domain` | Windows domain name | _string_ | +| `port` | Default to `445` | _int_ | + + +### GCS + +```yaml title="gcs-check.yaml" +# ... +kind: Canary +spec: + folder: + //highlight-next-line + - path: gcs://bucket/folder + gcpConnection: + # ... +``` diff --git a/canary-checker/docs/reference/gcs-bucket.mdx b/canary-checker/docs/reference/gcs-bucket.mdx deleted file mode 100644 index 81b3cce3..00000000 --- a/canary-checker/docs/reference/gcs-bucket.mdx +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: GCS Bucket ---- - -# GCSBucket - -Checks the contents of a GCP bucket for size, age and count. - -See [Folder](./folder.mdx) for a full description. - -```yaml title="gcs-folder-check.yaml" -apiVersion: canaries.flanksource.com/v1 -kind: Canary -metadata: - name: gcs-bucket-check -spec: - interval: 30 - spec: - folder: - - name: gcs auth test - path: gcs://somegcsbucket - minCount: 5 -``` - -| Field | Description | Scheme | Required | -| --------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | -------- | -| **`name`** | Name of the check | _string_ | Yes | -| **`path`** | A path to a GCS bucket and folder e.g. `gcs://bucket/folder` | string | Yes | -| `gcpConnection` | Connection details for GCP | [GCPConnection](./connections.mdx#gcp-connection) | | -| `*` | All other fields available in the folder check | [_Folder_](./folder.mdx) | | -| **`name`** | Name of the check, must be unique within the canary | `string` | Yes | -| `description` | Description for the check | `string` | | -| `icon` | Icon for overwriting default icon on the dashboard | `string` | | -| `labels` | Labels for check | `map[string]string` | | -| `test` | Evaluate whether a check is healthy | [`Expression`](../concepts/health-evaluation) | | -| `display` | Expression to change the formatting of the display | [`Expression`](../concepts/display-formatting) | | -| `transform` | Transform data from a check into multiple individual checks | [`Expression`](../concepts/transforms) | | -| `metrics` | Metrics to export from | [`[]Metrics`](../concepts/metrics-exporter) | | -| **Connection** | | | | -| `connection` | Path of an existing connection e.g. `connection://aws/instance`
Mutually exclusive with `credentials`
| _Connection_ | | -| `credentials` | GCP Access Token File. Mutually exclusive with `connection` | _EnvVar_ | Yes | - -### Connecting to GCP - -There are 3 options when connecting to GCP: - -1. GKE [workload identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) (the default if no `connection` or `credentials` is specified) -2. `connection`, this is the recommended method, connections are reusable and secure - -```yaml title="aws-connection.yaml" -apiVersion: canaries.flanksource.com/v1 -kind: Canary -metadata: - name: database-backup-check -spec: - interval: 60 - folder: - - name: gcs auth test - path: gcs://somegcsbucket - gcpConnection: - connection: connection://gcp/internal -``` - -3. `credentials` _EnvVar_ with the service account json key stored in a secret. - -```yaml title="aws.yaml" -apiVersion: canaries.flanksource.com/v1 -kind: Canary -metadata: - name: database-backup-check -spec: - interval: 60 - folder: - - name: gcs auth test - path: gcs://somegcsbucket - gcpConnection: - credentials: - valueFrom: - secretKeyRef: - name: gcp-credentials - key: AUTH_ACCESS_TOKEN -``` - -To create the secret - -```bash -kubectl create secret generic gcp-credentials --from-file=AUTH_ACCESS_TOKEN=path/to/your/SA_Key.json -``` diff --git a/canary-checker/docs/reference/kubernetes.mdx b/canary-checker/docs/reference/kubernetes.mdx index 7c002b74..3c0abffb 100644 --- a/canary-checker/docs/reference/kubernetes.mdx +++ b/canary-checker/docs/reference/kubernetes.mdx @@ -82,3 +82,31 @@ See the CEL *Kubernetes* d | `name` | Name of Kubernetes resource | *string* | | | `labelSelector` | Select Kubernetes resource based on label. e.g. app, canary. | *string* | | `fieldSelector` | Select Kubernetes resource based on the value of specified resource field | *string* | + + +## Examples + +### Certificate readiness + +```yaml title="cert-manager-check.yaml" +apiVersion: canaries.flanksource.com/v1 +kind: Canary +metadata: + name: cert-manager +spec: + schedule: "@every 15m" + kubernetes: + - name: cert-manager-check + kind: Certificate + test: + expr: | + dyn(results). + map(i, i.Object). + filter(i, i.status.conditions[0].status != "True").size() == 0 + display: + expr: | + dyn(results). + map(i, i.Object). + filter(i, i.status.conditions[0].status != "True"). + map(i, "%s/%s -> %s".format([i.metadata.namespace, i.metadata.name, i.status.conditions[0].message])).join('\n') +``` diff --git a/canary-checker/docs/reference/mssql.mdx b/canary-checker/docs/reference/mssql.mdx deleted file mode 100644 index 000c6f41..00000000 --- a/canary-checker/docs/reference/mssql.mdx +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: MSSQL ---- - -# MSSQL - -This check will try to connect to a specified SQL Server database, run a query against it and verify the results. - -```yaml -apiVersion: canaries.flanksource.com/v1 -kind: Canary -metadata: - name: mssql-check -spec: - interval: 30 - mssql: - - name: mssql pass - url: "server=mssql.default.svc;user id=$(username);password=$(password);port=1433;database=master" - username: - valueFrom: - secretKeyRef: - name: mssql-credentials - key: USERNAME - password: - valueFrom: - secretKeyRef: - name: mssql-credentials - key: PASSWORD - query: SELECT 1 - results: 1 -``` - -| Field | Description | Scheme | Required | -| ----- | ----------- | ------ | -------- | -| **`url`** | Connection string to connect to the SQL Server server | *string* | Yes | -| **`query`** | query that needs to be executed on the server | *string* | Yes | -| **`results`** | Number rows to check for | *int* | Yes | -| **`name`** | Name of the check, must be unique within the canary | `string` | Yes | -| `description` | Description for the check | `string` | | -| `icon` | Icon for overwriting default icon on the dashboard | `string` | | -| `labels` | Labels for check | `map[string]string` | | -| `test` | Evaluate whether a check is healthy | [`Expression`](../concepts/health-evaluation) | | -| `display` | Expression to change the formatting of the display | [`Expression`](../concepts/display-formatting) | | -| `transform` | Transform data from a check into multiple individual checks | [`Expression`](../concepts/transforms) | | -| `metrics` | Metrics to export from | [`[]Metrics`](../concepts/metrics-exporter) | | -| **Connection** | | | | -| `connection` | Path of existing connection e.g. `connection://mssql/instance`/ Mutually exclusive with `username`, `password`
| *Connection* | | -| `username` | Mutually exclusive with `connection` | *EnvVar* | | -| `password` | Mutually exclusive with `connection` | *EnvVar* | | -| `url` | If the url is specifed in both the `connection` and in the `url` field, the `url` field takes precedence | | | - - -## Result Variables - -| Name | Description | Scheme | -| ------- | ----------------------- | -------------------------- | -| `rows` | | *[]map[string]interface{ }* | -| `count` | Number of rows returned | *int* | diff --git a/canary-checker/docs/reference/mysql.mdx b/canary-checker/docs/reference/mysql.mdx deleted file mode 100644 index f19b81cc..00000000 --- a/canary-checker/docs/reference/mysql.mdx +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: MySQL ---- - -# MySQL - -This check will try to connect to a specified MySQL database, run a query against it and verify the results. - -```yaml -apiVersion: canaries.flanksource.com/v1 -kind: Canary -metadata: - name: mysql-check -spec: - interval: 30 - mysql: - - url: "$(username):$(password)@tcp(mysql.default.svc:3306)/mysqldb" - name: mysql ping check - username: - valueFrom: - secretKeyRef: - name: mysql-credentials - key: USERNAME - password: - valueFrom: - secretKeyRef: - name: mysql-credentials - key: PASSWORD - query: - results: 1 -``` - -| Field | Description | Scheme | Required | -| ----- | ----------- | ------ | -------- | -| **`query`** | query that needs to be executed on the server | *string* | Yes | -| **`results`** | Number rows to check for | *int* | Yes | -| **`name`** | Name of the check, must be unique within the canary | `string` | Yes | -| `description` | Description for the check | `string` | | -| `icon` | Icon for overwriting default icon on the dashboard | `string` | | -| `labels` | Labels for check | `map[string]string` | | -| `test` | Evaluate whether a check is healthy | [`Expression`](../concepts/health-evaluation) | | -| `display` | Expression to change the formatting of the display | [`Expression`](../concepts/display-formatting) | | -| `transform` | Transform data from a check into multiple individual checks | [`Expression`](../concepts/transforms) | | -| `metrics` | Metrics to export from | [`[]Metrics`](../concepts/metrics-exporter) | | -| **Connection** | | | | -| `connection` | Path of existing connection e.g. `connection://mysql/instance` Mutually exclusive with `username`, `password`
| *Connection* | | -| `username` | Mutually exclusive with `connection` | *EnvVar* | | -| `password` | Mutually exclusive with `connection` | *EnvVar* | | -| `url` | If the url is specifed in both the `connection` and in the `url` field, the `url` field takes precedence | | | - - -## Result Variables - -| Name | Description | Scheme | -| ------- | ----------------------- | -------------------------- | -| `rows` | | *[]map[string]interface{ }* | -| `count` | Number of rows returned | *int* | diff --git a/canary-checker/docs/reference/properties.md b/canary-checker/docs/reference/properties.md new file mode 100644 index 00000000..f205f7f6 --- /dev/null +++ b/canary-checker/docs/reference/properties.md @@ -0,0 +1,3 @@ +metrics.debug +http.debug +http.trace diff --git a/canary-checker/docs/reference/s3-bucket.mdx b/canary-checker/docs/reference/s3-bucket.mdx deleted file mode 100644 index a09998b0..00000000 --- a/canary-checker/docs/reference/s3-bucket.mdx +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: S3 Bucket ---- - -# S3 Bucket - -Checks the contents of a S3 bucket for size, age and count. - -See [Folder](./folder.mdx) for a full description. - -:::info -This check looks at the contents of an S3 bucket, to verify that an S3 compatible -object storage endpoint is functioning correctly use: [S3 Protocol](s3-protocol) -::: - -```yaml title="folder-check.yaml" -apiVersion: canaries.flanksource.com/v1 -kind: Canary -metadata: - name: folder-check -spec: - interval: 30 - folder: - - path: s3://some-bucket/folder - name: folder-check-min - description: Checks if there are at least 10 files in the folder - minCount: 10 -``` - -| Field | Description | Scheme | Required | -| --------------- | ---------------------------------------------------------- | ------------------------------------------------- | -------- | -| **`name`** | Name of the check | _string_ | Yes | -| **`path`** | A path to a S3 bucket and folder e.g. `s3://bucket/folder` | string | Yes | -| `awsConnection` | AWS Access credentials | [AWSConnection](./connections.mdx#aws-connection) | | -| `*` | All other fields available in the folder check | [_Folder_](./folder.mdx) | | - -### Connecting to AWS - -There are 3 options when connecting to AWS: - -1. An 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) -2. `connection`, this is the recommended method, connections are reusable and secure - - ```yaml title="aws-connection.yaml" - apiVersion: canaries.flanksource.com/v1 - kind: Canary - metadata: - name: aws-config-rule - spec: - interval: 30 - folder: - - path: s3://some-bucket/folder - awsConnection: - connection: connection://aws/s3 - name: folder-check-min - minCount: 10 - description: Checks if there are at least 10 files in the folder - ``` - -3. `accessKey` and `secretKey` _EnvVar_ with the credentials stored in a secret. - - ```yaml title="aws.yaml" - apiVersion: canaries.flanksource.com/v1 - kind: Canary - metadata: - name: s3-bucket - spec: - interval: 30 - folder: - - path: s3://some-bucket/folder - name: folder-check-min - minCount: 10 - description: Checks if there are at least 10 files in the folder - awsConnection: - accessKey: - valueFrom: - secretKeyRef: - name: aws-credentials - key: AWS_ACCESS_KEY_ID - secretKey: - valueFrom: - secretKeyRef: - name: aws-credentials - key: AWS_SECRET_ACCESS_KEY - region: us-east-1 - ``` diff --git a/canary-checker/docs/reference/smb.mdx b/canary-checker/docs/reference/smb.mdx index 7eda9f21..dba25122 100644 --- a/canary-checker/docs/reference/smb.mdx +++ b/canary-checker/docs/reference/smb.mdx @@ -39,12 +39,3 @@ spec: | `smbConnection` | SMB connection details | [SMBConnection](#smb-connection) | | | `*` | All other fields available in the folder check | [_Folder_](folder) | | -## SMB Connection - -| Field | Description | Scheme | -| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- | -| `connection` | Path of existing connection e.g. `connection://windows/svc-account`
Mutually exclusive with`username` and `password`
| _Connections_ | -| `username` | Mutually exclusive with `connection` | _EnvVar_ | -| `password` | Mutually exclusive with `connection` | _EnvVar_ | -| `domain` | Windows domain name | _string_ | -| `port` | Default to `445` | _int_ | diff --git a/canary-checker/docs/reference/postgres.mdx b/canary-checker/docs/reference/sql.mdx similarity index 78% rename from canary-checker/docs/reference/postgres.mdx rename to canary-checker/docs/reference/sql.mdx index 954326a4..05360a3d 100644 --- a/canary-checker/docs/reference/postgres.mdx +++ b/canary-checker/docs/reference/sql.mdx @@ -1,8 +1,10 @@ --- -title: Postgres +title: SQL --- -# Postgres +import { AzureSqlServer} from "@flanksource/icons/mi" + +# SQL This check will try to connect to a specified Postgres database, run a query against it and verify the results. @@ -59,3 +61,45 @@ spec: | ------- | ----------------------- | -------------------------- | | `rows` | | *[]map[string]interface{ }* | | `count` | Number of rows returned | *int* | + + +## SQL Server + +```yaml title=canary-mssql.yaml +# ... +kind: Canary +spec: + mssql: + //highlight-next-line + - url: "server=mssql.default.svc;user id=$(username);password=$(password);port=1433;database=master" + # ... +``` + + +## MySQL + + + +```yaml title=lookup-mysql.yaml +# ... +kind: Canary +spec: + mysql: + url: "$(username):$(password)@tcp(mysql.default.svc:3306)/mysqldb" + # ... +``` +## Postgres + + +```yaml title=canary-postgres.yaml +# ... +kind: Topology +spec: + components: + - lookup: + postgres: + //highlight-next-line + url: "postgres://$(username):$(password)@postgres.default.svc:5432/postgres?sslmode=disable" + # ... +``` + diff --git a/common/src/components/Badges.jsx b/common/src/components/Badges.jsx index a6953f6d..0f7f5c10 100644 --- a/common/src/components/Badges.jsx +++ b/common/src/components/Badges.jsx @@ -23,23 +23,23 @@ export function SkipOSS({ children }) { if (siteConfig.customFields.oss) { return null } - // if (Array.isArray(children)) { - // if (children.length == 0) { - // return null - // } - // return <> - // { - // children.forEach(i => { - // { i } - // }) - // } - // - // } + + return <> {children} + +} + +export function SkipCommercial({ children }) { + const { siteConfig, siteMetadata } = useDocusaurusContext(); + if (!siteConfig.customFields.oss) { + return null + } + return <> {children} } + export function Commercial({ color }) { return null diff --git a/common/src/components/Step.jsx b/common/src/components/Step.jsx new file mode 100644 index 00000000..e14f8806 --- /dev/null +++ b/common/src/components/Step.jsx @@ -0,0 +1,20 @@ +import React from 'react'; + +export default function Step({ name, step, children, style = "tutorial" }) { + return <> + + + + + {name} + +
+ {children} +
+ +} + + diff --git a/common/src/css/custom.css b/common/src/css/custom.css index f49edc46..9f00035d 100644 --- a/common/src/css/custom.css +++ b/common/src/css/custom.css @@ -179,9 +179,9 @@ --ifm-heading-font-family: var(--ifm-font-family-base); --ifm-heading-font-weight: var(--ifm-font-weight-bold); --ifm-heading-line-height: 1.25; - --ifm-h1-font-size: 2rem; - --ifm-h2-font-size: 1.5rem; - --ifm-h3-font-size: 1.25rem; + --ifm-h1-font-size: 1.5rem; + --ifm-h2-font-size: 1.25rem; + --ifm-h3-font-size: 1rem; --ifm-h4-font-size: 1rem; --ifm-h5-font-size: 0.875rem; --ifm-h6-font-size: 0.85rem; @@ -1046,14 +1046,14 @@ img[align='left'] { } .markdown h1:first-child { - --ifm-h1-font-size: 3rem; + --ifm-h1-font-size: 2rem; margin-bottom: calc( var(--ifm-h1-vertical-rhythm-bottom) * var(--ifm-leading) ); } .markdown > h2 { - --ifm-h2-font-size: 2rem; + --ifm-h2-font-size: 1.25rem; margin-bottom: calc( var(--ifm-heading-vertical-rhythm-bottom) * var(--ifm-leading) ); @@ -1061,7 +1061,7 @@ img[align='left'] { } .markdown > h3 { - --ifm-h3-font-size: 1.5rem; + --ifm-h3-font-size: 1rem; margin-bottom: calc( var(--ifm-heading-vertical-rhythm-bottom) * var(--ifm-leading) ); @@ -2335,6 +2335,16 @@ hr { .menu__link--active { color: var(--ifm-menu-color-active); + font-weight: var(--ifm-font-weight-bold); +} + +#__docusaurus_skipToContent_fallback > div > aside > div > div > nav > ul > li.theme-doc-sidebar-item-category.theme-doc-sidebar-item-category-level-1.menu__list-item.condensed > ul > li > a + +.condensed > ul > li > a { + padding-top: 2px important; + padding-bottom: 2px important; + color: red; + } .menu__link--active:hover { @@ -2345,6 +2355,10 @@ hr { background-color: var(--ifm-menu-color-background-active); } +.navbar__link--active { + font-weight: 700 !important; +} + .menu__caret { padding: var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal); @@ -2931,11 +2945,11 @@ html[data-theme='dark'] { } .markdown > h2 { - --ifm-h2-font-size: 1.5rem; + --ifm-h2-font-size: 1.25rem; } .markdown > h3 { - --ifm-h3-font-size: 1.25rem; + --ifm-h3-font-size: 1rem; } } diff --git a/common/src/theme/MDXComponents/index.js b/common/src/theme/MDXComponents/index.js index a8405877..02e74988 100644 --- a/common/src/theme/MDXComponents/index.js +++ b/common/src/theme/MDXComponents/index.js @@ -15,8 +15,10 @@ import { Commercial, Standard, Enterprise, - SkipOSS + SkipOSS, + SkipCommercial } from '@site/src/components/Badges' +import Step from '@site/src/components/Step' import Highlight from '@site/src/components/Highlight' import { FullImage } from '@site/src/components/Badges' import { CommonLink } from '@site/src/components/Link' @@ -33,8 +35,10 @@ const MDXComponents = { FullImage: FullImage, Standard: Standard, SkipOSS: SkipOSS, + SkipCommercial: SkipCommercial, Enterprise: Enterprise, Highlight: Highlight, + Step: Step, head: MDXHead, code: MDXCode, a: MDXA, diff --git a/common/static/img/icons/circled-1.svg b/common/static/img/icons/circled-1.svg new file mode 100644 index 00000000..a20dcc18 --- /dev/null +++ b/common/static/img/icons/circled-1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/common/static/img/icons/circled-2.svg b/common/static/img/icons/circled-2.svg new file mode 100644 index 00000000..9e7b99da --- /dev/null +++ b/common/static/img/icons/circled-2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/common/static/img/icons/circled-3.svg b/common/static/img/icons/circled-3.svg new file mode 100644 index 00000000..eb7457c1 --- /dev/null +++ b/common/static/img/icons/circled-3.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/common/static/img/icons/circled-4.svg b/common/static/img/icons/circled-4.svg new file mode 100644 index 00000000..ceaac9e4 --- /dev/null +++ b/common/static/img/icons/circled-4.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/common/static/img/icons/circled-5.svg b/common/static/img/icons/circled-5.svg new file mode 100644 index 00000000..bf234300 --- /dev/null +++ b/common/static/img/icons/circled-5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/common/static/img/icons/circled-6.svg b/common/static/img/icons/circled-6.svg new file mode 100644 index 00000000..218e0e6a --- /dev/null +++ b/common/static/img/icons/circled-6.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/common/static/img/icons/circled-7.svg b/common/static/img/icons/circled-7.svg new file mode 100644 index 00000000..1e6592df --- /dev/null +++ b/common/static/img/icons/circled-7.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/apm-hub/concepts/routing.md b/docs/apm-hub/concepts/routing.md index cfb1cd0b..68b36f1c 100644 --- a/docs/apm-hub/concepts/routing.md +++ b/docs/apm-hub/concepts/routing.md @@ -2,7 +2,7 @@ `apm-hub` can possibly serve hundreds of backends, but you might not want all of them to serve a request. Routing helps you to control which backends should serve a given request based on the parameters shown below. -![Routing Diagram](../images/routing.svg) +![Routing Diagram](/img/routing.svg) ## Route @@ -88,7 +88,7 @@ As you can imagine, a single search query can possibly be served by numerous bac All routes are non-additive by default. -![Non additive route](../images/non-additive-route.svg) +![Non additive route](/img/non-additive-route.svg) ````yaml backends: diff --git a/docs/apm-hub/overview.md b/docs/apm-hub/overview.md index dad4b304..30d7801a 100644 --- a/docs/apm-hub/overview.md +++ b/docs/apm-hub/overview.md @@ -2,11 +2,11 @@ -![](../images/logging.svg) +![](/img/logging.svg) -Logging in Mission Control is provided by the apm-hub tool. APM Hub is a log aggregator - it does not provide any log storage or query capabilities and relies entirely on external log sources. +Logging in Mission Control is provided by the apm-hub tool. APM Hub is a log aggregator - it does not provide any log storage or query capabilities and relies entirely on external log sources. @@ -14,7 +14,7 @@ Logging in Mission Control is provided by the apm-hub tool. APM Hub is a log agg Aggregating logs has multiple benefits: -* **Faster time to value** without the need to setup complex logging pipelines +* **Faster time to value** without the need to setup complex logging pipelines * **Reduced storage costs** by using fit-for-purpose data stores and migrating/switching between them without developers being impacted. * **Reduced time to access** logs, There is no need to log onto multiple data sources and remember the queries to find specific logs, simply select the component you are interested in. * **Improved security** by restricting log access to specific components and only during incidents @@ -25,8 +25,8 @@ Aggregating logs has multiple benefits: For example an application deployed on AWS EKS could have these different log stores: -* Application logs stored in Elasticsearch -* Raw container logs (For when the logging pipeline is down or dropping messages) +* Application logs stored in Elasticsearch +* Raw container logs (For when the logging pipeline is down or dropping messages) * Log files inside a pod that are not printed to stderr/out (e.g. access logs or troubleshooting logs) * Cloudwatch logs: * Kubernetes Control Plane diff --git a/docs/incidents/concepts/done-definition.md b/docs/incidents/concepts/done-definition.md index d76eb9ef..217e1bff 100644 --- a/docs/incidents/concepts/done-definition.md +++ b/docs/incidents/concepts/done-definition.md @@ -2,7 +2,7 @@ Incidents can be programatically resolved using done definition. When an evidence is added to an incident, a done definition can be created based on the attached object of the evidence. -![Done definition form](../../images/done-definition-form.png) +![Done definition form](/img/done-definition-form.png) Done definitions are checked periodically every 5 minutes. diff --git a/docs/incidents/concepts/evidence.md b/docs/incidents/concepts/evidence.md index 716365cb..b8a85467 100644 --- a/docs/incidents/concepts/evidence.md +++ b/docs/incidents/concepts/evidence.md @@ -6,24 +6,24 @@ Evidence plays a critical role in understanding and resolving incidents. Evidenc ### A. Topology -![Topology as an evidence](../../images/evidence-component.png) +![Topology as an evidence](/img/evidence-component.png) ### B. Config Items -![Topology as an evidence](../../images/evidence-config.png) +![Topology as an evidence](/img/evidence-config.png) ### C. Config Changes -![Topology as an evidence](../../images/evidence-config-change.png) +![Topology as an evidence](/img/evidence-config-change.png) ### D. Config Analysis -![Topology as an evidence](../../images/evidence-config-analysis.png) +![Topology as an evidence](/img/evidence-config-analysis.png) ### E. Health Checks -![Topology as an evidence](../../images/evidence-health-check.png) +![Topology as an evidence](/img/evidence-health-check.png) ### F. Logs -![Topology as an evidence](../../images/evidence-logs.png) +![Topology as an evidence](/img/evidence-logs.png) diff --git a/docs/incidents/concepts/hypothesis.md b/docs/incidents/concepts/hypothesis.md index 872444f5..71564343 100644 --- a/docs/incidents/concepts/hypothesis.md +++ b/docs/incidents/concepts/hypothesis.md @@ -22,10 +22,10 @@ To update the hypothesis status: - Go to the "Action Plan" tab. - On the relevant hypothesis and click on the icon at the beginning and select the desired status. -![Updating the status of a hypothesis](../../images/hypothesis-status.png) +![Updating the status of a hypothesis](/img/hypothesis-status.png) ### Commenting You can comment on a hypothesis either from the main incident page or from the action plan tab. -![Leaving a comment on a hypothesis](../../images/hypothesis-comment.png) +![Leaving a comment on a hypothesis](/img/hypothesis-comment.png) diff --git a/docs/incidents/concepts/responders.md b/docs/incidents/concepts/responders.md index 00ba6886..b03b1314 100644 --- a/docs/incidents/concepts/responders.md +++ b/docs/incidents/concepts/responders.md @@ -5,11 +5,11 @@ Responders allow you to link up the incident to an external incident management - MS Planner, and - Jira -![Adding a Jira responder](../../images/responder-add-jira.png) +![Adding a Jira responder](/img/responder-add-jira.png) Once the responder is linked up, the comments are synced between Flanksource and the responder client. -![Comments in Jira from Flanksource](../../images/responder-jira-comments.png) +![Comments in Jira from Flanksource](/img/responder-jira-comments.png) ## How to add a responder diff --git a/docs/incidents/overview.md b/docs/incidents/overview.md index e8d0e89b..83faacb5 100644 --- a/docs/incidents/overview.md +++ b/docs/incidents/overview.md @@ -1,6 +1,6 @@ # Incidents -![Incidents Overview](../images/incidents.png) +![Incidents Overview](/img/incidents.png) Any event capable of causing a disruption in your organization's workflow qualifies as an incident. It's crucial to establish a methodical procedure for managing such events. Our incident management feature serves as a strategic solution for your organization to efficiently identify and resolve incidents. diff --git a/mission-control/docs/architecture.md b/mission-control/docs/architecture.md index 04c2cdcd..41be8ed6 100644 --- a/mission-control/docs/architecture.md +++ b/mission-control/docs/architecture.md @@ -3,7 +3,7 @@ -![](./images/architecture.svg) +![](/img/architecture.svg) @@ -30,7 +30,7 @@ Communication between services happen in 3 ways: 3. **HTTP/REST** - This model is primarily used when the service need to interact with services outside the DB (e.g. the APM hub needs to connect to log stores to retrieve logs) ## Postgres - ++ Postgres is the only data store used by Mission Control and is also used as a JSON document database and message queue. This limits the dependencies and complexity especially when self-hosting. All services use a shared database and model via the [duty](https://github.com/flanksource/duty) project, this provides the following benefits: diff --git a/mission-control/docs/comparison/mission-control-vs-backstage.md b/mission-control/docs/comparison/mission-control-vs-backstage.md new file mode 100644 index 00000000..c4228bc0 --- /dev/null +++ b/mission-control/docs/comparison/mission-control-vs-backstage.md @@ -0,0 +1,2 @@ +# Comparison of Mission Control to Backstage + diff --git a/mission-control/docs/config-db/concepts/changes.md b/mission-control/docs/config-db/concepts/changes.md index fd7c2854..542c8dea 100644 --- a/mission-control/docs/config-db/concepts/changes.md +++ b/mission-control/docs/config-db/concepts/changes.md @@ -13,13 +13,13 @@ Changes are of two types These are changes generated by ConfigDB by simply comparing the old and new config values. The image below shows a change where the port value was modified from 8080 to 3000. -![Kubernetes Deployment Replica change](../../images/config-changes.png) +![Kubernetes Deployment Replica change](/img/config-changes.png) ### Event based change These are changes provided by an external source example: Kubernetes Events & AWS CLoudtrail. Event based changes have a type associated to it. -![Event based config changes of a Kubernetes Pod](../../images/event-based-config-changes.png) +![Event based config changes of a Kubernetes Pod](/img/event-based-config-changes.png) ## Change Transformation diff --git a/mission-control/docs/config-db/concepts/exclusion.md b/mission-control/docs/config-db/concepts/exclusion.md deleted file mode 100644 index b244724b..00000000 --- a/mission-control/docs/config-db/concepts/exclusion.md +++ /dev/null @@ -1,28 +0,0 @@ -# Exclusions - -Exclusions allow you to remove certain fields from the scraped configuration. This is useful when you want to remove sensitive or just useless data from the scraped configuration. - -```yaml title="kubernetes-exclude-superfluous-fields.yaml" -apiVersion: configs.flanksource.com/v1 -kind: ScrapeConfig -metadata: - name: kubernetes-scraper -spec: - kubernetes: - - clusterName: local-kind-cluster - transform: - exclude: - - jsonpath: '.metadata.ownerReferences' - - types: - - Kubernetes::Pod - jsonpath: '.metadata.generateName' -``` - -## Exclude - -| Field | Description | Scheme | Required | -| ---------- | -------------------------------------------------------------------------- | ---------- | -------- | -| `jsonpath` | Specify JSONPath expression for the fields | `string` | `true` | -| `types` | specify the config types from which the JSONPath fields need to be removed | `[]string` | | - -The `types` field is optional and if left empty, the filter will apply to all config items. diff --git a/mission-control/docs/config-db/concepts/extraction.md b/mission-control/docs/config-db/concepts/extraction.md new file mode 100644 index 00000000..601c88dd --- /dev/null +++ b/mission-control/docs/config-db/concepts/extraction.md @@ -0,0 +1,52 @@ + +# Extraction + +Config DB needs to extract a few important pieces of information from the config. For example, to identify the ID of a config item, it must extract the ID from the scraped config. To do this, it heavily uses JSONPath expressions. + +## JSONPath + +A JSONPath expression, similar to `XPath` for XML, is used to extract data from a JSON structure by specifying a path to an element(s) in a JSON structure. + +### Example + +Below is an example of the JSONPath expression in use for the [File scraper](../scrapers/file.md) + +```yaml title="file-scraper.yaml" +apiVersion: configs.flanksource.com/v1 +kind: ScrapeConfig +metadata: + name: file-scraper +spec: + file: + - type: $.Config.InstanceType + id: $.Config.InstanceId + path: + - my-config.json +``` + +Suppose that `my-config.json` file referenced in the path above contains the following JSON structure + +```json +{ + "Config": { + "InstanceId": "i-1234567890abcdef0", + "InstanceType": "t2.micro" + } +} +``` + +Then, the type and id of the config item will be `t2.micro` and `i-1234567890abcdef0` respectively. + +## Use cases + +Some of the common use cases of JSONPath expression are + +| Field | Description | +| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | A static value or JSONPath expression to use as the ID for the resource. | +| `name` | A static value or JSONPath expression to use as the Name for the resource. Default value is the `id`. | +| `items` | A JSONPath expression to use to extract individual items from the resource | +| `type` | A static value or JSONPath expression to use as the type for the resource. | +| `timestampFormat` | TimestampFormat is a Go time format string used to parse timestamps in createFields and DeletedFields. If not specified, the default is `RFC3339`. | +| `createFields` | CreateFields is a list of JSONPath expression used to identify the created time of the config. If multiple fields are specified, the first non-empty value will be used | +| `deleteFields` | DeleteFields is a JSONPath expression used to identify the deleted time of the config. If multiple fields are specified, the first non-empty value will be used | diff --git a/mission-control/docs/config-db/concepts/insights.md b/mission-control/docs/config-db/concepts/insights.md index d3878381..57e8eea5 100644 --- a/mission-control/docs/config-db/concepts/insights.md +++ b/mission-control/docs/config-db/concepts/insights.md @@ -2,7 +2,7 @@ Scrapers can create and attach insights (security, performance, cost, etc..) to related config items. -![Config Insights](../../images/config-insights.png) +![Config Insights](/img/config-insights.png) _Fig: Config insights_ diff --git a/mission-control/docs/config-db/concepts/masking.md b/mission-control/docs/config-db/concepts/masking.md deleted file mode 100644 index 921dac21..00000000 --- a/mission-control/docs/config-db/concepts/masking.md +++ /dev/null @@ -1,44 +0,0 @@ -# Masking - -Masking allows replacing sensitive fields with hash of that field or with a static string. -The field to mask is specified by the `jsonPath` config and `value` field defines the hash function or the static value. - -```yaml title="file-mask-scraper.yaml" -apiVersion: configs.flanksource.com/v1 -kind: ScrapeConfig -metadata: - name: file-mask-scraper -spec: - file: - - type: Config - id: $.id - name: $.name - transform: - mask: - - selector: config.name == 'Config1' - jsonpath: $.password - value: md5sum - - selector: config.name == 'Config1' - jsonpath: $.secret - value: '***' - paths: - - fixtures/data/single-config.json -``` - -| Field | Description | Scheme | Required | -| ---------- | ------------------------------------------------------------- | ------------------------------------------------- | -------- | -| `selector` | Selector helps in choosing which configs should use the mask. | `jsonpath` | `true` | -| `jsonpath` | Specify JSONPath expression for the fields | `string` | `true` | -| `value` | Value can be a name of a hash function or just a string. | [`hashFunction`](#supported-hash-functions) | `true` | - -:::info -Masks are applied in the order they are specified in the configuration file. -::: - -## Template Variable - -The `selector` cel expression receives the [`ScrapeResult`](../references/scrape-result) as its template variable. - -## Supported hash functions - -- `md5sum` diff --git a/mission-control/docs/config-db/concepts/relationship.md b/mission-control/docs/config-db/concepts/relationship.md index 24a97e1d..25ff698c 100644 --- a/mission-control/docs/config-db/concepts/relationship.md +++ b/mission-control/docs/config-db/concepts/relationship.md @@ -2,7 +2,9 @@ Relationships associate two different configs. They help in visualizing the connection of a config above and below in a hierarchy. Example: A kubernetes pod is linked to a Deployment and ReplicaSet and also to the persistent volumes. -![Kubernetes Relationship](../../images/config-relationships.png) + + +![Kubernetes Relationship](/img/config-relationships.png) ```yaml title="kubernetes-scraper.yaml" apiVersion: configs.flanksource.com/v1 @@ -21,58 +23,80 @@ spec: name: expr: | has(config.spec.selector) && has(config.spec.selector.name) ? config.spec.selector.name : '' - # Link Pods to PVCs - - filter: config_type == 'Kubernetes::Pod' - expr: | - config.spec.volumes. - filter(item, has(item.persistentVolumeClaim)). - map(item, { - "type": "Kubernetes::PersistentVolumeClaim", - "name": item.persistentVolumeClaim.claimName - }). - toJSON() ``` +:::warning Directionality matters + +When creating relationships ensure that you specify the relationship on the parent and not on the child, as this can effect the change graph, +e.g. If you link a pod to a namespace, when you view changes on the pod by default it will show all changes to all resources in the namespace. +When a namespace is linked to a pod, no changes at the namespace level will be shown when using `Outgoing` (the default) option. + +You can see changes on the incoming relationships (and their parents) by choosing the `Incoming` option. + +::: + ## Relationship Config This transformation function allows you to dynamically form relationships between two different config items using selectors. Example: You can link a kubernetes deployment with the corresponding pods, or you can link AWS EC2 instances with the AWS Account. It's even possible to link two configs scraped by different scrape configs like: linking a Kubernetes Node in an EKS cluster to the EC2 instance. -| Field | Description | Scheme | Required | -| -------- | ------------------------------------------------------------------------------------- | -------------------------------------------- | -------- | -| `filter` | Specify the config item with which relationship should be formed | `string` | `true` | -| `expr` | cel-expression that returns a list of [relationship selector](#relationshipselector). | `string` | | -| `id` | id of the config to link to | [`RelationshipLookup`](#relationship-lookup) | | -| `name` | name of the config to link to | [`RelationshipLookup`](#relationship-lookup) | | -| `type` | type of the config to link to | [`RelationshipLookup`](#relationship-lookup) | | -| `agent` | agent of the config to link to | [`RelationshipLookup`](#relationship-lookup) | | -| `labels` | Labels of the config to link to | [`RelationshipLookup`](#relationship-lookup) | | +| Field | Description | Scheme | Required | +| -------- | ------------------------------------------------------------ | -------------------------------------------- | -------- | +| | | | | +| `filter` | Specify the config item with which relationship should be formed | `string` | `true` | +| `expr` | cel-expression that returns a list of [relationship selector](#relationshipselector). | [Dynamic Linking](#dyamic-liking) | | +| `id` | id of the config to link to | [`RelationshipLookup`](#relationship-lookup) | | +| `name` | name of the config to link to | [`RelationshipLookup`](#relationship-lookup) | | +| `type` | type of the config to link to | [`RelationshipLookup`](#relationship-lookup) | | +| `agent` | agent of the config to link to | [`RelationshipLookup`](#relationship-lookup) | | +| `labels` | Labels of the config to link to | [`RelationshipLookup`](#relationship-lookup) | | :::info `expr` is an alternative, more flexible, way to define the selectors. Either use `expr` or the other selector fields (`id`, `name`, `type`, `agent`, `labels`) but not both. ::: -### RelationshipSelector - -| Field | Description | Scheme | Required | -| -------- | ------------------------------- | ------------------- | -------- | -| `id` | id of the config to link to | `string` | | -| `name` | id of the config to link to | `string` | | -| `type` | id of the config to link to | `string` | | -| `agent` | id of the config to link to | `string` | | -| `labels` | Labels of the config to link to | `map[string]string` | | - ### Relationship Lookup RelationshipLookup offers different ways to specify a lookup value -| Field | Description | Scheme | Required | -| ------- | ---------------------------------- | -------- | -------- | -| `expr` | Use an expression to get the value | `string` | | -| `value` | Specify a static value | `string` | | -| `label` | Get the value from a label | `string` | | +| Field | Description | Scheme | Variables | +| ------- | --------------------------------------------- | ------------------------------------- | --------------------------------------------- | +| `expr` | An expression that returns a value to be used | CEL | [`ScrapeResult`](../references/scrape-result) | +| `value` | Specify a static value | `string` | | +| `label` | Use the value from an existing label | `string` | | + + + +## Dynamic Linking + +Expressions can be used to define the linking criteria by return a list of [resource selectors](/reference/resource-selector). + +```yaml title=link-pvc-to-pod.yaml +apiVersion: configs.flanksource.com/v1 +kind: ScrapeConfig +metadata: + name: kubernetes-scraper +spec: + kubernetes: + - clusterName: local-kind-cluster + transform: + relationship: + - filter: config_type == 'Kubernetes::Pod' + //highlight-next-line + expr: | + config.spec.volumes. + filter(item, has(item.persistentVolumeClaim)). + map(item, { + "type": "Kubernetes::PersistentVolumeClaim", + "name": item.persistentVolumeClaim.claimName + }). + toJSON() +``` + + -### Template Variables +| Field | Description | Scheme | Variables | +| ------ | ------------------------------------------------------------ | ------------------------------------- | --------------------------------------------- | +| `expr` | An expression that returns a list of [ResourceSelectors](/reference/resource-selector) | CEL | [`ScrapeResult`](../references/scrape-result) | -Both the `filter` and `expr` in the relationship config & the `expr` in relationship lookup receive the [`ScrapeResult`](../references/scrape-result) as its template variable. diff --git a/mission-control/docs/config-db/concepts/scraping.md b/mission-control/docs/config-db/concepts/scraping.md new file mode 100644 index 00000000..6b1777e4 --- /dev/null +++ b/mission-control/docs/config-db/concepts/scraping.md @@ -0,0 +1,84 @@ +# Scraping + + +Every config item has the following metadata: + +| Field | Description | Example | +| ------------ | ------------------------------------------------------------ | ------------------------------------------------ | +| id | A `UUID` representing the item, where possible the resource providers `id` is used | | +| name | | | +| type | The config item type | `EC2::Instance`, `Kubernetes::Pod`, `Azure:VM` | +| config_class | A non-cloud specific class of resources | `VM` | +| external_id | One or more aliases that refer to the same item | `AmazonEC2/i-abcd`, `aws::ec2::instance:/i-abcd` | +| status | The externally reported status of the item using [is-healthy](https://github.com/flanksource/is-healthy) | `Healthy`,`Progressing`, `Terminated` | +| config | The JSON representation of an item
_e.g. the json returned from `kubectl get -o json`_ | | +| | | | + + +## Transformation + +### Exclusions + +Exclusions allow you to remove fields from the `config` of an item. This is useful when you want to remove sensitive or overly verbose from being recorded. + +```yaml title="kubernetes-exclude-superfluous-fields.yaml" +apiVersion: configs.flanksource.com/v1 +kind: ScrapeConfig +metadata: + name: kubernetes-scraper +spec: + kubernetes: + - clusterName: local-kind-cluster + transform: + exclude: + - jsonpath: '.metadata.ownerReferences' + - types: + - Kubernetes::Pod + jsonpath: '.metadata.generateName' +``` + + + +| Field | Description | Scheme | Required | +| ---------- | ------------------------------------------------------------ | ------------------------------------------------- | -------- | +| `jsonpath` | All matching elements will be removed from the `config` | `jsonpath` | `true` | +| `types` | Only run exclusion rules for these config types, if empty apply to all | `[]string` | | + + + +### Masking + +Masking allows replacing sensitive fields with a hash or static string. + +```yaml title="file-mask-scraper.yaml" +apiVersion: configs.flanksource.com/v1 +kind: ScrapeConfig +metadata: + name: file-mask-scraper +spec: + file: + - type: Config + id: $.id + name: $.name + transform: + mask: + - selector: config.name == 'Config1' + jsonpath: $.password + value: md5sum + - selector: config.name == 'Config1' + jsonpath: $.secret + value: '***' + paths: + - fixtures/data/single-config.json +``` + +| Field | Description | Scheme | Required | Context | +| ---------- | ------------------------------------------- | ------------------------------------------------- | -------- | --------------------------------------------- | +| `selector` | Filter which config items to apply masks on | `CEL` | `true` | [`ScrapeResult`](../references/scrape-result) | +| `jsonpath` | Values to mask | `jsonpath` | `true` | | +| `value` | The replacement value of matched elements | `md5` or any static string e.g. `***` | `true` | | + +:::info +Masks are applied in the order they are specified in the configuration file. +::: + diff --git a/mission-control/docs/config-db/overview.md b/mission-control/docs/config-db/overview.md deleted file mode 100644 index f3242aea..00000000 --- a/mission-control/docs/config-db/overview.md +++ /dev/null @@ -1,29 +0,0 @@ -# Overview - -![config db](../images/config-db.svg) - -`Config DB` is a JSON-based configuration management database. It enables you to scrape configuration from several sources on an ongoing basis and navigate that configuration in an easy-to-navigate and search JSON tree. - -By doing this, `Config DB` enables you to view and search the change history of your configuration across multiple dimensions _(node, zone, environment, application, technology, etc...)_ as well as compare and view the differences between configurations across environments. - -It is able to scan multiple configuration sources including - -- [AWS Cloud Resources](./scrapers/aws.md) -- [Azure Devops](./scrapers/azure-devops.md) - Azure Devops Pipeline runs -- [Files](./scrapers/file.md) - On a local filesystem, git or HTTP -- [Files - Kubernetes](./scrapers/kubernetes-file.md) - Files inside a running Kubernetes pod -- [Kubernetes](./scrapers/kubernetes.md) - Kubernetes resources -- [SQL](./scrapers/sql.md) - Data available via queries on MySQL, SQL Server, and Postgres databases -- [Trivy](./scrapers/trivy.md) - Security scanning of Kubernetes clusters - -Each configuration has: - -- **Configuration** - Normally JSON, but XML and properties files are also available -- **Insights** - Security, cost, performance, and other recommendations from scanners including AWS Trusted Advisor, AWS Config rules, etc... -- **Changes** - Either change directly on the config _(recorded as diff change type)_ or changes identified via AWS Cloudtrail, etc... - - - -A configuration summary is shown below: - -![](../images/config-db.png) diff --git a/mission-control/docs/config-db/overview.mdx b/mission-control/docs/config-db/overview.mdx new file mode 100644 index 00000000..26683c43 --- /dev/null +++ b/mission-control/docs/config-db/overview.mdx @@ -0,0 +1,107 @@ +--- +slug: /config-db +title: Catalog +# hide_title: true +hide_table_of_contents: true +pagination_next: playbooks/overview +pagination_prev: +--- + +import useBaseUrl from '@docusaurus/useBaseUrl'; + +import ConceptURL from "/img/config-db.svg"; + +# Catalog +The catalog in Mission Control is implemented under the hood using [config-db](https://github.com/flanksource/config-db) - A JSON based configuration management database (CMDB) that scrapes data from external systems. + + + + + + +The catalog is comprised of: + + +* **Config Items** are individual reaources e.g. `Pod`, `EBS`, `IAM Role`, `postgres.conf` file +* **Changes** recorded against config items either through automatic change detection (diffs) or from sources like `AWS CloudTrail` or `Kubernetes Events` +* **Insights** recorded against config items from external sources like `AWS Trusted Advisor` or `Trivy` +* **Relationships** between configuration items + +## Scraping + +Config items, insights and change are ingested using scrapers which are jobs that run periodically, scrapers come in 2 types: + + + + +Native scrapers ingest config items from common sources like [AWS](./scrapers/aws), [Kubernetes](./scrapers/kubernetes), [Azure](./scrapers/azure) and automatically add metadata and relationshops + + + + +Custom scrapers ingest raw data from [Files](./scrapers/file) and [SQL queries](./scrapers/sql) the results of which need to mapped to metadata and relationships manually. + + +#### Transformation + + +## Relationships + +Config items can be related to other items using both hard and soft links. + +**Hard Links** represent a physical relationship, e.g. A pod is always a child of namespace, hard links are created automatically by the relevant scraper or can be created by specifying `Parent Type` and `ID` in custom scrapers. + +**Soft Links** represent logical relationships and can have directionality. e.g. Node is related to a pod that runs on it, and a pod is related to an Persistent Volume that is attached the pod. Soft Links are created automatically by some scrapers e.g. Using `ownerRef` in kubernetes and `subnet-id` in AWS. Custom soft links can be created using a [Relationship](./relationship) transformation. + + + +## Config Items + +#### JSON +Config items are stored as `jsonb` fields in Postrgres, The JSON used is typically returned by resource provider e.g. `kubectl get -o json` or `aws --output=json` - The UI will convert from JSON to YAML when showing the config. + +#### XML / Properties / etc. +[**Custom**](./concepts/custom-scraper) scrapers can ingest non-JSON config which is represented as: + +```yaml +{ + "format": "xml", + "content": ".." +} +``` + +The UI will format and render XML appropriately. + + + + +## Features + +* Scrape data from typical data sources like AWS, GCP, Azure, Kubernetes and Github +* + +By doing this, `Config DB` enables you to view and search the change history of your configuration across multiple dimensions _(node, zone, environment, application, technology, etc...)_ as well as compare and view the differences between configurations across environments. + +It is able to scan multiple configuration sources including + +- [AWS Cloud Resources](./scrapers/aws.md) +- [Azure Devops](./scrapers/azure-devops.md) - Azure Devops Pipeline runs +- [Files](./scrapers/file.md) - On a local filesystem, git or HTTP +- [Files - Kubernetes](./scrapers/kubernetes-file.md) - Files inside a running Kubernetes pod +- [Kubernetes](./scrapers/kubernetes.md) - Kubernetes resources +- [SQL](./scrapers/sql.md) - Data available via queries on MySQL, SQL Server, and Postgres databases +- [Trivy](./scrapers/trivy.md) - Security scanning of Kubernetes clusters + +Each configuration has: + +- **Configuration** - Normally JSON, but XML and properties files are also available +- **Insights** - Security, cost, performance, and other recommendations from scanners including AWS Trusted Advisor, AWS Config rules, etc... +- **Changes** - Either change directly on the config _(recorded as diff change type)_ or changes identified via AWS Cloudtrail, etc... + + + +A configuration summary is shown below: + +![](/img/config-db.png) +import { name } from "file-loader" + diff --git a/mission-control/docs/config-db/scrapers/github.md b/mission-control/docs/config-db/scrapers/github.md new file mode 100644 index 00000000..e69de29b diff --git a/mission-control/docs/config-db/scrapers/kubernetes-file.md b/mission-control/docs/config-db/scrapers/kubernetes-file.md index d85b19d2..831534b6 100644 --- a/mission-control/docs/config-db/scrapers/kubernetes-file.md +++ b/mission-control/docs/config-db/scrapers/kubernetes-file.md @@ -42,7 +42,7 @@ spec: | `deleteFields` | DeleteFields is a JSONPath expression used to identify the deleted time of the config. If multiple fields are specified, the first non-empty value will be used | `[]string` | | | `files` | Specify path to file contained in Pod | [`[]File`](#file) | | | `format` | Format of config item, defaults to JSON, available options are JSON | `string` | | -| `selector` | Specify Kubernetes resource for configuration based on `namespace`, `kind`, `name` and more. | [`ResourceSelector`](../../reference/resource_selector) | `true` | +| `selector` | Specify Kubernetes resource for configuration based on `namespace`, `kind`, `name` and more. | [`ResourceSelector`](../../reference/resource-selector) | `true` | | `timestampFormat` | TimestampFormat is a Go time format string used to parse timestamps in createFields and DeletedFields. If not specified, the default is `RFC3339`. | `string` | | | `transform` | Field to transform result | [`Transform`](#transform) | | | `tags` | set custom tags on the scraped config items | `map[string]string` | | diff --git a/mission-control/docs/config-db/scrapers/trivy.md b/mission-control/docs/config-db/scrapers/trivy.md index a2620957..a1df14c2 100644 --- a/mission-control/docs/config-db/scrapers/trivy.md +++ b/mission-control/docs/config-db/scrapers/trivy.md @@ -16,10 +16,10 @@ spec: Unlike other scrapers, this one does not scape new configs but rather look for security vulnerabilities in the existing configs. This scrapper, if configured to scan a kubernetes cluster, will map all the found vulnerabilities to the corresponding config item. -![Config Insights generated by Trivy Scraper](../../images/config-insights-trivy.png) +![Config Insights generated by Trivy Scraper](/img/config-insights-trivy.png) _Fig: Config Insights generated by Trivy Scraper_ -![Config Insights generated by Trivy Scraper](../../images/config-insight-trivy-postgres.png) +![Config Insights generated by Trivy Scraper](/img/config-insight-trivy-postgres.png) _Fig: A detailed view of the analysis on the postgres container_ ## Scraper diff --git a/mission-control/docs/config-db/tutorials/date-mapping.md b/mission-control/docs/config-db/tutorials/date-mapping.md index 37b31419..40846b9e 100644 --- a/mission-control/docs/config-db/tutorials/date-mapping.md +++ b/mission-control/docs/config-db/tutorials/date-mapping.md @@ -53,4 +53,4 @@ spec: The `createFields` in the above scrape config instructs config-db to first look at the `installed_on` field to get the creation date of the config and then try the `deployed_at` field if it's empty. Specifying the timestampFormat is important because the timestamps in the VM configuration are not in the expected default format. -![](../../images/tutorial-vm-scraper-creation-date.png) +![](/img/tutorial-vm-scraper-creation-date.png) diff --git a/mission-control/docs/config-db/tutorials/file-scraper.md b/mission-control/docs/config-db/tutorials/file-scraper.md index 35f843ea..6884e708 100644 --- a/mission-control/docs/config-db/tutorials/file-scraper.md +++ b/mission-control/docs/config-db/tutorials/file-scraper.md @@ -43,17 +43,17 @@ This scraper will scraper our file the api endpoint every 30 seconds and track i Save the scraper and wait for it to run. You should see the job status go green. -![](../../images/tutorial-config-scrapers.png) +![](/img/tutorial-config-scrapers.png) You should now be able to see the currency config type in Catalog page. -![](../../images/example-config-items-vms.png) +![](/img/example-config-items-vms.png) The number `1` represents that there is one config item of type `Currency`. The content of the config items should be exactly what the api endpoint returns. -![](../../images/example-currency-scraper-config.png) +![](/img/example-currency-scraper-config.png) :::note The config is represented as YAML by default however internally it is stored in its original JSON form. @@ -85,9 +85,9 @@ spec: ``` You should see a new `diff` change in the config changes tab. -![Catalog Overview Page](../../images/example-currency-scraper-changes.png) +![Catalog Overview Page](/img/example-currency-scraper-changes.png) The summary `eur, date` indicates that the fields `eur` and `date` were modified. To see the details of the change, click on the change row. -![](../../images/example-currency-scraper-diff-change.png) +![](/img/example-currency-scraper-diff-change.png) diff --git a/mission-control/docs/external-postgres.md b/mission-control/docs/external-postgres.md index 482de511..786c5d84 100644 --- a/mission-control/docs/external-postgres.md +++ b/mission-control/docs/external-postgres.md @@ -1,9 +1,13 @@ + +# create superuser like privileges on a single database/scheme + + ``` CREATE ROLE "canary-checker" LOGIN PASSWORD 'r03wYPFDSdMc3aaJ'; ALTER ROLE "canary-checker" SUPERUSER; - GRANT CREATE, SELECT, UPDATE, DELETE, INSERT ON ALL TABLES IN SCHEMA public TO "canary-checker"; - GRANT CREATE ON SCHEMA public TO "canary-checker"; - ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT CREATE, SELECT, UPDATE, DELETE, INSERT ON TABLES TO "canary-checker"; +GRANT CREATE, SELECT, UPDATE, DELETE, INSERT ON ALL TABLES IN SCHEMA public TO "canary-checker"; +GRANT CREATE ON SCHEMA public TO "canary-checker"; +ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT CREATE, SELECT, UPDATE, DELETE, INSERT ON TABLES TO "canary-checker"; ALTER SCHEMA public OWNER TO "canary-checker"; diff --git a/mission-control/docs/images/config-db.svg b/mission-control/docs/images/config-db.svg deleted file mode 100644 index 31d351cd..00000000 --- a/mission-control/docs/images/config-db.svg +++ /dev/null @@ -1,279 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Config DB -Analysis -Change Detectors -AWS Trusted Advisor -AWS Config Rules - - -SQL -REST -AWS Cloud Trail - - - - - - - - - - - - - - - - - - - -A - -B -transformation - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mission-control/docs/images/flanksource-icon.png b/mission-control/docs/images/flanksource-icon.png deleted file mode 100644 index 1996dbe8..00000000 Binary files a/mission-control/docs/images/flanksource-icon.png and /dev/null differ diff --git a/mission-control/docs/index.md b/mission-control/docs/index.md deleted file mode 100644 index 7de1a790..00000000 --- a/mission-control/docs/index.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -slug: / -title: Flanksource Mission Control -hide_title: true -# hide_table_of_contents: true -# pagination_next: null -# pagination_prev: null ---- - - -Flanksource Mission Control is an Internal Developer Platform focused on GitOps platforms. - -![](./images/how-it-works.svg) - - -* [Catalog](./config-db/overview) - Catalog all your infrastructure, applications, pipelines and configuration into a schema-less JSON database, with automatic change tracking. -* [Playbooks](./playbooks/overview) - Self-Service portal for day 0-2 operations like provisioning a new namespace, restarting a deployment, or updating files in git repositories. Playbooks also be triggered via webhooks and events. -* [Health Checks](./canary-checker/overview) - RAG (red, amber, green) statuses across infrastructure, applications and commercial off the shelf software, With alert aggregation, synthethic application and infrastructure checks. -* [Topology](./topology/overview) - Visualize complex systems using a multi-dimensional hierarchical cards. -* [Notifications](./notifications/overview) - Send notifcations during playbook execution or based on any event fired from catalog, health or topology changes. - diff --git a/mission-control/docs/index.mdx b/mission-control/docs/index.mdx new file mode 100644 index 00000000..9dc451b8 --- /dev/null +++ b/mission-control/docs/index.mdx @@ -0,0 +1,37 @@ +--- +slug: / +title: Flanksource Mission Control +hide_title: true +# hide_table_of_contents: true +pagination_next: config-db/overview +pagination_prev: null +--- + + +Flanksource Mission Control is an Internal Developer Platform that helps teams improve developer productivity and operational resilience. + +![](/img/how-it-works.svg) + +With Mission Control you can: + +* [Catalog](./config-db/overview) and track changes on infrastructure, applications and configuration. +* [Empower Developers](./playbooks/overview) with self-service playbooks for Day 0-2 operations. +* [Run Health Checks](./canary-checker/overview) across both cloud-native and legacy infrastructure and applications. +* [Incrementally Adopt GitOps](./playbooks/actions/gitops) with playbooks that perform Git commits in the background. +* [Aggregate Alerts](./canary-checker/probes) from Prometheus, Cloudwatch, Datadog, etc. +* [Visualize Complex Systems](./topology/overview) with a multi-dimensional system topology. +* [Build Event Driven Control Planes](./playbooks/actions/gitops) with a combination of webhooks, events and GitOps. +* [Notify People and Systems](./notifications/overview) about changes in health and configuration. + + + +## Getting Help + +If you have any questions about canary checker: + +* Invite yourself to the [CNCF community slack](https://slack.cncf.io/) and join the [#canary-checker](https://cloud-native.slack.com/messages/canary-checker/) channel. +* Check out the [Youtube Playlist](https://www.youtube.com/playlist?list=PLz4F_KggvA58D6krlw433TNr8qMbu1aIU). +* File an [issue](https://github.com/flanksource/mission-control/issues/new) - (We do provide user support via Github Issues, so don't worry if your issue a real bug or not) +* Email us at [hello@flanksource.com](mailto:hello@flanksource.com) + +Your feedback is always welcome! diff --git a/mission-control/docs/installation/artifacts.md b/mission-control/docs/installation/artifacts.md new file mode 100644 index 00000000..72dbba0c --- /dev/null +++ b/mission-control/docs/installation/artifacts.md @@ -0,0 +1,19 @@ +# Artifacts + +## Filestores + +- AWS S3 +- Google Cloud Storage +- SFTP +- SMB +- Local Filesystem + +## Setting up artifact store + +One of the above filestores can be used as the global artifact store. To setup an artifact store, pass the connection name of the store using the `artifact-connection` flag. If the artifact connection isn't setup, the artifacts are simply ignored. + +Example: + +```bash +mission-control --artifact-connection='connection://sftp/artifacts' +``` diff --git a/mission-control/docs/installation/database.md b/mission-control/docs/installation/database.md index a8205530..ecab98ba 100644 --- a/mission-control/docs/installation/database.md +++ b/mission-control/docs/installation/database.md @@ -5,7 +5,7 @@ description: Alternative methods for connecting to the db used for persistence Mission Control stores all state in a Postgres Database, by default a Postgres StatefulSet is created. -## Update the Postgres Statefulset +## Configuring the Default Statefulset ```yaml title="values.yaml" db: @@ -14,9 +14,6 @@ db: secretKeyRef: # auto-generated if it doesn't exist name: incident-commander-postgres key: DB_URL - jwtSecretKeyRef: # auto generated key for postgrest to validate tokens from users - name: incident-commander-postgrest-jwt - key: PGRST_JWT_SECRET storageClass: # optional storage class for PVC volume storage: 20Gi shmVolume: 256Mi # size of shm memory file to be mounted @@ -33,7 +30,7 @@ kubectl get secret incident-commander-postgres -o json | jq -r '.data.POSTGRES_P :::info Connecting -If you ever need to connect to the embedded database, you can do so by forwarding the port: +If you ever need to connect to the database, you can do so by forwarding the port: ```shell kubectl port-forward svc/postgres 5432:5432 @@ -41,7 +38,7 @@ psql -U postgres localhost -p 5432 mission_control ``` ::: -## Connecting to an external db +## Using an External Database In order to connect to an existing Postgres server, a database must be created on the server, along with a user that has administrator permissions for the database. diff --git a/mission-control/docs/installation/helm.md b/mission-control/docs/installation/helm.md index 663effb7..bf59ad85 100644 --- a/mission-control/docs/installation/helm.md +++ b/mission-control/docs/installation/helm.md @@ -1,10 +1,8 @@ -# Quick Start - -How to Install Mission control with helm +# Self-Hosted Install With Helm ## Prerequisites -To install and run the Mission Control chart on your Kubernetes Cluster, you need to have the following prerequisites; +To install and run Mission Control you need to have the following prerequisites: - A Kubernetes installation of version 1.26 or higher. - (Optional) SMTP Server (For sending notifications and invites) @@ -12,10 +10,6 @@ To install and run the Mission Control chart on your Kubernetes Cluster, you nee ## Install Chart -```console -helm install [RELEASE_NAME] flanksource/mission-control -``` - To set custom values file for your mission-control helm chart installation to override existing values in [`mission-control-chart`](https://github.com/flanksource/mission-control-chart/blob/main/chart/values.yaml). ```yaml title="values.yaml" @@ -27,10 +21,6 @@ global: adminPassword: admin # The default password for the admin@local user -canary-checker: - image: - type: full # use minimal for a smaller image - flanksource-ui: ingress: enabled: true @@ -43,6 +33,8 @@ db: ``` ```bash +helm repo add flanksource https://flanksource.github.io/charts +helm repo update helm install mission-control \ flanksource/mission-control \ -n mission-control \ diff --git a/mission-control/docs/installation/iam.json b/mission-control/docs/installation/iam.json new file mode 100644 index 00000000..a0b818c5 --- /dev/null +++ b/mission-control/docs/installation/iam.json @@ -0,0 +1,37 @@ +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "cloudtrail:LookupEvents", + "ec2:DescribeDhcpOptions", + "ec2:DescribeInstances", + "ec2:DescribeRouteTables", + "ec2:DescribeSecurityGroups", + "ec2:DescribeSubnets", + "ec2:DescribeVolumes", + "ec2:DescribeVpcs", + "ecr:DescribeRepositories", + "eks:ListClusters", + "elasticfilesystem:DescribeFileSystems", + "elasticloadbalancing:DescribeLoadBalancers", + "elasticloadbalancing:DescribeTags", + "sts:GetCallerIdentity", + "eks:DescribeCluster", + "rds:DescribeDBInstances", + "s3:GetBucketLocation" + ], + "Resource": "*" + }, + { + "Effect": "Allow", + "Action": [ + "athena:GetQueryExecution", + "athena:GetQueryResults", + "athena:StartQueryExecution" + ], + "Resource": "arn:aws:athena:${Region}:${Account}:workgroup/${WorkGroupName}" + } + ] +} diff --git a/mission-control/docs/installation/kind_linux.md b/mission-control/docs/installation/kind_linux.md index 2bd68323..ca0b99a0 100644 --- a/mission-control/docs/installation/kind_linux.md +++ b/mission-control/docs/installation/kind_linux.md @@ -56,11 +56,6 @@ Add the Flanksource repository to helm: ```bash helm repo add flanksource https://flanksource.github.io/charts -``` - -then fetch the latest chart list with - -```bash helm repo update ``` diff --git a/mission-control/docs/notifications/examples/slack.md b/mission-control/docs/notifications/examples/slack.md index f5aaef40..c0e0c2cb 100644 --- a/mission-control/docs/notifications/examples/slack.md +++ b/mission-control/docs/notifications/examples/slack.md @@ -8,13 +8,13 @@ In this example, we will walk through the process of creating a health check ale Visit https://api.slack.com/apps and create a new app. Use the "From an app manifest" option. -![App Creation](../../images/slack-app-creation.png) +![App Creation](/img/slack-app-creation.png) ### Set up OAuth permission After creating the app, you should be navigated to the app's homepage. On the left panel menu, go to Features->OAuth & Permissions. Scroll down and you should see the **"Scopes"** section -![](../../images/slack-app-oauth-scope.png) +![](/img/slack-app-oauth-scope.png) Set `chat:write` permission @@ -22,11 +22,11 @@ Set `chat:write` permission While still on the same page, scroll up to the "OAuth Tokens for Your Workspace" section. Install the newly created app on your Slack workspace. -![](../../images/slack-app-install-to-workspace.png) +![](/img/slack-app-install-to-workspace.png) Once you install the app you should see the OAuth token -![](../../images/slack-bot-user-oauth-token.png) +![](/img/slack-bot-user-oauth-token.png) ## Set up the notification diff --git a/mission-control/docs/notifications/overview.md b/mission-control/docs/notifications/overview.md index 549162ec..a6ce57dc 100644 --- a/mission-control/docs/notifications/overview.md +++ b/mission-control/docs/notifications/overview.md @@ -1,3 +1,7 @@ +--- +pagination_next: registry/overview +pagination_prev: canary-checker/health-checks +--- # Notifications Notification allows you to receive alerts on a preferred channel when a particular set of events occur. diff --git a/mission-control/docs/playbooks/actions/exec.md b/mission-control/docs/playbooks/actions/exec.md index 0df4e955..23eee2b7 100644 --- a/mission-control/docs/playbooks/actions/exec.md +++ b/mission-control/docs/playbooks/actions/exec.md @@ -61,20 +61,18 @@ will be setup on the host running the script. | ------ | ------------- | -------- | -------- | | `path` | Path or glob. | `string` | `true` | -[Read more ...](../concepts/artifacts.md) - ### Git Checkout For authentication, either provide the connection name or the basic auth or the certificate. -| Field | Description | Type | Required | -| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | -------- | -| `url` | Git repository URL. | `string` | `true` | -| `connection` | Specify the connection name to use for git authentication (if required) | *EnvVar* | | -| `username` | Git auth username. | *EnvVar* | | -| `password` | Git auth password. | *EnvVar* | | -| `certificate` | Git auth certificate. | *EnvVar* | | -| `destination` | Destination is the full path to where the contents of the URL should be downloaded to. If left empty, the sha256 hash of the URL will be used as the dir name. | `string` | | +| Field | Description | Type | Required | +| ------------- | ------------------------------------------------------------ | ----------------------------------------------------- | -------- | +| `url` | Git repository URL. | `string` | `true` | +| `connection` | Specify the connection name to use for git authentication (if required) | *Connection* | | +| `username` | Git auth username. | *EnvVar* | | +| `password` | Git auth password. | *EnvVar* | | +| `certificate` | Git auth certificate. | *EnvVar* | | +| `destination` | Destination is the full path to where the contents of the URL should be downloaded to. If left empty, the sha256 hash of the URL will be used as the dir name. | `string` | | ## Templating @@ -86,3 +84,14 @@ Scripts can be templated. The script template receives a environment variable th | `component` | Component passed to the playbook | [`Component`](../references/component.md) | | `check` | Canary Check passed to the playbook | [`Check`](../references/check.md) | | `params` | User provided parameters to the playbook | `map[string]string` | + + + +### Action Result + +| Field | Description | Schema | +| ---------- | ----------------- | -------- | +| `stdout` | | `string` | +| `stderr` | | `string` | +| `exitCode` | Process exit code | `int` | + diff --git a/mission-control/docs/playbooks/actions/gitops.md b/mission-control/docs/playbooks/actions/gitops.md index 8cf6c237..f0d68414 100644 --- a/mission-control/docs/playbooks/actions/gitops.md +++ b/mission-control/docs/playbooks/actions/gitops.md @@ -10,42 +10,56 @@ GitOps action allows you to make commits and push to a remote repository. apiVersion: mission-control.flanksource.com/v1 kind: Playbook metadata: - name: update-pod-namespace + name: edit-kubernetes-manifests-gitops spec: + title: 'Edit Kustomize Resource' + icon: flux parameters: - - name: namespace - label: The new namespace + - default: 'chore: update $(.config.type)/$(.config.name)' + label: Commit Message + name: commit_message + - default: $(.config.config | toJSON | neat | json | toYAML) + label: "" + name: yamlInput + properties: + size: large + type: code + configs: - - type: Kubernetes::Pod + - labelSelector: 'kustomize.toolkit.fluxcd.io/name' + + env: + - name: file_path + value: {{ .config.config | jq `.metadata.annotations["config.kubernetes.io/origin"]` | yaml).path }} + - name: kustomization_path + value: {{ (catalog_traverse .config.id "Kubernetes::Kustomization").Config | json | jq `.spec.path` }} + - name: git_url + value: {{ (catalog_traverse .config.id "Kubernetes::Kustomization/Kubernetes::GitRepository").Config | json | jq `.spec.url` }} + - name: git_branch + value: {{ (catalog_traverse .config.id "Kubernetes::Kustomization/Kubernetes::GitRepository").Config | json | jq `.spec.ref.branch` }} + actions: - - name: Modify namespace + - name: Create Pull Request With Changes gitops: repo: - url: https://github.com/example/repo - connection: connection://github/example - base: master - branch: playbooks-branch-{{.params.namespace}} + url: '$(.env.git_url)' + connection: + base: '$(.env.git_branch)' + branch: edit-manifest-$(random.Alpha 8) commit: - email: john@doe.com - author: John Doe - message: | - Modifying namespace from {{.config.namespace}} to {{.params.namespace}} + author: '$(.user.name)' + email: '$(.user.email)' + message: $(.params.commit_message) pr: - title: 'chore: Update namespace to {{.params.namespace}}' - tags: - - low + title: $(.params.commit_message) patches: - - path: navidrome.yaml - yq: '.metadata.namespace = "{{.params.namespace}}"' - files: - - path: { { .config.namespace } } - content: $delete - - path: '{{.params.namespace}}/namespace.yaml' - content: | - apiVersion: v1 - kind: Namespace - metadata: - name: {{.params.namespace}} + - path: '$(filepath.Join .env.kustomization_path .env.file_path)' + yq: | + select( + .kind=="$(.config.config | jq `.kind`)" and + .metadata.name=="$(.config.config | jq `.metadata.name`)" + ) |= $(.params.yamlInput | yaml | toJSON) + ``` :::info diff --git a/mission-control/docs/playbooks/actions/overview.md b/mission-control/docs/playbooks/actions/overview.md new file mode 100644 index 00000000..1b141a7f --- /dev/null +++ b/mission-control/docs/playbooks/actions/overview.md @@ -0,0 +1,84 @@ +# Actions + +Actions are the fundamental tasks executed by a playbook. A playbook can comprise multiple actions, which are executed sequentially. If any action encounters an error and fails, the execution of the playbook is halted. + +| Field | Description | Scheme | Required | +| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | -------- | +| `name` | Name of action. | `string` | `true` | +| `runsOn` | Specify the [runners](./runners.md) that can run this action. One will be chosen on random. When empty, the playbook will run on the main instance itself | `[]string` | | +| `templatesOn` | Specify where the templating of the action spec should occur | `host` or `agent` | | +| `delay` | A delay before running the action e.g. `8h` | `Duration` or [`Expression`](../concepts/expression) | | +| `filter` | Whether to run the step or not | [`Expression`](../concepts/expression) | | +| `timeout` | Timeout on this action. | `Duration` | | +| `exec` | Specify exec of action. | [`Exec`](../actions/exec.md) | | +| `gitops` | Specify gitops of action. | [`Gitops`](../actions/gitops.md) | | +| `http` | Specify http of action. | [`Http`](../actions/http.md) | | +| `sql` | Specify sql of action. | [`Sql`](../actions/sql.md) | | +| `pod` | Specify pod of action. | [`Pod`](../actions/pod.md) | | +| `notification` | Specify notification of action. | [`Notification`](../actions/notification.md) | | + +:::note +Specify one or more actions; but at least one. +::: + + + +## Templating + +Templating allows your playbook actions to work in context of a config, health check or a component. + +```yaml title='scale-deployment.yaml' +apiVersion: mission-control.flanksource.com/v1 +kind: Playbook +metadata: + name: scale-deployment +spec: + description: Scale deployment + configs: + - types: [Kubernetes::Deployment] + parameters: + - name: replicas + label: The new desired number of replicas. + actions: + - name: scale deployment + exec: + script: kubectl scale --replicas={{.params.replicas}} --namespace={{.config.tags.namespace}} deployment {{.config.name}} +``` + + +### Accessing results of another action + +You can base your filters based on result of a previous action. The following two cel functions can be used: + +#### getLastAction + +`getLastAction()` returns the result of the action that ran just before this action. + +Syntax: + +```javascript +getLastAction().result.stdout.JSON().count < 5; +``` + +#### getAction + +To fetch the result of any action that ran before this action, use `getAction()` + +Syntax: + +```javascript +getAction('action_name').result.stdout.JSON().count < 5; +``` + +### Context + +Templates receive a context variable that contain details about the config or component it is running for. In addition, it also contains the optional `params` variable which contains the parameters passed to the playbook. + +| Field | Description | Schema | +| ----------- | ---------------------------------------- | -------------------------------------------- | +| `.config` | Config passed to the playbook | [`ConfigItem`](/reference/config-db/config-item) | +| `.component` | Component passed to the playbook | [`Component`](/reference/topology/components) | +| `.check` | Canary Check passed to the playbook | [`Check`](/reference/canary-checker/check) | +| `.params` | User provided parameters to the playbook | `map[string]string` | +| `.user.name` | Name of the user who invoked the action | `string` | +| `.user.email` | Email of the user who invoked the action | `string` | diff --git a/mission-control/docs/playbooks/concepts/approval.md b/mission-control/docs/playbooks/concepts/approval.md index de9b5410..76d80bc2 100644 --- a/mission-control/docs/playbooks/concepts/approval.md +++ b/mission-control/docs/playbooks/concepts/approval.md @@ -3,19 +3,10 @@ Authorization safeguards can be applied to playbook runs, ensuring their execution is limited to specific individuals or teams who grant approval. ```yaml title="approve-kubernetes-scaling.yaml" -apiVersion: mission-control.flanksource.com/v1 +#... kind: Playbook -metadata: - name: scale-deployment spec: - description: Scale deployment - configs: - - type: Kubernetes::Deployment - tags: - environment: staging - parameters: - - name: replicas - label: The new desired number of replicas. + #... approval: type: any approvers: @@ -23,29 +14,10 @@ spec: - admin@local teams: - DevOps - actions: - - name: 'scale deployment' - exec: - script: kubectl scale --replicas={{.params.replicas}} --namespace={{.config.tags.namespace}} deployment {{.config.name}} ``` -## Approval - | Field | Description | Scheme | Required | | ----------- | ------------------------------ | ------------ | -------- | -| `type` | Specify type of approval. | `string` | `false` | -| `approvers` | Specify approvers of approval. | `[]Approver` | `false` | - -### Approval Type - -| Type | Description | -| ----- | ------------------------------------- | -| `any` | A single approval can suffice. | -| `all` | All approvals are required. (default) | - -### Approvers - -| Field | Description | Scheme | Required | -| -------- | ------------------------- | ---------- | -------- | -| `people` | Specify ids of the people | `[]string` | `false` | -| `teams` | Specify ids of the teams | `[]string` | `false` | +| `type` | How many approvals required. Defaults to `all` | `any` or `all` | `false` | +| `approvers.[]people` | Login or id of a person| `People` | `false` | +| `approvers.[]teams` | Name or id of a team | `Team` | `false` | diff --git a/mission-control/docs/playbooks/concepts/artifacts.md b/mission-control/docs/playbooks/concepts/artifacts.md index fd525000..9aa782ef 100644 --- a/mission-control/docs/playbooks/concepts/artifacts.md +++ b/mission-control/docs/playbooks/concepts/artifacts.md @@ -2,25 +2,11 @@ Artifacts allow you to archive files generated by playbook actions to a file store of your choice. -## Filestores -- AWS S3 -- Google Cloud Storage -- SFTP -- SMB -- Local Filesystem +:::note Prerequisite +Configure the [artifact store](/installation/artifacts). +::: -## Setting up artifact store - -One of the above filestores can be used as the global artifact store. To setup an artifact store, pass the connection name of the store using the `artifact-connection` flag. If the artifact connection isn't setup, the artifacts are simply ignored. - -Example: - -```bash -mission-control --artifact-connection='connection://sftp/artifacts' -``` - -## Archiving artifacts The following actions support archiving artifacts @@ -29,7 +15,7 @@ The following actions support archiving artifacts The only configuration required on the action is to provide the path(s) of the artifacts generated by the actions. -### Ex1. Archiving `/tmp/results/` directory +## Archiving a directory For the following script in an exec action @@ -66,7 +52,7 @@ artifacts - path: '/tmp/results/*.com' ``` -### Ex2. Archiving artifacts from stdout/stderr +## Archiving output from stdout/stderr The path field accepts two special paths diff --git a/mission-control/docs/playbooks/concepts/expression.md b/mission-control/docs/playbooks/concepts/expression.md index 12557182..90f866ba 100644 --- a/mission-control/docs/playbooks/concepts/expression.md +++ b/mission-control/docs/playbooks/concepts/expression.md @@ -35,11 +35,36 @@ spec: script: notify-send "a config was created" ``` +## Conditionally running actions + +Playbook actions can be selectively executed based on CEL expressions. These expressions must either return + +- a boolean value (`true` indicating run the action & skip the action otherwise) +- or a special function among the ones listed below + +| Function | Description | +| ----------- | ----------------------------------------------------------- | +| `always()` | run no matter what; even if the playbook is cancelled/fails | +| `failure()` | run if any of the previous actions failed | +| `skip()` | skip running this action | +| `success()` | run only if all previous actions succeeded (default) | +| `timeout()` | run only if any of the previous actions timed out | + +**Examples** + +- `if: config.deleted_at ? true: false` +- `if: always()` + ## Context +Expressions have access to the following variables and functions + | Field | Description | Schema | | ----------- | ---------------------------------------- | -------------------------------------------- | -| `config` | Config passed to the playbook | [`ConfigItem`](../references/config_item.md) | -| `component` | Component passed to the playbook | [`Component`](../references/component.md) | -| `check` | Canary Check passed to the playbook | [`Check`](../references/check.md) | -| `params` | User provided parameters to the playbook | `map[string]string` | +| `.config` | Config passed to the playbook | [`ConfigItem`](/reference/config-db/config-item) | +| `.component` | Component passed to the playbook | [`Component`](/reference/topology/components) | +| `.check` | Canary Check passed to the playbook | [`Check`](/reference/canary-checker/check) | +| `.params` | User provided parameters to the playbook | `map[string]string` | +| `.user.name` | Name of the user who invoked the action | `string` | +| `.user.email` | Email of the user who invoked the action | `string` | + diff --git a/mission-control/docs/playbooks/concepts/parameters.md b/mission-control/docs/playbooks/concepts/parameters.md new file mode 100644 index 00000000..e69de29b diff --git a/mission-control/docs/playbooks/concepts/playbook.md b/mission-control/docs/playbooks/concepts/playbook.md index 4c568cad..c14ba7dc 100644 --- a/mission-control/docs/playbooks/concepts/playbook.md +++ b/mission-control/docs/playbooks/concepts/playbook.md @@ -1,45 +1,23 @@ # Playbook -Playbooks are configurable automated processes that can be used to perform a variety of actions for a resource like config item, component, & check. -They can also operate independently of any specific resource, providing versatility in handling different tasks and processes within a system or environment - -```yaml title="restart-unhealthy-database.yaml" -apiVersion: mission-control.flanksource.com/v1 -kind: Playbook -metadata: - name: restart-unhealthy-database -spec: - description: Restart when a database becomes unhealthy - on: - component: - - event: unhealthy - filter: component.type == 'database' - labels: - industry: e-commerce - actions: - - name: 'Restart kubernetes deployment' - exec: - script: kubectl rollout restart deployment {{.component.name}} -``` - -![Playbooks List](../../images/playbooks-list.png) + _Fig: Playbooks Page_ ## Spec -| Field | Description | Scheme | Required | -| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | -------- | -| `description` | A short description | `string` | `true` | -| `icon` | Icon for the playbook | `string` | | -| `on` | Specify events to automatically trigger the Playbook. . | [`[]Trigger`](#trigger) | | -| `runsOn` | Specify the [runners](./runners.md) that can run this playbook. One will be chosen on random. When empty, the playbook will run on the main instance itself | `[]string` | | -| `templatesOn` | Specify where the templating of the action spec should occur | `host`\|`agent` | | -| `checks` | Specify selectors for checks that can be run on the Playbook. | [`[]ResourceFilter`](#resourcefilter) | | -| `configs` | Specify selectors for config items that can be run on the Playbook. | [`[]ResourceFilter`](#resourcefilter) | | -| `components` | Specify selectors for component items that can be run on the Playbook. | [`[]ResourceFilter`](#resourcefilter) | | -| `parameters` | Define a set of labeled parameters for the Playbook. | [`[]Parameter`](#parameter) | | -| `actions` | Specify the set of actions to run. | [`[]Action`](#action) | `true` | -| `approval` | Specify who can approve runs on this playbook. | [`Approval`](./approval#approval) | | +| Field | Description | Scheme | Required | +| ------------- | ------------------------------------------------------------ | ---------------------------------------------------- | -------- | +| `description` | A short description | `string` | `true` | +| `icon` | Icon for the playbook | `string` | | +| `on` | Specify events to automatically trigger the Playbook. . | [`[]Trigger`](#trigger) | | +| `runsOn` | Specify the [runners](./runners.md) that can run this playbook. One will be chosen on random. When empty, the playbook will run on the main instance itself | `[]string` | | +| `templatesOn` | Specify where the templating of the action spec should occur | `host` or `agent` | | +| `checks` | Specify selectors for checks that can be run on the Playbook. | [`[]ResourceSelector`](/reference/resource-selector) | | +| `configs` | Specify selectors for config items that can be run on the Playbook. | [`[]ResourceSelector`](/reference/resource-selector) | | +| `components` | Specify selectors for component items that can be run on the Playbook. | [`[]ResourceSelector`](/reference/resource-selector) | | +| `parameters` | Define a set of labeled parameters for the Playbook. | [`[]Parameter`](#parameter) | | +| `actions` | Specify the set of actions to run. | [`[]Action`](#action) | `true` | +| `approval` | Specify who can approve runs on this playbook. | [`Approval`](./approval#approval) | | ### Trigger @@ -49,86 +27,7 @@ _Fig: Playbooks Page_ | `component` | Setup trigger on health check events. | [`EventTrigger`](../concepts/events#event-spec) | | | `webhook` | Setup a webhook endpoint that triggers the playbook. | [`WebhookTrigger`](../concepts/webhook#spec) | | -### ResourceFilter - -Filters can define what resources (checks, configs or components) are permitted be run on the Playbook. - -| Field | Description | Scheme | Required | -| ------ | -------------------------- | ------------------- | -------- | -| `type` | Specify type of component. | `string` | | -| `tags` | Specify tags of component. | `map[string]string` | | - -### Parameter - -Playbook parameter defines a parameter that a playbook needs to run. - -| Field | Description | Scheme | Required | Templatable | -| ------------- | ------------------------------------------------------------------------------------------------- | ------------------- | -------- | ----------- | -| `name` | Name of parameter. | `string` | `true` | -| `default` | Default value of the parameter. | `string` | | `true` | -| `label` | Label of the parameter. | `string` | `true` | -| `required` | Specify if the parameter is required | `bool` | | -| `icon` | Icon of parameter. See [icons](https://github.com/flanksource/flanksource-ui/tree/main/src/icons) | `string` | | -| `description` | Description of the parameter. | `string` | | -| `type` | Type of parameter. _(Defaults to "text")_ | `string` | | -| `properties` | Properties of parameter. _Varies based on the type_ | `map[string]string` | | - -#### Parameter Type - -| name | Description | UI Component | Schema | Properties | -| ----------- | ---------------------------------- | ------------ | --------- | ---------------------------------------------------------- | -| `check` | Limits the value to a check. | Dropdown | `string` | [`Check Property`](#table-filter-parameter-properties) | -| `checkbox` | Boolean value toggle | Checkbox | `boolean` | - | -| `code` | Text area | Code Editor | `string` | [`Code Property`](#code-parameter-properties) | -| `component` | Limits the value to a component. | Dropdown | `string` | [`Component Property`](#table-filter-parameter-properties) | -| `config` | Limits the value to a config item. | Dropdown | `string` | [`Config Property`](#table-filter-parameter-properties) | -| `list` | Specify a custom list of values | Dropdown | `string` | [`List Property`](#list-parameter-properties) | -| `people` | Limits the value to people. | Dropdown | `string` | [`People Property`](#people-parameter-properties) | -| `team` | Limits the value to teams. | Dropdown | `string` | - | -| `text` | Text input | Text Input | `string` | [`Text Property`](#text-parameter-properties) | - -##### table filter parameter properties - -| Field | Description | Schema | -| -------- | ---------------------------------------- | ------------------------------- | -| `filter` | A set of filters to apply on the options | [`Table Filter`](#table-filter) | - -###### table filter -| Field | Description | Schema | -| ------ | -------------------------------------- | -------- | -| `type` | Limit the components to the given type | `string` | - -##### `code` parameter properties - -| Field | Description | Schema | -| ---------- | ----------------------------------------- | -------- | -| `language` | Langauge name e.g. yaml, json, toml, etc. | `string` | - -##### `people` parameter properties - -| Field | Description | Schema | -| ------ | ---------------------------------- | ------- | -| `role` | Limit the people to the given role | `string | - -##### `text` parameter properties - -| Field | Description | Schema | -| ----------- | ------------------------------------------------------- | --------- | -| `multiline` | Whether the text field should be rendered as a text are | `boolean` | - -##### `list` parameter properties - -| Field | Description | Schema | -| --------- | ------------------ | ------------------------------ | -| `options` | Label of the check | [`[]ListOption`](#list-option) | - -###### List Option - -| Field | Description | Schema | -| ------- | -------------------------------- | -------- | -| `label` | Specify label of the list option | `string` | -| `value` | Specify value of the list option | `string` | ## Run @@ -140,7 +39,7 @@ A run is the execution of a Playbook consisting of a sequence of actions. A run For example, a playbook can be executed when a health check passes or fails. -![Playbook Runs](../../images/playbook-runs.png) +![Playbook Runs](/img/playbook-runs.png) _Fig: Playbooks Runs_ ### Start Time @@ -149,36 +48,6 @@ Every run must have a start time which is the time the run is scheduled to start Start time can be in future or even in the past. -## Action - -Actions are the fundamental tasks executed by a playbook. A playbook can comprise multiple actions, which are executed sequentially. If any action encounters an error and fails, the execution of the playbook is halted. - -| Field | Description | Scheme | Required | -| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | -------- | -| `name` | Name of action. | `string` | `true` | -| `runsOn` | Specify the [runners](./runners.md) that can run this action. One will be chosen on random. When empty, the playbook will run on the main instance itself | `[]string` | | -| `templatesOn` | Specify where the templating of the action spec should occur | `host`\|`agent` | | -| `delay` | A CEL expression that evaluates to a duration to delay the execution of the action. _(Sensitive to the minute.)_ | `string` | | -| `filter` | A CEL expression that returns a boolean or special value to indicated whether the action should run or not. [Read below](#conditionally-running-actions) | `string` | | -| `timeout` | Timeout on this action. | [`DurationString`](#duration-string) | | -| `exec` | Specify exec of action. | [`ExecAction`](../actions/exec.md) | | -| `gitops` | Specify gitops of action. | [`GitopsAction`](../actions/gitops.md) | | -| `http` | Specify http of action. | [`HttpAction`](../actions/http.md) | | -| `sql` | Specify sql of action. | [`SqlAction`](../actions/sql.md) | | -| `pod` | Specify pod of action. | [`PodAction`](../actions/pod.md) | | -| `notification` | Specify notification of action. | [`NotificationAction`](../actions/notification.md) | | - -:::note -Specify one or more actions; but at least one. -::: - -![Playbook Action Logs](../../images/playbook-action-logs.png) -_Fig: Playbooks Action Logs_ - -### Delaying actions - -Actions can be delayed by a fixed duration or conditionally by a CEL expression. -It's only sensitive to the minute. i.e. if you delay by 20s it can take upto a minute to execute. #### Templating @@ -191,57 +60,4 @@ The CEL expression receives a environment variable that contain details about th | `check` | Canary Check passed to the playbook | [`Check`](../references/check.md) | | `params` | User provided parameters to the playbook | `map[string]string` | -Valid time units are "s", "m", "h", "d", "w", "y". Eg: - -- `1m15s` -- `1h5m` -- `23h` -- `1d8h` -- `1w6d8h` -- `19w0d8h` - -### Conditionally running actions - -Playbook actions can be selectively executed based on CEL expressions. These expressions must either return - -- a boolean value _(`true` indicating run the action & skip the action otherwise)_ -- or a special function among the ones listed below - -#### Functions - -| Function | Description | -| ----------- | ----------------------------------------------------------- | -| `always()` | run no matter what; even if the playbook is cancelled/fails | -| `failure()` | run if any of the previous actions failed | -| `skip()` | skip running this action | -| `success()` | run only if all previous actions succeeded (default) | -| `timeout()` | run only if any of the previous actions timed out | - -#### Examples - -- `if: config.deleted_at ? true: false` -- `if: always()` - -#### Accessing results of another action - -You can base your filters based on result of a previous action. The following two cel functions can be used: - -1. **getLastAction** - -`getLastAction()` returns the result of the action that ran just before this action. - -Syntax: - -```javascript -getLastAction().result.stdout.JSON().count < 5; -``` - -2. **getAction** - -To fetch the result of any action that ran before this action, use `getAction()` - -Syntax: -```javascript -getAction('action_name').result.stdout.JSON().count < 5; -``` diff --git a/mission-control/docs/playbooks/concepts/runners.md b/mission-control/docs/playbooks/concepts/runners.md index 1aa46cf9..508d4519 100644 --- a/mission-control/docs/playbooks/concepts/runners.md +++ b/mission-control/docs/playbooks/concepts/runners.md @@ -5,6 +5,8 @@ This enables a playbook action to access environment specific information such a Runners can be set at the playbook or action level. +## Runs On + ```yaml title='delete-namespace.yaml' apiVersion: mission-control.flanksource.com/v1 kind: Playbook @@ -39,7 +41,7 @@ spec: title: Namespace {{.config.name}} deleted successfully ``` -## Templating on the agent +## Templates On Actions are templated by the host before it's sent to the runner for execution. This setup permits the runner to execute actions that are templated with resources exclusively available on the host, such as config items or components, checks, ... etc. @@ -63,6 +65,7 @@ spec: actions: - name: send heartbeat exec: + # environment variables from the mission control cluster env: - name: HEARTBEAT_TOKEN valueFrom: @@ -70,12 +73,13 @@ spec: name: canary-checker-heartbeat key: token script: | - curl -H "Authorization: $HEARTBEAT_TOKEN" -H "X-CHECK-ID: {{.params.check_id}}" https://httpbin.demo.aws.flanksource.com/bearer + curl -H "Authorization: $HEARTBEAT_TOKEN" https://httpbin.demo.aws.flanksource.com/bearer - name: send heartbeat from the agent runsOn: - 'aws' templatesOn: 'agent' exec: + # environment variables from cluster the agent is running on env: - name: HEARTBEAT_TOKEN valueFrom: @@ -83,5 +87,5 @@ spec: name: canary-checker-heartbeat key: token script: | - curl -H "Authorization: $HEARTBEAT_TOKEN" -H "X-CHECK-ID: {{.params.check_id}}" https://httpbin.demo.aws.flanksource.com/bearer + curl -H "Authorization: $HEARTBEAT_TOKEN" https://httpbin.demo.aws.flanksource.com/bearer ``` diff --git a/mission-control/docs/playbooks/concepts/templating.md b/mission-control/docs/playbooks/concepts/templating.md index a43429df..074d8f9e 100644 --- a/mission-control/docs/playbooks/concepts/templating.md +++ b/mission-control/docs/playbooks/concepts/templating.md @@ -1,9 +1,5 @@ # Templating -**Templating is:** - -> Simply a way to represent data in different forms. - Templating allows your playbook actions to work in context of a config, health check or a component. **Example**: @@ -28,13 +24,59 @@ spec: script: kubectl scale --replicas={{.params.replicas}} --namespace={{.config.tags.namespace}} deployment {{.config.name}} ``` + +## Accessing results of another action + +You can base your filters based on result of a previous action. The following two cel functions can be used: + +### getLastAction + +`getLastAction()` + +Syntax: + +```javascript +getLastAction().result.stdout.JSON().count < 5; +``` + +### getAction + +To fetch the result of any action that ran before this action, use `getAction()` + +Syntax: + +```javascript +getAction('action_name').result.stdout.JSON().count < 5; +``` + ## Context Templates receive a context variable that contain details about the config or component it is running for. In addition, it also contains the optional `params` variable which contains the parameters passed to the playbook. | Field | Description | Schema | | ----------- | ---------------------------------------- | -------------------------------------------- | -| `config` | Config passed to the playbook | [`ConfigItem`](../references/config_item.md) | -| `component` | Component passed to the playbook | [`Component`](../references/component.md) | -| `check` | Canary Check passed to the playbook | [`Check`](../references/check.md) | -| `params` | User provided parameters to the playbook | `map[string]string` | +| `.config` | Config passed to the playbook | [`ConfigItem`](/reference/config-db/config-item) | +| `.component` | Component passed to the playbook | [`Component`](/reference/topology/components) | +| `.check` | Canary Check passed to the playbook | [`Check`](/reference/canary-checker/check) | +| `.params` | User provided parameters to the playbook | `map[string]string` | +| `.user.name` | Name of the user who invoked the action | `string` | +| `.user.email` | Email of the user who invoked the action | `string` | +| `getLastAction()` | Returns the result of the action that just run | Action Specific | +| `getAction({action})` | Return the result of a specific action | Action Specific | + + + +### Action Result + + + +| Field | Description | Schema | +| --------------- | ----------- | ------ | +| `result.stdout` | | | +| | | | +| | | | + + + + + diff --git a/mission-control/docs/playbooks/examples/gitops-k8s-cluster-role-binding.md b/mission-control/docs/playbooks/examples/gitops-k8s-cluster-role-binding.md index 723903ca..c198ca18 100644 --- a/mission-control/docs/playbooks/examples/gitops-k8s-cluster-role-binding.md +++ b/mission-control/docs/playbooks/examples/gitops-k8s-cluster-role-binding.md @@ -69,19 +69,19 @@ spec: ### 1. Triggering playbook manully from a Cluster component -![Playbook option on the component page](../../images/playbook-eg-gitops-playbook-on-cluster-component.png) +![Playbook option on the component page](/img/playbook-eg-gitops-playbook-on-cluster-component.png) _Fig: Playbook option on the component page_ -![Playbook trigger popup on the component](../../images/playbook-eg-self-service-cluster-role-gitops-playbook.png) +![Playbook trigger popup on the component](/img/playbook-eg-self-service-cluster-role-gitops-playbook.png) _Fig: Playbook trigger popup on the component_ ### 2. Created PullRequest on Github -![Created PullRequest on Github](../../images/playbooks-eg-gitops-pr-cluster-role-binding.png) +![Created PullRequest on Github](/img/playbooks-eg-gitops-pr-cluster-role-binding.png) _Fig: Created PullRequest on Github_ ### 3. Playbook action logs -![Playbook action logs](../../images/playbook-eg-gitops-cluster-role-binding-action-logs.png) +![Playbook action logs](/img/playbook-eg-gitops-cluster-role-binding-action-logs.png) _Fig: Playbook action logs_ diff --git a/mission-control/docs/playbooks/examples/kubectl-cluster-role-binding.md b/mission-control/docs/playbooks/examples/kubectl-cluster-role-binding.md index ec8f220b..b33b1a92 100644 --- a/mission-control/docs/playbooks/examples/kubectl-cluster-role-binding.md +++ b/mission-control/docs/playbooks/examples/kubectl-cluster-role-binding.md @@ -20,7 +20,7 @@ spec: kubectl create clusterrolebinding demo-playbook-cluster-role-binding --clusterrole=demo-playbook-clusterrole --serviceaccount=default:demo-playbook-sa kubectl auth can-i get pods --as=system:serviceaccount:default:demo-playbook-sa - name: Cleanup - delay: 5s + delay: 8h exec: script: | kubectl delete clusterrolebinding demo-playbook-cluster-role-binding @@ -30,5 +30,5 @@ spec: ## Screenshots -![Playbook Logs](../../images/playbook-eg-cluster-role-binding.png) +![Playbook Logs](/img/playbook-eg-cluster-role-binding.png) _Fig: Playbook Logs_ diff --git a/mission-control/docs/playbooks/examples/kubectl-logs-artifacts.md b/mission-control/docs/playbooks/examples/kubectl-logs-artifacts.md index b8362d9d..9f69308f 100644 --- a/mission-control/docs/playbooks/examples/kubectl-logs-artifacts.md +++ b/mission-control/docs/playbooks/examples/kubectl-logs-artifacts.md @@ -26,10 +26,10 @@ spec: ### Triggering playbook on the component -![Playbook trigger](../../images/etcd-kind-component-playbook.png) +![Playbook trigger](/img/etcd-kind-component-playbook.png) -![Trigger Playbook](../../images/etcd-component-playbook-trigger-popup.png) +![Trigger Playbook](/img/etcd-component-playbook-trigger-popup.png) ### Playbook action logs -![Playbook action logs](../../images/etcd-component-kubectl-logs.png) +![Playbook action logs](/img/etcd-component-kubectl-logs.png) diff --git a/mission-control/docs/playbooks/overview.md b/mission-control/docs/playbooks/overview.md deleted file mode 100644 index 62525600..00000000 --- a/mission-control/docs/playbooks/overview.md +++ /dev/null @@ -1,5 +0,0 @@ -# Overview - -A Playbook is a configurable automated process that can run one or more actions for a component, check or a config item. It is a streamlined way to orchestrate tasks. The foundation of playbooks lies in YAML files, where you outline the specifications for each playbook. Once defined, these playbooks are executed as runs, encapsulating a series of actions. - -![Playbook overview](../images/playbook-overview.png) diff --git a/mission-control/docs/playbooks/overview.mdx b/mission-control/docs/playbooks/overview.mdx new file mode 100644 index 00000000..a5c0528e --- /dev/null +++ b/mission-control/docs/playbooks/overview.mdx @@ -0,0 +1,141 @@ +--- +slug: /playbooks +title: Playbooks +hide_title: true +# hide_table_of_contents: true +pagination_prev: config-db/overview +pagination_next: topology/overview +--- + +# Playbooks + +Playbooks are configurable automated processes that can be used to perform a variety of actions for a resource like config item, component, & check. +They can also operate independently of any specific resource, providing versatility in handling different tasks and processes within a system or environment + + + + + +## Triggers + + +## Context + + + + + + + + + +```yaml title="restrict-to-deployment.yaml" +#... +kind: Playbook +spec: + # components: ... + # checks: ... + //highlight-next-line + configs: + - types: + - Kubernetes::Deployment +``` + +## Self-Service + + +## Parameters + +Playbooks have 2 types of parameters: + + + +A playbook can be restricted to specific `configs`, `components` or health `checks` using [resource selectors](/reference/resource-selector). For example Restarting a Kubernetes Deployment is only applicable to config items of type: `Kubernetes::Deployment` + +```yaml title="scale-deployment.yaml" +#... +kind: Playbook +spec: + configs: + - types: + - Kubernetes::Deployment + #.... +``` + + + + +Before running a playbook, users can provide input using [`parameters`](/reference/playbooks/parameters) +```yaml title="parameters.yaml" +#... +kind: Playbook +spec: + # user input + parameters: + - name: replicas + # ... +``` + + + +## Events + +## Webhooks + + +## Actions + +Playbooks execute a sequence of actions (steps), these actions can update git repositories, invoke pipelines or run command line tools like `kubectl` and `aws`. + +### Templating + +The actions values can be templated using [Go Templates](/reference/scripting/gotemplate) + +```yaml title="restart-deployment.yaml" +#... +kind: Playbook +spec: + configs: + - types: + - Kubernetes::Deployment + actions: + - name: 'Restart kubernetes deployment' + exec: + //highlight-next-line + script: kubectl rollout restart deployment {{.config.name}} -n {{.config.tags.namespace}} +``` + +The parameters to the playbooks are available in the [Context](reference/playbooks/context) + + +![Playbook Action Logs](/img/playbook-action-logs.png) + + +### Runners + +## Approvals + +Authorization safeguards can be applied to playbook runs, ensuring their execution is limited to specific individuals or teams who grant approval. + +```yaml title="approve-kubernetes-scaling.yaml" +#... +kind: Playbook +spec: + #... + approval: + type: any + approvers: + people: + - admin@local + teams: + - DevOps +``` + +| Field | Description | Scheme | Required | +| ----------- | ------------------------------ | ------------ | -------- | +| `type` | How many approvals required. Defaults to `all` | `any` or `all` | `false` | +| `approvers.[]people` | Login or id of a person| `People` | `false` | +| `approvers.[]teams` | Name or id of a team | `Team` | `false` | + + + diff --git a/mission-control/docs/playbooks/quick-start.md b/mission-control/docs/playbooks/quick-start.mdx similarity index 65% rename from mission-control/docs/playbooks/quick-start.md rename to mission-control/docs/playbooks/quick-start.mdx index 5f72d0a9..267abbb7 100644 --- a/mission-control/docs/playbooks/quick-start.md +++ b/mission-control/docs/playbooks/quick-start.mdx @@ -6,31 +6,26 @@ The only prerequisites are - you have a config item for a Kubernetes Deployment - you have kubectl configured. -## 1. Create the playbook + -```yaml title="scale-deployment.yaml" +```yaml title="restart-deployment.yaml" apiVersion: mission-control.flanksource.com/v1 kind: Playbook metadata: - name: scale-deployment + name: restart-deployment spec: - description: Scale deployment + description: Restart deployment configs: - - type: Kubernetes::Deployment - tags: - namespace: default - cluster: local-kind-cluster - parameters: - - name: replicas - label: The new desired number of replicas. + - types: + - Kubernetes::Deployment actions: - - name: 'scale deployment' + - name: 'Restart kubernetes deployment' exec: - script: kubectl scale --replicas={{.params.replicas}} deployment {{.config.name}} + script: kubectl rollout restart deployment {{.config.name}} -n {{.config.tags.namespace}} ``` -This playbook is designed to run on a Kubernetes Depolyment (with a config type of `Kubernetes::Deployment`). -If you need, you can adjust the tags to your needs. + +This playbook is designed to run on a Kubernetes Deployment (with a config type of `Kubernetes::Deployment`). Save the above YAML to a file called `scale-deployment.yaml`. Then, to store the playbook, run: @@ -38,9 +33,8 @@ Save the above YAML to a file called `scale-deployment.yaml`. Then, to store the kubectl apply -f scale-deployment.yaml ``` -Please check the `playbooks` table in the database to see if the playbook has been created. - -## 2. Run the playbook + + To run the playbook, we need its id. In addition to that please get the id for the deployment config item that you want to scale. @@ -58,7 +52,8 @@ curl -sL -X POST -u 'admin@local:admin' \ The above command scales the deployment of the given config item to just 1 replica. Since the playbook didn't have any approvers defined, the run starts immediately. -## 3. Get the run + + At this stage, the run should have terminated successfully. We can check the status of the run by running: @@ -68,3 +63,4 @@ curl -sL -X GET -u 'admin@local:admin' \ ``` The run id is returned by the API call in the previous step. + diff --git a/mission-control/docs/playbooks/references/connections.md b/mission-control/docs/playbooks/references/connections.md deleted file mode 100644 index a484d69b..00000000 --- a/mission-control/docs/playbooks/references/connections.md +++ /dev/null @@ -1,32 +0,0 @@ -# Connections - - -### AWS Connection - -| Field | Description | Type | Required | -| ---------------- | --------------- | ----------------------------------------------------------------------------- | -------- | -| `connectionName` | Connection name | `string` | | -| `accessKey` | Access key | *EnvVar* | | -| `secretKey` | Secret key | *EnvVar* | | -| `region` | Region | `string` | | -| `endpoint` | Endpoint | `string` | | -| `skipTLSVerify` | Skip TLS verify | `bool` | | -| `objectPath` | Object path | `string` | | -| `usePathStyle` | Use path style | `bool` | | - -### GCP Connection - -| Field | Description | Type | Required | -| ---------------- | --------------- | ----------------------------------------------------------------------------- | -------- | -| `connectionName` | Connection name | `string` | | -| `endpoint` | Endpoint | `string` | | -| `credentials` | Credentials | *EnvVar* | | - -### Azure Connection - -| Field | Description | Type | Required | -| ---------------- | --------------- | ----------------------------------------------------------------------------- | -------- | -| `connectionName` | Connection name | `string` | | -| `clientID` | Client ID | *EnvVar* | | -| `clientSecret` | Client Secret | *EnvVar* | | -| `tenantID` | Tenant ID | `string` | | diff --git a/mission-control/docs/playbooks/references/envvar.md b/mission-control/docs/playbooks/references/envvar.md deleted file mode 100644 index 3c8d09e1..00000000 --- a/mission-control/docs/playbooks/references/envvar.md +++ /dev/null @@ -1,45 +0,0 @@ -# EnvVar - -EnvVar allows you to pull in data from the environment (eg: Kubernetes configmaps or secrets ...) - -| Field | Description | Type | Required | -| ----------- | ------------------------------------------- | ------------------- | -------- | -| `name` | Give an arbitrary unique name to the envvar | `string` | `true` | -| `value` | The value of the envvar | `string` | | -| `valueFrom` | The source of the envvar value | [`Source`](#source) | | - -:::note -You can also provide a static value to the envvar with `value`. -::: - -## Source - -| Field | Description | Type | Required | -| ----------------- | ------------------------------------------------- | ----------------------------------------------- | -------- | -| `serviceAccount` | The service account whose token should be fetched | `string` | | -| `helmRef` | The helm reference | [`HelmRefKeySelector`](#helmrefkeyselector) | | -| `configMapKeyRef` | The configmap reference | [`ConfigMapKeySelector`](#configmapkeyselector) | | -| `secretKeyRef` | The secret reference | [`SecretKeySelector`](#secretkeyselector) | | - -### HelmRefKeySelector - -Helm ref allows you to pull in data from the helm values file. - -| Field | Description | Type | Required | -| ------ | ------------------------ | -------- | -------- | -| `name` | Name of the helm release | `string` | `true` | -| `key` | JSON Path key | `string` | `true` | - -### ConfigMapKeySelector - -| Field | Description | Type | Required | -| ------ | --------------------- | -------- | -------- | -| `name` | ConfigMap name | `string` | `true` | -| `key` | The key in the config | `string` | `true` | - -### SecretKeySelector - -| Field | Description | Type | Required | -| ------ | --------------------- | -------- | -------- | -| `name` | Secret name | `string` | `true` | -| `key` | The key in the Secret | `string` | `true` | diff --git a/mission-control/docs/playbooks/references/playbook.md b/mission-control/docs/playbooks/references/playbook.md deleted file mode 100644 index b817d17e..00000000 --- a/mission-control/docs/playbooks/references/playbook.md +++ /dev/null @@ -1,27 +0,0 @@ -# Playbooks - -## Trigger - -| Field | Description | Scheme | Required | -| ----------- | ---------------------------------------------------- | ---------------------------------------- | -------- | -| `canary` | Setup trigger on canary events | [`EventTrigger`](../concepts/events#event-spec) | | -| `component` | Setup trigger on health check events. | [`EventTrigger`](../concepts/events#event-spec) | | -| `webhook` | Setup a webhook endpoint that triggers the playbook. | [`WebhookTrigger`](../concepts/webhook#spec) | | - -## ResourceFilter - -Filters can define what resources (checks, configs or components) are permitted be run on the Playbook. - -| Field | Description | Scheme | Required | -| ------ | -------------------------- | ------------------- | -------- | -| `type` | Specify type of component. | `string` | | -| `tags` | Specify tags of component. | `map[string]string` | | - -## Parameter - -Playbook parameter defines a parameter that a playbook needs to run. - -| Field | Description | Scheme | Required | -| ------- | --------------------------- | -------- | -------- | -| `name` | Specify name of parameter. | `string` | `true` | -| `label` | Specify label of parameter. | `string` | `true` | \ No newline at end of file diff --git a/mission-control/docs/playbooks/triggers/self-service.md b/mission-control/docs/playbooks/triggers/self-service.md index 217536e9..cc94610f 100644 --- a/mission-control/docs/playbooks/triggers/self-service.md +++ b/mission-control/docs/playbooks/triggers/self-service.md @@ -40,11 +40,11 @@ spec: sleep 10 echo Draining ip-10-0-4-33.eu-west-1.compute.internal echo Terminating ip-10-0-4-33.eu-west-1.compute.internal - + ``` -![Playbook on a config item](../../images/playbook-on-a-eks-cluster-config-item.png) +![Playbook on a config item](/img/playbook-on-a-eks-cluster-config-item.png) **Fig: Playbook on a config item** -![Playbook parameters](../../images/playbook-on-a-eks-cluster-config-item-popup.png) +![Playbook parameters](/img/playbook-on-a-eks-cluster-config-item-popup.png) **Fig: Playbook parameters** diff --git a/mission-control/docs/playbooks/references/check.md b/mission-control/docs/reference/canary-checker/check.md similarity index 100% rename from mission-control/docs/playbooks/references/check.md rename to mission-control/docs/reference/canary-checker/check.md diff --git a/mission-control/docs/reference/config-db/change-result.md b/mission-control/docs/reference/config-db/change-result.md new file mode 100644 index 00000000..a8549d56 --- /dev/null +++ b/mission-control/docs/reference/config-db/change-result.md @@ -0,0 +1,17 @@ +# Change Result + +| Field | Description | Scheme | +| -------------------- | --------------------------------------- | ---------------- | +| `external_id` | ID of the change | `string` | +| `config_type` | Type of the config | `string` | +| `external_change_id` | ID of the change in the external system | `string` | +| `action` | Action of the change | `delete\|ignore` | +| `change_type` | Type of the change | `string` | +| `patches` | Patches of the change | `string` | +| `summary` | Summary of the change | `string` | +| `severity` | Severity of the change | `string` | +| `source` | Source of the change | `string` | +| `created_by` | User who created the change | `string` | +| `created_at` | Creation time of the change | `time.Time` | +| `details` | Details of the change | `map[string]any` | +| `diff` | Diff of the change | `string` | diff --git a/mission-control/docs/playbooks/references/config_item.md b/mission-control/docs/reference/config-db/config-item.md similarity index 100% rename from mission-control/docs/playbooks/references/config_item.md rename to mission-control/docs/reference/config-db/config-item.md diff --git a/mission-control/docs/reference/config-db/scrape-result.md b/mission-control/docs/reference/config-db/scrape-result.md new file mode 100644 index 00000000..392edffc --- /dev/null +++ b/mission-control/docs/reference/config-db/scrape-result.md @@ -0,0 +1,20 @@ +# Scrape Result + +| Field | Description | Scheme | +| -------------- | ------------------------------------------------------ | ------------------ | +| `id` | Designated id (or the external id) of this config item | `string` | +| `config_class` | Class of the config item | `string` | +| `config_type` | Type of the config item | `string` | +| `status` | Status extracted from the config itself | `string` | +| `name` | Name of the config item | `string` | +| `namespace` | Namespace of the config item | `string` | +| `description` | Description of the config item | `string` | +| `aliases` | Aliases associated with the config item | `[]string` | +| `source` | Source of the config item | `string` | +| `config` | Configuration details | `interface{}` | +| `format` | Format of the config item | `string` | +| `icon` | Icon associated with the config item | `string` | +| `tags` | Tags associated with the config item | `JSONStringMap` | +| `analysis` | Analysis result of the config item | `*AnalysisResult` | +| `action` | Action related to the config item | `string` | +| `properties` | Properties associated with the config item | `types.Properties` | diff --git a/mission-control/docs/reference/connection.md b/mission-control/docs/reference/connection.md index 2a760347..afc9e036 100644 --- a/mission-control/docs/reference/connection.md +++ b/mission-control/docs/reference/connection.md @@ -27,7 +27,7 @@ spec: Eventually, the URL that gets templated is used for establishing connections. This can be used for any datasource that authenticates via URL (PostgreSQL, MySQL, MSSQL, Redis, Opensearch, Elasticsearch etc.) -A connection string can be represented in the form of `type/connection_name` or `type/namespace/connection_name` +A connection string can be represented in the form of `type/connection_name` or `type/namespace/connection_name` It can then be used in Health Checks via `connection` attribute or during Topology creation in `component.lookup` diff --git a/mission-control/docs/reference/connections.md b/mission-control/docs/reference/connections.md deleted file mode 120000 index 0383b186..00000000 --- a/mission-control/docs/reference/connections.md +++ /dev/null @@ -1 +0,0 @@ -../../../canary-checker/docs/concepts/connections.md \ No newline at end of file diff --git a/mission-control/docs/reference/connections/aws.mdx b/mission-control/docs/reference/connections/aws.mdx new file mode 100644 index 00000000..a89df3a7 --- /dev/null +++ b/mission-control/docs/reference/connections/aws.mdx @@ -0,0 +1,62 @@ +# AWS + +| Field | Description | Type | Required | +| ------------------------------- | --------------- | -------------------------------------------------------------------------- | -------- | +| `connection` | Mutually exclusive with `accessKey` and `secretKey` | _Connections_ | | +| `accessKey` | Access key | _EnvVar_ | | +| `secretKey` | Secret key | _EnvVar_ | | +| `region` | Region | `string` | | +| `endpoint` | Endpoint | `string` | | +| `skipTLSVerify` | Skip TLS verify | `bool` | | +| `objectPath` | Object path | `string` | | +| `usePathStyle` | Use path style | `bool` | | + + + +There are 3 options when connecting to AWS: + + + +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) + + + +Using a shared Connection +```yaml title="aws-connection.yaml" +apiVersion: canaries.flanksource.com/v1 +kind: Canary +metadata: + name: cloudwatch-check +spec: + interval: 30 + cloudwatch: + - connection: connection://aws/internal + region: us-east-1 # optional if specified in the connection +``` + + + +```yaml title="inline.yaml" +apiVersion: canaries.flanksource.com/v1 +kind: Canary +metadata: + name: cloudwatch-check +spec: + interval: 30 + cloudwatch: + - accessKey: + valueFrom: + secretKeyRef: + name: aws-credentials + key: AWS_ACCESS_KEY_ID + secretKey: + valueFrom: + secretKeyRef: + name: aws-credentials + key: AWS_SECRET_ACCESS_KEY + region: us-east-1 +``` + + + + diff --git a/mission-control/docs/reference/connections/azure.mdx b/mission-control/docs/reference/connections/azure.mdx new file mode 100644 index 00000000..a7fca0f8 --- /dev/null +++ b/mission-control/docs/reference/connections/azure.mdx @@ -0,0 +1,9 @@ +# Azure + +| Field | Description | Type | Required | +| ------------------------------- | ------------- | -------------------------------------------------------------------------- | -------- | +| `connection` | | _Connections_ | | +| `clientID` | Client ID | _EnvVar_ | | +| `clientSecret` | Client Secret | _EnvVar_ | | +| `tenantID` | Tenant ID | `string` | | + diff --git a/mission-control/docs/reference/connections/gcp.mdx b/mission-control/docs/reference/connections/gcp.mdx new file mode 100644 index 00000000..34bea304 --- /dev/null +++ b/mission-control/docs/reference/connections/gcp.mdx @@ -0,0 +1,58 @@ +# GCP + +| Field | Description | Type | Required | +| ------------------------------- | ----------- | -------------------------------------------------------------------------- | -------- | +| `connection` | Mutually exclusive with `credentials`4 | _Connections_ | | +| `endpoint` | Endpoint | `string` | | +| `credentials` | Credentials | _EnvVar_ to service account JSON | | + + + + +There are 3 options when connecting to GCP: + + + +GKE [workload identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) (the default if no `connection` or `credentials` is specified) + + + + +```yaml title="gcs-connection.yaml" +apiVersion: canaries.flanksource.com/v1 +kind: Canary +metadata: + name: database-backup-check +spec: + interval: 60 + folder: + - name: gcs auth test + path: gcs://somegcsbucket + gcpConnection: + connection: connection://gcp/internal +``` + + + + + +```yaml title="gcp-inline.yaml" +apiVersion: canaries.flanksource.com/v1 +kind: Canary +metadata: + name: database-backup-check +spec: + interval: 60 + folder: + - name: gcs auth test + path: gcs://somegcsbucket + gcpConnection: + credentials: + valueFrom: + secretKeyRef: + name: gcp-credentials + key: AUTH_ACCESS_TOKEN +``` + + + diff --git a/mission-control/docs/reference/connections/sftp.mdx b/mission-control/docs/reference/connections/sftp.mdx new file mode 100644 index 00000000..e69de29b diff --git a/mission-control/docs/reference/connections/smb.mdx b/mission-control/docs/reference/connections/smb.mdx new file mode 100644 index 00000000..e69de29b diff --git a/mission-control/docs/reference/secret-management.md b/mission-control/docs/reference/env-var.md similarity index 100% rename from mission-control/docs/reference/secret-management.md rename to mission-control/docs/reference/env-var.md diff --git a/mission-control/docs/reference/playbooks/context.md b/mission-control/docs/reference/playbooks/context.md new file mode 100644 index 00000000..656bf8df --- /dev/null +++ b/mission-control/docs/reference/playbooks/context.md @@ -0,0 +1,44 @@ +# Playbook Context + +The `filter`, `actions`, `if` and `delays` fields that can be templated have a context with the following variables available: + +### Variables + +| Field | Description | Schema | +| ----------- | ---------------------------------------- | -------------------------------------------- | +| `.config` | Config passed to the playbook | [`ConfigItem`](/reference/config-db/config-item) | +| `.component` | Component passed to the playbook | [`Component`](/reference/topology/components) | +| `.check` | Canary Check passed to the playbook | [`Check`](/reference/canary-checker/check) | +| `.params` | User provided parameters to the playbook | `map[string]string` | +| `.env` | Environment variables defined on the playbook | `map[string]string` | +| `.user.name` | Name of the user who invoked the action | `string` | +| `.user.email` | Email of the user who invoked the action | `string` | + +### Functions + +| Function | Description | Return | +| ----------- | ---------------------------------------- | -------------------------------------------- | +|`getLastAction()` | Returns the result of the action that just run | Action Specific | +|`getAction({action})` | Return the result of a specific action |Action Specific | + +## Conditionally running actions + +Playbook actions can be selectively executed based on CEL expressions. These expressions must either return + +- a boolean value (`true` indicating run the action & skip the action otherwise) +- or a special function among the ones listed below + +| Function | Description | +| ----------- | ----------------------------------------------------------- | +| `always()` | run no matter what; even if the playbook is cancelled/fails | +| `failure()` | run if any of the previous actions failed | +| `skip()` | skip running this action | +| `success()` | run only if all previous actions succeeded (default) | +| `timeout()` | run only if any of the previous actions timed out | + +**Examples** + +- `if: config.deleted_at ? true: false` +- `if: always()` + +## Context diff --git a/mission-control/docs/reference/playbooks/parameters.md b/mission-control/docs/reference/playbooks/parameters.md new file mode 100644 index 00000000..74511f91 --- /dev/null +++ b/mission-control/docs/reference/playbooks/parameters.md @@ -0,0 +1,93 @@ + +# Parameters + +Playbook parameter defines a parameter that a playbook needs to run. + +| Field | Description | Scheme | Required | Templatable | +| ------------- | ------------------------------------------------------------------------------------------------- | ------------------- | -------- | ----------- | +| `name` | Name of parameter. | `string` | `true` | +| `default` | Default value of the parameter. | `string` | | `true` | +| `label` | Label of the parameter. | `string` | `true` | +| `required` | Specify if the parameter is required | `bool` | | +| `icon` | Icon of parameter. See [icons](https://github.com/flanksource/flanksource-ui/tree/main/src/icons) | `string` | | +| `description` | Description of the parameter. | `string` | | +| `type` | Type of parameter. _(Defaults to "text")_ | `string` | | +| `properties` | Properties of parameter. _Varies based on the type_ | `map[string]string` | | + +## Defaulting + +Parameter values can be defaulted from the selected resource + +```yaml title="default parameters.yaml" +#... +kind: Playbook +spec: + parameters: + // Use the config items type and name in the parameter + // highlight-next-line + - default: 'chore: update $(.config.type)/$(.config.name)' +``` + +When running the playbook on a `Deployment` named `mysql` the following will be prepopulated: + + + + +## Types + +| name | Description | UI Component | Schema | Properties | +| ----------- | ---------------------------------- | ------------ | --------- | ---------------------------------------------------------- | +| `check` | Limits the value to a check. | Dropdown | `string` | [`Check`](#checks) | +| `checkbox` | Boolean value toggle | Checkbox | `boolean` | - | +| `code` | Text area | Code Editor | `string` | [`Code`](#code) | +| `component` | Limits the value to a component. | Dropdown | `string` | [`Component`](#component) | +| `config` | Limits the value to a config item. | Dropdown | `string` | [`Config`](#config) | +| `list` | Specify a custom list of values | Dropdown | `string` | [`List`](#list) | +| `people` | Limits the value to people. | Dropdown | `string` | [`People`](#people) | +| `team` | Limits the value to teams. | Dropdown | `string` | - | +| `text` | Text input | Text Input | `string` | [`Text`](#text) | + + +### component + +| Field | Description | Schema | +| ------ | -------------------------------------- | -------- | +| `filter.type` | Limit the components to the given type | `string` | + +### config + +| Field | Description | Schema | +| ------ | -------------------------------------- | -------- | +| `filter.type` | Limit the components to the given type | `string` | + +### checks + +| Field | Description | Schema | +| ------ | -------------------------------------- | -------- | +| `filter.type` | Limit the components to the given type | `string` | + +### code + + +| Field | Description | Schema | +| ---------- | ----------------------------------------- | -------- | +| `language` | Langauge name e.g. yaml, json, toml, etc. | `string` | + +### people + +| Field | Description | Schema | +| ------ | ---------------------------------- | ------- | +| `role` | Limit the people to the given role | `string | + +### text + +| Field | Description | Schema | +| ----------- | ------------------------------------------------------- | --------- | +| `multiline` | Whether the text field should be rendered as a text are | `boolean` | + +### list + +| Field | Description | Schema | +| ------- | -------------------------------- | -------- | +| `options[].label` | Specify label of the list option | `string` | +| `options[].value` | Specify value of the list option | `string` | diff --git a/mission-control/docs/reference/playbooks/playbook.md b/mission-control/docs/reference/playbooks/playbook.md new file mode 100644 index 00000000..5d523221 --- /dev/null +++ b/mission-control/docs/reference/playbooks/playbook.md @@ -0,0 +1,69 @@ +# Playbooks + + +| Field | Description | Scheme | Required | +| ------------- | ------------------------------------------------------------ | ---------------------------------------------------- | -------- | +| `description` | A short description | `string` | `true` | +| `icon` | Icon for the playbook | `string` | | +| `on` | Specify events to automatically trigger the Playbook. . | [`[]Trigger`](#trigger) | | +| `runsOn` | Specify the [runners](./runners.md) that can run this playbook. One will be chosen on random. When empty, the playbook will run on the main instance itself | `[]string` | | +| `templatesOn` | Specify where the templating of the action spec should occur | `host` or `agent` | | +| `checks` | Specify selectors for checks that can be run on the Playbook. | [`[]ResourceSelector`](/reference/resource-selector) | | +| `configs` | Specify selectors for config items that can be run on the Playbook. | [`[]ResourceSelector`](/reference/resource-selector) | | +| `components` | Specify selectors for component items that can be run on the Playbook. | [`[]ResourceSelector`](/reference/resource-selector) | | +| `parameters` | Define a set of labeled parameters for the Playbook. | [`[]Parameter`](./parameters) | | +| `actions` | Specify the set of actions to run. | [`[]Action`](#action) | `true` | +| `approval` | Specify who can approve runs on this playbook. | [`Approval`](#approval) | | + + +## Action + +| Field | Description | Scheme | Required | +| -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | -------- | +| `name` | Name of action. | `string` | `true` | +| `runsOn` | Specify the [runners](./runners.md) that can run this action. One will be chosen on random. When empty, the playbook will run on the main instance itself | `[]string` | | +| `templatesOn` | Specify where the templating of the action spec should occur | `host` or `agent` | | +| `delay` | A delay before running the action e.g. `8h` | `Duration` or [`Expression`](../concepts/expression) | | +| `filter` | Whether to run the step or not | [`Expression`](../concepts/expression) | | +| `timeout` | Timeout on this action. | `Duration` | | +| `exec` | Specify exec of action. | [`Exec`](/playbooks/actions/exec.md) | | +| `gitops` | Specify gitops of action. | [`Gitops`](/playbooks/actions/gitops.md) | | +| `http` | Specify http of action. | [`Http`](/playbooks/actions/http.md) | | +| `sql` | Specify sql of action. | [`Sql`](/playbooks/actions/sql.md) | | +| `pod` | Specify pod of action. | [`Pod`](/playbooks/actions/pod.md) | | +| `notification` | Specify notification of action. | [`Notification`](/playbooks/actions/notification.md) | | + + +## Trigger + +| Field | Description | Scheme | Required | +| ----------- | ---------------------------------------------------- | ---------------------------------------- | -------- | +| `canary` | Setup trigger on canary events | [`EventTrigger`](../concepts/events#event-spec) | | +| `component` | Setup trigger on health check events. | [`EventTrigger`](../concepts/events#event-spec) | | +| `webhook` | Setup a webhook endpoint that triggers the playbook. | [`WebhookTrigger`](../concepts/webhook#spec) | | + + +## Approval + +Authorization safeguards can be applied to playbook runs, ensuring their execution is limited to specific individuals or teams who grant approval. + +```yaml title="approve-kubernetes-scaling.yaml" +#... +kind: Playbook +spec: + #... + approval: + type: any + approvers: + people: + - admin@local + teams: + - DevOps +``` + +| Field | Description | Scheme | Required | +| ----------- | ------------------------------ | ------------ | -------- | +| `type` | How many approvals required. Defaults to `all` | `any` or `all` | `false` | +| `approvers.[]people` | Login or id of a person| `People` | `false` | +| `approvers.[]teams` | Name or id of a team | `Team` | `false` | + diff --git a/mission-control/docs/reference/property.md b/mission-control/docs/reference/property.md index 6085c8e1..279d1e77 100644 --- a/mission-control/docs/reference/property.md +++ b/mission-control/docs/reference/property.md @@ -1,23 +1,26 @@ # Property -| Field | Description | Schema | Required | -| ---------------- | ----------------------------------- | -------- | -------- | -| `label` | The label of the property. | `string` | | -| `name` | The name of the property. | `string` | | -| `tooltip` | The tooltip of the property. | `string` | | -| `icon` | The icon of the property. | `string` | | -| `type` | The type of the property. | `string` | | -| `color` | The color of the property. | `string` | | -| `order` | The order of the property. | `int` | | -| `headline` | The headline of the property. | `bool` | | -| `text` | The text of the property. | `string` | | -| `value` | The value of the property. | `int` | | -| `unit` | The unit of the property. | `string` | | -| `max` | The max of the property. | `int` | | -| `min` | The min of the property. | `int` | | -| `status` | The status of the property. | `string` | | -| `lastTransition` | The lastTransition of the property. | `string` | | -| `links` | The links of the property. | `[]Link` | | +| Field | Description | Scheme | Required | +| -------------- | ----------------------------------------------------------------------------- | --------------------------------------- | ---------- | +| `name` | Set name for component property. | `string` | | +| `value` | Mutually exclusive with `text` | `int64` | | +| `text` | Mutually exclusive with `value` | `string` | | +| `type` | Specify type of component property, one of `currency`, `number`, `url` | `string` | | +| `unit` | Unit for component property e.g. milliseconds, bytes, millicores, epoch etc. | `string` | | +| `color` | Set color for component property. | `string` | | +| `headline` | Toggle headline for component property. | `bool` | | +| `icon` | Specify icon for component. | `string` | | +| `label` | Specify label for component property. | `string` | | +| `links` | Set links pertaining to component. | [`[]Link`](#link) | | +| `max` | Set maximum value for components to display. | `int64` | `optional` | +| `min` | Set minimum value for components to display. | `int64` | | +| `order` | Set integer value order for component property. | `int` | | +| `status` | Specify status for component property. | `string` | | +| `tooltip` | Set tooltip outlining information pertaining to the component. | `string` | | +| `configLookup` | Specify lookup for component config. | [`ConfigLookup`](#config-lookup) | `optional` | + + + ## Link @@ -29,3 +32,15 @@ | `icon` | The icon of the link. | `string` | | | `text` | The text of the link. | `string` | | | `label` | The label of the link. | `string` | | + + +## Config Lookup + +| Field | Description | Scheme | Required | +| --------------- | -------------------------------------------------------- | -------------------------------------- | -------- | +| `config.name` | The name of the config item. | `string` | | +| `config.type` | The type of config item. | `string` | | +| `config.labels` | Match labels of the config item, all labels must match | `map[string]string` | | +| `field` | A JSONPath expression to lookup the value in the config. | `string` | `true` | +| `display` | Apply transformations to the value. | [`Display`](../concepts/templating.md) | | +| `id` | The UUID of config item, rarely used | `string` | | diff --git a/mission-control/docs/reference/resource-selector.md b/mission-control/docs/reference/resource-selector.md new file mode 100644 index 00000000..847e2862 --- /dev/null +++ b/mission-control/docs/reference/resource-selector.md @@ -0,0 +1,50 @@ +# ResourceSelector + +Resource Selectors are used in multiple places including: + +* Attaching components to a topology +* 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` | | +| name | Name of the component/config | `string` | | +| namespace | Select resources in this namespace only, if empty find resources in all namespaces | `string` | | +| types | Match any of the types specified | `[]string` | | +| statuses | Match any of the statuses specified | `[]string` | | +| labelSelector | Kubernetes Style Label Selector | [LabelSelector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) | | +| 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/) | | +| agent | Select resources created on this agent, Defaults to `local` | `uuid`, `{name}`, `local` or `all` | | +| cache | Cache settings to use for the results, expensive selectors or selectors that are are use very often should be cached for longer periods. Defaults to `max-age=10m` | `no-cache`, `no-store` or `max-age={duration}` | | + + + +## Examples + +### Selecting components in a topology + +```yaml title="topology-component-selectors.yaml" +kind: Topology +metadata: + name: Example +spec: + components: + - name: Components with healthy status in kube-system namespace of all agents + selectors: + - statuses: ['healthy'] + namespace: kube-system + agent: all + + - name: Components with Node type with spot instance property labelled with gpu tag + selectors: + - types: ['Kubernetes::Node'] + fieldSelector: 'instance-type=spot' + labelSelector: 'sku-type=gpu' + + - name: Components with labels of team payments and team orders + # Using multiple selectors to aggregate + selectors: + - labelSelector: 'team=payments' + - labelSelector: 'team=orders' +``` diff --git a/mission-control/docs/reference/resource_selector.md b/mission-control/docs/reference/resource_selector.md deleted file mode 100644 index 1a8d3335..00000000 --- a/mission-control/docs/reference/resource_selector.md +++ /dev/null @@ -1,44 +0,0 @@ -# ResourceSelector - -We use resource selectors to link components with each other - -| Field | Description | Scheme | Required | -|---------------|----------------------------------------------------------------------------------------------------------------------------------------|----------|----------| -| id | ID of the component | string | | -| name | Name of the component | string | | -| namespace | Namespace of the component | string | | -| types | List of types of the component | []string | | -| statuses | List of statuses of the component | []string | | -| labelSelector | Labels to select the component in kubernetes format | string | | -| fieldSelector | Property fields of the component in kubernetes format (or database columns: owner, topology_id, parent_id) | string | | -| agent | ID or name of the agent (Default: local agent). Use 'all' to select all the agents | string | | -| cache | One of 'no-cache' (should not fetch from cache but can be cached), 'no-store' (should not cache) or 'max-age=X' (cache for X duration) | string | | - - -A resource selector fetches components that satisfy all the parameters, you can use multiple selectors to aggregate - -## Example -```yaml -kind: Topology -metadata: - name: Example -spec: - components: - - name: Components with healthy status in kube-system namespace of all agents - selectors: - - statuses: ['healthy'] - namespace: kube-system - agent: all - - - name: Components with Node type with spot instance property labelled with gpu tag - selectors: - - types: ['Kubernetes::Node'] - fieldSelector: 'instance-type=spot' - labelSelector: 'sku-type=gpu' - - - name: Components with labels of team payments and team orders - # Using multiple selectors to aggregate - selectors: - - labelSelector: 'team=payments' - - labelSelector: 'team=orders' -``` diff --git a/mission-control/docs/reference/types.md b/mission-control/docs/reference/types.md new file mode 100644 index 00000000..4e5dd8f4 --- /dev/null +++ b/mission-control/docs/reference/types.md @@ -0,0 +1,12 @@ +# Common Types + +## Duration + +Valid time units are "s", "m", "h", "d", "w", "y". Eg: + +- `1m15s` +- `1h5m` +- `23h` +- `1d8h` +- `1w6d8h` +- `19w0d8h` diff --git a/mission-control/docs/system-properties.md b/mission-control/docs/system-properties.md new file mode 100644 index 00000000..6057f71c --- /dev/null +++ b/mission-control/docs/system-properties.md @@ -0,0 +1,11 @@ +topology.cache.age +ctx.Properties().Int("check.status.retention.days", 30)*9 + + }, + BatchSize: ctx.Properties().Int("push_queue.batch.size", 50), + ConsumerOption: &postq.ConsumerOption{ + NumConsumers: ctx.Properties().Int("push_queue.consumers", 5), + + component.retention.period = 7d + canary.retention.age + check.retention.age diff --git a/mission-control/docs/topology/concepts/catalog.md b/mission-control/docs/topology/concepts/catalog.md index 40676265..279b9f5b 100644 --- a/mission-control/docs/topology/concepts/catalog.md +++ b/mission-control/docs/topology/concepts/catalog.md @@ -4,7 +4,7 @@ You can link components with configs. The linked config items appears in the com To establish this relationship, you need to specify which config items to link with using the `config` field. -![Component Config relationship](../images/component-config-relationship.png) +![Component Config relationship](/img/component-config-relationship.png) ```yaml title="kubernetes-cluster.yaml" apiVersion: canaries.flanksource.com/v1 diff --git a/mission-control/docs/topology/concepts/health-checks.md b/mission-control/docs/topology/concepts/health-checks.md index c4abd751..b4b62a2e 100644 --- a/mission-control/docs/topology/concepts/health-checks.md +++ b/mission-control/docs/topology/concepts/health-checks.md @@ -12,7 +12,7 @@ Health checks can be associated in 2 ways: | Field | Description | Scheme | Required | | ---------- | -------------------------------- | -------------------------------------------------------------- | -------- | | `inline` | Define a new health check inline | [`CanarySpec`](../../canary-checker/reference/canary-spec.mdx) | | -| `selector` | Select an existing health check | [`[]ResourceSelector`](../../reference/resource_selector) | | +| `selector` | Select an existing health check | [`[]ResourceSelector`](../../reference/resource-selector) | | ### Selector diff --git a/mission-control/docs/topology/concepts/lookup.md b/mission-control/docs/topology/concepts/lookup.md index c6e565c3..8aecadf2 100644 --- a/mission-control/docs/topology/concepts/lookup.md +++ b/mission-control/docs/topology/concepts/lookup.md @@ -87,7 +87,7 @@ spec: | `properties` | Create or lookup properties for each component | [`[]Property`](./properties.md) | | | `configs` | Link configuration items for each component | [`[]ConfigSelector`](./catalog.md#config-selector) | | | `checks` | Create or link health checks for each component | [`[]CheckSelector`](./health-checks.md#check) | | -| `selectors` | Select existing components to be used as the child components. | [`[]ResourceSelector`](../../reference/resource_selector.md) | | +| `selectors` | Select existing components to be used as the child components. | [`[]ResourceSelector`](../../reference/resource-selector.md) | | ## Templating diff --git a/mission-control/docs/topology/concepts/properties.md b/mission-control/docs/topology/concepts/properties.md index d4e47f13..85f24363 100644 --- a/mission-control/docs/topology/concepts/properties.md +++ b/mission-control/docs/topology/concepts/properties.md @@ -23,29 +23,8 @@ properties: text: '447' ``` -![Properties Displayed](../images/properties-in-mission-control.png) +![Properties Displayed](/img/properties-in-mission-control.png) -## Property - -| Field | Description | Scheme | Required | -| -------------- | ----------------------------------------------------------------------------- | --------------------------------------- | ---------- | -| `name` | Set name for component property. | `string` | | -| `value` | Mutually exclusive with `text` | `int64` | | -| `text` | Mutually exclusive with `value` | `string` | | -| `type` | Specify type of component property, one of `currency`, `number`, `url` | `string` | | -| `unit` | Unit for component property e.g. milliseconds, bytes, millicores, epoch etc. | `string` | | -| `color` | Set color for component property. | `string` | | -| `headline` | Toggle headline for component property. | `bool` | | -| `icon` | Specify icon for component. | `string` | | -| `label` | Specify label for component property. | `string` | | -| `links` | Set links pertaining to component. | [`[]Link`](#link) | | -| `max` | Set maximum value for components to display. | `int64` | `optional` | -| `min` | Set minimum value for components to display. | `int64` | | -| `order` | Set integer value order for component property. | `int` | | -| `status` | Specify status for component property. | `string` | | -| `summary` | Set Summary for component property e.g Healthy, Unhealthy, Warning, and Info. | [`Template`](../concepts/templating.md) | `optional` | -| `tooltip` | Set tooltip outlining information pertaining to the component. | `string` | | -| `configLookup` | Specify lookup for component config. | [`ConfigLookup`](#configlookup) | `optional` | ### Configuration Lookup @@ -73,22 +52,3 @@ spec: This `config` object is used to find the config item to lookup a value from, if there are multiple matches, the first match is used. -| Field | Description | Scheme | Required | -| --------------- | -------------------------------------------------------- | -------------------------------------- | -------- | -| `config.name` | The name of the config item. | `string` | | -| `config.type` | The type of config item. | `string` | | -| `config.labels` | Match labels of the config item, all labels must match | `map[string]string` | | -| `field` | A JSONPath expression to lookup the value in the config. | `string` | `true` | -| `display` | Apply transformations to the value. | [`Display`](../concepts/templating.md) | | -| `id` | The UUID of config item, rarely used | `string` | | - -### Link - -| Field | Description | Scheme | Required | -| --------- | ----------------------------------------------------------- | -------- | -------- | -| `icon` | Set icon for link. | `string` | | -| `label` | Set label for link. | `string` | | -| `text` | Set text of choice for link. | `string` | | -| `tooltip` | Set tooltip outlining information pertaining to the link. | `string` | | -| `type` | Specify type of link e.g. documentation, support, playbook. | `string` | | -| `url` | Specify URL for link. | `string` | | diff --git a/mission-control/docs/topology/examples/embedding.md b/mission-control/docs/topology/examples/embedding.md new file mode 100644 index 00000000..84675da4 --- /dev/null +++ b/mission-control/docs/topology/examples/embedding.md @@ -0,0 +1 @@ +# Embedding Cards diff --git a/mission-control/docs/topology/overview.md b/mission-control/docs/topology/overview.md index ee37ae46..4158e150 100644 --- a/mission-control/docs/topology/overview.md +++ b/mission-control/docs/topology/overview.md @@ -1,9 +1,84 @@ +--- +slug: /topology +title: Topology +hide_title: true +# hide_table_of_contents: true + +pagination_next: canary-checker/health-checks +pagination_prev: playbooks/overview +--- + + # Topology -![](../images/topology-overview.svg) +A topology is a represenation of logical system made up of components and sub-components. Many views can be created using the same underlying components based on the way the consumer thinks about the system - e.g. from an Infrastructure or Application focused view. + + + + + + + + + + + +* **Components** +* **Catalog** +* **Health Checks** +* **Properties** +* Metrics + + + +## Components + +### Relationships + + +## Health / RAG Status +:::tip Mini Dashboards + +One way to think about a component is as a mini dashboard that has provides a detailed RAG status that incorporates metrics and configuration from multiple sub-components and/or external systems. + +::: + +![](/img/topology-card.svg) + + + +## Logical Views + +Components can be created to represent any logical view of a system, for example the below represents a FluxCD installation, mapping helm releases to pods and resources that they create. + + + + + + + +## Catalog + +| | Component | Catalog | +| ------------------ | ----------------------------------------------- | ---------------------------------------------- | +| | | | +| Examples | Namespace, Pod, Datacenter | Namespace, Pod, Security Group, postgres.conf | +| Ownership | Yes | No | +| Properties | Custom Properties | Derived from config | +| Health Checks | Yes | Yes | +| Playbooks | Yes | Yes | +| Changes / Insights | None - (Derived from linked catalog item only) | Using change tracking, events and audit trails | +| Cost | Sum of related catalog costs | Based on Cloud Cost & Usage Reports | + + + + + Topology is a way for you to describe the different parts of your infrastructure, like servers, databases, applications, or any other elements that make up your system, in a structured way. It is represented as a tree-like structure where the nodes are called Components. The Components in a Topology can reference each other, which allows you to create a more complex and interconnected topology. This makes it easy to visualize how different parts of your infrastructure are related to each other and how they interact with each other. For example, you can have a database component that is referenced by multiple server components, indicating that these servers are all dependent on the database. Users can provide the Topology structure as a YAML specification, which is a simple way to represent data in a human-readable format. With this specification, users can create a clear and detailed description of their system infrastructure, allowing them to easily manage and maintain their systems. + +## Health diff --git a/mission-control/docs/topology/references/components.md b/mission-control/docs/topology/references/components.md index caea5165..687373e6 100644 --- a/mission-control/docs/topology/references/components.md +++ b/mission-control/docs/topology/references/components.md @@ -19,7 +19,7 @@ Components are the building blocks of a Topology. The component specification pr | `owner` | Specify owner of component | `string` | | | `properties` | Customize component properties as to be visualized on Mission control UI | [`[]Property`](../concepts/properties) | | | `relationships` | Specify relationship of component | [`[]RelationshipSpec`](#relationshipspec) | | -| `selectors` | Specify component for topology based on `fieldSelector` and `labelSelector` | [`[]ResourceSelector`](../../reference/resource_selector) | | +| `selectors` | Specify component for topology based on `fieldSelector` and `labelSelector` | [`[]ResourceSelector`](../../reference/resource-selector) | | | `tooltip` | Set tooltip outlining information pertaining to the component | `string` | | | `type` | Set type of component e.g. service, API, website, library, database, etc. | `string` | | diff --git a/mission-control/docs/topology/references/configdb.md b/mission-control/docs/topology/references/configdb.mdx similarity index 96% rename from mission-control/docs/topology/references/configdb.md rename to mission-control/docs/topology/references/configdb.mdx index c0746605..58621f33 100644 --- a/mission-control/docs/topology/references/configdb.md +++ b/mission-control/docs/topology/references/configdb.mdx @@ -1,8 +1,10 @@ --- -title: Config DB +title: Catalog --- -# Config DB +import { ConfigDb} from "@flanksource/icons/mi"; + +# Catalog ConfigDB component lookup enables you to query configs from the database to use as components. @@ -45,3 +47,5 @@ The `results` variable in the template will contain the following fields | ------- | ----------------------- | ------------------ | | `rows` | stderr from the script | `[]map[string]any` | | `count` | exit code of the script | `int` | + + diff --git a/mission-control/docs/topology/references/exec.md b/mission-control/docs/topology/references/exec.md index e5863de0..99eb33e3 100644 --- a/mission-control/docs/topology/references/exec.md +++ b/mission-control/docs/topology/references/exec.md @@ -4,7 +4,7 @@ title: Exec # Exec -Exec Check executes a command or script file on the target host. The type of scripts executed include: +Run a script and use the results to generate a topology. - Bash scripts - Powershell scripts @@ -51,9 +51,9 @@ spec: | Field | Description | Scheme | Required | | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- | -------- | +| **`script`** | Script can be a inline script or a path to a script that needs to be executed. On windows executed via powershell and in darwin and linux executed using bash. | `Path`, `Bash`or`Powershell` | Yes | | `display` | Template to display server response in text (overrides default bar format for UI) | [_Template_](../concepts/templating.md) | | | `labels` | Labels for the check | Labels | | -| **`script`** | Script can be a inline script or a path to a script that needs to be executed. On windows executed via powershell and in darwin and linux executed using bash. | _string_ | Yes | | `transform` | Template to transform results by excluding or including certain fields in result | [_Template_](../concepts/templating.md) | | ## Results diff --git a/mission-control/docs/topology/references/http.md b/mission-control/docs/topology/references/http.md index 5d0463c1..df89424b 100644 --- a/mission-control/docs/topology/references/http.md +++ b/mission-control/docs/topology/references/http.md @@ -33,14 +33,12 @@ spec: This topology will create a root **"users"** component with all the users returned by the HTTP endpoint as its child components. -![](../images/component-lookup-http.png) +![](/img/component-lookup-http.png) | Field | Description | Scheme | Required | | -------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | -------- | +| **`url`** | HTTP URL, if a URL is specified on both the connection and check, the URL on the check takes precedence. | _string_ | Yes | | **Connection** | | | | -| `connection` | Path of existing connection e.g. `connection://sftp/instance`/ Mutually exclusive with `username`, `password` | _Connections_ | | +| `connection` | Path of existing connection e.g. `connection://http/instance`/ Mutually exclusive with `username`, `password` | _Connections_ | | | `username` | Mutually exclusive with `connection` | [_EnvVar_](../../concepts/authentication/#envvar) | | | `password` | Mutually exclusive with `connection` | [_EnvVar_](../../concepts/authentication/#envvar) | | -| **`url`** | HTTP URL, if a URL is specified on both the connection and check, the URL on the check takes precedence. | _string_ | Yes | -| `ntlm` | When true, will do authentication using NTLM v1 protocol | _bool_ | | -| `ntlmv2` | When true, will do authentication using NTLM v2 protocol | _bool_ | | diff --git a/mission-control/docs/topology/references/mssql.md b/mission-control/docs/topology/references/mssql.md deleted file mode 100644 index 0e6c3430..00000000 --- a/mission-control/docs/topology/references/mssql.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: MSSQL ---- - -# MSSQL - -The MSSQL component lookup allows you to form components from the records in a Postgres database. - -In this example below, we form components from all the tables in the `incident_commander` database. - -```yaml title="mssql-check.yml" -apiVersion: canaries.flanksource.com/v1 -kind: Topology -metadata: - name: mssql-tables - namespace: default -spec: - schedule: '@every 30s' - components: - - name: MSSQL - type: Table - icon: mssql - // highlight-start - lookup: - mssql: - - connection: mssql://sa:yourStrong(!)Password@localhost:1433/incident_commander - query: | - SELECT - s.name AS schema_name, - t.name AS table_name, - p.rows AS num_rows - FROM - sys.tables t - INNER JOIN sys.schemas s ON t.schema_id = s.schema_id - INNER JOIN sys.partitions p ON p.object_id = t.object_id - INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id - WHERE - t.is_ms_shipped = 0 - ORDER BY - p.rows DESC; - display: - expr: | - results.rows.map(row, { - 'name': row.schema_name + '.' + row.table_name, - 'type': "Table", - 'properties': [{ - "name": "Records", - "headline": true, - "value": double(row.num_rows), - }] - }).toJSON() - // highlight-end -``` - -| Field | Description | Scheme | Required | -| ---------------- | -------------------------------------------------------------------------------- | ------------------------------------------------- | -------- | -| `auth` | Username and password value, configMapKeyRef or SecretKeyRef for Postgres server | [_Authentication_](../concepts/authentication.md) | | -| **`connection`** | Connection string to connect to the SQL Server server | _string_ | Yes | -| `display` | Template to display query results in text (overrides default bar format for UI) | [_Template_](../concepts/templating.md) | | -| **`query`** | query that needs to be executed on the server | _string_ | Yes | -| **`results`** | Number rows to check for | _int_ | Yes | - -## Results - -The `results` variable in the template will contain the following fields - -| Field | Description | Scheme | -| ------- | ----------------------- | ------------------ | -| `rows` | stderr from the script | `[]map[string]any` | -| `count` | exit code of the script | `int` | diff --git a/mission-control/docs/topology/references/mysql.md b/mission-control/docs/topology/references/mysql.md deleted file mode 100644 index 2f4ea0e3..00000000 --- a/mission-control/docs/topology/references/mysql.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: MySQL ---- - -# MySQL - -The mysql component lookup allows you to form components from the records in a Postgres database. - -In this example below, we form components from all the tables in the `incident_commander` database. - -```yaml title="mysql-check.yml" -apiVersion: canaries.flanksource.com/v1 -kind: Topology -metadata: - name: mysql-tables - namespace: default -spec: - schedule: '@every 30s' - components: - - name: MySQL - type: Table - icon: mysql - // highlight-start - lookup: - mysql: - - connection: mysql://root:password@localhost:3306/incident_commander - query: | - SELECT - TABLE_SCHEMA AS database_name, - TABLE_NAME AS table_name, - TABLE_ROWS AS num_rows - FROM - information_schema.TABLES - WHERE - TABLE_TYPE = 'BASE TABLE' - ORDER BY - TABLE_ROWS DESC; - display: - expr: | - results.rows.map(row, { - 'name': row.database_name + '.' + row.table_name, - 'type': "Table", - 'properties': [{ - "name": "Records", - "headline": true, - "value": double(row.num_rows), - }] - }).toJSON() - // highlight-end -``` - -| Field | Description | Scheme | Required | -| ---------------- | -------------------------------------------------------------------------------- | ------------------------------------------------- | -------- | -| `auth` | Username and password value, configMapKeyRef or SecretKeyRef for Postgres server | [_Authentication_](../concepts/authentication.md) | | -| **`connection`** | Connection string to connect to the MySQL server | _string_ | Yes | -| `display` | Template to display query results in text (overrides default bar format for UI) | [_Template_](../concepts/templating.md) | | -| **`query`** | query that needs to be executed on the server | _string_ | Yes | -| **`results`** | Number rows to check for | _int_ | Yes | - -## Results - -The `results` variable in the template will contain the following fields - -| Field | Description | Scheme | -| ------- | ----------------------- | ------------------ | -| `rows` | stderr from the script | `[]map[string]any` | -| `count` | exit code of the script | `int` | diff --git a/mission-control/docs/topology/references/postgres.md b/mission-control/docs/topology/references/sql.mdx similarity index 73% rename from mission-control/docs/topology/references/postgres.md rename to mission-control/docs/topology/references/sql.mdx index eab49032..35e1ceda 100644 --- a/mission-control/docs/topology/references/postgres.md +++ b/mission-control/docs/topology/references/sql.mdx @@ -1,8 +1,10 @@ --- -title: Postgres +title: SQL --- -# Postgres +import { AzureSqlServer} from "@flanksource/icons/mi"; + +# SQL The postgres component lookup allows you to form components from the records in a Postgres database. @@ -20,7 +22,6 @@ spec: - name: Postgres type: Table icon: postgres - // highlight-start lookup: postgres: - connection: postgres://postgres:gunners@localhost:5432/incident_commander?sslmode=disable @@ -43,7 +44,6 @@ spec: "value": double(row.num_rows), }] }).toJSON() - // highlight-end ``` | Field | Description | Scheme | Required | @@ -61,3 +61,51 @@ The `results` variable in the template will contain the following fields | ------- | ----------------------- | ------------------ | | `rows` | stderr from the script | `[]map[string]any` | | `count` | exit code of the script | `int` | + +# Connection Types + +## SQL Server + +```yaml title=lookup-mssql.yaml +# ... +kind: Topology +spec: + components: + - lookup: + //highlight-next-line + mssql: + connection: mssql://sa:password@localhost:1433/db + # ... +``` + + +## MySQL + + + +```yaml title=lookup-mssql.yaml +# ... +kind: Topology +spec: + components: + - lookup: + //highlight-next-line + mssql: + connection: mysql://root:password@localhost:3306/db + # ... +``` +## Postgres + + +```yaml title=lookup-postgres.yaml +# ... +kind: Topology +spec: + components: + - lookup: + //highlight-next-line + postgres: + connection: postgres://postgres:gunners@localhost:5432/incident_commander?sslmode=disable + # ... +``` + diff --git a/mission-control/docusaurus.config.js b/mission-control/docusaurus.config.js index 9c6638b9..596005ea 100644 --- a/mission-control/docusaurus.config.js +++ b/mission-control/docusaurus.config.js @@ -11,7 +11,7 @@ const darkCodeTheme = require('prism-react-renderer/themes/dracula') const config = { title: 'Mission Control', tagline: '', - + // staticDirectories: ['images', 'static'], url: 'https://docs.flanksource.com', baseUrl: '/', organizationName: 'flanksource', // Usually your GitHub org/user name. @@ -24,8 +24,8 @@ const config = { oss: false, productName: 'Mission Control', links: { - authentication: '/reference/secret-management', - secrets: '/reference/secret-management', + authentication: '/reference/env-var', + secrets: '/reference/env-var', connection: '/reference/connection', cel: '/reference/scripting/cel', gotemplate: '/reference/scripting/gotemplate', @@ -64,6 +64,7 @@ const config = { ({ docs: { routeBasePath: '/', + sidebarPath: './sidebars.js', // Please change this to your repo. // Remove this to remove the "edit this page" links. @@ -73,6 +74,7 @@ const config = { showReadingTime: true }, theme: { + customCss: './src/css/custom.css' } }) @@ -85,6 +87,7 @@ const config = { // Replace with your project's social card image: 'img/flanksource-icon.png', home: 'docs/index.md', + navbar: { title: '', logo: { @@ -95,40 +98,43 @@ const config = { { to: '/', sidebarId: 'overview', - // activeBasePath: '/', + activeBasePath: 'null', position: 'left', label: 'Overview' }, { - to: 'canary-checker/overview', - label: 'Health Check', - activeBasePath: 'canary-checker', - position: 'left' - }, - { - to: 'config-db/overview', - activeBasePath: 'config-db', + to: 'config-db', + activeBasePath: '/config-db', label: 'Catalog', position: 'left' }, { - to: 'notifications/overview', - activeBasePath: 'notifications', - label: 'Notifications', + to: 'playbooks', + activeBasePath: '/playbooks', + label: 'Playbooks', position: 'left' }, { - to: 'topology/overview', + to: 'topology', activeBasePath: 'topology', label: 'Topology', position: 'left' }, { - to: 'playbooks/overview', - activeBasePath: 'playbooks', - label: 'Playbooks', + to: 'canary-checker/health-checks', + label: 'Health Checks', + activeBasePath: 'canary-checker', position: 'left' }, + + { + to: 'notifications/overview', + activeBasePath: 'notifications', + label: 'Notifications', + position: 'left' + }, + + { to: 'registry/overview', activeBasePath: 'registry', @@ -137,6 +143,7 @@ const config = { }, { to: 'reference/scripting', + activeBasePath: 'reference', label: 'Reference', position: 'left' } diff --git a/mission-control/package-lock.json b/mission-control/package-lock.json index b8c8a82c..d30eff75 100644 --- a/mission-control/package-lock.json +++ b/mission-control/package-lock.json @@ -18,6 +18,7 @@ "@docusaurus/preset-classic": "2.4.1", "@docusaurus/theme-mermaid": "^2.4.1", "@docusaurus/theme-search-algolia": "^2.4.1", + "@flanksource/icons": "^1.0.24", "@mdx-js/react": "^1.6.22", "clsx": "^1.2.1", "file-loader": "6.2.0", @@ -5556,6 +5557,14 @@ "react-waypoint": ">=9.0.2" } }, + "node_modules/@flanksource/icons": { + "version": "1.0.24", + "resolved": "https://registry.npmjs.org/@flanksource/icons/-/icons-1.0.24.tgz", + "integrity": "sha512-c16xVkXp0TMPUnJBP+mEMrzIUjNgrko7svUQhzD2l18jlCwHTO+SBeIy/hEbqF/h3I/Wv9DdxRkcRtODZu3FqA==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -25156,6 +25165,12 @@ "integrity": "sha512-QxMjt/Gvur/gLxSoCy7VIyGGGrGmDN+VHcXkN3R2ApoWX0EYUE+hMgPHSW/PV6VVebZ1Nd4t2UnGRBDihu16JQ==", "requires": {} }, + "@flanksource/icons": { + "version": "1.0.24", + "resolved": "https://registry.npmjs.org/@flanksource/icons/-/icons-1.0.24.tgz", + "integrity": "sha512-c16xVkXp0TMPUnJBP+mEMrzIUjNgrko7svUQhzD2l18jlCwHTO+SBeIy/hEbqF/h3I/Wv9DdxRkcRtODZu3FqA==", + "requires": {} + }, "@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", diff --git a/mission-control/package.json b/mission-control/package.json index 138d480c..810e85ba 100644 --- a/mission-control/package.json +++ b/mission-control/package.json @@ -17,13 +17,14 @@ "@docsearch/react": "3.5.2", "@docusaurus/core": "2.4.1", "@docusaurus/module-type-aliases": "2.4.1", + "@docusaurus/plugin-content-blog": "^2.4.1", "@docusaurus/plugin-google-gtag": "^2.4.3", "@docusaurus/plugin-google-tag-manager": "^2.4.3", "@docusaurus/plugin-ideal-image": "^2.4.1", "@docusaurus/preset-classic": "2.4.1", "@docusaurus/theme-mermaid": "^2.4.1", "@docusaurus/theme-search-algolia": "^2.4.1", - "@docusaurus/plugin-content-blog": "^2.4.1", + "@flanksource/icons": "^1.0.24", "@mdx-js/react": "^1.6.22", "clsx": "^1.2.1", "file-loader": "6.2.0", diff --git a/mission-control/sidebars.js b/mission-control/sidebars.js index 1fc39f16..73c37926 100644 --- a/mission-control/sidebars.js +++ b/mission-control/sidebars.js @@ -20,7 +20,7 @@ const sidebars = { canaryCheckerSidebar: [ { type: 'doc', - id: 'canary-checker/overview', + id: 'canary-checker/health-checks', label: 'Overview' }, { @@ -42,11 +42,7 @@ const sidebars = { id: 'canary-checker/cli', label: 'CLI' }, - { - type: 'doc', - id: 'canary-checker/concepts/image-variants', - label: 'Image Variants' - } + ] }, { @@ -99,106 +95,119 @@ const sidebars = { } ] }, + + { + type: 'html', + value: 'Common Checks', + defaultStyle: true + }, + { + type: 'doc', + id: 'canary-checker/reference/http', + label: 'HTTP' + }, + + + { + type: 'doc', + id: 'canary-checker/reference/prometheus', + label: 'Prometheus' + }, + + { + type: 'doc', + id: 'canary-checker/reference/kubernetes', + label: 'Kubernetes Resources' + }, + + { + type: 'doc', + id: 'canary-checker/reference/pod', + label: 'Pod' + }, + + { + type: 'doc', + id: 'canary-checker/reference/exec', + label: 'Exec' + }, + { + type: 'doc', + id: 'canary-checker/reference/folder', + label: 'Folder' + }, + + { + type: 'doc', + id: 'canary-checker/reference/sql', + label: 'SQL' + }, + + { type: 'category', - label: 'Probes / Alerts', - link: { - type: 'generated-index', - title: 'Probes / Alerts', - // description: 'Learn about the most important Docusaurus concepts!', - slug: '/types', - keywords: ['guides'], - image: '/img/docusaurus.png' - }, + label: 'Other Checks', + className: "condensed", + collapsed: false, items: [ - { - type: 'doc', - id: 'canary-checker/reference/http', - label: 'HTTP' - }, { - type: 'doc', - id: 'canary-checker/reference/tcp', - label: 'TCP' + type: 'html', + value: 'Protocols', + + defaultStyle: true }, + { type: 'doc', id: 'canary-checker/reference/dns', - label: 'DNS' + label: 'DNS', }, { type: 'doc', id: 'canary-checker/reference/icmp', label: 'ICMP' }, - { type: 'doc', - id: 'canary-checker/reference/alert-manager', - label: 'Alert Manager' - }, - { - type: 'doc', - id: 'canary-checker/reference/cloudwatch', - label: 'AWS Cloud Watch' - }, - { - type: 'doc', - id: 'canary-checker/reference/aws-config-rule', - label: 'AWS Config Rule' - } - ] - }, - { - type: 'category', - label: 'Folder / Backups', - items: [ - { - type: 'doc', - id: 'canary-checker/reference/folder', - label: 'Folder' + id: 'canary-checker/reference/tcp', + label: 'TCP' }, + + { type: 'doc', - id: 'canary-checker/reference/gcs-bucket', - label: 'GCS Bucket' + id: 'canary-checker/reference/s3-protocol', + label: 'S3 Protocol' }, + { - type: 'doc', - id: 'canary-checker/reference/s3-bucket', - label: 'S3 Bucket' + type: 'html', + value: 'Alerts', + defaultStyle: true }, + { type: 'doc', - id: 'canary-checker/reference/sftp', - label: 'SFTP' + id: 'canary-checker/reference/alert-manager', + label: 'Alert Manager' }, { type: 'doc', - id: 'canary-checker/reference/smb', - label: 'SMB/CIFS' + id: 'canary-checker/reference/cloudwatch', + label: 'AWS Cloud Watch' }, { type: 'doc', - id: 'canary-checker/reference/gcs-database-backup', - label: 'GCS Database Backup' + id: 'canary-checker/reference/aws-config-rule', + label: 'AWS Config Rule' }, + + { - type: 'doc', - id: 'canary-checker/reference/restic', - label: 'Restic' - } - ] - }, - { - type: 'category', - label: 'Data / Queries', - items: [ - { - type: 'doc', - id: 'canary-checker/reference/prometheus', - label: 'Prometheus' + type: 'html', + value: 'Data Sources', + defaultStyle: true }, { @@ -211,11 +220,7 @@ const sidebars = { id: 'canary-checker/reference/configdb', label: 'Flanksource Config DB' }, - { - type: 'doc', - id: 'canary-checker/reference/kubernetes', - label: 'Kubernetes Resources' - }, + { type: 'doc', id: 'canary-checker/reference/elasticsearch', @@ -231,37 +236,42 @@ const sidebars = { id: 'canary-checker/reference/mongo', label: 'MongoDB' }, + { type: 'doc', - id: 'canary-checker/reference/mssql', - label: 'MSSQL' + id: 'canary-checker/reference/redis', + label: 'Redis' }, + { - type: 'doc', - id: 'canary-checker/reference/mysql', - label: 'MySQL' + type: 'html', + value: 'Infrastructure', + defaultStyle: true }, + { type: 'doc', - id: 'canary-checker/reference/postgres', - label: 'Postgres' + id: 'canary-checker/reference/containerd', + label: 'Containerd/Docker' }, { type: 'doc', - id: 'canary-checker/reference/redis', - label: 'Redis' - } - ] - }, - { - type: 'category', - label: 'Active / Integration', - items: [ + id: 'canary-checker/reference/helm', + label: 'Helm' + }, { type: 'doc', - id: 'canary-checker/reference/exec', - label: 'Exec' + id: 'canary-checker/reference/ec2', + label: 'EC2' }, + + { + type: 'html', + value: 'Integration', + defaultStyle: true + }, + + { type: 'doc', id: 'canary-checker/reference/jmeter', @@ -272,6 +282,13 @@ const sidebars = { id: 'canary-checker/reference/junit', label: 'JUnit' }, + + { + type: 'doc', + id: 'canary-checker/reference/azure-devops', + label: 'Azure DevOps' + }, + { type: 'doc', id: 'canary-checker/reference/k6', @@ -289,39 +306,13 @@ const sidebars = { }, { type: 'doc', - id: 'canary-checker/reference/azure-devops', - label: 'Azure DevOps' - } - ] - }, - { - type: 'category', - label: 'Infrastructure', - items: [ - { - type: 'doc', - id: 'canary-checker/reference/containerd', - label: 'Containerd/Docker' - }, - { - type: 'doc', - id: 'canary-checker/reference/helm', - label: 'Helm' - }, - { - type: 'doc', - id: 'canary-checker/reference/ec2', - label: 'EC2' - }, - { - type: 'doc', - id: 'canary-checker/reference/pod', - label: 'Pod' + id: 'canary-checker/reference/gcs-database-backup', + label: 'GCS Database Backup' }, { type: 'doc', - id: 'canary-checker/reference/s3-protocol', - label: 'S3 Protocol' + id: 'canary-checker/reference/restic', + label: 'Restic' } ] }, @@ -338,8 +329,13 @@ const sidebars = { }, { type: 'category', - label: 'References', + label: 'Reference', items: [ + { + type: 'doc', + id: 'canary-checker/concepts/image-variants', + label: 'Image Variants' + }, { type: 'doc', id: 'canary-checker/reference/canary-spec', @@ -365,29 +361,23 @@ const sidebars = { items: [ { type: 'doc', - id: 'config-db/concepts/changes', - label: 'Changes' + id: 'config-db/concepts/relationship', + label: 'Relationships' }, { type: 'doc', - id: 'config-db/concepts/exclusion', - label: 'Field Exclusion' + id: 'config-db/concepts/changes', + label: 'Changes' }, + { type: 'doc', id: 'config-db/concepts/insights', label: 'Insights' }, - { - type: 'doc', - id: 'config-db/concepts/masking', - label: 'Masking' - }, - { - type: 'doc', - id: 'config-db/concepts/templating', - label: 'Templating' - }, + + + { type: 'doc', id: 'config-db/concepts/transform', @@ -398,17 +388,19 @@ const sidebars = { id: 'config-db/concepts/retention', label: 'Retention' }, - { - type: 'doc', - id: 'config-db/concepts/relationship', - label: 'Relationship' - } + ] }, { type: 'category', label: 'Scrapers', items: [ + { + type: 'doc', + id: 'config-db/concepts/scraping', + label: 'Overview' + }, + { type: 'doc', id: 'config-db/scrapers/aws', @@ -433,26 +425,15 @@ const sidebars = { type: 'doc', id: 'config-db/scrapers/kubernetes', label: 'Kubernetes' - } - ] - }, - { - type: 'category', - label: 'Custom', - items: [ - { - type: 'doc', - id: 'config-db/concepts/custom-scrapers', - label: 'Overview' }, { type: 'category', - label: 'Scrapers', + label: 'Custom', items: [ { type: 'doc', - id: 'config-db/scrapers/custom', - label: 'Custom' + id: 'config-db/concepts/custom-scrapers', + label: 'Overview' }, { type: 'doc', @@ -468,11 +449,11 @@ const sidebars = { type: 'doc', id: 'config-db/scrapers/sql', label: 'SQL' - } - ] - } + }] + }, ] }, + { type: 'category', label: 'Tutorials', @@ -517,11 +498,7 @@ const sidebars = { id: 'playbooks/quick-start', label: 'Quick Start' }, - { - type: 'doc', - id: 'playbooks/api', - label: 'API' - }, + { type: 'category', label: 'Concepts', @@ -539,17 +516,17 @@ const sidebars = { { type: 'doc', id: 'playbooks/concepts/approval', - label: 'Approval' - }, - { - type: 'doc', - id: 'playbooks/concepts/artifacts', - label: 'Artifacts' + label: 'Approvals' }, + // { + // type: 'doc', + // id: 'playbooks/concepts/artifacts', + // label: 'Artifacts' + // }, { type: 'doc', id: 'playbooks/concepts/expression', - label: 'Expression' + label: 'Expressions' }, { type: 'doc', @@ -583,6 +560,11 @@ const sidebars = { type: 'category', label: 'Actions', items: [ + { + type: 'doc', + id: 'playbooks/actions/overview', + label: 'Overview' + }, { type: 'doc', id: 'playbooks/actions/azure_devops_pipeline', @@ -662,7 +644,7 @@ const sidebars = { { type: 'doc', id: 'playbooks/examples/action-filter-action-result', - label: 'Accessing result of previous actions' + label: 'Passing values between steps' }, { type: 'doc', @@ -671,37 +653,7 @@ const sidebars = { } ] }, - { - type: 'category', - label: 'References', - items: [ - { - type: 'doc', - id: 'playbooks/references/connections', - label: 'Connections' - }, - { - type: 'doc', - id: 'playbooks/references/component', - label: 'Component' - }, - { - type: 'doc', - id: 'playbooks/references/check', - label: 'Check' - }, - { - type: 'doc', - id: 'playbooks/references/config_item', - label: 'ConfigItem' - }, - { - type: 'doc', - id: 'playbooks/references/envvar', - label: 'EnvVar' - } - ] - } + ], topologySidebar: [ { @@ -740,108 +692,89 @@ const sidebars = { } ] }, + + { type: 'category', - label: 'Examples', + label: 'Lookups', + link: { + type: 'generated-index', + title: 'Component Lookup', + slug: 'topology/references/lookup' + }, items: [ { type: 'doc', - id: 'topology/examples/prometheus', - label: 'Prometheus' + id: 'topology/references/configdb', + label: 'Catalog' }, { type: 'doc', - id: 'topology/examples/flux', - label: 'Flux' + id: 'topology/references/exec', + label: 'Exec' }, { type: 'doc', - id: 'topology/examples/kubernetes', + id: 'topology/references/http', + label: 'HTTP' + }, + { + type: 'doc', + id: 'topology/references/kubernetes', label: 'Kubernetes' }, + // Mongo lookup cannot query + // { + // type: 'doc', + // id: 'topology/references/mongo', + // label: 'Mongo' + // }, { type: 'doc', - id: 'topology/examples/kubernetes-workload', - label: 'Kubernetes-workload' + id: 'topology/references/sql', + label: 'SQL' + }, + { + type: 'doc', + id: 'topology/references/prometheus', + label: 'Prometheus' } + // Redis component lookup isn't implemeneted. You can't supply a query. + // { + // type: 'doc', + // id: 'topology/references/redis', + // label: 'Redis' + // } ] }, { type: 'category', - label: 'References', + label: 'Examples', items: [ { type: 'doc', - id: 'topology/references/topology', - label: 'Topology' + id: 'topology/examples/embedding', + label: 'Embedding Cards' }, { type: 'doc', - id: 'topology/references/components', - label: 'Components' + id: 'topology/examples/prometheus', + label: 'Prometheus' }, { - type: 'category', - label: 'Component Lookup', - link: { - type: 'generated-index', - title: 'Component Lookup', - slug: 'topology/references/lookup' - }, - items: [ - { - type: 'doc', - id: 'topology/references/configdb', - label: 'Config DB' - }, - { - type: 'doc', - id: 'topology/references/exec', - label: 'Exec' - }, - { - type: 'doc', - id: 'topology/references/http', - label: 'HTTP' - }, - { - type: 'doc', - id: 'topology/references/kubernetes', - label: 'Kubernetes' - }, - // Mongo lookup cannot query - // { - // type: 'doc', - // id: 'topology/references/mongo', - // label: 'Mongo' - // }, - { - type: 'doc', - id: 'topology/references/mssql', - label: 'MS SQL Server' - }, - { - type: 'doc', - id: 'topology/references/mysql', - label: 'MySQL' - }, - { - type: 'doc', - id: 'topology/references/postgres', - label: 'Postgres' - }, - { - type: 'doc', - id: 'topology/references/prometheus', - label: 'Prometheus' - } - // Redis component lookup isn't implemeneted. You can't supply a query. - // { - // type: 'doc', - // id: 'topology/references/redis', - // label: 'Redis' - // } - ] + type: 'doc', + id: 'topology/examples/flux', + label: 'Flux' + }, + { + type: 'doc', + id: 'topology/examples/kubernetes', + label: 'Kubernetes' + }, + { + type: 'doc', + id: 'topology/examples/kubernetes-workload', + label: 'Kubernetes-workload' } ] } @@ -931,23 +864,122 @@ const sidebars = { reference: [ { type: 'doc', - id: 'reference/secret-management', - label: 'Secret Management' + id: 'reference/env-var', + label: 'Env Vars' }, + { - type: 'doc', - id: 'reference/property', - label: 'Property' + type: 'category', + label: 'Connections', + items: [ + { + type: 'doc', + id: 'reference/connection', + label: 'Overview' + }, + { + type: 'doc', + id: 'reference/connections/aws', + label: 'AWS' + }, + { + type: 'doc', + id: 'reference/connections/gcp', + label: 'GCP' + }, + { + type: 'doc', + id: 'reference/connections/azure', + label: 'Azure' + } + ] }, + + + { type: 'doc', - id: 'reference/connection', - label: 'Connection' + id: 'reference/resource-selector', + label: 'Resource Selectors' + }, + + { + type: 'category', + label: 'Catalog', + items: [ + { + type: 'doc', + id: 'reference/config-db/config-item', + label: 'Config Item' + }, + { + type: 'doc', + id: 'config-db/references/scrape-result', + label: 'Scrape Result' + }, + { + type: 'doc', + id: 'config-db/references/change-result', + label: 'Change Result' + } + ] + }, + + { + type: 'category', + label: 'Playbooks', + items: [ + { + type: 'doc', + id: 'reference/playbooks/playbook', + label: 'Playbook' + }, + { + type: 'doc', + id: 'reference/playbooks/parameters', + label: 'Parameters' + }, + { + type: 'doc', + id: 'config-db/references/change-result', + label: 'Events' + }, + + { + type: 'doc', + id: 'reference/playbooks/context', + label: 'Context' + }, + + + ] + }, + + { + type: 'category', + label: 'Topology', + items: [ + { + type: 'doc', + id: 'topology/references/topology', + label: 'Topology' + }, + { + type: 'doc', + id: 'topology/references/components', + label: 'Components' + }, + { + type: 'doc', + id: 'reference/property', + label: 'Properties' + }, + ] }, { type: 'doc', - id: 'reference/connections', - label: 'Authentication' + label: 'Common Types', + id: 'reference/types', }, { type: 'category', @@ -974,11 +1006,6 @@ const sidebars = { label: 'Javascript' } ] - }, - { - type: 'doc', - id: 'reference/resource_selector', - label: 'Resource Selector' } ], overview: [ @@ -1001,11 +1028,7 @@ const sidebars = { label: 'SaaS', id: 'installation/saas' }, - { - type: 'doc', - id: 'installation/monitoring-and-tracing', - label: 'Monitoring & Tracing' - }, + { type: 'category', label: 'Self-Hosted', @@ -1024,7 +1047,17 @@ const sidebars = { type: 'doc', id: 'installation/oidc', label: 'SSO (OIDC)' - } + }, + { + type: 'doc', + id: 'installation/monitoring-and-tracing', + label: 'Monitoring & Tracing' + }, + // { + // type: 'doc', + // id: 'installation/artifacts', + // label: 'Artifacts' + // }, ] }, diff --git a/mission-control/docs/images/architecture.svg b/mission-control/static/img/How it works - card-architecture (1).svg similarity index 100% rename from mission-control/docs/images/architecture.svg rename to mission-control/static/img/How it works - card-architecture (1).svg diff --git a/mission-control/static/img/architecture.svg b/mission-control/static/img/architecture.svg new file mode 100644 index 00000000..ba4742d9 --- /dev/null +++ b/mission-control/static/img/architecture.svg @@ -0,0 +1,3 @@ + + +
Postgres
Postgres
Kratos
(Login + Auth)
On Premise
Kratos...
Canary Checker
(health checks)
Canary Checker...
APM Hub
(logs and metrics)
APM Hub...
Config DB
(JSON config database)
Config DB...
Mission Contol
Mission Contol
UI
UI
PostgREST
(Rest API for the DB)
PostgREST...
Kubernetes
Kubernetes
K8S Operator 
(syncs CRD's to DB)
K8S Operator...
Clerk
(Login + Auth)
SaaS
Clerk...
Prometheus
Prometheus
Text is not SVG - cannot display
\ No newline at end of file diff --git a/mission-control/docs/topology/images/component-config-relationship.png b/mission-control/static/img/component-config-relationship.png similarity index 100% rename from mission-control/docs/topology/images/component-config-relationship.png rename to mission-control/static/img/component-config-relationship.png diff --git a/mission-control/docs/topology/images/component-lookup-http.png b/mission-control/static/img/component-lookup-http.png similarity index 100% rename from mission-control/docs/topology/images/component-lookup-http.png rename to mission-control/static/img/component-lookup-http.png diff --git a/mission-control/static/img/concepts.svg b/mission-control/static/img/concepts.svg new file mode 100644 index 00000000..1a0ab41a --- /dev/null +++ b/mission-control/static/img/concepts.svg @@ -0,0 +1,3 @@ + + +
Catalog
Health Check
Component
Team
owns
Changes
Insights
\ No newline at end of file diff --git a/mission-control/docs/images/config-changes.png b/mission-control/static/img/config-changes.png similarity index 100% rename from mission-control/docs/images/config-changes.png rename to mission-control/static/img/config-changes.png diff --git a/mission-control/static/img/config-db copy.svg b/mission-control/static/img/config-db copy.svg new file mode 100644 index 00000000..6baf8e67 --- /dev/null +++ b/mission-control/static/img/config-db copy.svg @@ -0,0 +1,3 @@ + + +
pull
Security / Insights
Cloud
CI/CD
Scripts / Legacy
image/svg+xml
Changes
Config 
Catalog
mask
Insights
ABCD
link
transform
diff --git a/mission-control/docs/images/config-db.png b/mission-control/static/img/config-db.png similarity index 100% rename from mission-control/docs/images/config-db.png rename to mission-control/static/img/config-db.png diff --git a/mission-control/static/img/config-db.svg b/mission-control/static/img/config-db.svg new file mode 100644 index 00000000..6baf8e67 --- /dev/null +++ b/mission-control/static/img/config-db.svg @@ -0,0 +1,3 @@ + + +
pull
Security / Insights
Cloud
CI/CD
Scripts / Legacy
image/svg+xml
Changes
Config 
Catalog
mask
Insights
ABCD
link
transform
diff --git a/mission-control/docs/images/config-insight-trivy-postgres.png b/mission-control/static/img/config-insight-trivy-postgres.png similarity index 100% rename from mission-control/docs/images/config-insight-trivy-postgres.png rename to mission-control/static/img/config-insight-trivy-postgres.png diff --git a/mission-control/docs/images/config-insights-trivy.png b/mission-control/static/img/config-insights-trivy.png similarity index 100% rename from mission-control/docs/images/config-insights-trivy.png rename to mission-control/static/img/config-insights-trivy.png diff --git a/mission-control/docs/images/config-insights.png b/mission-control/static/img/config-insights.png similarity index 100% rename from mission-control/docs/images/config-insights.png rename to mission-control/static/img/config-insights.png diff --git a/mission-control/docs/images/config-relationships.png b/mission-control/static/img/config-relationships.png similarity index 100% rename from mission-control/docs/images/config-relationships.png rename to mission-control/static/img/config-relationships.png diff --git a/mission-control/docs/images/config.png b/mission-control/static/img/config.png similarity index 100% rename from mission-control/docs/images/config.png rename to mission-control/static/img/config.png diff --git a/mission-control/docs/images/dashboard-http-pass-canary.png b/mission-control/static/img/dashboard-http-pass-canary.png similarity index 100% rename from mission-control/docs/images/dashboard-http-pass-canary.png rename to mission-control/static/img/dashboard-http-pass-canary.png diff --git a/mission-control/docs/images/done-definition-form.png b/mission-control/static/img/done-definition-form.png similarity index 100% rename from mission-control/docs/images/done-definition-form.png rename to mission-control/static/img/done-definition-form.png diff --git a/mission-control/docs/images/etcd-component-kubectl-logs.png b/mission-control/static/img/etcd-component-kubectl-logs.png similarity index 100% rename from mission-control/docs/images/etcd-component-kubectl-logs.png rename to mission-control/static/img/etcd-component-kubectl-logs.png diff --git a/mission-control/docs/images/etcd-component-playbook-trigger-popup.png b/mission-control/static/img/etcd-component-playbook-trigger-popup.png similarity index 100% rename from mission-control/docs/images/etcd-component-playbook-trigger-popup.png rename to mission-control/static/img/etcd-component-playbook-trigger-popup.png diff --git a/mission-control/docs/images/etcd-kind-component-playbook.png b/mission-control/static/img/etcd-kind-component-playbook.png similarity index 100% rename from mission-control/docs/images/etcd-kind-component-playbook.png rename to mission-control/static/img/etcd-kind-component-playbook.png diff --git a/mission-control/docs/images/event-based-config-changes.png b/mission-control/static/img/event-based-config-changes.png similarity index 100% rename from mission-control/docs/images/event-based-config-changes.png rename to mission-control/static/img/event-based-config-changes.png diff --git a/mission-control/docs/images/evidence-component.png b/mission-control/static/img/evidence-component.png similarity index 100% rename from mission-control/docs/images/evidence-component.png rename to mission-control/static/img/evidence-component.png diff --git a/mission-control/docs/images/evidence-config-analysis.png b/mission-control/static/img/evidence-config-analysis.png similarity index 100% rename from mission-control/docs/images/evidence-config-analysis.png rename to mission-control/static/img/evidence-config-analysis.png diff --git a/mission-control/docs/images/evidence-config-change.png b/mission-control/static/img/evidence-config-change.png similarity index 100% rename from mission-control/docs/images/evidence-config-change.png rename to mission-control/static/img/evidence-config-change.png diff --git a/mission-control/docs/images/evidence-config.png b/mission-control/static/img/evidence-config.png similarity index 100% rename from mission-control/docs/images/evidence-config.png rename to mission-control/static/img/evidence-config.png diff --git a/mission-control/docs/images/evidence-health-check.png b/mission-control/static/img/evidence-health-check.png similarity index 100% rename from mission-control/docs/images/evidence-health-check.png rename to mission-control/static/img/evidence-health-check.png diff --git a/mission-control/docs/images/evidence-logs.png b/mission-control/static/img/evidence-logs.png similarity index 100% rename from mission-control/docs/images/evidence-logs.png rename to mission-control/static/img/evidence-logs.png diff --git a/mission-control/docs/images/example-config-items-vms.png b/mission-control/static/img/example-config-items-vms.png similarity index 100% rename from mission-control/docs/images/example-config-items-vms.png rename to mission-control/static/img/example-config-items-vms.png diff --git a/mission-control/docs/images/example-currency-scraper-changes.png b/mission-control/static/img/example-currency-scraper-changes.png similarity index 100% rename from mission-control/docs/images/example-currency-scraper-changes.png rename to mission-control/static/img/example-currency-scraper-changes.png diff --git a/mission-control/docs/images/example-currency-scraper-config.png b/mission-control/static/img/example-currency-scraper-config.png similarity index 100% rename from mission-control/docs/images/example-currency-scraper-config.png rename to mission-control/static/img/example-currency-scraper-config.png diff --git a/mission-control/docs/images/example-currency-scraper-diff-change.png b/mission-control/static/img/example-currency-scraper-diff-change.png similarity index 100% rename from mission-control/docs/images/example-currency-scraper-diff-change.png rename to mission-control/static/img/example-currency-scraper-diff-change.png diff --git a/mission-control/docs/images/example-vm-scraper-api-server-change.png b/mission-control/static/img/example-vm-scraper-api-server-change.png similarity index 100% rename from mission-control/docs/images/example-vm-scraper-api-server-change.png rename to mission-control/static/img/example-vm-scraper-api-server-change.png diff --git a/mission-control/docs/images/flanksource-icon-white.svg b/mission-control/static/img/flanksource-icon-white.svg similarity index 100% rename from mission-control/docs/images/flanksource-icon-white.svg rename to mission-control/static/img/flanksource-icon-white.svg diff --git a/mission-control/docs/images/flanksource-white.svg b/mission-control/static/img/flanksource-white.svg similarity index 100% rename from mission-control/docs/images/flanksource-white.svg rename to mission-control/static/img/flanksource-white.svg diff --git a/mission-control/docs/images/flanksource.png b/mission-control/static/img/flanksource.png similarity index 100% rename from mission-control/docs/images/flanksource.png rename to mission-control/static/img/flanksource.png diff --git a/mission-control/docs/images/flanksource.svg b/mission-control/static/img/flanksource.svg similarity index 100% rename from mission-control/docs/images/flanksource.svg rename to mission-control/static/img/flanksource.svg diff --git a/mission-control/static/img/flux-healthy.png b/mission-control/static/img/flux-healthy.png new file mode 100644 index 00000000..2ee9705a Binary files /dev/null and b/mission-control/static/img/flux-healthy.png differ diff --git a/mission-control/static/img/flux-topology.svg b/mission-control/static/img/flux-topology.svg new file mode 100644 index 00000000..1db206b7 --- /dev/null +++ b/mission-control/static/img/flux-topology.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/mission-control/static/img/flux.png b/mission-control/static/img/flux.png new file mode 100644 index 00000000..a3ea711f Binary files /dev/null and b/mission-control/static/img/flux.png differ diff --git a/mission-control/static/img/getting-started.mdx b/mission-control/static/img/getting-started.mdx new file mode 100644 index 00000000..739bc21f --- /dev/null +++ b/mission-control/static/img/getting-started.mdx @@ -0,0 +1,89 @@ + +# Getting Started + + + + ```bash + helm repo add flanksource https://flanksource.github.io/charts + helm repo update + helm install canary-checker flanksource/canary-checker -n "canary-checker" --create-namespace + ``` + + + + + ```yaml title="canary.yaml" + apiVersion: canaries.flanksource.com/v1 + kind: Canary + metadata: + name: http-check + spec: + interval: 30 + http: + - name: basic-check + url: https://httpbin.demo.aws.flanksource.com/status/200 + - name: failing-check + url: https://httpbin.demo.aws.flanksource.com/status/500 + ``` + +And then apply it to the cluster: + + ```shell + kubectl apply -f canary.yaml + ``` + +:::info + You can also run the check locally to see its output by using the [cli](./cli) + + ```bash + canary-checker run canary.yaml + ``` + + +::: + + + + + ```shell + kubectl get canary + ``` + + + + + + +You can access the web dashboard by forwarding the port: + +```bash +kubectl -n canary-checker port-forward svc/canary-checker-ui 8080:80 +``` + +![](/img/http-checks.png) + +[http://localhost:8080](http://localhost:8080) + +The canary checker itself only presents an API. To view the data graphically, the Flanksource UI is required, and is installed by default. The UI should be configured in [values.yaml](https://github.com/flanksource/canary-checker/blob/699f31a2326034f761ba1b30d966436d6318dd06/chart/values.yaml#L105) to allow external access via ingress + +| Parameter | Description | +|------------------------------------|---------------------------------------------------------------| +| `flanksource-ui.ingress.host` | URL at which the UI will be accessed | +| `flanksource-ui.ingress.annotations` | Map of annotations required by the ingress controller or certificate issuer | +| `flanksource-ui.ingress.tls` | Map of configuration options for TLS | + +More details regarding ingress configuration can be found in the [kubernetes documentation](https://kubernetes.io/docs/concepts/services-networking/ingress/) + + + +## Getting Help + +If you have any questions about canary checker: + +* Invite yourself to the [CNCF community slack](https://slack.cncf.io/) and join the [#canary-checker](https://cloud-native.slack.com/messages/canary-checker/) channel. +* Check out the [Youtube Playlist](https://www.youtube.com/playlist?list=PLz4F_KggvA58D6krlw433TNr8qMbu1aIU). +* File an [issue](https://github.com/flanksource/canary-checker/issues/new) - (We do provide user support via Github Issues, so don't worry if your issue a real bug or not) +* [Flanksource](https://www.flanksource.com) provides both commercial support for canary checker and a SaaS offering called Mission Control. + +Your feedback is always welcome! + diff --git a/mission-control/static/img/health-check-snippet.png b/mission-control/static/img/health-check-snippet.png new file mode 100644 index 00000000..4fdef21e Binary files /dev/null and b/mission-control/static/img/health-check-snippet.png differ diff --git a/mission-control/docs/images/health-checks.png b/mission-control/static/img/health-checks.png similarity index 100% rename from mission-control/docs/images/health-checks.png rename to mission-control/static/img/health-checks.png diff --git a/mission-control/docs/images/how-it-works.svg b/mission-control/static/img/how-it-works.svg similarity index 100% rename from mission-control/docs/images/how-it-works.svg rename to mission-control/static/img/how-it-works.svg diff --git a/mission-control/docs/images/hypothesis-comment.png b/mission-control/static/img/hypothesis-comment.png similarity index 100% rename from mission-control/docs/images/hypothesis-comment.png rename to mission-control/static/img/hypothesis-comment.png diff --git a/mission-control/docs/images/hypothesis-status.png b/mission-control/static/img/hypothesis-status.png similarity index 100% rename from mission-control/docs/images/hypothesis-status.png rename to mission-control/static/img/hypothesis-status.png diff --git a/mission-control/docs/images/incidents.png b/mission-control/static/img/incidents.png similarity index 100% rename from mission-control/docs/images/incidents.png rename to mission-control/static/img/incidents.png diff --git a/mission-control/docs/images/logging.svg b/mission-control/static/img/logging.svg similarity index 100% rename from mission-control/docs/images/logging.svg rename to mission-control/static/img/logging.svg diff --git a/mission-control/static/img/logo.svg b/mission-control/static/img/logo.svg deleted file mode 100644 index 9db6d0d0..00000000 --- a/mission-control/static/img/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/mission-control/static/img/parameter-defaulting.png b/mission-control/static/img/parameter-defaulting.png new file mode 100644 index 00000000..3a03ea3b Binary files /dev/null and b/mission-control/static/img/parameter-defaulting.png differ diff --git a/mission-control/docs/images/playbook-action-logs.png b/mission-control/static/img/playbook-action-logs.png similarity index 100% rename from mission-control/docs/images/playbook-action-logs.png rename to mission-control/static/img/playbook-action-logs.png diff --git a/mission-control/docs/images/playbook-eg-cluster-role-binding.png b/mission-control/static/img/playbook-eg-cluster-role-binding.png similarity index 100% rename from mission-control/docs/images/playbook-eg-cluster-role-binding.png rename to mission-control/static/img/playbook-eg-cluster-role-binding.png diff --git a/mission-control/docs/images/playbook-eg-gitops-cluster-role-binding-action-logs.png b/mission-control/static/img/playbook-eg-gitops-cluster-role-binding-action-logs.png similarity index 100% rename from mission-control/docs/images/playbook-eg-gitops-cluster-role-binding-action-logs.png rename to mission-control/static/img/playbook-eg-gitops-cluster-role-binding-action-logs.png diff --git a/mission-control/docs/images/playbook-eg-gitops-playbook-on-cluster-component.png b/mission-control/static/img/playbook-eg-gitops-playbook-on-cluster-component.png similarity index 100% rename from mission-control/docs/images/playbook-eg-gitops-playbook-on-cluster-component.png rename to mission-control/static/img/playbook-eg-gitops-playbook-on-cluster-component.png diff --git a/mission-control/docs/images/playbook-eg-self-service-cluster-role-gitops-playbook.png b/mission-control/static/img/playbook-eg-self-service-cluster-role-gitops-playbook.png similarity index 100% rename from mission-control/docs/images/playbook-eg-self-service-cluster-role-gitops-playbook.png rename to mission-control/static/img/playbook-eg-self-service-cluster-role-gitops-playbook.png diff --git a/mission-control/docs/images/playbook-on-a-eks-cluster-config-item-popup.png b/mission-control/static/img/playbook-on-a-eks-cluster-config-item-popup.png similarity index 100% rename from mission-control/docs/images/playbook-on-a-eks-cluster-config-item-popup.png rename to mission-control/static/img/playbook-on-a-eks-cluster-config-item-popup.png diff --git a/mission-control/docs/images/playbook-on-a-eks-cluster-config-item.png b/mission-control/static/img/playbook-on-a-eks-cluster-config-item.png similarity index 100% rename from mission-control/docs/images/playbook-on-a-eks-cluster-config-item.png rename to mission-control/static/img/playbook-on-a-eks-cluster-config-item.png diff --git a/mission-control/docs/images/playbook-overview.png b/mission-control/static/img/playbook-overview.png similarity index 100% rename from mission-control/docs/images/playbook-overview.png rename to mission-control/static/img/playbook-overview.png diff --git a/mission-control/docs/images/playbook-runs.png b/mission-control/static/img/playbook-runs.png similarity index 100% rename from mission-control/docs/images/playbook-runs.png rename to mission-control/static/img/playbook-runs.png diff --git a/mission-control/docs/images/playbooks-eg-gitops-pr-cluster-role-binding.png b/mission-control/static/img/playbooks-eg-gitops-pr-cluster-role-binding.png similarity index 100% rename from mission-control/docs/images/playbooks-eg-gitops-pr-cluster-role-binding.png rename to mission-control/static/img/playbooks-eg-gitops-pr-cluster-role-binding.png diff --git a/mission-control/docs/images/playbooks-list.png b/mission-control/static/img/playbooks-list.png similarity index 100% rename from mission-control/docs/images/playbooks-list.png rename to mission-control/static/img/playbooks-list.png diff --git a/mission-control/static/img/playbooks.svg b/mission-control/static/img/playbooks.svg new file mode 100644 index 00000000..4edebb1f --- /dev/null +++ b/mission-control/static/img/playbooks.svg @@ -0,0 +1,3 @@ + + +
Playbooks
Self-Service
Webhooks
GitOps
Webhooks
CI Runners
Scripts
Events
\ No newline at end of file diff --git a/mission-control/docs/topology/images/properties-in-mission-control.png b/mission-control/static/img/properties-in-mission-control.png similarity index 100% rename from mission-control/docs/topology/images/properties-in-mission-control.png rename to mission-control/static/img/properties-in-mission-control.png diff --git a/mission-control/docs/images/responder-add-jira.png b/mission-control/static/img/responder-add-jira.png similarity index 100% rename from mission-control/docs/images/responder-add-jira.png rename to mission-control/static/img/responder-add-jira.png diff --git a/mission-control/docs/images/responder-jira-comments.png b/mission-control/static/img/responder-jira-comments.png similarity index 100% rename from mission-control/docs/images/responder-jira-comments.png rename to mission-control/static/img/responder-jira-comments.png diff --git a/mission-control/docs/images/slack-app-creation.png b/mission-control/static/img/slack-app-creation.png similarity index 100% rename from mission-control/docs/images/slack-app-creation.png rename to mission-control/static/img/slack-app-creation.png diff --git a/mission-control/docs/images/slack-app-install-to-workspace.png b/mission-control/static/img/slack-app-install-to-workspace.png similarity index 100% rename from mission-control/docs/images/slack-app-install-to-workspace.png rename to mission-control/static/img/slack-app-install-to-workspace.png diff --git a/mission-control/docs/images/slack-app-oauth-scope.png b/mission-control/static/img/slack-app-oauth-scope.png similarity index 100% rename from mission-control/docs/images/slack-app-oauth-scope.png rename to mission-control/static/img/slack-app-oauth-scope.png diff --git a/mission-control/docs/images/slack-bot-user-oauth-token.png b/mission-control/static/img/slack-bot-user-oauth-token.png similarity index 100% rename from mission-control/docs/images/slack-bot-user-oauth-token.png rename to mission-control/static/img/slack-bot-user-oauth-token.png diff --git a/mission-control/static/img/topology-card.svg b/mission-control/static/img/topology-card.svg new file mode 100644 index 00000000..d7a6ae9c --- /dev/null +++ b/mission-control/static/img/topology-card.svg @@ -0,0 +1,3 @@ + + +
RAG Status
RAG Status
Aggregated Metrics
Aggregated Metrics
Sub Components
Sub Components
Status / Count
Status / Count
Properties
Properties
\ No newline at end of file diff --git a/mission-control/static/img/topology-node.png b/mission-control/static/img/topology-node.png new file mode 100644 index 00000000..1d6d5e15 Binary files /dev/null and b/mission-control/static/img/topology-node.png differ diff --git a/mission-control/docs/images/topology-overview.svg b/mission-control/static/img/topology-overview.svg similarity index 100% rename from mission-control/docs/images/topology-overview.svg rename to mission-control/static/img/topology-overview.svg diff --git a/mission-control/static/img/topology.svg b/mission-control/static/img/topology.svg new file mode 100644 index 00000000..4098e768 --- /dev/null +++ b/mission-control/static/img/topology.svg @@ -0,0 +1,3 @@ + + +
Catalog
Catalog
Health Check
Health Check
Component
Component
Changes
Changes
Insights
Insights
Metrics
Metrics
Scripts
Scripts
Catalog
Catalog
\ No newline at end of file diff --git a/mission-control/docs/images/tutorial-config-scrapers.png b/mission-control/static/img/tutorial-config-scrapers.png similarity index 100% rename from mission-control/docs/images/tutorial-config-scrapers.png rename to mission-control/static/img/tutorial-config-scrapers.png diff --git a/mission-control/docs/images/tutorial-vm-scraper-creation-date.png b/mission-control/static/img/tutorial-vm-scraper-creation-date.png similarity index 100% rename from mission-control/docs/images/tutorial-vm-scraper-creation-date.png rename to mission-control/static/img/tutorial-vm-scraper-creation-date.png diff --git a/mission-control/docs/images/ui01.png b/mission-control/static/img/ui01.png similarity index 100% rename from mission-control/docs/images/ui01.png rename to mission-control/static/img/ui01.png