diff --git a/config/crd/bases/config.projectsveltos.io_clusterprofiles.yaml b/config/crd/bases/config.projectsveltos.io_clusterprofiles.yaml index c0162387..73145090 100644 --- a/config/crd/bases/config.projectsveltos.io_clusterprofiles.yaml +++ b/config/crd/bases/config.projectsveltos.io_clusterprofiles.yaml @@ -1138,11 +1138,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -1168,6 +1171,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1183,15 +1248,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1245,11 +1308,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -1275,6 +1341,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1290,15 +1418,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1352,11 +1478,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -1382,6 +1511,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1397,15 +1588,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1615,11 +1804,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -1645,6 +1837,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1660,15 +1914,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic diff --git a/config/crd/bases/config.projectsveltos.io_clusterpromotions.yaml b/config/crd/bases/config.projectsveltos.io_clusterpromotions.yaml index 4a427ba2..bf60500b 100644 --- a/config/crd/bases/config.projectsveltos.io_clusterpromotions.yaml +++ b/config/crd/bases/config.projectsveltos.io_clusterpromotions.yaml @@ -1040,13 +1040,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -1072,6 +1073,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1087,15 +1150,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1150,13 +1211,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -1182,6 +1244,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1197,15 +1321,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1260,13 +1382,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -1292,6 +1415,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1307,15 +1492,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1518,13 +1701,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -1550,6 +1734,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1565,15 +1811,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1699,13 +1943,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in - the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in - the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources @@ -1732,6 +1977,70 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query + expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace + to reference a secret resource. + type: string + namespace: + description: namespace defines the space + within which the secret name must be + unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1747,15 +2056,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch - in the managed Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array preHealthCheckDeployment: @@ -1989,13 +2296,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in - the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in - the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources @@ -2022,6 +2330,70 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query + expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace + to reference a secret resource. + type: string + namespace: + description: namespace defines the space + within which the secret name must be + unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -2037,15 +2409,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch - in the managed Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array preHealthCheckDeployment: diff --git a/config/crd/bases/config.projectsveltos.io_clustersummaries.yaml b/config/crd/bases/config.projectsveltos.io_clustersummaries.yaml index 8443bfa3..497cd8ae 100644 --- a/config/crd/bases/config.projectsveltos.io_clustersummaries.yaml +++ b/config/crd/bases/config.projectsveltos.io_clustersummaries.yaml @@ -1177,13 +1177,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -1209,6 +1210,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1224,15 +1287,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1287,13 +1348,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -1319,6 +1381,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1334,15 +1458,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1397,13 +1519,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -1429,6 +1552,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1444,15 +1629,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1663,13 +1846,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -1695,6 +1879,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1710,15 +1956,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic diff --git a/config/crd/bases/config.projectsveltos.io_profiles.yaml b/config/crd/bases/config.projectsveltos.io_profiles.yaml index 6515430a..394a1811 100644 --- a/config/crd/bases/config.projectsveltos.io_profiles.yaml +++ b/config/crd/bases/config.projectsveltos.io_profiles.yaml @@ -1138,11 +1138,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -1168,6 +1171,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1183,15 +1248,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1245,11 +1308,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -1275,6 +1341,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1290,15 +1418,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1352,11 +1478,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -1382,6 +1511,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1397,15 +1588,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1615,11 +1804,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -1645,6 +1837,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1660,15 +1914,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic diff --git a/controllers/handlers_utils.go b/controllers/handlers_utils.go index e2891f98..5d00d0e5 100644 --- a/controllers/handlers_utils.go +++ b/controllers/handlers_utils.go @@ -1605,9 +1605,12 @@ func prepareSetters(clusterSummary *configv1beta1.ClusterSummary, featureID libs pullmode.WithContinueOnConflict(clusterSummary.Spec.ClusterProfileSpec.ContinueOnConflict), pullmode.WithContinueOnError(clusterSummary.Spec.ClusterProfileSpec.ContinueOnError), pullmode.WithPreDeployChecks(clusterSummary.Spec.ClusterProfileSpec.PreDeployChecks), - pullmode.WithValidateHealths(clusterSummary.Spec.ClusterProfileSpec.ValidateHealths), pullmode.WithDeployedGVKs(gvks)) + if clusterSummary.DeletionTimestamp.IsZero() { + setters = append(setters, pullmode.WithValidateHealths(clusterSummary.Spec.ClusterProfileSpec.ValidateHealths)) + } + if includeDeleteChecks { setters = append(setters, pullmode.WithPreDeleteChecks(clusterSummary.Spec.ClusterProfileSpec.PreDeleteChecks), diff --git a/go.mod b/go.mod index 3e48da69..2aa5df8e 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/onsi/ginkgo/v2 v2.29.0 github.com/onsi/gomega v1.41.0 github.com/pkg/errors v0.9.1 - github.com/projectsveltos/libsveltos v1.10.1-0.20260521153750-a1f348424b3f + github.com/projectsveltos/libsveltos v1.10.1-0.20260529122402-5f1c02139fd0 github.com/prometheus/client_golang v1.23.2 github.com/robfig/cron v1.2.0 github.com/spf13/pflag v1.0.10 diff --git a/go.sum b/go.sum index d0734b93..8275b59e 100644 --- a/go.sum +++ b/go.sum @@ -94,8 +94,6 @@ github.com/fluxcd/cli-utils v1.2.0 h1:1o07pXTMxJ/XJ1GpAbLtjdXwfCUMq4Ku1OcnvJHLoh github.com/fluxcd/cli-utils v1.2.0/go.mod h1:d5HdTDdR5sCbsIbgtOQ7x7srKYwYeZORU6CD2yn4j/M= github.com/fluxcd/pkg/apis/acl v0.9.0 h1:wBpgsKT+jcyZEcM//OmZr9RiF8klL3ebrDp2u2ThsnA= github.com/fluxcd/pkg/apis/acl v0.9.0/go.mod h1:TttNS+gocsGLwnvmgVi3/Yscwqrjc17+vhgYfqkfrV4= -github.com/fluxcd/pkg/apis/meta v1.27.0 h1:EspByEk5j8w3rs1cGbEh9AjSmpDwQIz7DFG/zzqf6uI= -github.com/fluxcd/pkg/apis/meta v1.27.0/go.mod h1:2t6JyrRfvIBhx6EBnXfFh/6sCCJ1db9WGaqko0JmNOE= github.com/fluxcd/pkg/apis/meta v1.28.0 h1:eJjMlLnfObnh23cyUB6xiIwDbgJaRU2MgfzzuilLFxI= github.com/fluxcd/pkg/apis/meta v1.28.0/go.mod h1:3DmYMnyH3XdY8/g2gXfsVIGEd/zpcB2PEkuurv2vgHU= github.com/fluxcd/pkg/http/fetch v0.25.0 h1:BM2sv9MygBBQ7+G+ISuTEGLVRV4GX9bpKK5UoAKLiQo= @@ -256,8 +254,6 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.28.3 h1:4JvMdwtFU0imd8fHx25OJXoDMRexnf8v5NHKYSTTji4= -github.com/onsi/ginkgo/v2 v2.28.3/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44= github.com/onsi/ginkgo/v2 v2.29.0 h1:rfh+ZFjgJhYWRoIqVf3Uwx/W20yLrcrE2h2GmYVRaag= github.com/onsi/ginkgo/v2 v2.29.0/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44= github.com/onsi/gomega v1.41.0 h1:OwKp4pXNgVxf6sCplzYo794OFNuoL2q2SBMU5NSWOjA= @@ -277,8 +273,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= -github.com/projectsveltos/libsveltos v1.10.1-0.20260521153750-a1f348424b3f h1:XrgpnRRH59AwSkSEIcKPUDpAME0Sl4sXLeEhDIaYQMU= -github.com/projectsveltos/libsveltos v1.10.1-0.20260521153750-a1f348424b3f/go.mod h1:AzKBiyMTL3KSTLYMii5QdR3ieWyUKBHZCMFWIVCfm6A= +github.com/projectsveltos/libsveltos v1.10.1-0.20260529122402-5f1c02139fd0 h1:MK7tWuz0RKKJS6SITR9fHsRXH9rRq4uYN4QmQbtHehc= +github.com/projectsveltos/libsveltos v1.10.1-0.20260529122402-5f1c02139fd0/go.mod h1:AzKBiyMTL3KSTLYMii5QdR3ieWyUKBHZCMFWIVCfm6A= github.com/projectsveltos/lua-utils/glua-json v0.0.0-20251212200258-2b3cdcb7c0f5 h1:khnc+994UszxZYu69J+R5FKiLA/Nk1JQj0EYAkwTWz0= github.com/projectsveltos/lua-utils/glua-json v0.0.0-20251212200258-2b3cdcb7c0f5/go.mod h1:yVL8KQFa9tmcxgwl9nwIMtKgtmIVC1zaFRSCfOwYvPY= github.com/projectsveltos/lua-utils/glua-runes v0.0.0-20251212200258-2b3cdcb7c0f5 h1:YbsebwRwTRhV8QacvEAdFqxcxHdeu7JTVtsBovbkgos= diff --git a/lib/clusterops/export_test.go b/lib/clusterops/export_test.go index 985b1fba..88867cd3 100644 --- a/lib/clusterops/export_test.go +++ b/lib/clusterops/export_test.go @@ -26,4 +26,9 @@ var ( var ( IsHealthy = isHealthyBasedOnLua FetchResources = fetchResources + ExtractScalar = extractScalar + ParsePromValue = parsePromValue ) + +// PrometheusData is exported for use in tests. +type PrometheusData = prometheusData diff --git a/lib/clusterops/validate_health.go b/lib/clusterops/validate_health.go index a85fcbfd..177f86e4 100644 --- a/lib/clusterops/validate_health.go +++ b/lib/clusterops/validate_health.go @@ -18,8 +18,14 @@ package clusterops import ( "context" + "encoding/base64" "encoding/json" "fmt" + "io" + "net/http" + "strconv" + "strings" + "time" "github.com/go-logr/logr" lua "github.com/yuin/gopher-lua" @@ -38,6 +44,11 @@ import ( sveltoslua "github.com/projectsveltos/libsveltos/lib/lua" ) +const ( + defaultPrometheusPath = "api/v1/query" + metricsHTTPTimeout = 30 * time.Second +) + type healthStatus struct { Healthy bool `json:"healthy"` Message string `json:"message"` @@ -58,6 +69,19 @@ func (e *HealthCheckError) Unwrap() error { return e.InternalErr } +// prometheusResponse is the top-level Prometheus HTTP API response. +type prometheusResponse struct { + Status string `json:"status"` + Error string `json:"error,omitempty"` + Data prometheusData `json:"data"` +} + +// prometheusData holds the result type and raw result from a Prometheus query. +type prometheusData struct { + ResultType string `json:"resultType"` + Result json.RawMessage `json:"result"` +} + // ValidateHealthPolicies runs all validateDeployment checks registered for the feature (Helm/Kustomize/Resources) func ValidateHealthPolicies(ctx context.Context, remoteConfig *rest.Config, validateHealths []libsveltosv1beta1.ValidateHealth, featureID libsveltosv1beta1.FeatureID, isDelete bool, logger logr.Logger) error { @@ -93,6 +117,16 @@ func validateHealthPolicy(ctx context.Context, remoteConfig *rest.Config, check l := logger.WithValues("validation", check.Name) l.V(logs.LogDebug).Info("running health validation") + metricsData, err := fetchMetrics(ctx, remoteConfig, check, l) + if err != nil { + return err + } + + // Metrics-only check: no resource kind specified, evaluate the script once. + if check.Kind == "" { + return evaluateMetricsOnly(check, metricsData, l) + } + list, err := fetchResources(ctx, remoteConfig, check) if err != nil { return err @@ -121,7 +155,7 @@ func validateHealthPolicy(ctx context.Context, remoteConfig *rest.Config, check l.V(logs.LogDebug).Info("examing resource's health") var healthy bool var msg string - healthy, msg, err = isHealthyBasedOnLua(&list.Items[i], check.Script, logger) + healthy, msg, err = isHealthyBasedOnLua(&list.Items[i], check.Script, metricsData, logger) if err != nil { return err } @@ -142,6 +176,212 @@ func validateHealthPolicy(ctx context.Context, remoteConfig *rest.Config, check return nil } +// evaluateMetricsOnly runs the Lua script once with no resource argument, +// using only the metric values collected from MetricSource. +func evaluateMetricsOnly(check *libsveltosv1beta1.ValidateHealth, metricsData map[string]float64, + logger logr.Logger) error { + + if check.Script == "" { + return fmt.Errorf("validateHealth %s: metric-only check (no kind set) requires a Lua script", check.Name) + } + + healthy, msg, err := isHealthyBasedOnLua(nil, check.Script, metricsData, logger) + if err != nil { + return err + } + if !healthy { + return fmt.Errorf("metric health check failed: %s", msg) + } + return nil +} + +// fetchMetrics queries the metric endpoint defined in check.MetricSource and +// returns a map from query name to scalar float value. Returns nil when no +// MetricSource is configured. +func fetchMetrics(ctx context.Context, remoteConfig *rest.Config, + check *libsveltosv1beta1.ValidateHealth, logger logr.Logger) (map[string]float64, error) { + + if check.MetricSource == nil || len(check.MetricQueries) == 0 { + return nil, nil + } + + source := check.MetricSource + + authHeader, err := buildAuthHeader(ctx, remoteConfig, source) + if err != nil { + return nil, fmt.Errorf("reading metric credentials: %w", err) + } + + path := source.Path + if path == "" { + path = defaultPrometheusPath + } + path = strings.TrimLeft(path, "/") + + endpoint := strings.TrimRight(source.URL, "/") + "/" + path + + httpClient := &http.Client{Timeout: metricsHTTPTimeout} + + results := make(map[string]float64, len(check.MetricQueries)) + for i := range check.MetricQueries { + q := &check.MetricQueries[i] + logger.V(logs.LogDebug).Info("querying metric", "name", q.Name, "query", q.Query) + value, err := queryMetricEndpoint(ctx, httpClient, endpoint, q.Query, authHeader) + if err != nil { + return nil, fmt.Errorf("metric query %q: %w", q.Name, err) + } + results[q.Name] = value + } + return results, nil +} + +// queryMetricEndpoint executes a single instant query against a +// Prometheus-compatible endpoint and returns the scalar result. +func queryMetricEndpoint(ctx context.Context, httpClient *http.Client, + endpoint, query, authHeader string) (float64, error) { + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint, http.NoBody) + if err != nil { + return 0, fmt.Errorf("building request: %w", err) + } + + params := req.URL.Query() + params.Set("query", query) + req.URL.RawQuery = params.Encode() + + if authHeader != "" { + req.Header.Set("Authorization", authHeader) + } + + resp, err := httpClient.Do(req) + if err != nil { + return 0, fmt.Errorf("querying Prometheus: %w", err) + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + return 0, fmt.Errorf("reading response: %w", err) + } + + if resp.StatusCode != http.StatusOK { + return 0, fmt.Errorf("metric source returned HTTP %d: %s", resp.StatusCode, string(body)) + } + + var promResp prometheusResponse + if err := json.Unmarshal(body, &promResp); err != nil { + return 0, fmt.Errorf("decoding Prometheus response: %w", err) + } + if promResp.Status != "success" { + return 0, fmt.Errorf("metric query failed: %s", promResp.Error) + } + + return extractScalar(promResp.Data) +} + +// extractScalar pulls a single float64 from a Prometheus-compatible instant-query result. +// Accepts scalar and single-element vector result types. +func extractScalar(data prometheusData) (float64, error) { + switch data.ResultType { + case "scalar": + // scalar result: [unixTime, "value"] + var pair [2]json.RawMessage + if err := json.Unmarshal(data.Result, &pair); err != nil { + return 0, fmt.Errorf("parsing scalar result: %w", err) + } + return parsePromValue(pair[1]) + case "vector": + var results []struct { + Value [2]json.RawMessage `json:"value"` + } + if err := json.Unmarshal(data.Result, &results); err != nil { + return 0, fmt.Errorf("parsing vector result: %w", err) + } + if len(results) == 0 { + return 0, fmt.Errorf("metric query returned no data") + } + if len(results) > 1 { + return 0, fmt.Errorf("metric query returned %d series; use an aggregation (e.g. sum()) to produce a single value", + len(results)) + } + return parsePromValue(results[0].Value[1]) + default: + return 0, fmt.Errorf("unsupported Prometheus result type %q; use an instant query returning scalar or vector", + data.ResultType) + } +} + +// parsePromValue converts a quoted Prometheus value string (e.g. "3.14") to float64. +func parsePromValue(raw json.RawMessage) (float64, error) { + var s string + if err := json.Unmarshal(raw, &s); err != nil { + return 0, fmt.Errorf("parsing value token: %w", err) + } + v, err := strconv.ParseFloat(s, 64) + if err != nil { + return 0, fmt.Errorf("converting %q to float64: %w", s, err) + } + return v, nil +} + +// buildAuthHeader reads credentials from source.SecretRef on the managed cluster +// and returns the appropriate Authorization header value, or empty string when +// no SecretRef is set. +func buildAuthHeader(ctx context.Context, remoteConfig *rest.Config, + source *libsveltosv1beta1.MetricSource) (string, error) { + + if source.SecretRef == nil { + return "", nil + } + + dynamicClient, err := dynamic.NewForConfig(remoteConfig) + if err != nil { + return "", fmt.Errorf("creating dynamic client: %w", err) + } + + secretGVR := schema.GroupVersionResource{Group: "", Version: "v1", Resource: "secrets"} + obj, err := dynamicClient.Resource(secretGVR). + Namespace(source.SecretRef.Namespace). + Get(ctx, source.SecretRef.Name, metav1.GetOptions{}) + if err != nil { + return "", fmt.Errorf("getting Secret %s/%s: %w", + source.SecretRef.Namespace, source.SecretRef.Name, err) + } + + // Secret.data values arrive base64-encoded from the Kubernetes API. + rawData, _, _ := unstructured.NestedStringMap(obj.Object, "data") + + if b64Token, ok := rawData["token"]; ok { + token, err := base64.StdEncoding.DecodeString(b64Token) + if err != nil { + return "", fmt.Errorf("decoding token from Secret %s/%s: %w", + source.SecretRef.Namespace, source.SecretRef.Name, err) + } + return "Bearer " + string(token), nil + } + + b64User, hasUser := rawData["username"] + b64Pass, hasPass := rawData["password"] + if hasUser && hasPass { + username, err := base64.StdEncoding.DecodeString(b64User) + if err != nil { + return "", fmt.Errorf("decoding username from Secret %s/%s: %w", + source.SecretRef.Namespace, source.SecretRef.Name, err) + } + password, err := base64.StdEncoding.DecodeString(b64Pass) + if err != nil { + return "", fmt.Errorf("decoding password from Secret %s/%s: %w", + source.SecretRef.Namespace, source.SecretRef.Name, err) + } + encoded := base64.StdEncoding.EncodeToString( + []byte(string(username) + ":" + string(password))) + return "Basic " + encoded, nil + } + + return "", fmt.Errorf("secret %s/%s must contain key \"token\" or keys \"username\" and \"password\"", + source.SecretRef.Namespace, source.SecretRef.Name) +} + // fetchResources fetches resources from the managed cluster func fetchResources(ctx context.Context, remoteConfig *rest.Config, check *libsveltosv1beta1.ValidateHealth, ) (*unstructured.UnstructuredList, error) { @@ -234,8 +474,13 @@ func isHealthyBasedOnCELRules(resource *unstructured.Unstructured, rules []libsv return healthy, err } -// isHealthyBasedOnLua verifies whether resource is healthy according to Lua script -func isHealthyBasedOnLua(resource *unstructured.Unstructured, script string, logger logr.Logger, +// isHealthyBasedOnLua verifies whether resource is healthy according to a Lua script. +// resource may be nil for metric-only checks; in that case evaluate is called with +// lua.LNil and obj is set to nil in the global environment. +// metricsData is injected as a global "metrics" table so scripts can access metric +// values via metrics[""]. An empty or nil map results in an empty table. +func isHealthyBasedOnLua(resource *unstructured.Unstructured, script string, + metricsData map[string]float64, logger logr.Logger, ) (healthy bool, msg string, err error) { if script == "" { @@ -247,7 +492,13 @@ func isHealthyBasedOnLua(resource *unstructured.Unstructured, script string, log sveltoslua.LoadModulesAndRegisterMethods(l) - obj := sveltoslua.MapToTable(resource.UnstructuredContent()) + // Always inject a metrics table so scripts can safely reference metrics["x"] + // even when no queries were executed. + metricsTable := l.NewTable() + for k, v := range metricsData { + metricsTable.RawSetString(k, lua.LNumber(v)) + } + l.SetGlobal("metrics", metricsTable) err = l.DoString(script) if err != nil { @@ -255,13 +506,21 @@ func isHealthyBasedOnLua(resource *unstructured.Unstructured, script string, log return false, "", err } - l.SetGlobal("obj", obj) + var luaArg lua.LValue + if resource != nil { + obj := sveltoslua.MapToTable(resource.UnstructuredContent()) + l.SetGlobal("obj", obj) + luaArg = obj + } else { + l.SetGlobal("obj", lua.LNil) + luaArg = lua.LNil + } err = l.CallByParam(lua.P{ Fn: l.GetGlobal("evaluate"), // name of Lua function NRet: 1, // number of returned values Protect: true, // return err or panic - }, obj) + }, luaArg) if err != nil { logger.V(logs.LogInfo).Info(fmt.Sprintf("failed to evaluate health for resource: %v", err)) return false, "", err @@ -295,8 +554,11 @@ func isHealthyBasedOnLua(resource *unstructured.Unstructured, script string, log logger.V(logs.LogDebug).Info(fmt.Sprintf("is healthy: %t", result.Healthy)) if !result.Healthy { - return false, fmt.Sprintf("resource %s/%s is not healthy: %s", - resource.GetNamespace(), resource.GetName(), result.Message), nil + if resource != nil { + return false, fmt.Sprintf("resource %s/%s is not healthy: %s", + resource.GetNamespace(), resource.GetName(), result.Message), nil + } + return false, result.Message, nil } return true, "", nil diff --git a/lib/clusterops/validate_health_test.go b/lib/clusterops/validate_health_test.go index 7093eeb4..1c9bc4f6 100644 --- a/lib/clusterops/validate_health_test.go +++ b/lib/clusterops/validate_health_test.go @@ -18,6 +18,7 @@ package clusterops_test import ( "context" + "encoding/json" "fmt" "os" "path/filepath" @@ -170,7 +171,7 @@ func verifyHealthLuaPolicy(dirName string) { By("Verifying valid resource") for i := range validResources { resource := validResources[i] - healthy, _, err := clusterops.IsHealthy(resource, string(luaPolicy), textlogger.NewLogger(textlogger.NewConfig())) + healthy, _, err := clusterops.IsHealthy(resource, string(luaPolicy), nil, textlogger.NewLogger(textlogger.NewConfig())) Expect(err).To(BeNil()) Expect(healthy).To(BeTrue()) } @@ -183,13 +184,151 @@ func verifyHealthLuaPolicy(dirName string) { By("Verifying non-matching content") for i := range invalidResources { resource := invalidResources[i] - healthy, _, err := clusterops.IsHealthy(resource, string(luaPolicy), textlogger.NewLogger(textlogger.NewConfig())) + healthy, _, err := clusterops.IsHealthy(resource, string(luaPolicy), nil, textlogger.NewLogger(textlogger.NewConfig())) Expect(err).To(BeNil()) Expect(healthy).To(BeFalse()) } } } +var _ = Describe("Metric health checks", func() { + + logger := textlogger.NewLogger(textlogger.NewConfig()) + + Context("parsePromValue", func() { + It("parses an integer value string", func() { + v, err := clusterops.ParsePromValue(json.RawMessage(`"42"`)) + Expect(err).To(BeNil()) + Expect(v).To(Equal(float64(42))) + }) + + It("parses a float value string", func() { + v, err := clusterops.ParsePromValue(json.RawMessage(`"3.14"`)) + Expect(err).To(BeNil()) + Expect(v).To(BeNumerically("~", 3.14, 0.001)) + }) + + It("returns error for non-string JSON", func() { + _, err := clusterops.ParsePromValue(json.RawMessage(`123`)) + Expect(err).NotTo(BeNil()) + }) + + It("returns error for non-numeric string", func() { + _, err := clusterops.ParsePromValue(json.RawMessage(`"abc"`)) + Expect(err).NotTo(BeNil()) + }) + }) + + Context("extractScalar", func() { + It("extracts value from scalar result type", func() { + data := clusterops.PrometheusData{ + ResultType: "scalar", + Result: json.RawMessage(`[1234567890.123, "7.5"]`), + } + v, err := clusterops.ExtractScalar(data) + Expect(err).To(BeNil()) + Expect(v).To(Equal(7.5)) + }) + + It("extracts value from single-element vector", func() { + data := clusterops.PrometheusData{ + ResultType: "vector", + Result: json.RawMessage(`[{"metric":{"job":"app"},"value":[1234567890.123,"2.0"]}]`), + } + v, err := clusterops.ExtractScalar(data) + Expect(err).To(BeNil()) + Expect(v).To(Equal(2.0)) + }) + + It("returns error for empty vector", func() { + data := clusterops.PrometheusData{ + ResultType: "vector", + Result: json.RawMessage(`[]`), + } + _, err := clusterops.ExtractScalar(data) + Expect(err).NotTo(BeNil()) + }) + + It("returns error for multi-element vector", func() { + data := clusterops.PrometheusData{ + ResultType: "vector", + Result: json.RawMessage( + `[{"metric":{},"value":[1,"1"]},{"metric":{},"value":[2,"2"]}]`), + } + _, err := clusterops.ExtractScalar(data) + Expect(err).NotTo(BeNil()) + }) + + It("returns error for unsupported result type", func() { + data := clusterops.PrometheusData{ + ResultType: "matrix", + Result: json.RawMessage(`[]`), + } + _, err := clusterops.ExtractScalar(data) + Expect(err).NotTo(BeNil()) + }) + }) + + Context("isHealthyBasedOnLua with metrics", func() { + const errorRateScript = ` +function evaluate() + if metrics["errorRate"] > 0.05 then + return {healthy=false, message="error rate too high"} + end + return {healthy=true, message=""} +end` + + It("evaluates metrics-only check as healthy", func() { + healthy, _, err := clusterops.IsHealthy(nil, errorRateScript, + map[string]float64{"errorRate": 0.01}, logger) + Expect(err).To(BeNil()) + Expect(healthy).To(BeTrue()) + }) + + It("evaluates metrics-only check as unhealthy when threshold exceeded", func() { + healthy, msg, err := clusterops.IsHealthy(nil, errorRateScript, + map[string]float64{"errorRate": 0.10}, logger) + Expect(err).To(BeNil()) + Expect(healthy).To(BeFalse()) + Expect(msg).NotTo(BeEmpty()) + }) + + It("makes metrics available alongside resource obj", func() { + obj := &unstructured.Unstructured{} + obj.SetKind("Deployment") + obj.SetNamespace("default") + obj.SetName("my-app") + obj.Object["spec"] = map[string]interface{}{"replicas": int64(2)} + obj.Object["status"] = map[string]interface{}{"availableReplicas": int64(2)} + + script := ` +function evaluate(obj) + if obj.status.availableReplicas ~= obj.spec.replicas then + return {healthy=false, message="replicas not ready"} + end + if metrics["p99Ms"] > 500 then + return {healthy=false, message="latency too high"} + end + return {healthy=true, message=""} +end` + healthy, _, err := clusterops.IsHealthy(obj, script, + map[string]float64{"p99Ms": 200}, logger) + Expect(err).To(BeNil()) + Expect(healthy).To(BeTrue()) + }) + + It("empty metrics table does not cause script error", func() { + script := ` +function evaluate() + return {healthy=true, message=""} +end` + healthy, _, err := clusterops.IsHealthy(nil, script, nil, logger) + Expect(err).To(BeNil()) + Expect(healthy).To(BeTrue()) + }) + }) +}) + func getResources(dirName, fileName string) []*unstructured.Unstructured { resourceFileName := filepath.Join(dirName, fileName) diff --git a/manifest/manifest.yaml b/manifest/manifest.yaml index 72cdafc4..38aa4f2e 100644 --- a/manifest/manifest.yaml +++ b/manifest/manifest.yaml @@ -1447,11 +1447,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -1477,6 +1480,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1492,15 +1557,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1554,11 +1617,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -1584,6 +1650,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1599,15 +1727,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1661,11 +1787,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -1691,6 +1820,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1706,15 +1897,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -1924,11 +2113,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -1954,6 +2146,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -1969,15 +2223,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -3290,13 +3542,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -3322,6 +3575,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -3337,15 +3652,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -3400,13 +3713,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -3432,6 +3746,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -3447,15 +3823,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -3510,13 +3884,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -3542,6 +3917,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -3557,15 +3994,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -3768,13 +4203,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -3800,6 +4236,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -3815,15 +4313,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -3949,13 +4445,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in - the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in - the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources @@ -3982,6 +4479,70 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query + expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace + to reference a secret resource. + type: string + namespace: + description: namespace defines the space + within which the secret name must be + unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -3997,15 +4558,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch - in the managed Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array preHealthCheckDeployment: @@ -4239,13 +4798,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in - the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in - the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources @@ -4272,6 +4832,70 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query + expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace + to reference a secret resource. + type: string + namespace: + description: namespace defines the space + within which the secret name must be + unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -4287,15 +4911,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch - in the managed Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array preHealthCheckDeployment: @@ -6014,13 +6636,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -6046,6 +6669,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -6061,15 +6746,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -6124,13 +6807,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -6156,6 +6840,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -6171,15 +6917,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -6234,13 +6978,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -6262,10 +7007,72 @@ spec: description: Value is the label value type: string required: - - key - - operation + - key + - operation + type: object + type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query type: object type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -6281,15 +7088,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -6500,13 +7305,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed - Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed - Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based @@ -6532,6 +7338,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to + reference a secret resource. + type: string + namespace: + description: namespace defines the space within + which the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -6547,15 +7415,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -7895,11 +8761,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -7925,6 +8794,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -7940,15 +8871,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -8002,11 +8931,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -8032,6 +8964,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -8047,15 +9041,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -8109,11 +9101,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -8139,6 +9134,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -8154,15 +9211,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic @@ -8372,11 +9427,14 @@ spec: - Kustomize type: string group: - description: Group of the resource to fetch in the managed Cluster. + description: |- + Group of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string kind: - description: Kind of the resource to fetch in the managed Cluster. - minLength: 1 + description: |- + Kind of the resource to fetch in the managed Cluster. + Leave empty for metric-only checks. type: string labelFilters: description: LabelFilters allows to filter resources based on @@ -8402,6 +9460,68 @@ spec: - operation type: object type: array + metricQueries: + description: |- + MetricQueries lists the PromQL instant queries to execute against + MetricSource. Results are injected into the evaluation script as a + "metrics" map keyed by each query's Name field, value is the scalar + float result. Scripts access results via metrics[""]. + items: + description: |- + MetricQuery binds a PromQL instant-query result to a name the evaluation + script can reference via the metrics table (e.g. metrics["errorRate"]). + properties: + name: + description: |- + Name is the key under which the scalar result is available in the script. + Must be unique within the ValidateHealth entry. + minLength: 1 + type: string + query: + description: Query is a PromQL instant-query expression. + minLength: 1 + type: string + required: + - name + - query + type: object + type: array + metricSource: + description: |- + MetricSource identifies the Prometheus-compatible endpoint to query. + Required when MetricQueries is set. + properties: + path: + description: |- + Path is the HTTP path for Prometheus instant queries. + Defaults to /api/v1/query when empty. + type: string + secretRef: + description: |- + SecretRef optionally references a Secret on the managed cluster containing + credentials to authenticate against the endpoint. + The Secret namespace and name must both be specified. + Supported keys: "token" (bearer token), "username" and "password" (basic auth). + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + url: + description: |- + URL is the base HTTP(S) address of the Prometheus-compatible endpoint + (e.g. http://prometheus.monitoring.svc:9090). + minLength: 1 + type: string + required: + - url + type: object name: description: Name is the name of this check type: string @@ -8417,15 +9537,13 @@ spec: representing whether object is a match (true or false) type: string version: - description: Version of the resource to fetch in the managed - Cluster. + description: |- + Version of the resource to fetch in the managed Cluster. + Required when Kind is set. Leave empty for metric-only checks. type: string required: - featureID - - group - - kind - name - - version type: object type: array x-kubernetes-list-type: atomic diff --git a/test/fv/validate_health_metrics_test.go b/test/fv/validate_health_metrics_test.go new file mode 100644 index 00000000..75247f46 --- /dev/null +++ b/test/fv/validate_health_metrics_test.go @@ -0,0 +1,262 @@ +/* +Copyright 2026. projectsveltos.io. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package fv_test + +import ( + "context" + "fmt" + "net" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + + configv1beta1 "github.com/projectsveltos/addon-controller/api/v1beta1" + "github.com/projectsveltos/addon-controller/lib/clusterops" + libsveltosv1beta1 "github.com/projectsveltos/libsveltos/api/v1beta1" +) + +// prometheusHelmValues configures the prometheus-community/prometheus chart for FV tests: +// - only the Prometheus server component is enabled (alertmanager, pushgateway, +// kube-state-metrics and nodeExporter are disabled to save resources) +// - the server service is exposed as NodePort 30090 so the management cluster can +// reach it in push mode (both clusters share the same Docker bridge network) +// - a static scrape job targets podinfo on port 9898 inside the managed cluster +const prometheusHelmValues = ` +alertmanager: + enabled: false +prometheus-pushgateway: + enabled: false +kube-state-metrics: + enabled: false +nodeExporter: + enabled: false +configmapReload: + prometheus: + enabled: false +server: + persistentVolume: + enabled: false + service: + type: NodePort + nodePort: 30090 +extraScrapeConfigs: | + - job_name: podinfo + static_configs: + - targets: + - podinfo.monitoring.svc.cluster.local:9898 +` + +// luaDeploymentHealthScript evaluates whether a Deployment has all requested replicas available. +const luaDeploymentHealthScript = ` +function evaluate(obj) + if obj.status ~= nil and obj.status.availableReplicas ~= nil + and obj.status.availableReplicas == obj.spec.replicas then + return {healthy=true, message=""} + end + return {healthy=false, message="available replicas not matching requested replicas"} +end` + +// luaMetricUpScript evaluates the "up" metric returned for a scrape job. +// A value of 1 means the target is being scraped successfully. +const luaMetricUpScript = ` +function evaluate() + if metrics["up"] < 1 then + return {healthy=false, message="target not yet scraped: up=" .. tostring(metrics["up"])} + end + return {healthy=true, message=""} +end` + +var _ = Describe("ValidateHealth metric-based checks", func() { + const ( + namePrefix = "metric-health-" + monitoringNs = "monitoring" + prometheusRelease = "prometheus-server" + podinfoRelease = "podinfo" + ) + + // Runs in push mode only (CAPI): in pull mode the agent would need to implement + // metric checks, which is a separate change. + It("holds a ClusterProfile as not provisioned until Prometheus confirms the app is scraped", + Label("NEW-FV", "NEW-FV-PULLMODE", "EXTENDED"), func() { + + Byf("Determining Prometheus URL for cluster %s/%s", + kindWorkloadCluster.GetNamespace(), kindWorkloadCluster.GetName()) + prometheusURL, err := getPrometheusURL() + Expect(err).To(BeNil()) + Byf("Prometheus URL: %s", prometheusURL) + + // ── ClusterProfile 1: Prometheus + Byf("Creating ClusterProfile %s to deploy Prometheus in namespace %s", + namePrefix+"prometheus", monitoringNs) + cpPrometheus := getClusterProfile(namePrefix+"prometheus-", map[string]string{key: value}) + cpPrometheus.Spec.SyncMode = configv1beta1.SyncModeContinuous + cpPrometheus.Spec.HelmCharts = []configv1beta1.HelmChart{ + { + RepositoryURL: "https://prometheus-community.github.io/helm-charts", + RepositoryName: "prometheus-community", + ChartName: "prometheus-community/prometheus", + ChartVersion: "25.27.0", + ReleaseName: prometheusRelease, + ReleaseNamespace: monitoringNs, + HelmChartAction: configv1beta1.HelmChartActionInstall, + Values: prometheusHelmValues, + }, + } + cpPrometheus.Spec.ValidateHealths = []libsveltosv1beta1.ValidateHealth{ + { + Name: "prometheus-server-ready", + FeatureID: libsveltosv1beta1.FeatureHelm, + Group: "apps", + Version: "v1", + Kind: "Deployment", + Namespace: monitoringNs, + Script: luaDeploymentHealthScript, + }, + } + Expect(k8sClient.Create(context.TODO(), cpPrometheus)).To(Succeed()) + + verifyClusterProfileMatches(cpPrometheus) + clusterSummaryPrometheus := verifyClusterSummary(clusterops.ClusterProfileLabelName, + cpPrometheus.Name, &cpPrometheus.Spec, + kindWorkloadCluster.GetNamespace(), kindWorkloadCluster.GetName(), getClusterType()) + + // Deploying Prometheus takes time. + Byf("Waiting for ClusterSummary %s to provision Prometheus", clusterSummaryPrometheus.Name) + const two = 2 + Eventually(func() bool { + currentClusterSummary := &configv1beta1.ClusterSummary{} + err := k8sClient.Get(context.TODO(), + types.NamespacedName{Namespace: clusterSummaryPrometheus.Namespace, Name: clusterSummaryPrometheus.Name}, + currentClusterSummary) + if err != nil { + return false + } + for i := range currentClusterSummary.Status.FeatureSummaries { + if currentClusterSummary.Status.FeatureSummaries[i].FeatureID == libsveltosv1beta1.FeatureHelm { + if currentClusterSummary.Status.FeatureSummaries[i].Status == libsveltosv1beta1.FeatureStatusProvisioned && + currentClusterSummary.Status.FeatureSummaries[i].FailureMessage == nil { + + return true + } + } + } + return false + }, two*timeout, pollingInterval).Should(BeTrue()) + + // ── ClusterProfile 2: podinfo + // DependsOn ensures podinfo is only deployed after Prometheus is provisioned. + // The validateHealth metric check holds the profile as not provisioned until + // Prometheus reports up{job="podinfo"} == 1 (i.e. podinfo is being scraped). + Byf("Creating ClusterProfile %s to deploy podinfo in namespace %s", + namePrefix+"podinfo", monitoringNs) + cpPodinfo := getClusterProfile(namePrefix+"podinfo-", map[string]string{key: value}) + cpPodinfo.Spec.SyncMode = configv1beta1.SyncModeContinuous + cpPodinfo.Spec.DependsOn = []string{cpPrometheus.Name} + cpPodinfo.Spec.HelmCharts = []configv1beta1.HelmChart{ + { + RepositoryURL: "https://stefanprodan.github.io/podinfo", + RepositoryName: "podinfo", + ChartName: "podinfo/podinfo", + ChartVersion: "6.7.1", + ReleaseName: podinfoRelease, + ReleaseNamespace: monitoringNs, + HelmChartAction: configv1beta1.HelmChartActionInstall, + Values: "image:\n repository: docker.io/stefanprodan/podinfo\n", + }, + } + cpPodinfo.Spec.ValidateHealths = []libsveltosv1beta1.ValidateHealth{ + { + Name: "podinfo-scraped", + FeatureID: libsveltosv1beta1.FeatureHelm, + MetricSource: &libsveltosv1beta1.MetricSource{ + URL: prometheusURL, + }, + MetricQueries: []libsveltosv1beta1.MetricQuery{ + { + Name: "up", + Query: `up{job="podinfo"}`, + }, + }, + Script: luaMetricUpScript, + }, + } + Expect(k8sClient.Create(context.TODO(), cpPodinfo)).To(Succeed()) + + verifyClusterProfileMatches(cpPodinfo) + clusterSummaryPodinfo := verifyClusterSummary(clusterops.ClusterProfileLabelName, + cpPodinfo.Name, &cpPodinfo.Spec, + kindWorkloadCluster.GetNamespace(), kindWorkloadCluster.GetName(), getClusterType()) + + Byf("Waiting for ClusterSummary %s to provision podinfo (metric check must pass)", + clusterSummaryPodinfo.Name) + verifyFeatureStatusIsProvisioned(kindWorkloadCluster.GetNamespace(), + clusterSummaryPodinfo.Name, libsveltosv1beta1.FeatureHelm) + + // ── Cleanup ─────────────────────────────────────────────────────────────── + Byf("Deleting ClusterProfile %s (podinfo)", cpPodinfo.Name) + deleteClusterProfile(cpPodinfo) + + Byf("Deleting ClusterProfile %s (Prometheus)", cpPrometheus.Name) + // Update prometheus profile to remove the finalizer dependency before deleting + currentCP := &configv1beta1.ClusterProfile{} + Expect(k8sClient.Get(context.TODO(), + types.NamespacedName{Name: cpPrometheus.Name}, currentCP)).To(Succeed()) + deleteClusterProfile(cpPrometheus) + }) +}) + +// getPrometheusURL returns the URL to use in the validateHealth metricSource. +// In pull mode (SveltosCluster) the agent runs inside the managed cluster and can +// reach the service via its DNS name. +// In push mode (CAPI) the addon-controller runs on the management cluster; both clusters +// share the same Docker bridge network, so the NodePort (30090) is reachable at the +// InternalIP of any workload cluster node. +func getPrometheusURL() (string, error) { + if kindWorkloadCluster.GetKind() == libsveltosv1beta1.SveltosClusterKind { + return "http://prometheus-server-server.monitoring.svc:80", nil + } + + // Push mode: the workload kubeconfig server URL may be 0.0.0.0 (the local bind + // address used when creating the kind cluster), so we get the real Docker bridge IP + // by listing the workload cluster's nodes directly. + workloadClient, err := getKindWorkloadClusterKubeconfig() + if err != nil { + return "", fmt.Errorf("getting workload cluster client: %w", err) + } + + nodeList := &corev1.NodeList{} + if err := workloadClient.List(context.TODO(), nodeList, &client.ListOptions{}); err != nil { + return "", fmt.Errorf("listing workload cluster nodes: %w", err) + } + if len(nodeList.Items) == 0 { + return "", fmt.Errorf("no nodes found in workload cluster") + } + + for i := range nodeList.Items { + for _, addr := range nodeList.Items[i].Status.Addresses { + if addr.Type == corev1.NodeInternalIP { + return "http://" + net.JoinHostPort(addr.Address, "30090"), nil + } + } + } + + return "", fmt.Errorf("no InternalIP address found on any workload cluster node") +} diff --git a/test/pullmode-sveltosapplier.yaml b/test/pullmode-sveltosapplier.yaml index 04458dca..03cc7ba4 100644 --- a/test/pullmode-sveltosapplier.yaml +++ b/test/pullmode-sveltosapplier.yaml @@ -99,7 +99,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - image: docker.io/projectsveltos/sveltos-applier@sha256:9e7170faec7d9bf58c857d193f9c682f286eef20c3875a9a05a71fb74cf203e3 + image: docker.io/projectsveltos/sveltos-applier@sha256:1d2e0f7921212f93fa3cd2607c57eefb305b3d06e1a71a27a5fd1919fd1b6566 livenessProbe: failureThreshold: 3 httpGet: