def dump(dirpath): """Dumps configuration data for debugging Dumps most files in /etc/kolla and /usr/share/kolla into a tar file so be given to support / development to help with debugging problems. """ kolla_home = get_kolla_ansible_home() kolla_logs = get_kolla_ansible_log_dir() kolla_ansible = os.path.join(kolla_home, 'ansible') kollacli_etc = get_kolla_cli_etc().rstrip('/') ketc = 'kolla/etc/' kshare = 'kolla/share/' fd, dump_path = tempfile.mkstemp(dir=dirpath, prefix='kollacli_dump_', suffix='.tgz') os.close(fd) # avoid fd leak with tarfile.open(dump_path, 'w:gz') as tar: # Can't blanket add kolla_home because the .ssh dir is # accessible by the kolla user only (not kolla group) tar.add(kolla_ansible, arcname=kshare + os.path.basename(kolla_ansible)) # Can't blanket add kolla_etc because the passwords.yml # file is accessible by the kolla user only (not kolla group) tar.add(kollacli_etc, arcname=ketc + os.path.basename(kollacli_etc)) # add kolla log files if os.path.isdir(kolla_logs): tar.add(kolla_logs) # add output of various commands _add_cmd_info(tar) return dump_path
def destroy_hosts(hostnames, destroy_type, verbose_level=1, include_data=False, remove_images=False): '''destroy containers on a set of hosts. The containers on the specified hosts will be stopped or killed. ''' playbook = AnsiblePlaybook() playbook_name = 'destroy.yml' LOG.info(u._LI('Please be patient as this may take a while.')) kolla_home = get_kolla_ansible_home() playbook.playbook_path = os.path.join(kolla_home, 'ansible/' + playbook_name) # 'hosts' is defined as 'all' in the playbook yml code, but inventory # filtering will subset that down to the hosts in playbook.hosts. playbook.hosts = hostnames if remove_images: playbook.extra_vars = 'destroy_include_images=yes' if verbose_level <= 1: playbook.print_output = False playbook.verbose_level = verbose_level job = playbook.run() return job
def __init__(self, verbose_level=0, playbook_name=''): self.playbook_name = playbook_name self.playbook_path = os.path.join(get_kolla_ansible_home(), 'ansible/', self.playbook_name) self.playbook = AnsiblePlaybook() self.playbook.verbose_level = verbose_level self.playbook.playbook_path = self.playbook_path
def pull(verbose_level=1): '''run pull action against all hosts''' playbook = AnsiblePlaybook() kolla_home = get_kolla_ansible_home() playbook.playbook_path = os.path.join(kolla_home, 'ansible/site.yml') playbook.extra_vars = 'action=pull' playbook.verbose_level = verbose_level job = playbook.run() return job
def upgrade(verbose_level=1, servicenames=[]): playbook = AnsiblePlaybook() kolla_home = get_kolla_ansible_home() playbook.playbook_path = os.path.join(kolla_home, 'ansible/site.yml') playbook.extra_vars = 'action=upgrade' playbook.print_output = True playbook.verbose_level = verbose_level playbook.services = servicenames job = playbook.run() return job
def reconfigure(verbose_level=1): playbook = AnsiblePlaybook() kolla_home = get_kolla_ansible_home() playbook.playbook_path = os.path.join(kolla_home, 'ansible/site.yml') playbook.extra_vars = 'action=reconfigure' playbook.verbose_level = verbose_level _run_deploy_rules(playbook) job = playbook.run() return job
def deploy(hostnames=[], serial_flag=False, verbose_level=1, servicenames=[]): playbook = AnsiblePlaybook() kolla_home = get_kolla_ansible_home() playbook.playbook_path = os.path.join(kolla_home, 'ansible/site.yml') playbook.extra_vars = 'action=deploy' playbook.hosts = hostnames playbook.serial = serial_flag playbook.verbose_level = verbose_level playbook.services = servicenames _run_deploy_rules(playbook) job = playbook.run() return job
def certificate_init(verbose_level=1): '''Creates a self-signed certificate''' playbook = AnsiblePlaybook() playbook_name = 'certificates.yml' kolla_home = get_kolla_ansible_home() playbook.playbook_path = os.path.join(kolla_home, 'ansible/' + playbook_name) playbook.verbose_level = verbose_level playbook.local_only = True playbook.become_user = get_admin_user() job = playbook.run() return job
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 _load_properties_all(self): allvars_path = os.path.join(get_kolla_ansible_home(), ALLVARS_PATH) with open(allvars_path) as allvars_file: allvars_contents = yaml.safe_load(allvars_file) for key, value in allvars_contents.items(): overrides = False orig_value = None if key in self.unique_global_props: overrides = True orig_value = self.unique_global_props[key].value ansible_prop = AnsibleProperty(key, value, 'group_vars/all.yml', overrides, orig_value) self.global_props.append(ansible_prop) self.unique_global_props[key] = ansible_prop
def _load_properties_roles(self): start_dir = os.path.join(get_kolla_ansible_home(), ANSIBLE_ROLES_PATH) services = next(os.walk(start_dir))[1] for service_name in services: file_name = os.path.join(start_dir, service_name, ANSIBLE_DEFAULTS_PATH) if os.path.isfile(file_name): with open(file_name) as service_file: service_contents = yaml.safe_load(service_file) prop_file_name = service_name + ':main.yml' for key, value in service_contents.items(): ansible_prop = AnsibleProperty(key, value, prop_file_name) self.global_props.append(ansible_prop) self.unique_global_props[key] = ansible_prop
def _restore_config(self): """restore config""" # restore inventory dst_path = os.path.join(utils.get_kolla_cli_etc(), 'ansible', 'inventory.json') src_path = os.path.join('/tmp', 'inventory.json.utest.save') copyfile(src_path, dst_path) # restore group vars ansible_dir = os.path.join(utils.get_kolla_ansible_home(), 'ansible') groupdir = os.path.join(ansible_dir, 'group_vars') self._restore_dir(groupdir) # restore host vars hostdir = os.path.join(ansible_dir, 'host_vars') self._restore_dir(hostdir)
def precheck(hostnames, verbose_level=1): '''run check playbooks on a set of hosts''' playbook_name = 'prechecks_preinstall.yml' kolla_home = get_kolla_ansible_home() playbook = AnsiblePlaybook() playbook.playbook_path = os.path.join(kolla_home, 'ansible/' + playbook_name) # define 'hosts' to be all, but inventory filtering will subset # that down to the hosts in playbook.hosts. playbook.extra_vars = 'hosts=all' playbook.hosts = hostnames playbook.print_output = True playbook.verbose_level = verbose_level job = playbook.run() return job
def stop_hosts(hostnames=[], verbose_level=1): '''stop containers on a set of hosts. The containers on the specified hosts will be stopped or killed if the stop takes over 20 seconds. ''' playbook = AnsiblePlaybook() playbook_name = 'stop.yml' LOG.info(u._LI('Please be patient as this may take a while.')) kolla_home = get_kolla_ansible_home() playbook.playbook_path = os.path.join(kolla_home, 'ansible/' + playbook_name) # 'hosts' is defined as 'all' in the playbook yml code, but inventory # filtering will subset that down to the hosts in playbook.hosts. playbook.hosts = hostnames if verbose_level <= 1: playbook.print_output = False playbook.verbose_level = verbose_level job = playbook.run() return job
def __init__(self): """initialize ansible property information property information is pulled from the following files (from lowest to highest priority): KOLLA_HOME/ansible/roles/<service>/default/main.yml KOLLA_HOME/ansible/group_vars/all.yml KOLLA_HOME/ansible/group_vars/__GLOBAL__ KOLLA_HOME/ansible/group_vars/* KOLLA_HOME/ansible/host_vars/* KOLLA_ETC/passwords.yml """ self.globals_path = os.path.join(get_kolla_ansible_home(), GLOBALS_PATH) self.global_props = [] self.unique_global_props = {} self.unique_override_flags = {} self.group_props = {} self.host_props = {} self.properties_loaded = False self._inventory = None
# 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 os import sys from kolla_cli.common import utils kolla_ansible_source_base = '../kolla-ansible' kolla_ansible_home_target = utils.get_kolla_ansible_home() kolla_ansible_etc_target = utils.get_kolla_etc() ansible = 'ansible' kolla = 'kolla' kolla_cli = 'kolla-cli' tools = 'tools' def setup_ansible_etc(): # if the kolla-cli directory for the inventory doesn't exist # already then make it. this will also create the directory the # globals and password file goes into cli_etc_dir = os.path.join(kolla_ansible_etc_target, kolla_cli, ansible) if not os.path.exists(cli_etc_dir): make_cli_etc_dir_cmd = ('mkdir -p %s' % cli_etc_dir)
def _properties_test(self, groups=[], hosts=[]): switch = '' if groups: switch = '--groups' dir_name = 'group_vars' elif hosts: switch = '--hosts' dir_name = 'host_vars' key = 'TeStKeY' value = 'TeStVaLuE:123:abc' # initialize keys targets_csv = '' targets = groups + hosts if 'all' in groups: inv = Inventory.load() targets = inv.get_groupnames() targets_csv = 'all' elif 'all' in hosts: inv = Inventory.load() targets = inv.get_hostnames() targets_csv = 'all' comma = '' sizes = {} # key = path, value = [size1, size2, etc] for target in targets: self.run_cli_cmd('property clear %s %s %s' % (switch, target, key)) if targets_csv != 'all': targets_csv += comma + target comma = ',' path = os.path.join(get_kolla_ansible_home(), 'ansible', dir_name, target) sizes[path] = [os.path.getsize(path)] if not switch: self.run_cli_cmd('property clear %s' % key) path = os.path.join(get_kolla_ansible_home(), 'ansible/group_vars/__GLOBAL__') sizes[path] = [os.path.getsize(path)] # test append self.run_cli_cmd('property set %s %s %s %s' % (switch, targets_csv, key, value)) if switch: msg = self.run_cli_cmd('property list -f json %s all' % (switch)) else: msg = self.run_cli_cmd('property list -f json') err_msg = self._check_property_values(key, value, msg, targets) self.assertEqual( err_msg, '', 'set failed property not in output: %s, %s (%s %s)' % (key, value, switch, targets_csv)) bad_path = self._is_size_ok(sizes, 0, '<', 1) self.assertIsNone( bad_path, 'Size of file %s did not ' % bad_path + 'increase after append (%s %s)' % (switch, targets_csv)) # test modify existing value += '2' self.run_cli_cmd('property set %s %s %s %s' % (switch, targets_csv, key, value)) msg = self.run_cli_cmd('property list --all -f json %s %s' % (switch, targets_csv)) err_msg = self._check_property_values(key, value, msg, targets) self.assertEqual( err_msg, '', 'set failed property not in output: %s, %s (%s %s)' % (key, value, switch, targets_csv)) bad_path = self._is_size_ok(sizes, 1, '<', 2) self.assertIsNone( bad_path, 'Size of file %s did not ' % bad_path + 'increase after modify (%s %s)' % (switch, targets_csv)) # test clear self.run_cli_cmd('property clear %s %s %s' % (switch, targets_csv, key)) msg = self.run_cli_cmd('property list --long -f json %s %s' % (switch, targets_csv)) err_msg = self._check_property_values(key, value, msg, targets) self.assertTrue( 'missing' in err_msg, 'clear failed, property still in output: ' + '%s, %s (%s %s)' % (key, value, switch, targets_csv)) bad_path = self._is_size_ok(sizes, 0, '=', 3) self.assertIsNone( bad_path, 'Size of file %s is ' % bad_path + 'different from initial size ' '(%s %s %s)' % (switch, targets_csv, str(sizes))) # test setting empty string value = '""' self.run_cli_cmd('property set %s %s %s %s' % (switch, targets_csv, key, value)) msg = self.run_cli_cmd('property list --all -f json %s %s' % (switch, targets_csv)) err_msg = self._check_property_values(key, value, msg, targets) self.assertTrue( 'missing' in err_msg, 'clear failed, property still in output: ' + '%s, %s (%s %s)' % (key, value, switch, targets_csv)) self.run_cli_cmd('property clear %s %s %s' % (switch, targets_csv, key))
def _load(self, inventory_path): """load an ansible inventory file Note: This assumes that there will be a blank line between each section: # Mistral [mistral-api:children] mistral [mistral-executor:children] mistral """ if not inventory_path: inventory_path = os.path.join(get_kolla_ansible_home(), 'ansible', 'inventory', 'all-in-one') with open(inventory_path, 'r') as ain1: ain1_inv = ain1.read() lines = [x for x in ain1_inv.split('\n') if not x.startswith('#')] for i in range(0, len(lines)): line = lines[i] if not line.startswith('['): continue line.strip() if ':vars' in line: # this is defining a set of group vars in the next set # of lines. groupname = line.split(':')[0] i = self._process_group_vars(groupname, lines, i) continue if ':children' not in line: groupname = line[1:len(line) - 1] self.add_group(groupname) continue servicename = line.split(':children')[0] servicename = servicename[1:] service = self.add_service(servicename) # next lines will be parents or groups for service found above has_parents_or_groups = False while True: i += 1 line = lines[i] parent_or_group = line.strip() if parent_or_group.startswith('#'): # comment line, skip continue if not parent_or_group: # blank line, done processing parents # if a service has no parent or group associations # we infer that it is not supported and is filtered # from being shown to the client service.set_supported(has_parents_or_groups) break if parent_or_group in self.groups: service.add_groupname(parent_or_group) has_parents_or_groups = True else: service.add_parentname(parent_or_group) has_parents_or_groups = True for _, service in self.services.items(): for parentname in service.get_parentnames(): parent = self.services[parentname] if parent: parent.add_childname(service.name)