def render(jp_data, saltenv='base', sls='', **kws): ''' Accepts Java Properties as a string or as a file object and runs it through the jproperties parser. Uses the jproperties package https://pypi.python.org/pypi/jproperties so please "pip install jproperties" to use this renderer. Returns a flat dictionary by default: {'some.java.thing': 'whatever'} If using a 'shebang' "#!jproperties" header on the first line, an argument can be optionally supplied as a key to contain a dictionary of the rendered properties (ie. "#!jproperties foo"): {'foo': {'some.java.thing': 'whatever'}} :rtype: A Python data structure ''' if not isinstance(jp_data, string_types): jp_data = jp_data.read() container = False if jp_data.startswith('#!'): args = jp_data[:jp_data.find('\n')].split() if len(args) >= 2: container = args[1] jp_data = jp_data[(jp_data.find('\n') + 1):] if not jp_data.strip(): return {} properties = jp() properties.load(jp_data) if container: return {container: dict([(k, properties[k]) for k in six.iterkeys(properties)])} else: return dict([(k, properties[k]) for k in six.iterkeys(properties)])
def test_kill(self): def spin(): salt.utils.appendproctitle('test_kill') while True: time.sleep(1) process_manager = salt.utils.process.ProcessManager() process_manager.add_process(spin) initial_pid = next(six.iterkeys(process_manager._process_map)) # kill the child os.kill(initial_pid, signal.SIGKILL) # give the OS time to give the signal... time.sleep(0.1) process_manager.check_children() try: assert initial_pid != next(six.iterkeys(process_manager._process_map)) finally: process_manager.stop_restarting() process_manager.kill_children() time.sleep(0.5) # Are there child processes still running? if process_manager._process_map.keys(): process_manager.send_signal_to_processes(signal.SIGKILL) process_manager.stop_restarting() process_manager.kill_children()
def __call_cli(jboss_config, command, retries=1): command_segments = [ jboss_config['cli_path'], '--connect', '--controller="{0}"'.format(jboss_config['controller']) ] if 'cli_user' in six.iterkeys(jboss_config): command_segments.append('--user="{0}"'.format(jboss_config['cli_user'])) if 'cli_password' in six.iterkeys(jboss_config): command_segments.append('--password="{0}"'.format(jboss_config['cli_password'])) command_segments.append('--command="{0}"'.format(__escape_command(command))) cli_script = ' '.join(command_segments) cli_command_result = __salt__['cmd.run_all'](cli_script) log.debug('cli_command_result=%s', str(cli_command_result)) log.debug('========= STDOUT:\n%s', cli_command_result['stdout']) log.debug('========= STDERR:\n%s', cli_command_result['stderr']) log.debug('========= RETCODE: %d', cli_command_result['retcode']) if cli_command_result['retcode'] == 127: raise CommandExecutionError('Could not execute jboss-cli.sh script. Have you specified server_dir variable correctly?\nCurrent CLI path: {cli_path}. '.format(cli_path=jboss_config['cli_path'])) if cli_command_result['retcode'] == 1 and 'Unable to authenticate against controller' in cli_command_result['stderr']: raise CommandExecutionError('Could not authenticate against controller, please check username and password for the management console. Err code: {retcode}, stdout: {stdout}, stderr: {stderr}'.format(**cli_command_result)) # It may happen that eventhough server is up it may not respond to the call if cli_command_result['retcode'] == 1 and 'JBAS012144' in cli_command_result['stderr'] and retries > 0: # Cannot connect to cli log.debug('Command failed, retrying... (%d tries left)', retries) time.sleep(3) return __call_cli(jboss_config, command, retries - 1) return cli_command_result
def table_find(table_to_find): ''' Finds the schema in which the given table is present CLI Example:: salt '*' drizzle.table_find table_name ''' # Initializing the required variables ret_val = {} count = 1 drizzle_db = _connect() cursor = drizzle_db.cursor() # Finding the schema schema = schemas() for schema_iter in six.iterkeys(schema): table = tables(schema[schema_iter]) for table_iter in six.iterkeys(table): if table[table_iter] == table_to_find: ret_val[count] = schema[schema_iter] count = count+1 cursor.close() drizzle_db.close() return ret_val
def SetIncludes(self, includes): if includes: for inc in includes: value = inc[next(six.iterkeys(inc))] include = next(six.iterkeys(inc)) self.SetInclude(include, value) log.debug('was asked to set {0} to {1}'.format(include, value))
def test_cmd_call(self): result = self.HIGHSTATE.state.call_template_str( textwrap.dedent( """\ #!pydsl state('A').cmd.run('echo this is state A', cwd='/') some_var = 12345 def do_something(a, b, *args, **kws): return dict(result=True, changes={'a': a, 'b': b, 'args': args, 'kws': kws, 'some_var': some_var}) state('C').cmd.call(do_something, 1, 2, 3, x=1, y=2) \ .require(state('A').cmd) state('G').cmd.wait('echo this is state G', cwd='/') \ .watch(state('C').cmd) """ ) ) ret = next(result[k] for k in six.iterkeys(result) if "do_something" in k) changes = ret["changes"] self.assertEqual(changes, dict(a=1, b=2, args=(3,), kws=dict(x=1, y=2), some_var=12345)) ret = next(result[k] for k in six.iterkeys(result) if "-G_" in k) self.assertEqual(ret["changes"]["stdout"], "this is state G")
def list_upgrades(jid, style="group", outputter="nested", ext_source=None): """ Show list of available pkg upgrades using a specified format style CLI Example: .. code-block:: bash salt-run pkg.list_upgrades jid=20141120114114417719 style=group """ mminion = salt.minion.MasterMinion(__opts__) returner = _get_returner((__opts__["ext_job_cache"], ext_source, __opts__["master_job_cache"])) data = mminion.returners["{0}.get_jid".format(returner)](jid) pkgs = {} if style == "group": for minion in data: results = data[minion]["return"] for pkg, pkgver in six.iteritems(results): if pkg not in six.iterkeys(pkgs): pkgs[pkg] = {pkgver: {"hosts": []}} if pkgver not in six.iterkeys(pkgs[pkg]): pkgs[pkg].update({pkgver: {"hosts": []}}) pkgs[pkg][pkgver]["hosts"].append(minion) if outputter: salt.output.display_output(pkgs, outputter, opts=__opts__) return pkgs
def stages_iter(self): ''' Return an iterator that yields the state call data as it is processed ''' def yielder(gen_ret): if (not isinstance(gen_ret, list) and not isinstance(gen_ret, dict) and hasattr(gen_ret, 'next')): for sub_ret in gen_ret: for yret in yielder(sub_ret): yield yret else: yield gen_ret self.over_run = {} yield self.over for comp in self.over: name = next(six.iterkeys(comp)) stage = comp[name] if name not in self.over_run: v_stage = self.verify_stage(stage) if isinstance(v_stage, list): yield [comp] yield v_stage else: for sret in self.call_stage(name, stage): for yret in yielder(sret): sname = next(six.iterkeys(yret)) yield [self.get_stage(sname)] final = {} for minion in yret[sname]: final[minion] = yret[sname][minion]['ret'] yield final
def test_basic(self): ''' Make sure that the process is alive 2s later ''' def spin(): salt.utils.appendproctitle('test_basic') while True: time.sleep(1) process_manager = salt.utils.process.ProcessManager() process_manager.add_process(spin) initial_pid = next(six.iterkeys(process_manager._process_map)) time.sleep(2) process_manager.check_children() try: assert initial_pid == next(six.iterkeys(process_manager._process_map)) finally: process_manager.stop_restarting() process_manager.kill_children() time.sleep(0.5) # Are there child processes still running? if process_manager._process_map.keys(): process_manager.send_signal_to_processes(signal.SIGKILL) process_manager.stop_restarting() process_manager.kill_children()
def user_role_add(user_id=None, user=None, tenant_id=None, tenant=None, role_id=None, role=None, profile=None, project_id=None, project_name=None, **connection_args): ''' Add role for user in tenant (keystone user-role-add) CLI Examples: .. code-block:: bash salt '*' keystone.user_role_add \ user_id=298ce377245c4ec9b70e1c639c89e654 \ tenant_id=7167a092ece84bae8cead4bf9d15bb3b \ role_id=ce377245c4ec9b70e1c639c89e8cead4 salt '*' keystone.user_role_add user=admin tenant=admin role=admin ''' kstone = auth(profile, **connection_args) if project_id and not tenant_id: tenant_id = project_id elif project_name and not tenant: tenant = project_name if user: user_id = user_get(name=user, profile=profile, **connection_args)[user].get('id') else: user = next(six.iterkeys(user_get(user_id, profile=profile, **connection_args)))['name'] if not user_id: return {'Error': 'Unable to resolve user id'} if tenant: tenant_id = tenant_get(name=tenant, profile=profile, **connection_args)[tenant].get('id') else: tenant = next(six.iterkeys(tenant_get(tenant_id, profile=profile, **connection_args)))['name'] if not tenant_id: return {'Error': 'Unable to resolve tenant/project id'} if role: role_id = role_get(name=role, profile=profile, **connection_args)[role]['id'] else: role = next(six.iterkeys(role_get(role_id, profile=profile, **connection_args)))['name'] if not role_id: return {'Error': 'Unable to resolve role id'} if _OS_IDENTITY_API_VERSION > 2: kstone.roles.grant(role_id, user=user_id, project=tenant_id) else: kstone.roles.add_user_role(user_id, role_id, tenant_id) ret_msg = '"{0}" role added for user "{1}" for "{2}" tenant/project' return ret_msg.format(role, user, tenant)
def test_restarting(self): ''' Make sure that the process is alive 2s later ''' def die(): time.sleep(1) process_manager = salt.utils.process.ProcessManager() process_manager.add_process(die) initial_pid = next(six.iterkeys(process_manager._process_map)) time.sleep(2) process_manager.check_children() assert initial_pid != next(six.iterkeys(process_manager._process_map)) process_manager.kill_children()
def test_kill(self): def spin(): while True: time.sleep(1) process_manager = salt.utils.process.ProcessManager() process_manager.add_process(spin) initial_pid = next(six.iterkeys(process_manager._process_map)) # kill the child os.kill(initial_pid, signal.SIGTERM) # give the OS time to give the signal... time.sleep(0.1) process_manager.check_children() assert initial_pid != next(six.iterkeys(process_manager._process_map)) process_manager.kill_children()
def test_basic(self): ''' Make sure that the process is alive 2s later ''' def spin(): while True: time.sleep(1) process_manager = salt.utils.process.ProcessManager() process_manager.add_process(spin) initial_pid = next(six.iterkeys(process_manager._process_map)) time.sleep(2) process_manager.check_children() assert initial_pid == next(six.iterkeys(process_manager._process_map)) process_manager.kill_children()
def purge(name, delete_key=True): ''' Destroy the named vm ''' ret = {} client = salt.client.get_local_client(__opts__['conf_file']) data = vm_info(name, quiet=True) if not data: __jid_event__.fire_event({'error': 'Failed to find vm {0} to purge'.format(name)}, 'progress') return 'fail' hyper = next(six.iterkeys(data)) try: cmd_ret = client.cmd_iter( hyper, 'virt.purge', [name, True], timeout=600) except SaltClientError as client_error: return 'Virtual machine {0} could not be purged: {1}'.format(name, client_error) for comp in cmd_ret: ret.update(comp) if delete_key: skey = salt.key.Key(__opts__) skey.delete_key(name) __jid_event__.fire_event({'message': 'Purged VM {0}'.format(name)}, 'progress') return 'good'
def force_off(name): ''' Force power down the named virtual machine ''' ret = {} client = salt.client.get_local_client(__opts__['conf_file']) data = vm_info(name, quiet=True) if not data: print('Failed to find vm {0} to destroy'.format(name)) return 'fail' hyper = next(six.iterkeys(data)) if data[hyper][name]['state'] == 'shutdown': print('VM {0} is already shutdown'.format(name)) return'bad state' try: cmd_ret = client.cmd_iter( hyper, 'virt.destroy', [name], timeout=600) except SaltClientError as client_error: return 'Virtual machine {0} could not be forced off: {1}'.format(name, client_error) for comp in cmd_ret: ret.update(comp) __jid_event__.fire_event({'message': 'Powered off VM {0}'.format(name)}, 'progress') return 'good'
def start(name): ''' Start a named virtual machine ''' ret = {} client = salt.client.get_local_client(__opts__['conf_file']) data = vm_info(name, quiet=True) if not data: __jid_event__.fire_event({'message': 'Failed to find vm {0} to start'.format(name)}, 'progress') return 'fail' hyper = next(six.iterkeys(data)) if data[hyper][name]['state'] == 'running': print('VM {0} is already running'.format(name)) return 'bad state' try: cmd_ret = client.cmd_iter( hyper, 'virt.start', [name], timeout=600) except SaltClientError as client_error: return 'Virtual machine {0} not started: {1}'. format(name, client_error) for comp in cmd_ret: ret.update(comp) __jid_event__.fire_event({'message': 'Started VM {0}'.format(name)}, 'progress') return 'good'
def pause(name): ''' Pause the named VM ''' ret = {} client = salt.client.get_local_client(__opts__['conf_file']) data = vm_info(name, quiet=True) if not data: __jid_event__.fire_event({'error': 'Failed to find VM {0} to pause'.format(name)}, 'progress') return 'fail' host = next(six.iterkeys(data)) if data[host][name]['state'] == 'paused': __jid_event__.fire_event({'error': 'VM {0} is already paused'.format(name)}, 'progress') return 'bad state' try: cmd_ret = client.cmd_iter( host, 'virt.pause', [name], timeout=600) except SaltClientError as client_error: return 'Virtual machine {0} could not be pasued: {1}'.format(name, client_error) for comp in cmd_ret: ret.update(comp) __jid_event__.fire_event({'message': 'Paused VM {0}'.format(name)}, 'progress') return 'good'
def list_renderers(*args): """ List the renderers loaded on the minion .. versionadded:: 2015.5.0 CLI Example: .. code-block:: bash salt '*' sys.list_renderers Render names can be specified as globs. .. code-block:: bash salt '*' sys.list_renderers 'yaml*' """ ren_ = salt.loader.render(__opts__, []) ren = set() if not args: for func in six.iterkeys(ren_): ren.add(func) return sorted(ren) for module in args: for func in fnmatch.filter(ren_, module): ren.add(func) return sorted(ren)
def attrs(self): kwargs = self.kwargs # handle our requisites for attr in REQUISITES: if attr in kwargs: # our requisites should all be lists, but when you only have a # single item it's more convenient to provide it without # wrapping it in a list. transform them into a list if not isinstance(kwargs[attr], list): kwargs[attr] = [kwargs[attr]] # rebuild the requisite list transforming any of the actual # StateRequisite objects into their representative dict kwargs[attr] = [ req() if isinstance(req, StateRequisite) else req for req in kwargs[attr] ] # build our attrs from kwargs. we sort the kwargs by key so that we # have consistent ordering for tests return [ {k: kwargs[k]} for k in sorted(six.iterkeys(kwargs)) ]
def _list_iter(host=None, path=None): ''' Return a generator iterating over hosts path path to the container parent default: /var/lib/lxc (system default) .. versionadded:: Beryllium ''' tgt = host or '*' client = salt.client.get_local_client(__opts__['conf_file']) for container_info in client.cmd_iter( tgt, 'lxc.list', kwarg={'path': path} ): if not container_info: continue if not isinstance(container_info, dict): continue chunk = {} id_ = next(six.iterkeys(container_info)) if host and host != id_: continue if not isinstance(container_info[id_], dict): continue if 'ret' not in container_info[id_]: continue if not isinstance(container_info[id_]['ret'], dict): continue chunk[id_] = container_info[id_]['ret'] yield chunk
def avail_images(call=None): ''' Return a list of the images that are on the provider ''' if call == 'action': raise SaltCloudSystemExit( 'The avail_images function must be called with ' '-f or --function, or with the --list-images option' ) fetch = True page = 1 ret = {} while fetch: items = query(method='images', command='?page=' + str(page) + '&per_page=200') for image in items['images']: ret[image['name']] = {} for item in six.iterkeys(image): ret[image['name']][item] = image[item] page += 1 try: fetch = 'next' in items['links']['pages'] except KeyError: fetch = False return ret
def _execute_pillar(pillar_name, run_type): ''' Run one or more nagios plugins from pillar data and get the result of run_type The pillar have to be in this format: ------ webserver: Ping_google: - check_icmp: 8.8.8.8 - check_icmp: google.com Load: - check_load: -w 0.8 -c 1 APT: - check_apt ------- ''' groups = __salt__['pillar.get'](pillar_name) data = {} for group in groups: data[group] = {} commands = groups[group] for command in commands: # Check if is a dict to get the arguments # in command if not set the arguments to empty string if isinstance(command, dict): plugin = next(six.iterkeys(command)) args = command[plugin] else: plugin = command args = '' command_key = _format_dict_key(args, plugin) data[group][command_key] = run_type(plugin, args) return data
def _expand_one_key_dictionary(_dict): ''' Returns the only one key and it's value from a dictionary. ''' key = next(six.iterkeys(_dict)) value = _dict[key] return key, value
def destroy(self, linger=5000): if self.cpub is True and self.sub.closed is False: # Wait at most 2.5 secs to send any remaining messages in the # socket or the context.term() below will hang indefinitely. # See https://github.com/zeromq/pyzmq/issues/102 self.sub.close() if self.cpush is True and self.push.closed is False: self.push.close() # If sockets are not unregistered from a poller, nothing which touches # that poller gets garbage collected. The Poller itself, its # registered sockets and the Context if isinstance(self.poller.sockets, dict): for socket in six.iterkeys(self.poller.sockets): if socket.closed is False: socket.setsockopt(zmq.LINGER, linger) socket.close() self.poller.unregister(socket) else: for socket in self.poller.sockets: if socket[0].closed is False: socket[0].setsockopt(zmq.LINGER, linger) socket[0].close() self.poller.unregister(socket[0]) if self.context.closed is False: self.context.term() # Hardcore destruction if hasattr(self.context, 'destroy'): self.context.destroy(linger=1) # https://github.com/zeromq/pyzmq/issues/173#issuecomment-4037083 # Assertion failed: get_load () == 0 (poller_base.cpp:32) time.sleep(0.025)
def _sanatize_network_params(self, kwargs): """ Sanatize novaclient network parameters """ params = [ "label", "bridge", "bridge_interface", "cidr", "cidr_v6", "dns1", "dns2", "fixed_cidr", "gateway", "gateway_v6", "multi_host", "priority", "project_id", "vlan_start", "vpn_start", ] for variable in six.iterkeys(kwargs): # iterate over a copy, we might delete some if variable not in params: del kwargs[variable] return kwargs
def __gather_minions(self): ''' Return a list of minions to use for the batch run ''' args = [self.opts['tgt'], 'test.ping', [], self.opts['timeout'], ] selected_target_option = self.opts.get('selected_target_option', None) if selected_target_option is not None: args.append(selected_target_option) else: args.append(self.opts.get('expr_form', 'glob')) ping_gen = self.local.cmd_iter(*args, **self.eauth) fret = set() try: for ret in ping_gen: m = next(six.iterkeys(ret)) if m is not None: fret.add(m) return (list(fret), ping_gen) except StopIteration: raise salt.exceptions.SaltClientError('No minions matched the target.')
def resume(name): ''' Resume a paused vm ''' ret = {} client = salt.client.get_local_client(__opts__['conf_file']) data = vm_info(name, quiet=True) if not data: __jid_event__.fire_event({'error': 'Failed to find VM {0} to pause'.format(name)}, 'progress') return 'not found' hyper = next(six.iterkeys(data)) if data[hyper][name]['state'] != 'paused': __jid_event__.fire_event({'error': 'VM {0} is not paused'.format(name)}, 'progress') return 'bad state' try: cmd_ret = client.cmd_iter( hyper, 'virt.resume', [name], timeout=600) except SaltClientError as client_error: return 'Virtual machine {0} could not be resumed: {1}'.format(name, client_error) for comp in cmd_ret: ret.update(comp) __jid_event__.fire_event({'message': 'Resumed VM {0}'.format(name)}, 'progress') return 'good'
def list_keypairs(call=None): ''' Return a dict of all available VM locations on the cloud provider with relevant data ''' if call != 'function': log.error( 'The list_keypairs function must be called with -f or --function.' ) return False items = query(method='account/keys') ret = {} for key_pair in items['ssh_keys']: name = key_pair['name'] if name in ret: raise SaltCloudSystemExit( 'A duplicate key pair name, \'{0}\', was found in DigitalOcean\'s ' 'key pair list. Please change the key name stored by DigitalOcean. ' 'Be sure to adjust the value of \'ssh_key_file\' in your cloud ' 'profile or provider configuration, if necessary.'.format( name ) ) ret[name] = {} for item in six.iterkeys(key_pair): ret[name][item] = str(key_pair[item]) return ret
def spec_check(self, auth_list, fun, form): ''' Check special API permissions ''' if form != 'cloud': comps = fun.split('.') if len(comps) != 2: return False mod = comps[0] fun = comps[1] else: mod = fun for ind in auth_list: if isinstance(ind, six.string_types): if ind.startswith('@') and ind[1:] == mod: return True if ind == '@{0}'.format(form): return True if ind == '@{0}s'.format(form): return True elif isinstance(ind, dict): if len(ind) != 1: continue valid = next(six.iterkeys(ind)) if valid.startswith('@') and valid[1:] == mod: if isinstance(ind[valid], six.string_types): if self.match_check(ind[valid], fun): return True elif isinstance(ind[valid], list): for regex in ind[valid]: if self.match_check(regex, fun): return True return False
def config(name, config, edit=True): ''' Create VirtualHost configuration files name File for the virtual host config VirtualHost configurations .. note:: This function is not meant to be used from the command line. Config is meant to be an ordered dict of all of the apache configs. CLI Example: .. code-block:: bash salt '*' apache.config /etc/httpd/conf.d/ports.conf config="[{'Listen': '22'}]" ''' for entry in config: key = next(six.iterkeys(entry)) configs = _parse_config(entry[key], key) if edit: with salt.utils.fopen(name, 'w') as configfile: configfile.write('# This file is managed by saltstack.\n') configfile.write(configs) return configs