Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Python 3 #3028

Merged
merged 3 commits into from
Jan 26, 2019
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ jobs:
- stage: test
env: CHECK=kube_proxy PYTHON3=true
- stage: test
env: CHECK=kubelet
env: CHECK=kubelet PYTHON3=true
- stage: test
env: CHECK=kubernetes_state
- stage: test
Expand Down
9 changes: 4 additions & 5 deletions kubelet/datadog_checks/kubelet/cadvisor.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
# (C) Datadog, Inc. 2010-2018
# All rights reserved
# Licensed under Simplified BSD License (see LICENSE)
from __future__ import division

"""kubernetes check
Collects metrics from cAdvisor instance
"""
# stdlib
from fnmatch import fnmatch
import numbers
from urlparse import urlparse
from six import iteritems
from six.moves.urllib.parse import urlparse
import logging

# 3p
import requests

# check
from .common import tags_for_docker, tags_for_pod, is_static_pending_pod, get_pod_by_uid
from tagger import get_tags

Expand Down Expand Up @@ -138,7 +137,7 @@ def _publish_raw_metrics(self, metric, dat, tags, is_pod, depth=0):
self.gauge(metric, float(dat), tags)

elif isinstance(dat, dict):
for k, v in dat.iteritems():
for k, v in iteritems(dat):
self._publish_raw_metrics(metric + '.%s' % k.lower(), v, tags, is_pod, depth + 1)

elif isinstance(dat, list):
Expand Down
16 changes: 7 additions & 9 deletions kubelet/datadog_checks/kubelet/kubelet.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
# (C) Datadog, Inc. 2016-2017
# All rights reserved
# Licensed under Simplified BSD License (see LICENSE)
from __future__ import division

# stdlib
import logging
import re
from collections import defaultdict
from urlparse import urljoin
from copy import deepcopy

# 3p
import requests

# project
from datadog_checks.checks import AgentCheck
from datadog_checks.checks.openmetrics import OpenMetricsBaseCheck
from datadog_checks.errors import CheckException
from kubeutil import get_connection_info
from six import iteritems
from six.moves.urllib.parse import urljoin
from tagger import get_tags

# check
from .common import CADVISOR_DEFAULT_PORT, PodListUtils, KubeletCredentials
from .cadvisor import CadvisorScraper
from .prometheus import CadvisorPrometheusScraperMixin
Expand Down Expand Up @@ -307,9 +305,9 @@ def _report_pods_running(self, pods, instance_tags):
tags += instance_tags
hash_tags = tuple(sorted(tags))
containers_tag_counter[hash_tags] += 1
for tags, count in pods_tag_counter.iteritems():
for tags, count in iteritems(pods_tag_counter):
self.gauge(self.NAMESPACE + '.pods.running', count, list(tags))
for tags, count in containers_tag_counter.iteritems():
for tags, count in iteritems(containers_tag_counter):
self.gauge(self.NAMESPACE + '.containers.running', count, list(tags))

def _report_container_spec_metrics(self, pod_list, instance_tags):
Expand Down Expand Up @@ -341,14 +339,14 @@ def _report_container_spec_metrics(self, pod_list, instance_tags):
tags = get_tags('%s' % cid, True) + instance_tags

try:
for resource, value_str in ctr.get('resources', {}).get('requests', {}).iteritems():
for resource, value_str in iteritems(ctr.get('resources', {}).get('requests', {})):
value = self.parse_quantity(value_str)
self.gauge('{}.{}.requests'.format(self.NAMESPACE, resource), value, tags)
except (KeyError, AttributeError) as e:
self.log.debug("Unable to retrieve container requests for %s: %s", c_name, e)

try:
for resource, value_str in ctr.get('resources', {}).get('limits', {}).iteritems():
for resource, value_str in iteritems(ctr.get('resources', {}).get('limits', {})):
value = self.parse_quantity(value_str)
self.gauge('{}.{}.limits'.format(self.NAMESPACE, resource), value, tags)
except (KeyError, AttributeError) as e:
Expand Down
16 changes: 9 additions & 7 deletions kubelet/datadog_checks/kubelet/prometheus.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
# (C) Datadog, Inc. 2018
# All rights reserved
# Licensed under Simplified BSD License (see LICENSE)
from __future__ import division

# project
from copy import deepcopy

from six import iteritems

from datadog_checks.checks.openmetrics import OpenMetricsBaseCheck
from tagger import get_tags

# check
from .common import is_static_pending_pod, get_pod_by_uid

