Skip to content
Open
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: 0 additions & 1 deletion examples/cronjob_crud.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/python3
# -*- coding:utf-8 -*-

import json
import time
Expand Down
1 change: 0 additions & 1 deletion examples/duration-gep2257.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/python3
# -*- coding:utf-8 -*-

"""
This example uses kubernetes.utils.duration to parse and display
Expand Down
3 changes: 1 addition & 2 deletions examples/pod_portforward.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
import select
import socket
import time

import six.moves.urllib.request as urllib_request
from urllib import request as urllib_request

from kubernetes import config
from kubernetes.client import Configuration
Expand Down
10 changes: 7 additions & 3 deletions kubernetes/base/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@

from .config_exception import ConfigException
from .incluster_config import load_incluster_config
from .kube_config import (KUBE_CONFIG_DEFAULT_LOCATION,
list_kube_config_contexts, load_kube_config,
load_kube_config_from_dict, new_client_from_config, new_client_from_config_dict)
from .kube_config import (
KUBE_CONFIG_DEFAULT_LOCATION,
list_kube_config_contexts,
load_kube_config,
load_kube_config_from_dict,
new_client_from_config,
new_client_from_config_dict)


def load_config(**kwargs):
Expand Down
11 changes: 5 additions & 6 deletions kubernetes/base/config/dateutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,24 @@ def parse_rfc3339(s):
if not s.tzinfo:
return s.replace(tzinfo=UTC)
return s

m = _re_rfc3339.fullmatch(s.strip())
if m is None:
raise ValueError(
f"Invalid RFC3339 datetime: {s!r} "
"(expected YYYY-MM-DDTHH:MM:SS[.frac][Z|±HH:MM])"
)

groups = m.groups()
dt = [0] * 7
for x in range(6):
dt[x] = int(groups[x])

us = 0
if groups[6] is not None:
partial_sec = float(groups[6].replace(",", "."))
us = int(MICROSEC_PER_SEC * partial_sec)

tz = UTC
if groups[7] is not None and groups[7] not in ('Z', 'z', ' '):
tz_match = _re_timezone.search(groups[7])
Expand All @@ -87,7 +87,7 @@ def parse_rfc3339(s):
if tz_groups[2]:
minute = int(tz_groups[2])
tz = TimezoneInfo(hour, minute)

try:
return datetime.datetime(
year=dt[0], month=dt[1], day=dt[2],
Expand All @@ -99,7 +99,6 @@ def parse_rfc3339(s):
) from e



def format_rfc3339(date_time):
if date_time.tzinfo is None:
date_time = date_time.replace(tzinfo=UTC)
Expand Down
2 changes: 0 additions & 2 deletions kubernetes/base/config/dateutil_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@ def test_parse_rfc3339_invalid_formats(self):
with self.assertRaises(ValueError):
parse_rfc3339(invalid_input)



def test_parse_rfc3339_with_whitespace(self):
"""Test that leading/trailing whitespace is handled"""
actual = parse_rfc3339(" 2017-07-25T04:44:21Z ")
Expand Down
4 changes: 2 additions & 2 deletions kubernetes/base/config/exec_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from .config_exception import ConfigException


class ExecProvider(object):
class ExecProvider:
"""
Implementation of the proposal for out-of-tree client
authentication providers as described here --
Expand Down Expand Up @@ -58,7 +58,7 @@ def __init__(self, exec_config, cwd, cluster=None):
else:
self.cluster = None
self.cwd = cwd or None

@property
def shell(self):
# for windows systems `shell` should be `True`
Expand Down
9 changes: 7 additions & 2 deletions kubernetes/base/config/exec_provider_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,10 @@ def test_with_cluster_info(self, mock):
instance = mock.return_value
instance.wait.return_value = 0
instance.communicate.return_value = (self.output_ok, '')
ep = ExecProvider(self.input_with_cluster, None, ConfigNode("cluster", {'server': 'name.company.com'}))
ep = ExecProvider(
self.input_with_cluster, None, ConfigNode(
"cluster", {
'server': 'name.company.com'}))
result = ep.run()
self.assertTrue(isinstance(result, dict))
self.assertTrue('token' in result)
Expand Down Expand Up @@ -213,8 +216,10 @@ def test_with_cluster_info_from_exec_extension(self, mock):

obj = json.loads(mock.call_args.kwargs["env"]["KUBERNETES_EXEC_INFO"])
self.assertEqual(obj["spec"]["cluster"]["server"], "name.company.com")
self.assertEqual(obj["spec"]["cluster"]["config"]["namespace"], "myproject")
self.assertEqual(obj["spec"]["cluster"]["config"]
["namespace"], "myproject")
self.assertEqual(obj["spec"]["cluster"]["config"]["name"], "mycluster")


if __name__ == '__main__':
unittest.main()
2 changes: 1 addition & 1 deletion kubernetes/base/config/incluster_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def _join_host_port(host, port):
return template % (host, port)


