kolla-cli/tools/kolla_actions.py

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()