dotfiles/bin/kube-import
2023-02-28 09:40:55 +08:00

138 lines
3.4 KiB
Python
Executable File

#!/usr/bin/env python3
import json
import os
import sys
import subprocess
try:
import yaml
# import clipboard
except:
print("please install PyYAML first", file=sys.stderr)
print("sudo pip install PyYAML", file=sys.stderr)
sys.exit(-1)
def halt_with_help():
print("Usage: kube-import <YAML_FILE_PATH>", file=sys.stderr)
print(" pipe from stdin is not supported because user input is needed", file=sys.stderr)
print(file=sys.stderr)
sys.exit(-1)
if len(sys.argv) < 2:
halt_with_help()
# new_config_data = clipboard.paste()
yaml_path = sys.argv[1]
with open(yaml_path) as yaml_file:
new_config_data = yaml_file.read()
if not new_config_data:
halt_with_help()
try:
new_config = yaml.load(new_config_data, Loader=yaml.Loader)
except:
print("illegal yaml format", file=sys.stderr)
new_clusters = new_config.get('clusters')
new_contexts = new_config.get('contexts')
new_users = new_config.get('users')
if not new_clusters or not new_contexts or not new_users:
print("configuration yaml must have clusers/contexts/users", file=sys.stderr)
sys.exit(-1)
new_context_name = input("Enter context name:")
if not new_context_name:
print("aborted!", file=sys.stderr)
sys.exit(-1)
new_cluster_name = input("Enter cluster name:")
if not new_cluster_name:
print("aborted!", file=sys.stderr)
sys.exit(-1)
new_user_name = f'{new_cluster_name}-user'
# load config file
cfg_path = os.path.expanduser('~/.kube/config')
if os.path.exists(cfg_path):
with open(cfg_path) as f:
config = yaml.load(f, Loader=yaml.Loader) or {}
else:
os.makedirs(os.path.dirname(cfg_path), exist_ok=True)
config = {}
config['apiVersion'] = config.get('apiVersion', 'v1')
config['kind'] = config.get('kind', 'Config')
config['clusters'] = config.get('clusters', [])
config['contexts'] = config.get('contexts', [])
config['users'] =config.get('users', [])
# merge cluster into config
def append_or_replace(array, elem, cond):
index = -1
for i, c in enumerate(array):
if cond(c):
index = i
break
if index > -1:
old_elem = array[index]
array[index] = elem
return old_elem
else:
array.append(elem)
def update_context_ref(old, new, ref_key):
if old and old['name'] != new['name']:
for ctx in config['contexts']:
# import ipdb; ipdb.set_trace()
if ctx['name'] == old['name']:
ctx['context'][ref_key] = new['name']
new_context = new_contexts[0]
new_cluster = new_clusters[0]
new_user = new_users[0]
new_context['name'] = new_context_name
new_context['context']['cluster'] = new_cluster_name
new_context['context']['user'] = new_user_name
new_cluster['name'] = new_cluster_name
new_user['name'] = new_user_name
old_cluster = append_or_replace(
config['clusters'],
new_cluster,
lambda c: (
c['name'] == new_cluster_name or c['cluster'] == new_cluster['cluster']
)
)
update_context_ref(old_cluster, new_cluster, 'cluster')
old_user = append_or_replace(
config['users'],
new_user,
lambda u: (
u['name'] == new_user['name'] or u['user'] == new_user['user']
)
)
update_context_ref(old_user, new_user, 'user')
append_or_replace(
config['contexts'],
new_context,
lambda c: (
c['name'] == new_context_name
)
)
# save config file
config['current-context'] = new_context_name
with open(cfg_path, 'w') as f:
f.write(yaml.dump(config))