diff --git a/docs/content/en/docs/feature-status/_index.md b/docs/content/en/docs/feature-status/_index.md index 80160d9a80..6dde7a550b 100644 --- a/docs/content/en/docs/feature-status/_index.md +++ b/docs/content/en/docs/feature-status/_index.md @@ -72,7 +72,7 @@ Please note that the phases (Incubating, Alpha, Beta, and Stable) are applied to | [Notification](/docs/operator-manual/piped/configuring-notifications/) to Slack | Beta | | [Notification](/docs/operator-manual/piped/configuring-notifications/) to Webhook | Incubating | | [Secrets Management](/docs/user-guide/sealed-secrets/) | Beta | -| [Image Watcher](/docs/user-guide/image-watcher/) | Incubating | +| [Event Watcher](/docs/user-guide/event-watcher/) | Incubating | | Support executing custom stage | Incubating | | [ADA](/docs/user-guide/automated-deployment-analysis/) (Automated Deployment Analysis) by Prometheus metrics | Alpha | | [ADA](/docs/user-guide/automated-deployment-analysis/) by Datadog metrics | Incubating | diff --git a/docs/content/en/docs/operator-manual/piped/configuration-reference.md b/docs/content/en/docs/operator-manual/piped/configuration-reference.md index f2be6c0fb3..0a70df2f4a 100644 --- a/docs/content/en/docs/operator-manual/piped/configuration-reference.md +++ b/docs/content/en/docs/operator-manual/piped/configuration-reference.md @@ -32,6 +32,7 @@ spec: | analysisProviders | [][AnalysisProvider](/docs/operator-manual/piped/configuration-reference/#analysisprovider) | List of analysis providers can be used by this piped. | No | | imageProviders | [][ImageProvider](/docs/operator-manual/piped/configuration-reference/#imageprovider) | List of image providers can be used by this piped. | No | | imageWatcher | [ImageWatcher](/docs/operator-manual/piped/configuration-reference/#imagewatcher) | Optional Image watcher settings for each git repository | No | +| eventWatcher | [EventWatcher](/docs/operator-manual/piped/configuration-reference/#eventwatcher) | Optional Event watcher settings | No | | notifications | [Notifications](/docs/operator-manual/piped/configuration-reference/#notifications) | Sending notifications to Slack, Webhook... | No | ## Git @@ -179,6 +180,22 @@ Must be one of the following structs: | includes | []string | The paths to ImageWatcher files to be included. | No | | excludes | []string | The paths to ImageWatcher files to be excluded. This is prioritized if both includes and this are given. | No | +## EventWatcher + +| Field | Type | Description | Required | +|-|-|-|-| +| checkInterval | duration | Interval to fetch the latest event and compare it with one defined in EventWatcher config files. Defaults to `5m`. | No | +| gitRepos | [][EventWatcherGitRepo](/docs/operator-manual/piped/configuration-reference/#eventwatchergitrepo) | List of settings for each git repository | No | + +### EventWatcherGitRepo + +| Field | Type | Description | Required | +|-|-|-|-| +| repoId | string | Id of the git repository. This must be unique within the repos' elements. | Yes | +| commitMessage | string | The commit message used to push after replacing values. Default message is used if not given. | No | +| includes | []string | The paths to EventWatcher files to be included. | No | +| excludes | []string | The paths to EventWatcher files to be excluded. This is prioritized if both includes and this are given. | No | + ## Notifications | Field | Type | Description | Required | diff --git a/docs/content/en/docs/operator-manual/piped/configuring-event-watcher.md b/docs/content/en/docs/operator-manual/piped/configuring-event-watcher.md new file mode 100644 index 0000000000..35b7bab9fd --- /dev/null +++ b/docs/content/en/docs/operator-manual/piped/configuring-event-watcher.md @@ -0,0 +1,46 @@ +--- +title: "Configuring event watcher" +linkTitle: "Configuring event watcher" +weight: 6 +description: > + This page describes how to configure piped to enable event watcher. +--- + +To enable [EventWatcher](/docs/user-guide/event-watcher/), you have to configure your piped at first. + +### [required] Grant write permission +The [SSH key used by Piped](/docs/operator-manual/piped/configuration-reference/#git) must be a key with write-access because piped needs to commit and push to your git repository when any incoming event matches. + +### [optional] Settings for watcher +The Piped's behavior can be finely controlled by setting the `eventWatcher` field. + +```yaml +apiVersion: pipecd.dev/v1beta1 +kind: Piped +spec: + eventWatcher: + checkInterval: 5m + gitRepos: + - repoId: repo-1 + commitMessage: Update values by Event watcher + includes: + - event-watcher-dev.yaml + - event-watcher-stg.yaml +``` + +If multiple Pipeds handle a single repository, you can prevent conflicts by splitting into the multiple EventWatcher files and setting `includes/excludes` to specify the files that should be monitored by this Piped. +`excludes` is prioritized if both `includes` and `excludes` are given. + +The full list of configurable fields are [here](/docs/operator-manual/piped/configuration-reference/#eventwatcher). + +### [optional] Settings for git user +By default, every git commit uses `piped` as a username and `pipecd.dev@gmail.com` as an email. You can change it with the [git](/docs/operator-manual/piped/configuration-reference/#git) field. + +```yaml +apiVersion: pipecd.dev/v1beta1 +kind: Piped +spec: + git: + username: foo + email: foo@example.com +``` diff --git a/docs/content/en/docs/operator-manual/piped/configuring-image-watcher.md b/docs/content/en/docs/operator-manual/piped/configuring-image-watcher.md index 9fd78be93d..e747a1b556 100644 --- a/docs/content/en/docs/operator-manual/piped/configuring-image-watcher.md +++ b/docs/content/en/docs/operator-manual/piped/configuring-image-watcher.md @@ -1,7 +1,7 @@ --- title: "Configuring image watcher" linkTitle: "Configuring image watcher" -weight: 6 +weight: 10 description: > This page describes how to configure piped to enable image watcher. --- diff --git a/docs/content/en/docs/user-guide/configuration-reference.md b/docs/content/en/docs/user-guide/configuration-reference.md index 07414bcb9e..7b6f2d45cf 100644 --- a/docs/content/en/docs/user-guide/configuration-reference.md +++ b/docs/content/en/docs/user-guide/configuration-reference.md @@ -136,6 +136,32 @@ spec: | filePath | string | The path to the file to be updated. | Yes | | field | string | The path to the field to be updated. It requires to start with `$` which represents the root element. e.g. `$.foo.bar[0].baz`. | Yes | +## Event Watcher Configuration + +```yaml +apiVersion: pipecd.dev/v1beta1 +kind: EventWatcher +spec: + events: + - name: helloworld-image-update + replacements: + - file: helloworld/deployment.yaml + yamlField: $.spec.template.spec.containers[0].image +``` + +| Field | Type | Description | Required | +|-|-|-|-| +| name | string | The event name. | Yes | +| labels | map[string]string | Additional attributes of event. This can make an event definition unique even if the one with the same name exists. | No | +| replacements | [][EventWatcherReplacement](/docs/user-guide/configuration-reference/#eventwatcherreplacement) | List of places where will be replaced when the new event matches. | Yes | + +## EventWatcherReplacement + +| Field | Type | Description | Required | +|-|-|-|-| +| file | string | The path to the file to be updated. | Yes | +| yamlField | string | The yaml path to the field to be updated. It requires to start with `$` which represents the root element. e.g. `$.foo.bar[0].baz`. | Yes | + ## CommitMatcher | Field | Type | Description | Required | diff --git a/docs/content/en/docs/user-guide/event-watcher.md b/docs/content/en/docs/user-guide/event-watcher.md new file mode 100644 index 0000000000..f264c876c9 --- /dev/null +++ b/docs/content/en/docs/user-guide/event-watcher.md @@ -0,0 +1,152 @@ +--- +title: "Event watcher" +linkTitle: "Event watcher" +weight: 13 +description: > + A helper facility to automatically update files when it finds out a new event. +--- + +The only way to upgrade your application with PipeCD is modifying configuration files managed by the Git repositories. +It brings benefits quite a bit, but it can be painful to manually update them every time in some cases (e.g. continuous deployment to your development environment for debugging, the latest prerelease to the staging environment). + +If you're experiencing any of the above pains, Event watcher is for you. +Event watcher works as a helper facility to seamlessly link CI and CD. This feature lets you automatically update files managed by your Piped when an arbitrary event has occurred. +While it empowers you to build pretty versatile workflows, the canonical use case is that you trigger a new deployment by image updates, package releases, etc. + +This guide walks you through configuring Event watcher and how to push an Event. + +## Prerequisites +Before configuring EventWatcher, be sure to grant write permission to the SSH key used by Piped. See [here](/docs/operator-manual/piped/configuring-event-watcher/) for more details. + +## Usage +File updating can be done by registering the latest value corresponding to the Event in the control-plane and comparing it with the current value. + +Therefore, you mainly need to: +1. define which values in which files should be updated when a new Event found. +1. integrate a step to push an Event to the control-plane using `pipectl` into your CI workflow. + +### 1. Defining Events +Prepare EventWatcher configuration files under the `.pipe/` directory at the root of your Git repository. +In that files, you define which values in which files should be updated when the Piped found out a new Event. + +For instance, suppose you want to update the Kubernetes manifest defined in `helloworld/deployment.yaml` when an Event with the name `helloworld-image-update` occurs: + +```yaml +apiVersion: pipecd.dev/v1beta1 +kind: EventWatcher +spec: + events: + - name: helloworld-image-update + replacements: + - file: helloworld/deployment.yaml + yamlField: $.spec.template.spec.containers[0].image +``` + +The full list of configurable `EventWatcher` fields are [here](/docs/user-guide/configuration-reference/#event-watcher-configuration). + +### 2. Pushing an Event with `pipectl` +To register a new value corresponding to Event such as the above in the control-plane, you need to perform `pipectl`. +And we highly recommend integrating a step for that into your CI workflow. + +According to [this guide](/docs/user-guide/command-line-tool/#installation), you first install it on your CI system or where you want to run. +And then you grab the API key for the control-plane according to [this guide](/docs/user-guide/command-line-tool/#authentication). + +Once you're all set up, pushing a new Event to the control-plane by the following command: + +```bash +pipectl event register \ + --address=CONTROL_PLANE_API_ADDRESS \ + --api-key=API_KEY \ + --name=helloworld-image-update \ + --data=gcr.io/pipecd/helloworld:v0.2.0 +``` + + +After a while, Piped will create a commit as shown below: + +```diff + spec: + containers: + - name: helloworld +- image: gcr.io/pipecd/helloworld:v0.1.0 ++ image: gcr.io/pipecd/helloworld:v0.2.0 +``` + +NOTE: Keep in mind that it may take a little while because Piped periodically fetches the new events from the control-plane. You can change its interval according to [here](/docs/operator-manual/piped/configuring-event-watcher/#optional-settings-for-watcher). + +### [optional] Using labels +Event watcher is a project-wide feature, hence an event name is unique inside a project. That is, you can update multiple repositories at the same time if you use the same event name for different events. + +On the contrary, if you want to explicitly distinguish those, we recommend using labels. You can make an event definition unique by using any number of labels with arbitrary keys and values. +Suppose you define an event with the labels `repoId: repo-1` and `appName: helloworld`: + +```yaml +apiVersion: pipecd.dev/v1beta1 +kind: EventWatcher +spec: + events: + - name: image-update + labels: + repoId: repo-1 + appName: helloworld + replacements: + - file: helloworld/deployment.yaml + yamlField: $.spec.template.spec.containers[0].image +``` + +The file update will be executed only when the labels are explicitly specified with the `--labels` flag. + +```bash +pipectl event register \ + --address=CONTROL_PLANE_API_ADDRESS \ + --api-key=API_KEY \ + --name=image-update \ + --labels repoId=repo-1,appName=helloworld \ + --data=gcr.io/pipecd/helloworld:v0.2.0 +``` + +Note that it is considered a match only when labels are an exact match. + +## Examples +For Helm release: + +```yaml +apiVersion: pipecd.dev/v1beta1 +kind: EventWatcher +spec: + events: + - name: helm-release + labels: + repoId: repo-1 + appName: helloworld + replacements: + - file: helloworld/.pipe.yaml + yamlField: $.spec.input.helmChart.version +``` + +Push a new version `0.2.0` as a data. + +```bash +pipectl event register \ + --address=CONTROL_PLANE_API_ADDRESS \ + --api-key=API_KEY \ + --name=helm-release \ + --labels repoId=repo-1,appName=helloworld \ + --data=0.2.0 +``` + +Then you'll see that Piped updates as: + +```diff +apiVersion: pipecd.dev/v1beta1 +kind: KubernetesApp +spec: + input: + helmChart: + name: helloworld +- version: 0.1.0 ++ version: 0.2.0 +``` + +See [here](https://github.com/pipe-cd/examples/tree/master/.pipe) for more examples. + diff --git a/examples/.pipe/event-watcher.yaml b/examples/.pipe/event-watcher.yaml new file mode 100644 index 0000000000..0f916aefa3 --- /dev/null +++ b/examples/.pipe/event-watcher.yaml @@ -0,0 +1,29 @@ +apiVersion: pipecd.dev/v1beta1 +kind: EventWatcher +spec: + events: + # For those who want to update the manifest file when a new docker image was pushed. + - name: helloworld-image-update + replacements: + - file: helloworld/deployment.yaml + yamlField: $.spec.template.spec.containers[0].image + # For those who want to update the deployment config file when releasing a new Helm package. + - name: helloworld-helm-release + replacements: + - file: helloworld/.pipe.yaml + yamlField: $.spec.input.helmChart.version + # For those who want to identify Events using labels. + - name: image-update + labels: + repoId: repo-1 + appName: helloworld + replacements: + - file: helloworld/deployment.yaml + yamlField: $.spec.template.spec.containers[0].image + # For those who want to update multiple files at once. + - name: helloworld-image-update + replacements: + - file: dev/helloworld/deployment.yaml + yamlField: $.spec.template.spec.containers[0].image + - file: stg/helloworld/deployment.yaml + yamlField: $.spec.template.spec.containers[0].image