From b493056ae6f3650597bf701e1e53e44415b78ae1 Mon Sep 17 00:00:00 2001 From: Daniel Gonzalez Date: Tue, 5 Dec 2023 11:52:56 -0600 Subject: [PATCH 1/7] feat(orca-spe): included docs for SPE calculator Plugin --- .../_index.md | 53 +++++++++++++++ .../api.md | 67 +++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 content/en/plugins/orca-successful-pipeline-calculator/_index.md create mode 100644 content/en/plugins/orca-successful-pipeline-calculator/api.md diff --git a/content/en/plugins/orca-successful-pipeline-calculator/_index.md b/content/en/plugins/orca-successful-pipeline-calculator/_index.md new file mode 100644 index 0000000000..afdb144aac --- /dev/null +++ b/content/en/plugins/orca-successful-pipeline-calculator/_index.md @@ -0,0 +1,53 @@ +--- +title: Orca-Successful-Pipeline-Calculator +linkTitle: Pipelines-as-Code +description: > + Armory SPE Calculator automates the aggregation of Successful Pipeline count by day and makes the information available to query and visualize through an API +no_list: true +--- + +![Proprietary](/images/proprietary.svg) [![Generally available](/images/ga.svg)]({{< ref "release-definitions#ga" >}}) + +## Requirements +- [Orca configured with SQL backing](https://docs.armory.io/continuous-deployment/armory-admin/orca-sql-configure/) + +## Installation With Spinnaker Operator +Create `insights-plugin.yml` with the following contents: +```yaml +apiVersion: spinnaker.io/v1alpha2 +kind: SpinnakerService +metadata: + name: spinnaker +spec: + spinnakerConfig: + profiles: + spinnaker: + insights: + jobs: + pipelineStatusCount: + cron: '1 1 1 * * *' + fetch: + limit: 1000 + spinnaker: + extensibility: + repositories: + repository: + enabled: true + url: https://raw.githubusercontent.com/armory-plugins/pluginRepository/master/repositories.json + orca: + spinnaker: + extensibility: + plugins: + Armory.Insights: + version: + enabled: true + extensions: + armory.insights: + enabled: true +``` +- `version`: Replace `` with the plugin version compatible with your Spinnaker version. +- `insights.jobs.pipelinStatusCount.cron`: Replace with a cron expression that corresponds to the time of the day with lowest load. It can be disabled by using `-` as an expression. +- `insights.jobs.pipelineStatusCount.fetch.limit`: Indicates how many records are read at a time from `orca.pipelines`, adjust based on performance (Defaults to 1000). + +### [API Usage]({{< linkWithTitle "plugins/orca-successful-pipeline-calculator/usage/api.md" >}}) + diff --git a/content/en/plugins/orca-successful-pipeline-calculator/api.md b/content/en/plugins/orca-successful-pipeline-calculator/api.md new file mode 100644 index 0000000000..d8c8460fe7 --- /dev/null +++ b/content/en/plugins/orca-successful-pipeline-calculator/api.md @@ -0,0 +1,67 @@ +--- +title: Armory SPE Calculator API Usage +linkTitle: API Usage +weight: 10 +description: > + Learn how to retrieve SPE count using the REST API +--- + +## {{% heading "prereq" %}} + +* You have installed the [Orca SPE Calculator Plugin]({{< ref "/plugins/orca-successful-pipeline-calculator" >}}}) +* You're able to call Orca's endpoint service endpoint (by default `http://spin-orca:8083`) + +### Path +`/insights/pipelines/statuses/count` + +| Parameter | Type | Description | Optional | Default Value | +|-----------|-----------------------|----------------------------------|----------|---------------| +| from | Date (yyyy-MM-dd) | Starting Date | Yes | 30 days ago | +| to | Date (yyyy-MM-dd) | End Date | Yes | Today | +| limit | Number | Max Number of results | Yes | 1000 | +| offsetId | Number | Starting Id (Exclusive) | Yes | nil | +| descOrder | Boolean | Sort results in descending order | Yes | false | +| status | SUCCEEDED \| TERMINAL | Status of the aggregate | Yes | SUCCEEDED | + +### Response +## JSON Structure Documentation + +### Root Object +| Field | Type | Description | +|---------|--------|--------------------------------------| +| records | Array | Array of record objects | +| limit | Number | Limit on the number of records | +| count | Number | Total number of records | +| from | String | Start date for the record collection | +| to | String | End date for the record collection | + +### Record Object +Each object in the `records` array has the following structure: + +| Field | Type | Description | +|--------|--------|---------------------------------------------------------| +| id | Number | Unique identifier of the record | +| status | String | Status of the record (e.g., "SUCCEEDED") | +| date | Number | Date of the record in milliseconds since epoch | +| count | Number | Count associated with the record | +| day | String | The day corresponding to the record (yyyy-MM-dd format) | + +## Example + +```json +{ + "records": [ + { + "id": [id], + "status": "[status]", + "date": [UNIX milliseconds], + "count": [count], + "day": "yyyy-MM-dd" + }, + ... + ], + "limit": [limit], + "count": [count], + "from": "yyyy-MM-dd", + "to": "yyyy-MM-dd" +} From b856d9adc4cb9bb911b2913b4af86c638ab79b14 Mon Sep 17 00:00:00 2001 From: Daniel Gonzalez Date: Tue, 5 Dec 2023 11:55:55 -0600 Subject: [PATCH 2/7] fixed reference path --- .../en/plugins/orca-successful-pipeline-calculator/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/plugins/orca-successful-pipeline-calculator/_index.md b/content/en/plugins/orca-successful-pipeline-calculator/_index.md index afdb144aac..17b1d5a158 100644 --- a/content/en/plugins/orca-successful-pipeline-calculator/_index.md +++ b/content/en/plugins/orca-successful-pipeline-calculator/_index.md @@ -49,5 +49,5 @@ spec: - `insights.jobs.pipelinStatusCount.cron`: Replace with a cron expression that corresponds to the time of the day with lowest load. It can be disabled by using `-` as an expression. - `insights.jobs.pipelineStatusCount.fetch.limit`: Indicates how many records are read at a time from `orca.pipelines`, adjust based on performance (Defaults to 1000). -### [API Usage]({{< linkWithTitle "plugins/orca-successful-pipeline-calculator/usage/api.md" >}}) +### [API Usage]({{< linkWithTitle "plugins/orca-successful-pipeline-calculator/api.md" >}}) From 5cdd9d1f5bfbfd6397c54be7013d221ff1c82eb1 Mon Sep 17 00:00:00 2001 From: Daniel Gonzalez Date: Tue, 5 Dec 2023 11:58:58 -0600 Subject: [PATCH 3/7] fixed link title --- .../en/plugins/orca-successful-pipeline-calculator/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/plugins/orca-successful-pipeline-calculator/_index.md b/content/en/plugins/orca-successful-pipeline-calculator/_index.md index 17b1d5a158..3d8adaeda0 100644 --- a/content/en/plugins/orca-successful-pipeline-calculator/_index.md +++ b/content/en/plugins/orca-successful-pipeline-calculator/_index.md @@ -1,6 +1,6 @@ --- title: Orca-Successful-Pipeline-Calculator -linkTitle: Pipelines-as-Code +linkTitle: Orca Successful Pipeline Calculator description: > Armory SPE Calculator automates the aggregation of Successful Pipeline count by day and makes the information available to query and visualize through an API no_list: true From 6b4f04b3de07b3ded14b37d41a5e92e1b6d92d32 Mon Sep 17 00:00:00 2001 From: Daniel Gonzalez Date: Tue, 5 Dec 2023 13:10:27 -0600 Subject: [PATCH 4/7] fixed a few things --- .../plugins/orca-successful-pipeline-calculator/_index.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/content/en/plugins/orca-successful-pipeline-calculator/_index.md b/content/en/plugins/orca-successful-pipeline-calculator/_index.md index 3d8adaeda0..1bbdad479a 100644 --- a/content/en/plugins/orca-successful-pipeline-calculator/_index.md +++ b/content/en/plugins/orca-successful-pipeline-calculator/_index.md @@ -25,9 +25,7 @@ spec: insights: jobs: pipelineStatusCount: - cron: '1 1 1 * * *' - fetch: - limit: 1000 + cron: '1 1 1 * * *' spinnaker: extensibility: repositories: @@ -47,7 +45,6 @@ spec: ``` - `version`: Replace `` with the plugin version compatible with your Spinnaker version. - `insights.jobs.pipelinStatusCount.cron`: Replace with a cron expression that corresponds to the time of the day with lowest load. It can be disabled by using `-` as an expression. -- `insights.jobs.pipelineStatusCount.fetch.limit`: Indicates how many records are read at a time from `orca.pipelines`, adjust based on performance (Defaults to 1000). -### [API Usage]({{< linkWithTitle "plugins/orca-successful-pipeline-calculator/api.md" >}}) +### {{< linkWithTitle "plugins/orca-successful-pipeline-calculator/api.md" >}} From 78616f9265eef389aa6278bbc51a030908f54bd2 Mon Sep 17 00:00:00 2001 From: Aimee Ukasick Date: Thu, 7 Dec 2023 12:18:01 -0600 Subject: [PATCH 5/7] change plugin name to Armory Insights; merge files; add compat matrix --- .../includes/plugins/plugin-compat-matrix.md | 1 + content/en/plugins/armory-insights/index.md | 165 ++++++++++++++++++ .../_index.md | 50 ------ .../api.md | 67 ------- 4 files changed, 166 insertions(+), 117 deletions(-) create mode 100644 content/en/plugins/armory-insights/index.md delete mode 100644 content/en/plugins/orca-successful-pipeline-calculator/_index.md delete mode 100644 content/en/plugins/orca-successful-pipeline-calculator/api.md diff --git a/content/en/includes/plugins/plugin-compat-matrix.md b/content/en/includes/plugins/plugin-compat-matrix.md index 5509937476..fcfabaeaeb 100644 --- a/content/en/includes/plugins/plugin-compat-matrix.md +++ b/content/en/includes/plugins/plugin-compat-matrix.md @@ -5,6 +5,7 @@ | {{< linkWithLinkTitle "plugins/echo-event-filter.md" >}}
{{% getPageDesc "/plugins/echo-event-filter.md" %}} | 1.29+ | 2.30+ | | {{< linkWithLinkTitle "plugins/github-integration/_index.md" >}}
{{% getPageDesc "/plugins/github-integration/_index.md" %}} | 1.30+ | 2.30+ | | {{< linkWithLinkTitle "plugins/plugin-k8s-custom-resource-status.md" >}}
{{% getPageDesc "/plugins/plugin-k8s-custom-resource-status.md" %}} | 1.27+ | 2.27+ | +| {{< linkWithLinkTitle "plugins/armory-insights/index.md" >}}
{{% getPageDesc "/plugins/armory-insights/index.md" %}} | 1.28+ | 2.28+ | | {{< linkWithLinkTitle "plugins/pipelines-as-code/_index.md" >}}
{{% getPageDesc "/plugins/pipelines-as-code/_index.md" %}} | 1.26+ | 2.21+ | | {{< linkWithLinkTitle "plugins/policy-engine/_index.md" >}}
{{% getPageDesc "/plugins/policy-engine/_index.md" %}} | 1.26+ | 2.26+ | | {{< linkWithLinkTitle "plugins/scale-agent/_index.md" >}}
{{% getPageDesc "/plugins/scale-agent/_index.md" %}} | 1.26+ | 2.26+ | diff --git a/content/en/plugins/armory-insights/index.md b/content/en/plugins/armory-insights/index.md new file mode 100644 index 0000000000..9175728b98 --- /dev/null +++ b/content/en/plugins/armory-insights/index.md @@ -0,0 +1,165 @@ +--- +title: Armory Insights Plugin for Armory CD +linkTitle: Armory Insights +description: > + The Armory Insights Plugin for Armory Continuous Deployment automates the aggregation of successful pipeline count by day and makes the information available to query and visualize through an API. +no_list: true +--- + +![Proprietary](/images/proprietary.svg) [![Generally available](/images/ga.svg)]({{< ref "release-definitions#ga" >}}) + +**Armory Continuous Deployment only** + +## {{% heading "prereq" %}} + +* Your Orca service uses a SQL backend. See [Orca configured with SQL backend]({{< ref "continuous-deployment/armory-admin/orca-sql-configure" >}}) for instructions. +* You're able to call Orca's service endpoint (by default `http://spin-orca:8083`) + +## Compatibility matrix + +| Armory CD Version | Armory Insights Plugin Version | +|-------------------|-----------------------------| +| 2.31.x | 0.0.1 | +| 2.30.x | 0.0.1 | +| 2.28.x | 0.0.1 | + +## Installation + +### Configure the plugin + +In your `spinnaker-kustomize-patches/plugins` directory, create an `insights-plugin.yml` file with the following contents: + +```yaml +apiVersion: spinnaker.armory.io/v1alpha2 +kind: SpinnakerService +metadata: + name: spinnaker +spec: + spinnakerConfig: + profiles: + spinnaker: + insights: + jobs: + pipelineStatusCount: + cron: '1 1 1 * * *' + spinnaker: + extensibility: + repositories: + repository: + enabled: true + url: https://raw.githubusercontent.com/armory-plugins/pluginRepository/master/repositories.json + orca: + spinnaker: + extensibility: + plugins: + Armory.Insights: + version: + enabled: true + extensions: + armory.insights: + enabled: true +``` + +- `version`: Replace `` with the plugin version compatible with your Spinnaker version. +- `insights.jobs.pipelinStatusCount.cron`: Replace with a cron expression that corresponds to the time of the day with lowest load. You can disable this field by using `-` as the expression. For example: + + ```yaml + spec: + spinnakerConfig: + profiles: + spinnaker: + insights: + jobs: + pipelineStatusCount: + cron: '-' + ``` + +### Install the plugin + +1. Add the plugin patch to your Kustomize recipe's `patchesStrategicMerge` section. For example: + + {{< highlight yaml "linenos=table,hl_lines=13" >}} + apiVersion: kustomize.config.k8s.io/v1beta1 + kind: Kustomization + + namespace: spinnaker + + components: + - core/base + - core/persistence/in-cluster + - targets/kubernetes/default + + patchesStrategicMerge: + - core/patches/oss-version.yml + - plugins/insights-plugin.yml + + patches: + - target: + kind: SpinnakerService + path: utilities/switch-to-oss.yml + {{< /highlight >}} + +1. Apply the updates to your Kustomization recipe. + + ```bash + kubectl apply -k + ``` + +## How to use the plugin + +### API endpoint + +`/insights/pipelines/statuses/count` + +| Parameter | Type | Description | Optional | Default Value | +|-----------|-----------------------|----------------------------------|----------|---------------| +| from | Date (yyyy-MM-dd) | Starting Date | Yes | 30 days ago | +| to | Date (yyyy-MM-dd) | End Date | Yes | Today | +| limit | Number | Max Number of results | Yes | 1000 | +| offsetId | Number | Starting Id (Exclusive) | Yes | nil | +| descOrder | Boolean | Sort results in descending order | Yes | false | +| status | SUCCEEDED \| TERMINAL | Status of the aggregate | Yes | SUCCEEDED | + +### JSON Response + +```json +{ + "records": [ + { + "id": [id], + "status": "[status]", + "date": [UNIX milliseconds], + "count": [count], + "day": "yyyy-MM-dd" + }, + ... + ], + "limit": [limit], + "count": [count], + "from": "yyyy-MM-dd", + "to": "yyyy-MM-dd" +} +``` + +#### Root object + +| Field | Type | Description | +|---------|--------|--------------------------------------| +| records | Array | Array of record objects | +| limit | Number | Limit on the number of records | +| count | Number | Total number of records | +| from | String | Start date for the record collection | +| to | String | End date for the record collection | + +#### Record object + +Each object in the `records` array has the following structure: + +| Field | Type | Description | +|--------|--------|---------------------------------------------------------| +| id | Number | Unique identifier of the record | +| status | String | Status of the record (e.g., "SUCCEEDED") | +| date | Number | Date of the record in milliseconds since epoch | +| count | Number | Count associated with the record | +| day | String | The day corresponding to the record (yyyy-MM-dd format) | + diff --git a/content/en/plugins/orca-successful-pipeline-calculator/_index.md b/content/en/plugins/orca-successful-pipeline-calculator/_index.md deleted file mode 100644 index 1bbdad479a..0000000000 --- a/content/en/plugins/orca-successful-pipeline-calculator/_index.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: Orca-Successful-Pipeline-Calculator -linkTitle: Orca Successful Pipeline Calculator -description: > - Armory SPE Calculator automates the aggregation of Successful Pipeline count by day and makes the information available to query and visualize through an API -no_list: true ---- - -![Proprietary](/images/proprietary.svg) [![Generally available](/images/ga.svg)]({{< ref "release-definitions#ga" >}}) - -## Requirements -- [Orca configured with SQL backing](https://docs.armory.io/continuous-deployment/armory-admin/orca-sql-configure/) - -## Installation With Spinnaker Operator -Create `insights-plugin.yml` with the following contents: -```yaml -apiVersion: spinnaker.io/v1alpha2 -kind: SpinnakerService -metadata: - name: spinnaker -spec: - spinnakerConfig: - profiles: - spinnaker: - insights: - jobs: - pipelineStatusCount: - cron: '1 1 1 * * *' - spinnaker: - extensibility: - repositories: - repository: - enabled: true - url: https://raw.githubusercontent.com/armory-plugins/pluginRepository/master/repositories.json - orca: - spinnaker: - extensibility: - plugins: - Armory.Insights: - version: - enabled: true - extensions: - armory.insights: - enabled: true -``` -- `version`: Replace `` with the plugin version compatible with your Spinnaker version. -- `insights.jobs.pipelinStatusCount.cron`: Replace with a cron expression that corresponds to the time of the day with lowest load. It can be disabled by using `-` as an expression. - -### {{< linkWithTitle "plugins/orca-successful-pipeline-calculator/api.md" >}} - diff --git a/content/en/plugins/orca-successful-pipeline-calculator/api.md b/content/en/plugins/orca-successful-pipeline-calculator/api.md deleted file mode 100644 index d8c8460fe7..0000000000 --- a/content/en/plugins/orca-successful-pipeline-calculator/api.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: Armory SPE Calculator API Usage -linkTitle: API Usage -weight: 10 -description: > - Learn how to retrieve SPE count using the REST API ---- - -## {{% heading "prereq" %}} - -* You have installed the [Orca SPE Calculator Plugin]({{< ref "/plugins/orca-successful-pipeline-calculator" >}}}) -* You're able to call Orca's endpoint service endpoint (by default `http://spin-orca:8083`) - -### Path -`/insights/pipelines/statuses/count` - -| Parameter | Type | Description | Optional | Default Value | -|-----------|-----------------------|----------------------------------|----------|---------------| -| from | Date (yyyy-MM-dd) | Starting Date | Yes | 30 days ago | -| to | Date (yyyy-MM-dd) | End Date | Yes | Today | -| limit | Number | Max Number of results | Yes | 1000 | -| offsetId | Number | Starting Id (Exclusive) | Yes | nil | -| descOrder | Boolean | Sort results in descending order | Yes | false | -| status | SUCCEEDED \| TERMINAL | Status of the aggregate | Yes | SUCCEEDED | - -### Response -## JSON Structure Documentation - -### Root Object -| Field | Type | Description | -|---------|--------|--------------------------------------| -| records | Array | Array of record objects | -| limit | Number | Limit on the number of records | -| count | Number | Total number of records | -| from | String | Start date for the record collection | -| to | String | End date for the record collection | - -### Record Object -Each object in the `records` array has the following structure: - -| Field | Type | Description | -|--------|--------|---------------------------------------------------------| -| id | Number | Unique identifier of the record | -| status | String | Status of the record (e.g., "SUCCEEDED") | -| date | Number | Date of the record in milliseconds since epoch | -| count | Number | Count associated with the record | -| day | String | The day corresponding to the record (yyyy-MM-dd format) | - -## Example - -```json -{ - "records": [ - { - "id": [id], - "status": "[status]", - "date": [UNIX milliseconds], - "count": [count], - "day": "yyyy-MM-dd" - }, - ... - ], - "limit": [limit], - "count": [count], - "from": "yyyy-MM-dd", - "to": "yyyy-MM-dd" -} From 69a0e06cc884dee7129f2a122e7f6d19f57bf19b Mon Sep 17 00:00:00 2001 From: Aimee Ukasick Date: Wed, 13 Dec 2023 15:43:12 -0600 Subject: [PATCH 6/7] rename to operational analytics plugin --- .../includes/plugins/plugin-compat-matrix.md | 14 + content/en/plugins/armory-insights/index.md | 165 ---------- .../en/plugins/operational-analytics/index.md | 301 ++++++++++++++++++ .../operational-analytics-architecture.jpg | Bin 0 -> 66408 bytes 4 files changed, 315 insertions(+), 165 deletions(-) delete mode 100644 content/en/plugins/armory-insights/index.md create mode 100644 content/en/plugins/operational-analytics/index.md create mode 100644 content/en/plugins/operational-analytics/operational-analytics-architecture.jpg diff --git a/content/en/includes/plugins/plugin-compat-matrix.md b/content/en/includes/plugins/plugin-compat-matrix.md index fcfabaeaeb..fdf31d4b5c 100644 --- a/content/en/includes/plugins/plugin-compat-matrix.md +++ b/content/en/includes/plugins/plugin-compat-matrix.md @@ -1,3 +1,4 @@ +<<<<<<< HEAD | Plugin | Spinnaker | Armory CD | |:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------:|:----------------------------------:| | [Armory CD-as-a-Service Plugin](https://developer.armory.io/docs/integrations/plugin-spinnaker)
The Armory Continuous Deployment-as-a-Service plugin enables performing canary and blue/green deployments in a single stage from Spinnaker to your Kubernetes deployment target using CD-as-a-Service. | 1.24+ | 2.24+
(included with Armory CD) | @@ -11,3 +12,16 @@ | {{< linkWithLinkTitle "plugins/scale-agent/_index.md" >}}
{{% getPageDesc "/plugins/scale-agent/_index.md" %}} | 1.26+ | 2.26+ | | {{< linkWithLinkTitle "plugins/self-serve-error-management.md" >}}
{{% getPageDesc "/plugins/self-serve-error-management.md" %}} | 1.29+ | 2.30+ | | {{< linkWithLinkTitle "plugins/terraform/_index.md" >}}
{{% getPageDesc "/plugins/terraform/_index.md" %}} | 1.26+ | 2.26+ | +======= +| Plugin | Spinnaker | Armory CD | +|:-------|:--------:|:--------:| +| [Armory CD-as-a-Service Plugin](https://developer.armory.io/docs/integrations/plugin-spinnaker)
The Armory Continuous Deployment-as-a-Service plugin enables performing canary and blue/green deployments in a single stage from Spinnaker to your Kubernetes deployment target using CD-as-a-Service. | 1.24+ | 2.24+
(included with Armory CD)| +| {{< linkWithLinkTitle "plugins/echo-event-filter.md" >}}
{{% getPageDesc "/plugins/echo-event-filter.md" %}} | 1.29+ | 2.30+ | +| {{< linkWithLinkTitle "plugins/github-integration/_index.md" >}}
{{% getPageDesc "/plugins/github-integration/_index.md" %}} | 1.30+ | 2.30+ | +| {{< linkWithLinkTitle "plugins/plugin-k8s-custom-resource-status.md" >}}
{{% getPageDesc "/plugins/plugin-k8s-custom-resource-status.md" %}} | 1.27+ | 2.27+ | +| {{< linkWithLinkTitle "plugins/operational-analytics/index.md" >}}
{{% getPageDesc "/plugins/operational-analytics/index.md" %}} | 1.28+ | 2.28+ | +| {{< linkWithLinkTitle "plugins/pipelines-as-code/_index.md" >}}
{{% getPageDesc "/plugins/pipelines-as-code/_index.md" %}} | 1.26+ | 2.21+ | +| {{< linkWithLinkTitle "plugins/policy-engine/_index.md" >}}
{{% getPageDesc "/plugins/policy-engine/_index.md" %}} | 1.26+ | 2.26+ | +| {{< linkWithLinkTitle "plugins/scale-agent/_index.md" >}}
{{% getPageDesc "/plugins/scale-agent/_index.md" %}} | 1.26+ | 2.26+ | +| {{< linkWithLinkTitle "plugins/terraform/_index.md" >}}
{{% getPageDesc "/plugins/terraform/_index.md" %}} | 1.26+ | 2.26+ | +>>>>>>> f6ad53f3 (rename to operational analytics plugin) diff --git a/content/en/plugins/armory-insights/index.md b/content/en/plugins/armory-insights/index.md deleted file mode 100644 index 9175728b98..0000000000 --- a/content/en/plugins/armory-insights/index.md +++ /dev/null @@ -1,165 +0,0 @@ ---- -title: Armory Insights Plugin for Armory CD -linkTitle: Armory Insights -description: > - The Armory Insights Plugin for Armory Continuous Deployment automates the aggregation of successful pipeline count by day and makes the information available to query and visualize through an API. -no_list: true ---- - -![Proprietary](/images/proprietary.svg) [![Generally available](/images/ga.svg)]({{< ref "release-definitions#ga" >}}) - -**Armory Continuous Deployment only** - -## {{% heading "prereq" %}} - -* Your Orca service uses a SQL backend. See [Orca configured with SQL backend]({{< ref "continuous-deployment/armory-admin/orca-sql-configure" >}}) for instructions. -* You're able to call Orca's service endpoint (by default `http://spin-orca:8083`) - -## Compatibility matrix - -| Armory CD Version | Armory Insights Plugin Version | -|-------------------|-----------------------------| -| 2.31.x | 0.0.1 | -| 2.30.x | 0.0.1 | -| 2.28.x | 0.0.1 | - -## Installation - -### Configure the plugin - -In your `spinnaker-kustomize-patches/plugins` directory, create an `insights-plugin.yml` file with the following contents: - -```yaml -apiVersion: spinnaker.armory.io/v1alpha2 -kind: SpinnakerService -metadata: - name: spinnaker -spec: - spinnakerConfig: - profiles: - spinnaker: - insights: - jobs: - pipelineStatusCount: - cron: '1 1 1 * * *' - spinnaker: - extensibility: - repositories: - repository: - enabled: true - url: https://raw.githubusercontent.com/armory-plugins/pluginRepository/master/repositories.json - orca: - spinnaker: - extensibility: - plugins: - Armory.Insights: - version: - enabled: true - extensions: - armory.insights: - enabled: true -``` - -- `version`: Replace `` with the plugin version compatible with your Spinnaker version. -- `insights.jobs.pipelinStatusCount.cron`: Replace with a cron expression that corresponds to the time of the day with lowest load. You can disable this field by using `-` as the expression. For example: - - ```yaml - spec: - spinnakerConfig: - profiles: - spinnaker: - insights: - jobs: - pipelineStatusCount: - cron: '-' - ``` - -### Install the plugin - -1. Add the plugin patch to your Kustomize recipe's `patchesStrategicMerge` section. For example: - - {{< highlight yaml "linenos=table,hl_lines=13" >}} - apiVersion: kustomize.config.k8s.io/v1beta1 - kind: Kustomization - - namespace: spinnaker - - components: - - core/base - - core/persistence/in-cluster - - targets/kubernetes/default - - patchesStrategicMerge: - - core/patches/oss-version.yml - - plugins/insights-plugin.yml - - patches: - - target: - kind: SpinnakerService - path: utilities/switch-to-oss.yml - {{< /highlight >}} - -1. Apply the updates to your Kustomization recipe. - - ```bash - kubectl apply -k - ``` - -## How to use the plugin - -### API endpoint - -`/insights/pipelines/statuses/count` - -| Parameter | Type | Description | Optional | Default Value | -|-----------|-----------------------|----------------------------------|----------|---------------| -| from | Date (yyyy-MM-dd) | Starting Date | Yes | 30 days ago | -| to | Date (yyyy-MM-dd) | End Date | Yes | Today | -| limit | Number | Max Number of results | Yes | 1000 | -| offsetId | Number | Starting Id (Exclusive) | Yes | nil | -| descOrder | Boolean | Sort results in descending order | Yes | false | -| status | SUCCEEDED \| TERMINAL | Status of the aggregate | Yes | SUCCEEDED | - -### JSON Response - -```json -{ - "records": [ - { - "id": [id], - "status": "[status]", - "date": [UNIX milliseconds], - "count": [count], - "day": "yyyy-MM-dd" - }, - ... - ], - "limit": [limit], - "count": [count], - "from": "yyyy-MM-dd", - "to": "yyyy-MM-dd" -} -``` - -#### Root object - -| Field | Type | Description | -|---------|--------|--------------------------------------| -| records | Array | Array of record objects | -| limit | Number | Limit on the number of records | -| count | Number | Total number of records | -| from | String | Start date for the record collection | -| to | String | End date for the record collection | - -#### Record object - -Each object in the `records` array has the following structure: - -| Field | Type | Description | -|--------|--------|---------------------------------------------------------| -| id | Number | Unique identifier of the record | -| status | String | Status of the record (e.g., "SUCCEEDED") | -| date | Number | Date of the record in milliseconds since epoch | -| count | Number | Count associated with the record | -| day | String | The day corresponding to the record (yyyy-MM-dd format) | - diff --git a/content/en/plugins/operational-analytics/index.md b/content/en/plugins/operational-analytics/index.md new file mode 100644 index 0000000000..ed1c77eb42 --- /dev/null +++ b/content/en/plugins/operational-analytics/index.md @@ -0,0 +1,301 @@ +--- +title: Operational Analytics Plugin for Spinnaker +linkTitle: Operational Analytics +description: > + The Operational Analytics Plugin for Spinnaker and Armory Continuous Deployment automates the aggregation of successful pipeline count by day and makes the information available to query and visualize through an API. +no_list: true +--- + +![Proprietary](/images/proprietary.svg) [![Generally available](/images/ga.svg)]({{< ref "release-definitions#ga" >}}) + +## What the Operational Analytics plugin does + +Armory’s Operational Analytics plugin for Spinnaker and Armory CD adds functionality to Orca that enables the storage of new metrics in Orca. You can retrieve those metrics using the API. The plugin is designed to provide key performance indicators without adding more services or operational overhead to the Spinnaker cluster to which it is installed. + +{{< figure src="operational-analytics-architecture" height="80%" width=80%" >}} + +## {{% heading "prereq" %}} + +* Your Orca service must use a SQL backend. See [Orca configured with SQL backend]({{< ref "continuous-deployment/armory-admin/orca-sql-configure" >}}) for instructions. +* You're able to call Orca's service endpoint (by default `http://spin-orca:8083`) + +## Compatibility matrix + +| Armory CD Version | Spinnaker Version | Armory Insights Plugin Version | +|-------------------|-----------------------------| ------------------- | +| 2.31.x | 1.31.x | 1.0.0 | +| 2.30.x | 1.29.x, 1.30.x | 1.0.0 | +| 2.28.x | 1.28.x | 1.0.0 | + +## Install the plugin + +{{< tabpane text=true right=true >}} + +{{% tab header="**Install Method**:" disabled=true /%}} + + +{{% tab header="Armory Operator" %}} + +1. In your `spinnaker-kustomize-patches/plugins` directory, create an `operational-analytics-plugin.yml` file with the following contents: + + ```yaml + apiVersion: spinnaker.armory.io/v1alpha2 + kind: SpinnakerService + metadata: + name: spinnaker + spec: + spinnakerConfig: + profiles: + spinnaker: + insights: + jobs: + pipelineStatusCount: + cron: '1 1 1 * * *' + spinnaker: + extensibility: + repositories: + repository: + enabled: true + url: https://raw.githubusercontent.com/armory-plugins/pluginRepository/master/repositories.json + orca: + spinnaker: + extensibility: + plugins: + Armory.Insights: + version: + enabled: true + extensions: + armory.insights: + enabled: true + ``` + + - `version`: Replace `` with the plugin version compatible with your Spinnaker version. + - `insights.jobs.pipelineStatusCount.cron`: Replace with a cron expression that corresponds to the time of the day with lowest load. You can disable this field by using `-` as the expression. For example: + + ```yaml + spec: + spinnakerConfig: + profiles: + spinnaker: + insights: + jobs: + pipelineStatusCount: + cron: '-' + ``` + + +1. Add the plugin patch to your Kustomize recipe's `patchesStrategicMerge` section. For example: + + ```yaml + apiVersion: kustomize.config.k8s.io/v1beta1 + kind: Kustomization + + namespace: spinnaker + + components: + - core/base + - core/persistence/in-cluster + - targets/kubernetes/default + + patchesStrategicMerge: + - core/patches/oss-version.yml + - plugins/operational-analytics-plugin.yml + + patches: + - target: + kind: SpinnakerService + path: utilities/switch-to-oss.yml + ``` + +1. Apply the updates to your Kustomization recipe. + + ```bash + kubectl apply -k + ``` + +{{% /tab %}} + + +{{% tab header="Spinnaker Operator" %}} + +1. In your `spinnaker-kustomize-patches/plugins/oss` directory, create an `operational-analytics-plugin.yml` file with the following contents: + + ```yaml + apiVersion: spinnaker.io/v1alpha2 + kind: SpinnakerService + metadata: + name: spinnaker + spec: + spinnakerConfig: + profiles: + spinnaker: + insights: + jobs: + pipelineStatusCount: + cron: '1 1 1 * * *' + spinnaker: + extensibility: + repositories: + repository: + enabled: true + url: https://raw.githubusercontent.com/armory-plugins/pluginRepository/master/repositories.json + orca: + spinnaker: + extensibility: + plugins: + Armory.Insights: + version: + enabled: true + extensions: + armory.insights: + enabled: true + ``` + + - `version`: Replace `` with the plugin version compatible with your Spinnaker version. + - `insights.jobs.pipelineStatusCount.cron`: Replace with a cron expression that corresponds to the time of the day with lowest load. You can disable this field by using `-` as the expression. For example: + + ```yaml + spec: + spinnakerConfig: + profiles: + spinnaker: + insights: + jobs: + pipelineStatusCount: + cron: '-' + ``` + + +1. Add the plugin patch to your Kustomize recipe's `patchesStrategicMerge` section. + + For example: + + ```yaml + apiVersion: kustomize.config.k8s.io/v1beta1 + kind: Kustomization + + namespace: spinnaker + + components: + - core/base + - core/persistence/in-cluster + - targets/kubernetes/default + + patchesStrategicMerge: + - core/patches/oss-version.yml + - plugins/oss/operational-analytics-plugin.yml + + patches: + - target: + kind: SpinnakerService + path: utilities/switch-to-oss.yml + ``` + +1. Apply the updates to your Kustomization recipe. + + ```bash + kubectl apply -k + ``` + +{{% /tab %}} + + +{{% tab header="Spinnaker Halyard" %}} + +The Operational Analytics plugin extends Orca. You should create or update the extended service’s local profile in the same directory as the other Halyard configuration files. This is usually `~/.hal/default/profiles` on the machine where Halyard is running. + +```yaml +insights: + jobs: + pipelineStatusCount: + cron: '1 1 1 * * *' + +spinnaker: + extensibility: + plugins: + Armory.Insights: + version: + enabled: true + extensions: + armory.insights: + enabled: true + repositories: + repository: + enabled: true + url: https://raw.githubusercontent.com/armory-plugins/pluginRepository/master/repositories.json +``` + +- `version`: Replace `` with the plugin version compatible with your Spinnaker version. +- `insights.jobs.pipelineStatusCount.cron`: Replace with a cron expression that corresponds to the time of the day with lowest load. You can disable this field by using `-` as the expression. For example: + +```yaml +insights: + jobs: + pipelineStatusCount: + cron: '-' +``` + +Save your file and apply your changes by running `hal deploy apply`. + +{{% /tab %}} + +{{< /tabpane >}} + +## How to use the plugin + +### API endpoint + +`/insights/pipelines/statuses/count` + +| Parameter | Type | Description | Optional | Default Value | +|-----------|-----------------------|----------------------------------|----------|---------------| +| from | Date (yyyy-MM-dd) | Starting Date | Yes | 30 days ago | +| to | Date (yyyy-MM-dd) | End Date | Yes | Today | +| limit | Number | Max Number of results | Yes | 1000 | +| offsetId | Number | Starting Id (Exclusive) | Yes | nil | +| descOrder | Boolean | Sort results in descending order | Yes | false | +| status | SUCCEEDED \| TERMINAL | Status of the aggregate | Yes | SUCCEEDED | + +### JSON Response + +```json +{ + "records": [ + { + "id": [id], + "status": "[status]", + "date": [UNIX milliseconds], + "count": [count], + "day": "yyyy-MM-dd" + }, + ... + ], + "limit": [limit], + "count": [count], + "from": "yyyy-MM-dd", + "to": "yyyy-MM-dd" +} +``` + +#### Root object + +| Field | Type | Description | +|---------|--------|--------------------------------------| +| records | Array | Array of record objects | +| limit | Number | Limit on the number of records | +| count | Number | Total number of records | +| from | String | Start date for the record collection | +| to | String | End date for the record collection | + +#### Record object + +Each object in the `records` array has the following structure: + +| Field | Type | Description | +|--------|--------|---------------------------------------------------------| +| id | Number | Unique identifier of the record | +| status | String | Status of the record (e.g., "SUCCEEDED") | +| date | Number | Date of the record in milliseconds since epoch | +| count | Number | Count associated with the record | +| day | String | The day corresponding to the record (yyyy-MM-dd format) | + diff --git a/content/en/plugins/operational-analytics/operational-analytics-architecture.jpg b/content/en/plugins/operational-analytics/operational-analytics-architecture.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bf64d1c112df436cd45c74c8ca5251730d552343 GIT binary patch literal 66408 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 H?<4;WEan8> literal 0 HcmV?d00001 From 1b936900adf97ab550f4aacded3ac074d39a9c09 Mon Sep 17 00:00:00 2001 From: Aimee Ukasick Date: Wed, 13 Dec 2023 15:47:49 -0600 Subject: [PATCH 7/7] fix error in plugin compat matrix --- .../includes/plugins/plugin-compat-matrix.md | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/content/en/includes/plugins/plugin-compat-matrix.md b/content/en/includes/plugins/plugin-compat-matrix.md index fdf31d4b5c..ede38b46d3 100644 --- a/content/en/includes/plugins/plugin-compat-matrix.md +++ b/content/en/includes/plugins/plugin-compat-matrix.md @@ -1,21 +1,7 @@ -<<<<<<< HEAD -| Plugin | Spinnaker | Armory CD | -|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:---------:|:----------------------------------:| -| [Armory CD-as-a-Service Plugin](https://developer.armory.io/docs/integrations/plugin-spinnaker)
The Armory Continuous Deployment-as-a-Service plugin enables performing canary and blue/green deployments in a single stage from Spinnaker to your Kubernetes deployment target using CD-as-a-Service. | 1.24+ | 2.24+
(included with Armory CD) | -| {{< linkWithLinkTitle "plugins/aws-event-cache/_index.md" >}}
{{% getPageDesc "/plugins/aws-event-cache/_index.md" %}} | 1.28+ | 2.28+ | -| {{< linkWithLinkTitle "plugins/echo-event-filter.md" >}}
{{% getPageDesc "/plugins/echo-event-filter.md" %}} | 1.29+ | 2.30+ | -| {{< linkWithLinkTitle "plugins/github-integration/_index.md" >}}
{{% getPageDesc "/plugins/github-integration/_index.md" %}} | 1.30+ | 2.30+ | -| {{< linkWithLinkTitle "plugins/plugin-k8s-custom-resource-status.md" >}}
{{% getPageDesc "/plugins/plugin-k8s-custom-resource-status.md" %}} | 1.27+ | 2.27+ | -| {{< linkWithLinkTitle "plugins/armory-insights/index.md" >}}
{{% getPageDesc "/plugins/armory-insights/index.md" %}} | 1.28+ | 2.28+ | -| {{< linkWithLinkTitle "plugins/pipelines-as-code/_index.md" >}}
{{% getPageDesc "/plugins/pipelines-as-code/_index.md" %}} | 1.26+ | 2.21+ | -| {{< linkWithLinkTitle "plugins/policy-engine/_index.md" >}}
{{% getPageDesc "/plugins/policy-engine/_index.md" %}} | 1.26+ | 2.26+ | -| {{< linkWithLinkTitle "plugins/scale-agent/_index.md" >}}
{{% getPageDesc "/plugins/scale-agent/_index.md" %}} | 1.26+ | 2.26+ | -| {{< linkWithLinkTitle "plugins/self-serve-error-management.md" >}}
{{% getPageDesc "/plugins/self-serve-error-management.md" %}} | 1.29+ | 2.30+ | -| {{< linkWithLinkTitle "plugins/terraform/_index.md" >}}
{{% getPageDesc "/plugins/terraform/_index.md" %}} | 1.26+ | 2.26+ | -======= | Plugin | Spinnaker | Armory CD | |:-------|:--------:|:--------:| | [Armory CD-as-a-Service Plugin](https://developer.armory.io/docs/integrations/plugin-spinnaker)
The Armory Continuous Deployment-as-a-Service plugin enables performing canary and blue/green deployments in a single stage from Spinnaker to your Kubernetes deployment target using CD-as-a-Service. | 1.24+ | 2.24+
(included with Armory CD)| +| {{< linkWithLinkTitle "plugins/aws-event-cache/_index.md" >}}
{{% getPageDesc "/plugins/aws-event-cache/_index.md" %}} | 1.28+ | 2.28+ | | {{< linkWithLinkTitle "plugins/echo-event-filter.md" >}}
{{% getPageDesc "/plugins/echo-event-filter.md" %}} | 1.29+ | 2.30+ | | {{< linkWithLinkTitle "plugins/github-integration/_index.md" >}}
{{% getPageDesc "/plugins/github-integration/_index.md" %}} | 1.30+ | 2.30+ | | {{< linkWithLinkTitle "plugins/plugin-k8s-custom-resource-status.md" >}}
{{% getPageDesc "/plugins/plugin-k8s-custom-resource-status.md" %}} | 1.27+ | 2.27+ | @@ -23,5 +9,5 @@ | {{< linkWithLinkTitle "plugins/pipelines-as-code/_index.md" >}}
{{% getPageDesc "/plugins/pipelines-as-code/_index.md" %}} | 1.26+ | 2.21+ | | {{< linkWithLinkTitle "plugins/policy-engine/_index.md" >}}
{{% getPageDesc "/plugins/policy-engine/_index.md" %}} | 1.26+ | 2.26+ | | {{< linkWithLinkTitle "plugins/scale-agent/_index.md" >}}
{{% getPageDesc "/plugins/scale-agent/_index.md" %}} | 1.26+ | 2.26+ | +| {{< linkWithLinkTitle "plugins/self-serve-error-management.md" >}}
{{% getPageDesc "/plugins/self-serve-error-management.md" %}} | 1.29+ | 2.30+ | | {{< linkWithLinkTitle "plugins/terraform/_index.md" >}}
{{% getPageDesc "/plugins/terraform/_index.md" %}} | 1.26+ | 2.26+ | ->>>>>>> f6ad53f3 (rename to operational analytics plugin)