Skip to content

Commit

Permalink
[Feature] Istio Mixer and Mesh endpoints are optional (#3875)
Browse files Browse the repository at this point in the history
* Make Mesh and Mixer config Optional
  • Loading branch information
mikekatica authored and therve committed Jun 18, 2019
1 parent 79c0b64 commit 8f6246e
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 14 deletions.
2 changes: 1 addition & 1 deletion istio/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ instances:
send_histograms_buckets: true
```

The first two endpoints are required for the check to work. See the [istio documentation][4] to learn more about the prometheus adapter.
Each of the endpoints are optional, but at least one must be configured. See the [istio documentation][4] to learn more about the prometheus adapter.

### Validation

Expand Down
4 changes: 2 additions & 2 deletions istio/datadog_checks/istio/data/conf.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ init_config:

instances:

## @param istio_mesh_endpoint - string - required
## @param istio_mesh_endpoint - string - optional
## To enable Istio metrics you must specify the url exposing the API
##
## Note for RHEL and SUSE users: due to compatibility issues, the check does not make use of
Expand All @@ -11,7 +11,7 @@ instances:
#
- istio_mesh_endpoint: http://istio-telemetry.istio-system:42422/metrics

## @param mixer_endpoint - string - required
## @param mixer_endpoint - string - optional
## Define the mixer endpoint in order to collect all Prometheus metrics on the Mixer process as well
## as gRPC metrics related to API calls and metrics on adapter dispatch.
## If using Istio < v1.1, replace port 15014 with port 9093. See the changes here:
Expand Down
31 changes: 20 additions & 11 deletions istio/datadog_checks/istio/istio.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,26 @@ def __init__(self, name, init_config, agentConfig, instances=None):

def check(self, instance):
"""
Process the istio_mesh endpoint, the process_mixer endpoint and optionally the pilot and galley endpoints
Process the istio_mesh, process_mixer, pilot, and galley endpoints
associated with this instance.
All the endpoints themselves are optional, but at least one must be passed.
"""

# Get the config for the istio_mesh instance
istio_mesh_endpoint = instance.get('istio_mesh_endpoint')
istio_mesh_config = self.config_map[istio_mesh_endpoint]
if istio_mesh_endpoint:
istio_mesh_config = self.config_map[istio_mesh_endpoint]

# Process istio_mesh
self.process(istio_mesh_config)
# Process istio_mesh
self.process(istio_mesh_config)

# Get the config for the process_mixer instance
process_mixer_endpoint = instance.get('mixer_endpoint')
process_mixer_config = self.config_map[process_mixer_endpoint]
if process_mixer_endpoint:
process_mixer_config = self.config_map[process_mixer_endpoint]

# Process process_mixer
self.process(process_mixer_config)
# Process process_mixer
self.process(process_mixer_config)

# Get the config for the process_pilot instance
process_pilot_endpoint = instance.get('pilot_endpoint')
Expand All @@ -61,15 +64,21 @@ def check(self, instance):
# Process process_galley
self.process(process_galley_config)

# Check that at least 1 endpoint is configured
if not (process_galley_endpoint or process_pilot_endpoint or process_mixer_endpoint or istio_mesh_endpoint):
raise CheckException("At least one of Mixer, Mesh, Pilot, or Galley endpoints must be configured")

def create_generic_instances(self, instances):
"""
Generalize each (single) Istio instance into two OpenMetricsBaseCheck instances
"""
for instance in instances:
istio_mesh_instance = self._create_istio_mesh_instance(instance)
yield istio_mesh_instance
process_mixer_instance = self._create_process_mixer_instance(instance)
yield process_mixer_instance
if 'istio_mesh_endpoint' in instance:
istio_mesh_instance = self._create_istio_mesh_instance(instance)
yield istio_mesh_instance
if 'mixer_endpoint' in instance:
process_mixer_instance = self._create_process_mixer_instance(instance)
yield process_mixer_instance
if 'pilot_endpoint' in instance:
process_pilot_instance = self._create_process_pilot_instance(instance)
yield process_pilot_instance
Expand Down
50 changes: 50 additions & 0 deletions istio/tests/test_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,10 @@
'galley_endpoint': 'http://istio-galley:15014/metrics',
}

NEW_MOCK_PILOT_ONLY_INSTANCE = {'pilot_endpoint': 'http://istio-pilot:15014/metrics'}

NEW_MOCK_GALLEY_ONLY_INSTANCE = {'galley_endpoint': 'http://istio-galley:15014/metrics'}


class MockResponse:
"""
Expand Down Expand Up @@ -419,6 +423,32 @@ def new_mesh_mixture_fixture():
yield


@pytest.fixture
def new_pilot_fixture():
files = ['pilot.txt']
responses = []
for filename in files:
file_path = os.path.join(os.path.dirname(__file__), 'fixtures', '1.1', filename)
with open(file_path, 'r') as f:
responses.append(f.read())

with mock.patch('requests.get', return_value=MockResponse(responses, 'text/plain'), __name__="get"):
yield


@pytest.fixture
def new_galley_fixture():
files = ['galley.txt']
responses = []
for filename in files:
file_path = os.path.join(os.path.dirname(__file__), 'fixtures', '1.1', filename)
with open(file_path, 'r') as f:
responses.append(f.read())

with mock.patch('requests.get', return_value=MockResponse(responses, 'text/plain'), __name__="get"):
yield


def test_istio(aggregator, mesh_mixture_fixture):
"""
Test the full check
Expand All @@ -442,6 +472,26 @@ def test_new_istio(aggregator, new_mesh_mixture_fixture):
aggregator.assert_all_metrics_covered()


def test_pilot_only_istio(aggregator, new_pilot_fixture):
check = Istio('istio', {}, {}, [NEW_MOCK_PILOT_ONLY_INSTANCE])
check.check(NEW_MOCK_PILOT_ONLY_INSTANCE)

for metric in PILOT_METRICS:
aggregator.assert_metric(metric)

aggregator.assert_all_metrics_covered()


def test_galley_only_istio(aggregator, new_galley_fixture):
check = Istio('istio', {}, {}, [NEW_MOCK_GALLEY_ONLY_INSTANCE])
check.check(NEW_MOCK_GALLEY_ONLY_INSTANCE)

for metric in GALLEY_METRICS:
aggregator.assert_metric(metric)

aggregator.assert_all_metrics_covered()


def test_scraper_creator():
check = Istio('istio', {}, {}, [MOCK_INSTANCE])
istio_mesh_config = check.config_map.get(MOCK_INSTANCE['istio_mesh_endpoint'])
Expand Down

0 comments on commit 8f6246e

Please sign in to comment.