def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): # the group_by module does not need to pay attention to check mode. # it always runs. args = {} if complex_args: args.update(complex_args) args.update(parse_kv(self.runner.module_args)) if not 'key' in args: raise ae("'key' is a required argument.") vv("created 'group_by' ActionModule: key=%s" % (args['key'])) inventory = self.runner.inventory result = {'changed': False} ### find all groups groups = {} for host in self.runner.host_set: data = inject['hostvars'][host] if not check_conditional( template.template(self.runner.basedir, self.runner.conditional, data)): continue group_name = template.template(self.runner.basedir, args['key'], data) group_name = group_name.replace(' ', '-') if group_name not in groups: groups[group_name] = [] groups[group_name].append(host) result['groups'] = groups ### add to inventory for group, hosts in groups.items(): inv_group = inventory.get_group(group) if not inv_group: inv_group = ansible.inventory.Group(name=group) inventory.add_group(inv_group) for host in hosts: del self.runner.inventory._vars_per_host[host] inv_host = inventory.get_host(host) if not inv_host: inv_host = ansible.inventory.Host(name=host) if inv_group not in inv_host.get_groups(): result['changed'] = True inv_group.add_host(inv_host) return ReturnData(conn=conn, comm_ok=True, result=result)
def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): ''' transfer & execute a module that is not 'copy' or 'template' ''' # 传输并执行一个模块,除了“copy”和“template”模块 module_args = self.runner._complex_args_hack(complex_args, module_args) if self.runner.noop_on_check(inject): if module_name in [ 'shell', 'command' ]: return ReturnData(conn=conn, comm_ok=True, result=dict(skipped=True, msg='check mode not supported for %s' % module_name)) # else let the module parsing code decide, though this will only be allowed for AnsibleModuleCommon using # python modules for now module_args += " CHECKMODE=True" if self.runner.no_log: module_args += " NO_LOG=True" # shell and command are the same module if module_name == 'shell': module_name = 'command' module_args += " #USE_SHELL" if self.runner.no_log: module_display_args = "(no_log enabled, args censored)" else: module_display_args = module_args vv("REMOTE_MODULE %s %s" % (module_name, module_display_args), host=conn.host) return self.runner._execute_module(conn, tmp, module_name, module_args, inject=inject, complex_args=complex_args)
def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): ''' transfer & execute a module that is not 'copy' or 'template' ''' module_args = self.runner._complex_args_hack(complex_args, module_args) if self.runner.noop_on_check(inject): if module_name in [ 'shell', 'command' ]: return ReturnData(conn=conn, comm_ok=True, result=dict(skipped=True, msg='check mode not supported for %s' % module_name)) # else let the module parsing code decide, though this will only be allowed for AnsibleModuleCommon using # python modules for now module_args += " CHECKMODE=True" if self.runner.no_log: module_args += " NO_LOG=True" # shell and command are the same module if module_name == 'shell': module_name = 'command' module_args += " #USE_SHELL" if self.runner.no_log: module_display_args = "(no_log enabled, args censored)" else: module_display_args = module_args vv("REMOTE_MODULE %s %s" % (module_name, module_display_args), host=conn.host) return self.runner._execute_module(conn, tmp, module_name, module_args, inject=inject, complex_args=complex_args)
def run(self): # Work out the hosts to run on. if this.task is None or this.task.run_once_per is None: return old_run(self) per_expr = "{{" + this.task.run_once_per + "}}" # Evaluate that expression per current host. groups = collections.defaultdict(list) if not self.run_hosts: self.run_hosts = self.inventory.list_hosts(self.pattern) hosts = self.run_hosts if len(hosts) == 0: return old_run(self) for host in hosts: inject = self.get_inject_vars(host) value = template.template(self.basedir, per_expr, inject, fail_on_undefined=True) vvv("evaluating {} for {} and got {!r}".format( per_expr, host, value)) groups[value].append(host) vv("run_once_per for each of {!r}".format(groups)) try: self.run_hosts = [groups[value][0] for value in groups] return old_run(self) finally: self.run_hosts = hosts
def run(self, conn, tmp, module_name, module_args, inject): args = parse_kv(module_args) if not 'hostname' in args: raise ae("'hostname' is a required argument.") vv("created 'add_host' ActionModule: hostname=%s" % (args['hostname'])) result = {'changed': True} new_host = Host(args['hostname']) inventory = self.runner.inventory # add the new host to the 'all' group allgroup = inventory.get_group('all') allgroup.add_host(new_host) result['changed'] = True # add it to the group if that was specified if 'groupname' in args: if not inventory.get_group(args['groupname']): new_group = Group(args['groupname']) inventory.add_group(new_group) ngobj = inventory.get_group(args['groupname']) ngobj.add_host(new_host) vv("created 'add_host' ActionModule: groupname=%s" % (args['groupname'])) result['new_group'] = args['groupname'] result['new_host'] = args['hostname'] return ReturnData(conn=conn, comm_ok=True, result=result)
def create_docker_compose_file(self): """ Create the role's docker-compose file. """ vv("creating: docker-compose configuration file for '{}'".format( self.role, )) module = TemplateModule(self.runner) with NamedTemporaryFile() as template_file: # Create a template file for the YAML data template_file.write("{{ data|to_nice_yaml }}\n") template_file.flush() # Use the template module to create the file from YAML data. module_args = "src={} dest={}".format( template_file.name, self.docker_compose_file, ) module_inject = self.inject.copy() module_inject["data"] = self.data module_response = module.run( self.conn, self.tmp, "template", module_args, inject=module_inject, ) return self.handle_module_result(module_response.result)
def run(self, conn, tmp, module_name, module_args, inject): args = parse_kv(module_args) if not "hostname" in args: raise ae("'hostname' is a required argument.") vv("created 'add_host' ActionModule: hostname=%s" % (args["hostname"])) result = {"changed": True} new_host = Host(args["hostname"]) inventory = self.runner.inventory # add the new host to the 'all' group allgroup = inventory.get_group("all") allgroup.add_host(new_host) result["changed"] = True # add it to the group if that was specified if "groupname" in args: if not inventory.get_group(args["groupname"]): new_group = Group(args["groupname"]) inventory.add_group(new_group) ngobj = inventory.get_group(args["groupname"]) ngobj.add_host(new_host) vv("created 'add_host' ActionModule: groupname=%s" % (args["groupname"])) result["new_group"] = args["groupname"] result["new_host"] = args["hostname"] return ReturnData(conn=conn, comm_ok=True, result=result)
def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): # the group_by module does not need to pay attention to check mode. # it always runs. args = {} if complex_args: args.update(complex_args) args.update(parse_kv(self.runner.module_args)) if not 'key' in args: raise ae("'key' is a required argument.") vv("created 'group_by' ActionModule: key=%s"%(args['key'])) inventory = self.runner.inventory result = {'changed': False} ### find all groups groups = {} for host in self.runner.host_set: data = {} data.update(inject) data.update(inject['hostvars'][host]) conds = self.runner.conditional if type(conds) != list: conds = [ conds ] next_host = False for cond in conds: if not check_conditional(cond, self.runner.basedir, data, fail_on_undefined=self.runner.error_on_undefined_vars): next_host = True break if next_host: continue group_name = template.template(self.runner.basedir, args['key'], data) group_name = group_name.replace(' ','-') if group_name not in groups: groups[group_name] = [] groups[group_name].append(host) result['groups'] = groups ### add to inventory for group, hosts in groups.items(): inv_group = inventory.get_group(group) if not inv_group: inv_group = ansible.inventory.Group(name=group) inventory.add_group(inv_group) for host in hosts: del self.runner.inventory._vars_per_host[host] inv_host = inventory.get_host(host) if not inv_host: inv_host = ansible.inventory.Host(name=host) if inv_group not in inv_host.get_groups(): result['changed'] = True inv_group.add_host(inv_host) return ReturnData(conn=conn, comm_ok=True, result=result)
def remove_docker_compose_file(self): """ Remove the role's docker-compose file. """ vv("removing: docker-compose configuration file for '{}'".format( self.role, )) module_args = "path={} state=absent".format(self.docker_compose_file, ) return self.execute_module("file", module_args)
def remove_docker_compose_containers(self): """ Remove containers using docker-compose. """ vv("removing: docker-compose containers for '{}'".format(self.role, )) module_args = "path={} state=absent force=true".format( self.docker_compose_file, ) return self.execute_module("docker-compose", module_args)
def remove_images(self): vv("removing: docker images for '{}'".format(self.role, )) module_args = "state={}".format(self.images_state, ) return self.execute_module( "docker-images", module_args, complex_args=dict(images=self.images), )
def remove_docker_compose_configuration_directory(self): """ Remove directory for role-specific docker-compose.yml files. """ vv("removing: docker-compose configuration directory for '{}'".format( self.role)) module_args = "path={} state=absent".format( self.docker_compose_directory, ) return self.execute_module("file", module_args)
def has_docker_compose_file(self): """ Does the role's docker-compose file exist? """ vv("checking: docker-compose configuration file for '{}'".format( self.role, )) module_args = "path={}".format(self.docker_compose_file, ) result = self.execute_module("stat", module_args) return result["stat"]["exists"]
def run(self, conn, tmp, module_name, module_args, inject): ''' transfer & execute a module that is not 'copy' or 'template' ''' # shell and command are the same module if module_name == 'shell': module_name = 'command' module_args += " #USE_SHELL" vv("REMOTE_MODULE %s %s" % (module_name, module_args), host=conn.host) return self.runner._execute_module(conn, tmp, module_name, module_args, inject=inject)
def remove_docker_compose_containers(self): """ Remove containers using docker-compose. """ vv("removing: docker-compose containers for '{}'".format( self.role, )) module_args = "path={} state=absent force=true".format( self.docker_compose_file, ) return self.execute_module("docker-compose", module_args)
def remove_docker_compose_file(self): """ Remove the role's docker-compose file. """ vv("removing: docker-compose configuration file for '{}'".format( self.role, )) module_args = "path={} state=absent".format( self.docker_compose_file, ) return self.execute_module("file", module_args)
def remove_docker_compose_configuration_directory(self): """ Remove directory for role-specific docker-compose.yml files. """ vv("removing: docker-compose configuration directory for '{}'".format( self.role )) module_args = "path={} state=absent".format( self.docker_compose_directory, ) return self.execute_module("file", module_args)
def pull_images(self): """ Pull docker images. """ vv("pulling: docker images for '{}'".format(self.role, )) module_args = "state={}".format(self.images_state, ) return self.execute_module( "docker-images", module_args, complex_args=dict(images=self.images), )
def has_docker_compose_file(self): """ Does the role's docker-compose file exist? """ vv("checking: docker-compose configuration file for '{}'".format( self.role, )) module_args = "path={}".format( self.docker_compose_file, ) result = self.execute_module("stat", module_args) return result["stat"]["exists"]
def _list_objects(self, type, path): vv("Reading %s from SD" % type) changed = False allgroup = self.runner.inventory.get_group('all') allvariables = allgroup.get_variables() if not allvariables.has_key('_serverdensity_' + type): changed = True objects = self._request(path) allgroup.set_variable('_serverdensity_' + type, objects) else: objects = allvariables.get('_serverdensity_' + type) return changed, objects
def create_docker_compose_configuration_directory(self): """ Create directory for role-specific docker-compose.yml files. Each role's compose file lives in `/etc/docker-compose/<role>/` for clarity and to support container recreation outside of Ansible. """ vv("creating: docker-compose configuration directory for '{}'".format( self.role, )) module_args = "path={} state=directory".format( self.docker_compose_directory, ) return self.execute_module("file", module_args)
def remove_images(self): vv("removing: docker images for '{}'".format( self.role, )) module_args = "state={}".format( self.images_state, ) return self.execute_module( "docker-images", module_args, complex_args=dict(images=self.images), )
def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): if self.runner.check: return ReturnData(conn=conn, comm_ok=True, result=dict(skipped=True, msg='check mode not supported for this module')) args = {} if complex_args: args.update(complex_args) args.update(parse_kv(module_args)) if not 'hostname' in args and not 'name' in args: raise ae("'name' is a required argument.") result = {} # Parse out any hostname:port patterns new_name = args.get('name', args.get('hostname', None)) vv("creating host via 'add_host': hostname=%s" % new_name) if ":" in new_name: new_name, new_port = new_name.split(":") args['ansible_ssh_port'] = new_port # create host and get inventory new_host = Host(new_name) inventory = self.runner.inventory # Add any variables to the new_host for k in args.keys(): if not k in [ 'name', 'hostname', 'groupname', 'groups' ]: new_host.set_variable(k, args[k]) # add the new host to the 'all' group allgroup = inventory.get_group('all') allgroup.add_host(new_host) groupnames = args.get('groupname', args.get('groups', '')) # add it to the group if that was specified if groupnames != '': for group_name in groupnames.split(","): if not inventory.get_group(group_name): new_group = Group(group_name) inventory.add_group(new_group) grp = inventory.get_group(group_name) grp.add_host(new_host) vv("added host to group via add_host module: %s" % group_name) result['new_groups'] = groupnames.split(",") result['new_host'] = new_name return ReturnData(conn=conn, comm_ok=True, result=result)
def pull_images(self): """ Pull docker images. """ vv("pulling: docker images for '{}'".format( self.role, )) module_args = "state={}".format( self.images_state, ) return self.execute_module( "docker-images", module_args, complex_args=dict(images=self.images), )
def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): vv("Kind of verbose") vvv("Verbose") vvvv("Lookout!") vvvvv("Super custom verbosity") return ReturnData(conn=conn, comm_ok=True, result={ "failed": False, "changed": False })
def create_docker_compose_containers(self): """ Create containers using docker-compose. Containers will be forcibly recreated if the state is "restarted". Note that docker-compose will recreate containers even if the state is "started" if it detects a change to the image or configuration data. In the event that recreation needs to be suppressed, docker-compose must be told explicilty NOT to recreate containers. This behavior is not supported at this time. """ vv("creating: docker-compose containers for '{}'".format(self.role)) module_args = "path={} state=started force={}".format( self.docker_compose_file, "true" if self.containers_state in (RESTARTED, ) else "false", ) return self.execute_module("docker-compose", module_args)
def create_docker_compose_containers(self): """ Create containers using docker-compose. Containers will be forcibly recreated if the state is "restarted". Note that docker-compose will recreate containers even if the state is "started" if it detects a change to the image or configuration data. In the event that recreation needs to be suppressed, docker-compose must be told explicilty NOT to recreate containers. This behavior is not supported at this time. """ vv("creating: docker-compose containers for '{}'".format( self.role )) module_args = "path={} state=started force={}".format( self.docker_compose_file, "true" if self.containers_state in (RESTARTED,) else "false", ) return self.execute_module("docker-compose", module_args)
def run(self, conn, tmp, module_name, module_args, inject): args = parse_kv(self.runner.module_args) if not 'key' in args: raise ae("'key' is a required argument.") vv("created 'group_by' ActionModule: key=%s"%(args['key'])) inventory = self.runner.inventory result = {'changed': False} ### find all groups groups = {} for host in self.runner.host_set: data = inject['hostvars'][host] if not check_conditional(template(self.runner.basedir, self.runner.conditional, data)): continue group_name = template(self.runner.basedir, args['key'], data) group_name = group_name.replace(' ','-') if group_name not in groups: groups[group_name] = [] groups[group_name].append(host) result['groups'] = groups ### add to inventory for group, hosts in groups.items(): inv_group = inventory.get_group(group) if not inv_group: inv_group = ansible.inventory.Group(name=group) inventory.add_group(inv_group) for host in hosts: inv_host = inventory.get_host(host) if not inv_host: inv_host = ansible.inventory.Host(name=host) if inv_group not in inv_host.get_groups(): result['changed'] = True inv_group.add_host(inv_host) return ReturnData(conn=conn, comm_ok=True, result=result)
def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): # the group_by module does not need to pay attention to check mode. # it always runs. args = {} if complex_args: args.update(complex_args) args.update(parse_kv(self.runner.module_args)) if not 'key' in args: raise ae("'key' is a required argument.") vv("created 'group_by' ActionModule: key=%s"%(args['key'])) inventory = self.runner.inventory result = {'changed': False} ### find all groups groups = {} for host in self.runner.host_set:
def run(self, conn, tmp, module_name, module_args, inject): args = parse_kv(self.runner.module_args) if not 'key' in args: raise ae("'key' is a required argument.") vv("created 'group_by' ActionModule: key=%s" % (args['key'])) inventory = self.runner.inventory result = {'changed': False} ### find all groups groups = {} for host in self.runner.host_set: data = inject['hostvars'][host] group_name = template(self.runner.basedir, args['key'], data) group_name = group_name.replace(' ', '-') if group_name not in groups: groups[group_name] = [] groups[group_name].append(host) result['groups'] = groups ### add to inventory for group, hosts in groups.items(): inv_group = inventory.get_group(group) if not inv_group: inv_group = ansible.inventory.Group(name=group) inventory.add_group(inv_group) for host in hosts: inv_host = inventory.get_host(host) if not inv_host: inv_host = ansible.inventory.Host(name=host) if inv_group not in inv_host.get_groups(): result['changed'] = True inv_group.add_host(inv_host) return ReturnData(conn=conn, comm_ok=True, result=result)
def run(self, conn, tmp, module_name, module_args, inject): ''' run the pause actionmodule ''' args = self.runner.module_args hosts = ', '.join(map(lambda x: x[1], self.runner.host_set)) (self.pause_type, sep, pause_params) = args.partition('=') if self.pause_type == '': self.pause_type = 'prompt' elif not self.pause_type in self.PAUSE_TYPES: raise ae("invalid parameter for pause, '%s'. must be one of: %s" % \ (self.pause_type, ", ".join(self.PAUSE_TYPES))) # error checking if self.pause_type in ['minutes', 'seconds']: try: int(pause_params) except ValueError: raise ae("value given to %s parameter invalid: '%s', must be an integer" % \ self.pause_type, pause_params) # The time() command operates in seconds so we need to # recalculate for minutes=X values. if self.pause_type == 'minutes': self.seconds = int(pause_params) * 60 elif self.pause_type == 'seconds': self.seconds = int(pause_params) self.duration_unit = 'seconds' else: # if no args are given we pause with a prompt if pause_params == '': self.prompt = "[%s]\nPress enter to continue: " % hosts else: self.prompt = "[%s]\n%s: " % (hosts, pause_params) vv("created 'pause' ActionModule: pause_type=%s, duration_unit=%s, calculated_seconds=%s, prompt=%s" % \ (self.pause_type, self.duration_unit, self.seconds, self.prompt)) try: self._start() if not self.pause_type == 'prompt': print "[%s]\nPausing for %s seconds" % (hosts, self.seconds) time.sleep(self.seconds) else: # Clear out any unflushed buffered input which would # otherwise be consumed by raw_input() prematurely. tcflush(sys.stdin, TCIFLUSH) raw_input(self.prompt) except KeyboardInterrupt: while True: print '\nAction? (a)bort/(c)ontinue: ' c = getch() if c == 'c': # continue playbook evaluation break elif c == 'a': # abort further playbook evaluation raise ae('user requested abort!') finally: self._stop() return ReturnData(conn=conn, result=self.result)
def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): if self.runner.noop_on_check(inject): return ReturnData( conn=conn, comm_ok=True, result=dict(skipped=True, msg='check mode not supported for this module')) args = {} if complex_args: args.update(complex_args) args.update(parse_kv(module_args)) if not 'hostname' in args and not 'name' in args: raise ae("'name' is a required argument.") result = {} # Parse out any hostname:port patterns new_name = args.get('name', args.get('hostname', None)) vv("creating host via 'add_host': hostname=%s" % new_name) if ":" in new_name: new_name, new_port = new_name.split(":") args['ansible_ssh_port'] = new_port # redefine inventory and get group "all" inventory = self.runner.inventory allgroup = inventory.get_group('all') # check if host in cache, add if not if new_name in inventory._hosts_cache: new_host = inventory._hosts_cache[new_name] else: new_host = Host(new_name) # only groups can be added directly to inventory inventory._hosts_cache[new_name] = new_host allgroup.add_host(new_host) # Add any variables to the new_host for k in args.keys(): if not k in ['name', 'hostname', 'groupname', 'groups']: new_host.set_variable(k, args[k]) groupnames = args.get('groupname', args.get('groups', args.get('group', ''))) # add it to the group if that was specified if groupnames != '': for group_name in groupnames.split(","): group_name = group_name.strip() if not inventory.get_group(group_name): new_group = Group(group_name) inventory.add_group(new_group) grp = inventory.get_group(group_name) grp.add_host(new_host) # add this host to the group cache if inventory._groups_list is not None: if group_name in inventory._groups_list: if new_host.name not in inventory._groups_list[ group_name]: inventory._groups_list[group_name].append( new_host.name) vv("added host to group via add_host module: %s" % group_name) result['new_groups'] = groupnames.split(",") result['new_host'] = new_name # clear pattern caching completely since it's unpredictable what # patterns may have referenced the group inventory.clear_pattern_cache() return ReturnData(conn=conn, comm_ok=True, result=result)
# Code for do until feature until = self.module_vars.get('until', None) if until is not None and result.comm_ok: inject[self.module_vars.get('register')] = result.result cond = template.template(self.basedir, until, inject, expand_lists=False) if not utils.check_conditional(cond, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars): retries = self.module_vars.get('retries') delay = self.module_vars.get('delay') for x in range(1, retries + 1): time.sleep(delay) tmp = '' if getattr(handler, 'NEEDS_TMPPATH', True): tmp = self._make_tmp_path(conn) result = handler.run(conn, tmp, module_name, module_args, inject, complex_args) result.result['attempts'] = x vv("Result from run %i is: %s" % (x, result.result)) inject[self.module_vars.get('register')] = result.result cond = template.template(self.basedir, until, inject, expand_lists=False) if utils.check_conditional(cond, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars): break if result.result['attempts'] == retries and not utils.check_conditional(cond, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars): result.result['failed'] = True result.result['msg'] = "Task failed as maximum retries was encountered" else: result.result['attempts'] = 0 conn.close() if not result.comm_ok: # connection or parsing errors... self.callbacks.on_unreachable(host, result.result) else:
inject[self.module_vars.get('register')] = result.result cond = template.template(self.basedir, until, inject, expand_lists=False) if not utils.check_conditional(cond, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars): retries = self.module_vars.get('retries') delay = self.module_vars.get('delay') for x in range(1, int(retries) + 1): # template the delay, cast to float and sleep delay = template.template(self.basedir, delay, inject, expand_lists=False) delay = float(delay) time.sleep(delay) tmp = '' if self._early_needs_tmp_path(module_name, handler): tmp = self._make_tmp_path(conn) result = handler.run(conn, tmp, module_name, module_args, inject, complex_args) result.result['attempts'] = x vv("Result from run %i is: %s" % (x, result.result)) inject[self.module_vars.get('register')] = result.result cond = template.template(self.basedir, until, inject, expand_lists=False) if utils.check_conditional(cond, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars): break if result.result['attempts'] == retries and not utils.check_conditional(cond, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars): result.result['failed'] = True result.result['msg'] = "Task failed as maximum retries was encountered" else: result.result['attempts'] = 0 conn.close() if not result.comm_ok: # connection or parsing errors... self.callbacks.on_unreachable(host, result.result) else:
def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): if self.runner.noop_on_check(inject): return ReturnData(conn=conn, comm_ok=True, result=dict(skipped=True, msg='check mode not supported for this module')) args = {} if complex_args: args.update(complex_args) args.update(parse_kv(module_args)) if not 'hostname' in args and not 'name' in args: raise ae("'name' is a required argument.") result = {} # Parse out any hostname:port patterns new_name = args.get('name', args.get('hostname', None)) vv("creating host via 'add_host': hostname=%s" % new_name) if ":" in new_name: new_name, new_port = new_name.split(":") args['ansible_ssh_port'] = new_port # redefine inventory and get group "all" inventory = self.runner.inventory allgroup = inventory.get_group('all') # check if host in cache, add if not if new_name in inventory._hosts_cache: new_host = inventory._hosts_cache[new_name] else: new_host = Host(new_name) # only groups can be added directly to inventory inventory._hosts_cache[new_name] = new_host allgroup.add_host(new_host) # Add any variables to the new_host for k in args.keys(): if not k in [ 'name', 'hostname', 'groupname', 'groups' ]: new_host.set_variable(k, args[k]) groupnames = args.get('groupname', args.get('groups', args.get('group', ''))) # add it to the group if that was specified if groupnames != '': for group_name in groupnames.split(","): group_name = group_name.strip() if not inventory.get_group(group_name): new_group = Group(group_name) inventory.add_group(new_group) grp = inventory.get_group(group_name) grp.add_host(new_host) # add this host to the group cache if inventory._groups_list is not None: if group_name in inventory._groups_list: if new_host.name not in inventory._groups_list[group_name]: inventory._groups_list[group_name].append(new_host.name) vv("added host to group via add_host module: %s" % group_name) result['new_groups'] = groupnames.split(",") result['new_host'] = new_name # clear pattern caching completely since it's unpredictable what # patterns may have referenced the group inventory.clear_pattern_cache() return ReturnData(conn=conn, comm_ok=True, result=result)
def materialize_results(self, dest, resultant, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): ''' Place resultant in-memory output string text "resultant" at target destination dir "dest" in target file "resultant_basename". ''' dest = os.path.abspath(os.path.expanduser(dest)) (dest_path, dest_basename) = os.path.split(dest) # ensure dest directory exists vv("ensuring ssh config target directory {0} exists".format(dest_path)) file_module_args = dict( path=dest_path, state="directory", ) if self.runner.noop_on_check(inject): file_module_args['CHECKMODE'] = True file_module_args = utils.merge_module_args("", file_module_args) res = self.runner._execute_module(conn, tmp, 'file', file_module_args, inject=inject, delete_remote_tmp=False) # compare resultant string with current contents of destination vv("comparing checksums") local_checksum = utils.checksum_s(resultant) remote_checksum = self.runner._remote_checksum(conn, tmp, dest, inject) if local_checksum != remote_checksum: # template is different from the remote value vv("checksums differ") # if showing diffs, we need to get the remote value dest_contents = '' if self.runner.diff: # using persist_files to keep the temp directory around to avoid needing to grab another dest_result = self.runner._execute_module(conn, tmp, 'slurp', "path=%s" % dest, inject=inject, persist_files=True) if 'content' in dest_result.result: dest_contents = dest_result.result['content'] if dest_result.result['encoding'] == 'base64': dest_contents = base64.b64decode(dest_contents) else: raise Exception("unknown encoding, failed: %s" % dest_result.result) vv("transfering {0}, {1}, {2}, {3}".format(conn, tmp, 'source', resultant)) xfered = self.runner._transfer_str(conn, tmp, 'source', resultant) vv("transfer successful!!") # fix file permissions when the copy is done as a different user # ansible pre-1.9.4 uses "sudo" & "sudo_user" or "su" & "su_user" sudo_18 = getattr(self.runner, "sudo", False) su_18 = getattr(self.runner, "su", False) # ansible 1.9.4-1 uses "become" & "become_user" become_1941 = getattr(self.runner, "become", False) if sudo_18 and self.runner.sudo_user != 'root' or su_18 and self.runner.su_user != 'root' or become_1941 and self.runner.become_user != 'root': self.runner._remote_chmod(conn, 'a+r', xfered, tmp) # run the copy module vv("running copy module") new_module_args = dict( src=xfered, dest=dest, original_basename=dest_basename, follow=True, ) module_args_tmp = utils.merge_module_args(module_args, new_module_args) res = self.runner._execute_module(conn, tmp, 'copy', module_args_tmp, inject=inject, delete_remote_tmp=False, complex_args=None) if res.result.get('changed', False): res.diff = dict(before=dest_contents, after=resultant) return res else: vv("checksums match, using file module to fix up file parameters") # when running the file module based on the template data, we do # not want the source filename (the name of the template) to be used, # since this would mess up links, so we clear the src param and tell # the module to follow links. When doing that, we have to set # original_basename to the template just in case the dest is # a directory. new_module_args = dict( src=None, dest=dest, original_basename=dest_basename, follow=True, ) # be sure to inject the check mode param into the module args and # rely on the file module to report its changed status if self.runner.noop_on_check(inject): new_module_args['CHECKMODE'] = True file_module_args = utils.merge_module_args(module_args, new_module_args) file_module_complex_args = complex_args for stripkey in ["identity_file", "user", "bastion_user"]: if stripkey in file_module_complex_args: del file_module_complex_args[ stripkey] # not supported or needed by file module return self.runner._execute_module( conn, tmp, 'file', file_module_args, inject=inject, delete_remote_tmp=False, complex_args=file_module_complex_args)
raise ae("non-integer value given for prompt duration:\n%s" % str(e)) # Is 'prompt' a key in 'args'? elif 'prompt' in args: self.pause_type = 'prompt' self.prompt = "[%s]\n%s:\n" % (hosts, args['prompt']) # Is 'args' empty, then this is the default prompted pause elif len(args.keys()) == 0: self.pause_type = 'prompt' self.prompt = "[%s]\nPress enter to continue:\n" % hosts # I have no idea what you're trying to do. But it's so wrong. else: raise ae("invalid pause type given. must be one of: %s" % \ ", ".join(self.PAUSE_TYPES)) vv("created 'pause' ActionModule: pause_type=%s, duration_unit=%s, calculated_seconds=%s, prompt=%s" % \ (self.pause_type, self.duration_unit, self.seconds, self.prompt)) ######################################################################## # Begin the hard work! try: self._start() if not self.pause_type == 'prompt': print "[%s]\nPausing for %s seconds" % (hosts, self.seconds) time.sleep(self.seconds) else: # Clear out any unflushed buffered input which would # otherwise be consumed by raw_input() prematurely. tcflush(sys.stdin, TCIFLUSH) self.result['user_input'] = raw_input( self.prompt.encode(sys.stdout.encoding)) except KeyboardInterrupt:
def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): try: args = {} if complex_args: args.update(complex_args) args.update(parse_kv(module_args)) # get starting credentials # from environment: # AWS_ACCESS_KEY_ID # AWS_SECRET_ACCESS_KEY # use get started credentials to do the roles dance and obtain # temporary credentials in target account #target_role_name = 'init-test3-shoppertrak-NucleatorCageBuilder-1I5ZOAYRJLS8Z' data = {} data.update(inject) # TODO use nucleator facts instead source_role_name = data[ 'nucleator_builder_role_name'] # TODO - RHS var here could have names in better alignment with current conventions target_role_name = data[ 'cage_builder_role_name'] # TODO - RHS var here could have names in better alignment with current conventions print "Target Role Name: ", target_role_name print "Source Role Name: ", source_role_name source_account_id = data['source_account_number'] target_account_id = data['target_account_number'] print "Target Account Number: ", target_account_id print "Source Account Number: ", source_account_id try: envdict = {} if self.runner.environment: env = template.template(self.runner.basedir, self.runner.environment, inject, convert_bare=True) env = utils.safe_eval(env) aws_access_key_id = env.get("AWS_ACCESS_KEY_ID") aws_secret_access_key = env.get("AWS_SECRET_ACCESS_KEY") security_token = env.get("AWS_SECURITY_TOKEN") aws_access_key_id = aws_access_key_id if aws_access_key_id else None aws_secret_access_key = aws_secret_access_key if aws_secret_access_key else None security_token = security_token if security_token else None sts_connection = STSConnection( aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key, security_token=security_token) source_role = sts_connection.assume_role( role_arn='arn:aws:iam::{0}:role/{1}'.format( source_account_id, source_role_name), role_session_name='SourceRoleSession') vv("Successfully assumed {0} role in account {1}".format( source_role_name, source_account_id)) except Exception, e: result = dict( failed=True, msg=type(e).__name__ + ": Failed to obtain temporary credentials for role " + source_role_name + " in target account " + source_account_id + ", message: '" + str(e)) return ReturnData(conn=conn, comm_ok=False, result=result) try: sts_connection = STSConnection( aws_access_key_id=source_role.credentials.access_key, aws_secret_access_key=source_role.credentials.secret_key, security_token=source_role.credentials.session_token) target_role = sts_connection.assume_role( role_arn='arn:aws:iam::{0}:role/{1}'.format( target_account_id, target_role_name), role_session_name='TargetRoleSession') vv("Successfully assumed {0} role in account {1}".format( target_role_name, target_account_id)) except Exception, e: # deal with failure gracefully result = dict( failed=True, msg=type(e).__name__ + ": Failed to obtain temporary credentials for role " + target_role_name + " in target account " + target_account_id + ", message: '" + str(e) + " Security_Token: " + source_role.credentials.session_token) return ReturnData(conn=conn, comm_ok=False, result=result)
def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): """ Run the action. *module_args* (``str``) contains the action arguments when passed as a string. E.g., .. code-block:: yaml - expr: eval=... *inject* (``dict``) contains the current set of Ansible variables. *complex_args* (``dict``) contains the action arguments when passed as a dictionary. E.g.,:: .. code-block:: yaml - expr: eval: ... Returns the result of the action (``ansible.runner.return_data.ReturnData``). """ if self.runner.noop_on_check(inject): # Skip this action in check mode. return ReturnData(conn=conn, result={'skipped': True}) # Load arguments. args = {} args.update(utils.parse_kv(module_args)) if complex_args is not None: args.update(complex_args) # The local context the expression will be evaluated in. local = {} # Import specified modules. imports = args.get('imports') if imports is not None: try: imports = self._parse_imports(imports) except Exception as e: vv(traceback.format_exc()) return ReturnData(conn=conn, result={'failed': True, 'imports': imports, 'msg': "Invalid imports: {}".format(e)}) try: imports = self._import_modules(imports) except Exception as e: vv(traceback.format_exc()) return ReturnData(conn=conn, result={'failed': True, 'imports': imports, 'msg': "Import error: {}".format(e)}) local.update(imports) # Expose specified variables. vars = args.get('vars') if vars is not None: try: local.update(vars) except Exception as e: vv(traceback.format_exc()) return ReturnData(conn=conn, result={'failed': True, 'vars': vars, 'msg': "Invalid vars: {}".format(e)}) # Get command. if 'eval' in args and 'exec' in args: return ReturnData(conn=conn, result={'failed': True, 'eval': args['eval'], 'exec': args['exec'], 'msg': "eval and exec are mutually exclusive."}) elif 'eval' in args: key = 'eval' # Evaluate expression. expr = args['eval'] try: result = eval(expr, inject, local) except Exception as e: vv(traceback.format_exc()) return ReturnData(conn=conn, result={'failed': True, 'eval': expr, 'msg': "Eval error: {}".format(e)}) elif 'exec' in args: key = 'exec' # Get return expression. returns = args.get('returns') if returns is None: return ReturnData(conn=conn, result={'failed': True, 'msg': "returns is required for exec."}) # Execute statements. expr = args['exec'] try: exec(expr, inject, local) except Exception as e: vv(traceback.format_exc()) return ReturnData(conn=conn, result={'failed': True, 'exec': expr, 'msg': "Exec error: {}".format(e)}) # Get return value. try: result = eval(returns, inject, local) except Exception as e: vv(traceback.format_exc()) return ReturnData(conn=conn, result={'failed': True, 'returns': returns, 'msg': "Return error: {}".format(e)}) # Returns the action result. return ReturnData(conn=conn, result={'failed': False, 'changed': False, key: result})
except ValueError, e: raise ae("non-integer value given for prompt duration:\n%s" % str(e)) # Is 'prompt' a key in 'args'? elif 'prompt' in args: self.pause_type = 'prompt' self.prompt = "[%s]\n%s:\n" % (hosts, args['prompt']) # Is 'args' empty, then this is the default prompted pause elif len(args.keys()) == 0: self.pause_type = 'prompt' self.prompt = "[%s]\nPress enter to continue:\n" % hosts # I have no idea what you're trying to do. But it's so wrong. else: raise ae("invalid pause type given. must be one of: %s" % \ ", ".join(self.PAUSE_TYPES)) vv("created 'pause' ActionModule: pause_type=%s, duration_unit=%s, calculated_seconds=%s, prompt=%s" % \ (self.pause_type, self.duration_unit, self.seconds, self.prompt)) ######################################################################## # Begin the hard work! try: self._start() if not self.pause_type == 'prompt': print "[%s]\nPausing for %s seconds" % (hosts, self.seconds) time.sleep(self.seconds) else: # Clear out any unflushed buffered input which would # otherwise be consumed by raw_input() prematurely. tcflush(sys.stdin, TCIFLUSH) self.result['user_input'] = raw_input(self.prompt.encode(sys.stdout.encoding)) except KeyboardInterrupt: while True:
def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): if self.runner.noop_on_check(inject): return ReturnData(conn=conn, comm_ok=True, result=dict(skipped=True, msg='check mode not supported for this module')) args = {} if complex_args: args.update(complex_args) args.update(parse_kv(module_args)) if not 'api_token' in args: raise ae("'api_token' is a required argument.") self.api_token = args.get('api_token') self.force_update = args.get('force', False) self.cache_file_name = args.get('cache', False) cleanup = args.get('cleanup', False) just_download = args.get('readonly', False) if just_download: self.force_update = False self.cache_file_name = tempfile.mktemp(prefix='sd_', suffix='.json') cleanup = False result = {} self.list_all() if just_download: vv('Downloaded settings to %s' % self.cache_file_name) return ReturnData(conn=conn, comm_ok=True, result=result) services = {} devicegroup_alerts = {} servicegroup_alerts = {} vv('Ensure hosts...') for host in self.runner.host_set: vv('- ' + host) host_vars = self.runner.inventory.get_variables(host) facts = host_vars.get('ansible_facts', {}) location = host_vars.get('location') if not location: location = {} host_services = host_vars.get('sd_services') if host_services: for host_service in host_services: name = host_service.get('name') if not services.has_key(name): services.__setitem__(name, host_service) host_group = host_vars.get('sd_group') if not host_group: host_group = 'All others' host_devicegroup_alerts = host_vars.get('sd_devicegroup_alerts') if host_devicegroup_alerts: for name in host_devicegroup_alerts: host_devicegroup_alert = host_devicegroup_alerts.get(name) if not devicegroup_alerts.has_key(host_group): devicegroup_alerts.__setitem__(host_group, {}) alerts = devicegroup_alerts.get(host_group) if not alerts.has_key(name): alerts.__setitem__(name, host_devicegroup_alert) devicegroup_alerts.__setitem__(host_group, alerts) host_servicegroup_alerts = host_vars.get('sd_servicegroup_alerts') if host_servicegroup_alerts: for name in host_servicegroup_alerts: if not servicegroup_alerts.has_key(name): host_servicegroup_alert = host_servicegroup_alerts.get(name) servicegroup_alerts.__setitem__(name, host_servicegroup_alert) self.ensure_host( cpuCores=facts.get('ansible_processor_count', None), group=host_group, hostname=host, installedRAM=facts.get('ansible_memtotal_mb', None), name=host, os={ 'code': facts.get('ansible_system', '')+' '+facts.get('ansible_distribution', '')+' '+facts.get('ansible_distribution_release', '')+' '+facts.get('ansible_distribution_version', ''), 'name': facts.get('ansible_system', ''), }, # privateIPs=facts[''], # privateDNS=facts[''], publicIPs=facts.get('ansible_all_ipv4_addresses', '')+facts.get('ansible_all_ipv6_addresses', ''), # publicDNS=facts[''], swapSpace=facts.get('ansible_swaptotal_mb', None), location={ 'countryCode': location.get('countryCode'), 'countryName': location.get('countryName'), 'text': location.get('text'), }, provider=host_vars.get('provider') ) alerts = host_vars.get('sd_alerts') if alerts: vv('- - Ensure device alerts...') for alertname in alerts: vv('- - - ' + alertname) alert = alerts.get(alertname) alert.__setitem__('host', host) self.ensure_alert(alert, 'device') vv('Ensure device group alerts...') for groupname in devicegroup_alerts: vv('- ' + groupname) group_alerts = devicegroup_alerts.get(groupname) for alertname in group_alerts: vv('- - ' + alertname) alert = group_alerts.get(alertname) self.ensure_alert(alert, 'deviceGroup', groupname) vv('Ensure services...') for servicename in services: vv('- ' + servicename) service = services.get(servicename) self.ensure_service(servicename, service) alerts = service.get('alerts') if alerts: vv('- - Ensure service alerts...') for alertname in alerts: vv('- - - ' + alertname) alert = alerts.get(alertname) alert.__setitem__('service', service.get('name')) self.ensure_alert(alert, 'service') vv('Ensure service group alerts...') for servicegroupname in servicegroup_alerts: vv('- ' + servicegroupname) alert = servicegroup_alerts.get(servicegroupname) groupname = alert.get('group') self.ensure_alert(alert, 'serviceGroup', groupname) if cleanup: vv('Cleanup unused alerts...') self.cleanup_alerts() vv('Completed successfully!') return ReturnData(conn=conn, comm_ok=True, result=result)
def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): # the group_by module does not need to pay attention to check mode. # it always runs. # module_args and complex_args have already been templated for the first host. # Use them here only to check that a key argument is provided. args = {} if complex_args: args.update(complex_args) args.update(parse_kv(module_args)) if not 'key' in args: raise ae("'key' is a required argument.") vv("created 'group_by' ActionModule: key=%s" % (args['key'])) inventory = self.runner.inventory result = {'changed': False} ### find all groups groups = {} for host in self.runner.host_set: data = {} data.update(inject) data.update(inject['hostvars'][host]) conds = self.runner.conditional if type(conds) != list: conds = [conds] next_host = False for cond in conds: if not check_conditional( cond, self.runner.basedir, data, fail_on_undefined=self.runner.error_on_undefined_vars): next_host = True break if next_host: continue # Template original module_args and complex_args from runner for each host. host_module_args = template.template(self.runner.basedir, self.runner.module_args, data) host_complex_args = template.template(self.runner.basedir, self.runner.complex_args, data) host_args = {} if host_complex_args: host_args.update(host_complex_args) host_args.update(parse_kv(host_module_args)) group_name = host_args['key'] group_name = group_name.replace(' ', '-') if group_name not in groups: groups[group_name] = [] groups[group_name].append(host) result['groups'] = groups ### add to inventory for group, hosts in groups.items(): inv_group = inventory.get_group(group) if not inv_group: inv_group = ansible.inventory.Group(name=group) inventory.add_group(inv_group) for host in hosts: if host in self.runner.inventory._vars_per_host: del self.runner.inventory._vars_per_host[host] inv_host = inventory.get_host(host) if not inv_host: inv_host = ansible.inventory.Host(name=host) if inv_group not in inv_host.get_groups(): result['changed'] = True inv_group.add_host(inv_host) return ReturnData(conn=conn, comm_ok=True, result=result)
def run(self, conn, tmp, module_name, module_args, inject, complex_args=None, **kwargs): # the group_by module does not need to pay attention to check mode. # it always runs. # module_args and complex_args have already been templated for the first host. # Use them here only to check that a key argument is provided. args = {} if complex_args: args.update(complex_args) args.update(parse_kv(module_args)) if not 'key' in args: raise ae("'key' is a required argument.") vv("created 'group_by' ActionModule: key=%s"%(args['key'])) inventory = self.runner.inventory result = {'changed': False} ### find all groups groups = {} for host in self.runner.host_set: data = {} data.update(inject) data.update(inject['hostvars'][host]) conds = self.runner.conditional if type(conds) != list: conds = [ conds ] next_host = False for cond in conds: if not check_conditional(cond, self.runner.basedir, data, fail_on_undefined=self.runner.error_on_undefined_vars): next_host = True break if next_host: continue # Template original module_args and complex_args from runner for each host. host_module_args = template.template(self.runner.basedir, self.runner.module_args, data) host_complex_args = template.template(self.runner.basedir, self.runner.complex_args, data) host_args = {} if host_complex_args: host_args.update(host_complex_args) host_args.update(parse_kv(host_module_args)) group_name = host_args['key'] group_name = group_name.replace(' ','-') if group_name not in groups: groups[group_name] = [] groups[group_name].append(host) result['groups'] = groups ### add to inventory for group, hosts in groups.items(): inv_group = inventory.get_group(group) if not inv_group: inv_group = ansible.inventory.Group(name=group) inventory.add_group(inv_group) inventory.get_group('all').add_child_group(inv_group) inv_group.vars = inventory.get_group_variables(group, update_cached=False, vault_password=inventory._vault_password) for host in hosts: if host in self.runner.inventory._vars_per_host: del self.runner.inventory._vars_per_host[host] inv_host = inventory.get_host(host) if not inv_host: inv_host = ansible.inventory.Host(name=host) if inv_group not in inv_host.get_groups(): result['changed'] = True inv_group.add_host(inv_host) return ReturnData(conn=conn, comm_ok=True, result=result)