class InClusterConfigLoader(object):
class InClusterConfigLoader:
def __init__(self,
token_filename,
cert_filename,
Expand Down
61 changes: 30 additions & 31 deletions kubernetes/base/config/kube_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@
import platform
import subprocess
import tempfile
import time
from collections import namedtuple

import oauthlib.oauth2
import urllib3
import yaml
from requests_oauthlib import OAuth2Session
from six import PY3

from kubernetes.client import ApiClient, Configuration
from kubernetes.config.exec_provider import ExecProvider
Expand All @@ -45,7 +43,6 @@
google_auth_available = False



EXPIRY_SKEW_PREVENTION_DELAY = datetime.timedelta(minutes=5)
KUBE_CONFIG_DEFAULT_LOCATION = os.environ.get('KUBECONFIG', '~/.kube/config')
ENV_KUBECONFIG_PATH_SEPARATOR = ';' if platform.system() == 'Windows' else ':'
Expand All @@ -62,7 +59,10 @@ def _cleanup_temp_files():
_temp_files = {}


def _create_temp_file_with_content(content, temp_file_path=None, force_recreate=False):
def _create_temp_file_with_content(
content,
temp_file_path=None,
force_recreate=False):
if len(_temp_files) == 0:
atexit.register(_cleanup_temp_files)
# Because we may change context several times, try to remember files we
Expand All @@ -85,7 +85,7 @@ def _is_expired(expiry):
datetime.datetime.now(tz=UTC))


class FileOrData(object):
class FileOrData:
"""Utility class to read content of obj[%data_key_name] or file's
content of obj[%file_key_name] and represent it as file or data.
Note that the data is preferred. The obj[%file_key_name] will be used iff
Expand Down Expand Up @@ -145,13 +145,15 @@ def _write_file(self, force_rewrite=False):
else:
content = self._data
self._file = _create_temp_file_with_content(
base64.standard_b64decode(content), self._temp_file_path, force_recreate=force_rewrite)
base64.standard_b64decode(content),
self._temp_file_path,
force_recreate=force_rewrite)
else:
self._file = _create_temp_file_with_content(
self._data, self._temp_file_path, force_recreate=force_rewrite)


class CommandTokenSource(object):
class CommandTokenSource:
def __init__(self, cmd, args, tokenKey, expiryKey):
self._cmd = cmd
self._args = args
Expand Down Expand Up @@ -191,7 +193,7 @@ def token(self):
expiry=parse_rfc3339(data['credential']['token_expiry']))


class KubeConfigLoader(object):
class KubeConfigLoader:

def __init__(self, config_dict, active_context=None,
get_google_credentials=None,
Expand Down Expand Up @@ -247,7 +249,7 @@ def _refresh_credentials():
'config' in self._user['auth-provider'] and
'cmd-path' in self._user['auth-provider']['config']):
return _refresh_credentials_with_cmd_path()

# Make the Google auth block optional.
if google_auth_available:
credentials, project_id = google.auth.default(scopes=[
Expand All @@ -259,7 +261,7 @@ def _refresh_credentials():
return credentials
else:
return None

if get_google_credentials:
self._get_google_credentials = get_google_credentials
else:
Expand Down Expand Up @@ -316,8 +318,6 @@ def _load_auth_provider_token(self):
if provider['name'] == 'oidc':
return self._load_oid_token(provider)



def _load_gcp_token(self, provider):
if (('config' not in provider) or
('access-token' not in provider['config']) or
Expand Down Expand Up @@ -363,14 +363,9 @@ def _load_oid_token(self, provider):
# https://tools.ietf.org/html/rfc7515#appendix-C
return

if PY3:
jwt_attributes = json.loads(
base64.urlsafe_b64decode(parts[1] + padding).decode('utf-8')
)
else:
jwt_attributes = json.loads(
base64.b64decode(parts[1] + padding)
)
jwt_attributes = json.loads(
base64.urlsafe_b64decode(parts[1] + padding).decode('utf-8')
)

expire = jwt_attributes.get('exp')

Expand All @@ -392,14 +387,9 @@ def _refresh_oidc(self, provider):
if 'idp-certificate-authority-data' in provider['config']:
ca_cert = tempfile.NamedTemporaryFile(delete=True)

if PY3:
cert = base64.b64decode(
provider['config']['idp-certificate-authority-data']
).decode('utf-8')
else:
cert = base64.b64decode(
provider['config']['idp-certificate-authority-data'] + "=="
)
cert = base64.b64decode(
provider['config']['idp-certificate-authority-data']
).decode('utf-8')

with open(ca_cert.name, 'w') as fh:
fh.write(cert)
Expand Down Expand Up @@ -454,7 +444,10 @@ def _load_from_exec_plugin(self):
return
try:
base_path = self._get_base_path(self._cluster.path)
status = ExecProvider(self._user['exec'], base_path, self._cluster).run()
status = ExecProvider(
self._user['exec'],
base_path,
self._cluster).run()
if 'token' in status:
self.token = "Bearer %s" % status['token']
elif 'clientCertificateData' in status:
Expand Down Expand Up @@ -547,7 +540,13 @@ def _refresh_api_key(client_configuration):
self._set_config(client_configuration)
client_configuration.refresh_api_key_hook = _refresh_api_key
# copy these keys directly from self to configuration object
keys = ['host', 'ssl_ca_cert', 'cert_file', 'key_file', 'verify_ssl','tls_server_name']
keys = [
'host',
'ssl_ca_cert',
'cert_file',
'key_file',
'verify_ssl',
'tls_server_name']
for key in keys:
if key in self.__dict__:
setattr(client_configuration, key, getattr(self, key))
Expand All @@ -565,7 +564,7 @@ def current_context(self):
return self._current_context.value


class ConfigNode(object):
class ConfigNode:
"""Remembers each config key's path and construct a relevant exception
message in case of missing keys. The assumption is all access keys are
present in a well-formed kube-config."""
Expand Down
Loading