diff --git a/CONVENTIONS.md b/CONVENTIONS.md
index 0cab7346..841a3e2e 100644
--- a/CONVENTIONS.md
+++ b/CONVENTIONS.md
@@ -1,20 +1,28 @@
+
+
1. Use an active, present tense voice
-2. Do not use any salesy or marketing terms, Do not use adverbs
-3. Use MDX formatting
-4. Do not use the first person, Use "you" or "your team"
-5. Do not use archaic language
-6. Do not use oxymorons
-7. Precede every command with an explanation of what the command does. After the command, provide additional details about the command, such as what the arguments do and why your reader is using them.
-8. Avoid pop culture references, gender assumptions, holidays, hemisphere seasons, and other exclusionary language
-9. Do not tell people how they feel
-10. Explicitly tell the user to create or open each file you’ll have them use.
-11. Like commands, always introduce a file or script by describing its general purpose, then explain any changes that the reader will be making in the file. Without these explanations, readers won’t be able to customize, update, or troubleshoot issues in the long run.
-12. If you’re asking the reader to write code, follow the same approach for commands: introduce the code block with a high-level explanation of what it does. Then show the code, and then call out any important details.
-13. Avoid adverbs and complex language
-14. Use markdown codeblocks with a language and a title
-15. Do not remove any "```" or "//highlight-next-line" text
-16. Do not use the term "this document", when referring to the system or product being documented always use "Mission Control"
-17. For examples using the following structure:
+2. When referring to concepts or resources do not use the term "they", use the name of the concept or resource instead
+3. Do not use any salesy or marketing terms, Do not use adverbs.
+4. Prefer simple language over complex language, target Grade 10 reading level.
+5. Parse the text as Markdown mixed with JSX blocks i.e. MDX
+6. Avoid using more than 1 list in a paragraph or section.
+7. Never remove or reformat JSX or code blocks\
+8. Do not use the first person, Use "you" or "your team"
+9. Do not use archaic language
+10. Do not use oxymorons
+11. Do not refer to "the system" use "Mission Control" instead
+12. Precede every command with an explanation of what the command does. After the command, provide additional details about the command, such as what the arguments do and why your reader is using them.
+13. Avoid pop culture references, gender assumptions, holidays, hemisphere seasons, and other exclusionary language
+14. Do not tell people how they feel
+15. Explicitly tell the user to create or open each file you’ll have them use.
+16. Always introduce a file or script by describing its general purpose, then explain any changes that the reader will be making in the file. Without these explanations, readers won’t be able to customize, update, or troubleshoot issues in the long run.
+17. If you’re asking the reader to write code. introduce the code block with a high-level explanation of what it does. Then show the code, and then call out any important details.
+18. Avoid adverbs and complex language
+19. Use markdown codeblocks with a language and a title
+20. Do not remove any "```" or "//highlight-next-line" text
+21. Follow standard markdown rules provided by markdownlint
+22. Do not use the term "this document", when referring to the system or product being documented always use "Mission Control"
+23. For examples using the following structure:
Introduction of example
Example Code
This example:
diff --git a/canary-checker/docs/comparisons/index.md b/canary-checker/docs/comparisons/index.md
index 7bca3805..0db49073 100644
--- a/canary-checker/docs/comparisons/index.md
+++ b/canary-checker/docs/comparisons/index.md
@@ -1,6 +1,6 @@
---
title: Comparisons
-sidebar_position: 3
+sidebar_position: 4
sidebar_custom_props:
- icon: material-symbols-light:text-compare-outline
+ icon: compare
---
diff --git a/canary-checker/docs/concepts/concepts.md b/canary-checker/docs/concepts/concepts.md
new file mode 100644
index 00000000..e7fb8087
--- /dev/null
+++ b/canary-checker/docs/concepts/concepts.md
@@ -0,0 +1,11 @@
+---
+title: Concepts
+hide_sidebar: true
+sidebar_position: 2
+sidebar_custom_props:
+ icon: concepts
+---
+
+import DocCardList from '@theme/DocCardList';
+
+
diff --git a/canary-checker/docs/concepts/expressions/_transform_fields.mdx b/canary-checker/docs/concepts/expressions/_transform_fields.mdx
index 867af3d0..51de13bf 100644
--- a/canary-checker/docs/concepts/expressions/_transform_fields.mdx
+++ b/canary-checker/docs/concepts/expressions/_transform_fields.mdx
@@ -102,9 +102,11 @@
{
field: "metrics",
description: "Add custom metrics to be exported",
- scheme: "[[]Metric](../metrics/custom-metrics#metric)",
+ scheme: "[]Metric",
required: false
},
+
+
{
field: "icon",
description: null,
diff --git a/canary-checker/docs/concepts/expressions/index.md b/canary-checker/docs/concepts/expressions/index.md
index 0994a3a7..b2a9281d 100644
--- a/canary-checker/docs/concepts/expressions/index.md
+++ b/canary-checker/docs/concepts/expressions/index.md
@@ -1,7 +1,7 @@
---
title: Expressions
sidebar_custom_props:
- icon: variable
+ icon: code
---
canary-checker can be extended using expressions in 3 ways:
diff --git a/canary-checker/docs/concepts/image-variants.md b/canary-checker/docs/concepts/image-variants.md
new file mode 100644
index 00000000..fd0d045e
--- /dev/null
+++ b/canary-checker/docs/concepts/image-variants.md
@@ -0,0 +1,50 @@
+---
+title: Image Variants
+sidebar_custom_props:
+ icon: docker
+---
+
+Canary checker comes with 3 image variants:
+
+## [Slim](https://github.com/flanksource/canary-checker/blob/master/build/slim/Dockerfile)
+
+- [arkade](https://github.com/alexellis/arkade)
+- jq
+- yq
+- python3
+
+## [Minimal](https://github.com/flanksource/canary-checker/blob/master/build/minimal/Dockerfile)
+
+- [arkade](https://github.com/alexellis/arkade)
+- kubectl
+- [stern](https://github.com/stern/stern)
+- [fblog](https://github.com/brocode/fblog)
+- jq
+- yq
+- [sops](https://github.com//mozilla/sops)
+- PowerShell 7
+ - powershell-yaml
+- python3
+- [azure-cli](https://learn.microsoft.com/en-us/cli/azure/)
+- [gcloud-cli](https://cloud.google.com/sdk/gcloud)
+ - kubectl-oidc
+ - gke-gcloud-auth-plugin
+- [aws-cli](https://aws.amazon.com/cli/)
+
+## [Full](https://github.com/flanksource/canary-checker/blob/master/build/full/Dockerfile)
+
+Everything in the minimal image plus:
+
+- [k6](https://github.com/grafana/k6)
+- OpenJDK Temurin 21
+- [JMeter](https://jmeter.apache.org/)
+- [Robot Framework](https://robotframework.org/)
+- [benthos](https://benthos.dev)
+- [dsq](https://github.com/multiprocessio/dsq)
+- [restic](https://restic.net/)
+
+You can choose which variant to use in the helm chart using:
+
+```bash
+helm install flanksource/canary-checker --set image.type=full
+```
diff --git a/canary-checker/docs/concepts/index.md b/canary-checker/docs/concepts/index.md
deleted file mode 100644
index b297838c..00000000
--- a/canary-checker/docs/concepts/index.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Concepts
-sidebar_position: 1
-sidebar_custom_props:
- icon: concepts
----
diff --git a/canary-checker/docs/concepts/metrics.mdx b/canary-checker/docs/concepts/metrics.mdx
new file mode 100644
index 00000000..5d5f2be1
--- /dev/null
+++ b/canary-checker/docs/concepts/metrics.mdx
@@ -0,0 +1,117 @@
+---
+title: Metrics
+sidebar_custom_props:
+ icon: dashboard-line
+---
+
+
+Canary Checker works well with Prometheus and exports metrics for every check, the standard metrics included are:
+
+| Metric | Type | Description |
+| ---------------------------------------------- | --------- | ------------------------------------------- |
+| canary_check | Gauge | Set to 0 when passing and 1 when failing |
+| canary_check_success_count | Counter | |
+| canary_check_failed_count | Counter | |
+| canary_check_info | Info | |
+| canary_check_duration | Histogram | Histogram of canary durations |
+
+Some checks like [pod](../../reference/pod) and [http](../../reference/http) expose additional metrics.
+
+
+## Custom Metrics
+
+Canary checker can export custom metrics from any check type, replacing and/or consolidating multiple standalone Prometheus Exporters into a single exporter.
+
+In the example below, exchange rates against USD are exported by first calling an HTTP api and then using the values from the JSON response to create the metrics:
+
+```yaml title="exchange-rates-exporter.yaml" file=/modules/canary-checker/fixtures/minimal/metrics-multiple.yaml
+
+```
+
+Which would output:
+
+```shell
+exchange_rate{from=USD, to=GBP} 0.819
+exchange_rate{from=USD, to=EUR} 0.949
+exchange_rate{from=USD, to=ILS} 3.849
+exchange_rate_api 260.000
+```
+
+### Fields
+
+| Field | Description | Scheme | Required |
+| -------- | ------------------------------------------------------ | ----------------- | -------- |
+| `metrics[].name` | Name of the metric | `string` | Yes |
+| `metrics[].value` | An expression to derive the metric value from | CEL with [Check Context](#check-context) that returns `float` | Yes |
+| `metrics[].type` | Prometheus Metric Type | `counter`, `guage`, `histogram` | Yes |
+| `metrics[].labels[].name` | Name of the label | `string` | Yes |
+| `metrics[].labels[].value` | A static value for the label value | `float` | |
+| `metrics[].labels[].valueExpr` | An expression to derive the label value from | CEL with [Check Context](#check-context) | |
+| `metrics[].labels[].labels` | Labels for prometheus metric (values can be templated) | `map[string]string` | |
+
+Expressions can make use of the following variables:
+
+### Check Context
+
+| Fields | Description | Scheme |
+| ------------------------- | ------------------------------------------ | ----------------------------------------- |
+| `*` | All fields from the check result | See result variables section of the check |
+| **`last_result.results`** | The last result | |
+| `check.name` | Check name | `string` |
+| `check.description` | Check description | `string` |
+| `check.labels` | Dynamic labels attached to the check | `map[string]string` |
+| `check.endpoint` | Endpoint (usually a URL) | `string` |
+| `check.duration` | Duration in milliseconds | `int64` |
+| `canary.name` | Canary name | `string` |
+| `canary.namespace` | Canary namespace | `string` |
+| `canary.labels` | Labels attached to the canary CRD (if any) | `map[string]string` |
+
+
+## Prometheus Operator
+
+The helm chart can install a `ServiceMonitor` for the prometheus operator, by enabling the serviceMonitor flag
+
+```
+--set serviceMonitor=true
+```
+
+## Grafana
+
+
+Default grafana dashboards are available. After you deploy Grafana, these dashboards can be installed with
+
+```
+--set grafanaDashboards=true --set serviceMonitor=true
+```
+
+
+
+
+## Stateful Metrics
+
+
+Metrics can be generated from time based data, e.g. logs per minute, logins per second by using the output of one check execution as the input to the next.
+
+```yaml file=/modules/canary-checker/fixtures/elasticsearch/stateful_metrics.yaml
+
+```
+
+This snippet retrieves the `last_result.results.max` value from the last execution ensuring data is not duplicated or missed
+
+```go
+"@timestamp" : {
+ {{- if last_result.results.max }}
+ "gte": "{{ last_result.results.max }}"
+ {{- else }}
+ "gte": "now-5m"
+ {{- end }}
+}
+```
+
+The max value is saved in the `transform` section using:
+
+```yaml
+#...
+'detail': { 'max': string(json.?aggregations.logs.age.value_as_string.orValue(last_result().?results.max.orValue(time.Now()))) },
+#...
+```
diff --git a/canary-checker/docs/concepts/metrics/custom-metrics.md b/canary-checker/docs/concepts/metrics/custom-metrics.md
deleted file mode 100644
index bfb8ad64..00000000
--- a/canary-checker/docs/concepts/metrics/custom-metrics.md
+++ /dev/null
@@ -1,61 +0,0 @@
----
-title: Custom Metrics
----
-
-Canary checker can export custom metrics from any check type, replacing and/or consolidating multiple standalone Prometheus Exporters into a single exporter.
-
-In the example below, exchange rates against the USD are exported by first calling an HTTP api and then using the values from the JSON response to create the metrics:
-
-```yaml title="exchange-rates-exporter.yaml" file=/modules/canary-checker/fixtures/minimal/metrics-multiple.yaml
-
-```
-
-Which would output:
-
-```shell
-exchange_rate{from=USD, to=GBP} 0.819
-exchange_rate{from=USD, to=EUR} 0.949
-exchange_rate{from=USD, to=ILS} 3.849
-exchange_rate_api 260.000
-```
-
-## Result Variables
-
-| Field | Description | Scheme | Required |
-| --------- | ------------------------------------ | ----------------- | -------- |
-| `metrics` | Metrics to export from check results | [Metric](#metric) | |
-
-### Metric
-
-| Field | Description | Scheme | Required |
-| -------- | ------------------------------------------------------ | ----------------- | -------- |
-| `name` | Name of the metric | `string` | Yes |
-| `value` | An expression to derive the metric value from | `Expression` | Yes |
-| `type` | Prometheus Metric Type (counter, gauge or histogram) | `string` | Yes |
-| `labels` | Labels for prometheus metric (values can be templated) | [[]Label](#label) | |
-
-### Label
-
-| Field | Description | Scheme | Required |
-| ----------- | ------------------------------------------------------ | ------------------- | -------- |
-| `name` | Name of the label | `string` | Yes |
-| `value` | A static value for the header | `string` | |
-| `valueExpr` | An expression to derive the header value from | `Expression` | |
-| `labels` | Labels for prometheus metric (values can be templated) | `map[string]string` | |
-
-Expressions can make use of the following variables:
-
-### **Expression Variables**
-
-| Fields | Description | Scheme |
-| ------------------------- | ------------------------------------------ | ----------------------------------------- |
-| **`result`** | Check Result | See result variables section of the check |
-| **`last_result.results`** | The last result | |
-| `check.name` | Check name | `string` |
-| `check.description` | Check description | `string` |
-| `check.labels` | Dynamic labels attached to the check | `map[string]string` |
-| `check.endpoint` | Endpoint (usually a URL) | `string` |
-| `check.duration` | Duration in milliseconds | `int64` |
-| `canary.name` | Canary name | `string` |
-| `canary.namespace` | Canary namespace | `string` |
-| `canary.labels` | Labels attached to the canary CRD (if any) | `map[string]string` |
diff --git a/canary-checker/docs/concepts/metrics/grafana.md b/canary-checker/docs/concepts/metrics/grafana.md
deleted file mode 100644
index 7e36d8c3..00000000
--- a/canary-checker/docs/concepts/metrics/grafana.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-title: Grafana
----
-
-Default grafana dashboards are available. After you deploy Grafana, these dashboards can be installed with
-
-```
---set grafanaDashboards=true --set serviceMonitor=true
-```
-
-
diff --git a/canary-checker/docs/concepts/metrics/index.mdx b/canary-checker/docs/concepts/metrics/index.mdx
deleted file mode 100644
index fa969b53..00000000
--- a/canary-checker/docs/concepts/metrics/index.mdx
+++ /dev/null
@@ -1,30 +0,0 @@
----
-title: Metrics
-sidebar_custom_props:
- icon: clarity:dashboard-line
----
-
-Default Metrics exposed by canary-checker:
-
-| Metric | Type | Description |
-| ---------------------------------------------- | --------- | ------------------------------------------- |
-| canary_check | Gauge | Set to 0 when passing and 1 when failing |
-| canary_check_success_count | Counter | |
-| canary_check_failed_count | Counter | |
-| canary_check_info | Info | |
-| canary_check_duration | Histogram | Histogram of canary durations |
-
-Some checks like [pod](../../reference/pod) and [http](../../reference/http) expose additional metrics.
-
-:::tip
-Custom metrics can be exported from any check, see [custom-metrics](./custom-metrics)
-:::
-
-
-## Prometheus Operator
-
-The helm chart can install a `ServiceMonitor` for the prometheus operator, by enabling the serviceMonitor flag
-
-```
---set serviceMonitor=true
-```
diff --git a/canary-checker/docs/concepts/metrics/stateful-metrics.md b/canary-checker/docs/concepts/metrics/stateful-metrics.md
deleted file mode 100644
index 2118b51a..00000000
--- a/canary-checker/docs/concepts/metrics/stateful-metrics.md
+++ /dev/null
@@ -1,29 +0,0 @@
----
-title: Stateful Metrics
----
-
-Metrics can be generated from time based data, e.g. logs per minute, logins per second by using the output of one check execution as the input to the next.
-
-```yaml file=/modules/canary-checker/fixtures/elasticsearch/stateful_metrics.yaml
-
-```
-
-This snippet retrieves the `last_result.results.max` value from the last execution ensuring data is not duplicated or missed
-
-```go
-"@timestamp" : {
- {{- if last_result.results.max }}
- "gte": "{{ last_result.results.max }}"
- {{- else }}
- "gte": "now-5m"
- {{- end }}
-}
-```
-
-The max value is saved in the `transform` section using:
-
-```yaml
-#...
-'detail': { 'max': string(json.?aggregations.logs.age.value_as_string.orValue(last_result().?results.max.orValue(time.Now()))) },
-#...
-```
diff --git a/canary-checker/docs/concepts/secret-management.md b/canary-checker/docs/concepts/secret-management.md
index 971cf477..8b2c8812 100644
--- a/canary-checker/docs/concepts/secret-management.md
+++ b/canary-checker/docs/concepts/secret-management.md
@@ -1,7 +1,7 @@
---
title: Env Vars
sidebar_custom_props:
- icon: stash:search-box-light
+ icon: shield-lock
sidebar_position: 1
---
diff --git a/canary-checker/docs/examples/index.md b/canary-checker/docs/examples/index.md
deleted file mode 100644
index 0db2ed21..00000000
--- a/canary-checker/docs/examples/index.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: Examples
-sidebar_position: 2
-sidebar_custom_props:
- icon: stash:graduation-cap-light
----
diff --git a/canary-checker/docs/examples/index.mdx b/canary-checker/docs/examples/index.mdx
new file mode 100644
index 00000000..1d5f201b
--- /dev/null
+++ b/canary-checker/docs/examples/index.mdx
@@ -0,0 +1,11 @@
+---
+title: Examples
+sidebar_position: 3
+hide_sidebar: true
+sidebar_custom_props:
+ icon: learning
+
+---
+import DocCardList from '@theme/DocCardList';
+
+
diff --git a/canary-checker/docs/examples/k6.mdx b/canary-checker/docs/examples/k6.mdx
index 13f50c24..851e6a2c 100644
--- a/canary-checker/docs/examples/k6.mdx
+++ b/canary-checker/docs/examples/k6.mdx
@@ -91,4 +91,4 @@ For a complete working example, see **[canary-checker-examples/k6](https://githu
## Test Result Variables
-See [JUnit Test Results](/guide/canary-checker/reference/junit#test-result-variables) for the schema that is ingested and can be used for evaluating health or formatting the display.
+See [JUnit Test Results](../reference/junit#test-result-variables) for the schema that is ingested and can be used for evaluating health or formatting the display.
diff --git a/canary-checker/docs/examples/newman.mdx b/canary-checker/docs/examples/newman.mdx
index 3d050384..2bc310bc 100644
--- a/canary-checker/docs/examples/newman.mdx
+++ b/canary-checker/docs/examples/newman.mdx
@@ -60,4 +60,4 @@ For a complete working example, see **[canary-checker-examples/newman](https://g
## Test Result Variables
-See [JUnit Test Results](/guide/canary-checker/reference/junit#test-result-variables) for the schema that is ingested and can be used for evaluating health or formatting the display.
+See [JUnit Test Results](../reference/junit#test-result-variables) for the schema that is ingested and can be used for evaluating health or formatting the display.
diff --git a/canary-checker/docs/examples/playwright.mdx b/canary-checker/docs/examples/playwright.mdx
index 75dc84fd..1c85d601 100644
--- a/canary-checker/docs/examples/playwright.mdx
+++ b/canary-checker/docs/examples/playwright.mdx
@@ -57,4 +57,4 @@ For a complete working example, see **[canary-checker-examples/playwright](https
## Test Result Variables
-See [JUnit Test Results](/guide/canary-checker/reference/junit#test-result-variables) for the schema that is ingested and can be used for evaluating health or formatting the display.
+See [JUnit Test Results](../reference/junit#test-result-variables) for the schema that is ingested and can be used for evaluating health or formatting the display.
diff --git a/canary-checker/docs/examples/sftp.mdx b/canary-checker/docs/examples/sftp.mdx
index 79fc2e73..a3a02af5 100644
--- a/canary-checker/docs/examples/sftp.mdx
+++ b/canary-checker/docs/examples/sftp.mdx
@@ -41,7 +41,7 @@ spec:
| **`name`** | Name of the check | *string* | Yes |
| **`path`** | A path to the remote folder | string | Yes |
| **`sftpConnection`** | SFTP connection details | [SFTPConnection](#sftp-connection) | Yes |
-| `*` | All other fields available in the folder check | [*Folder*](/guide/canary-checker/reference/folder) | |
+| `*` | All other fields available in the folder check | [*Folder*](../reference/folder) | |
## SFTP Connection
diff --git a/canary-checker/docs/examples/smb.mdx b/canary-checker/docs/examples/smb.mdx
index 8aba10f0..39cca6d5 100644
--- a/canary-checker/docs/examples/smb.mdx
+++ b/canary-checker/docs/examples/smb.mdx
@@ -39,9 +39,10 @@ spec:
| **`name`** | Name of the check | _string_ | Yes |
| **`path`** | A path to a shared windows folder e.g. `smb://host/folder` | string | Yes |
| `smbConnection` | SMB connection details | [SMB](#smb) | |
-| `*` | All other fields available in the folder check | [_Folder_](/guide/canary-checker/reference/folder) | |
+| `*` | All other fields available in the folder check | [_Folder_](../reference/folder) | |
+## SMB
diff --git a/canary-checker/docs/getting-started.canary.mdx b/canary-checker/docs/getting-started.canary.mdx
index 3c337fab..72a20fbf 100644
--- a/canary-checker/docs/getting-started.canary.mdx
+++ b/canary-checker/docs/getting-started.canary.mdx
@@ -3,6 +3,7 @@ title: Getting Started
sidebar_position: 1
sidebar_custom_props:
icon: getting-started
+slug: /getting-started
---
import { HiOutlineExternalLink } from "react-icons/hi";
@@ -11,9 +12,9 @@ import { HiOutlineExternalLink } from "react-icons/hi";
1. Install canary checker using helm
-
+
2. Create a new check
@@ -29,7 +30,7 @@ import { HiOutlineExternalLink } from "react-icons/hi";
```
- You can also run the check locally to see its output by using the [cli](./cli)
+ You can also run the check locally to see its output by using the [cli](./installation/cli)
```bash
canary-checker run canary.yaml
diff --git a/canary-checker/docs/health-checks.canary.mdx b/canary-checker/docs/health-checks.canary.mdx
index b4898384..56e05f72 100644
--- a/canary-checker/docs/health-checks.canary.mdx
+++ b/canary-checker/docs/health-checks.canary.mdx
@@ -1,7 +1,10 @@
---
slug: /overview
-title: Health Checks
+sidebar_position: 0
+title: Overview
id: health-checks
+sidebar_custom_props:
+ icon: canary-checker
---
@@ -45,7 +48,8 @@ The health checks page provides a high-level view of the overall health of all s
## Prometheus
-[Prometheus](canary-checker/concepts/metrics) metrics are exposed from health checks to provide high-level visibility into latency, error rates, and other metrics. This allows monitoring the health of services and applications using existing Prometheus alerts and [Grafana](canary-checker/concepts/metrics/grafana) dashboards.
+Prometheus metrics are exposed from health checks to provide high-level visibility into latency, error rates, and other metrics. This allows monitoring the health of services and applications using existing Prometheus alerts and
+Grafana dashboards.
## Synthetic
diff --git a/canary-checker/docs/index.mdx b/canary-checker/docs/index.mdx
index c05773e8..67c87714 100644
--- a/canary-checker/docs/index.mdx
+++ b/canary-checker/docs/index.mdx
@@ -47,7 +47,7 @@ Health checks can be associated with components in a [topology](topology/concept
### Prometheus
-[Prometheus](canary-checker/concepts/metrics) metrics are exposed from health checks to provide high level visibility into latency, error rates and other metrics. This allows monitoring the health of services and applications using existing Prometheus alerts and [Grafana](canary-checker/concepts/metrics/grafana) dashboards.
+[Prometheus](/concepts/metrics) metrics are exposed from health checks to provide high level visibility into latency, error rates and other metrics. This allows monitoring the health of services and applications using existing Prometheus alerts and Grafana dashboards.
### Synthetic
diff --git a/canary-checker/docs/helm.canary.md b/canary-checker/docs/installation/1-helm.canary.md
similarity index 83%
rename from canary-checker/docs/helm.canary.md
rename to canary-checker/docs/installation/1-helm.canary.md
index 33146764..a6b8c56d 100644
--- a/canary-checker/docs/helm.canary.md
+++ b/canary-checker/docs/installation/1-helm.canary.md
@@ -2,7 +2,9 @@
title: Helm
description: Recommended method for installing canary-checker
sidebar_class_name: hidden-mission-control
-slug: /guide/canary-checker/helm
+slug: /installation/helm
+sidebar_custom_props:
+ icon: helm
---
import Schema from '@site/modules/canary-checker/chart/values.schema.json'
@@ -22,7 +24,7 @@ The recommended method for installing Canary Checker is using [helm](https://hel
/>
:::info
- Note the default installation of canary-checker uses an embedded postgres database and does not persist history, see: [Database](database)
+ Note the default installation of canary-checker uses an embedded postgres database and does not persist history, see: [Database](/installation/database)
:::
1. Create a canary
@@ -41,14 +43,14 @@ The recommended method for installing Canary Checker is using [helm](https://hel
EOF
```
-
+
1. Check the results via the [CLI](./cli)
-
-NAME INTERVAL STATUS LAST CHECK UPTIME 1H LATENCY 1H LAST TRANSITIONED
-http-check 30 Passed 13s 18/18 (100.0%) 480ms 13s
-
+
+ NAME INTERVAL STATUS LAST CHECK UPTIME 1H LATENCY 1H LAST TRANSITIONED
+ http-check 30 Passed 13s 18/18 (100.0%) 480ms 13s
+
1. Access the dashboard
diff --git a/canary-checker/docs/concepts/cli.mdx b/canary-checker/docs/installation/cli.mdx
similarity index 100%
rename from canary-checker/docs/concepts/cli.mdx
rename to canary-checker/docs/installation/cli.mdx
diff --git a/canary-checker/docs/database.canary.md b/canary-checker/docs/installation/database.canary.md
similarity index 96%
rename from canary-checker/docs/database.canary.md
rename to canary-checker/docs/installation/database.canary.md
index eac6d9ee..c322e2f8 100644
--- a/canary-checker/docs/database.canary.md
+++ b/canary-checker/docs/installation/database.canary.md
@@ -1,6 +1,9 @@
---
description: Alternative methods for connecting to the db used for persistence
sidebar_class_name: hidden-mission-control
+slug: /installation/database
+sidebar_custom_props:
+ icon: postgres
---
# Database
diff --git a/canary-checker/docs/installation/index.md b/canary-checker/docs/installation/index.md
new file mode 100644
index 00000000..7a855a9a
--- /dev/null
+++ b/canary-checker/docs/installation/index.md
@@ -0,0 +1,10 @@
+---
+title: Installation
+sidebar_position: 2
+sidebar_custom_props:
+ icon: package-install
+---
+
+import DocCardList from '@theme/DocCardList';
+
+
diff --git a/canary-checker/docs/partials/_domain.mdx b/canary-checker/docs/partials/_domain.mdx
index ea95b278..4c8aeaa4 100644
--- a/canary-checker/docs/partials/_domain.mdx
+++ b/canary-checker/docs/partials/_domain.mdx
@@ -1,4 +1,4 @@
Choose a routable `DOMAIN` for Mission Control
- > See [Ingress](/reference/helm/mission-control#ingress) for more options on configuring the ingress including generating certs with cert-manager
- >
See [Local Testing](../local-testing) for testing using a kind or minikube without a routable domain
+ > See [Ingress](/installation/self-hosted/ingress) for more options on configuring the ingress including generating certs with cert-manager
+ >
See [Local Testing](/installation/local-testing) for testing using a kind or minikube without a routable domain
diff --git a/canary-checker/docs/partials/_gotemplate.md b/canary-checker/docs/partials/_gotemplate.md
index dd93358f..e4a4ec5a 100644
--- a/canary-checker/docs/partials/_gotemplate.md
+++ b/canary-checker/docs/partials/_gotemplate.md
@@ -20,13 +20,13 @@ If you need to pass a template through a Helm Chart and prevent Helm from templa
{{`{{ .secret }}`}}
```
-Alternatively [change the templating delimiters](#changing-templating-delimiters)
+Alternatively [change the templating delimiters](#delimiters)
-If you are using a YAML multiline string use `|` and not `>` which will strip newlines
+If you are using a YAML multiline string use `|` and not `>` which strips newlines.
Instead of:
diff --git a/canary-checker/docs/reference/1-alert-manager.mdx b/canary-checker/docs/reference/1-alert-manager.mdx
index dc715bee..4fbf0752 100644
--- a/canary-checker/docs/reference/1-alert-manager.mdx
+++ b/canary-checker/docs/reference/1-alert-manager.mdx
@@ -1,12 +1,16 @@
---
title: Alertmanager
hide_title: true
+hide_toc: true
sidebar_position: 0
sidebar_custom_props:
icon: prometheus
---
+
+
+
# Alertmanager
Checks [Prometheus AlertManager](https://prometheus.io/docs/alerting/latest/alertmanager/) for any firing alerts.
diff --git a/canary-checker/docs/reference/1-catalog.mdx b/canary-checker/docs/reference/1-catalog.mdx
index 5e2e05c7..f6e46062 100644
--- a/canary-checker/docs/reference/1-catalog.mdx
+++ b/canary-checker/docs/reference/1-catalog.mdx
@@ -13,12 +13,40 @@ Runs a [config-db](https://github.com/flanksource/config-db) query.
```yaml title="catalog.yaml" file=/modules/canary-checker/fixtures/external/catalog.yaml
```
-
+
+## Resource Selectors
+
+
+| Field | Description | Scheme | Required |
+| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------- | -------- |
+| `id` | ID of the component | `string` | No |
+| `name` | Name of the component/config | `string` | No |
+| `namespace` | Select resources in this namespace only, if empty find resources in all namespaces | `string` | No |
+| `types` | Match any of the types specified | `[]string` | No |
+| `statuses` | Match any of the statuses specified | `[]string` | No |
+| `labelSelector` | Kubernetes Style Label Selector | [LabelSelector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) | No |
+| `fieldSelector` | Kubernetes Style Field Selector Property fields of the component in kubernetes format (or database columns: owner, topology_id, parent_id) | [FieldSelector](https://kubernetes.io/docs/concepts/overview/working-with-objects/field-selectors/) | No |
+| `agent` | Select resources created on this agent, Defaults to `local` | `uuid`, `{name}`, `local` or `all` | No |
+| `cache` | Cache settings to use for the results, expensive selectors or selectors that are used often should be cached for longer periods. Defaults to `max-age=10m` | `no-cache`, `no-store` or `max-age={duration}` | No |
+| `search` | Search for resources via key value pairs using parsing expression grammar | [Search](#search) | No |
+
+## Search
+
+The query syntax is `field1=value1 field2>value2 field3=value3* field4=*value4`. `*` is for prefix and suffix matching.
+
+Supported operators:
+
+| Operator | Syntax | Types |
+| -------- | -------------------------------- | --------------------- |
+| `=` | `field=value` | `string` `int` `json` |
+| `!=` | `field!=value` | `string` `int` `json` |
+| `*` | `field=*value` or `field=value*` | `string` `int` |
+| `>` `<` | `field>value` or `fieldImage Variants for a list of installed applications
:::
```yaml title="exec.yaml" file=/modules/canary-checker/fixtures/minimal/exec_pass.yaml
@@ -48,6 +48,20 @@ See [image-variants](/reference/canary-checker/image-variants)
]}/>
+## Shell Language
+
+Use a shebang (`#!`) line to choose a different shell (`python`, `bash` and `pwsh` are included in the base image)
+
+```yaml
+exec:
+ script: |
+ //highlight-next-line
+ #! pwsh
+ Get-Items | ConvertTo-JSON
+```
+
+
+
```yaml title="exec_artifact.yaml" file=/modules/canary-checker/fixtures/minimal/exec_env_pass.yaml
diff --git a/canary-checker/docs/reference/1-folder.mdx b/canary-checker/docs/reference/1-folder.mdx
index 9d4f2372..798388cb 100644
--- a/canary-checker/docs/reference/1-folder.mdx
+++ b/canary-checker/docs/reference/1-folder.mdx
@@ -26,9 +26,34 @@ Checks the contents of a folder for size, age, and count. Folder based checks ar
},
{ field: 'sftpConnection',description: "Connection details", scheme: "[SFTP](#sftp)" },
{ field: "gcpConnection", description: "Connection details for GCP", scheme: "[GCP](#gcp)" },
-{field: "awsConnection", description: "AWS Access credentials", scheme: "[AWS](#aws)" },
+{field: "awsConnection", description: "AWS Access credentials", scheme: "[S3](#s3)" },
{field: "smbConnection", description: "SMB connection details", scheme: "[SMB](#smb)"},
- {field: "filter", description: "Filter objects out before checking if they are valid", scheme: "[FolderFilter](#folderfilter)"},
+ {
+ field: "filter.maxAge",
+ description: "MaxAge the latest object should be younger than defined age",
+ scheme: "Duration"
+ },
+ {
+ field: "filter.maxSize",
+ description: "MaxSize of the files inside the searchPath",
+ scheme: "Size"
+ },
+ {
+ field: "filter.minAge",
+ description: "MinAge the latest object should be older than defined age",
+ scheme: "Duration"
+ },
+ {
+ field: "filter.minSize",
+ description: "MinSize of the files inside the searchPath",
+ scheme: "Size"
+ },
+ {
+ field: "filter.regex",
+ description: "Filter files based on regular expression",
+ scheme: "regex"
+ },
+
{field: "minCount", description: "The minimum number of files inside the `path`", scheme: "int"},
{field: "maxCount", description: "The maximum number of files inside the `path`, can be used in conjunction with `filter.regex` to detect error files", scheme: "int"},
{field: "minAge", description: "The youngest age a file can be", scheme: "Duration"},
@@ -38,17 +63,11 @@ Checks the contents of a folder for size, age, and count. Folder based checks ar
]}/>
-## FolderFilter
-| Field | Description | Scheme | Required |
-| --------- | ----------------------------------------------------------- | ---------------------------------------------------- | -------- |
-| `maxAge` | MaxAge the latest object should be younger than defined age | [Duration](/reference/types#duration) | |
-| `maxSize` | MaxSize of the files inside the searchPath | [Size](/reference/types#size) | |
-| `minAge` | MinAge the latest object should be older than defined age | [Duration](/reference/types#duration) | |
-| `minSize` | MinSize of the files inside the searchPath | [Size](/reference/types#size) | |
-| `regex` | Filter files based on regular expression | _[regex](https://github.com/google/re2/wiki/Syntax)_ | |
+In the example below it checks a local folder for files matching`pg-backups-.*.zip`, the check fails if:
+- No files is created within the last `1d`
+- The size of the matching files us smaller than `10mb`
-e.g. to verify that database backups are being performed
```yaml title="postgres-backup-check.yaml" file=/modules/canary-checker/fixtures/datasources/folder_with_filter.yaml
```
@@ -69,15 +88,6 @@ The following fields are available in `test`, `display` and `transform` [express
| `AvailableSize` | int64 |
| `Files` | [[]os.FileInfo](https://pkg.go.dev/io/fs#FileInfo) |
-### FolderFilter
-
-| Field | Description | Scheme | Required |
-| --------- | ----------- | --------------------------------------- | -------- |
-| `minAge` | | [`Duration`](/reference/types#duration) | |
-| `maxAge` | | [`Duration`](/reference/types#duration) | |
-| `minSize` | | [`Size`](/reference/types#size) | |
-| `maxSize` | | [`Size`](/reference/types#size) | |
-| `regex` | | `string` | |
## Connection Types
diff --git a/canary-checker/docs/reference/1-kubernetes.mdx b/canary-checker/docs/reference/1-kubernetes.mdx
index 1e61293e..6720d15d 100644
--- a/canary-checker/docs/reference/1-kubernetes.mdx
+++ b/canary-checker/docs/reference/1-kubernetes.mdx
@@ -4,6 +4,7 @@ sidebar_position: 0
sidebar_custom_props:
icon: k8s
---
+import ReactMarkdown from 'react-markdown';
# Kubernetes
@@ -15,20 +16,57 @@ The Kubernetes check performs requests on Kubernetes resources such as Pods to g
+ Failing checks are placed in this namespace, useful if you have shared namespaces.
+
+ **NOTE:** this does not change the namespace of the resources being queried
+ },
{field: "ignore", description: "Ignore the specified resources from the fetched resources. Can be a glob pattern.", scheme: '[]glob'},
{field: "healthy", description: "Fail the check if any resources are unhealthy", scheme: 'bool'},
{field: "ready", description: "Fail the check if any resources are not ready", scheme: 'bool'},
]}/>
+
+
+## Resource Selector
+
+
+| Field | Description | Scheme | Required |
+| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------- | -------- |
+| `name` | Name of the component/config | `string` | No |
+| `namespace` | Select resources in this namespace only, if empty find resources in all namespaces | `string` | No | | No |
+| `labelSelector` | Kubernetes Style Label Selector | [LabelSelector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) | No |
+| `fieldSelector` | Kubernetes Style Field Selector Property fields of the component in kubernetes format (or database columns: owner, topology_id, parent_id) | [FieldSelector](https://kubernetes.io/docs/concepts/overview/working-with-objects/field-selectors/) | No |
+| `search` | Search for resources via key value pairs using parsing expression grammar | [Search](#search) | No |
+
+### Search
+
+The query syntax is `field1=value1 field2>value2 field3=value3* field4=*value4`. `*` is for prefix and suffix matching.
+
+Supported operators:
+
+| Operator | Syntax | Types |
+| -------- | -------------------------------- | --------------------- |
+| `=` | `field=value` | `string` `int` `json` |
+| `!=` | `field!=value` | `string` `int` `json` |
+| `*` | `field=*value` or `field=value*` | `string` `int` |
+| `>` `<` | `field>value` or `field %s".format([i.metadata.namespace, i.metadata.name, k8s.getHealth(i).message])).join('\n')
+
```
-See the CEL _Kubernetes_ docs for more details on the `k8s.isHealthy` and other functions available
+See the CEL function k8s.isHealthy for more details
## Ready
@@ -68,7 +101,7 @@ dyn(results).all(x, k8s.isReady(x))
diff --git a/canary-checker/docs/reference/1-s3-protocol.mdx b/canary-checker/docs/reference/1-s3-protocol.mdx
index 7bb93811..a04bf5ea 100644
--- a/canary-checker/docs/reference/1-s3-protocol.mdx
+++ b/canary-checker/docs/reference/1-s3-protocol.mdx
@@ -28,6 +28,7 @@ The S3 check:
{field: "bucket", description: "Bucket name to test against", scheme: "string", required: true},
{field: "objectPath", description: "Path of object to upload/download for test", scheme: "string", required: true},
+ {field: "storageClass", description: "Storage Class of the test object to create", scheme: "string"},
]}/>
diff --git a/canary-checker/docs/reference/1-webhook.mdx b/canary-checker/docs/reference/1-webhook.mdx
index 8f25269d..7a1edc0d 100644
--- a/canary-checker/docs/reference/1-webhook.mdx
+++ b/canary-checker/docs/reference/1-webhook.mdx
@@ -73,8 +73,8 @@ The request is available to the transformation function with these fields:
scheme: "`map[string]string`"
}, {
field: 'results.content',
- description: 'Request body text, See [YAML](/reference/scripting/cel#yaml), [CSV](/reference/scripting/cel#csv)',
- scheme: 'string'
+ description: 'Request body text, See YAML and See CSV for handling other file formats',
+
}
]}/>
diff --git a/canary-checker/docs/reference/3-gcs-database-backup.mdx b/canary-checker/docs/reference/3-gcs-database-backup.mdx
index f42d322d..06d6be62 100644
--- a/canary-checker/docs/reference/3-gcs-database-backup.mdx
+++ b/canary-checker/docs/reference/3-gcs-database-backup.mdx
@@ -5,40 +5,22 @@ sidebar_custom_props:
icon: google-cloud
---
-# Google Cloud SQL Backups
+# Google Cloud SQL Backups
Checks if a Google Cloud SQL instance has been successfully backed up recently.
```yaml title="gcs-database.yaml" file=/modules/canary-checker/fixtures/datasources/GCP/database_backup.yaml
```
-| Field | Description | Scheme | Required |
-| ------------- | ----------------------------------------------------------- | ---------------------------------------------- | -------- |
-| **`gcp`** | Connect to GCP project and instance | [_GCPDatabase_](#gcpdatabase) | Yes |
-| **`maxAge`** | Max age for backup allowed, e.g. 5h30m | _Duration_ | |
-| **`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/expressions/health-evaluation) | |
-| `display` | Expression to change the formatting of the display | [`Expression`](../concepts/expressions/display-formatting ) | |
-| `transform` | Transform data from a check into multiple individual checks | [`Expression`](../concepts/expressions/transforms) | |
-| `metrics` | Metrics to export from | [`[]Metrics`](../concepts/metrics/custom-metrics) | |
-| | | | |
-
-## Duration
-
-Durations are strings with an optional fraction and unit e.g. `300ms`, `1.5h` or `2h45m`. Valid time units are `ms`, `s`, `m`, `h`.
-
-## GCPDatabase
-
-| Field | Description | Scheme | Required |
-| -------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | -------- |
-| `project` | GCP project name | _string_ | Yes |
-| `instance` | Google CloudSQL instance name | _string_ | Yes |
-| **Connection** | | | |
-| `connection` | Path of an existing connection e.g. `connection://gcp`/. Mutually exclusive with `credentials` | _Connections_ | |
-| `credentials` | GCP Access Token File. Mutually exclusive with `connection` | _EnvVar_ | Yes |
+
+
+
### Connecting to GCP
diff --git a/canary-checker/docs/reference/3-namespace.mdx b/canary-checker/docs/reference/3-namespace.mdx
index bb5710b5..768a6fd5 100644
--- a/canary-checker/docs/reference/3-namespace.mdx
+++ b/canary-checker/docs/reference/3-namespace.mdx
@@ -49,4 +49,4 @@ The Namespace check:
| `test` | Evaluate whether a check is healthy | [`Expression`](../concepts/expressions/health-evaluation) | |
| `display` | Expression to change the formatting of the display | [`Expression`](../concepts/expressions/display-formatting ) | |
| `transform` | Transform data from a check into multiple individual checks | [`Expression`](../concepts/expressions/transforms) | |
-| `metrics` | Metrics to export from | [`[]Metrics`](../concepts/metrics/custom-metrics) | |
+| `metrics` | Metrics to export from | [`[]Metrics`](../concepts/metrics#custom-metrics) | |
diff --git a/canary-checker/docs/reference/_connections.mdx b/canary-checker/docs/reference/_connections.mdx
index 22d5f490..52574d93 100644
--- a/canary-checker/docs/reference/_connections.mdx
+++ b/canary-checker/docs/reference/_connections.mdx
@@ -23,11 +23,10 @@ title: Connections
There are 3 options when connecting to AWS:
-
+1. AWS Instance or Pod Identity
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)
-
-
+1. Connection
Using a shared Connection
```yaml title="aws-connection.yaml"
@@ -41,8 +40,7 @@ spec:
- connection: connection://aws/internal
region: us-east-1 # optional if specified in the connection
```
-
-
+1. Inline
```yaml title="inline.yaml"
apiVersion: canaries.flanksource.com/v1
@@ -64,9 +62,6 @@ spec:
key: AWS_SECRET_ACCESS_KEY
region: us-east-1
```
-
-
-
## GCP
@@ -81,12 +76,11 @@ spec:
There are 3 options when connecting to GCP:
-
+1. GKE Workload Identity
GKE [workload identity](https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity) (the default if no `connection` or `credentials` is specified)
-
-
+1. Connection
```yaml title="gcs-connection.yaml"
apiVersion: canaries.flanksource.com/v1
@@ -102,9 +96,8 @@ spec:
connection: connection://gcp/internal
```
-
-
+1. Inline
```yaml title="gcp-inline.yaml"
apiVersion: canaries.flanksource.com/v1
@@ -123,8 +116,6 @@ spec:
name: gcp-credentials
key: AUTH_ACCESS_TOKEN
```
-
-
## Azure
diff --git a/canary-checker/docs/reference/jmeter.mdx b/canary-checker/docs/reference/jmeter.mdx
index 9a75468f..0b9de648 100644
--- a/canary-checker/docs/reference/jmeter.mdx
+++ b/canary-checker/docs/reference/jmeter.mdx
@@ -27,4 +27,4 @@ This check executes the JMeter CLI to execute the JMX test plan on the specified
| `test` | Evaluate whether a check is healthy | [`Expression`](../concepts/expressions/health-evaluation) | |
| `display` | Expression to change the formatting of the display | [`Expression`](../concepts/expressions/display-formatting ) | |
| `transform` | Transform data from a check into multiple individual checks | [`Expression`](../concepts/expressions/transforms) | |
-| `metrics` | Metrics to export from | [`[]Metrics`](../concepts/metrics/custom-metrics) | |
+| `metrics` | Metrics to export from | [`[]Metrics`](../concepts/metrics#custom-metrics) | |
diff --git a/canary-checker/docs/reference/index.md b/canary-checker/docs/reference/reference.md
similarity index 69%
rename from canary-checker/docs/reference/index.md
rename to canary-checker/docs/reference/reference.md
index fa353e24..fbb27a91 100644
--- a/canary-checker/docs/reference/index.md
+++ b/canary-checker/docs/reference/reference.md
@@ -1,8 +1,10 @@
---
title: Checks
-sidebar_position: 1
+sidebar_position: 2
+hide_sidebar: true
sidebar_custom_props:
icon: codicon:pass
+ category: true
---
import DocCardList from '@theme/DocCardList';
diff --git a/canary-checker/docs/scripting/cel.mdx b/canary-checker/docs/scripting/cel.mdx
index 9fe8824d..a7490cdb 100644
--- a/canary-checker/docs/scripting/cel.mdx
+++ b/canary-checker/docs/scripting/cel.mdx
@@ -950,7 +950,7 @@ filepath.Match("*.txt", "foo.txt") // true
`filepath.Rel` returns a relative path that is lexically equivalent to targpath when
joined to basepath with an intervening separator. That is,
Join(basepath, Rel(basepath, targpath)) is equivalent to targpath itself.
-On success, the returned path will always be relative to basepath,
+On success, the returned path is always be relative to basepath,
even if basepath and targpath share no elements.
An error is returned if targpath can't be made relative to basepath or if
knowing the current working directory would be necessary to compute it.
@@ -1617,7 +1617,7 @@ regexp.Split(pattern, count, input)
```
- `pattern` is the regular expression pattern that separates the substrings.
-- `count` is the maximum number of splits. Use -1 for no limit.
+- `count` is the maximum number of splits. Use `-1` for no limit.
- `input` is the string to split.
```javascript
@@ -1640,12 +1640,11 @@ regexp.Split("z", -1, "hello") // ["hello"]
### .abbrev
-`abbrev` on a string abbreviates the string using ellipses. Tl turn the string "Now is the time for all good men" into "...s the time for..."
-This function works like `Abbreviate(string, int)`, but allows you to specify a "left edge" offset. The left edge is not
-necessarily going to be the leftmost character in the result, or the first character following the ellipses, but it will appear
-somewhere in the result.
-In no case will it return a string of length greater than maxWidth.
+The `abbrev` function abbreviates a string using ellipses. For example, it transforms "Now is the time for all good men" into "...s the time for..."
+This function works like `Abbreviate(string, int)`, but allows you to specify a "left edge" offset. The left edge appears somewhere in the result, though not necessarily as the leftmost character or the first character following the ellipses.
+
+The function ensures the returned string length does not exceed maxWidth.
```javascript
"string".abbrev(offset, maxWidth)
```
@@ -1688,9 +1687,8 @@ Examples:
```
### .charAt
-
Returns the character at the given position. If the position is negative, or
-greater than the length of the string, the function will produce an error:
+greater than the length of the string, an error is thrown
```javascript
"hello".charAt(4) // return 'o'
@@ -1706,7 +1704,7 @@ greater than the length of the string, the function will produce an error:
### .contains
-`contains` check if a string contains a given substring.
+`contains` checks if a string contains a given substring.
```javascript
"apple".contains("app") // true
@@ -1721,19 +1719,17 @@ greater than the length of the string, the function will produce an error:
```
### .format
-
-`format` Returns a new string with substitutions being performed, printf-style.
+`format` creates a new string with substitutions performed in printf-style.
The valid formatting clauses are:
-- `%s` substitutes a string. This can also be used on `bools`, `lists`, `maps`, `bytes`,
- `Duration`, `Timestamp`,`int`, `double`
- the dot/period decimal separator will always be used when printing a list or map that contains a double, and that null can be passed (which results in the string "null") in addition to types.
+- `%s` substitutes a string. Use this for `bools`, `lists`, `maps`, `bytes`, `Duration`, `Timestamp`,`int`, `double`
+ The dot/period decimal separator appears when printing a list or map containing a double. You can pass null, which outputs the string "null" in addition to types.
- `%d` substitutes an integer.
-- `%f` substitutes a double with fixed-point precision. The default precision is 6, but this can be adjusted. The strings `Infinity`, `-Infinity`, and `NaN` are also valid input for this clause.
-- `%e` substitutes a double in scientific notation. The default precision is 6, but this can be adjusted.
-- `%b` substitutes an integer with its equivalent binary string. Can also be used on bools.
-- `%x` substitutes an integer with its equivalent in hexadecimal, or if given a string or bytes, will output each character's equivalent in hexadecimal.
-- `%X` same as above, but with A-F capitalized.
+- `%f` substitutes a double with fixed-point precision. The default precision is 6, but you can adjust this. The strings `Infinity`, `-Infinity`, and `NaN` are valid input for this clause.
+- `%e` substitutes a double in scientific notation. The default precision is 6, but you can adjust this.
+- `%b` substitutes an integer with its equivalent binary string. Use this for bools too.
+- `%x` substitutes an integer with its equivalent in hexadecimal. For strings or bytes, it outputs each character's hexadecimal equivalent.
+- `%X` same as `%x`, but with A-F capitalized.
- `%o` substitutes an integer with its equivalent in octal.
```javascript
diff --git a/canary-checker/docs/scripting/gotemplate.mdx b/canary-checker/docs/scripting/gotemplate.mdx
index cc456405..a7f5ca65 100644
--- a/canary-checker/docs/scripting/gotemplate.mdx
+++ b/canary-checker/docs/scripting/gotemplate.mdx
@@ -16,8 +16,56 @@ In this example we print out the exchange rates returned by an HTTP API Call
-
+## Escaping
+If you need to pass a template through a Helm Chart and prevent Helm from templating you need to escape it:
+
+```
+{{`{{ .secret }}`}}
+```
+
+Alternatively [change the templating delimiters](#delimiters)
+
+
+## Multiline YAML
+
+If you are using a YAML multiline string use `|` and not `>` which strips newlines
+
+Instead of:
+
+```yaml
+exec:
+ //highlight-next-line
+ script: >
+ #! pwsh
+ Get-Items | ConvertTo-JSON
+```
+
+Do this:
+
+```yaml
+exec:
+ //highlight-next-line
+ script: |
+ #! pwsh
+ Get-Items | ConvertTo-JSON
+```
+
+
+## Delimiters
+
+The template delimiters can be changed from the defaults of `$()` and `{{}}` with `gotemplate` comments
+
+```yaml
+exec:
+ script: |
+ #! pwsh
+ //highlight-next-line
+ # gotemplate: left-delim=$[[ right-delim=]]
+ $message = "$[[.config.name]]"
+ Write-Host "{{ $message }}"
+ Write-Host @{ Number = 1; Shape = "Square"; Color = "Blue"} | ConvertTo-JSON
+```
## base64
@@ -155,7 +203,7 @@ Where books is from [fantasy.json](https://openlibrary.org/subjects/fantasy.json
Return a list of keys in one or more maps.
-The keys will be ordered first by map position (if multiple maps are given), then alphabetically.
+The keys are ordered first by map position (if multiple maps are given), then alphabetically.
See also [`coll.Values`](#values).
@@ -168,7 +216,7 @@ See also [`coll.Values`](#values).
Return a list of values in one or more maps.
-The values will be ordered first by map position (if multiple maps are given), then alphabetically by key.
+The values are ordered first by map position (if multiple maps are given), then alphabetically by key.
See also [`coll.Keys`](#keys).
@@ -230,12 +278,11 @@ _this function does not change the given list; it always produces a new one._
### Sort
-Sort a given list. Uses the natural sort order if possible. For inputs that are not sortable (either because the elements are of different types, or of an un-sortable type), the input will simply be returned, unmodified.
+Sort a given list using the natural sort order when possible. For inputs that are not sortable (either because the elements are of different types, or of an un-sortable type), the input returns unmodified.
Maps and structs can be sorted by a named key.
_this function does not modify the input._
-
```go
{{ slice "foo" "bar" "baz" | coll.Sort }} // [bar baz foo]
```
@@ -246,10 +293,9 @@ _this function does not modify the input._
### Merge
-Merge maps together by overriding src with dst. In other words, the src map can be configured the "default" map, whereas the dst
-map can be configured the "overrides". Many source maps can be provided. Precedence is in left-to-right order.
+Merge combines multiple maps by overriding values from left to right. The first map acts as the base "defaults", while subsequent maps provide overrides. Multiple source maps can be provided, with precedence given in left-to-right order.
-_this function does not modify the input._
+_This function does not modify the input maps._
```go
{{ $default := dict "foo" 1 "bar" 2}}
@@ -313,10 +359,9 @@ Converts a true-ish string to a boolean. Can be used to simplify conditional sta
```
### default
-
Provides a default value given an empty input. Empty inputs are `0` for numeric types, `""` for strings, `false` for booleans, empty arrays/maps, and `nil`.
-this will not provide a default for the case where the input is undefined (i.e. referencing things like `.foo` where there is no `foo` field of `.`), but [`conv.Has`](#has) can be used for that.
+This provides no default for cases where the input is undefined (that is, referencing things like `.foo` where there is no `foo` field of `.`), but [`conv.Has`](#has) can be used for that.
```go
{{ "" | default "foo" }} // foo
@@ -526,7 +571,7 @@ This delegates to [`conv.ToFloat64`](#tofloat64) for each input argument.
Converts the input (of any type) to a `string`.
-The input will always be represented in _some_ way.
+The input is always be represented in _some_ way.
```go
{{ conv.ToString 0xFF }} // 255
@@ -561,7 +606,7 @@ _Warning: SHA-1 is cryptographically broken and should not be used for secure ap
### json
-Converts a JSON string into an object. Works for JSON Objects, but will also parse JSON Arrays. Will not parse other valid JSON types.
+Converts a JSON string into an object. Supports only JSON Objects and Arrays.
For more explicit JSON Array support, see [`data.JSONArray`](#jsonarray).
@@ -579,7 +624,7 @@ Converts a JSON string into a slice. Only works for JSON Arrays.
### yaml
-Converts a YAML string into an object. Works for YAML Objects but will also parse YAML Arrays. This can be used to access properties of YAML objects.
+Converts a YAML string into an object. Supports only YAML Objects and Arrays.
For more explicit YAML Array support, see [`data.JSONArray`](#yamlarray).
@@ -634,7 +679,7 @@ Converts a CSV-format string into a slice of maps.
By default, the [RFC 4180](https://tools.ietf.org/html/rfc4180) format is supported, but any single-character delimiter can be specified.
-Also by default, the first line of the string will be assumed to be the header, but this can be overridden by providing an explicit header, or auto-indexing can be used.
+Also by default, the first line of the string is assumed to be the header, but this can be overridden by providing an explicit header, or auto-indexing can be used.
```
{{ $c := `lang,keywords
@@ -701,7 +746,6 @@ The indent string must be provided as an argument.
Converts an object to a YAML document. Input objects may be the result of `data.JSON`, `data.YAML`, `data.JSONArray`, or `data.YAMLArray` functions.
-_This is obviously contrived - `data.JSON` is used to create an object._
```go
{{ (`{"foo":{"hello":"world"}}` | data.JSON).foo | data.ToYAML }} // hello: world
@@ -827,10 +871,9 @@ A wrapper for Go's [`filepath.Rel`](https://golang.org/pkg/path/filepath/#Rel) f
```
### Split
-
Splits path immediately following the final path separator, separating it into a directory and file name component.
-The function returns an array with two values, the first being the diretory, and the second the file.
+The function returns an array with two values, the first being the directory, and the second the file.
A wrapper for Go's [`filepath.Split`](https://golang.org/pkg/path/filepath/#Split) function.
@@ -861,7 +904,7 @@ A wrapper for Go's [`filepath.VolumeName`](https://golang.org/pkg/path/filepath/
## math
-Returns the absolute value of a given number. When the input is an integer, the result is `int64`, otherwise it will be a `float64`.
+Returns the absolute value of a given number. When the input is an integer, the result is `int64`, otherwise it is `float64`.
```go
{{ math.Abs -3.5 }} {{ math.Abs 3.5 }} {{ math.Abs -42 }} // 3.5 3.5 42
@@ -869,7 +912,7 @@ Returns the absolute value of a given number. When the input is an integer, the
### Add
-Adds all given operators. When one of the inputs is a floating-point number, the result will be a `float64`, otherwise it is `int64`.
+Adds all given operators. When one of the inputs is a floating-point number, the result is `float64`, otherwise it is `int64`.
```go
{{ math.Add 1 2 3 4 }} {{ math.Add 1.5 2 3 }} // 10 6.5
@@ -895,7 +938,7 @@ Returns the least integer value greater than or equal to a given floating-point
### Div
-Divide the first number by the second. Division by zero is disallowed. The result will be a `float64`.
+Divide the first number by the second. Division by zero is disallowed. The result is `float64`.
```go
{{ math.Div 8 2 }} {{ math.Div 3 2 }} // 4 1.5
@@ -921,9 +964,9 @@ Returns the greatest integer value less than or equal to a given floating-point
### IsFloat
-Returns whether or not the given number can be interpreted as a floating-point literal, as defined by the [Go language reference](https://golang.org/ref/spec#Floating-point_literals).
+Returns whether the given number can be interpreted as a floating-point literal, as defined by the [Go language reference](https://golang.org/ref/spec#Floating-point_literals).
-**Note:** If a decimal point is part of the input number, it will be considered a floating-point number, even if the decimal is `0`.
+**Note:** If a decimal point is part of the input number, it is considered a floating-point number, even if the decimal is `0`.
```go
{{ range (slice 1.0 "-1.0" 5.1 42 "3.14" "foo" "0xFF" "NaN" "Inf" "-0") }}{{ if (math.IsFloat .) }}{{.}} is a float{{"\n"}}{{ end }}{{end}}
@@ -938,7 +981,7 @@ Returns whether or not the given number can be interpreted as a floating-point l
### IsInt
-Returns whether or not the given number is an integer.
+Returns whether the given number is an integer.
```go
{{ range (slice 1.0 "-1.0" 5.1 42 "3.14" "foo" "0xFF" "NaN" "Inf" "-0") }}{{ if (math.IsInt .) }}{{.}} is an integer{{"\n"}}{{ end }}{{end}}
@@ -959,7 +1002,7 @@ Returns whether the given input is a number. Useful for `if` conditions.
### Max
-Returns the largest number provided. If any values are floating-point numbers, a `float64` is returned, otherwise an `int64` is returned. The same special-cases as Go's [`math.Max`](https://golang.org/pkg/math/#Max) are followed.
+Returns the largest number provided. If any values are floating-point numbers, a `float64` is returned, otherwise an `int64` is returned. Follows the same syntax as Go's [`math.Max`](https://golang.org/pkg/math/#Max).
```go
{{ math.Max 0 8.0 4.5 "-1.5e-11" }} // 8
@@ -967,7 +1010,7 @@ Returns the largest number provided. If any values are floating-point numbers, a
### Min
-Returns the smallest number provided. If any values are floating-point numbers, a `float64` is returned, otherwise an `int64` is returned. The same special-cases as Go's [`math.Min`](https://golang.org/pkg/math/#Min) are followed.
+Returns the smallest number provided. If any values are floating-point numbers, a `float64` is returned, otherwise an `int64` is returned. Follows the same syntax as Go's [`math.Min`](https://golang.org/pkg/math/#Min).
```go
{{ math.Min 0 8 4.5 "-1.5e-11" }} // -1.5e-11
@@ -1151,7 +1194,7 @@ By default, the possible characters are those represented by the regular express
A different set of characters can be specified with a regular expression, or by giving a range of possible characters by specifying the lower and upper bounds. Lower/upper bounds can be specified as characters (e.g. `"q"`, or escape sequences such as `"\U0001f0AF"`), or numeric Unicode code-points (e.g. `48` or `0x30` for the character `0`).
-When given a range of Unicode code-points, `random.String` will discard non-printable characters from the selection. This may result in a much smaller set of possible characters than intended, so check the [Unicode character code charts](http://www.unicode.org/charts/) to verify the correct code-points.
+When given a range of Unicode code-points, `random.String` discards non-printable characters from the selection. This may result in a much smaller set of possible characters than intended, so check the [Unicode character code charts](http://www.unicode.org/charts/) to verify the correct code-points.
```go
{{ random.String 8 }} // FODZ01u_
@@ -1173,7 +1216,7 @@ Pick an element at a random from a given slice or array.
Pick a random integer. By default, a number between `0` and `100` (inclusive) is chosen, but this range can be overridden.
-the difference between `min` and `max` can not be larger than a 63-bit integer (i.e. the unsigned portion of a 64-bit signed integer). The result is given as an `int64`.
+the difference between `min` and `max` can not be larger than a 63-bit integer (that is the unsigned portion of a 64-bit signed integer). The result is given as an `int64`.
```go
{{ random.Number }} // 55
@@ -1183,7 +1226,7 @@ the difference between `min` and `max` can not be larger than a 63-bit integer (
### Float
-Pick a random decimal floating-point number. By default, a number between `0.0` and `1.0` (_exclusive_, i.e. `[0.0,1.0)`) is chosen, but this range can be overridden.
+Pick a random decimal floating-point number. By default, a number between `0.0` and `1.0` (_exclusive_, that is `[0.0,1.0)`) is chosen, but this range can be overridden.
The result is given as a `float64`.
@@ -1212,7 +1255,7 @@ no {{ "will not match" | regexp.Find "[0-9]" }}numbers // no numbers
Returns a list of all successive matches of the regular expression.
-This can be called with 2 or 3 arguments. When called with 2 arguments, the `n` argument (number of matches) will be set to `-1`, causing all matches to be returned.
+FindAll can be called with 2 or 3 arguments. When called with 2 arguments, the `n` argument (number of matches) is set to `-1`, causing all matches to be returned.
This function provides the same behavior as Go's
[`regexp.FindAllString`](https://golang.org/pkg/regexp/#Regexp.FindAllString) function.
@@ -1276,7 +1319,7 @@ This function provides the same behavior as Go's [`regexp.ReplaceAllLiteralStrin
Splits `input` into sub-strings, separated by the expression.
-This can be called with 2 or 3 arguments. When called with 2 arguments, the `n` argument (number of matches) will be set to `-1`, causing all sub-strings to be returned.
+This can be called with 2 or 3 arguments. When called with 2 arguments, the `n` argument (number of matches) is set to `-1`, causing all sub-strings to be returned.
This is equivalent to [`strings.SplitN`](#splitn), except that regular expressions are supported.
@@ -1330,7 +1373,7 @@ http://example.com:80
### Indent
-Indents a string. If the input string has multiple lines, each line will be indented.
+Indents a string. If the input string has multiple lines, each line is indented.
This function can be especially useful when adding YAML snippets into other YAML documents, where indentation is important:
@@ -1356,7 +1399,7 @@ foo:
**Deprecation Notice:** Use [`coll.Sort`](#sort) instead
-Returns an alphanumerically-sorted copy of a given string list.
+Returns an alphanumerically sorted copy of a given string list.
```go
{{ (slice "foo" "bar" "baz") | strings.Sort }} // [bar baz foo]
@@ -1429,7 +1472,7 @@ Replaces all occurrences of a given string with another.
### Slug
-Creates a a "slug" from a given string - supports Unicode correctly. This wraps the [github.com/gosimple/slug](https://github.com/gosimple/slug) package. See [the github.com/gosimple/slug docs](https://godoc.org/github.com/gosimple/slug) for more information.
+Creates a "slug" from a given string - supports Unicode correctly. This wraps the [github.com/gosimple/slug](https://github.com/gosimple/slug) package. See [the github.com/gosimple/slug docs](https://godoc.org/github.com/gosimple/slug) for more information.
```go
{{ "Hello, world!" | strings.Slug }} // hello-world
@@ -1437,8 +1480,8 @@ Creates a a "slug" from a given string - supports Unicode correctly. This wraps
### shellQuote
-Given a string, emits a version of that string that will evaluate to its literal data when expanded by any POSIX-compliant shell.
-Given an array or slice, emit a single string which will evaluate to a series of shell words, one per item in that array or slice.
+Given a string, emits a version of that string that evaluates to its literal data when expanded by any POSIX-compliant shell.
+Given an array or slice, emits a single string which evaluates to a series of shell words, one per item in that array or slice.
```go
{{ slice "one word" "foo='bar baz'" | shellQuote }}
@@ -1536,7 +1579,7 @@ _Also see [`strings.Abbrev`](#abbrev)._
Converts a sentence to CamelCase, i.e. `The quick brown fox` becomes `TheQuickBrownFox`.
-All non-alphanumeric characters are stripped, and the beginnings of words are upper-cased. If the input begins with a lower-case letter, the result will also begin with a lower-case letter.
+All non-alphanumeric characters are stripped, and the beginnings of words are upper-cased. If the input begins with a lower-case letter, the result also begin with a lower-case letter.
See [CamelCase on Wikipedia](https://en.wikipedia.org/wiki/Camel_case) for more details.
@@ -1550,7 +1593,7 @@ See [CamelCase on Wikipedia](https://en.wikipedia.org/wiki/Camel_case) for more
Converts a sentence to snake_case, i.e. `The quick brown fox` becomes `The_quick_brown_fox`.
-All non-alphanumeric characters are stripped, and spaces are replaced with an underscore (`_`). If the input begins with a lower-case letter, the result will also begin with a lower-case letter.
+All non-alphanumeric characters are stripped, and spaces are replaced with an underscore (`_`). If the input begins with a lower-case letter, the result also begin with a lower-case letter.
See [Snake Case on Wikipedia](https://en.wikipedia.org/wiki/Snake_case) for more details.
@@ -1561,7 +1604,7 @@ See [Snake Case on Wikipedia](https://en.wikipedia.org/wiki/Snake_case) for more
### KebabCase
-Converts a sentence to kebab-case, i.e. `The quick brown fox` becomes `The-quick-brown-fox`. All non-alphanumeric characters are stripped, and spaces are replaced with a hyphen (`-`). If the input begins with a lower-case letter, the result will also begin with a lower-case letter.
+Converts a sentence to kebab-case, i.e. `The quick brown fox` becomes `The-quick-brown-fox`. All non-alphanumeric characters are stripped, and spaces are replaced with a hyphen (`-`). If the input begins with a lower-case letter, the result also begins with a lower-case letter.
See [Kebab Case on Wikipedia](https://en.wikipedia.org/wiki/Kebab_case) for more details.
```go
@@ -1700,9 +1743,9 @@ See [the Go `reflect` source code](https://github.com/golang/go/blob/36fcde1676a
- `float64`
- `slice`
- `map`
-- `invalid` (a catch-all, usually just `nil` values)
+- `invalid` (a catch-all, usually only `nil` values)
-In addition, the special kind `number` is accepted by this function, to represent _any_ numeric kind (whether `float32`, `uint8`, or whatever). This is useful when the specific numeric type is unknown.
+In addition, the kind `number` is accepted by this function, to represent _any_ numeric kind (whether `float32`, `uint8`, or whatever). This is useful when the specific numeric type is unknown.
See also [`test.Kind`](#kind).
@@ -1731,7 +1774,7 @@ Got a number: {{ $object }}
### Kind
-Report the _kind_ of the given argument. This differs from the _type_ of the argument in specificity; for example, while a slice of strings may have a type of `[]string`, the _kind_ of that slice will simply be `slice`.
+Report the _kind_ of the given argument. This differs from the _type_ of the argument in specificity; for example, while a slice of strings may have a type of `[]string`, the _kind_ of that slice is `slice`.
If you need to know the precise type of a value, use `printf "%T" $value`.
See also [`test.IsKind`](#iskind)
@@ -1751,7 +1794,7 @@ This is effectively a short-form of the following template:
{{ if conv.ToBool $condition }}{{ $truevalue }}{{ else }}{{ $falsevalue }}{{ end }}
```
-Keep in mind that using an explicit `if`/`else` block is often easier to understand than ternary expressions!
+Keep in mind that using an explicit `if`/`else` block is often easier to understand than ternary expressions.
```go
{{ ternary "FOO" "BAR" false }} // BAR
@@ -1825,7 +1868,7 @@ time units are `ns`, `us` (or `µs`), `ms`, `s`, `m`, `h`.
### ParseLocal
-Same as [`time.Parse`](#parse), except that in the absence of a time zone indicator, the timestamp wil be parsed in the local timezone.
+Same as [`time.Parse`](#parse), except that in the absence of a time zone indicator, the timestamp is parsed in the local timezone.
Usage with [`Format`](https://golang.org/pkg/time/#Time.Format):
diff --git a/canary-checker/docs/scripting/index.mdx b/canary-checker/docs/scripting/index.mdx
index 979b44eb..1ec12666 100644
--- a/canary-checker/docs/scripting/index.mdx
+++ b/canary-checker/docs/scripting/index.mdx
@@ -1,9 +1,12 @@
---
title: Scripting
-sidebar_position: 1
+sidebar_position: 3
sidebar_class_name: hide-mission-control
sidebar_custom_props:
icon: hugeicons:code
---
+import DocCardList from '@theme/DocCardList';
+
+
diff --git a/canary-checker/docs/security.md b/canary-checker/docs/security.md
index 91f4658e..1f870f47 100644
--- a/canary-checker/docs/security.md
+++ b/canary-checker/docs/security.md
@@ -1,6 +1,8 @@
---
title: Security
sidebar_class_name: hidden-mission-control
+sidebar_custom_props:
+ icon: shield
---
Canary checker is essentially a remote command execution platform, which from a security perspective can be challenging
diff --git a/canary-checker/docs/troubleshooting.mdx b/canary-checker/docs/troubleshooting.mdx
index 6e09ea46..295ce8ba 100644
--- a/canary-checker/docs/troubleshooting.mdx
+++ b/canary-checker/docs/troubleshooting.mdx
@@ -1,7 +1,7 @@
---
title: Troubleshooting
sidebar_custom_props:
- icon: material-symbols-light:troubleshoot
+ icon: troubleshoot
---
import Install from '@site/docs/snippets/_install.mdx'
diff --git a/canary-checker/docs/tutorials/getting-started.md b/canary-checker/docs/tutorials/getting-started.md
deleted file mode 100644
index 3addffa0..00000000
--- a/canary-checker/docs/tutorials/getting-started.md
+++ /dev/null
@@ -1,223 +0,0 @@
-# Getting Started with Canary Checker
-
-Canary checker is a monitoring system for executing synthetic tests, providing a built-in user interface, CLI and multi-cluster and multi-instance aggregation. Canary checker is designed with multi-tenancy in mind.
-
-You are able to write your own tests and execute them to continually verify that your applications and clusters are working the way you expect.
-
-In this guide, you'll see how to use canary-checker to test a Postgres database in several ways, using the CLI.
-
-## Prerequisites
-
-For the purposes of this guide, you need a PostgreSQL instance running in Kubernetes. See the following guide on [how to install PostgreSQL](https://phoenixnap.com/kb/postgresql-kubernetes) in your Kubernetes Cluster via Helm.
-
-## Installing the CLI
-
-> For this guide, Docker Desktop is used to create a Kubernetes cluster on MacOS. You can create your Cluster on the environment of your choice.
-
-The canary-checker CLI will allow you to quickly and simply execute checks that you have defined, via a single CLI command.
-
-!!! info "Info"
-To install the CLI for preferred environment, See the [Canary-checker Installation guide](../run/#installation) for more information.
-
-To verify whether the CLI has been installed correctly, run `canary-checker run -h` from your terminal. You should see the following output:
-
-```console
-Execute checks and return
-
-Usage:
- canary-checker run [flags]
-
-Flags:
- --csv output results in csv format
- -d, --data string Template out each spec using the JSON or YAML data in this file
- -h, --help help for run
- -j, --junit output results in junit format
- -n, --namespace string Namespace to run canary checks in
- -o, --output-file string file to output the results in
-
-Global Flags:
- --db string Connection string for the postgres database (default "DB_URL")
- --db-trace Trace database queries
- --expose-env Expose environment variables for use in all templates. Note this has serious security implications with untrusted canaries
- --json-logs Print logs in json format to stderr
- --log-fail Log every failing check (default true)
- --log-pass Log every passing check
- -v, --loglevel count Increase logging level
- --shared-library stringArray Add javascript files to be shared by all javascript templates
-```
-
-## Creating a synthetic check for PostgreSQL
-
-You'll define a check against our database that will connect to it, run a query against it and verify the results. Additionally, you'll see how canary-checker responds when the results are incorrect.
-
-To get started, let’s created a directory to house our checks called `postgres-canaries`.
-
-In that directory, create a file named `postgres-canary-local.yaml`, which will house the definition for our first check.
-
-Add the following resource definition to our file. This is a Canary that will run the `SELECT current_schemas(true)` SQL query against our PostgreSQL instance every 30 seconds. It will also verify that the returned result is 1.
-
-Replace the username and password with your PostgreSQL username and password, and save the file.
-
-```yaml
-apiVersion: canaries.flanksource.com/v1
-kind: Canary
-metadata:
- name: postgres-succeed
-spec:
- interval: 30
- postgres:
- - connection: 'postgres://$(username):$(password)@127.0.0.1:5432/postgres?sslmode=disable'
- name: postgres schemas check
- auth:
- username:
- value: postgres
- password:
- value: yourpassword
- query: SELECT current_schemas(true)
- display:
- template: |
- {{- range $r := .results.rows }}
- {{- $r.current_schemas}}
- {{- end}}
- results: 1
-```
-
-The above Canary runs the query against our database, which has been port forwarded to port 5432 running on our development machine.
-
-Run the Canary using the following command:
-
-```bash
-canary-checker run postgres-canary-local.yaml
-```
-
-You should see that canary-checker ran the test that you defined, and validated the results:
-
-```console
-2022-08-20T13:03:49.264+0200 INFO Checking postgres-canary-local.yaml, 1 checks found
-2022-08-20T13:03:49+02:00 PASS [postgres] default/postgres-succeed/postgres schemas check duration=139 {pg_catalog,public}
-2022-08-20T13:03:49.413+0200 INFO 1 passed, 0 failed in 154ms
-```
-
-Let’s modify the `results` field in our Canary definition to be `2` instead of `1`, and run the check again.
-
-```console
-2022-08-20T13:05:38.469+0200 INFO Checking postgres-canary-local.yaml, 1 checks found
-2022-08-20T13:05:38+02:00 FAIL [postgres] default/postgres-succeed/postgres schemas check duration=130 {pg_catalog,public} Query return 1 rows, expected 2
-2022-08-20T13:05:38.607+0200 INFO 0 passed, 1 failed in 145ms
-```
-
-You can see that canary-checker is able to validate that the result was not as expected, as well as provide us with contextual information about why it was incorrect.
-Writing a custom check
-
-The above check was a simple query that validated something that exists by default in a PostgreSQL database. However, a common use case for synthetic testing might be to validate the existence of some business-specific information.
-
-Taking for instance there's a database table called `Users`, where you store the user information for your application.
-
-You might want to run a Canary to validate whether a specific entry exists in the `Users` table.
-
-To do this, create another Canary definition in our `postgres-canaries` directory called postgres-canary-local-does-admin-user-exist.yaml.
-
-```yaml
-apiVersion: canaries.flanksource.com/v1
-kind: Canary
-metadata:
- name: postgres-succeed
-spec:
- interval: 30
- postgres:
- - connection: 'postgres://$(username):$(password)@127.0.0.1:5432/postgres?sslmode=disable'
- name: postgres schemas check
- auth:
- username:
- value: postgres
- password:
- value: yourpassword
- query: SELECT * from Users
- resultsFunction: '[[ if index .results 0 "username | eq "admin" ]]true[[else]]false[[end]]'
- displayTemplate: '[[ index .results 0 ]]'
-```
-
-If you run your Canary right away, using the `canary-checker run` CLI command, you'll see that it fails, because you have not created the Users table yet.
-
-```bash
-canary-checker run ../postgres-canaries/postgres-canary-local-does-admin-user-exist.yaml
-```
-
-```
-2022-09-08T13:18:31.547+0200 INFO Checking ../postgres-canaries/postgres-canary-local-does-admin-user-exist.yaml, 1 checks found
-2022-09-08T13:18:31+02:00 FAIL [postgres] default/postgres-succeed/postgres schemas check duration=126 failed to query db: pq: relation "users" does not exist
-2022-09-08T13:18:31.677+0200 INFO 0 passed, 1 failed in 134ms
-```
-
-Let’s create and insert the required data into our database with the following SQL.
-
-```sql
-CREATE TABLE users(
- id int,
- username varchar(200),
- PRIMARY KEY(id)
-);
-
-insert into users (id, username) values (1, 'admin')
-```
-
-Now, running the Canary again, you see the expected behavior occurs - and our data is validated as expected.
-
-```bash
-canary-checker run ../postgres-canaries/postgres-canary-local-does-admin-user-exist.yaml
-```
-
-## Installing canary-checker as a Kubernetes operator
-
-So far, you've been running canary-checker using the CLI, but it's recommended you install it in your cluster and deploy a few Canaries with it.
-
-To do this, you can use the operator for canary-checker.
-
-From your terminal, run the following command to install canary-checker (Ensure that you have the prerequisites installed on your cluster first).
-
-```bash
-kubectl apply -f https://github.com/flanksource/canary-checker/releases/download/v0.38.154/release.yaml
-```
-
-Once the operator has been installed, you should be able to run `kubectl get canary` to see any canaries that you've deployed into our namespace.
-
-To get started using the operator, let’s deploy a simple HTTP canary to our namespace.
-
-Create a file called `http_pass.yaml` containing the below resource definition.
-
-```yaml
-apiVersion: canaries.flanksource.com/v1
-kind: Canary
-metadata:
- name: http-pass
-spec:
- interval: 30
- http:
- - endpoint: https://httpstat.us/200
- thresholdMillis: 3000
- responseCodes: [201, 200, 301]
- responseContent: ''
- maxSSLExpiry: 7`
-```
-
-You can then deploy this canary into our namespace using:
-
-```bash
-kubectl apply -f http_pass.yaml
-```
-
-```
-canary.canaries.flanksource.com/http-pass created
-```
-
-You can then check the status of our canary by running:
-
-```
-TODO - Add the status
-```
-
-### Wrapping up
-
-In this guide, you've seen how to get started with canary-checker and run a few synthetic tests against PostgreSQL running in Kubernetes. You've also seen how you can deploy canary-checker as a Kubernetes operator and deploy a Canary into your Kubernetes cluster to continuously monitor your systems.
-
-In the next guide, You'll take a look at how to model an application and Kubernetes cluster using Topologies, as well as how to link components together - eventually linking components to canaries.
diff --git a/canary-checker/docs/types.md b/canary-checker/docs/types.md
new file mode 100644
index 00000000..7cfaa76d
--- /dev/null
+++ b/canary-checker/docs/types.md
@@ -0,0 +1,11 @@
+---
+hide_title: true
+title: Common Types
+sidebar_position: 3
+sidebar_custom_props:
+ icon: library
+---
+
+import Types from '@site/docs/snippets/\_types.md'
+
+
diff --git a/canary-checker/docusaurus.config.js b/canary-checker/docusaurus.config.js
index e6a84068..934d1421 100644
--- a/canary-checker/docusaurus.config.js
+++ b/canary-checker/docusaurus.config.js
@@ -30,6 +30,9 @@ export default async function createConfigAsync() {
"cel": "/scripting/cel",
"gotemplate": "/scripting/gotemplate",
"javascript": '/scripting/javascript',
+ "types": "/types",
+ "image-variants": "/concepts/image-variants",
+ "grafana": "/concepts/metrics#grafana",
"jsonpath": 'https://jsonpath.com/'
}
},
@@ -54,6 +57,7 @@ export default async function createConfigAsync() {
routeBasePath: '/',
exclude: [
"**/*.mc.mdx",
+ "**/*.mc.md",
"**/modules/**",
"**/_*.mdx",
"**/_*.md",
@@ -82,6 +86,30 @@ export default async function createConfigAsync() {
customCss: './src/css/out.css'
}
})
+ ],
+
+ ['@docusaurus/plugin-client-redirects',
+ {
+ redirects: [
+ {
+ to: '/getting-started',
+ from: '/docs/getting-started/installation',
+ },
+ {
+ to: '/concepts/metrics#grafana',
+ from: '/concepts/metrics/grafana',
+ },
+ {
+ to: '/concepts/metrics',
+ from: '/concepts/metrics/custom-metrics',
+ },
+ {
+ to: '/concepts/metrics',
+ from: '/concepts/metrics-exporter',
+ }
+ ],
+ }
+
]
],
diff --git a/canary-checker/sidebars.js b/canary-checker/sidebars.js
index a6ef1b43..7a744d4d 100644
--- a/canary-checker/sidebars.js
+++ b/canary-checker/sidebars.js
@@ -1,99 +1,19 @@
module.exports = {
docs: [
- {
- type: 'doc',
- id: 'health-checks',
- label: 'Overview'
- },
- {
- type: 'doc',
- id: 'getting-started.canary',
- label: 'Getting Started'
- },
- {
- type: 'category',
- label: 'Concepts',
- items: [
- {
- type: 'autogenerated',
- dirName: "concepts"
- }]
- },
- {
- type: 'category',
- label: 'Checks',
- items: [
- {
- className: 'condensed',
- type: 'autogenerated',
- dirName: 'reference'
- }
- ]
- },
{
- type: 'category',
- label: 'Examples',
- items: [
-
- {
- className: 'condensed',
- type: 'autogenerated',
- dirName: 'examples'
- }
- ]
+ type: 'autogenerated',
+ dirName: "."
},
-
- {
- type: 'category',
- label: 'Reference',
- items: [
-
- {
- label: "CEL",
- type: 'doc',
- id: 'scripting/cel'
- },
- {
- label: "Go Templates",
- type: 'doc',
- id: 'scripting/gotemplate'
- },
- {
- label: "Javascript",
- type: 'doc',
- id: 'scripting/javascript'
- }
-
- ]
- },
- {
- type: 'category',
- label: 'Comparisons',
- items: [
- {
- type: 'doc',
- id: 'comparisons/blackbox-exporter',
- label: 'Blackbox Exporter'
- }
- ]
- },
- {
- type: 'doc',
- id: 'troubleshooting',
- label: 'Troubleshooting'
- },
-
-
{
type: 'category',
label: 'Tutorials',
- collapsed: false,
+ collapsed: true,
items: [
{
- type: 'doc',
- id: 'tutorials/control-plane-testing/index',
- label: 'Control Plane Testing'
+ type: 'link',
+ href: 'https://flanksource.com/docs/blog/infrastructure-testing-with-canary-checker-and-flux',
+ label: 'Synthetic Testing with Flux and Helm'
}
]
diff --git a/canary.yaml b/canary.yaml
new file mode 100644
index 00000000..e569dbf5
--- /dev/null
+++ b/canary.yaml
@@ -0,0 +1,24 @@
+apiVersion: canaries.flanksource.com/v1
+kind: Canary
+metadata:
+ name: http-crawl
+spec:
+ schedule: "@daily"
+ http:
+ - name: docs
+ url: http://localhost:3000/
+ crawl:
+ parallelism: 10
+ delay: 1ms
+ randomDelay: 1ms
+ depth: 10
+ disallowedURLFilters:
+ - http://localhost:8080
+
+ # - name: canary-checker
+ # url: https://canarychecker.io
+ # crawl:
+ # parallelism: 10
+ # delay: 1ms
+ # randomDelay: 1ms
+ # depth: 10
diff --git a/common/snippets/_resource-selector.md b/common/snippets/_resource-selector.md
new file mode 100644
index 00000000..e3536c00
--- /dev/null
+++ b/common/snippets/_resource-selector.md
@@ -0,0 +1,144 @@
+---
+title: Resource Selectors
+sidebar_position: 2
+sidebar_custom_props:
+ icon: stash:search-box-light
+---
+
+# Resource Selectors
+
+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` | No |
+| `name` | Name of the component/config | `string` | No |
+| `namespace` | Select resources in this namespace only, if empty find resources in all namespaces | `string` | No |
+| `types` | Match any of the types specified | `[]string` | No |
+| `statuses` | Match any of the statuses specified | `[]string` | No |
+| `labelSelector` | Kubernetes Style Label Selector | [LabelSelector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) | No |
+| `fieldSelector` | Kubernetes Style Field Selector Property fields of the component in kubernetes format (or database columns: owner, topology_id, parent_id) | [FieldSelector](https://kubernetes.io/docs/concepts/overview/working-with-objects/field-selectors/) | No |
+| `agent` | Select resources created on this agent, Defaults to `local` | `uuid`, `{name}`, `local` or `all` | No |
+| `cache` | Cache settings to use for the results, expensive selectors or selectors that are used often should be cached for longer periods. Defaults to `max-age=10m` | `no-cache`, `no-store` or `max-age={duration}` | No |
+| `search` | Search for resources via key value pairs using parsing expression grammar | `#search` | No |
+
+## Search
+
+The query syntax is `field1=value1 field2>value2 field3=value3* field4=*value4`. `*` is for prefix and suffix matching.
+
+Supported operators:
+
+| Operator | Syntax | Types |
+| -------- | -------------------------------- | --------------------- |
+| `=` | `field=value` | `string` `int` `json` |
+| `!=` | `field!=value` | `string` `int` `json` |
+| `*` | `field=*value` or `field=value*` | `string` `int` |
+| `>` `<` | `field>value` or `fieldnow-24h
+
+ - name: All components updated between a specific interval
+ selectors:
+ - search: updated_at>2024-10-10 updated_at<2024-10-17
+
+ - name: Component with name httpbin-service
+ # Not giving any key will do a name lookup (ie name=httpbin-service)
+ selectors:
+ - search: httpbin-service
+
+ - name: Components with label cluster
+ # JSON lookups are also supported
+ selectors:
+ - search: labels.cluster=prod
+
+ - name: Link configs which have logistics-api image
+ configs:
+ - search: config.spec.template.spec.containers[0].name=docker.io/example/logistics-api:latest
+```
diff --git a/common/snippets/_types.md b/common/snippets/_types.md
new file mode 100644
index 00000000..4b352b76
--- /dev/null
+++ b/common/snippets/_types.md
@@ -0,0 +1,82 @@
+---
+hide_title: true
+title: Common Types
+sidebar_position: 2
+sidebar_custom_props:
+ icon: library
+---
+# Common Types
+
+This document provides a reference for common types used in the configuration and operation of the system.
+
+## Agent
+
+An agent can be specified using:
+
+- `local`: The primary mission control instance.
+- `uuid`: The UUID of an agent.
+- `name`: The name of an agent.
+- `all`: Match all/any agents.
+
+## Cron
+
+```
+# ┌───────────── minute (0–59)
+# │ ┌───────────── hour (0–23)
+# │ │ ┌───────────── day of the month (1–31)
+# │ │ │ ┌───────────── month (1–12)
+# │ │ │ │ ┌───────────── day of the week (0–6) (Sunday to Saturday)
+# │ │ │ │ │
+# │ │ │ │ │
+# │ │ │ │ │
+ 0 * * * *
+```
+
+| Shortcut | Description | Equivalent |
+| ------------------------------ | ---------------------------------------------------------- | ----------- |
+| `@every` [Duration](#duration) | e.g., `@every 5m` | |
+| `@yearly` (or `@annually`) | Run once a year at midnight of 1 January | `0 0 1 1 *` |
+| `@monthly` | Run once a month at midnight of the first day of the month | `0 0 1 * *` |
+| `@weekly` | Run once a week at midnight on Sunday | `0 0 * * 0` |
+| `@daily` (or `@midnight`) | Run once a day at midnight | `0 0 * * *` |
+| `@hourly` | Run once an hour at the beginning of the hour | `0 * * * *` |
+
+## Duration
+
+Valid time units are `s`, `m`, `h`, `d`, `w`, `y`. For example:
+
+- `1m15s`
+- `1h5m`
+- `23h`
+- `1d8h`
+- `1w6d8h`
+- `19w0d8h`
+
+## Size
+
+Sizes are strings with a unit suffix, e.g., `100`, `100b`, `10mb`. Valid size units are `kb`, `mb`, `gb`, `tb`.
+
+## Icon
+
+One of the icons in the [flanksource-icons](https://github.com/flanksource/flanksource-icons/tree/main/svg) project or a URL to an image.
+
+e.g.
+
+- `kubernetes`
+- `Kubernetes::Pod`
+- `argo`
+- `aws-ebs-volume`
+
+Use the picker below to search for icons:
+
+
+
+## Match Pattern
+
+Pattern matching supports the following operations:
+
+- `*` - Match anything
+- `Added,Deleted` - Match either `Added` or `Deleted`
+- `Added*`: Match anything starting with `Added`.
+- `*Terminated`: Match anything ending with `Terminated`.
+- `!PodCrashLooping`: Match everything except `PodCrashLooping`.
diff --git a/common/src/components/Badges.jsx b/common/src/components/Badges.jsx
index f6c52127..1eddfbd5 100644
--- a/common/src/components/Badges.jsx
+++ b/common/src/components/Badges.jsx
@@ -2,7 +2,7 @@ import React from 'react';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import { GoDotFill } from "react-icons/go";
import clsx from 'clsx'
-
+import { CommonLink } from './Link'
export function Health({ color, children }) {
return
- Full Image Variant Required
+ Full Image variant required.
);
}
diff --git a/common/src/components/Fields.jsx b/common/src/components/Fields.jsx
index 2804551b..14f95849 100644
--- a/common/src/components/Fields.jsx
+++ b/common/src/components/Fields.jsx
@@ -1,12 +1,9 @@
import React from 'react'
-import Admonition from '@theme/Admonition'
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'
-import Link from '@docusaurus/Link'
import ReactMarkdown from 'react-markdown'
import useBaseUrl from '@docusaurus/useBaseUrl';
-import clsx from 'clsx'
-const schemes = {
+let schemes = {
envvar: '[EnvVar](/reference/env-var)',
matchpattern: '[MatchPattern](/reference/types#match-pattern)',
'[]envvar': '[[]EnvVar](/reference/env-var)',
@@ -18,6 +15,7 @@ const schemes = {
'[]jsonpathorstring': '`[]string` or [[]JSONPath](https://jsonpath.com/)',
jsonpath: '[JSONPath](https://jsonpath.com/)',
size: '[Size](/reference/types#size)',
+ "[]metric": '[[]Metric](/guides/canary-checker/concepts/metrics#custom-metrics)',
agent: '[Agent](/reference/types#agent)',
resourceselector: '[ResourceSelector](/reference/resource-selector)',
resourceselectors: '[[]ResourceSelector](/reference/resource-selector)',
@@ -33,7 +31,22 @@ const schemes = {
'[map[string]string](/reference/notifications#properties)'
}
-function useSchemeUrl(value) {
+let ossSchemes = {
+ icon: '[Icon](/types#icon)',
+ envvar: '[EnvVar](/concepts/secret-management)',
+ matchpattern: '[MatchPattern](/types#match-pattern)',
+ '[]envvar': '[[]EnvVar](/concepts/secret-management)',
+ cel: '[CEL](/scripting/cel)',
+ javascript: '[Javascript](/scripting/javascript)',
+ gotemplate: '[Go Template](/scripting/gotemplate)',
+ duration: '[Duration](/types#duration)',
+ size: '[Size](/types#size)',
+ "[]metric": '[[]Metric](/concepts/metrics#custom-metrics)',
+ resourceselector: '[ResourceSelector](/resource-selector)',
+ resourceselectors: '[[]ResourceSelector](/resource-selector)',
+}
+
+function useSchemeUrl(value, oss) {
if (value == null) {
return "string"
}
@@ -43,11 +56,20 @@ function useSchemeUrl(value) {
return value;
}
- value = schemes[key]
- if (value == null || !value.includes('](/')) {
+ if (oss) {
+ for (const key of Object.keys(ossSchemes)) {
+ schemes[key] = ossSchemes[key];
+ }
+ }
+
+ let mapping = schemes[value.toLowerCase()]
+
+ if (mapping == null || !mapping.includes('](/')) {
return value
}
+ value = mapping;
+
// Extract link text and URL
const matches = value.match(/\[(.*?)\]\((.*?)\)/);
if (matches) {
@@ -65,12 +87,11 @@ export default function Fields({ common = [], rows = [], oneOf, anyOf, connectio
const oss = siteConfig.customFields.oss;
-
rows = rows.filter(row => row.field != null &&
(row.field != "artifacts" || !oss));
- var fieldSorter = function(a, b) {
+ var fieldSorter = function (a, b) {
if (a.required && !b.required) {
return -1;
}
@@ -423,7 +444,7 @@ export default function Fields({ common = [], rows = [], oneOf, anyOf, connectio
{row.anyOf && {row.anyOf.join(' | ')}}
{!row.anyOf && row.scheme && (
- {useSchemeUrl(row.scheme)}
+ {useSchemeUrl(row.scheme, oss)}
)}
diff --git a/common/src/components/HealthCheck.jsx b/common/src/components/HealthCheck.jsx
index 3fcd84d1..ad0157ba 100644
--- a/common/src/components/HealthCheck.jsx
+++ b/common/src/components/HealthCheck.jsx
@@ -10,6 +10,10 @@ export default function HealthCheck({ name, edition, rows, ...props }) {
const { siteConfig } = useDocusaurusContext()
+ const oss = siteConfig.customFields.oss;
+
+ rows = rows.filter(row => row.field != null &&
+ (row.field != "artifacts" || !oss));
const commonsRows = [
{
@@ -51,7 +55,7 @@ export default function HealthCheck({ name, edition, rows, ...props }) {
{
field: "metrics",
description: "Metrics to export from",
- scheme: "[`[]Metrics`](../concepts/metrics/custom-metrics)"
+ scheme: "[`[]Metrics`](../concepts/metrics)"
}
]
diff --git a/common/src/components/Helm.jsx b/common/src/components/Helm.jsx
index d19a0871..1e46a895 100644
--- a/common/src/components/Helm.jsx
+++ b/common/src/components/Helm.jsx
@@ -55,6 +55,7 @@ export default function Helm({
repoName = "flanksource",
chart = "mission-control",
namespace = "mission-control",
+ mode = "tabs",
createNamespace = true,
createRepo = true,
wait = true,
@@ -70,6 +71,48 @@ export default function Helm({
const [cli, setCli] = useState(generateCli(
repo, repoName, chart, namespace, createNamespace, createRepo, wait, state, valueFile, args))
+
+ var flux =
+ {createNamespace && `apiVersion: v1
+kind: Namespace
+metadata:
+name: ${namespace}
+---
+` || ""}
+ {createRepo && `apiVersion: source.toolkit.fluxcd.io/v1
+kind: HelmRepository
+metadata:
+name: ${repoName}
+namespace: ${namespace}
+spec:
+interval: 5m0s
+url: ${repo}
+---
+` || ""}
+ {`apiVersion: helm.toolkit.fluxcd.io/v2
+kind: HelmRelease
+metadata:
+name: ${chart}
+namespace: ${namespace}
+spec:
+chart:
+spec:
+chart: ${chart}
+sourceRef:
+ kind: HelmRepository
+ name: ${repoName}
+ namespace: ${namespace}
+interval: 1m
+`}
+ {valueFile || values && "values:\n"}
+ {valueFile && valueFile.replace(/^/gm, ' ')}
+ {values && Object.keys(values).map((k) => {
+ return ` ${k}: ${values[k]}\n`
+ }).join("")}
+ ;
+
+
+
return <>
{/* */}
-
-
-
- {cli}
-
-
+ {mode == 'tabs' &&
+
+
+
+ {cli}
+
-
-
- {createNamespace && `apiVersion: v1
-kind: Namespace
-metadata:
- name: ${namespace}
----
-` || ""}
- {createRepo && `apiVersion: source.toolkit.fluxcd.io/v1
-kind: HelmRepository
-metadata:
- name: ${repoName}
- namespace: ${namespace}
-spec:
- interval: 5m0s
- url: ${repo}
----
-` || ""}
- {`apiVersion: helm.toolkit.fluxcd.io/v2
-kind: HelmRelease
-metadata:
- name: ${chart}
- namespace: ${namespace}
-spec:
- chart:
- spec:
- chart: ${chart}
- sourceRef:
- kind: HelmRepository
- name: ${repoName}
- namespace: ${namespace}
- interval: 1m
- `}
- {valueFile || values && "values:\n"}
- {valueFile && valueFile.replace(/^/gm, ' ')}
- {values && Object.keys(values).map((k) => {
- return ` ${k}: ${values[k]}\n`
- }).join("")}
-
-
-
+
+
+
+
+
+ {flux}
+
+
+ }
+
+ {mode == "helm" &&
+
+ {cli}
+
+ }
+
+ {mode == "flux" && flux}
{schema && }
{!schema && (chart == "mission-control" || chart == "mission-control-agent") &&
+
<>See < Link to={`/reference/helm/${chart}`}>values.yaml>
}
diff --git a/common/src/components/Home.jsx b/common/src/components/Home.jsx
index 20a3f064..5c3c2270 100644
--- a/common/src/components/Home.jsx
+++ b/common/src/components/Home.jsx
@@ -147,7 +147,7 @@ function Home() {
subtitle="Integrations"
title="Batteries included with 30+ check types"
image={}
- url="/checks">
+ url="/getting-started">
Canary checker is a single binary with most checks bundled and not requiring an external installation.
@@ -171,7 +171,7 @@ function Home() {
subtitle="Prometheus"
title="Metrics Exporter"
image="metrics-exporter.png"
- url="/concepts/metrics-exporter">
+ url="/concepts/metrics">
Export custom metrics from any check, replacing the need for multiple separate metric exporters.
@@ -180,7 +180,7 @@ function Home() {
title="Grafana"
left={false}
image="grafana-dashboard.png"
- url="/concepts/grafana">
+ url="/concepts/metrics#grafana">
Chose from a standard Grafana dashboard or create your own using the prometheus metrics exposed by Canary Checker.
@@ -226,7 +226,7 @@ function Home() {
image="display-format.png"
- url="/concepts/display-formatting">
+ url="/concepts/expressions/display-formatting">
Evaluate the health of checks using scripts in CEL, Javascript or Go Templating. Templates can also be used to format the output of checks.
@@ -250,7 +250,7 @@ function Home() {
subtitle="Control Plane Monitoring"
title="Active Infrastructure Checks"
image="infrastructure-check.png"
- url="/concepts/scripting">
+ url="https://flanksource.com/docs/blog/infrastructure-testing-with-canary-checker-and-flux">
Proactive infrastructure checks ensure your control plane has ample buffer/ or capacity. These checks validate the ability to schedule new pods, launch EC2 instances, and push/pull to docker and helm repositories.
@@ -267,7 +267,7 @@ function Home() {
left={false}
image="exec-check.png"
- url="/concepts/scripting">
+ url="/scripting">
Evaluate the health of checks using scripts in CEL, Javascript or Go Templating. Templates can also be used to format the output of checks.
)
}
diff --git a/common/src/theme/DocCardList/index.js b/common/src/theme/DocCardList/index.js
index b5aef3f6..25b68d26 100644
--- a/common/src/theme/DocCardList/index.js
+++ b/common/src/theme/DocCardList/index.js
@@ -22,11 +22,14 @@ export default function DocCardList(props) {
return
}
- const filteredItems = filterDocCardListItems(items);
+ const filteredItems = filterDocCardListItems(items).filter(i => !(i.customProps && i.customProps.category));
return (
<>
{props.items.map((item, index) => {
+ if (item.customProps && item.customProps.category) {
+ return null;
+ }
return
})
}
diff --git a/mission-control/Makefile b/mission-control/Makefile
index 583804e9..4cab347f 100644
--- a/mission-control/Makefile
+++ b/mission-control/Makefile
@@ -3,4 +3,6 @@ watch:
.PHONY:
sync:
- git submodule update --init --recursive
+ cd modules && make -b all
+
+
diff --git a/mission-control/blog/control-plane-testing b/mission-control/blog/control-plane-testing
deleted file mode 120000
index 221ee191..00000000
--- a/mission-control/blog/control-plane-testing
+++ /dev/null
@@ -1 +0,0 @@
-../../canary-checker/docs/tutorials/control-plane-testing
\ No newline at end of file
diff --git a/canary-checker/docs/tutorials/control-plane-testing/basic-canary.yaml b/mission-control/blog/control-plane-testing/basic-canary.yaml
similarity index 100%
rename from canary-checker/docs/tutorials/control-plane-testing/basic-canary.yaml
rename to mission-control/blog/control-plane-testing/basic-canary.yaml
diff --git a/canary-checker/docs/tutorials/control-plane-testing/basic-run.svg b/mission-control/blog/control-plane-testing/basic-run.svg
similarity index 100%
rename from canary-checker/docs/tutorials/control-plane-testing/basic-run.svg
rename to mission-control/blog/control-plane-testing/basic-run.svg
diff --git a/canary-checker/docs/tutorials/control-plane-testing/canary-checker.properties b/mission-control/blog/control-plane-testing/canary-checker.properties
similarity index 100%
rename from canary-checker/docs/tutorials/control-plane-testing/canary-checker.properties
rename to mission-control/blog/control-plane-testing/canary-checker.properties
diff --git a/canary-checker/docs/tutorials/control-plane-testing/custom-canary.yaml b/mission-control/blog/control-plane-testing/custom-canary.yaml
similarity index 100%
rename from canary-checker/docs/tutorials/control-plane-testing/custom-canary.yaml
rename to mission-control/blog/control-plane-testing/custom-canary.yaml
diff --git a/canary-checker/docs/tutorials/control-plane-testing/flux.yaml b/mission-control/blog/control-plane-testing/flux.yaml
similarity index 100%
rename from canary-checker/docs/tutorials/control-plane-testing/flux.yaml
rename to mission-control/blog/control-plane-testing/flux.yaml
diff --git a/canary-checker/docs/tutorials/control-plane-testing/index.mdx b/mission-control/blog/control-plane-testing/index.mdx
similarity index 100%
rename from canary-checker/docs/tutorials/control-plane-testing/index.mdx
rename to mission-control/blog/control-plane-testing/index.mdx
diff --git a/canary-checker/docs/tutorials/control-plane-testing/template.yaml b/mission-control/blog/control-plane-testing/template.yaml
similarity index 100%
rename from canary-checker/docs/tutorials/control-plane-testing/template.yaml
rename to mission-control/blog/control-plane-testing/template.yaml
diff --git a/mission-control/docs/guide/config-db/scrapers/aws.md b/mission-control/docs/guide/config-db/scrapers/aws.md
index 6ef98ad4..f2a13a4f 100644
--- a/mission-control/docs/guide/config-db/scrapers/aws.md
+++ b/mission-control/docs/guide/config-db/scrapers/aws.md
@@ -11,7 +11,7 @@ This config type is used to scrape information about your AWS infrastructure.
:::tip Registry
-The registry has an [AWS](/registry/aws) Helm chart that provides a pre-configured Scraper with some common defaults
+The Mission Control Registry includes an [AWS](/integration/aws) Helm chart that provides a pre-configured Scraper with common defaults
:::
diff --git a/mission-control/docs/guide/config-db/scrapers/kubernetes.mdx b/mission-control/docs/guide/config-db/scrapers/kubernetes.mdx
index 5e6cee50..95ac26ab 100644
--- a/mission-control/docs/guide/config-db/scrapers/kubernetes.mdx
+++ b/mission-control/docs/guide/config-db/scrapers/kubernetes.mdx
@@ -8,8 +8,7 @@ sidebar_custom_props:
# Kubernetes
:::tip Helm Chart
-
-See the [Kubernetes](/integrations/kubernetes/catalog) Helm chart that provides a pre-configured Scraper and Topology with some common defaults.
+See the [Kubernetes](/integrations/kubernetes/getting-started) Helm chart that provides a pre-configured Scraper and Topology with some common defaults.
:::
The `kubernetes` scraper collects all of the resources and events in a Kubernetes cluster, and then watches for changes.
@@ -21,7 +20,7 @@ The `kubernetes` scraper collects all of the resources and events in a Kubernete
| Field | Description | Scheme |
| ------------ | ---------------------------------------------------------------------------- | -------------------------------------------- |
| `logLevel` | Specify the level of logging. | `string` |
-| `schedule` | Specify the interval to scrape in cron format. Defaults to every 60 minutes. | `string` |
+| `schedule` | Specify the interval to scrape in cron format. Defaults to every 15 minutes. | `string` |
| `retention` | Settings for retaining changes, analysis and scraped items | [`Retention`](/guide/config-db/concepts/retention) |
| `kubernetes` | Specifies the list of Kubernetes configurations to scrape. | [`[]Kubernetes`](#kubernetes) |
@@ -40,18 +39,7 @@ The `kubernetes` scraper collects all of the resources and events in a Kubernete
description: 'Include resources only from this namespace',
scheme: 'string'
},
- {
- field: 'useCache',
- description:
- 'Whether to use cache or not when fetching resources. Default: false',
- scheme: 'bool'
- },
- {
- field: 'allowIncomplete',
- description:
- "whether to fail scrape if all api resources weren't fetched successfully",
- scheme: 'bool'
- },
+
{
field: 'scope',
description:
@@ -75,12 +63,6 @@ The `kubernetes` scraper collects all of the resources and events in a Kubernete
description: 'Resources to be included e.g `status.Phase=Running`',
scheme: 'string'
},
- {
- field: 'maxInflight',
- description:
- 'Concurrency level when resources are fetched one at a time.`',
- scheme: 'int'
- },
{
field: 'kubeconfig',
description: 'Kubeconfig to connect to the cluster',
@@ -88,7 +70,7 @@ The `kubernetes` scraper collects all of the resources and events in a Kubernete
},
{
field: 'watch',
- description: 'Kubeconfig to connect to the cluster',
+ description: 'List of resources to watch for real-time changes',
scheme: '[`[]WatchSelector`]()'
},
{
@@ -111,7 +93,26 @@ The `kubernetes` scraper collects all of the resources and events in a Kubernete
### Event
-`Kubernetes::Event` resources are mapped to config changes. Events can be very verbose so they can be excluded or their severity level changed:
+`Kubernetes::Event` resources are mapped to config changes. Events can be verbose so they can be excluded or their severity level changed:
+
+
+```yaml
+spec:
+ kubernetes:
+ - event:
+ exclusions:
+ reason:
+ - SuccessfulCreate
+ - Created
+ - DNSConfigForming
+ severityKeywords:
+ error:
+ - failed
+ - error
+ warn:
+ - backoff
+ - nodeoutofmemory
+```
| Field | Description | Scheme | Required |
| ------------------ | ------------------------------------------------------------------------------------------ | --------------------------------------- | -------- |
@@ -132,6 +133,8 @@ This allows near-real-time updates to your kubernetes catalogs with the flexibil
This feature is enabled by default but can be disabled by setting the property `watch.disable=true`.
+Kubernetes events automatically trigger a re-scrape of involved objects, so even though not all resources are watched by default, the vast majority of changes still reflect in real-time due to associated events that fire at the same time as the update.
+
#### Watch Selector
```yaml title="custom-watch-resources.yaml"
@@ -397,3 +400,13 @@ spec:
## Performance
+The scraper is highly reliant on the performance of the Kubernetes API server, and as such, it is recommended to run the scraper from within the cluster or as close as possible to the control pane.
+
+
+:::warning Overloading the API Server
+It is possible to overload the API server with too many requests, to reduce the load on the API Server:
+
+* Decentralize the scraper by running it on an agent, from-inside each cluster rather than remotely.
+* Increase the `schedule` to `1h` or more, real-time updates still be recorded by Kubernetes events and informers.
+* Filter out and exclude resources and events that have a high churn or verbosity
+
diff --git a/mission-control/docs/guide/config-db/tutorials/index.mdx b/mission-control/docs/guide/config-db/tutorials/index.mdx
index 093f1df0..7cfc0b8d 100644
--- a/mission-control/docs/guide/config-db/tutorials/index.mdx
+++ b/mission-control/docs/guide/config-db/tutorials/index.mdx
@@ -1,5 +1,5 @@
---
title: Tutorials
sidebar_custom_props:
- icon: stash:graduation-cap-light
+ icon: learning
---
diff --git a/mission-control/docs/guide/permissions/index.mdx b/mission-control/docs/guide/permissions/index.mdx
index 02224aca..7c5cc5b0 100644
--- a/mission-control/docs/guide/permissions/index.mdx
+++ b/mission-control/docs/guide/permissions/index.mdx
@@ -6,15 +6,15 @@ hide_title: true
# hide_table_of_contents: true
pagination_prev: guide/topology/index
sidebar_custom_props:
- icon: user
+ icon: shield-user
---
## Permission
In Mission Control, Permission provides a flexible and robust security model that combines two powerful approaches:
-Role-Based Access Control (RBAC) and Attribute-Based Access Control (ABAC).
+Role-Based Access Control (RBAC) and Attribute-Based Access Control (ABAC).
This unified permission system allows you to implement precise and granular access policies.
-For instance, while RBAC can control whether a user can execute any playbooks in the system,
+For instance, while RBAC can control whether a user can execute any playbooks in the system,
more refined ABAC policies allow you to specify exactly which playbooks specific users or teams can access.
Permissions are manageable via the UI as well as via CRDs.
@@ -138,4 +138,4 @@ Permissions applied to the group are then inherited by the encompassed subjects.
scheme: '`[]string`',
},
]}
-/>
\ No newline at end of file
+/>
diff --git a/mission-control/docs/guide/playbooks/actions/exec.mdx b/mission-control/docs/guide/playbooks/actions/exec.mdx
index e515eb6d..aee1ae6b 100644
--- a/mission-control/docs/guide/playbooks/actions/exec.mdx
+++ b/mission-control/docs/guide/playbooks/actions/exec.mdx
@@ -35,6 +35,18 @@ exec:
script: kubectl rollout release deployment -n $(.config.tags.namespace) $(.conf
```
+## Shell Language
+
+Use a shebang (`#!`) line to choose a different shell (`python`, `bash` and `pwsh` are included in the base image)
+
+```yaml
+exec:
+ script: |
+ //highlight-next-line
+ #! pwsh
+ Get-Items | ConvertTo-JSON
+```
+
diff --git a/mission-control/docs/guide/playbooks/actions/gitops.mdx b/mission-control/docs/guide/playbooks/actions/gitops.mdx
index 44d41038..d74e3a55 100644
--- a/mission-control/docs/guide/playbooks/actions/gitops.mdx
+++ b/mission-control/docs/guide/playbooks/actions/gitops.mdx
@@ -9,51 +9,18 @@ import Templating from '@site/docs/reference/playbooks/context.mdx'
# GitOps Action
-GitOps action allows you to make commits and push to a remote repository.
+The GitOps action creates commits and pushes changes to a git repository.
-```yaml title="edit-kubernetes-manifests-gitops.yaml"
-apiVersion: mission-control.flanksource.com/v1
-kind: Playbook
-metadata:
- name: edit-kubernetes-manifests-gitops
-spec:
- title: 'Edit Kustomize Resource'
- icon: 'flux'
- parameters:
- - default: 'chore: update $(.config.type)/$(.config.name)'
- label: 'Commit Message'
- name: 'commit_message'
- - default: '$(.config.config | toJSON | neat | json | toYAML)'
- label: 'Changes'
- name: 'yamlInput'
- properties:
- size: 'large'
- type: 'code'
- configs:
- - labelSelector: 'kustomize.toolkit.fluxcd.io/name'
- actions:
- - name: 'Create Pull Request With Changes'
- gitops:
- repo:
- url: 'https://github.com/flanksource/flux'
- connection: 'connection://default/github'
- base: 'main'
- branch: 'edit-manifest-$(random.Alpha 8)'
- commit:
- author: '$(.user.name)'
- email: '$(.user.email)'
- message: '$(.params.commit_message)'
- pr:
- title: '$(.params.commit_message)'
- patches:
- - path: 'prod/kustomization.yaml'
- yq: |
- select(
- .kind=="$(.config.config | jq `.kind`)" and
- .metadata.name=="$(.config.config | jq `.metadata.name`)"
- ) |= $(.params.yamlInput | yaml | toJSON)
+Common use cases:
+
+* Enable developers to provision and manage Infrastructure as Code through a GUI interface, while DevOps and Platform engineers maintain their preferred tooling workflow
+* Implement guardrail-driven access for developers to make infrastructure changes
+* Use native support for Flux and Kustomization to automatically identify git repositories and files using `originAnnotations`
+
+```yaml title="edit-kubernetes-manifests-gitops.yaml" file=/modules/generated/playbooks/kustomize-edit.yaml
```
+
+These env vars are extracted by traversing up the Flux Kustomization and Git Repository that created the config resource the playbook runs against.
-These env vars are extracted by traversing up the Flux Kustomization and Git Repository that created the config resource the playbook is running against. We'll see this in detail shortly.
-
-To tag all the resources with that annotation, you'll need to add `originAnnotations` to the buildMetadata field as shown below:
+To tag all the resources with that annotation, add `originAnnotations` to the `buildMetadata` field as shown below:
diff --git a/mission-control/docs/guide/playbooks/concepts/expression.md b/mission-control/docs/guide/playbooks/concepts/expression.md
deleted file mode 100644
index 8dcb6dac..00000000
--- a/mission-control/docs/guide/playbooks/concepts/expression.md
+++ /dev/null
@@ -1,73 +0,0 @@
----
-title: Expressions
-sidebar_custom_props:
- icon: hugeicons:code
----
-
-Playbook event filters use [Common Expression Language (CEL)](https://github.com/google/cel-go).
-
-> The Common Expression Language (CEL) is a non-Turing complete language designed for simplicity, speed, safety, and portability. CEL's C-like syntax looks nearly identical to equivalent expressions in C++, Go, Java, and TypeScript.
-
-**Examples:**
-
-```yaml title="notify-with-filter.yaml"
----
-apiVersion: mission-control.flanksource.com/v1
-kind: Playbook
-metadata:
- name: notify-with-filter
-spec:
- on:
- config:
- - event: created
- configs:
- - type: Kubernetes::Pod
- actions:
- - name: Send notification
- exec:
- script: notify-send "{{.config.name}} was created"
- - name: Bad script to create a failing action
- exec:
- script: non-existing-command
- - name: Send all success notification
- if: success() # this filter practically skips this action as the second action above always fails
- exec:
- script: notify-send "Everything went successfully"
- - name: Send notification regardless
- if: always()
- exec:
- 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`](/reference/config-db) |
-| `.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/guide/playbooks/concepts/expression.mdx b/mission-control/docs/guide/playbooks/concepts/expression.mdx
new file mode 100644
index 00000000..1609b808
--- /dev/null
+++ b/mission-control/docs/guide/playbooks/concepts/expression.mdx
@@ -0,0 +1,108 @@
+---
+title: Expressions
+sidebar_custom_props:
+ icon: hugeicons:code
+---
+
+Playbook event filters use [Common Expression Language (CEL)](https://github.com/google/cel-go).
+
+> The Common Expression Language (CEL) is a non-Turing complete language designed for simplicity, speed, safety, and portability. CEL's C-like syntax is similar to expressions in C++, Go, Java, and TypeScript.
+
+**Examples:**
+
+```yaml title="notify-with-filter.yaml"
+---
+apiVersion: mission-control.flanksource.com/v1
+kind: Playbook
+metadata:
+ name: notify-with-filter
+spec:
+ on:
+ config:
+ - event: created
+ configs:
+ - type: Kubernetes::Pod
+ actions:
+ - name: Send notification
+ exec:
+ script: notify-send "{{.config.name}} was created"
+ - name: Bad script to create a failing action
+ exec:
+ script: non-existing-command
+ - name: Send all success notification
+ if: success() # this filter practically skips this action as the second action above always fails
+ exec:
+ script: notify-send "Everything went successfully"
+ - name: Send notification regardless
+ if: always()
+ exec:
+ script: notify-send "a config was created"
+```
+
+## Conditionally running actions
+
+Playbook actions can be conditionally executed using CEL expressions. These expressions must return a `bool` value (return `false` to skip the action).
+
+Expressions support the following functions in addition to the standard CEL functions.
+
+| Function | Description |
+| ----------- | ----------------------------------------------------------- |
+| `always()` | Execute regardless of playbook state (cancelled/failed) |
+| `failure()` | Execute if any previous actions failed |
+| `skip()` | Skip execution of this action |
+| `success()` | Execute only if all previous actions succeeded (default) |
+| `timeout()` | Execute only if any 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` | Configuration object passed to the playbook | [`ConfigItem`](/reference/config-db) |
+| `component` | Component object passed to the playbook | [`Component`](/reference/topology/components) |
+| `check` | Canary Check object passed to the playbook | [`Check`](/reference/canary-checker/check) |
+| `params` | User-provided parameters for the playbook | `map[string]string` |
+| `user.id` | Unique identifier of the user who triggered the action | `string` |
+| `user.name` | Full name of the user who triggered the action | `string` |
+| `user.email` | Email address of the user who triggered the action | `string` |
+| `action.name` | Name of the current action | `string` |
+| `action.status` | Current status of the action (`scheduled`, `running`, `succeeded`, `failed`, `skipped`, or `cancelled`) | `string` |
+| `action.scheduled_time` | Timestamp when the action was scheduled | `string` |
+| `action.start_time` | Timestamp when the action execution began | `string` |
+
+For playbooks triggered via webhooks, the following additional fields are available:
+
diff --git a/mission-control/docs/guide/playbooks/examples/index.mdx b/mission-control/docs/guide/playbooks/examples/index.mdx
index c7d888eb..65f025d3 100644
--- a/mission-control/docs/guide/playbooks/examples/index.mdx
+++ b/mission-control/docs/guide/playbooks/examples/index.mdx
@@ -2,7 +2,7 @@
sidebar_position: 7
title: Examples
sidebar_custom_props:
- icon: stash:graduation-cap-light
+ icon: learning
---
diff --git a/mission-control/docs/guide/topology/examples/index.mdx b/mission-control/docs/guide/topology/examples/index.mdx
index 1209a27e..b169d831 100644
--- a/mission-control/docs/guide/topology/examples/index.mdx
+++ b/mission-control/docs/guide/topology/examples/index.mdx
@@ -1,6 +1,8 @@
---
sidebar_position: 100
title: Examples
+sidebar_custom_props:
+ icon: learning
---
diff --git a/mission-control/docs/guide/topology/lookups/index.mdx b/mission-control/docs/guide/topology/lookups/index.mdx
index 636dccb3..33716516 100644
--- a/mission-control/docs/guide/topology/lookups/index.mdx
+++ b/mission-control/docs/guide/topology/lookups/index.mdx
@@ -1,6 +1,8 @@
---
title: Lookups
sidebar_position: 3
+sidebar_custom_props:
+ icon: database-search-o
---
diff --git a/mission-control/docs/installation/_aws_iam.mdx b/mission-control/docs/installation/_aws_iam.mdx
index 2d97baf2..17bbd5ab 100644
--- a/mission-control/docs/installation/_aws_iam.mdx
+++ b/mission-control/docs/installation/_aws_iam.mdx
@@ -12,7 +12,7 @@ Depending on how you want to use Mission Control you need to create an IAM role
-You can also create a new policy with just the permissions required by Mission Control
+You can also create a new policy with only the permissions required by Mission Control
```json title="iam-policy.json"
{
diff --git a/mission-control/docs/installation/local-testing.md b/mission-control/docs/installation/local-testing.md
index 08f2a626..c5d7145f 100644
--- a/mission-control/docs/installation/local-testing.md
+++ b/mission-control/docs/installation/local-testing.md
@@ -1,6 +1,8 @@
---
title: Local Testing
description: Run Mission Control Locally using minikube or kind
+sidebar_custom_props:
+ icon: lab
---
import Tabs from '@theme/Tabs';
@@ -101,14 +103,14 @@ minikube addons enable ingress
-[nip.io](http://nip.io) is simple wildcard DNS server that returns the ip provided in the host name, e.g.
+[nip.io](http://nip.io) is a wildcard DNS server that returns the ip provided in the host name, e.g.
```bash
❯ nslookup 127.0.0.1.nip.io
Address: 127.0.0.1
```
-By using nip you will be able to access mission-control without any further networking / configuration setup.
+By using nip you can access mission-control without any further networking / configuration setup.
```yaml title="values.yaml"
global:
@@ -155,7 +157,7 @@ See [values.yaml](/installation/helm#self-hosted) for more options.
-The default username is `admin@local` and the password can be retrived with:
+The default username is `admin@local` and the password can be retrieved with:
```
kubectl get secret mission-control-admin-password \
@@ -166,7 +168,7 @@ kubectl get secret mission-control-admin-password \
You can then goto [https://127.0.0.1.nip.io:8443](https://127.0.0.1.nip.io:8443) to login.
:::info Self-Signed Certificate
-This example uses a self-signed certificate created by Nginx, We recommend using [cert-manager.io](https://cert-manager.io/).
+This example uses a self-signed certificate created by nginx, We recommend using [cert-manager.io](https://cert-manager.io/).
:::
@@ -193,6 +195,6 @@ and apply to the cluster with:
kubectl apply -f canaries.yaml
```
-When you goto the [Health](https://127.0.0.1.nip.io:8443/health) tab you can then see the check running:
+Navigate to the [Health](https://127.0.0.1.nip.io:8443/health) tab you can then see the check running:
diff --git a/mission-control/docs/installation/saas/agent.mdx b/mission-control/docs/installation/saas/agent.mdx
index cde39f37..8085c071 100644
--- a/mission-control/docs/installation/saas/agent.mdx
+++ b/mission-control/docs/installation/saas/agent.mdx
@@ -1,7 +1,12 @@
---
title: Agent Installation
+sidebar_custom_props:
+ icon: server
---
+import ReactMarkdown from 'react-markdown'
+import Link from '@docusaurus/Link';
+
:::info Prerequisites
To install and run the Mission Control agent you need to have the following prerequisites:
@@ -19,13 +24,16 @@ import OpenAPI from '@site/src/components/OpenAPI'
The recommended way of installing an agent is generating the Helm/Flux install script on the UI:
+
+
-1. Navigate to **Settings** --> **Agents**
-2. Click on the button
+
+1. Navigate to {props.saas && app.flanksource.com/settings/agents}{!props.saas && <>Settings → Agents>}
- Enter the following:
+
+2. Click on the button, and enter in the dialog:
* **clusterName**
- * Toggle **Kubernetes** to automatically scrape the cluster the agent is installed in, you can skip this step and perform it later by installing the [chart](/integrations/kubernets/catalog)
+ * Toggle **Kubernetes** to automatically scrape the cluster the agent is installed in, you can skip this step and perform it later by installing the [chart](/integrations/kubernetes/catalog)
3. Click **Next**
@@ -33,12 +41,11 @@ The recommended way of installing an agent is generating the Helm/Flux install s
-4. Alternatively if you are installing the agent in multiple locations you can reuse the same token generated
-
-
-
+
+",
"upstream.agent": "YOUR_LOCAL_NAME",
@@ -48,37 +55,53 @@ The recommended way of installing an agent is generating the Helm/Flux install s
}}
/>
+
+
+ ",
+ "upstream.agent": "YOUR_LOCAL_NAME",
+ "upstream.username": "token",
+ "upstream.password": "",
+ "upstream.host": ""
+ }}
+
+ />
+
+
-:::info Externalize the token
-We recommend that the upstream token be stored separately and encrypted using sops or similar
-1. Create a new secret called `mission-control-upstream`
- title=secret.yaml
- apiVersion: v1
- kind: Secret
- metadata:
- name: upstream
- stringData:
- UPSTREAM_HOST: ""
- UPSTREAM_USER: token
- UPSTREAM_PASSWORD: ""
- AGENT_NAME: "YOUR_LOCAL_NAME"
+
+:::info Encrypting the Token
+ We recommend that the upstream token be stored and encrypted using sops or similar
+1. Create a new secret called `mission-control-upstream`:
+ ```yaml title=secret.yaml
+ apiVersion: v1
+ kind: Secret
+ metadata:
+ name: mission-control-upstream
+ stringData:
+ UPSTREAM_HOST: ""
+ UPSTREAM_USER: token
+ UPSTREAM_PASSWORD: ""
+ AGENT_NAME: "YOUR_LOCAL_NAME"
+ ```
2. Update the chart values:
- title=values.yaml
+
+ ```yaml title=values.yaml
upstream:
createSecret: false
secretName: mission-control-upstream
+ ```
:::
-
-### values.yaml
-
-
diff --git a/mission-control/docs/installation/saas/eks.mdx b/mission-control/docs/installation/saas/eks.mdx
index 215bbedb..d92041f5 100644
--- a/mission-control/docs/installation/saas/eks.mdx
+++ b/mission-control/docs/installation/saas/eks.mdx
@@ -1,6 +1,8 @@
---
title: AWS EKS
slug: installation/eks
+sidebar_custom_props:
+ icon: aws-eks-cluster
---
import Tabs from '@theme/Tabs'
@@ -28,6 +30,19 @@ To install and run Mission Control you need to have the following prerequisites:
}}
/>
+
## Next Steps
-Install the [AWS](/registry/aws) registry chart to configure the AWS Scraper
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mission-control/docs/installation/saas/fully-hosted.mdx b/mission-control/docs/installation/saas/fully-hosted.mdx
deleted file mode 100644
index e69de29b..00000000
diff --git a/mission-control/docs/installation/saas/getting-started.mdx b/mission-control/docs/installation/saas/getting-started.mdx
index 1734a2ce..0985f610 100644
--- a/mission-control/docs/installation/saas/getting-started.mdx
+++ b/mission-control/docs/installation/saas/getting-started.mdx
@@ -7,30 +7,13 @@ sidebar_custom_props:
---
+import Agent from './agent.mdx'
import AgentToken from '@site/docs/partials/_agent_token.mdx'
-export const toc = [{
- value: "Signup",
- id: "signup",
- level: 2,
- },
- {
- value: "Agent Installation",
- id: "agent-installation",
- level: 2,
- },
-
- {
- value: "Technology Bundles",
- id: "registry",
- level: 2,
- }
-
-]
When using the Mission Control SaaS the agent based approach is recommended for ingesting data, The agent is headless installation of mission-control that caches data locally in a postgres database and replicates it to the SaaS.
-
+
The agent based approach has the following benefits:
@@ -53,10 +36,12 @@ See [Installation](/installation) for other deployment models including [Self Ho
Organization details and members can be changed by going to [accounts.flanksource.com/organization](https://accounts.flanksource.com/organization) or Clicking on **Manage Organization** when logged in
:::
-4. Install an Agent
-## Agent Installation
+### Agent Installation
+Next an agent needs to deployed to scrape resources and execute playbooks:
+
+
diff --git a/mission-control/docs/installation/self-hosted/database.md b/mission-control/docs/installation/self-hosted/database.md
index b871bf77..6b2ec960 100644
--- a/mission-control/docs/installation/self-hosted/database.md
+++ b/mission-control/docs/installation/self-hosted/database.md
@@ -1,6 +1,8 @@
---
title: Database
description: Alternative methods for connecting to the db used for persistence
+sidebar_custom_props:
+ icon: postgres
---
Mission Control stores all state in a Postgres Database, by default a Postgres StatefulSet is created.
diff --git a/mission-control/docs/installation/self-hosted/eks.mdx b/mission-control/docs/installation/self-hosted/eks.mdx
index 91453258..5401f266 100644
--- a/mission-control/docs/installation/self-hosted/eks.mdx
+++ b/mission-control/docs/installation/self-hosted/eks.mdx
@@ -1,5 +1,7 @@
---
title: AWS EKS
+sidebar_custom_props:
+ icon: aws-eks-cluster
---
import AwsIam from "../_aws_iam.mdx"
@@ -23,7 +25,20 @@ To install and run a self-hosted Mission Control on AWS EKS you need to have the
}}/>
-
## Next Steps
-Install the [AWS](/registry/aws) registry chart to configure the AWS Scraper
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mission-control/docs/installation/self-hosted/getting-started.mdx b/mission-control/docs/installation/self-hosted/getting-started.mdx
index eb47a40d..73f7886e 100644
--- a/mission-control/docs/installation/self-hosted/getting-started.mdx
+++ b/mission-control/docs/installation/self-hosted/getting-started.mdx
@@ -3,74 +3,55 @@ title: Getting Started
show_title: true
sidebar_custom_props:
icon: getting-started
-
+pagination_next: installation/self-hosted/database
sidebar_position: 0
---
-
import AdminPassword from '@site/docs/partials/_admin-password.mdx'
import Helm from "@site/src/components/Helm"
-export const toc = [
- {
- value: 'Prerequisites',
- id: 'prerequisites',
- level: 2
- },
- {
- value: 'Step 1: Install Helm Repository',
- id: 'step-1-install-helm-repository',
- level: 2
- },
- {
- value: 'Step 2: Install Helm Chart',
- id: 'helm-chart',
- level: 2
- },
- {
- value: 'Cert Manager',
- id: 'cert-manager',
- level: 3
- },
- {
- value: 'Optional Steps',
- id: 'optional-steps',
- level: 2
- },
- {
- value: 'Step 3: Configure Email (SMTP)',
- id: 'smtp',
- level: 3
- },
- {
- value: 'Step 4: Single Sign On',
- id: 'sso',
- level: 3
- },
- {
- value: 'Step 5: External Database',
- id: '-database',
- level: 3
- }
-]
-
-
-
-This tutorial guides you through setting up and configuring a self-hosted Mission Control environment.
+
+Mission Control is an internal developer platform built for operations. Built with a "self-hosted first" approach, Mission Control gives you complete control over your deployment environment while offering enterprise-grade features.
+
+## Self-Hosted Deployment
+
+When you self-host Mission Control, you maintain full ownership of your infrastructure and data while enjoying the same robust feature set available in the SaaS offering. In fact, some advanced features are exclusively available in the self-hosted version.
+
+
+
+### Why Self-Host Mission Control?
+
+**Key Benefits**
+- **Infrastructure Flexibility**: Deploy on your preferred infrastructure - whether on-premise, AWS, GCP, Azure, or any other Kubernetes environment
+- **Data Sovereignty**: Keep all your monitoring and operational data within your own environment
+- **Security Control**: Leverage your existing security practices and compliance frameworks
+- **Cost Efficiency**: Optimize resource allocation and scaling based on your specific needs
+- **Customization**: Tailor the platform to integrate with your specific infrastructure components
+
+**Implementation Considerations**
+- Configuration and management of authentication (SSO) is required
+- Database management responsibilities remain with your team
+- Updates and maintenance follow standard Kubernetes patterns
+
+
+
+
+This guide walks you through the complete setup process for your self-hosted Mission Control environment.
+
:::info Prerequisites
To install and run Mission Control you need the following:
- Kubernetes 1.26+ with an Ingress Controller
- [cert-manager.io](https://cert-manager.io/docs/) or an existing TLS secret for ingress
-- 1 - 2 CPUs and 6-8GB of Memory (2-4GB if using an external DB)
+- 1 - 2 CPU's and 6-8GB of Memory (2-4GB if using an external DB)
- Persistent Volumes with 20GB+ of storage or an external postgres database
- (Optional) [prometheus operator](https://prometheus-operator.dev/)
- (Optional) SMTP Server (For sending notifications and invites)
:::
----
1. Choose a routable `DOMAIN` for Mission Control
+
> See [Ingress](/reference/helm/mission-control#ingress) for more options on configuring the ingress including generating certs with cert-manager
>
See [Local Testing](../local-testing) for testing using a kind or minikube without a routable domain