Repository: Altinity/clickhouse-operator

Issue:
Request: Define `values.schema.json` for Helm chart
My team has Clickhouse-Operator deployed via the Helm chart. We recently had an issue where ClickhouseInstallation CRs were not being reconciled. Upon investigating, we realized that we had misconfigured the watched namespaces like so:
```yaml
configs:
  files:
    config.yaml:
      reconcile:
        host:
          queries: false
  watch:
    namespaces:
    - foo
```

When it fact it should be set like so:
```yaml
configs:
  files:
    config.yaml:
      watch:
        namespaces: foo
      reconcile:
        host:
          queries: false
```

I believe that a strict [schema](https://helm.sh/docs/topics/charts/#schema-files) on the `values.yaml` would have prevented this issue. Even if the full `config.yaml` is not reflected, a schema would presumably have at minimum notified us that `.configs.watch` is not valid and caused `helm install/upgrade/lint` to fail.

Hints from issue comments:
@Slach: Could you suggest best tool that allows creating automatic values.schema.json based on current values.yaml?@alex-zaitsev: Fixed in https://github.com/Altinity/clickhouse-operator/releases/tag/release-0.25.4@jinnovation: thanks both!

Solution patch:
diff --git a/deploy/helm/clickhouse-operator/templates/generated/ClusterRoleBinding-clickhouse-operator-kube-system.yaml b/deploy/helm/clickhouse-operator/templates/generated/ClusterRoleBinding-clickhouse-operator-kube-system.yaml
index 1f696a543..6b6131dbb 100644
--- a/deploy/helm/clickhouse-operator/templates/generated/ClusterRoleBinding-clickhouse-operator-kube-system.yaml
+++ b/deploy/helm/clickhouse-operator/templates/generated/ClusterRoleBinding-clickhouse-operator-kube-system.yaml
@@ -20,7 +20,6 @@ subjects:
   - kind: ServiceAccount
     name: {{ include "altinity-clickhouse-operator.serviceAccountName" . }}
     namespace: {{ include "altinity-clickhouse-operator.namespace" . }}
-
 # Template Parameters:
 #
 # NAMESPACE=kube-system
diff --git a/deploy/helm/clickhouse-operator/templates/generated/ServiceAccount-clickhouse-operator.yaml b/deploy/helm/clickhouse-operator/templates/generated/ServiceAccount-clickhouse-operator.yaml
index bcc55c20d..fd06949a6 100644
--- a/deploy/helm/clickhouse-operator/templates/generated/ServiceAccount-clickhouse-operator.yaml
+++ b/deploy/helm/clickhouse-operator/templates/generated/ServiceAccount-clickhouse-operator.yaml
@@ -13,7 +13,6 @@ metadata:
   namespace: {{ include "altinity-clickhouse-operator.namespace" . }}
   labels: {{ include "altinity-clickhouse-operator.labels" . | nindent 4 }}
   annotations: {{ include "altinity-clickhouse-operator.annotations" . | nindent 4 }}{{ if .Values.serviceAccount.annotations }}{{ toYaml .Values.serviceAccount.annotations | nindent 4 }}{{ end }}
-
 # Template Parameters:
 #
 # NAMESPACE=kube-system
diff --git a/deploy/helm/clickhouse-operator/values.schema.json b/deploy/helm/clickhouse-operator/values.schema.json
new file mode 100644
index 000000000..c299c1e2d
--- /dev/null
+++ b/deploy/helm/clickhouse-operator/values.schema.json
@@ -0,0 +1,895 @@
+{
+    "$schema": "https://json-schema.org/draft/2020-12/schema",
+    "type": "object",
+    "properties": {
+        "additionalResources": {
+            "description": "list of additional resources to create (processed via `tpl` function), useful for create ClickHouse clusters together with clickhouse-operator. check `kubectl explain chi` for details",
+            "type": "array"
+        },
+        "affinity": {
+            "description": "affinity for scheduler pod assignment, check `kubectl explain pod.spec.affinity` for details",
+            "type": "object"
+        },
+        "commonAnnotations": {
+            "description": "set of annotations that will be applied to all the resources for the operator",
+            "type": "object"
+        },
+        "commonLabels": {
+            "description": "set of labels that will be applied to all the resources for the operator",
+            "type": "object"
+        },
+        "configs": {
+            "description": "clickhouse operator configs",
+            "type": "object",
+            "properties": {
+                "confdFiles": {
+                    "type": ["string", "null"]
+                },
+                "configdFiles": {
+                    "type": "object",
+                    "properties": {
+                        "01-clickhouse-01-listen.xml": {
+                            "type": "string"
+                        },
+                        "01-clickhouse-02-logger.xml": {
+                            "type": "string"
+                        },
+                        "01-clickhouse-03-query_log.xml": {
+                            "type": "string"
+                        },
+                        "01-clickhouse-04-part_log.xml": {
+                            "type": "string"
+                        },
+                        "01-clickhouse-05-trace_log.xml": {
+                            "type": "string"
+                        }
+                    }
+                },
+                "files": {
+                    "type": "object",
+                    "properties": {
+                        "config.yaml": {
+                            "type": "object",
+                            "properties": {
+                                "annotation": {
+                                    "type": "object",
+                                    "properties": {
+                                        "exclude": {
+                                            "type": "array"
+                                        },
+                                        "include": {
+                                            "type": "array"
+                                        }
+                                    }
+                                },
+                                "clickhouse": {
+                                    "type": "object",
+                                    "properties": {
+                                        "access": {
+                                            "type": "object",
+                                            "properties": {
+                                                "password": {
+                                                    "type": "string"
+                                                },
+                                                "port": {
+                                                    "type": "integer"
+                                                },
+                                                "rootCA": {
+                                                    "type": "string"
+                                                },
+                                                "scheme": {
+                                                    "type": "string"
+                                                },
+                                                "secret": {
+                                                    "type": "object",
+                                                    "properties": {
+                                                        "name": {
+                                                            "type": "string"
+                                                        },
+                                                        "namespace": {
+                                                            "type": "string"
+                                                        }
+                                                    }
+                                                },
+                                                "timeouts": {
+                                                    "type": "object",
+                                                    "properties": {
+                                                        "connect": {
+                                                            "type": "integer"
+                                                        },
+                                                        "query": {
+                                                            "type": "integer"
+                                                        }
+                                                    }
+                                                },
+                                                "username": {
+                                                    "type": "string"
+                                                }
+                                            }
+                                        },
+                                        "addons": {
+                                            "type": "object",
+                                            "properties": {
+                                                "rules": {
+                                                    "type": "array",
+                                                    "items": {
+                                                        "type": "object",
+                                                        "properties": {
+                                                            "spec": {
+                                                                "type": "object",
+                                                                "properties": {
+                                                                    "configuration": {
+                                                                        "type": "object",
+                                                                        "properties": {
+                                                                            "files": {
+                                                                                "type": "null"
+                                                                            },
+                                                                            "profiles": {
+                                                                                "type": ["object", "null"],
+                                                                                "properties": {
+                                                                                    "clickhouse_operator/format_display_secrets_in_show_and_select": {
+                                                                                        "type": "integer"
+                                                                                    }
+                                                                                }
+                                                                            },
+                                                                            "quotas": {
+                                                                                "type": ["object", "null"]
+                                                                            },
+                                                                            "settings": {
+                                                                                "type": ["object", "null"],
+                                                                                "properties": {
+                                                                                    "display_secrets_in_show_and_select": {
+                                                                                        "type": "integer"
+                                                                                    }
+                                                                                }
+                                                                            },
+                                                                            "users": {
+                                                                                "type": ["object", "null"],
+                                                                                "properties": {
+                                                                                    "{clickhouseOperatorUser}/access_management": {
+                                                                                        "type": "integer"
+                                                                                    },
+                                                                                    "{clickhouseOperatorUser}/named_collection_control": {
+                                                                                        "type": "integer"
+                                                                                    },
+                                                                                    "{clickhouseOperatorUser}/show_named_collections": {
+                                                                                        "type": "integer"
+                                                                                    },
+                                                                                    "{clickhouseOperatorUser}/show_named_collections_secrets": {
+                                                                                        "type": "integer"
+                                                                                    }
+                                                                                }
+                                                                            }
+                                                                        }
+                                                                    }
+                                                                }
+                                                            },
+                                                            "version": {
+                                                                "type": "string"
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        },
+                                        "configuration": {
+                                            "type": "object",
+                                            "properties": {
+                                                "file": {
+                                                    "type": "object",
+                                                    "properties": {
+                                                        "path": {
+                                                            "type": "object",
+                                                            "properties": {
+                                                                "common": {
+                                                                    "type": "string"
+                                                                },
+                                                                "host": {
+                                                                    "type": "string"
+                                                                },
+                                                                "user": {
+                                                                    "type": "string"
+                                                                }
+                                                            }
+                                                        }
+                                                    }
+                                                },
+                                                "network": {
+                                                    "type": "object",
+                                                    "properties": {
+                                                        "hostRegexpTemplate": {
+                                                            "type": "string"
+                                                        }
+                                                    }
+                                                },
+                                                "user": {
+                                                    "type": "object",
+                                                    "properties": {
+                                                        "default": {
+                                                            "type": "object",
+                                                            "properties": {
+                                                                "networksIP": {
+                                                                    "type": "array",
+                                                                    "items": {
+                                                                        "type": "string"
+                                                                    }
+                                                                },
+                                                                "password": {
+                                                                    "type": "string"
+                                                                },
+                                                                "profile": {
+                                                                    "type": "string"
+                                                                },
+                                                                "quota": {
+                                                                    "type": "string"
+                                                                }
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        },
+                                        "configurationRestartPolicy": {
+                                            "type": "object",
+                                            "properties": {
+                                                "rules": {
+                                                    "type": "array",
+                                                    "items": {
+                                                        "type": "object",
+                                                        "properties": {
+                                                            "rules": {
+                                                                "type": "array",
+                                                                "items": {
+                                                                    "type": "object",
+                                                                    "properties": {
+                                                                        "files/*.xml": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "files/config.d/*.xml": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "files/config.d/*dict*.xml": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "files/config.d/*no_restart*": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "profiles/default/background_*_pool_size": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "profiles/default/max_*_for_server": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "settings/*": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "settings/access_control_path": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "settings/dictionaries_config": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "settings/display_secrets_in_show_and_select": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "settings/logger": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "settings/logger/*": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "settings/macros/*": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "settings/max_*_to_drop": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "settings/max_concurrent_queries": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "settings/max_server_memory_*": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "settings/models_config": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "settings/remote_servers/*": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "settings/user_defined_executable_functions_config": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "settings/user_directories/*": {
+                                                                            "type": "string"
+                                                                        },
+                                                                        "zookeeper/*": {
+                                                                            "type": "string"
+                                                                        }
+                                                                    }
+                                                                }
+                                                            },
+                                                            "version": {
+                                                                "type": "string"
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        },
+                                        "metrics": {
+                                            "type": "object",
+                                            "properties": {
+                                                "timeouts": {
+                                                    "type": "object",
+                                                    "properties": {
+                                                        "collect": {
+                                                            "type": "integer"
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                },
+                                "keeper": {
+                                    "type": "object",
+                                    "properties": {
+                                        "configuration": {
+                                            "type": "object",
+                                            "properties": {
+                                                "file": {
+                                                    "type": "object",
+                                                    "properties": {
+                                                        "path": {
+                                                            "type": "object",
+                                                            "properties": {
+                                                                "common": {
+                                                                    "type": "string"
+                                                                },
+                                                                "host": {
+                                                                    "type": "string"
+                                                                },
+                                                                "user": {
+                                                                    "type": "string"
+                                                                }
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                },
+                                "label": {
+                                    "type": "object",
+                                    "properties": {
+                                        "appendScope": {
+                                            "type": "string"
+                                        },
+                                        "exclude": {
+                                            "type": "array"
+                                        },
+                                        "include": {
+                                            "type": "array"
+                                        }
+                                    }
+                                },
+                                "logger": {
+                                    "type": "object",
+                                    "properties": {
+                                        "alsologtostderr": {
+                                            "type": "string"
+                                        },
+                                        "log_backtrace_at": {
+                                            "type": "string"
+                                        },
+                                        "logtostderr": {
+                                            "type": "string"
+                                        },
+                                        "stderrthreshold": {
+                                            "type": "string"
+                                        },
+                                        "v": {
+                                            "type": "string"
+                                        },
+                                        "vmodule": {
+                                            "type": "string"
+                                        }
+                                    }
+                                },
+                                "metrics": {
+                                    "type": "object",
+                                    "properties": {
+                                        "labels": {
+                                            "type": "object",
+                                            "properties": {
+                                                "exclude": {
+                                                    "type": "array"
+                                                }
+                                            }
+                                        }
+                                    }
+                                },
+                                "pod": {
+                                    "type": "object",
+                                    "properties": {
+                                        "terminationGracePeriod": {
+                                            "type": "integer"
+                                        }
+                                    }
+                                },
+                                "reconcile": {
+                                    "type": "object",
+                                    "properties": {
+                                        "host": {
+                                            "type": "object",
+                                            "properties": {
+                                                "wait": {
+                                                    "type": "object",
+                                                    "properties": {
+                                                        "exclude": {
+                                                            "type": "boolean"
+                                                        },
+                                                        "include": {
+                                                            "type": "boolean"
+                                                        },
+                                                        "probes": {
+                                                            "type": "object",
+                                                            "properties": {
+                                                                "readiness": {
+                                                                    "type": "boolean"
+                                                                },
+                                                                "startup": {
+                                                                    "type": "boolean"
+                                                                }
+                                                            }
+                                                        },
+                                                        "queries": {
+                                                            "type": "boolean"
+                                                        },
+                                                        "replicas": {
+                                                            "type": "object",
+                                                            "properties": {
+                                                                "all": {
+                                                                    "type": "boolean"
+                                                                },
+                                                                "delay": {
+                                                                    "type": "integer"
+                                                                },
+                                                                "new": {
+                                                                    "type": "boolean"
+                                                                }
+                                                            }
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        },
+                                        "runtime": {
+                                            "type": "object",
+                                            "properties": {
+                                                "reconcileCHIsThreadsNumber": {
+                                                    "type": "integer"
+                                                },
+                                                "reconcileShardsMaxConcurrencyPercent": {
+                                                    "type": "integer"
+                                                },
+                                                "reconcileShardsThreadsNumber": {
+                                                    "type": "integer"
+                                                }
+                                            }
+                                        },
+                                        "statefulSet": {
+                                            "type": "object",
+                                            "properties": {
+                                                "create": {
+                                                    "type": "object",
+                                                    "properties": {
+                                                        "onFailure": {
+                                                            "type": "string"
+                                                        }
+                                                    }
+                                                },
+                                                "update": {
+                                                    "type": "object",
+                                                    "properties": {
+                                                        "onFailure": {
+                                                            "type": "string"
+                                                        },
+                                                        "pollInterval": {
+                                                            "type": "integer"
+                                                        },
+                                                        "timeout": {
+                                                            "type": "integer"
+                                                        }
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                },
+                                "statefulSet": {
+                                    "type": "object",
+                                    "properties": {
+                                        "revisionHistoryLimit": {
+                                            "type": "integer"
+                                        }
+                                    }
+                                },
+                                "status": {
+                                    "type": "object",
+                                    "properties": {
+                                        "fields": {
+                                            "type": "object",
+                                            "properties": {
+                                                "action": {
+                                                    "type": "boolean"
+                                                },
+                                                "actions": {
+                                                    "type": "boolean"
+                                                },
+                                                "error": {
+                                                    "type": "boolean"
+                                                },
+                                                "errors": {
+                                                    "type": "boolean"
+                                                }
+                                            }
+                                        }
+                                    }
+                                },
+                                "template": {
+                                    "type": "object",
+                                    "properties": {
+                                        "chi": {
+                                            "type": "object",
+                                            "properties": {
+                                                "path": {
+                                                    "type": "string"
+                                                },
+                                                "policy": {
+                                                    "type": "string"
+                                                }
+                                            }
+                                        },
+                                        "chk": {
+                                            "type": "object",
+                                            "properties": {
+                                                "path": {
+                                                    "type": "string"
+                                                },
+                                                "policy": {
+                                                    "type": "string"
+                                                }
+                                            }
+                                        }
+                                    }
+                                },
+                                "watch": {
+                                    "type": "object",
+                                    "properties": {
+                                        "namespaces": {
+                                            "type": "array"
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                },
+                "keeperConfdFiles": {
+                    "type": ["string", "null"]
+                },
+                "keeperConfigdFiles": {
+                    "type": "object",
+                    "properties": {
+                        "01-keeper-01-default-config.xml": {
+                            "type": "string"
+                        },
+                        "01-keeper-02-readiness.xml": {
+                            "type": "string"
+                        },
+                        "01-keeper-03-enable-reconfig.xml": {
+                            "type": "string"
+                        }
+                    }
+                },
+                "keeperTemplatesdFiles": {
+                    "type": ["object", "null"],
+                    "properties": {
+                        "readme": {
+                            "type": ["string", "null"]
+                        }
+                    }
+                },
+                "keeperUsersdFiles": {
+                    "type": ["string", "null"]
+                },
+                "templatesdFiles": {
+                    "type": ["object", "null"],
+                    "properties": {
+                        "001-templates.json.example": {
+                            "type": ["string", "null"]
+                        },
+                        "default-pod-template.yaml.example": {
+                            "type": ["string", "null"]
+                        },
+                        "default-storage-template.yaml.example": {
+                            "type": ["string", "null"]
+                        },
+                        "readme": {
+                            "type": ["string", "null"]
+                        }
+                    }
+                },
+                "usersdFiles": {
+                    "type": ["object", "null"],
+                    "properties": {
+                        "01-clickhouse-operator-profile.xml": {
+                            "type": ["string", "null"]
+                        },
+                        "02-clickhouse-default-profile.xml": {
+                            "type": ["string", "null"]
+                        }
+                    }
+                }
+            }
+        },
+        "dashboards": {
+            "type": "object",
+            "properties": {
+                "additionalLabels": {
+                    "description": "labels to add to a secret with dashboards",
+                    "type": "object",
+                    "properties": {
+                        "grafana_dashboard": {
+                            "type": "string"
+                        }
+                    }
+                },
+                "annotations": {
+                    "description": "annotations to add to a secret with dashboards",
+                    "type": "object"
+                },
+                "enabled": {
+                    "description": "provision grafana dashboards as configMaps (can be synced by grafana dashboards sidecar https://github.com/grafana/helm-charts/blob/grafana-8.3.4/charts/grafana/values.yaml#L778 )",
+                    "type": "boolean"
+                },
+                "grafana_folder": {
+                    "type": "string"
+                }
+            }
+        },
+        "deployment": {
+            "type": "object",
+            "properties": {
+                "strategy": {
+                    "type": "object",
+                    "properties": {
+                        "type": {
+                            "type": "string"
+                        }
+                    }
+                }
+            }
+        },
+        "fullnameOverride": {
+            "description": "full name of the chart.",
+            "type": "string"
+        },
+        "imagePullSecrets": {
+            "description": "image pull secret for private images in clickhouse-operator pod possible value format `[{\"name\":\"your-secret-name\"}]`, check `kubectl explain pod.spec.imagePullSecrets` for details",
+            "type": "array"
+        },
+        "metrics": {
+            "type": "object",
+            "properties": {
+                "containerSecurityContext": {
+                    "type": "object"
+                },
+                "enabled": {
+                    "type": "boolean"
+                },
+                "env": {
+                    "description": "additional environment variables for the deployment of metrics-exporter containers possible format value `[{\"name\": \"SAMPLE\", \"value\": \"text\"}]`",
+                    "type": "array"
+                },
+                "image": {
+                    "type": "object",
+                    "properties": {
+                        "pullPolicy": {
+                            "description": "image pull policy",
+                            "type": "string"
+                        },
+                        "repository": {
+                            "description": "image repository",
+                            "type": "string"
+                        },
+                        "tag": {
+                            "description": "image tag (chart's appVersion value will be used if not set)",
+                            "type": "string"
+                        }
+                    }
+                },
+                "resources": {
+                    "description": "custom resource configuration",
+                    "type": "object"
+                }
+            }
+        },
+        "nameOverride": {
+            "description": "override name of the chart",
+            "type": "string"
+        },
+        "namespaceOverride": {
+            "type": "string"
+        },
+        "nodeSelector": {
+            "description": "node for scheduler pod assignment, check `kubectl explain pod.spec.nodeSelector` for details",
+            "type": "object"
+        },
+        "operator": {
+            "type": "object",
+            "properties": {
+                "containerSecurityContext": {
+                    "type": "object"
+                },
+                "env": {
+                    "description": "additional environment variables for the clickhouse-operator container in deployment possible format value `[{\"name\": \"SAMPLE\", \"value\": \"text\"}]`",
+                    "type": "array"
+                },
+                "image": {
+                    "type": "object",
+                    "properties": {
+                        "pullPolicy": {
+                            "description": "image pull policy",
+                            "type": "string"
+                        },
+                        "repository": {
+                            "description": "image repository",
+                            "type": "string"
+                        },
+                        "tag": {
+                            "description": "image tag (chart's appVersion value will be used if not set)",
+                            "type": "string"
+                        }
+                    }
+                },
+                "priorityClassName": {
+                    "description": "priority class name for the clickhouse-operator deployment, check `kubectl explain pod.spec.priorityClassName` for details",
+                    "type": "string"
+                },
+                "resources": {
+                    "description": "custom resource configuration, check `kubectl explain pod.spec.containers.resources` for details",
+                    "type": "object"
+                }
+            }
+        },
+        "podAnnotations": {
+            "description": "annotations to add to the clickhouse-operator pod, check `kubectl explain pod.spec.annotations` for details",
+            "type": "object",
+            "properties": {
+                "clickhouse-operator-metrics/port": {
+                    "type": "string"
+                },
+                "clickhouse-operator-metrics/scrape": {
+                    "type": "string"
+                },
+                "prometheus.io/port": {
+                    "type": "string"
+                },
+                "prometheus.io/scrape": {
+                    "type": "string"
+                }
+            }
+        },
+        "podLabels": {
+            "description": "labels to add to the clickhouse-operator pod",
+            "type": "object"
+        },
+        "podSecurityContext": {
+            "type": "object"
+        },
+        "rbac": {
+            "type": "object",
+            "properties": {
+                "create": {
+                    "description": "specifies whether rbac resources should be created",
+                    "type": "boolean"
+                },
+                "namespaceScoped": {
+                    "description": "specifies whether to create roles and rolebindings at the cluster level or namespace level",
+                    "type": "boolean"
+                }
+            }
+        },
+        "secret": {
+            "type": "object",
+            "properties": {
+                "create": {
+                    "description": "create a secret with operator credentials",
+                    "type": "boolean"
+                },
+                "password": {
+                    "description": "operator credentials password",
+                    "type": "string"
+                },
+                "username": {
+                    "description": "operator credentials username",
+                    "type": "string"
+                }
+            }
+        },
+        "serviceAccount": {
+            "type": "object",
+            "properties": {
+                "annotations": {
+                    "description": "annotations to add to the service account",
+                    "type": "object"
+                },
+                "create": {
+                    "description": "specifies whether a service account should be created",
+                    "type": "boolean"
+                },
+                "name": {
+                    "description": "the name of the service account to use; if not set and create is true, a name is generated using the fullname template",
+                    "type": "null"
+                }
+            }
+        },
+        "serviceMonitor": {
+            "type": "object",
+            "properties": {
+                "additionalLabels": {
+                    "description": "additional labels for service monitor",
+                    "type": "object"
+                },
+                "clickhouseMetrics": {
+                    "type": "object",
+                    "properties": {
+                        "interval": {
+                            "type": "string"
+                        },
+                        "metricRelabelings": {
+                            "type": "array"
+                        },
+                        "relabelings": {
+                            "type": "array"
+                        },
+                        "scrapeTimeout": {
+                            "type": "string"
+                        }
+                    }
+                },
+                "enabled": {
+                    "description": "ServiceMonitor Custom resource is created for a [prometheus-operator](https://github.com/prometheus-operator/prometheus-operator) In serviceMonitor will be created two endpoints ch-metrics on port 8888 and op-metrics # 9999. Ypu can specify interval, scrapeTimeout, relabelings, metricRelabelings for each endpoint below",
+                    "type": "boolean"
+                },
+                "operatorMetrics": {
+                    "type": "object",
+                    "properties": {
+                        "interval": {
+                            "type": "string"
+                        },
+                        "metricRelabelings": {
+                            "type": "array"
+                        },
+                        "relabelings": {
+                            "type": "array"
+                        },
+                        "scrapeTimeout": {
+                            "type": "string"
+                        }
+                    }
+                }
+            }
+        },
+        "tolerations": {
+            "description": "tolerations for scheduler pod assignment, check `kubectl explain pod.spec.tolerations` for details",
+            "type": "array"
+        },
+        "topologySpreadConstraints": {
+            "type": "array"
+        }
+    }
+}
diff --git a/dev/generate_helm_chart.sh b/dev/generate_helm_chart.sh
index 6aeda1347..a31ebc6b2 100755
--- a/dev/generate_helm_chart.sh
+++ b/dev/generate_helm_chart.sh
@@ -75,6 +75,11 @@ function main() {
     echo "WARNING"
     echo "helm-docs is not available, skip docs generation"
   fi
+
+#  if [[ "0" == $(helm plugin list | grep -c schema) ]]; then
+#    helm plugin install https://github.com/losisin/helm-values-schema-json.git
+#  fi
+#  helm schema --use-helm-docs -f "${values_yaml}" --output "${chart_path}/values.schema.json"
 }
 
 function process() {
diff --git a/pkg/metrics/clickhouse/clickhouse_metrics_fetcher.go b/pkg/metrics/clickhouse/clickhouse_metrics_fetcher.go
index c3c0ab373..292f882cf 100644
--- a/pkg/metrics/clickhouse/clickhouse_metrics_fetcher.go
+++ b/pkg/metrics/clickhouse/clickhouse_metrics_fetcher.go
@@ -38,14 +38,7 @@ const (
         	toString(value)           AS value,
         	''                        AS description,
         	'gauge'                   AS type
-    	FROM system.asynchronous_metrics
-    	UNION ALL
-    	SELECT
-	        concat('metric.', metric) AS metric,
-	        toString(value)           AS value,
-    	    ''                        AS description,
-	        'gauge'                   AS type
-	    FROM system.metrics
+    	FROM merge('system','^(metrics|asynchronous_metrics|custom_metrics)$')
 	    UNION ALL
 	    SELECT
 	        concat('event.', event)   AS metric,



Test patch:
diff --git a/tests/e2e/steps.py b/tests/e2e/steps.py
index f0865fd1c..22881fa1d 100644
--- a/tests/e2e/steps.py
+++ b/tests/e2e/steps.py
@@ -158,8 +158,7 @@ def check_metrics_monitoring(
         port="8888",
         max_retries=7
 ):
-    with Then(f"metrics-exporter /metrics endpoint result should contain"):
-        print(f"expect: '{expect_pattern}', '{expect_metric}', '{expect_labels}'")
+    with Then(f"metrics-exporter /metrics endpoint result should contain {expect_pattern}{expect_metric}"):
         expected_pattern_found = False
         for i in range(1, max_retries):
             url_cmd = util.make_http_get_request("127.0.0.1", port, "/metrics")
diff --git a/tests/e2e/test_metrics_exporter.py b/tests/e2e/test_metrics_exporter.py
index 4e6f4c52c..923abd08a 100644
--- a/tests/e2e/test_metrics_exporter.py
+++ b/tests/e2e/test_metrics_exporter.py
@@ -9,6 +9,8 @@ from testflows.asserts import error
 import e2e.kubectl as kubectl
 import e2e.settings as settings
 import e2e.util as util
+import e2e.clickhouse as clickhouse
+import e2e.steps as steps
 
 
 @TestScenario
@@ -46,6 +48,7 @@ def test_metrics_exporter_chi(self):
                 with Then("Not ready. Wait for " + str(i * 5) + " seconds"):
                     time.sleep(i * 5)
             assert out == expect_result, error()
+
     def check_monitoring_metrics(operator_namespace, operator_pod, expect_result, max_retries=10):
         with Then(f"metrics-exporter /metrics endpoint result should match with {expect_result}"):
             found = 0
@@ -120,6 +123,11 @@ def test_metrics_exporter_chi(self):
                     ]
                 }
             ]
+
+        with Then("Add system.custom_metrics"):
+            clickhouse.query("test-017-multi-version", "CREATE VIEW system.custom_metrics as SELECT 'MyCustomMetric' as metric, 1 as value")
+
+
         with Then("Check both pods are monitored"):
             check_monitoring_chi(self.context.operator_namespace, operator_pod, expected_chi)
         labels = ','.join([
@@ -127,17 +135,25 @@ def test_metrics_exporter_chi(self):
                   'clickhouse_altinity_com_chi="test-017-multi-version"',
                   'clickhouse_altinity_com_email="myname@mydomain.com, yourname@yourdoman.com"'
                   ])
+
         with Then("Check not empty /metrics"):
-                check_monitoring_metrics(
-                    self.context.operator_namespace,
-                    operator_pod,
-                    expect_result={
-                        "# HELP chi_clickhouse_metric_VersionInteger": True,
-                        "# TYPE chi_clickhouse_metric_VersionInteger gauge": True,
-                        "chi_clickhouse_metric_VersionInteger{" + labels +",hostname=\"chi-test-017-multi-version-default-0-0": True,
-                        "chi_clickhouse_metric_VersionInteger{" + labels +",hostname=\"chi-test-017-multi-version-default-1-0": True,
-                    },
-                )
+            check_monitoring_metrics(
+                self.context.operator_namespace,
+                operator_pod,
+                expect_result={
+                    "# HELP chi_clickhouse_metric_VersionInteger": True,
+                    "# TYPE chi_clickhouse_metric_VersionInteger gauge": True,
+                    "chi_clickhouse_metric_VersionInteger{" + labels +",hostname=\"chi-test-017-multi-version-default-0-0": True,
+                    "chi_clickhouse_metric_VersionInteger{" + labels +",hostname=\"chi-test-017-multi-version-default-1-0": True,
+                },
+            )
+
+        with Then("Check that custom_metrics is properly monitored"):
+            steps.check_metrics_monitoring(
+                operator_namespace = self.context.operator_namespace,
+                operator_pod = operator_pod,
+                expect_pattern="^chi_clickhouse_metric_MyCustomMetric{(.*?)} 1$"
+            )
 
         with When("reboot metrics exporter"):
             kubectl.launch(f"exec -n {self.context.operator_namespace} {operator_pod} -c metrics-exporter -- bash -c 'kill 1'")
diff --git a/tests/e2e/test_operator.py b/tests/e2e/test_operator.py
index 9d0431592..0b274324c 100644
--- a/tests/e2e/test_operator.py
+++ b/tests/e2e/test_operator.py
@@ -5439,7 +5439,7 @@ def test_020003(self):
     chi = yaml_manifest.get_name(util.get_full_path(manifest))
     cluster = "default"
     keeper_version_from = "24.8"
-    keeper_version_to = "24.9"
+    keeper_version_to = "25.3"
     with Given("CHI with 2 replicas"):
         kubectl.create_and_check(
             manifest=manifest,
@@ -5449,6 +5449,9 @@ def test_020003(self):
             },
         )
 
+    with And("Make sure Keeper is ready"):
+        kubectl.wait_chk_status('clickhouse-keeper', 'Completed')
+
     check_replication(chi, {0, 1}, 1)
 
     with When(f"I check clickhouse-keeper version is {keeper_version_from}"):