METRIC_TYPES = ['counter', 'gauge', 'summary']
Expand Down Expand Up @@ -266,7 +268,7 @@ def _process_container_metric(self, type, metric_name, metric, scraper_config):
return

samples = self._sum_values_by_context(metric, self._get_container_id_if_container_metric)
for c_id, sample in samples.iteritems():
for c_id, sample in iteritems(samples):
pod_uid = self._get_pod_uid(sample[self.SAMPLE_LABELS])
if self.pod_list_utils.is_excluded(c_id, pod_uid):
continue
Expand Down Expand Up @@ -299,7 +301,7 @@ def _process_pod_rate(self, metric_name, metric, scraper_config):
return

samples = self._sum_values_by_context(metric, self._get_pod_uid_if_pod_metric)
for pod_uid, sample in samples.iteritems():
for pod_uid, sample in iteritems(samples):
if '.network.' in metric_name and self._is_pod_host_networked(pod_uid):
continue
tags = get_tags('kubernetes_pod://%s' % pod_uid, True)
Expand All @@ -317,7 +319,7 @@ def _process_usage_metric(self, m_name, metric, cache, scraper_config):
seen_keys = {k: False for k in cache}

samples = self._sum_values_by_context(metric, self._get_container_id_if_container_metric)
for c_id, sample in samples.iteritems():
for c_id, sample in iteritems(samples):
c_name = self._get_container_label(sample[self.SAMPLE_LABELS], 'name')
if not c_name:
continue
Expand All @@ -342,7 +344,7 @@ def _process_usage_metric(self, m_name, metric, cache, scraper_config):
self.gauge(m_name, val, tags)

# purge the cache
for k, seen in seen_keys.iteritems():
for k, seen in iteritems(seen_keys):
if not seen:
del cache[k]

Expand All @@ -353,7 +355,7 @@ def _process_limit_metric(self, m_name, metric, cache, scraper_config, pct_m_nam
for each sample in the metric and reports the usage_pct
"""
samples = self._sum_values_by_context(metric, self._get_container_id_if_container_metric)
for c_id, sample in samples.iteritems():
for c_id, sample in iteritems(samples):
limit = sample[self.SAMPLE_VALUE]
pod_uid = self._get_pod_uid(sample[self.SAMPLE_LABELS])
if self.pod_list_utils.is_excluded(c_id, pod_uid):
Expand Down
19 changes: 8 additions & 11 deletions kubelet/tests/test_cadvisor.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,20 @@
]


@pytest.fixture
def aggregator():
from datadog_checks.stubs import aggregator
aggregator.reset()
return aggregator
@pytest.fixture()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did you change this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant to put this in the PR description, basically there is a bug in requests-mock where the decorator isn't registered as a fixture for pytest, and this only impacts PY3 - pytest-dev/pytest#2749

def mock_request():
with requests_mock.Mocker() as m:
yield m


@requests_mock.mock()
def test_detect_cadvisor_nominal(m):
m.head('http://kubelet:4192/api/v1.3/subcontainers/', text='{}')
def test_detect_cadvisor_nominal(mock_request):
mock_request.head('http://kubelet:4192/api/v1.3/subcontainers/', text='{}')
url = KubeletCheck.detect_cadvisor("http://kubelet:10250", 4192)
assert url == "http://kubelet:4192/api/v1.3/subcontainers/"


@requests_mock.mock()
def test_detect_cadvisor_404(m):
m.head('http://kubelet:4192/api/v1.3/subcontainers/', status_code=404)
def test_detect_cadvisor_404(mock_request):
mock_request.head('http://kubelet:4192/api/v1.3/subcontainers/', status_code=404)
with pytest.raises(HTTPError):
url = KubeletCheck.detect_cadvisor("http://kubelet:10250", 4192)
assert url == ""
Expand Down
3 changes: 2 additions & 1 deletion kubelet/tests/test_kubelet.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import mock
import pytest
from six import iteritems
from datadog_checks.kubelet import KubeletCheck, KubeletCredentials

# Skip the whole tests module on Windows
Expand Down Expand Up @@ -141,7 +142,7 @@ def test_bad_config():


def test_parse_quantity():
for raw, res in QUANTITIES.iteritems():
for raw, res in iteritems(QUANTITIES):
assert KubeletCheck.parse_quantity(raw) == res


Expand Down
4 changes: 1 addition & 3 deletions kubelet/tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
minversion = 2.0
basepython = py27
envlist =
kubelet
{py27,py36}-kubelet
flake8

[testenv]
usedevelop = true
platform = linux2|darwin

[testenv:kubelet]
deps =
-e../datadog_checks_base[deps]
-rrequirements-dev.txt
Expand Down