diff --git a/global_config.yaml.tpl b/global_config.yaml.tpl index c6842226f..c75920487 100644 --- a/global_config.yaml.tpl +++ b/global_config.yaml.tpl @@ -38,15 +38,18 @@ actions: executors: - kubectl-read-only + # Map of sources. Source contains configuration for Kubernetes events and sending recommendations. # The property name under `sources` object is an alias for a given configuration. You can define multiple sources configuration with different names. # Key name is used as a binding reference. +# See the `values.yaml` file for full object. # ## Format: sources.{alias} sources: 'k8s-recommendation-events': displayName: "Kubernetes Recommendations" # Describes Kubernetes source configuration. + # See the `values.yaml` file for full object. kubernetes: # Describes configuration for various recommendation insights. recommendations: @@ -66,19 +69,21 @@ sources: 'k8s-all-events': displayName: "Kubernetes Info" # Describes Kubernetes source configuration. + # See the `values.yaml` file for full object. kubernetes: # Describes namespaces for every Kubernetes resources you want to watch or exclude. # These namespaces are applied to every resource specified in the resources list. # However, every specified resource can override this by using its own namespaces object. namespaces: &k8s-events-namespaces # Include contains a list of allowed Namespaces. - # It can also contain a regex expressions: + # It can also contain regex expressions: # `- ".*"` - to specify all Namespaces. include: - ".*" # Exclude contains a list of Namespaces to be ignored even if allowed by Include. - # It can also contain a regex expressions: + # It can also contain regex expressions: # `- "test-.*"` - to specif all Namespaces with `test-` prefix. + # Exclude list is checked before the Include list. # exclude: [] # Describes event constraints for Kubernetes resources. @@ -89,16 +94,63 @@ sources: - create - delete - error + # Optional list of exact values or regex patterns to filter events by event reason. + # Skipped, if both include/exclude lists are empty. + reason: + # Include contains a list of allowed values. It can also contain regex expressions. + include: [] + # Exclude contains a list of values to be ignored even if allowed by Include. It can also contain regex expressions. + # Exclude list is checked before the Include list. + exclude: [] + # Optional list of exact values or regex patterns to filter event by event message. Skipped, if both include/exclude lists are empty. + # If a given event has multiple messages, it is considered a match if any of the messages match the constraints. + message: + # Include contains a list of allowed values. It can also contain regex expressions. + include: [] + # Exclude contains a list of values to be ignored even if allowed by Include. It can also contain regex expressions. + # Exclude list is checked before the Include list. + exclude: [] + + # Filters Kubernetes resources to watch by annotations. Each resource needs to have all the specified annotations. + # Regex expressions are not supported. + annotations: {} + # Filters Kubernetes resources to watch by labels. Each resource needs to have all the specified labels. + # Regex expressions are not supported. + labels: {} # Describes the Kubernetes resources to watch. # Resources are identified by its type in `{group}/{version}/{kind (plural)}` format. Examples: `apps/v1/deployments`, `v1/pods`. # Each resource can override the namespaces and event configuration by using dedicated `event` and `namespaces` field. + # Also, each resource can specify its own `annotations`, `labels` and `name` regex. + # See the `values.yaml` file for full object. resources: - type: v1/pods - # namespaces: # Overrides 'source'.kubernetes.namespaces - # include: - # - ".*" - # exclude: [] + namespaces: # Overrides 'source'.kubernetes.namespaces + include: + - ".*" + exclude: [] + annotations: {} # Overrides 'source'.kubernetes.annotations + labels: {} # Overrides 'source'.kubernetes.labels + # Optional resource name constraints. + name: + # Include contains a list of allowed values. It can also contain regex expressions. + include: [] + # Exclude contains a list of values to be ignored even if allowed by Include. It can also contain regex expressions. + # Exclude list is checked before the Include list. + exclude: [] + event: + # Overrides 'source'.kubernetes.event.reason + reason: + include: [] + exclude: [] + # Overrides 'source'.kubernetes.event.message + message: + include: [] + exclude: [] + # Overrides 'source'.kubernetes.event.types + types: + - create + - type: v1/services - type: networking.k8s.io/v1/ingresses - type: v1/nodes @@ -180,6 +232,7 @@ sources: displayName: "Kubernetes Errors" # Describes Kubernetes source configuration. + # See the `values.yaml` file for full object. kubernetes: # Describes namespaces for every Kubernetes resources you want to watch or exclude. # These namespaces are applied to every resource specified in the resources list. @@ -194,6 +247,7 @@ sources: - error # Describes the Kubernetes resources you want to watch. + # See the `values.yaml` file for full object. resources: - type: v1/pods - type: v1/services @@ -215,6 +269,7 @@ sources: displayName: "Kubernetes Errors for resources with logs" # Describes Kubernetes source configuration. + # See the `values.yaml` file for full object. kubernetes: # Describes namespaces for every Kubernetes resources you want to watch or exclude. # These namespaces are applied to every resource specified in the resources list. @@ -229,6 +284,7 @@ sources: - error # Describes the Kubernetes resources you want to watch. + # See the `values.yaml` file for full object. resources: - type: v1/pods - type: apps/v1/deployments @@ -241,6 +297,7 @@ sources: displayName: "Kubernetes Resource Created Events" # Describes Kubernetes source configuration. + # See the `values.yaml` file for full object. kubernetes: # Describes namespaces for every Kubernetes resources you want to watch or exclude. # These namespaces are applied to every resource specified in the resources list. @@ -255,6 +312,7 @@ sources: - create # Describes the Kubernetes resources you want to watch. + # See the `values.yaml` file for full object. resources: - type: v1/pods - type: v1/services @@ -267,6 +325,24 @@ sources: - type: apps/v1/daemonsets - type: batch/v1/jobs + 'prometheus': + ## Prometheus source configuration + ## Plugin name syntax: /[@]. If version is not provided, the latest version from repository is used. + botkube/prometheus: + # If true, enables `prometheus` source. + enabled: false + config: + # Prometheus endpoint without api version and resource. + url: "http://localhost:9090" + # If set as true, Prometheus source plugin will not send alerts that is created before plugin start time. + ignoreOldAlerts: true + # Only the alerts that have state provided in this config will be sent as notification. https://pkg.go.dev/github.com/prometheus/prometheus/rules#AlertState + alertStates: ["firing", "pending", "inactive"] + # Logging configuration + log: + # Log level + level: info + # Filter settings for various sources. # Currently, all filters are globally enabled or disabled. # You can enable or disable filters with `@Botkube enable/disable filters` commands. diff --git a/helm/botkube/README.md b/helm/botkube/README.md index 8518e47b9..2e625e3b6 100644 --- a/helm/botkube/README.md +++ b/helm/botkube/README.md @@ -54,151 +54,159 @@ Controller for the Botkube Slack app which helps you monitor your Kubernetes clu | [sources.k8s-recommendation-events.kubernetes.recommendations.ingress.tlsSecretValid](./values.yaml#L122) | bool | `true` | If true, notifies about Ingress resources with invalid TLS secret reference. | | [sources.k8s-all-events.kubernetes](./values.yaml#L128) | object | See the `values.yaml` file for full object. | Describes Kubernetes source configuration. | | [sources.k8s-all-events.kubernetes.namespaces](./values.yaml#L132) | object | `{"include":[".*"]}` | Describes namespaces for every Kubernetes resources you want to watch or exclude. These namespaces are applied to every resource specified in the resources list. However, every specified resource can override this by using its own namespaces object. | -| [sources.k8s-all-events.kubernetes.event](./values.yaml#L145) | object | `{"message":"","reason":"","types":["create","delete","error"]}` | Describes event constraints for Kubernetes resources. These constraints are applied for every resource specified in the `resources` list, unless they are overridden by the resource's own `events` object. | -| [sources.k8s-all-events.kubernetes.event.types](./values.yaml#L147) | list | `["create","delete","error"]` | Lists all event types to be watched. | -| [sources.k8s-all-events.kubernetes.event.reason](./values.yaml#L152) | string | `""` | Optional regex to filter events by event reason. | -| [sources.k8s-all-events.kubernetes.event.message](./values.yaml#L154) | string | `""` | Optional regex to filter events by message. If a given event has multiple messages, it is considered a match if any of the messages match the regex. | -| [sources.k8s-all-events.kubernetes.annotations](./values.yaml#L157) | object | `{}` | Filters Kubernetes resources to watch by annotations. | -| [sources.k8s-all-events.kubernetes.labels](./values.yaml#L159) | object | `{}` | Filters Kubernetes resources to watch by labels. | -| [sources.k8s-all-events.kubernetes.resources](./values.yaml#L166) | list | See the `values.yaml` file for full object. | Describes the Kubernetes resources to watch. Resources are identified by its type in `{group}/{version}/{kind (plural)}` format. Examples: `apps/v1/deployments`, `v1/pods`. Each resource can override the namespaces and event configuration by using dedicated `event` and `namespaces` field. Also, each resource can specify its own `annotations`, `labels` and `name` regex. | -| [sources.k8s-err-events.kubernetes](./values.yaml#L263) | object | See the `values.yaml` file for full object. | Describes Kubernetes source configuration. | -| [sources.k8s-err-events.kubernetes.namespaces](./values.yaml#L267) | object | `{"include":[".*"]}` | Describes namespaces for every Kubernetes resources you want to watch or exclude. These namespaces are applied to every resource specified in the resources list. However, every specified resource can override this by using its own namespaces object. | -| [sources.k8s-err-events.kubernetes.event](./values.yaml#L271) | object | `{"types":["error"]}` | Describes event constraints for Kubernetes resources. These constraints are applied for every resource specified in the `resources` list, unless they are overridden by the resource's own `events` object. | -| [sources.k8s-err-events.kubernetes.event.types](./values.yaml#L273) | list | `["error"]` | Lists all event types to be watched. | -| [sources.k8s-err-events.kubernetes.resources](./values.yaml#L278) | list | See the `values.yaml` file for full object. | Describes the Kubernetes resources you want to watch. | -| [sources.k8s-err-with-logs-events.kubernetes](./values.yaml#L300) | object | See the `values.yaml` file for full object. | Describes Kubernetes source configuration. | -| [sources.k8s-err-with-logs-events.kubernetes.namespaces](./values.yaml#L304) | object | `{"include":[".*"]}` | Describes namespaces for every Kubernetes resources you want to watch or exclude. These namespaces are applied to every resource specified in the resources list. However, every specified resource can override this by using its own namespaces object. | -| [sources.k8s-err-with-logs-events.kubernetes.event](./values.yaml#L308) | object | `{"types":["error"]}` | Describes event constraints for Kubernetes resources. These constraints are applied for every resource specified in the `resources` list, unless they are overridden by the resource's own `events` object. | -| [sources.k8s-err-with-logs-events.kubernetes.event.types](./values.yaml#L310) | list | `["error"]` | Lists all event types to be watched. | -| [sources.k8s-err-with-logs-events.kubernetes.resources](./values.yaml#L315) | list | See the `values.yaml` file for full object. | Describes the Kubernetes resources you want to watch. | -| [sources.k8s-create-events.kubernetes](./values.yaml#L328) | object | See the `values.yaml` file for full object. | Describes Kubernetes source configuration. | -| [sources.k8s-create-events.kubernetes.namespaces](./values.yaml#L332) | object | `{"include":[".*"]}` | Describes namespaces for every Kubernetes resources you want to watch or exclude. These namespaces are applied to every resource specified in the resources list. However, every specified resource can override this by using its own namespaces object. | -| [sources.k8s-create-events.kubernetes.event](./values.yaml#L336) | object | `{"types":["create"]}` | Describes event constraints for Kubernetes resources. These constraints are applied for every resource specified in the `resources` list, unless they are overridden by the resource's own `events` object. | -| [sources.k8s-create-events.kubernetes.event.types](./values.yaml#L338) | list | `["create"]` | Lists all event types to be watched. | -| [sources.k8s-create-events.kubernetes.resources](./values.yaml#L343) | list | See the `values.yaml` file for full object. | Describes the Kubernetes resources you want to watch. | -| [sources.prometheus.botkube/prometheus.enabled](./values.yaml#L360) | bool | `false` | If true, enables `prometheus` source. | -| [sources.prometheus.botkube/prometheus.config.url](./values.yaml#L363) | string | `"http://localhost:9090"` | Prometheus endpoint without api version and resource. | -| [sources.prometheus.botkube/prometheus.config.ignoreOldAlerts](./values.yaml#L365) | bool | `true` | If set as true, Prometheus source plugin will not send alerts that is created before plugin start time. | -| [sources.prometheus.botkube/prometheus.config.alertStates](./values.yaml#L367) | list | `["firing","pending","inactive"]` | Only the alerts that have state provided in this config will be sent as notification. https://pkg.go.dev/github.com/prometheus/prometheus/rules#AlertState | -| [sources.prometheus.botkube/prometheus.config.log](./values.yaml#L369) | object | `{"level":"info"}` | Logging configuration | -| [sources.prometheus.botkube/prometheus.config.log.level](./values.yaml#L371) | string | `"info"` | Log level | -| [filters](./values.yaml#L377) | object | See the `values.yaml` file for full object. | Filter settings for various sources. Currently, all filters are globally enabled or disabled. You can enable or disable filters with `@Botkube enable/disable filters` commands. | -| [filters.kubernetes.objectAnnotationChecker](./values.yaml#L380) | bool | `true` | If true, enables support for `botkube.io/disable` and `botkube.io/channel` resource annotations. | -| [filters.kubernetes.nodeEventsChecker](./values.yaml#L382) | bool | `true` | If true, filters out Node-related events that are not important. | -| [executors](./values.yaml#L390) | object | See the `values.yaml` file for full object. | Map of executors. Executor contains configuration for running `kubectl` commands. The property name under `executors` is an alias for a given configuration. You can define multiple executor configurations with different names. Key name is used as a binding reference. | -| [executors.kubectl-read-only.kubectl.namespaces.include](./values.yaml#L398) | list | `[".*"]` | List of allowed Kubernetes Namespaces for command execution. It can also contain a regex expressions: `- ".*"` - to specify all Namespaces. | -| [executors.kubectl-read-only.kubectl.namespaces.exclude](./values.yaml#L403) | list | `[]` | List of ignored Kubernetes Namespace. It can also contain a regex expressions: `- "test-.*"` - to specify all Namespaces. | -| [executors.kubectl-read-only.kubectl.enabled](./values.yaml#L405) | bool | `false` | If true, enables `kubectl` commands execution. | -| [executors.kubectl-read-only.kubectl.commands.verbs](./values.yaml#L409) | list | `["api-resources","api-versions","cluster-info","describe","explain","get","logs","top"]` | Configures which `kubectl` methods are allowed. | -| [executors.kubectl-read-only.kubectl.commands.resources](./values.yaml#L411) | list | `["deployments","pods","namespaces","daemonsets","statefulsets","storageclasses","nodes","configmaps","services","ingresses"]` | Configures which K8s resource are allowed. | -| [executors.kubectl-read-only.kubectl.defaultNamespace](./values.yaml#L413) | string | `"default"` | Configures the default Namespace for executing Botkube `kubectl` commands. If not set, uses the 'default'. | -| [executors.kubectl-read-only.kubectl.restrictAccess](./values.yaml#L415) | bool | `false` | If true, enables commands execution from configured channel only. | -| [executors.helm.botkube/helm.enabled](./values.yaml#L422) | bool | `false` | If true, enables `helm` commands execution. | -| [executors.helm.botkube/helm.config.helmDriver](./values.yaml#L425) | string | `"secret"` | Allowed values are configmap, secret, memory. | -| [executors.helm.botkube/helm.config.helmConfigDir](./values.yaml#L427) | string | `"/tmp/helm/"` | Location for storing Helm configuration. | -| [executors.helm.botkube/helm.config.helmCacheDir](./values.yaml#L429) | string | `"/tmp/helm/.cache"` | Location for storing cached files. Must be under the Helm config directory. | -| [aliases](./values.yaml#L437) | object | See the `values.yaml` file for full object. | Custom aliases for given commands. The aliases are replaced with the underlying command before executing it. Aliases can replace a single word or multiple ones. For example, you can define a `k` alias for `kubectl`, or `kgp` for `kubectl get pods`. | -| [existingCommunicationsSecretName](./values.yaml#L457) | string | `""` | Configures existing Secret with communication settings. It MUST be in the `botkube` Namespace. To reload Botkube once it changes, add label `botkube.io/config-watch: "true"`. | -| [communications](./values.yaml#L464) | object | See the `values.yaml` file for full object. | Map of communication groups. Communication group contains settings for multiple communication platforms. The property name under `communications` object is an alias for a given configuration group. You can define multiple communication groups with different names. | -| [communications.default-group.socketSlack.enabled](./values.yaml#L469) | bool | `false` | If true, enables Slack bot. | -| [communications.default-group.socketSlack.channels](./values.yaml#L473) | object | `{"default":{"bindings":{"executors":["kubectl-read-only","helm"],"sources":["k8s-err-events","k8s-recommendation-events"]},"name":"SLACK_CHANNEL"}}` | Map of configured channels. The property name under `channels` object is an alias for a given configuration. | -| [communications.default-group.socketSlack.channels.default.name](./values.yaml#L476) | string | `"SLACK_CHANNEL"` | Slack channel name without '#' prefix where you have added Botkube and want to receive notifications in. | -| [communications.default-group.socketSlack.channels.default.bindings.executors](./values.yaml#L479) | list | `["kubectl-read-only","helm"]` | Executors configuration for a given channel. | -| [communications.default-group.socketSlack.channels.default.bindings.sources](./values.yaml#L483) | list | `["k8s-err-events","k8s-recommendation-events"]` | Notification sources configuration for a given channel. | -| [communications.default-group.socketSlack.botToken](./values.yaml#L488) | string | `""` | Slack bot token for your own Slack app. [Ref doc](https://api.slack.com/authentication/token-types). | -| [communications.default-group.socketSlack.appToken](./values.yaml#L491) | string | `""` | Slack app-level token for your own Slack app. [Ref doc](https://api.slack.com/authentication/token-types). | -| [communications.default-group.socketSlack.notification.type](./values.yaml#L494) | string | `"short"` | Configures notification type that are sent. Possible values: `short`, `long`. | -| [communications.default-group.mattermost.enabled](./values.yaml#L498) | bool | `false` | If true, enables Mattermost bot. | -| [communications.default-group.mattermost.botName](./values.yaml#L500) | string | `"Botkube"` | User in Mattermost which belongs the specified Personal Access token. | -| [communications.default-group.mattermost.url](./values.yaml#L502) | string | `"MATTERMOST_SERVER_URL"` | The URL (including http/https schema) where Mattermost is running. e.g https://example.com:9243 | -| [communications.default-group.mattermost.token](./values.yaml#L504) | string | `"MATTERMOST_TOKEN"` | Personal Access token generated by Botkube user. | -| [communications.default-group.mattermost.team](./values.yaml#L506) | string | `"MATTERMOST_TEAM"` | The Mattermost Team name where Botkube is added. | -| [communications.default-group.mattermost.channels](./values.yaml#L510) | object | `{"default":{"bindings":{"executors":["kubectl-read-only","helm"],"sources":["k8s-err-events","k8s-recommendation-events"]},"name":"MATTERMOST_CHANNEL","notification":{"disabled":false}}}` | Map of configured channels. The property name under `channels` object is an alias for a given configuration. | -| [communications.default-group.mattermost.channels.default.name](./values.yaml#L514) | string | `"MATTERMOST_CHANNEL"` | The Mattermost channel name for receiving Botkube alerts. The Botkube user needs to be added to it. | -| [communications.default-group.mattermost.channels.default.notification.disabled](./values.yaml#L517) | bool | `false` | If true, the notifications are not sent to the channel. They can be enabled with `@Botkube` command anytime. | -| [communications.default-group.mattermost.channels.default.bindings.executors](./values.yaml#L520) | list | `["kubectl-read-only","helm"]` | Executors configuration for a given channel. | -| [communications.default-group.mattermost.channels.default.bindings.sources](./values.yaml#L524) | list | `["k8s-err-events","k8s-recommendation-events"]` | Notification sources configuration for a given channel. | -| [communications.default-group.mattermost.notification.type](./values.yaml#L529) | string | `"short"` | Configures notification type that are sent. Possible values: `short`, `long`. | -| [communications.default-group.teams.enabled](./values.yaml#L534) | bool | `false` | If true, enables MS Teams bot. | -| [communications.default-group.teams.botName](./values.yaml#L536) | string | `"Botkube"` | The Bot name set while registering Bot to MS Teams. | -| [communications.default-group.teams.appID](./values.yaml#L538) | string | `"APPLICATION_ID"` | The Botkube application ID generated while registering Bot to MS Teams. | -| [communications.default-group.teams.appPassword](./values.yaml#L540) | string | `"APPLICATION_PASSWORD"` | The Botkube application password generated while registering Bot to MS Teams. | -| [communications.default-group.teams.bindings.executors](./values.yaml#L543) | list | `["kubectl-read-only","helm"]` | Executor bindings apply to all MS Teams channels where Botkube has access to. | -| [communications.default-group.teams.bindings.sources](./values.yaml#L547) | list | `["k8s-err-events","k8s-recommendation-events"]` | Source bindings apply to all channels which have notification turned on with `@Botkube enable notifications` command. | -| [communications.default-group.teams.messagePath](./values.yaml#L551) | string | `"/bots/teams"` | The path in endpoint URL provided while registering Botkube to MS Teams. | -| [communications.default-group.teams.port](./values.yaml#L553) | int | `3978` | The Service port for bot endpoint on Botkube container. | -| [communications.default-group.discord.enabled](./values.yaml#L558) | bool | `false` | If true, enables Discord bot. | -| [communications.default-group.discord.token](./values.yaml#L560) | string | `"DISCORD_TOKEN"` | Botkube Bot Token. | -| [communications.default-group.discord.botID](./values.yaml#L562) | string | `"DISCORD_BOT_ID"` | Botkube Application Client ID. | -| [communications.default-group.discord.channels](./values.yaml#L566) | object | `{"default":{"bindings":{"executors":["kubectl-read-only","helm"],"sources":["k8s-err-events","k8s-recommendation-events"]},"id":"DISCORD_CHANNEL_ID","notification":{"disabled":false}}}` | Map of configured channels. The property name under `channels` object is an alias for a given configuration. | -| [communications.default-group.discord.channels.default.id](./values.yaml#L570) | string | `"DISCORD_CHANNEL_ID"` | Discord channel ID for receiving Botkube alerts. The Botkube user needs to be added to it. | -| [communications.default-group.discord.channels.default.notification.disabled](./values.yaml#L573) | bool | `false` | If true, the notifications are not sent to the channel. They can be enabled with `@Botkube` command anytime. | -| [communications.default-group.discord.channels.default.bindings.executors](./values.yaml#L576) | list | `["kubectl-read-only","helm"]` | Executors configuration for a given channel. | -| [communications.default-group.discord.channels.default.bindings.sources](./values.yaml#L580) | list | `["k8s-err-events","k8s-recommendation-events"]` | Notification sources configuration for a given channel. | -| [communications.default-group.discord.notification.type](./values.yaml#L585) | string | `"short"` | Configures notification type that are sent. Possible values: `short`, `long`. | -| [communications.default-group.elasticsearch.enabled](./values.yaml#L590) | bool | `false` | If true, enables Elasticsearch. | -| [communications.default-group.elasticsearch.awsSigning.enabled](./values.yaml#L594) | bool | `false` | If true, enables awsSigning using IAM for Elasticsearch hosted on AWS. Make sure AWS environment variables are set. [Ref doc](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html). | -| [communications.default-group.elasticsearch.awsSigning.awsRegion](./values.yaml#L596) | string | `"us-east-1"` | AWS region where Elasticsearch is deployed. | -| [communications.default-group.elasticsearch.awsSigning.roleArn](./values.yaml#L598) | string | `""` | AWS IAM Role arn to assume for credentials, use this only if you don't want to use the EC2 instance role or not running on AWS instance. | -| [communications.default-group.elasticsearch.server](./values.yaml#L600) | string | `"ELASTICSEARCH_ADDRESS"` | The server URL, e.g https://example.com:9243 | -| [communications.default-group.elasticsearch.username](./values.yaml#L602) | string | `"ELASTICSEARCH_USERNAME"` | Basic Auth username. | -| [communications.default-group.elasticsearch.password](./values.yaml#L604) | string | `"ELASTICSEARCH_PASSWORD"` | Basic Auth password. | -| [communications.default-group.elasticsearch.skipTLSVerify](./values.yaml#L607) | bool | `false` | If true, skips the verification of TLS certificate of the Elastic nodes. It's useful for clusters with self-signed certificates. | -| [communications.default-group.elasticsearch.indices](./values.yaml#L611) | object | `{"default":{"bindings":{"sources":["k8s-err-events","k8s-recommendation-events"]},"name":"botkube","replicas":0,"shards":1,"type":"botkube-event"}}` | Map of configured indices. The `indices` property name is an alias for a given configuration. | -| [communications.default-group.elasticsearch.indices.default.name](./values.yaml#L614) | string | `"botkube"` | Configures Elasticsearch index settings. | -| [communications.default-group.elasticsearch.indices.default.bindings.sources](./values.yaml#L620) | list | `["k8s-err-events","k8s-recommendation-events"]` | Notification sources configuration for a given index. | -| [communications.default-group.webhook.enabled](./values.yaml#L627) | bool | `false` | If true, enables Webhook. | -| [communications.default-group.webhook.url](./values.yaml#L629) | string | `"WEBHOOK_URL"` | The Webhook URL, e.g.: https://example.com:80 | -| [communications.default-group.webhook.bindings.sources](./values.yaml#L632) | list | `["k8s-err-events","k8s-recommendation-events"]` | Notification sources configuration for the webhook. | -| [communications.default-group.slack](./values.yaml#L642) | object | See the `values.yaml` file for full object. | Settings for deprecated Slack integration. **DEPRECATED:** Legacy Slack integration has been deprecated and removed from the Slack App Directory. Use `socketSlack` instead. Read more here: https://docs.botkube.io/installation/slack/ | -| [settings.clusterName](./values.yaml#L663) | string | `"not-configured"` | Cluster name to differentiate incoming messages. | -| [settings.lifecycleServer](./values.yaml#L666) | object | `{"enabled":true,"port":2113}` | Server configuration which exposes functionality related to the app lifecycle. | -| [settings.healthPort](./values.yaml#L669) | int | `2114` | | -| [settings.upgradeNotifier](./values.yaml#L671) | bool | `true` | If true, notifies about new Botkube releases. | -| [settings.log.level](./values.yaml#L675) | string | `"info"` | Sets one of the log levels. Allowed values: `info`, `warn`, `debug`, `error`, `fatal`, `panic`. | -| [settings.log.disableColors](./values.yaml#L677) | bool | `false` | If true, disable ANSI colors in logging. | -| [settings.systemConfigMap](./values.yaml#L680) | object | `{"name":"botkube-system"}` | Botkube's system ConfigMap where internal data is stored. | -| [settings.persistentConfig](./values.yaml#L685) | object | `{"runtime":{"configMap":{"annotations":{},"name":"botkube-runtime-config"},"fileName":"_runtime_state.yaml"},"startup":{"configMap":{"annotations":{},"name":"botkube-startup-config"},"fileName":"_startup_state.yaml"}}` | Persistent config contains ConfigMap where persisted configuration is stored. The persistent configuration is evaluated from both chart upgrade and Botkube commands used in runtime. | -| [ssl.enabled](./values.yaml#L700) | bool | `false` | If true, specify cert path in `config.ssl.cert` property or K8s Secret in `config.ssl.existingSecretName`. | -| [ssl.existingSecretName](./values.yaml#L706) | string | `""` | Using existing SSL Secret. It MUST be in `botkube` Namespace. | -| [ssl.cert](./values.yaml#L709) | string | `""` | SSL Certificate file e.g certs/my-cert.crt. | -| [service](./values.yaml#L712) | object | `{"name":"metrics","port":2112,"targetPort":2112}` | Configures Service settings for ServiceMonitor CR. | -| [ingress](./values.yaml#L719) | object | `{"annotations":{"kubernetes.io/ingress.class":"nginx"},"create":false,"host":"HOST","tls":{"enabled":false,"secretName":""}}` | Configures Ingress settings that exposes MS Teams endpoint. [Ref doc](https://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource). | -| [serviceMonitor](./values.yaml#L730) | object | `{"enabled":false,"interval":"10s","labels":{},"path":"/metrics","port":"metrics"}` | Configures ServiceMonitor settings. [Ref doc](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor). | -| [deployment.annotations](./values.yaml#L740) | object | `{}` | Extra annotations to pass to the Botkube Deployment. | -| [extraAnnotations](./values.yaml#L747) | object | `{}` | Extra annotations to pass to the Botkube Pod. | -| [extraLabels](./values.yaml#L749) | object | `{}` | Extra labels to pass to the Botkube Pod. | -| [priorityClassName](./values.yaml#L751) | string | `""` | Priority class name for the Botkube Pod. | -| [nameOverride](./values.yaml#L754) | string | `""` | Fully override "botkube.name" template. | -| [fullnameOverride](./values.yaml#L756) | string | `""` | Fully override "botkube.fullname" template. | -| [resources](./values.yaml#L762) | object | `{}` | The Botkube Pod resource request and limits. We usually recommend not to specify default resources and to leave this as a conscious choice for the user. This also increases chances charts run on environments with little resources, such as Minikube. [Ref docs](https://kubernetes.io/docs/user-guide/compute-resources/) | -| [extraEnv](./values.yaml#L774) | list | `[]` | Extra environment variables to pass to the Botkube container. [Ref docs](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#environment-variables). | -| [extraVolumes](./values.yaml#L786) | list | `[]` | Extra volumes to pass to the Botkube container. Mount it later with extraVolumeMounts. [Ref docs](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/volume/#Volume). | -| [extraVolumeMounts](./values.yaml#L801) | list | `[]` | Extra volume mounts to pass to the Botkube container. [Ref docs](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#volumes-1). | -| [nodeSelector](./values.yaml#L819) | object | `{}` | Node labels for Botkube Pod assignment. [Ref doc](https://kubernetes.io/docs/user-guide/node-selection/). | -| [tolerations](./values.yaml#L823) | list | `[]` | Tolerations for Botkube Pod assignment. [Ref doc](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/). | -| [affinity](./values.yaml#L827) | object | `{}` | Affinity for Botkube Pod assignment. [Ref doc](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity). | -| [rbac](./values.yaml#L831) | object | `{"create":true,"rules":[{"apiGroups":["*"],"resources":["*"],"verbs":["get","watch","list"]}]}` | Role Based Access for Botkube Pod. [Ref doc](https://kubernetes.io/docs/admin/authorization/rbac/). | -| [serviceAccount.create](./values.yaml#L840) | bool | `true` | If true, a ServiceAccount is automatically created. | -| [serviceAccount.name](./values.yaml#L843) | string | `""` | The name of the service account to use. If not set, a name is generated using the fullname template. | -| [serviceAccount.annotations](./values.yaml#L845) | object | `{}` | Extra annotations for the ServiceAccount. | -| [extraObjects](./values.yaml#L848) | list | `[]` | Extra Kubernetes resources to create. Helm templating is allowed as it is evaluated before creating the resources. | -| [analytics.disable](./values.yaml#L876) | bool | `false` | If true, sending anonymous analytics is disabled. To learn what date we collect, see [Privacy Policy](https://docs.botkube.io/privacy#privacy-policy). | -| [configWatcher.enabled](./values.yaml#L881) | bool | `true` | If true, restarts the Botkube Pod on config changes. | -| [configWatcher.tmpDir](./values.yaml#L883) | string | `"/tmp/watched-cfg/"` | Directory, where watched configuration resources are stored. | -| [configWatcher.initialSyncTimeout](./values.yaml#L886) | int | `0` | Timeout for the initial Config Watcher sync. If set to 0, waiting for Config Watcher sync will be skipped. In a result, configuration changes may not reload Botkube app during the first few seconds after Botkube startup. | -| [configWatcher.image.registry](./values.yaml#L889) | string | `"ghcr.io"` | Config watcher image registry. | -| [configWatcher.image.repository](./values.yaml#L891) | string | `"kubeshop/k8s-sidecar"` | Config watcher image repository. | -| [configWatcher.image.tag](./values.yaml#L893) | string | `"ignore-initial-events"` | Config watcher image tag. | -| [configWatcher.image.pullPolicy](./values.yaml#L895) | string | `"IfNotPresent"` | Config watcher image pull policy. | -| [plugins](./values.yaml#L898) | object | `{"cacheDir":"/tmp","repositories":{"botkube":{"url":"https://github.com/kubeshop/botkube/releases/download/v9.99.9-dev/plugins-index.yaml"}}}` | Configuration for Botkube executors and sources plugins. | -| [plugins.cacheDir](./values.yaml#L900) | string | `"/tmp"` | Directory, where downloaded plugins are cached. | -| [plugins.repositories](./values.yaml#L902) | object | `{"botkube":{"url":"https://github.com/kubeshop/botkube/releases/download/v9.99.9-dev/plugins-index.yaml"}}` | List of plugins repositories. | -| [plugins.repositories.botkube](./values.yaml#L904) | object | `{"url":"https://github.com/kubeshop/botkube/releases/download/v9.99.9-dev/plugins-index.yaml"}` | This repository serves officially supported Botkube plugins. | -| [config](./values.yaml#L908) | object | `{"provider":{"endpoint":"","identifier":""}}` | Configuration for remote Botkube settings | -| [config.provider](./values.yaml#L910) | object | `{"endpoint":"","identifier":""}` | Base provider definition | -| [config.provider.identifier](./values.yaml#L912) | string | `""` | Unique identifier for remote Botkube settings | -| [config.provider.endpoint](./values.yaml#L914) | string | `""` | Endpoint to fetch Botkube settings from | +| [sources.k8s-err-events.kubernetes.namespaces.include](./values.yaml#L136) | list | `[".*"]` | Include contains a list of allowed Namespaces. It can also contain regex expressions: `- ".*"` - to specify all Namespaces. | +| [sources.k8s-all-events.kubernetes.namespaces.include](./values.yaml#L136) | list | `[".*"]` | Include contains a list of allowed Namespaces. It can also contain regex expressions: `- ".*"` - to specify all Namespaces. | +| [sources.k8s-create-events.kubernetes.namespaces.include](./values.yaml#L136) | list | `[".*"]` | Include contains a list of allowed Namespaces. It can also contain regex expressions: `- ".*"` - to specify all Namespaces. | +| [sources.k8s-err-with-logs-events.kubernetes.namespaces.include](./values.yaml#L136) | list | `[".*"]` | Include contains a list of allowed Namespaces. It can also contain regex expressions: `- ".*"` - to specify all Namespaces. | +| [sources.k8s-all-events.kubernetes.event](./values.yaml#L146) | object | `{"message":{"exclude":[],"include":[]},"reason":{"exclude":[],"include":[]},"types":["create","delete","error"]}` | Describes event constraints for Kubernetes resources. These constraints are applied for every resource specified in the `resources` list, unless they are overridden by the resource's own `events` object. | +| [sources.k8s-all-events.kubernetes.event.types](./values.yaml#L148) | list | `["create","delete","error"]` | Lists all event types to be watched. | +| [sources.k8s-all-events.kubernetes.event.reason](./values.yaml#L154) | object | `{"exclude":[],"include":[]}` | Optional list of exact values or regex patterns to filter events by event reason. Skipped, if both include/exclude lists are empty. | +| [sources.k8s-all-events.kubernetes.event.reason.include](./values.yaml#L156) | list | `[]` | Include contains a list of allowed values. It can also contain regex expressions. | +| [sources.k8s-all-events.kubernetes.event.reason.exclude](./values.yaml#L159) | list | `[]` | Exclude contains a list of values to be ignored even if allowed by Include. It can also contain regex expressions. Exclude list is checked before the Include list. | +| [sources.k8s-all-events.kubernetes.event.message](./values.yaml#L162) | object | `{"exclude":[],"include":[]}` | Optional list of exact values or regex patterns to filter event by event message. Skipped, if both include/exclude lists are empty. If a given event has multiple messages, it is considered a match if any of the messages match the constraints. | +| [sources.k8s-all-events.kubernetes.event.message.include](./values.yaml#L164) | list | `[]` | Include contains a list of allowed values. It can also contain regex expressions. | +| [sources.k8s-all-events.kubernetes.event.message.exclude](./values.yaml#L167) | list | `[]` | Exclude contains a list of values to be ignored even if allowed by Include. It can also contain regex expressions. Exclude list is checked before the Include list. | +| [sources.k8s-all-events.kubernetes.annotations](./values.yaml#L171) | object | `{}` | Filters Kubernetes resources to watch by annotations. Each resource needs to have all the specified annotations. Regex expressions are not supported. | +| [sources.k8s-all-events.kubernetes.labels](./values.yaml#L174) | object | `{}` | Filters Kubernetes resources to watch by labels. Each resource needs to have all the specified labels. Regex expressions are not supported. | +| [sources.k8s-all-events.kubernetes.resources](./values.yaml#L181) | list | See the `values.yaml` file for full object. | Describes the Kubernetes resources to watch. Resources are identified by its type in `{group}/{version}/{kind (plural)}` format. Examples: `apps/v1/deployments`, `v1/pods`. Each resource can override the namespaces and event configuration by using dedicated `event` and `namespaces` field. Also, each resource can specify its own `annotations`, `labels` and `name` regex. | +| [sources.k8s-err-events.kubernetes](./values.yaml#L291) | object | See the `values.yaml` file for full object. | Describes Kubernetes source configuration. | +| [sources.k8s-err-events.kubernetes.namespaces](./values.yaml#L295) | object | `{"include":[".*"]}` | Describes namespaces for every Kubernetes resources you want to watch or exclude. These namespaces are applied to every resource specified in the resources list. However, every specified resource can override this by using its own namespaces object. | +| [sources.k8s-err-events.kubernetes.event](./values.yaml#L299) | object | `{"types":["error"]}` | Describes event constraints for Kubernetes resources. These constraints are applied for every resource specified in the `resources` list, unless they are overridden by the resource's own `events` object. | +| [sources.k8s-err-events.kubernetes.event.types](./values.yaml#L301) | list | `["error"]` | Lists all event types to be watched. | +| [sources.k8s-err-events.kubernetes.resources](./values.yaml#L306) | list | See the `values.yaml` file for full object. | Describes the Kubernetes resources you want to watch. | +| [sources.k8s-err-with-logs-events.kubernetes](./values.yaml#L328) | object | See the `values.yaml` file for full object. | Describes Kubernetes source configuration. | +| [sources.k8s-err-with-logs-events.kubernetes.namespaces](./values.yaml#L332) | object | `{"include":[".*"]}` | Describes namespaces for every Kubernetes resources you want to watch or exclude. These namespaces are applied to every resource specified in the resources list. However, every specified resource can override this by using its own namespaces object. | +| [sources.k8s-err-with-logs-events.kubernetes.event](./values.yaml#L336) | object | `{"types":["error"]}` | Describes event constraints for Kubernetes resources. These constraints are applied for every resource specified in the `resources` list, unless they are overridden by the resource's own `events` object. | +| [sources.k8s-err-with-logs-events.kubernetes.event.types](./values.yaml#L338) | list | `["error"]` | Lists all event types to be watched. | +| [sources.k8s-err-with-logs-events.kubernetes.resources](./values.yaml#L343) | list | See the `values.yaml` file for full object. | Describes the Kubernetes resources you want to watch. | +| [sources.k8s-create-events.kubernetes](./values.yaml#L356) | object | See the `values.yaml` file for full object. | Describes Kubernetes source configuration. | +| [sources.k8s-create-events.kubernetes.namespaces](./values.yaml#L360) | object | `{"include":[".*"]}` | Describes namespaces for every Kubernetes resources you want to watch or exclude. These namespaces are applied to every resource specified in the resources list. However, every specified resource can override this by using its own namespaces object. | +| [sources.k8s-create-events.kubernetes.event](./values.yaml#L364) | object | `{"types":["create"]}` | Describes event constraints for Kubernetes resources. These constraints are applied for every resource specified in the `resources` list, unless they are overridden by the resource's own `events` object. | +| [sources.k8s-create-events.kubernetes.event.types](./values.yaml#L366) | list | `["create"]` | Lists all event types to be watched. | +| [sources.k8s-create-events.kubernetes.resources](./values.yaml#L371) | list | See the `values.yaml` file for full object. | Describes the Kubernetes resources you want to watch. | +| [sources.prometheus.botkube/prometheus.enabled](./values.yaml#L388) | bool | `false` | If true, enables `prometheus` source. | +| [sources.prometheus.botkube/prometheus.config.url](./values.yaml#L391) | string | `"http://localhost:9090"` | Prometheus endpoint without api version and resource. | +| [sources.prometheus.botkube/prometheus.config.ignoreOldAlerts](./values.yaml#L393) | bool | `true` | If set as true, Prometheus source plugin will not send alerts that is created before plugin start time. | +| [sources.prometheus.botkube/prometheus.config.alertStates](./values.yaml#L395) | list | `["firing","pending","inactive"]` | Only the alerts that have state provided in this config will be sent as notification. https://pkg.go.dev/github.com/prometheus/prometheus/rules#AlertState | +| [sources.prometheus.botkube/prometheus.config.log](./values.yaml#L397) | object | `{"level":"info"}` | Logging configuration | +| [sources.prometheus.botkube/prometheus.config.log.level](./values.yaml#L399) | string | `"info"` | Log level | +| [filters](./values.yaml#L405) | object | See the `values.yaml` file for full object. | Filter settings for various sources. Currently, all filters are globally enabled or disabled. You can enable or disable filters with `@Botkube enable/disable filters` commands. | +| [filters.kubernetes.objectAnnotationChecker](./values.yaml#L408) | bool | `true` | If true, enables support for `botkube.io/disable` and `botkube.io/channel` resource annotations. | +| [filters.kubernetes.nodeEventsChecker](./values.yaml#L410) | bool | `true` | If true, filters out Node-related events that are not important. | +| [executors](./values.yaml#L418) | object | See the `values.yaml` file for full object. | Map of executors. Executor contains configuration for running `kubectl` commands. The property name under `executors` is an alias for a given configuration. You can define multiple executor configurations with different names. Key name is used as a binding reference. | +| [executors.kubectl-read-only.kubectl.namespaces.include](./values.yaml#L426) | list | `[".*"]` | List of allowed Kubernetes Namespaces for command execution. It can also contain a regex expressions: `- ".*"` - to specify all Namespaces. | +| [executors.kubectl-read-only.kubectl.namespaces.exclude](./values.yaml#L431) | list | `[]` | List of ignored Kubernetes Namespace. It can also contain a regex expressions: `- "test-.*"` - to specify all Namespaces. | +| [executors.kubectl-read-only.kubectl.enabled](./values.yaml#L433) | bool | `false` | If true, enables `kubectl` commands execution. | +| [executors.kubectl-read-only.kubectl.commands.verbs](./values.yaml#L437) | list | `["api-resources","api-versions","cluster-info","describe","explain","get","logs","top"]` | Configures which `kubectl` methods are allowed. | +| [executors.kubectl-read-only.kubectl.commands.resources](./values.yaml#L439) | list | `["deployments","pods","namespaces","daemonsets","statefulsets","storageclasses","nodes","configmaps","services","ingresses"]` | Configures which K8s resource are allowed. | +| [executors.kubectl-read-only.kubectl.defaultNamespace](./values.yaml#L441) | string | `"default"` | Configures the default Namespace for executing Botkube `kubectl` commands. If not set, uses the 'default'. | +| [executors.kubectl-read-only.kubectl.restrictAccess](./values.yaml#L443) | bool | `false` | If true, enables commands execution from configured channel only. | +| [executors.helm.botkube/helm.enabled](./values.yaml#L450) | bool | `false` | If true, enables `helm` commands execution. | +| [executors.helm.botkube/helm.config.helmDriver](./values.yaml#L453) | string | `"secret"` | Allowed values are configmap, secret, memory. | +| [executors.helm.botkube/helm.config.helmConfigDir](./values.yaml#L455) | string | `"/tmp/helm/"` | Location for storing Helm configuration. | +| [executors.helm.botkube/helm.config.helmCacheDir](./values.yaml#L457) | string | `"/tmp/helm/.cache"` | Location for storing cached files. Must be under the Helm config directory. | +| [aliases](./values.yaml#L465) | object | See the `values.yaml` file for full object. | Custom aliases for given commands. The aliases are replaced with the underlying command before executing it. Aliases can replace a single word or multiple ones. For example, you can define a `k` alias for `kubectl`, or `kgp` for `kubectl get pods`. | +| [existingCommunicationsSecretName](./values.yaml#L485) | string | `""` | Configures existing Secret with communication settings. It MUST be in the `botkube` Namespace. To reload Botkube once it changes, add label `botkube.io/config-watch: "true"`. | +| [communications](./values.yaml#L492) | object | See the `values.yaml` file for full object. | Map of communication groups. Communication group contains settings for multiple communication platforms. The property name under `communications` object is an alias for a given configuration group. You can define multiple communication groups with different names. | +| [communications.default-group.socketSlack.enabled](./values.yaml#L497) | bool | `false` | If true, enables Slack bot. | +| [communications.default-group.socketSlack.channels](./values.yaml#L501) | object | `{"default":{"bindings":{"executors":["kubectl-read-only","helm"],"sources":["k8s-err-events","k8s-recommendation-events"]},"name":"SLACK_CHANNEL"}}` | Map of configured channels. The property name under `channels` object is an alias for a given configuration. | +| [communications.default-group.socketSlack.channels.default.name](./values.yaml#L504) | string | `"SLACK_CHANNEL"` | Slack channel name without '#' prefix where you have added Botkube and want to receive notifications in. | +| [communications.default-group.socketSlack.channels.default.bindings.executors](./values.yaml#L507) | list | `["kubectl-read-only","helm"]` | Executors configuration for a given channel. | +| [communications.default-group.socketSlack.channels.default.bindings.sources](./values.yaml#L511) | list | `["k8s-err-events","k8s-recommendation-events"]` | Notification sources configuration for a given channel. | +| [communications.default-group.socketSlack.botToken](./values.yaml#L516) | string | `""` | Slack bot token for your own Slack app. [Ref doc](https://api.slack.com/authentication/token-types). | +| [communications.default-group.socketSlack.appToken](./values.yaml#L519) | string | `""` | Slack app-level token for your own Slack app. [Ref doc](https://api.slack.com/authentication/token-types). | +| [communications.default-group.socketSlack.notification.type](./values.yaml#L522) | string | `"short"` | Configures notification type that are sent. Possible values: `short`, `long`. | +| [communications.default-group.mattermost.enabled](./values.yaml#L526) | bool | `false` | If true, enables Mattermost bot. | +| [communications.default-group.mattermost.botName](./values.yaml#L528) | string | `"Botkube"` | User in Mattermost which belongs the specified Personal Access token. | +| [communications.default-group.mattermost.url](./values.yaml#L530) | string | `"MATTERMOST_SERVER_URL"` | The URL (including http/https schema) where Mattermost is running. e.g https://example.com:9243 | +| [communications.default-group.mattermost.token](./values.yaml#L532) | string | `"MATTERMOST_TOKEN"` | Personal Access token generated by Botkube user. | +| [communications.default-group.mattermost.team](./values.yaml#L534) | string | `"MATTERMOST_TEAM"` | The Mattermost Team name where Botkube is added. | +| [communications.default-group.mattermost.channels](./values.yaml#L538) | object | `{"default":{"bindings":{"executors":["kubectl-read-only","helm"],"sources":["k8s-err-events","k8s-recommendation-events"]},"name":"MATTERMOST_CHANNEL","notification":{"disabled":false}}}` | Map of configured channels. The property name under `channels` object is an alias for a given configuration. | +| [communications.default-group.mattermost.channels.default.name](./values.yaml#L542) | string | `"MATTERMOST_CHANNEL"` | The Mattermost channel name for receiving Botkube alerts. The Botkube user needs to be added to it. | +| [communications.default-group.mattermost.channels.default.notification.disabled](./values.yaml#L545) | bool | `false` | If true, the notifications are not sent to the channel. They can be enabled with `@Botkube` command anytime. | +| [communications.default-group.mattermost.channels.default.bindings.executors](./values.yaml#L548) | list | `["kubectl-read-only","helm"]` | Executors configuration for a given channel. | +| [communications.default-group.mattermost.channels.default.bindings.sources](./values.yaml#L552) | list | `["k8s-err-events","k8s-recommendation-events"]` | Notification sources configuration for a given channel. | +| [communications.default-group.mattermost.notification.type](./values.yaml#L557) | string | `"short"` | Configures notification type that are sent. Possible values: `short`, `long`. | +| [communications.default-group.teams.enabled](./values.yaml#L562) | bool | `false` | If true, enables MS Teams bot. | +| [communications.default-group.teams.botName](./values.yaml#L564) | string | `"Botkube"` | The Bot name set while registering Bot to MS Teams. | +| [communications.default-group.teams.appID](./values.yaml#L566) | string | `"APPLICATION_ID"` | The Botkube application ID generated while registering Bot to MS Teams. | +| [communications.default-group.teams.appPassword](./values.yaml#L568) | string | `"APPLICATION_PASSWORD"` | The Botkube application password generated while registering Bot to MS Teams. | +| [communications.default-group.teams.bindings.executors](./values.yaml#L571) | list | `["kubectl-read-only","helm"]` | Executor bindings apply to all MS Teams channels where Botkube has access to. | +| [communications.default-group.teams.bindings.sources](./values.yaml#L575) | list | `["k8s-err-events","k8s-recommendation-events"]` | Source bindings apply to all channels which have notification turned on with `@Botkube enable notifications` command. | +| [communications.default-group.teams.messagePath](./values.yaml#L579) | string | `"/bots/teams"` | The path in endpoint URL provided while registering Botkube to MS Teams. | +| [communications.default-group.teams.port](./values.yaml#L581) | int | `3978` | The Service port for bot endpoint on Botkube container. | +| [communications.default-group.discord.enabled](./values.yaml#L586) | bool | `false` | If true, enables Discord bot. | +| [communications.default-group.discord.token](./values.yaml#L588) | string | `"DISCORD_TOKEN"` | Botkube Bot Token. | +| [communications.default-group.discord.botID](./values.yaml#L590) | string | `"DISCORD_BOT_ID"` | Botkube Application Client ID. | +| [communications.default-group.discord.channels](./values.yaml#L594) | object | `{"default":{"bindings":{"executors":["kubectl-read-only","helm"],"sources":["k8s-err-events","k8s-recommendation-events"]},"id":"DISCORD_CHANNEL_ID","notification":{"disabled":false}}}` | Map of configured channels. The property name under `channels` object is an alias for a given configuration. | +| [communications.default-group.discord.channels.default.id](./values.yaml#L598) | string | `"DISCORD_CHANNEL_ID"` | Discord channel ID for receiving Botkube alerts. The Botkube user needs to be added to it. | +| [communications.default-group.discord.channels.default.notification.disabled](./values.yaml#L601) | bool | `false` | If true, the notifications are not sent to the channel. They can be enabled with `@Botkube` command anytime. | +| [communications.default-group.discord.channels.default.bindings.executors](./values.yaml#L604) | list | `["kubectl-read-only","helm"]` | Executors configuration for a given channel. | +| [communications.default-group.discord.channels.default.bindings.sources](./values.yaml#L608) | list | `["k8s-err-events","k8s-recommendation-events"]` | Notification sources configuration for a given channel. | +| [communications.default-group.discord.notification.type](./values.yaml#L613) | string | `"short"` | Configures notification type that are sent. Possible values: `short`, `long`. | +| [communications.default-group.elasticsearch.enabled](./values.yaml#L618) | bool | `false` | If true, enables Elasticsearch. | +| [communications.default-group.elasticsearch.awsSigning.enabled](./values.yaml#L622) | bool | `false` | If true, enables awsSigning using IAM for Elasticsearch hosted on AWS. Make sure AWS environment variables are set. [Ref doc](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html). | +| [communications.default-group.elasticsearch.awsSigning.awsRegion](./values.yaml#L624) | string | `"us-east-1"` | AWS region where Elasticsearch is deployed. | +| [communications.default-group.elasticsearch.awsSigning.roleArn](./values.yaml#L626) | string | `""` | AWS IAM Role arn to assume for credentials, use this only if you don't want to use the EC2 instance role or not running on AWS instance. | +| [communications.default-group.elasticsearch.server](./values.yaml#L628) | string | `"ELASTICSEARCH_ADDRESS"` | The server URL, e.g https://example.com:9243 | +| [communications.default-group.elasticsearch.username](./values.yaml#L630) | string | `"ELASTICSEARCH_USERNAME"` | Basic Auth username. | +| [communications.default-group.elasticsearch.password](./values.yaml#L632) | string | `"ELASTICSEARCH_PASSWORD"` | Basic Auth password. | +| [communications.default-group.elasticsearch.skipTLSVerify](./values.yaml#L635) | bool | `false` | If true, skips the verification of TLS certificate of the Elastic nodes. It's useful for clusters with self-signed certificates. | +| [communications.default-group.elasticsearch.indices](./values.yaml#L639) | object | `{"default":{"bindings":{"sources":["k8s-err-events","k8s-recommendation-events"]},"name":"botkube","replicas":0,"shards":1,"type":"botkube-event"}}` | Map of configured indices. The `indices` property name is an alias for a given configuration. | +| [communications.default-group.elasticsearch.indices.default.name](./values.yaml#L642) | string | `"botkube"` | Configures Elasticsearch index settings. | +| [communications.default-group.elasticsearch.indices.default.bindings.sources](./values.yaml#L648) | list | `["k8s-err-events","k8s-recommendation-events"]` | Notification sources configuration for a given index. | +| [communications.default-group.webhook.enabled](./values.yaml#L655) | bool | `false` | If true, enables Webhook. | +| [communications.default-group.webhook.url](./values.yaml#L657) | string | `"WEBHOOK_URL"` | The Webhook URL, e.g.: https://example.com:80 | +| [communications.default-group.webhook.bindings.sources](./values.yaml#L660) | list | `["k8s-err-events","k8s-recommendation-events"]` | Notification sources configuration for the webhook. | +| [communications.default-group.slack](./values.yaml#L670) | object | See the `values.yaml` file for full object. | Settings for deprecated Slack integration. **DEPRECATED:** Legacy Slack integration has been deprecated and removed from the Slack App Directory. Use `socketSlack` instead. Read more here: https://docs.botkube.io/installation/slack/ | +| [settings.clusterName](./values.yaml#L691) | string | `"not-configured"` | Cluster name to differentiate incoming messages. | +| [settings.lifecycleServer](./values.yaml#L694) | object | `{"enabled":true,"port":2113}` | Server configuration which exposes functionality related to the app lifecycle. | +| [settings.healthPort](./values.yaml#L697) | int | `2114` | | +| [settings.upgradeNotifier](./values.yaml#L699) | bool | `true` | If true, notifies about new Botkube releases. | +| [settings.log.level](./values.yaml#L703) | string | `"info"` | Sets one of the log levels. Allowed values: `info`, `warn`, `debug`, `error`, `fatal`, `panic`. | +| [settings.log.disableColors](./values.yaml#L705) | bool | `false` | If true, disable ANSI colors in logging. | +| [settings.systemConfigMap](./values.yaml#L708) | object | `{"name":"botkube-system"}` | Botkube's system ConfigMap where internal data is stored. | +| [settings.persistentConfig](./values.yaml#L713) | object | `{"runtime":{"configMap":{"annotations":{},"name":"botkube-runtime-config"},"fileName":"_runtime_state.yaml"},"startup":{"configMap":{"annotations":{},"name":"botkube-startup-config"},"fileName":"_startup_state.yaml"}}` | Persistent config contains ConfigMap where persisted configuration is stored. The persistent configuration is evaluated from both chart upgrade and Botkube commands used in runtime. | +| [ssl.enabled](./values.yaml#L728) | bool | `false` | If true, specify cert path in `config.ssl.cert` property or K8s Secret in `config.ssl.existingSecretName`. | +| [ssl.existingSecretName](./values.yaml#L734) | string | `""` | Using existing SSL Secret. It MUST be in `botkube` Namespace. | +| [ssl.cert](./values.yaml#L737) | string | `""` | SSL Certificate file e.g certs/my-cert.crt. | +| [service](./values.yaml#L740) | object | `{"name":"metrics","port":2112,"targetPort":2112}` | Configures Service settings for ServiceMonitor CR. | +| [ingress](./values.yaml#L747) | object | `{"annotations":{"kubernetes.io/ingress.class":"nginx"},"create":false,"host":"HOST","tls":{"enabled":false,"secretName":""}}` | Configures Ingress settings that exposes MS Teams endpoint. [Ref doc](https://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource). | +| [serviceMonitor](./values.yaml#L758) | object | `{"enabled":false,"interval":"10s","labels":{},"path":"/metrics","port":"metrics"}` | Configures ServiceMonitor settings. [Ref doc](https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#servicemonitor). | +| [deployment.annotations](./values.yaml#L768) | object | `{}` | Extra annotations to pass to the Botkube Deployment. | +| [extraAnnotations](./values.yaml#L775) | object | `{}` | Extra annotations to pass to the Botkube Pod. | +| [extraLabels](./values.yaml#L777) | object | `{}` | Extra labels to pass to the Botkube Pod. | +| [priorityClassName](./values.yaml#L779) | string | `""` | Priority class name for the Botkube Pod. | +| [nameOverride](./values.yaml#L782) | string | `""` | Fully override "botkube.name" template. | +| [fullnameOverride](./values.yaml#L784) | string | `""` | Fully override "botkube.fullname" template. | +| [resources](./values.yaml#L790) | object | `{}` | The Botkube Pod resource request and limits. We usually recommend not to specify default resources and to leave this as a conscious choice for the user. This also increases chances charts run on environments with little resources, such as Minikube. [Ref docs](https://kubernetes.io/docs/user-guide/compute-resources/) | +| [extraEnv](./values.yaml#L802) | list | `[]` | Extra environment variables to pass to the Botkube container. [Ref docs](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#environment-variables). | +| [extraVolumes](./values.yaml#L814) | list | `[]` | Extra volumes to pass to the Botkube container. Mount it later with extraVolumeMounts. [Ref docs](https://kubernetes.io/docs/reference/kubernetes-api/config-and-storage-resources/volume/#Volume). | +| [extraVolumeMounts](./values.yaml#L829) | list | `[]` | Extra volume mounts to pass to the Botkube container. [Ref docs](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#volumes-1). | +| [nodeSelector](./values.yaml#L847) | object | `{}` | Node labels for Botkube Pod assignment. [Ref doc](https://kubernetes.io/docs/user-guide/node-selection/). | +| [tolerations](./values.yaml#L851) | list | `[]` | Tolerations for Botkube Pod assignment. [Ref doc](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/). | +| [affinity](./values.yaml#L855) | object | `{}` | Affinity for Botkube Pod assignment. [Ref doc](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity). | +| [rbac](./values.yaml#L859) | object | `{"create":true,"rules":[{"apiGroups":["*"],"resources":["*"],"verbs":["get","watch","list"]}]}` | Role Based Access for Botkube Pod. [Ref doc](https://kubernetes.io/docs/admin/authorization/rbac/). | +| [serviceAccount.create](./values.yaml#L868) | bool | `true` | If true, a ServiceAccount is automatically created. | +| [serviceAccount.name](./values.yaml#L871) | string | `""` | The name of the service account to use. If not set, a name is generated using the fullname template. | +| [serviceAccount.annotations](./values.yaml#L873) | object | `{}` | Extra annotations for the ServiceAccount. | +| [extraObjects](./values.yaml#L876) | list | `[]` | Extra Kubernetes resources to create. Helm templating is allowed as it is evaluated before creating the resources. | +| [analytics.disable](./values.yaml#L904) | bool | `false` | If true, sending anonymous analytics is disabled. To learn what date we collect, see [Privacy Policy](https://docs.botkube.io/privacy#privacy-policy). | +| [configWatcher.enabled](./values.yaml#L909) | bool | `true` | If true, restarts the Botkube Pod on config changes. | +| [configWatcher.tmpDir](./values.yaml#L911) | string | `"/tmp/watched-cfg/"` | Directory, where watched configuration resources are stored. | +| [configWatcher.initialSyncTimeout](./values.yaml#L914) | int | `0` | Timeout for the initial Config Watcher sync. If set to 0, waiting for Config Watcher sync will be skipped. In a result, configuration changes may not reload Botkube app during the first few seconds after Botkube startup. | +| [configWatcher.image.registry](./values.yaml#L917) | string | `"ghcr.io"` | Config watcher image registry. | +| [configWatcher.image.repository](./values.yaml#L919) | string | `"kubeshop/k8s-sidecar"` | Config watcher image repository. | +| [configWatcher.image.tag](./values.yaml#L921) | string | `"ignore-initial-events"` | Config watcher image tag. | +| [configWatcher.image.pullPolicy](./values.yaml#L923) | string | `"IfNotPresent"` | Config watcher image pull policy. | +| [plugins](./values.yaml#L926) | object | `{"cacheDir":"/tmp","repositories":{"botkube":{"url":"https://github.com/kubeshop/botkube/releases/download/v9.99.9-dev/plugins-index.yaml"}}}` | Configuration for Botkube executors and sources plugins. | +| [plugins.cacheDir](./values.yaml#L928) | string | `"/tmp"` | Directory, where downloaded plugins are cached. | +| [plugins.repositories](./values.yaml#L930) | object | `{"botkube":{"url":"https://github.com/kubeshop/botkube/releases/download/v9.99.9-dev/plugins-index.yaml"}}` | List of plugins repositories. | +| [plugins.repositories.botkube](./values.yaml#L932) | object | `{"url":"https://github.com/kubeshop/botkube/releases/download/v9.99.9-dev/plugins-index.yaml"}` | This repository serves officially supported Botkube plugins. | +| [config](./values.yaml#L936) | object | `{"provider":{"endpoint":"","identifier":""}}` | Configuration for remote Botkube settings | +| [config.provider](./values.yaml#L938) | object | `{"endpoint":"","identifier":""}` | Base provider definition | +| [config.provider.identifier](./values.yaml#L940) | string | `""` | Unique identifier for remote Botkube settings | +| [config.provider.endpoint](./values.yaml#L942) | string | `""` | Endpoint to fetch Botkube settings from | ### AWS IRSA on EKS support diff --git a/helm/botkube/values.yaml b/helm/botkube/values.yaml index 07634420f..b6d3d1256 100644 --- a/helm/botkube/values.yaml +++ b/helm/botkube/values.yaml @@ -130,14 +130,15 @@ sources: # These namespaces are applied to every resource specified in the resources list. # However, every specified resource can override this by using its own namespaces object. namespaces: &k8s-events-namespaces - # Include contains a list of allowed Namespaces. - # It can also contain a regex expressions: + # -- Include contains a list of allowed Namespaces. + # It can also contain regex expressions: # `- ".*"` - to specify all Namespaces. include: - ".*" - # Exclude contains a list of Namespaces to be ignored even if allowed by Include. - # It can also contain a regex expressions: + # -- Exclude contains a list of Namespaces to be ignored even if allowed by Include. + # It can also contain regex expressions: # `- "test-.*"` - to specif all Namespaces with `test-` prefix. + # Exclude list is checked before the Include list. # exclude: [] # -- Describes event constraints for Kubernetes resources. @@ -148,14 +149,28 @@ sources: - create - delete - error - # -- Optional regex to filter events by event reason. - reason: "" - # -- Optional regex to filter events by message. If a given event has multiple messages, it is considered a match if any of the messages match the regex. - message: "" - - # -- Filters Kubernetes resources to watch by annotations. + # -- Optional list of exact values or regex patterns to filter events by event reason. + # Skipped, if both include/exclude lists are empty. + reason: + # -- Include contains a list of allowed values. It can also contain regex expressions. + include: [] + # -- Exclude contains a list of values to be ignored even if allowed by Include. It can also contain regex expressions. + # Exclude list is checked before the Include list. + exclude: [] + # -- Optional list of exact values or regex patterns to filter event by event message. Skipped, if both include/exclude lists are empty. + # If a given event has multiple messages, it is considered a match if any of the messages match the constraints. + message: + # -- Include contains a list of allowed values. It can also contain regex expressions. + include: [] + # -- Exclude contains a list of values to be ignored even if allowed by Include. It can also contain regex expressions. + # Exclude list is checked before the Include list. + exclude: [] + + # -- Filters Kubernetes resources to watch by annotations. Each resource needs to have all the specified annotations. + # Regex expressions are not supported. annotations: {} - # -- Filters Kubernetes resources to watch by labels. + # -- Filters Kubernetes resources to watch by labels. Each resource needs to have all the specified labels. + # Regex expressions are not supported. labels: {} # -- Describes the Kubernetes resources to watch. @@ -165,18 +180,31 @@ sources: # @default -- See the `values.yaml` file for full object. resources: - type: v1/pods - # namespaces: # Overrides 'source'.kubernetes.namespaces - # include: - # - ".*" - # exclude: [] - # annotations: {} # Overrides 'source'.kubernetes.annotations - # labels: {} # Overrides 'source'.kubernetes.labels - # name: "" # Optional resource name regex. - # event: - # reason: "" # Overrides 'source'.kubernetes.event.reason - # message: "" # Overrides 'source'.kubernetes.event.message - # types: # Overrides 'source'.kubernetes.event.types - # - create + namespaces: # Overrides 'source'.kubernetes.namespaces + include: + - ".*" + exclude: [] + annotations: {} # Overrides 'source'.kubernetes.annotations + labels: {} # Overrides 'source'.kubernetes.labels + # Optional resource name constraints. + name: + # Include contains a list of allowed values. It can also contain regex expressions. + include: [] + # Exclude contains a list of values to be ignored even if allowed by Include. It can also contain regex expressions. + # Exclude list is checked before the Include list. + exclude: [] + event: + # Overrides 'source'.kubernetes.event.reason + reason: + include: [] + exclude: [] + # Overrides 'source'.kubernetes.event.message + message: + include: [] + exclude: [] + # Overrides 'source'.kubernetes.event.types + types: + - create - type: v1/services - type: networking.k8s.io/v1/ingresses diff --git a/internal/source/registration.go b/internal/source/registration.go index 147a261e6..edbfde1ef 100644 --- a/internal/source/registration.go +++ b/internal/source/registration.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "reflect" - "regexp" "strings" "github.com/sirupsen/logrus" @@ -145,86 +144,94 @@ func (r registration) sourcesForEvent(routes []route, event event.Event) ([]stri errs := multierror.New() for _, route := range routes { - // event reason - match, err := matchRegexForStringIfDefined(route.event.Reason, event.Reason) + shouldSend, err := r.shouldSendEventToRoute(route, event) if err != nil { errs = multierror.Append(errs, err) continue } - if !match { - r.log.Debugf("Ignoring as reason %q doesn't match regex %q", event.Reason, route.event.Reason) - continue - } - // event message - match, err = matchRegexForStringsIfDefined(route.event.Message, event.Messages) - if err != nil { - errs = multierror.Append(errs, err) - continue - } - if !match { - r.log.Debugf("Ignoring as messages %q don't match regex %q", strings.Join(event.Messages, ";"), route.event.Message) + if !shouldSend { continue } - // resource name - match, err = matchRegexForStringIfDefined(route.resourceName, event.Name) + out = append(out, route.source) + } + + return out, errs.ErrorOrNil() +} + +func (r registration) shouldSendEventToRoute(route route, event event.Event) (bool, error) { + // event reason + if route.event.Reason.AreConstraintsDefined() { + match, err := route.event.Reason.IsAllowed(event.Reason) if err != nil { - errs = multierror.Append(errs, err) - continue + return false, err } if !match { - r.log.Debugf("Ignoring as resource name %q doesn't match regex %q", event.Name, route.resourceName) - continue + r.log.Debugf("Ignoring as reason %q doesn't match regex %q", event.Reason, route.event.Reason) + return false, nil } + } - // namespace - if event.Namespace != "" && !route.namespaces.IsAllowed(event.Namespace) { - continue - } + // event message + if route.event.Message.AreConstraintsDefined() { + var anyMsgMatches bool + var lastErr error - // annotations - if !kvsSatisfiedForMap(route.annotations, event.ObjectMeta.Annotations) { - continue + for _, msg := range event.Messages { + match, err := route.event.Message.IsAllowed(msg) + if err != nil { + lastErr = err + continue + } + if match { + anyMsgMatches = true + break + } } - - // labels - if !kvsSatisfiedForMap(route.labels, event.ObjectMeta.Labels) { - continue + if lastErr != nil { + return false, lastErr + } + if !anyMsgMatches { + r.log.Debugf("Ignoring as any event message from %q doesn't match regex %q", strings.Join(event.Messages, ";"), route.event.Message) + return false, nil } - - out = append(out, route.source) } - return out, errs.ErrorOrNil() -} - -func matchRegexForStringIfDefined(regexStr, str string) (bool, error) { - return matchRegexForStringsIfDefined(regexStr, []string{str}) -} - -func matchRegexForStringsIfDefined(regexStr string, str []string) (bool, error) { - if regexStr == "" { - return true, nil + // resource name + if route.resourceName.AreConstraintsDefined() { + allowed, err := route.resourceName.IsAllowed(event.Name) + if err != nil { + return false, err + } + if !allowed { + r.log.Debugf("Ignoring as resource name %q doesn't match regex %q", event.Name, route.resourceName) + return false, nil + } } - regex, err := regexp.Compile(regexStr) - if err != nil { - return false, fmt.Errorf("while compiling regex: %w", err) + // namespace + if event.Namespace != "" && route.namespaces.AreConstraintsDefined() { + match, err := route.namespaces.IsAllowed(event.Namespace) + if err != nil { + return false, err + } + if !match { + return false, nil + } } - if len(str) == 0 { - // no messages, so let's check if regex matches empty string - str = append(str, "") + // annotations + if !kvsSatisfiedForMap(route.annotations, event.ObjectMeta.Annotations) { + return false, nil } - for _, s := range str { - if regex.MatchString(s) { - return true, nil - } + // labels + if !kvsSatisfiedForMap(route.labels, event.ObjectMeta.Labels) { + return false, nil } - return false, nil + return true, nil } func kvsSatisfiedForMap(expectedKV, obj map[string]string) bool { diff --git a/internal/source/registration_test.go b/internal/source/registration_test.go index 362a70a33..299343d24 100644 --- a/internal/source/registration_test.go +++ b/internal/source/registration_test.go @@ -29,14 +29,20 @@ func TestSourcesForEvent(t *testing.T) { { source: "success", event: config.KubernetesEvent{ - Reason: "^NodeNotReady", + Reason: config.RegexConstraints{ + Include: []string{"^NodeNotReady"}, + }, }, namespaces: allNsCfg, }, { - source: "fail", - resourceName: "^Created", - namespaces: allNsCfg, + source: "fail", + event: config.KubernetesEvent{ + Reason: config.RegexConstraints{ + Include: []string{"^Created"}, + }, + }, + namespaces: allNsCfg, }, }, Event: event.Event{ @@ -51,14 +57,20 @@ func TestSourcesForEvent(t *testing.T) { { source: "success", event: config.KubernetesEvent{ - Reason: "^NodeNotReady", + Reason: config.RegexConstraints{ + Include: []string{"^NodeNotReady"}, + }, }, namespaces: allNsCfg, }, { - source: "error", - resourceName: "[", - namespaces: allNsCfg, + source: "error", + event: config.KubernetesEvent{ + Reason: config.RegexConstraints{ + Exclude: []string{"["}, + }, + }, + namespaces: allNsCfg, }, }, Event: event.Event{ @@ -68,7 +80,7 @@ func TestSourcesForEvent(t *testing.T) { ExpectedResult: []string{"success"}, ExpectedErrMessage: heredoc.Docf(` 1 error occurred: - * while compiling regex: error parsing regexp: missing closing ]: %s`, "`[`"), + * while matching "NodeNotReady" with exclude regex "[": error parsing regexp: missing closing ]: %s`, "`[`"), }, { Name: "Event message - success", @@ -76,21 +88,47 @@ func TestSourcesForEvent(t *testing.T) { { source: "success", event: config.KubernetesEvent{ - Message: "^Status.*", + Message: config.RegexConstraints{ + Include: []string{"^Status.*"}, + }, }, namespaces: allNsCfg, }, { source: "success2", event: config.KubernetesEvent{ - Message: "^Second.*", + Message: config.RegexConstraints{ + Include: []string{"^Second.*"}, + }, + }, + namespaces: allNsCfg, + }, + { + source: "success3", + event: config.KubernetesEvent{ + Message: config.RegexConstraints{ + Include: []string{".*"}, + Exclude: []string{"^Something.*"}, + }, }, namespaces: allNsCfg, }, { source: "fail", event: config.KubernetesEvent{ - Message: "^Resource", + Message: config.RegexConstraints{ + Include: []string{"^Resource"}, + }, + }, + namespaces: allNsCfg, + }, + { + source: "fail2", + event: config.KubernetesEvent{ + Message: config.RegexConstraints{ + Include: []string{".*"}, + Exclude: []string{"^Second", "^Status", "^Third"}, + }, }, namespaces: allNsCfg, }, @@ -103,7 +141,7 @@ func TestSourcesForEvent(t *testing.T) { "Third", }, }, - ExpectedResult: []string{"success", "success2"}, + ExpectedResult: []string{"success", "success2", "success3"}, }, { Name: "Event message - error", @@ -111,14 +149,18 @@ func TestSourcesForEvent(t *testing.T) { { source: "success", event: config.KubernetesEvent{ - Message: "^Status.*", + Message: config.RegexConstraints{ + Include: []string{"^Status.*"}, + }, }, namespaces: allNsCfg, }, { source: "error", event: config.KubernetesEvent{ - Message: "[", + Message: config.RegexConstraints{ + Include: []string{"["}, + }, }, namespaces: allNsCfg, }, @@ -134,20 +176,24 @@ func TestSourcesForEvent(t *testing.T) { ExpectedResult: []string{"success"}, ExpectedErrMessage: heredoc.Docf(` 1 error occurred: - * while compiling regex: error parsing regexp: missing closing ]: %s`, "`[`"), + * while matching "Third" with include regex "[": error parsing regexp: missing closing ]: %s`, "`[`"), }, { Name: "Resource name - success", Routes: []route{ { - source: "success", - resourceName: "^test-.*", - namespaces: allNsCfg, + source: "success", + resourceName: config.RegexConstraints{ + Include: []string{"^test-.*"}, + }, + namespaces: allNsCfg, }, { - source: "fail", - resourceName: "^one-.*", - namespaces: allNsCfg, + source: "fail", + resourceName: config.RegexConstraints{ + Include: []string{"^one-.*"}, + }, + namespaces: allNsCfg, }, }, Event: event.Event{ @@ -159,14 +205,18 @@ func TestSourcesForEvent(t *testing.T) { Name: "Resource name - error", Routes: []route{ { - source: "success", - resourceName: "^test-.*", - namespaces: allNsCfg, + source: "success", + resourceName: config.RegexConstraints{ + Include: []string{"^test-.*"}, + }, + namespaces: allNsCfg, }, { - source: "error", - resourceName: "[", - namespaces: allNsCfg, + source: "error", + resourceName: config.RegexConstraints{ + Include: []string{"["}, + }, + namespaces: allNsCfg, }, }, Event: event.Event{ @@ -175,7 +225,7 @@ func TestSourcesForEvent(t *testing.T) { ExpectedResult: []string{"success"}, ExpectedErrMessage: heredoc.Docf(` 1 error occurred: - * while compiling regex: error parsing regexp: missing closing ]: %s`, "`[`"), + * while matching "test-one" with include regex "[": error parsing regexp: missing closing ]: %s`, "`[`"), }, { Name: "Namespace", diff --git a/internal/source/router.go b/internal/source/router.go index 105f2c355..fc900a893 100644 --- a/internal/source/router.go +++ b/internal/source/router.go @@ -21,7 +21,7 @@ type eventHandler func(ctx context.Context, event event.Event, sources []string, type route struct { source string - resourceName string + resourceName config.RegexConstraints labels map[string]string annotations map[string]string namespaces config.RegexConstraints @@ -414,7 +414,7 @@ func flattenEventTypes(globalEvents []config.EventType, resourceEvents config.Ku // sourceOrResourceNamespaces returns the kubernetes source namespaces // unless the resource namespaces are configured. func sourceOrResourceNamespaces(sourceNs, resourceNs config.RegexConstraints) config.RegexConstraints { - if resourceNs.IsConfigured() { + if resourceNs.AreConstraintsDefined() { return resourceNs } return sourceNs diff --git a/pkg/config/config.go b/pkg/config/config.go index c9e6cda8d..e9120f6bf 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -225,14 +225,14 @@ type KubernetesSource struct { // KubernetesEvent contains configuration for Kubernetes events. type KubernetesEvent struct { - Reason string `yaml:"reason"` - Message string `yaml:"message"` + Reason RegexConstraints `yaml:"reason"` + Message RegexConstraints `yaml:"message"` Types KubernetesResourceEventTypes `yaml:"types"` } // AreConstraintsDefined checks if any of the event constraints are defined. func (e KubernetesEvent) AreConstraintsDefined() bool { - return e.Reason != "" || e.Message != "" + return e.Reason.AreConstraintsDefined() || e.Message.AreConstraintsDefined() } // IsAllowed checks if a given resource event is allowed according to the configuration. @@ -249,11 +249,17 @@ func (r *KubernetesSource) IsAllowed(resourceType, namespace string, eventType E } for _, resource := range r.Resources { - var namespaceAllowed bool - if resource.Namespaces.IsConfigured() { - namespaceAllowed = resource.Namespaces.IsAllowed(namespace) + var nsConstraints RegexConstraints + if resource.Namespaces.AreConstraintsDefined() { + nsConstraints = resource.Namespaces } else { - namespaceAllowed = r.Namespaces.IsAllowed(namespace) + nsConstraints = r.Namespaces + } + + namespaceAllowed, err := nsConstraints.IsAllowed(namespace) + if err != nil { + // regex error, so don't allow the event + return false } if resource.Type == resourceType && @@ -361,7 +367,7 @@ type Analytics struct { // Resource contains resources to watch type Resource struct { Type string `yaml:"type"` - Name string `yaml:"name"` + Name RegexConstraints `yaml:"name"` Namespaces RegexConstraints `yaml:"namespaces"` Annotations map[string]string `yaml:"annotations"` Labels map[string]string `yaml:"labels"` @@ -411,16 +417,16 @@ type RegexConstraints struct { Exclude []string `yaml:"exclude,omitempty"` } -// IsConfigured checks whether the RegexConstraints has any Include/Exclude configuration. -func (r *RegexConstraints) IsConfigured() bool { +// AreConstraintsDefined checks whether the RegexConstraints has any Include/Exclude configuration. +func (r *RegexConstraints) AreConstraintsDefined() bool { return len(r.Include) > 0 || len(r.Exclude) > 0 } // IsAllowed checks if a given value is allowed based on the config. // Firstly, it checks if the value is excluded. If not, then it checks if the value is included. -func (r *RegexConstraints) IsAllowed(value string) bool { +func (r *RegexConstraints) IsAllowed(value string) (bool, error) { if r == nil || value == "" { - return false + return false, nil } // 1. Check if excluded @@ -431,13 +437,16 @@ func (r *RegexConstraints) IsAllowed(value string) bool { } // exact match if excludeNamespace == value { - return false + return false, nil } // regexp matched, err := regexp.MatchString(excludeNamespace, value) - if err == nil && matched { - return false + if err != nil { + return false, fmt.Errorf("while matching %q with exclude regex %q: %v", value, excludeNamespace, err) + } + if matched { + return false, nil } } } @@ -451,19 +460,22 @@ func (r *RegexConstraints) IsAllowed(value string) bool { // exact match if includeNamespace == value { - return true + return true, nil } // regexp matched, err := regexp.MatchString(includeNamespace, value) - if err == nil && matched { - return true + if err != nil { + return false, fmt.Errorf("while matching %q with include regex %q: %v", value, includeNamespace, err) + } + if matched { + return true, nil } } } // 2.1. If not included, return false - return false + return false, nil } // Notification holds notification configuration. diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 064998f8f..93a876894 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -438,11 +438,12 @@ func readTestdataFile(t *testing.T, name string) []byte { return out } -func TestIsNamespaceAllowed(t *testing.T) { +func TestRegexConstraints_IsAllowed(t *testing.T) { tests := map[string]struct { - nsConfig config.RegexConstraints - givenNs string - isAllowed bool + nsConfig config.RegexConstraints + givenNs string + isAllowed bool + expectedErrMessage string }{ "should watch all except ignored ones": { nsConfig: config.RegexConstraints{Include: []string{".*"}, Exclude: []string{"demo", "abc"}}, @@ -474,14 +475,32 @@ func TestIsNamespaceAllowed(t *testing.T) { givenNs: "demo", isAllowed: true, }, + "invalid exclude regex": { + nsConfig: config.RegexConstraints{Include: []string{".*"}, Exclude: []string{"["}}, + givenNs: "demo", + isAllowed: false, + expectedErrMessage: "while matching \"demo\" with exclude regex \"[\": error parsing regexp: missing closing ]: `[`", + }, + "invalid include regex": { + nsConfig: config.RegexConstraints{Include: []string{"["}, Exclude: []string{}}, + givenNs: "demo", + isAllowed: false, + expectedErrMessage: "while matching \"demo\" with include regex \"[\": error parsing regexp: missing closing ]: `[`", + }, } for name, test := range tests { name, test := name, test t.Run(name, func(t *testing.T) { - actual := test.nsConfig.IsAllowed(test.givenNs) - if actual != test.isAllowed { - t.Errorf("expected: %v != actual: %v\n", test.isAllowed, actual) + actual, err := test.nsConfig.IsAllowed(test.givenNs) + + if test.expectedErrMessage != "" { + require.False(t, actual) + require.EqualError(t, err, test.expectedErrMessage) + return } + + require.NoError(t, err) + assert.Equal(t, test.isAllowed, actual) }) } } diff --git a/pkg/config/testdata/TestLoadConfigSuccess/config-all.yaml b/pkg/config/testdata/TestLoadConfigSuccess/config-all.yaml index bf10b4a83..f9ee9a63d 100644 --- a/pkg/config/testdata/TestLoadConfigSuccess/config-all.yaml +++ b/pkg/config/testdata/TestLoadConfigSuccess/config-all.yaml @@ -119,8 +119,10 @@ sources: - ".*" exclude: [ ] event: - reason: ".*" - message: "^Error .*" + reason: + include: ".*" + message: + include: "^Error .*" types: - create - delete @@ -136,8 +138,12 @@ sources: - type: networking.k8s.io/v1/ingresses - type: v1/nodes event: - reason: NodeNotReady - message: "status .*" + reason: + include: + - NodeNotReady + message: + include: + - "status .*" - type: v1/namespaces - type: v1/persistentvolumes - type: v1/persistentvolumeclaims @@ -174,7 +180,8 @@ sources: my-own-annotation: "true" labels: # Overrides 'source'.kubernetes.labels my-own-label: "true" - name: "my-.*" + name: + include: "my-.*" updateSetting: includeDiff: true fields: diff --git a/pkg/config/testdata/TestLoadConfigSuccess/config.golden.yaml b/pkg/config/testdata/TestLoadConfigSuccess/config.golden.yaml index ee9c95c0c..698efa4e6 100644 --- a/pkg/config/testdata/TestLoadConfigSuccess/config.golden.yaml +++ b/pkg/config/testdata/TestLoadConfigSuccess/config.golden.yaml @@ -20,106 +20,134 @@ sources: noLatestImageTag: false labelsSet: true event: - reason: .* - message: ^Error .* + reason: + include: + - .* + message: + include: + - ^Error .* types: - create - delete - error resources: - type: v1/pods - name: "" + name: + include: [] namespaces: include: [] annotations: {} labels: {} event: - reason: "" - message: "" + reason: + include: [] + message: + include: [] types: [] updateSetting: fields: [] includeDiff: false - type: v1/services - name: "" + name: + include: [] namespaces: include: [] annotations: {} labels: {} event: - reason: "" - message: "" + reason: + include: [] + message: + include: [] types: [] updateSetting: fields: [] includeDiff: false - type: networking.k8s.io/v1/ingresses - name: "" + name: + include: [] namespaces: include: [] annotations: {} labels: {} event: - reason: "" - message: "" + reason: + include: [] + message: + include: [] types: [] updateSetting: fields: [] includeDiff: false - type: v1/nodes - name: "" + name: + include: [] namespaces: include: [] annotations: {} labels: {} event: - reason: NodeNotReady - message: status .* + reason: + include: + - NodeNotReady + message: + include: + - status .* types: [] updateSetting: fields: [] includeDiff: false - type: v1/namespaces - name: "" + name: + include: [] namespaces: include: [] annotations: {} labels: {} event: - reason: "" - message: "" + reason: + include: [] + message: + include: [] types: [] updateSetting: fields: [] includeDiff: false - type: v1/persistentvolumes - name: "" + name: + include: [] namespaces: include: [] annotations: {} labels: {} event: - reason: "" - message: "" + reason: + include: [] + message: + include: [] types: [] updateSetting: fields: [] includeDiff: false - type: v1/persistentvolumeclaims - name: "" + name: + include: [] namespaces: include: [] annotations: {} labels: {} event: - reason: "" - message: "" + reason: + include: [] + message: + include: [] types: [] updateSetting: fields: [] includeDiff: false - type: v1/configmaps - name: "" + name: + include: [] namespaces: include: - default @@ -128,73 +156,90 @@ sources: annotations: {} labels: {} event: - reason: "" - message: "" + reason: + include: [] + message: + include: [] types: [] updateSetting: fields: [] includeDiff: false - type: rbac.authorization.k8s.io/v1/roles - name: "" + name: + include: [] namespaces: include: [] annotations: {} labels: {} event: - reason: "" - message: "" + reason: + include: [] + message: + include: [] types: [] updateSetting: fields: [] includeDiff: false - type: rbac.authorization.k8s.io/v1/rolebindings - name: "" + name: + include: [] namespaces: include: [] annotations: {} labels: {} event: - reason: "" - message: "" + reason: + include: [] + message: + include: [] types: [] updateSetting: fields: [] includeDiff: false - type: rbac.authorization.k8s.io/v1/clusterrolebindings - name: "" + name: + include: [] namespaces: include: [] annotations: {} labels: {} event: - reason: "" - message: "" + reason: + include: [] + message: + include: [] types: [] updateSetting: fields: [] includeDiff: false - type: rbac.authorization.k8s.io/v1/clusterroles - name: "" + name: + include: [] namespaces: include: [] annotations: {} labels: {} event: - reason: "" - message: "" + reason: + include: [] + message: + include: [] types: [] updateSetting: fields: [] includeDiff: false - type: apps/v1/daemonsets - name: "" + name: + include: [] namespaces: include: [] annotations: {} labels: {} event: - reason: "" - message: "" + reason: + include: [] + message: + include: [] types: - create - update @@ -206,7 +251,9 @@ sources: - status.numberReady includeDiff: true - type: batch/v1/jobs - name: my-.* + name: + include: + - my-.* namespaces: include: [] annotations: @@ -214,8 +261,10 @@ sources: labels: my-own-label: "true" event: - reason: "" - message: "" + reason: + include: [] + message: + include: [] types: - create - update @@ -227,14 +276,17 @@ sources: - status.conditions[*].type includeDiff: true - type: apps/v1/deployments - name: "" + name: + include: [] namespaces: include: [] annotations: {} labels: {} event: - reason: "" - message: "" + reason: + include: [] + message: + include: [] types: - create - update @@ -246,14 +298,17 @@ sources: - status.availableReplicas includeDiff: true - type: apps/v1/statefulsets - name: "" + name: + include: [] namespaces: include: [] annotations: {} labels: {} event: - reason: "" - message: "" + reason: + include: [] + message: + include: [] types: - create - update diff --git a/pkg/config/testdata/TestLoadConfigWithPlugins/config-all.yaml b/pkg/config/testdata/TestLoadConfigWithPlugins/config-all.yaml index 978caf411..dbc207600 100644 --- a/pkg/config/testdata/TestLoadConfigWithPlugins/config-all.yaml +++ b/pkg/config/testdata/TestLoadConfigWithPlugins/config-all.yaml @@ -26,7 +26,7 @@ sources: namespaces: include: [ ".*" ] resources: - - name: v1/pods + - type: v1/pods botkube/keptn: enabled: true diff --git a/pkg/config/testdata/TestLoadedConfigValidationWarnings/executors-include-warning.yaml b/pkg/config/testdata/TestLoadedConfigValidationWarnings/executors-include-warning.yaml index fa7e63cb4..741564807 100644 --- a/pkg/config/testdata/TestLoadedConfigValidationWarnings/executors-include-warning.yaml +++ b/pkg/config/testdata/TestLoadedConfigValidationWarnings/executors-include-warning.yaml @@ -15,10 +15,11 @@ sources: k8s-events: kubernetes: resources: - - name: v1/pods + - type: v1/pods namespaces: include: [ ".*", "kube-system" ] - events: + event: + types: - create - delete - error diff --git a/pkg/execute/kubectl/merger.go b/pkg/execute/kubectl/merger.go index a349f2790..846347f15 100644 --- a/pkg/execute/kubectl/merger.go +++ b/pkg/execute/kubectl/merger.go @@ -39,7 +39,13 @@ func NewMerger(executors map[string]config.Executors) *Merger { // The order of merging is the same as the order of items specified in the includeBindings list. func (kc *Merger) MergeForNamespace(includeBindings []string, forNamespace string) EnabledKubectl { enabledInNs := func(executor config.Kubectl) bool { - return executor.Enabled && executor.Namespaces.IsAllowed(forNamespace) + nsAllowed, err := executor.Namespaces.IsAllowed(forNamespace) + if err != nil { + // regex error + return false + } + + return executor.Enabled && nsAllowed } return kc.merge(kc.collect(includeBindings, enabledInNs), includeBindings) } diff --git a/pkg/execute/kubectl_cmd_builder.go b/pkg/execute/kubectl_cmd_builder.go index cb236b866..c9401f7ff 100644 --- a/pkg/execute/kubectl_cmd_builder.go +++ b/pkg/execute/kubectl_cmd_builder.go @@ -327,7 +327,14 @@ func (e *KubectlCmdBuilder) tryToGetNamespaceSelect(ctx context.Context, botName initialNamespace = e.appendNamespaceSuffixIfDefault(initialNamespace) for _, item := range allClusterNamespaces.Items { - if !allowedNS.IsAllowed(item.Name) { + allowed, err := allowedNS.IsAllowed(item.Name) + if err != nil { + log.WithField("namespace", item.Name). + WithField("error", err.Error()). + Error("Cannot check if namespace is allowed, so skipping it.") + continue + } + if !allowed { log.WithField("namespace", item.Name).Debug("Namespace is not allowed, so skipping it.") continue }