def take_action(self, parsed_args): try: groupname = parsed_args.groupname.strip() groupname = utils.convert_to_unicode(groupname) inventory = Inventory.load() inventory.remove_group(groupname) Inventory.save(inventory) except CommandError as e: raise e except Exception as e: raise Exception(traceback.format_exc())
def test_json_generator(self): self.run_cli_cmd('setdeploy local') host1 = 'host_test1' self.run_cli_cmd('host add %s' % host1) inventory = Inventory.load() path = inventory.create_json_gen_file() (retval, msg) = self.run_command(path) os.remove(path) self.assertEqual(0, retval, 'json generator command failed: %s' % msg) self.assertNotEqual('', msg, 'json generator returned no data: %s' % msg) self.assertIn(host1, msg, '%s not in json_gen output: %s' % (host1, msg)) for service, subservices in SERVICES.items(): self.assertIn(service, msg, '%s not in json_gen output: %s' % (service, msg)) for subservice in subservices: self.assertIn( subservice, msg, '%s not in json_gen output: %s' % (subservice, msg)) # verify that json output is valid. This will throw if invalid json try: json.loads(msg) except Exception: self.assertTrue(False, 'invalid json: %s' % msg) remote_msg = '"ansible_ssh_user": "******"' local_msg = '"ansible_connection": "local"' # verify that setdeploy local worked: self.assertIn(local_msg, msg, '%s not in local json_gen output: %s' % (local_msg, msg)) self.assertNotIn(remote_msg, msg, '%s in local json_gen output: %s' % (remote_msg, msg)) # verify that setdeploy remote worked: self.run_cli_cmd('setdeploy remote') inventory = Inventory.load() path = inventory.create_json_gen_file() (retval, msg) = self.run_command(path) os.remove(path) self.assertEqual(0, retval, 'json generator command failed: %s' % msg) self.assertIn( remote_msg, msg, '%s not in remote json_gen output: %s' % (remote_msg, msg)) self.assertNotIn(local_msg, msg, '%s in remote json_gen output: %s' % (local_msg, msg))
def take_action(self, parsed_args): try: hostname = parsed_args.hostname.strip() hostname = utils.convert_to_unicode(hostname) inventory = Inventory.load() inventory.add_host(hostname) Inventory.save(inventory) except CommandError as e: raise e except Exception as e: raise Exception(traceback.format_exc())
def run_ansible_cmd(cmd, host): # sudo -u kolla ansible ol7-c4 -i inv_path -a "cmd" out = None user = get_admin_user() inventory = Inventory.load() inv_path = inventory.create_json_gen_file() acmd = ('/usr/bin/sudo -u %s ansible %s -i %s -a "%s"' % (user, host, inv_path, cmd)) try: (out, err) = subprocess.Popen(acmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() except Exception as e: print('%s\nCannot communicate with host: %s, skipping' % (e, host)) finally: os.remove(inv_path) if not out: print('Host %s is not accessible: %s, skipping' % (host, err)) elif '>>' not in out: print('Ansible command: %s' % acmd) print('Host: %s. \nInvalid ansible return data: [%s]. skipping' % (host, out)) out = None return out
def take_action(self, parsed_args): try: hostname = None if parsed_args.hostname: hostname = parsed_args.hostname.strip() hostname = utils.convert_to_unicode(hostname) inventory = Inventory.load() if hostname: host = inventory.get_host(hostname) if not host: _host_not_found(self.log, hostname) data = [] host_groups = inventory.get_host_groups() if host_groups: if hostname: data.append((hostname, host_groups[hostname])) else: for (hostname, groupnames) in host_groups.items(): data.append((hostname, groupnames)) else: data.append(('', '')) return (('Host', 'Groups'), sorted(data)) except CommandError as e: raise e except Exception as e: raise Exception(traceback.format_exc())
def take_action(self, parsed_args): try: mode = parsed_args.mode.strip() remote_flag = False if mode == 'remote': remote_flag = True elif mode != 'local': raise CommandError('Invalid deploy mode. Mode must be ' + 'either "local" or "remote"') inventory = Inventory.load() inventory.set_deploy_mode(remote_flag) Inventory.save(inventory) except CommandError as e: raise e except Exception: raise Exception(traceback.format_exc())
def test_json_generator(self): self.run_cli_cmd("setdeploy local") host1 = "host_test1" self.run_cli_cmd("host add %s" % host1) inventory = Inventory.load() path = inventory.create_json_gen_file() (retval, msg) = self.run_command(path) os.remove(path) self.assertEqual(0, retval, "json generator command failed: %s" % msg) self.assertNotEqual("", msg, "json generator returned no data: %s" % msg) self.assertIn(host1, msg, "%s not in json_gen output: %s" % (host1, msg)) for service, subservices in SERVICES.items(): self.assertIn(service, msg, "%s not in json_gen output: %s" % (service, msg)) for subservice in subservices: self.assertIn(subservice, msg, "%s not in json_gen output: %s" % (subservice, msg)) # verify that json output is valid. This will throw if invalid json try: json.loads(msg) except Exception: self.assertTrue(False, "invalid json: %s" % msg) remote_msg = '"ansible_ssh_user": "******"' local_msg = '"ansible_connection": "local"' # verify that setdeploy local worked: self.assertIn(local_msg, msg, "%s not in local json_gen output: %s" % (local_msg, msg)) self.assertNotIn(remote_msg, msg, "%s in local json_gen output: %s" % (remote_msg, msg)) # verify that setdeploy remote worked: self.run_cli_cmd("setdeploy remote") inventory = Inventory.load() path = inventory.create_json_gen_file() (retval, msg) = self.run_command(path) os.remove(path) self.assertEqual(0, retval, "json generator command failed: %s" % msg) self.assertIn(remote_msg, msg, "%s not in remote json_gen output: %s" % (remote_msg, msg)) self.assertNotIn(local_msg, msg, "%s in remote json_gen output: %s" % (local_msg, msg))
def main(): """collect docker logs from servers $ command is $ log_collector.py <all | host1[,host2,host3...]> """ global tar_file_descr help_msg = 'Usage: log_collector.py <all | host1[,host2,host3...]>' hosts = [] if len(sys.argv) == 2: if '-h' == sys.argv[1] or '--help' == sys.argv[1]: print(help_msg) sys.exit(0) elif 'all' == sys.argv[1]: # get logs from all hosts inventory = Inventory.load() hosts = inventory.get_hostnames() else: # get logs from specified hosts hostnames = sys.argv[1].split(',') for host in hostnames: if host not in hosts: hosts.append(host) else: print(help_msg) sys.exit(1) # open tar file for storing logs fd, tar_path = tempfile.mkstemp(prefix='kolla_support_logs_', suffix='.tgz') os.close(fd) # avoid fd leak with tarfile.open(tar_path, 'w:gz') as tar_file_descr: # gather dump output from kollacli print('Getting kollacli logs') # cliff prints log output to stderr (_, err) = subprocess.Popen('kollacli dump'.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() if '/' in err: dump_path = '/' + err.strip().split('/', 1)[1] if os.path.isfile(dump_path): tar_file_descr.add(dump_path) os.remove(dump_path) else: print('ERROR: No kolla dump output file at %s' % dump_path) else: print('ERROR: No path found in dump command output: %s' % err) # gather logs from selected hosts for host in hosts: print('Getting docker logs from host: %s' % host) add_logs_from_host(host) print('Log collection complete. Logs are at %s' % tar_path)
def take_action(self, parsed_args): try: hostname = parsed_args.hostname.strip() hostname = utils.convert_to_unicode(hostname) inventory = Inventory.load() if not inventory.get_host(hostname): _host_not_found(self.log, hostname) inventory.check_host(hostname) except CommandError as e: raise e except Exception as e: raise Exception(traceback.format_exc())
def test_json_filtering(self): hosts = ['host_test1', 'host_test2', 'host_test3'] groups = ['control', 'network', 'storage'] for host in hosts: self.run_cli_cmd('host add %s' % host) for group in groups: self.run_cli_cmd('group addhost %s %s' % (group, host)) inventory = Inventory.load() # filter by host- include all hosts inv_filter = {'deploy_hosts': hosts} path = inventory.create_json_gen_file(inv_filter) self.log.info('run command: %s' % path) (retval, msg) = self.run_command(path) os.remove(path) self.assertEqual(0, retval, 'json generator command failed: %s' % msg) self.check_json(msg, groups, hosts, groups, hosts) # filter by host- to first host included_host = hosts[0] inv_filter = {'deploy_hosts': [included_host]} path = inventory.create_json_gen_file(inv_filter) self.log.info('run command: %s' % path) (retval, msg) = self.run_command(path) os.remove(path) self.assertEqual(0, retval, 'json generator command failed: %s' % msg) self.check_json(msg, groups, hosts, groups, [included_host]) # filter by group- include all groups inv_filter = {'deploy_groups': groups} path = inventory.create_json_gen_file(inv_filter) self.log.info('run command: %s' % path) (retval, msg) = self.run_command(path) os.remove(path) self.assertEqual(0, retval, 'json generator command failed: %s' % msg) self.check_json(msg, groups, hosts, groups, hosts) # filter by group- to first group included_group = groups[0] inv_filter = {'deploy_groups': [included_group]} path = inventory.create_json_gen_file(inv_filter) self.log.info('run command: %s' % path) (retval, msg) = self.run_command(path) os.remove(path) self.assertEqual(0, retval, 'json generator command failed: %s' % msg) self.check_json(msg, groups, hosts, [included_group], hosts)
def test_json_filtering(self): hosts = ["host_test1", "host_test2", "host_test3"] groups = ["control", "network", "storage"] for host in hosts: self.run_cli_cmd("host add %s" % host) for group in groups: self.run_cli_cmd("group addhost %s %s" % (group, host)) inventory = Inventory.load() # filter by host- include all hosts inv_filter = {"deploy_hosts": hosts} path = inventory.create_json_gen_file(inv_filter) self.log.info("run command: %s" % path) (retval, msg) = self.run_command(path) os.remove(path) self.assertEqual(0, retval, "json generator command failed: %s" % msg) self.check_json(msg, groups, hosts, groups, hosts) # filter by host- to first host included_host = hosts[0] inv_filter = {"deploy_hosts": [included_host]} path = inventory.create_json_gen_file(inv_filter) self.log.info("run command: %s" % path) (retval, msg) = self.run_command(path) os.remove(path) self.assertEqual(0, retval, "json generator command failed: %s" % msg) self.check_json(msg, groups, hosts, groups, [included_host]) # filter by group- include all groups inv_filter = {"deploy_groups": groups} path = inventory.create_json_gen_file(inv_filter) self.log.info("run command: %s" % path) (retval, msg) = self.run_command(path) os.remove(path) self.assertEqual(0, retval, "json generator command failed: %s" % msg) self.check_json(msg, groups, hosts, groups, hosts) # filter by group- to first group included_group = groups[0] inv_filter = {"deploy_groups": [included_group]} path = inventory.create_json_gen_file(inv_filter) self.log.info("run command: %s" % path) (retval, msg) = self.run_command(path) os.remove(path) self.assertEqual(0, retval, "json generator command failed: %s" % msg) self.check_json(msg, groups, hosts, [included_group], hosts)
def take_action(self, parsed_args): try: inventory = Inventory.load() data = [] group_services = inventory.get_group_services() if group_services: for (groupname, servicenames) in group_services.items(): data.append((groupname, sorted(servicenames))) else: data.append(('', '')) return (('Group', 'Services'), sorted(data)) except CommandError as e: raise e except Exception as e: raise Exception(traceback.format_exc())
def take_action(self, parsed_args): try: inventory = Inventory.load() data = [] service_subsvcs = inventory.get_service_sub_services() if service_subsvcs: for (servicename, sub_svcname) in service_subsvcs.items(): data.append((servicename, sub_svcname)) else: data.append(('', '')) return (('Service', 'Sub-Services'), sorted(data)) except CommandError as e: raise e except Exception as e: raise Exception(traceback.format_exc())
def take_action(self, parsed_args): try: if not parsed_args.hostname and not parsed_args.file: raise CommandError('Hostname or hosts info file path ' + 'is required') if parsed_args.hostname and parsed_args.file: raise CommandError('Hostname and hosts info file path ' + 'cannot both be present') inventory = Inventory.load() if parsed_args.file: # multi-host setup via xml file hosts_data = self.get_yml_data(parsed_args.file.strip()) inventory.setup_hosts(hosts_data) else: # single host setup hostname = parsed_args.hostname.strip() hostname = utils.convert_to_unicode(hostname) if not inventory.get_host(hostname): _host_not_found(self.log, hostname) check_ok = inventory.check_host(hostname, True) if check_ok: self.log.info( 'Skipping setup of host (%s) as check is ok' % hostname) return True if parsed_args.insecure: password = parsed_args.insecure.strip() else: setup_user = get_setup_user() password = getpass.getpass('%s password for %s: ' % (setup_user, hostname)) password = utils.convert_to_unicode(password) inventory.setup_host(hostname, password) except CommandError as e: raise e except Exception as e: raise Exception(traceback.format_exc())
def take_action(self, parsed_args): try: inventory = Inventory.load() data = [] service_groups = inventory.get_service_groups() if service_groups: for (servicename, (groupnames, inherit)) \ in service_groups.items(): inh_str = 'yes' if inherit is None: inh_str = '-' elif inherit is False: inh_str = 'no' data.append((servicename, groupnames, inh_str)) else: data.append(('', '')) return (('Service', 'Groups', 'Inherited'), sorted(data)) except CommandError as e: raise e except Exception as e: raise Exception(traceback.format_exc())
def take_action(self, parsed_args): try: hostname = '' hostname = parsed_args.hostname.strip() hostname = convert_to_unicode(hostname) if hostname != 'all': inventory = Inventory.load() host = inventory.get_host(hostname) if not host: _host_not_found(self.log, hostname) destroy_type = 'kill' if parsed_args.stop: destroy_type = 'stop' self.log.info('please be patient as this may take a while.') ansible_properties = properties.AnsibleProperties() base_distro = \ ansible_properties.get_property('kolla_base_distro') install_type = \ ansible_properties.get_property('kolla_install_type') container_prefix = base_distro + '-' + install_type kollacli_home = get_kollacli_home() playbook = AnsiblePlaybook() playbook.playbook_path = os.path.join(kollacli_home, 'ansible/host_destroy.yml') playbook.extra_vars = 'hosts=' + hostname + \ ' prefix=' + container_prefix + \ ' destroy_type=' + destroy_type playbook.print_output = False playbook.verbose_level = self.app.options.verbose_level playbook.run() except CommandError as e: raise e except Exception as e: raise Exception(traceback.format_exc())
def _add_cmd_info(self, tar): # run all the kollacli list commands cmds = ['kollacli service listgroups', 'kollacli service list', 'kollacli group listservices', 'kollacli group listhosts', 'kollacli host list', 'kollacli property list', 'kollacli password list'] # collect the json inventory output inventory = Inventory.load() inv_path = inventory.create_json_gen_file() cmds.append(inv_path) try: fd, path = tempfile.mkstemp(suffix='.tmp') os.close(fd) with open(path, 'w') as tmp_file: for cmd in cmds: err_msg, output = run_cmd(cmd, False) tmp_file.write('\n\n$ %s\n' % cmd) if err_msg: tmp_file.write('Error message: %s\n' % err_msg) lines = output.split('\n') for line in lines: tmp_file.write(line + '\n') tar.add(path, arcname=os.path.join('kolla', 'cmds_output')) except Exception as e: raise e finally: if path: os.remove(path) if inv_path: os.remove(inv_path) return
def run(self): globals_string = None password_string = None inventory_path = None cmd = '' try: flag = '' # verbose levels: 1=not verbose, 2=more verbose if self.verbose_level > 1: flag = '-vvv' admin_user = get_admin_user() command_string = ('/usr/bin/sudo -u %s ansible-playbook %s' % (admin_user, flag)) inventory = Inventory.load() inventory_filter = {} if self.hosts: for hostname in self.hosts: host = inventory.get_host(hostname) if not host: raise CommandError( 'Host (%s) not found. ' % hostname) inventory_filter['deploy_hosts'] = self.hosts elif self.groups: for groupname in self.groups: group = inventory.get_group(groupname) if not group: raise CommandError( 'Group (%s) not found. ' % groupname) inventory_filter['deploy_groups'] = self.groups inventory_path = inventory.create_json_gen_file(inventory_filter) inventory_string = '-i ' + inventory_path cmd = (command_string + ' ' + inventory_string) if self.include_globals: globals_string = self._get_globals_path() cmd = (cmd + ' ' + globals_string) if self.include_passwords: password_string = self._get_password_path() cmd = (cmd + ' ' + password_string) cmd = (cmd + ' ' + self.playbook_path) if self.extra_vars or self.serial: extra_vars = '' if self.extra_vars: extra_vars = self.extra_vars if self.serial: extra_vars += ' ' if self.serial: extra_vars += 'serial_var=1' cmd = (cmd + ' --extra-vars \"' + extra_vars + '\"') if self.services: service_string = '' first = True for service in self.services: valid_service = inventory.get_service(service) if not valid_service: raise CommandError( 'Service (%s) not found. ' % service) if not first: service_string = service_string + ',' else: first = False service_string = service_string + service cmd = (cmd + ' --tags ' + service_string) if self.flush_cache: cmd = (cmd + ' --flush-cache') if self.verbose_level > 1: # log the ansible command self.log.debug('cmd:' + cmd) if self.verbose_level > 2: # log the inventory dbg_gen = inventory_path (inv, _) = \ subprocess.Popen(dbg_gen.split(' '), stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() self.log.debug(inv) err_msg, output = run_cmd(cmd, self.print_output) if err_msg: if not self.print_output: # since the user didn't see the output, include it in # the error message err_msg = '%s %s' % (err_msg, output) raise CommandError(err_msg) self.log.info('Success') except CommandError as e: raise e except Exception: raise Exception(traceback.format_exc()) finally: if inventory_path: os.remove(inventory_path)
def run(self): globals_string = None password_string = None inventory_path = None cmd = '' try: flag = '' # verbose levels: 1=not verbose, 2=more verbose if self.verbose_level > 1: flag = '-vvv' admin_user = get_admin_user() command_string = ('/usr/bin/sudo -u %s ansible-playbook %s' % (admin_user, flag)) inventory = Inventory.load() inventory_filter = {} if self.hosts: for hostname in self.hosts: host = inventory.get_host(hostname) if not host: raise CommandError('Host (%s) not found. ' % hostname) inventory_filter['deploy_hosts'] = self.hosts elif self.groups: for groupname in self.groups: group = inventory.get_group(groupname) if not group: raise CommandError('Group (%s) not found. ' % groupname) inventory_filter['deploy_groups'] = self.groups inventory_path = inventory.create_json_gen_file(inventory_filter) inventory_string = '-i ' + inventory_path cmd = (command_string + ' ' + inventory_string) if self.include_globals: globals_string = self._get_globals_path() cmd = (cmd + ' ' + globals_string) if self.include_passwords: password_string = self._get_password_path() cmd = (cmd + ' ' + password_string) cmd = (cmd + ' ' + self.playbook_path) if self.extra_vars or self.serial: extra_vars = '' if self.extra_vars: extra_vars = self.extra_vars if self.serial: extra_vars += ' ' if self.serial: extra_vars += 'serial_var=1' cmd = (cmd + ' --extra-vars \"' + extra_vars + '\"') if self.services: service_string = '' first = True for service in self.services: valid_service = inventory.get_service(service) if not valid_service: raise CommandError('Service (%s) not found. ' % service) if not first: service_string = service_string + ',' else: first = False service_string = service_string + service cmd = (cmd + ' --tags ' + service_string) if self.flush_cache: cmd = (cmd + ' --flush-cache') if self.verbose_level > 1: # log the ansible command self.log.debug('cmd:' + cmd) if self.verbose_level > 2: # log the inventory dbg_gen = inventory_path (inv, _) = \ subprocess.Popen(dbg_gen.split(' '), stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() self.log.debug(inv) err_msg, output = run_cmd(cmd, self.print_output) if err_msg: if not self.print_output: # since the user didn't see the output, include it in # the error message err_msg = '%s %s' % (err_msg, output) raise CommandError(err_msg) self.log.info('Success') except CommandError as e: raise e except Exception: raise Exception(traceback.format_exc()) finally: if inventory_path: os.remove(inventory_path)