Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions kube_scheduler/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<!-- towncrier release notes start -->


## 7.0.1 / 2025-08-07

***Fixed***:
Expand Down
15 changes: 14 additions & 1 deletion kube_scheduler/assets/configuration/spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,23 @@ files:
value:
type: string
example: http://localhost:10251/healthz
- name: openmetrics_endpoint
description: |
The URL exposing metrics in the OpenMetrics format.
One of openmetrics_endpoint or prometheus_url parameter is required.
required: false
value:
type: string
example: http://localhost:10251/metrics
display_priority: 1
- template: instances/openmetrics_legacy
overrides:
prometheus_url.value.example: http://localhost:10251/metrics
prometheus_url.display_priority: 1
prometheus_url.display_priority: 2
prometheus_url.required: false
prometheus_url.description: |
The URL where your application metrics are exposed by Prometheus.
One of openmetrics_endpoint or prometheus_url parameter is required.

- name: auto_conf.yaml
options:
Expand Down
1 change: 1 addition & 0 deletions kube_scheduler/changelog.d/21178.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for openmetrics_endpoint configuration parameter as an alternative to prometheus_url
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,18 @@ def instance_namespace():
return 'service'


def instance_openmetrics_endpoint():
return 'http://localhost:10251/metrics'


def instance_persist_connections():
return False


def instance_prometheus_url():
return 'http://localhost:10251/metrics'


def instance_request_size():
return 10

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,11 @@ class InstanceConfig(BaseModel):
min_collection_interval: Optional[float] = None
namespace: Optional[str] = None
ntlm_domain: Optional[str] = None
openmetrics_endpoint: Optional[str] = None
password: Optional[str] = None
persist_connections: Optional[bool] = None
prometheus_metrics_prefix: Optional[str] = None
prometheus_url: str
prometheus_url: Optional[str] = None
proxy: Optional[Proxy] = None
read_timeout: Optional[float] = None
request_size: Optional[float] = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,19 @@
# Licensed under a 3-clause BSD style license (see LICENSE)

# Here you can include additional config validators or transformers
#
# def initialize_instance(values, **kwargs):
# if 'my_option' not in values and 'my_legacy_option' in values:
# values['my_option'] = values['my_legacy_option']
# if values.get('my_number') > 10:
# raise ValueError('my_number max value is 10, got %s' % str(values.get('my_number')))
#
# return values


def initialize_instance(values, **kwargs):
"""
Normalize instances to support both field names.
Parse prometheus_url first, if not available, fall back to openmetrics_endpoint.
"""
# Map openmetrics_endpoint to prometheus_url if prometheus_url is not present
if 'openmetrics_endpoint' in values and 'prometheus_url' not in values:
values['prometheus_url'] = values['openmetrics_endpoint']

# Ensure at least one endpoint is provided
if not values.get('prometheus_url') and not values.get('openmetrics_endpoint'):
raise ValueError('Field `openmetrics_endpoint` or `prometheus_url` must be set')

return values
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ init_config:
#
instances:

## @param prometheus_url - string - required
-
## @param prometheus_url - string - optional - default: http://localhost:10251/metrics
## The URL where your application metrics are exposed by Prometheus.
## One of openmetrics_endpoint or prometheus_url parameter is required.
#
- prometheus_url: http://localhost:10251/metrics
# prometheus_url: http://localhost:10251/metrics

## @param leader_election - boolean - optional - default: true
## Monitor the leader-election process on the kube-system:kube-scheduler.
Expand All @@ -71,6 +73,12 @@ instances:
#
# health_url: http://localhost:10251/healthz

## @param openmetrics_endpoint - string - optional - default: http://localhost:10251/metrics
## The URL exposing metrics in the OpenMetrics format.
## One of openmetrics_endpoint or prometheus_url parameter is required.
#
# openmetrics_endpoint: http://localhost:10251/metrics

## @param prometheus_metrics_prefix - string - optional
## Removes a given <PREFIX> from exposed Prometheus metrics.
#
Expand Down
48 changes: 48 additions & 0 deletions kube_scheduler/tests/test_validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# (C) Datadog, Inc. 2025-present
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)

import pytest

from datadog_checks.kube_scheduler.config_models.validators import initialize_instance


class TestValidators:
def test_openmetrics_endpoint_only(self):
"""Test that openmetrics_endpoint gets mapped to prometheus_url when prometheus_url is not present"""
config = {"openmetrics_endpoint": "http://localhost:10251/metrics"}

# This should not raise an exception and should map openmetrics_endpoint to prometheus_url
result = initialize_instance(config)
assert result["openmetrics_endpoint"] == "http://localhost:10251/metrics"
assert result["prometheus_url"] == "http://localhost:10251/metrics" # Should be mapped

def test_prometheus_url_only(self):
"""Test that prometheus_url works without openmetrics_endpoint"""
config = {"prometheus_url": "http://localhost:10251/metrics"}

# This should not raise an exception
result = initialize_instance(config)
assert result["prometheus_url"] == "http://localhost:10251/metrics"
assert result.get("openmetrics_endpoint") is None

def test_both_endpoints(self):
"""Test that both endpoints can be provided and prometheus_url takes precedence (no mapping occurs)"""
config = {
"openmetrics_endpoint": "http://openmetrics.example.com:8080/metrics",
"prometheus_url": "http://prometheus.example.com:9090/metrics",
}

# This should not raise an exception and prometheus_url should not be overwritten
# The mapping should NOT occur when both are present
result = initialize_instance(config)
assert result["openmetrics_endpoint"] == "http://openmetrics.example.com:8080/metrics"
assert result["prometheus_url"] == "http://prometheus.example.com:9090/metrics" # Should remain unchanged

def test_no_endpoints(self):
"""Test that validation fails when neither endpoint is provided"""
config = {}

# This should raise a ValueError
with pytest.raises(ValueError, match="Field `openmetrics_endpoint` or `prometheus_url` must be set"):
initialize_instance(config)
Loading