-
Notifications
You must be signed in to change notification settings - Fork 38
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
Add cmd for creating user kubeconfigs (cont. from #545) #598
Changes from all commits
fa75fb5
48629bf
acc63ed
e3f517e
f84777a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,8 +5,10 @@ | |
from rich import print as richprint | ||
|
||
from .constants import NETWORK_DIR | ||
from .k8s import get_kubeconfig_value, get_namespaces_by_prefix, get_service_accounts_in_namespace | ||
from .namespaces import copy_namespaces_defaults, namespaces | ||
from .network import copy_network_defaults | ||
from .process import run_command | ||
|
||
|
||
@click.group(name="admin", hidden=True) | ||
|
@@ -33,3 +35,93 @@ def init(): | |
f"[green]Copied network and namespace example files to {Path(current_dir) / NETWORK_DIR.name}[/green]" | ||
) | ||
richprint(f"[green]Created warnet project structure in {current_dir}[/green]") | ||
|
||
|
||
@admin.command() | ||
@click.argument("prefix", type=str, required=True) | ||
@click.option( | ||
"--kubeconfig-dir", | ||
default="kubeconfigs", | ||
help="Directory to store kubeconfig files (default: kubeconfigs)", | ||
) | ||
@click.option( | ||
"--token-duration", | ||
default=172800, | ||
type=int, | ||
help="Duration of the token in seconds (default: 48 hours)", | ||
) | ||
def create_kubeconfigs(prefix: str, kubeconfig_dir, token_duration): | ||
"""Create kubeconfig files for all ServiceAccounts in warnet team namespaces starting with <prefix>.""" | ||
kubeconfig_dir = os.path.expanduser(kubeconfig_dir) | ||
|
||
cluster_name = get_kubeconfig_value("{.clusters[0].name}") | ||
cluster_server = get_kubeconfig_value("{.clusters[0].cluster.server}") | ||
cluster_ca = get_kubeconfig_value("{.clusters[0].cluster.certificate-authority-data}") | ||
|
||
os.makedirs(kubeconfig_dir, exist_ok=True) | ||
|
||
# Get all namespaces that start with prefix | ||
# This assumes when deploying multiple namespacs for the purpose of team games, all namespaces start with a prefix, | ||
# e.g., tabconf-wargames-*. Currently, this is a bit brittle, but we can improve on this in the future | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah it feel like instead of using naming conventions k8s probably wants us to use metadata labels or something. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, it would be great to have a "cluster level" configmap. We could have a |
||
# by automatically applying a TEAM_PREFIX when creating the get_warnet_namespaces | ||
# TODO: choose a prefix convention and have it managed by the helm charts instead of requiring the | ||
# admin user to pipe through the correct string in multiple places. Another would be to use | ||
# labels instead of namespace naming conventions | ||
warnet_namespaces = get_namespaces_by_prefix(prefix) | ||
|
||
for namespace in warnet_namespaces: | ||
click.echo(f"Processing namespace: {namespace}") | ||
service_accounts = get_service_accounts_in_namespace(namespace) | ||
|
||
for sa in service_accounts: | ||
# Create a token for the ServiceAccount with specified duration | ||
command = f"kubectl create token {sa} -n {namespace} --duration={token_duration}s" | ||
try: | ||
token = run_command(command) | ||
except Exception as e: | ||
click.echo( | ||
f"Failed to create token for ServiceAccount {sa} in namespace {namespace}. Error: {str(e)}. Skipping..." | ||
) | ||
continue | ||
|
||
# Create a kubeconfig file for the user | ||
kubeconfig_file = os.path.join(kubeconfig_dir, f"{sa}-{namespace}-kubeconfig") | ||
|
||
# TODO: move yaml out of python code to resources/manifests/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you could use |
||
# | ||
# might not be worth it since we are just reading the yaml to then create a bunch of values and its not | ||
# actually used to deploy anything into the cluster | ||
# Then benefit would be making this code a bit cleaner and easy to follow, fwiw | ||
kubeconfig_content = f"""apiVersion: v1 | ||
kind: Config | ||
clusters: | ||
- name: {cluster_name} | ||
cluster: | ||
server: {cluster_server} | ||
certificate-authority-data: {cluster_ca} | ||
users: | ||
- name: {sa} | ||
user: | ||
token: {token} | ||
contexts: | ||
- name: {sa}-{namespace} | ||
context: | ||
cluster: {cluster_name} | ||
namespace: {namespace} | ||
user: {sa} | ||
current-context: {sa}-{namespace} | ||
""" | ||
with open(kubeconfig_file, "w") as f: | ||
f.write(kubeconfig_content) | ||
|
||
click.echo(f" Created kubeconfig file for {sa}: {kubeconfig_file}") | ||
|
||
click.echo("---") | ||
click.echo( | ||
f"All kubeconfig files have been created in the '{kubeconfig_dir}' directory with a duration of {token_duration} seconds." | ||
) | ||
click.echo("Distribute these files to the respective users.") | ||
click.echo( | ||
"Users can then use by running `warnet auth <file>` or with kubectl by specifying the --kubeconfig flag or by setting the KUBECONFIG environment variable." | ||
) | ||
click.echo(f"Note: The tokens will expire after {token_duration} seconds.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s "namespaces"