Skip to content

Commit 7ccb072

Browse files
committed
auth: revamp to not use kubectl
Also, provide some logic around overwriting existing entries and also provide a warning when the namepsace is not set.
1 parent cac0e68 commit 7ccb072

File tree

1 file changed

+68
-53
lines changed

1 file changed

+68
-53
lines changed

src/warnet/users.py

Lines changed: 68 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,85 @@
1-
import os
2-
import subprocess
31
import sys
42

53
import click
64
import yaml
75

6+
from warnet.constants import KUBECONFIG
7+
88

99
@click.command()
10-
@click.argument("kube_config", type=str)
11-
def auth(kube_config: str) -> None:
12-
"""
13-
Authenticate with a warnet cluster using a kube config file
14-
"""
15-
try:
16-
current_kubeconfig = os.environ.get("KUBECONFIG", os.path.expanduser("~/.kube/config"))
17-
combined_kubeconfig = (
18-
f"{current_kubeconfig}:{kube_config}" if current_kubeconfig else kube_config
19-
)
20-
os.environ["KUBECONFIG"] = combined_kubeconfig
21-
with open(kube_config) as file:
22-
content = yaml.safe_load(file)
23-
user = content["users"][0]
24-
user_name = user["name"]
25-
user_token = user["user"]["token"]
26-
current_context = content["current-context"]
27-
flatten_cmd = "kubectl config view --flatten"
28-
result_flatten = subprocess.run(
29-
flatten_cmd, shell=True, check=True, capture_output=True, text=True
10+
@click.argument("auth_config", type=str)
11+
def auth(auth_config):
12+
"""Authenticate with a Warnet cluster using a kubernetes config file"""
13+
base_config = yaml_try_with_open(KUBECONFIG)
14+
auth_config = yaml_try_with_open(auth_config)
15+
16+
clusters = "clusters"
17+
if clusters in auth_config:
18+
merge_entries(
19+
base_config.setdefault(clusters, []), auth_config[clusters], "name", "cluster"
3020
)
31-
except subprocess.CalledProcessError as e:
32-
click.secho("Error occurred while executing kubectl config view --flatten:", fg="red")
33-
click.secho(e.stderr, fg="red")
34-
sys.exit(1)
3521

36-
if result_flatten.returncode == 0:
37-
with open(current_kubeconfig, "w") as file:
38-
file.write(result_flatten.stdout)
39-
click.secho(f"Authorization file written to: {current_kubeconfig}", fg="green")
40-
else:
41-
click.secho("Could not create authorization file", fg="red")
42-
click.secho(result_flatten.stderr, fg="red")
43-
sys.exit(result_flatten.returncode)
22+
users = "users"
23+
if users in auth_config:
24+
merge_entries(base_config.setdefault(users, []), auth_config[users], "name", "user")
4425

45-
try:
46-
update_cmd = f"kubectl config set-credentials {user_name} --token {user_token}"
47-
result_update = subprocess.run(
48-
update_cmd, shell=True, check=True, capture_output=True, text=True
26+
contexts = "contexts"
27+
if contexts in auth_config:
28+
merge_entries(
29+
base_config.setdefault(contexts, []), auth_config[contexts], "name", "context"
4930
)
50-
if result_update.returncode != 0:
51-
click.secho("Could not update authorization file", fg="red")
52-
click.secho(result_flatten.stderr, fg="red")
53-
sys.exit(result_flatten.returncode)
54-
except subprocess.CalledProcessError as e:
55-
click.secho("Error occurred while executing kubectl config view --flatten:", fg="red")
56-
click.secho(e.stderr, fg="red")
57-
sys.exit(1)
5831

59-
with open(current_kubeconfig) as file:
60-
contents = yaml.safe_load(file)
32+
new_current_context = auth_config.get("current-context")
33+
base_config["current-context"] = new_current_context
6134

62-
with open(current_kubeconfig, "w") as file:
63-
contents["current-context"] = current_context
64-
yaml.safe_dump(contents, file)
35+
# Check if the new current context has an explicit namespace
36+
context_entry = next(
37+
(ctx for ctx in base_config["contexts"] if ctx["name"] == new_current_context), None
38+
)
39+
if context_entry and "namespace" not in context_entry["context"]:
40+
click.secho(
41+
f"Warning: The context '{new_current_context}' does not have an explicit namespace.",
42+
fg="yellow",
43+
)
6544

66-
with open(current_kubeconfig) as file:
45+
with open(KUBECONFIG, "w") as file:
46+
yaml.safe_dump(base_config, file)
47+
click.secho(f"Updated kubeconfig with authorization data: {KUBECONFIG}", fg="green")
48+
49+
with open(KUBECONFIG) as file:
6750
contents = yaml.safe_load(file)
6851
click.secho(
69-
f"\nwarnet's current context is now set to: {contents['current-context']}", fg="green"
52+
f"Warnet's current context is now set to: {contents['current-context']}", fg="green"
7053
)
54+
55+
56+
def merge_entries(base_list, auth_list, key, entry_type):
57+
base_entry_names = {entry[key] for entry in base_list} # Extract existing names
58+
for entry in auth_list:
59+
if entry[key] in base_entry_names:
60+
if click.confirm(
61+
f"The {entry_type} '{entry[key]}' already exists. Overwrite?", default=False
62+
):
63+
# Find and replace the existing entry
64+
base_list[:] = [e if e[key] != entry[key] else entry for e in base_list]
65+
click.secho(f"Overwrote {entry_type} '{entry[key]}'", fg="yellow")
66+
else:
67+
click.secho(f"Skipped {entry_type} '{entry[key]}'", fg="yellow")
68+
else:
69+
base_list.append(entry)
70+
click.secho(f"Added new {entry_type} '{entry[key]}'", fg="green")
71+
72+
73+
def yaml_try_with_open(filename: str):
74+
try:
75+
with open(filename) as f:
76+
return yaml.safe_load(f)
77+
except FileNotFoundError:
78+
click.secho(f"Could not find: {KUBECONFIG}", fg="red")
79+
sys.exit(1)
80+
except OSError as e:
81+
click.secho(f"An I/O error occurred: {e}", fg="red")
82+
sys.exit(1)
83+
except Exception as e:
84+
click.secho(f"An unexpected error occurred: {e}", fg="red")
85+
sys.exit(1)

0 commit comments

Comments
 (0)