243 lines
7.3 KiB
Python
Executable File
243 lines
7.3 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# Copyright(c) 2016, Oracle and/or its affiliates. All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
import getopt
|
|
import os
|
|
import signal
|
|
import subprocess
|
|
import sys
|
|
import yaml
|
|
|
|
from kolla_cli.common.utils import change_password
|
|
from kolla_cli.common.utils import clear_all_passwords
|
|
from kolla_cli.common.utils import get_kolla_ansible_home
|
|
from kolla_cli.common.utils import get_kolla_cli_etc
|
|
from kolla_cli.common.utils import get_kolla_etc
|
|
|
|
|
|
def _init_keys(path):
|
|
cmd = 'kolla-genpwd'
|
|
if not os.path.exists(path):
|
|
raise Exception('The path %s does not exist' % path)
|
|
|
|
cmd = ' '.join((cmd, '-p', path))
|
|
(_, err) = subprocess.Popen(cmd, shell=True,
|
|
stdout=subprocess.PIPE,
|
|
stderr=subprocess.PIPE).communicate()
|
|
if err:
|
|
raise Exception('Error running %s: %s' % (cmd, err))
|
|
|
|
|
|
def _get_empty_keys(path):
|
|
"""get empty keys
|
|
|
|
print string with keys that have empty pwd values
|
|
"""
|
|
ok_empty = ['docker_registry_password']
|
|
empty_keys = ''
|
|
with open(path, 'r') as f:
|
|
pwd_data = f.read()
|
|
pwds = yaml.safe_load(pwd_data)
|
|
comma = ''
|
|
if pwds:
|
|
for pwd_key, pwd_val in pwds.items():
|
|
is_empty = False
|
|
if not pwd_val and pwd_key not in ok_empty:
|
|
is_empty = True
|
|
elif isinstance(pwd_val, dict):
|
|
if not pwd_val.get('private_key', None):
|
|
is_empty = True
|
|
elif not pwd_val.get('public_key', None):
|
|
is_empty = True
|
|
if is_empty:
|
|
empty_keys = ''.join([empty_keys, comma, pwd_key])
|
|
comma = ','
|
|
if empty_keys:
|
|
print(empty_keys)
|
|
|
|
|
|
def _print_pwd_keys(path):
|
|
keys_str = ''
|
|
prefix = ''
|
|
with open(path, 'r') as f:
|
|
pwd_data = f.read()
|
|
pwds = yaml.safe_load(pwd_data)
|
|
if pwds:
|
|
for pwd_key in pwds.keys():
|
|
keys_str = ''.join([keys_str, prefix, pwd_key])
|
|
prefix = ','
|
|
print(keys_str)
|
|
|
|
|
|
def _password_cmd(argv):
|
|
"""password command
|
|
|
|
args for password command:
|
|
-p path # path to passwords.yaml
|
|
-k key # key of password
|
|
-v value # value of password (if not ssh keys)
|
|
-r private key value # ssh private key
|
|
-u public key value # ssh public key
|
|
-c # flag to clear the password
|
|
-l # print to stdout a csv string of the existing keys
|
|
-e # get keys of passwords with empty values
|
|
-i # init empty keys and ssh keys
|
|
"""
|
|
opts, _ = getopt.getopt(argv[2:], 'p:k:v:r:u:clei')
|
|
path = ''
|
|
pwd_key = ''
|
|
pwd_value = ''
|
|
pwd_ssh_private = ''
|
|
pwd_ssh_public = ''
|
|
clear_flag = False
|
|
list_flag = False
|
|
empty_flag = False
|
|
init_flag = False
|
|
for opt, arg in opts:
|
|
if opt == '-p':
|
|
path = arg
|
|
elif opt == '-k':
|
|
pwd_key = arg
|
|
elif opt == '-v':
|
|
pwd_value = arg
|
|
elif opt == '-r':
|
|
pwd_ssh_private = arg.replace('"', '')
|
|
elif opt == '-u':
|
|
pwd_ssh_public = arg.replace('"', '')
|
|
elif opt == '-c':
|
|
clear_flag = True
|
|
elif opt == '-l':
|
|
list_flag = True
|
|
elif opt == '-e':
|
|
empty_flag = True
|
|
elif opt == '-i':
|
|
init_flag = True
|
|
if init_flag:
|
|
# init empty keys
|
|
_init_keys(path)
|
|
elif list_flag:
|
|
# print the password keys
|
|
_print_pwd_keys(path)
|
|
elif empty_flag:
|
|
# get empty passwords
|
|
_get_empty_keys(path)
|
|
else:
|
|
# edit/clear a password
|
|
change_password(path, pwd_key, pvalue=pwd_value,
|
|
private_key=pwd_ssh_private,
|
|
public_key=pwd_ssh_public, clear=clear_flag)
|
|
|
|
|
|
def _job_cmd(argv):
|
|
"""jobs command
|
|
|
|
args for job command
|
|
-t # terminate action
|
|
-p pid # process pid
|
|
"""
|
|
opts, _ = getopt.getopt(argv[2:], 'tp:')
|
|
pid = None
|
|
term_flag = False
|
|
for opt, arg in opts:
|
|
if opt == '-p':
|
|
pid = arg
|
|
elif opt == '-t':
|
|
term_flag = True
|
|
|
|
if term_flag:
|
|
try:
|
|
os.kill(int(pid), signal.SIGKILL)
|
|
except Exception as e:
|
|
raise Exception('%s, pid %s' % (str(e), pid))
|
|
|
|
|
|
def _config_reset_cmd():
|
|
"""config_reset command
|
|
|
|
args for config_reset command
|
|
- none
|
|
"""
|
|
kolla_etc = get_kolla_etc()
|
|
kolla_home = get_kolla_ansible_home()
|
|
kollacli_etc = get_kolla_cli_etc()
|
|
|
|
group_vars_path = os.path.join(kolla_home, 'ansible/group_vars')
|
|
host_vars_path = os.path.join(kolla_home, 'ansible/host_vars')
|
|
globals_path = os.path.join(group_vars_path, '__GLOBAL__')
|
|
inventory_path = os.path.join(kollacli_etc, 'ansible/inventory.json')
|
|
|
|
# truncate global property and inventory files
|
|
with open(globals_path, 'w') as globals_file:
|
|
globals_file.truncate()
|
|
|
|
with open(inventory_path, 'w') as inventory_file:
|
|
inventory_file.truncate()
|
|
|
|
# clear all passwords
|
|
clear_all_passwords()
|
|
|
|
# nuke all files under the kolla etc base, skipping everything
|
|
# in the kolla-cli directory and the globals.yml and passwords.yml files
|
|
for dir_path, dir_names, file_names in os.walk(kolla_etc, topdown=False):
|
|
if 'kolla-cli' not in dir_path:
|
|
for dir_name in dir_names:
|
|
if dir_name != 'kolla-cli':
|
|
os.rmdir(os.path.join(dir_path, dir_name))
|
|
|
|
for file_name in file_names:
|
|
if file_name == 'passwords.yml' or file_name == 'globals.yml':
|
|
continue
|
|
os.remove(os.path.join(dir_path, file_name))
|
|
|
|
# nuke all property files under the kolla-ansible base other than
|
|
# all.yml and the global property file which we truncate above
|
|
for dir_path, _, file_names in os.walk(group_vars_path):
|
|
for file_name in file_names:
|
|
if (file_name != '__GLOBAL__' and
|
|
file_name != 'all.yml'):
|
|
os.remove(os.path.join(dir_path, file_name))
|
|
|
|
for dir_path, _, file_names in os.walk(host_vars_path):
|
|
for file_name in file_names:
|
|
os.remove(os.path.join(dir_path, file_name))
|
|
|
|
|
|
def main():
|
|
"""perform actions on behalf of kolla user
|
|
|
|
sys.argv:
|
|
sys.argv[1] # command
|
|
|
|
Supported commands:
|
|
- password
|
|
- job
|
|
- config_reset
|
|
"""
|
|
if len(sys.argv) <= 1:
|
|
raise Exception('Invalid number of parameters')
|
|
|
|
command = sys.argv[1]
|
|
if command == 'password':
|
|
_password_cmd(sys.argv)
|
|
elif command == 'job':
|
|
_job_cmd(sys.argv)
|
|
elif command == 'config_reset':
|
|
_config_reset_cmd()
|
|
else:
|
|
raise Exception('Invalid command %s' % command)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|