-
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Verify Kubernetes context before install (#1739)
* Add method to confirm kubectl context * Set development server name to thecombine.localhost * Add function to verify required environment variables are set * Update Python dependencies * Improve user feedback importing semantic domains * Confirm kubernetes context & AWS environment when installing The Combine Co-authored-by: D. Ror <imnasnainaec@gmail.com>
- Loading branch information
1 parent
fc22049
commit 0498b7b
Showing
11 changed files
with
318 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
#! /usr/bin/env python3 | ||
"""Set AWS Environment variables from aws cli profiles.""" | ||
|
||
from __future__ import annotations | ||
|
||
import os | ||
import re | ||
from typing import Dict, List, Optional | ||
|
||
from utils import choose_from_list, run_cmd | ||
|
||
|
||
def aws_version() -> Optional[int]: | ||
"""Test if the aws cli version 2 is installed.""" | ||
try: | ||
result = run_cmd(["aws", "--version"], check_results=False, chomp=True) | ||
except FileNotFoundError: | ||
print("AWS CLI version 2 is not installed.") | ||
return None | ||
else: | ||
if result.returncode == 0: | ||
# get major version number from stdout | ||
match = re.match(r"aws-cli/(\d+)\..*", result.stdout) | ||
if match: | ||
return int(match.group(1)) | ||
return None | ||
|
||
|
||
def list_aws_profiles() -> List[str]: | ||
aws_ver = aws_version() | ||
if aws_ver is not None and aws_ver == 2: | ||
result = run_cmd(["aws", "configure", "list-profiles"], chomp=True) | ||
return result.stdout.split("\n") | ||
return [] | ||
|
||
|
||
def get_profile_var(profile: str, var_name: str) -> str: | ||
result = run_cmd(["aws", "configure", "--profile", profile, "get", var_name], chomp=True) | ||
return result.stdout | ||
|
||
|
||
def init_aws_environment() -> None: | ||
profile_list = list_aws_profiles() | ||
# Build a map for looking up a profile name from the access key id. This | ||
# algorithm assumes: | ||
# - the 'default' profile will be processed first | ||
# - if there are profiles using the same access key id, only the last | ||
# one will be put into the map | ||
if len(profile_list) == 0: | ||
return | ||
profile_map: Dict[str, str] = {} | ||
for profile in profile_list: | ||
key_id = get_profile_var(profile, "aws_access_key_id") | ||
profile_map[key_id] = profile | ||
curr_access_key = os.getenv("AWS_ACCESS_KEY_ID", "") | ||
if curr_access_key in profile_map: | ||
curr_profile = profile_map[curr_access_key] | ||
else: | ||
curr_profile = None | ||
aws_profile = choose_from_list("AWS Environment", curr_profile, profile_list) | ||
if aws_profile is not None and aws_profile != curr_profile: | ||
os.environ["AWS_PROFILE"] = aws_profile | ||
os.environ["AWS_ACCESS_KEY_ID"] = get_profile_var(aws_profile, "aws_access_key_id") | ||
os.environ["AWS_SECRET_ACCESS_KEY"] = get_profile_var(aws_profile, "aws_secret_access_key") | ||
os.environ["AWS_DEFAULT_REGION"] = get_profile_var(aws_profile, "region") | ||
result = run_cmd( | ||
[ | ||
"aws", | ||
"sts", | ||
"--profile", | ||
aws_profile, | ||
"get-caller-identity", | ||
"--query", | ||
"Account", | ||
"--output", | ||
"text", | ||
], | ||
chomp=True, | ||
) | ||
os.environ["AWS_ACCOUNT"] = result.stdout | ||
|
||
|
||
if __name__ == "__main__": | ||
init_aws_environment() | ||
print("AWS Environment:") | ||
for env_var in [ | ||
"AWS_ACCOUNT", | ||
"AWS_DEFAULT_REGION", | ||
"AWS_ACCESS_KEY_ID", | ||
"AWS_SECRET_ACCESS_KEY", | ||
]: | ||
print(f"{env_var}: {os.getenv(env_var, None)}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
#!/usr/bin/env python3 | ||
"""Manage the Kubernetes environment for kubectl & helm.""" | ||
|
||
from __future__ import annotations | ||
|
||
import argparse | ||
from typing import List, Optional | ||
|
||
from utils import choose_from_list, run_cmd | ||
|
||
|
||
class KubernetesEnvironment: | ||
def __init__(self, args: argparse.Namespace) -> None: | ||
if "kubeconfig" in args and args.kubeconfig is not None: | ||
self.kubeconfig = args.kubeconfig | ||
else: | ||
self.kubeconfig = None | ||
if "context" in args and args.context is not None: | ||
# if the user specified a context, use that one. | ||
self.kubecontext = args.context | ||
else: | ||
context_list: List[str] = [] | ||
|
||
result = run_cmd( | ||
["kubectl"] + self.get_kubeconfig() + ["config", "get-contexts", "--no-headers"], | ||
check_results=True, | ||
) | ||
curr_context: Optional[str] = None | ||
for line in result.stdout.splitlines(): | ||
if line[0] == "*": | ||
curr_context = line.split()[1] | ||
context_list.append(curr_context) | ||
else: | ||
context_list.append(line.split()[0]) | ||
|
||
# If there is more than one context available, prompt the user to make sure | ||
# that the intended context will be used. | ||
curr_context = choose_from_list("context", curr_context, context_list) | ||
if curr_context: | ||
self.kubecontext = curr_context | ||
else: | ||
self.kubecontext = None | ||
if "debug" in args: | ||
self.debug = args.debug | ||
else: | ||
self.debug = False | ||
|
||
def get_kubeconfig(self) -> List[str]: | ||
if self.kubeconfig is not None: | ||
return ["--kubeconfig", self.kubeconfig] | ||
return [] | ||
|
||
def get_helm_opts(self) -> List[str]: | ||
""" | ||
Create list of general helm options. | ||
""" | ||
helm_opts = self.get_kubeconfig() | ||
|
||
if self.kubecontext is not None: | ||
helm_opts.extend(["--kube-context", self.kubecontext]) | ||
if self.debug: | ||
helm_opts.append("--debug") | ||
return helm_opts | ||
|
||
def get_kubectl_opts(self) -> List[str]: | ||
""" | ||
Create list of general kubectl options. | ||
""" | ||
kubectl_opts = self.get_kubeconfig() | ||
|
||
if self.kubecontext is not None: | ||
kubectl_opts.extend(["--context", self.kubecontext]) | ||
return kubectl_opts | ||
|
||
|
||
def add_kube_opts(parser: argparse.ArgumentParser) -> None: | ||
"""Add commandline arguments for Kubernetes tools.""" | ||
parser.add_argument( | ||
"--context", | ||
help="Context in kubectl configuration file to be used.", | ||
) | ||
parser.add_argument( | ||
"--debug", | ||
action="store_true", | ||
help="Enable debugging output for helm commands.", | ||
) | ||
parser.add_argument( | ||
"--kubeconfig", | ||
help="Specify the kubectl configuration file to be used.", | ||
) | ||
|
||
|
||
if __name__ == "__main__": | ||
parser = argparse.ArgumentParser( | ||
description="Generate Helm Charts for The Combine.", | ||
formatter_class=argparse.ArgumentDefaultsHelpFormatter, | ||
) | ||
add_kube_opts(parser) | ||
args = parser.parse_args() | ||
|
||
kube_env = KubernetesEnvironment(args) | ||
print(f"kubectl {kube_env.get_kubectl_opts()} ...") | ||
print(f"helm {kube_env.get_helm_opts()} ...") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.