Skip to content
This repository has been archived by the owner on Oct 3, 2020. It is now read-only.

Handle relative paths in kubeconfig #55

Merged
merged 2 commits into from
Mar 29, 2020
Merged
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
40 changes: 31 additions & 9 deletions pykube/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,15 @@ def set_current_context(self, value):
"""
self._current_context = value

@property
def kubeconfig_file(self):
"""
Returns the path to kubeconfig file, if it exists
"""
if not hasattr(self, "filename"):
return None
return self.filename

@property
def current_context(self):
if self._current_context is None:
Expand All @@ -148,7 +157,7 @@ def clusters(self):
cs[cr["name"]] = c = copy.deepcopy(cr["cluster"])
if "server" not in c:
c["server"] = "http://localhost"
BytesOrFile.maybe_set(c, "certificate-authority")
BytesOrFile.maybe_set(c, "certificate-authority", self.kubeconfig_file)
self._clusters = cs
return self._clusters

Expand All @@ -162,8 +171,8 @@ def users(self):
if "users" in self.doc:
for ur in self.doc["users"]:
us[ur["name"]] = u = copy.deepcopy(ur["user"])
BytesOrFile.maybe_set(u, "client-certificate")
BytesOrFile.maybe_set(u, "client-key")
BytesOrFile.maybe_set(u, "client-certificate", self.kubeconfig_file)
BytesOrFile.maybe_set(u, "client-key", self.kubeconfig_file)
self._users = us
return self._users

Expand Down Expand Up @@ -202,10 +211,10 @@ def namespace(self) -> str:
return self.contexts[self.current_context].get("namespace", "default")

def persist_doc(self):
if not hasattr(self, "filename") or not self.filename:
if not self.kubeconfig_file:
# Config was provided as string, not way to persit it
return
with open(self.filename, "w") as f:
with open(self.kubeconfig_file, "w") as f:
yaml.safe_dump(
self.doc,
f,
Expand All @@ -229,16 +238,16 @@ class BytesOrFile:
"""

@classmethod
def maybe_set(cls, d, key):
def maybe_set(cls, d, key, kubeconfig_file):
file_key = key
data_key = "{}-data".format(key)
if data_key in d:
d[file_key] = cls(data=d[data_key])
d[file_key] = cls(data=d[data_key], kubeconfig_file=kubeconfig_file)
del d[data_key]
elif file_key in d:
d[file_key] = cls(filename=d[file_key])
d[file_key] = cls(filename=d[file_key], kubeconfig_file=kubeconfig_file)

def __init__(self, filename=None, data=None):
def __init__(self, filename=None, data=None, kubeconfig_file=None):
"""
Creates a new instance of BytesOrFile.

Expand All @@ -251,6 +260,19 @@ def __init__(self, filename=None, data=None):
if filename is not None and data is not None:
raise TypeError("filename or data kwarg must be specified, not both")
elif filename is not None:

# If relative path is given, should be made absolute with respect to the directory of the kube config
# https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#file-references
if not os.path.isabs(filename):
if kubeconfig_file:
filename = os.path.join(os.path.dirname(kubeconfig_file), filename)
else:
raise exceptions.PyKubeError(
"{} passed as relative path, but cannot determine location of kube config".format(
filename
)
)

if not os.path.isfile(filename):
raise exceptions.PyKubeError(
"'{}' file does not exist".format(filename)
Expand Down