From ced876da6e442b5b36e84119ef7055832022590d Mon Sep 17 00:00:00 2001 From: Pawel Kosiec Date: Tue, 27 Feb 2024 16:23:49 +0100 Subject: [PATCH] Fix overwriting custom RBAC config and Kubernetes plugin JSON schema (#1401) - Fix overwriting custom RBAC config - Fix Kubernetes extraButtons schema - Remove unused properties --- helm/botkube/README.md | 121 +++++++++--------- helm/botkube/values.yaml | 21 --- internal/analytics/segment_reporter.go | 26 +++- internal/analytics/segment_reporter_test.go | 41 +++++- ...tSegmentReporter_ReportPluginsEnabled.json | 2 +- internal/executor/kubectl/executor.go | 2 +- internal/source/kubernetes/config_schema.json | 78 +++++------ 7 files changed, 155 insertions(+), 136 deletions(-) diff --git a/helm/botkube/README.md b/helm/botkube/README.md index d33f2a041..ce9306828 100644 --- a/helm/botkube/README.md +++ b/helm/botkube/README.md @@ -162,67 +162,66 @@ Controller for the Botkube Slack app which helps you monitor your Kubernetes clu | [communications.default-group.webhook.enabled](./values.yaml#L660) | bool | `false` | If true, enables Webhook. | | [communications.default-group.webhook.url](./values.yaml#L662) | string | `"WEBHOOK_URL"` | The Webhook URL, e.g.: https://example.com:80 | | [communications.default-group.webhook.bindings.sources](./values.yaml#L665) | list | `["k8s-err-events","k8s-recommendation-events"]` | Notification sources configuration for the webhook. | -| [communications.default-group.slack](./values.yaml#L675) | 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#L693) | string | `"not-configured"` | Cluster name to differentiate incoming messages. | -| [settings.healthPort](./values.yaml#L696) | int | `2114` | Health check port. | -| [settings.upgradeNotifier](./values.yaml#L698) | bool | `true` | If true, notifies about new Botkube releases. | -| [settings.log.level](./values.yaml#L702) | string | `"info"` | Sets one of the log levels. Allowed values: `info`, `warn`, `debug`, `error`, `fatal`, `panic`. | -| [settings.log.disableColors](./values.yaml#L704) | bool | `false` | If true, disable ANSI colors in logging. Ignored when `json` formatter is used. | -| [settings.log.formatter](./values.yaml#L706) | string | `"json"` | Configures log format. Allowed values: `text`, `json`. | -| [settings.systemConfigMap](./values.yaml#L709) | object | `{"name":"botkube-system"}` | Botkube's system ConfigMap where internal data is stored. | -| [settings.persistentConfig](./values.yaml#L714) | 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#L729) | bool | `false` | If true, specify cert path in `config.ssl.cert` property or K8s Secret in `config.ssl.existingSecretName`. | -| [ssl.existingSecretName](./values.yaml#L735) | string | `""` | Using existing SSL Secret. It MUST be in `botkube` Namespace. | -| [ssl.cert](./values.yaml#L738) | string | `""` | SSL Certificate file e.g certs/my-cert.crt. | -| [service](./values.yaml#L741) | object | `{"name":"metrics","port":2112,"targetPort":2112}` | Configures Service settings for ServiceMonitor CR. | -| [serviceMonitor](./values.yaml#L748) | 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#L758) | object | `{}` | Extra annotations to pass to the Botkube Deployment. | -| [deployment.livenessProbe](./values.yaml#L760) | object | `{"failureThreshold":35,"initialDelaySeconds":1,"periodSeconds":2,"successThreshold":1,"timeoutSeconds":1}` | Liveness probe. | -| [deployment.livenessProbe.initialDelaySeconds](./values.yaml#L762) | int | `1` | The liveness probe initial delay seconds. | -| [deployment.livenessProbe.periodSeconds](./values.yaml#L764) | int | `2` | The liveness probe period seconds. | -| [deployment.livenessProbe.timeoutSeconds](./values.yaml#L766) | int | `1` | The liveness probe timeout seconds. | -| [deployment.livenessProbe.failureThreshold](./values.yaml#L768) | int | `35` | The liveness probe failure threshold. | -| [deployment.livenessProbe.successThreshold](./values.yaml#L770) | int | `1` | The liveness probe success threshold. | -| [deployment.readinessProbe](./values.yaml#L773) | object | `{"failureThreshold":35,"initialDelaySeconds":1,"periodSeconds":2,"successThreshold":1,"timeoutSeconds":1}` | Readiness probe. | -| [deployment.readinessProbe.initialDelaySeconds](./values.yaml#L775) | int | `1` | The readiness probe initial delay seconds. | -| [deployment.readinessProbe.periodSeconds](./values.yaml#L777) | int | `2` | The readiness probe period seconds. | -| [deployment.readinessProbe.timeoutSeconds](./values.yaml#L779) | int | `1` | The readiness probe timeout seconds. | -| [deployment.readinessProbe.failureThreshold](./values.yaml#L781) | int | `35` | The readiness probe failure threshold. | -| [deployment.readinessProbe.successThreshold](./values.yaml#L783) | int | `1` | The readiness probe success threshold. | -| [extraAnnotations](./values.yaml#L790) | object | `{}` | Extra annotations to pass to the Botkube Pod. | -| [extraLabels](./values.yaml#L792) | object | `{}` | Extra labels to pass to the Botkube Pod. | -| [priorityClassName](./values.yaml#L794) | string | `""` | Priority class name for the Botkube Pod. | -| [nameOverride](./values.yaml#L797) | string | `""` | Fully override "botkube.name" template. | -| [fullnameOverride](./values.yaml#L799) | string | `""` | Fully override "botkube.fullname" template. | -| [resources](./values.yaml#L805) | 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#L817) | list | `[{"name":"LOG_LEVEL_SOURCE_BOTKUBE_KUBERNETES","value":"debug"}]` | 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#L831) | 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#L846) | 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#L864) | object | `{}` | Node labels for Botkube Pod assignment. [Ref doc](https://kubernetes.io/docs/user-guide/node-selection/). | -| [tolerations](./values.yaml#L868) | list | `[]` | Tolerations for Botkube Pod assignment. [Ref doc](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/). | -| [affinity](./values.yaml#L872) | object | `{}` | Affinity for Botkube Pod assignment. [Ref doc](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity). | -| [serviceAccount.create](./values.yaml#L876) | bool | `true` | If true, a ServiceAccount is automatically created. | -| [serviceAccount.name](./values.yaml#L879) | string | `""` | The name of the service account to use. If not set, a name is generated using the fullname template. | -| [serviceAccount.annotations](./values.yaml#L881) | object | `{}` | Extra annotations for the ServiceAccount. | -| [extraObjects](./values.yaml#L884) | list | `[]` | Extra Kubernetes resources to create. Helm templating is allowed as it is evaluated before creating the resources. | -| [analytics.disable](./values.yaml#L912) | 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](./values.yaml#L916) | object | `{"enabled":true,"inCluster":{"informerResyncPeriod":"10m"}}` | Parameters for the Config Watcher component which reloads Botkube on ConfigMap changes. It restarts Botkube when configuration data change is detected. It watches ConfigMaps and/or Secrets with the `botkube.io/config-watch: "true"` label from the namespace where Botkube is installed. | -| [configWatcher.enabled](./values.yaml#L918) | bool | `true` | If true, restarts the Botkube Pod on config changes. | -| [configWatcher.inCluster](./values.yaml#L920) | object | `{"informerResyncPeriod":"10m"}` | In-cluster Config Watcher configuration. It is used when remote configuration is not provided. | -| [configWatcher.inCluster.informerResyncPeriod](./values.yaml#L922) | string | `"10m"` | Resync period for the Config Watcher informers. | -| [plugins](./values.yaml#L925) | object | `{"cacheDir":"/tmp","healthCheckInterval":"10s","incomingWebhook":{"enabled":true,"port":2115,"targetPort":2115},"repositories":{"botkube":{"url":"https://storage.googleapis.com/botkube-plugins-latest/plugins-index.yaml"}},"restartPolicy":{"threshold":10,"type":"DeactivatePlugin"}}` | Configuration for Botkube executors and sources plugins. | -| [plugins.cacheDir](./values.yaml#L927) | string | `"/tmp"` | Directory, where downloaded plugins are cached. | -| [plugins.repositories](./values.yaml#L929) | object | `{"botkube":{"url":"https://storage.googleapis.com/botkube-plugins-latest/plugins-index.yaml"}}` | List of plugins repositories. Each repository defines the URL and optional `headers` | -| [plugins.repositories.botkube](./values.yaml#L931) | object | `{"url":"https://storage.googleapis.com/botkube-plugins-latest/plugins-index.yaml"}` | This repository serves officially supported Botkube plugins. | -| [plugins.incomingWebhook](./values.yaml#L936) | object | `{"enabled":true,"port":2115,"targetPort":2115}` | Configure Incoming webhook for source plugins. | -| [plugins.restartPolicy](./values.yaml#L941) | object | `{"threshold":10,"type":"DeactivatePlugin"}` | Botkube Restart Policy on plugin failure. | -| [plugins.restartPolicy.type](./values.yaml#L943) | string | `"DeactivatePlugin"` | Restart policy type. Allowed values: "RestartAgent", "DeactivatePlugin". | -| [plugins.restartPolicy.threshold](./values.yaml#L945) | int | `10` | Number of restarts before policy takes into effect. | -| [config](./values.yaml#L949) | object | `{"provider":{"apiKey":"","endpoint":"https://api.botkube.io/graphql","identifier":""}}` | Configuration for synchronizing Botkube configuration. | -| [config.provider](./values.yaml#L951) | object | `{"apiKey":"","endpoint":"https://api.botkube.io/graphql","identifier":""}` | Base provider definition. | -| [config.provider.identifier](./values.yaml#L954) | string | `""` | Unique identifier for remote Botkube settings. If set to an empty string, Botkube won't fetch remote configuration. | -| [config.provider.endpoint](./values.yaml#L956) | string | `"https://api.botkube.io/graphql"` | Endpoint to fetch Botkube settings from. | -| [config.provider.apiKey](./values.yaml#L958) | string | `""` | Key passed as a `X-API-Key` header to the provider's endpoint. | +| [settings.clusterName](./values.yaml#L672) | string | `"not-configured"` | Cluster name to differentiate incoming messages. | +| [settings.healthPort](./values.yaml#L675) | int | `2114` | Health check port. | +| [settings.upgradeNotifier](./values.yaml#L677) | bool | `true` | If true, notifies about new Botkube releases. | +| [settings.log.level](./values.yaml#L681) | string | `"info"` | Sets one of the log levels. Allowed values: `info`, `warn`, `debug`, `error`, `fatal`, `panic`. | +| [settings.log.disableColors](./values.yaml#L683) | bool | `false` | If true, disable ANSI colors in logging. Ignored when `json` formatter is used. | +| [settings.log.formatter](./values.yaml#L685) | string | `"json"` | Configures log format. Allowed values: `text`, `json`. | +| [settings.systemConfigMap](./values.yaml#L688) | object | `{"name":"botkube-system"}` | Botkube's system ConfigMap where internal data is stored. | +| [settings.persistentConfig](./values.yaml#L693) | 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#L708) | bool | `false` | If true, specify cert path in `config.ssl.cert` property or K8s Secret in `config.ssl.existingSecretName`. | +| [ssl.existingSecretName](./values.yaml#L714) | string | `""` | Using existing SSL Secret. It MUST be in `botkube` Namespace. | +| [ssl.cert](./values.yaml#L717) | string | `""` | SSL Certificate file e.g certs/my-cert.crt. | +| [service](./values.yaml#L720) | object | `{"name":"metrics","port":2112,"targetPort":2112}` | Configures Service settings for ServiceMonitor CR. | +| [serviceMonitor](./values.yaml#L727) | 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#L737) | object | `{}` | Extra annotations to pass to the Botkube Deployment. | +| [deployment.livenessProbe](./values.yaml#L739) | object | `{"failureThreshold":35,"initialDelaySeconds":1,"periodSeconds":2,"successThreshold":1,"timeoutSeconds":1}` | Liveness probe. | +| [deployment.livenessProbe.initialDelaySeconds](./values.yaml#L741) | int | `1` | The liveness probe initial delay seconds. | +| [deployment.livenessProbe.periodSeconds](./values.yaml#L743) | int | `2` | The liveness probe period seconds. | +| [deployment.livenessProbe.timeoutSeconds](./values.yaml#L745) | int | `1` | The liveness probe timeout seconds. | +| [deployment.livenessProbe.failureThreshold](./values.yaml#L747) | int | `35` | The liveness probe failure threshold. | +| [deployment.livenessProbe.successThreshold](./values.yaml#L749) | int | `1` | The liveness probe success threshold. | +| [deployment.readinessProbe](./values.yaml#L752) | object | `{"failureThreshold":35,"initialDelaySeconds":1,"periodSeconds":2,"successThreshold":1,"timeoutSeconds":1}` | Readiness probe. | +| [deployment.readinessProbe.initialDelaySeconds](./values.yaml#L754) | int | `1` | The readiness probe initial delay seconds. | +| [deployment.readinessProbe.periodSeconds](./values.yaml#L756) | int | `2` | The readiness probe period seconds. | +| [deployment.readinessProbe.timeoutSeconds](./values.yaml#L758) | int | `1` | The readiness probe timeout seconds. | +| [deployment.readinessProbe.failureThreshold](./values.yaml#L760) | int | `35` | The readiness probe failure threshold. | +| [deployment.readinessProbe.successThreshold](./values.yaml#L762) | int | `1` | The readiness probe success threshold. | +| [extraAnnotations](./values.yaml#L769) | object | `{}` | Extra annotations to pass to the Botkube Pod. | +| [extraLabels](./values.yaml#L771) | object | `{}` | Extra labels to pass to the Botkube Pod. | +| [priorityClassName](./values.yaml#L773) | string | `""` | Priority class name for the Botkube Pod. | +| [nameOverride](./values.yaml#L776) | string | `""` | Fully override "botkube.name" template. | +| [fullnameOverride](./values.yaml#L778) | string | `""` | Fully override "botkube.fullname" template. | +| [resources](./values.yaml#L784) | 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#L796) | list | `[{"name":"LOG_LEVEL_SOURCE_BOTKUBE_KUBERNETES","value":"debug"}]` | 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#L810) | 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#L825) | 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#L843) | object | `{}` | Node labels for Botkube Pod assignment. [Ref doc](https://kubernetes.io/docs/user-guide/node-selection/). | +| [tolerations](./values.yaml#L847) | list | `[]` | Tolerations for Botkube Pod assignment. [Ref doc](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/). | +| [affinity](./values.yaml#L851) | object | `{}` | Affinity for Botkube Pod assignment. [Ref doc](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity). | +| [serviceAccount.create](./values.yaml#L855) | bool | `true` | If true, a ServiceAccount is automatically created. | +| [serviceAccount.name](./values.yaml#L858) | string | `""` | The name of the service account to use. If not set, a name is generated using the fullname template. | +| [serviceAccount.annotations](./values.yaml#L860) | object | `{}` | Extra annotations for the ServiceAccount. | +| [extraObjects](./values.yaml#L863) | list | `[]` | Extra Kubernetes resources to create. Helm templating is allowed as it is evaluated before creating the resources. | +| [analytics.disable](./values.yaml#L891) | 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](./values.yaml#L895) | object | `{"enabled":true,"inCluster":{"informerResyncPeriod":"10m"}}` | Parameters for the Config Watcher component which reloads Botkube on ConfigMap changes. It restarts Botkube when configuration data change is detected. It watches ConfigMaps and/or Secrets with the `botkube.io/config-watch: "true"` label from the namespace where Botkube is installed. | +| [configWatcher.enabled](./values.yaml#L897) | bool | `true` | If true, restarts the Botkube Pod on config changes. | +| [configWatcher.inCluster](./values.yaml#L899) | object | `{"informerResyncPeriod":"10m"}` | In-cluster Config Watcher configuration. It is used when remote configuration is not provided. | +| [configWatcher.inCluster.informerResyncPeriod](./values.yaml#L901) | string | `"10m"` | Resync period for the Config Watcher informers. | +| [plugins](./values.yaml#L904) | object | `{"cacheDir":"/tmp","healthCheckInterval":"10s","incomingWebhook":{"enabled":true,"port":2115,"targetPort":2115},"repositories":{"botkube":{"url":"https://storage.googleapis.com/botkube-plugins-latest/plugins-index.yaml"}},"restartPolicy":{"threshold":10,"type":"DeactivatePlugin"}}` | Configuration for Botkube executors and sources plugins. | +| [plugins.cacheDir](./values.yaml#L906) | string | `"/tmp"` | Directory, where downloaded plugins are cached. | +| [plugins.repositories](./values.yaml#L908) | object | `{"botkube":{"url":"https://storage.googleapis.com/botkube-plugins-latest/plugins-index.yaml"}}` | List of plugins repositories. Each repository defines the URL and optional `headers` | +| [plugins.repositories.botkube](./values.yaml#L910) | object | `{"url":"https://storage.googleapis.com/botkube-plugins-latest/plugins-index.yaml"}` | This repository serves officially supported Botkube plugins. | +| [plugins.incomingWebhook](./values.yaml#L915) | object | `{"enabled":true,"port":2115,"targetPort":2115}` | Configure Incoming webhook for source plugins. | +| [plugins.restartPolicy](./values.yaml#L920) | object | `{"threshold":10,"type":"DeactivatePlugin"}` | Botkube Restart Policy on plugin failure. | +| [plugins.restartPolicy.type](./values.yaml#L922) | string | `"DeactivatePlugin"` | Restart policy type. Allowed values: "RestartAgent", "DeactivatePlugin". | +| [plugins.restartPolicy.threshold](./values.yaml#L924) | int | `10` | Number of restarts before policy takes into effect. | +| [config](./values.yaml#L928) | object | `{"provider":{"apiKey":"","endpoint":"https://api.botkube.io/graphql","identifier":""}}` | Configuration for synchronizing Botkube configuration. | +| [config.provider](./values.yaml#L930) | object | `{"apiKey":"","endpoint":"https://api.botkube.io/graphql","identifier":""}` | Base provider definition. | +| [config.provider.identifier](./values.yaml#L933) | string | `""` | Unique identifier for remote Botkube settings. If set to an empty string, Botkube won't fetch remote configuration. | +| [config.provider.endpoint](./values.yaml#L935) | string | `"https://api.botkube.io/graphql"` | Endpoint to fetch Botkube settings from. | +| [config.provider.apiKey](./values.yaml#L937) | string | `""` | Key passed as a `X-API-Key` header to the provider's endpoint. | ### AWS IRSA on EKS support diff --git a/helm/botkube/values.yaml b/helm/botkube/values.yaml index 44de6513d..42d4a4e3b 100644 --- a/helm/botkube/values.yaml +++ b/helm/botkube/values.yaml @@ -666,27 +666,6 @@ communications: - k8s-err-events - k8s-recommendation-events - # -- 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/ - # - # @default -- See the `values.yaml` file for full object. - ## This object will be removed as a part of https://github.com/kubeshop/botkube/issues/865. - slack: - enabled: false - channels: - 'default': - name: 'SLACK_CHANNEL' - notification: - disabled: false - bindings: - executors: - - k8s-default-tools - sources: - - k8s-err-events - - k8s-recommendation-events - token: '' - ## Global Botkube configuration. settings: # -- Cluster name to differentiate incoming messages. diff --git a/internal/analytics/segment_reporter.go b/internal/analytics/segment_reporter.go index 82852153e..4212ef1ec 100644 --- a/internal/analytics/segment_reporter.go +++ b/internal/analytics/segment_reporter.go @@ -382,14 +382,26 @@ func (r *SegmentReporter) getAnonymizedRBAC(rbac *config.PolicyRule) *config.Pol return nil } - rbac.Group.Prefix = r.anonymizedValue(rbac.Group.Prefix) - for key, name := range rbac.Group.Static.Values { - rbac.Group.Static.Values[key] = r.anonymizedValue(name) + var anonymizedGroupValues []string + for _, name := range rbac.Group.Static.Values { + anonymizedGroupValues = append(anonymizedGroupValues, r.anonymizedValue(name)) + } + return &config.PolicyRule{ + User: config.UserPolicySubject{ + Type: rbac.User.Type, + Static: config.UserStaticSubject{ + Value: r.anonymizedValue(rbac.User.Static.Value), + }, + Prefix: r.anonymizedValue(rbac.User.Prefix), + }, + Group: config.GroupPolicySubject{ + Type: rbac.Group.Type, + Static: config.GroupStaticSubject{ + Values: anonymizedGroupValues, + }, + Prefix: r.anonymizedValue(rbac.Group.Prefix), + }, } - - rbac.User.Prefix = r.anonymizedValue(rbac.User.Prefix) - rbac.User.Static.Value = r.anonymizedValue(rbac.User.Static.Value) - return rbac } func (r *SegmentReporter) anonymizedValue(value string) string { diff --git a/internal/analytics/segment_reporter_test.go b/internal/analytics/segment_reporter_test.go index 0a8ff9321..f222ebfd9 100644 --- a/internal/analytics/segment_reporter_test.go +++ b/internal/analytics/segment_reporter_test.go @@ -153,11 +153,7 @@ func TestSegmentReporter_ReportBotEnabled(t *testing.T) { func TestSegmentReporter_ReportPluginsEnabled(t *testing.T) { // given - identity := fixIdentity() - segmentReporter, segmentCli := fakeSegmentReporterWithIdentity(identity) - - // when - err := segmentReporter.ReportPluginsEnabled(map[string]config.Executors{ + executors := map[string]config.Executors{ "botkube/helm_11yy1": { DisplayName: "helm", Plugins: map[string]config.Plugin{ @@ -227,7 +223,8 @@ func TestSegmentReporter_ReportPluginsEnabled(t *testing.T) { }, }, }, - }, map[string]config.Sources{ + } + sources := map[string]config.Sources{ "botkube/kubernetes_22yy2": { DisplayName: "k8s", Plugins: map[string]config.Plugin{ @@ -294,11 +291,27 @@ func TestSegmentReporter_ReportPluginsEnabled(t *testing.T) { }, }, }, - }) + } + + executors2, err := deepClone[map[string]config.Executors](executors) + require.NoError(t, err) + + sources2, err := deepClone[map[string]config.Sources](sources) + require.NoError(t, err) + + identity := fixIdentity() + segmentReporter, segmentCli := fakeSegmentReporterWithIdentity(identity) + + // when + err = segmentReporter.ReportPluginsEnabled(executors, sources) require.NoError(t, err) // then compareMessagesAgainstGoldenFile(t, segmentCli.messages) + + // ensure the report doesn't modify the original maps + assert.Equal(t, executors2, executors) + assert.Equal(t, sources2, sources) } func TestSegmentReporter_ReportSinkEnabled(t *testing.T) { @@ -458,3 +471,17 @@ func fixIdentity() *analytics.Identity { ControlPlaneNodeCount: 0, } } + +func deepClone[T any](in any) (any, error) { + origJSON, err := json.Marshal(in) + if err != nil { + return nil, err + } + + var out T + if err = json.Unmarshal(origJSON, &out); err != nil { + return nil, err + } + + return out, nil +} diff --git a/internal/analytics/testdata/TestSegmentReporter_ReportPluginsEnabled.json b/internal/analytics/testdata/TestSegmentReporter_ReportPluginsEnabled.json index 4dac81551..deb67f278 100644 --- a/internal/analytics/testdata/TestSegmentReporter_ReportPluginsEnabled.json +++ b/internal/analytics/testdata/TestSegmentReporter_ReportPluginsEnabled.json @@ -48,7 +48,7 @@ "Group": { "Type": "ChannelName", "Static": { - "Values": [] + "Values": null }, "Prefix": "***" } diff --git a/internal/executor/kubectl/executor.go b/internal/executor/kubectl/executor.go index f83b44ecf..6ffc22fd1 100644 --- a/internal/executor/kubectl/executor.go +++ b/internal/executor/kubectl/executor.go @@ -63,7 +63,7 @@ func NewExecutor(ver string, kcRunner kcRunner) *Executor { } } -// Metadata returns details about Helm plugin. +// Metadata returns details about Kubectl plugin. func (e *Executor) Metadata(context.Context) (api.MetadataOutput, error) { return api.MetadataOutput{ Version: e.pluginVersion, diff --git a/internal/source/kubernetes/config_schema.json b/internal/source/kubernetes/config_schema.json index 042d93957..390328544 100644 --- a/internal/source/kubernetes/config_schema.json +++ b/internal/source/kubernetes/config_schema.json @@ -703,46 +703,48 @@ "extraButtons": { "title": "Extra Buttons", "description": "Extra buttons for actionable items.", - "type": "object", - "properties": { - "enabled": { - "type": "boolean", - "default": false, - "description": "If enabled, renders extra button.", - "title": "Enable extra button" - }, - "trigger": { - "title": "Trigger", - "description": "Define log level for the plugin. Ensure that Botkube has plugin logging enabled for standard output.", - "type": "object", - "additionalProperties": false, - "properties": { - "type": { - "title": "Event types", - "description": "Event types which will trigger this action", - "type": "array", - "items": { - "type": "string", - "title": "Event type" + "type": "array", + "items": { + "properties": { + "enabled": { + "type": "boolean", + "default": false, + "description": "If enabled, renders extra button.", + "title": "Enable extra button" + }, + "trigger": { + "title": "Trigger", + "description": "Define log level for the plugin. Ensure that Botkube has plugin logging enabled for standard output.", + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "title": "Event types", + "description": "Event types which will trigger this action", + "type": "array", + "items": { + "type": "string", + "title": "Event type" + } } } - } - }, - "button": { - "title": "Button", - "description": "Button settings for showing after each matched events.", - "type": "object", - "additionalProperties": false, - "properties": { - "commandTpl": { - "title": "Command template", - "description": "Command template that can be used to generate actual command.", - "type": "string" - }, - "displayName": { - "title": "Display name", - "description": "Display name of this command.", - "type": "string" + }, + "button": { + "title": "Button", + "description": "Button settings for showing after each matched events.", + "type": "object", + "additionalProperties": false, + "properties": { + "commandTpl": { + "title": "Command template", + "description": "Command template that can be used to generate actual command.", + "type": "string" + }, + "displayName": { + "title": "Display name", + "description": "Display name of this command.", + "type": "string" + } } } }