示例#1
0
class Base(FieldAttributeBase):

    _name = FieldAttribute(isa='string',
                           default='',
                           always_post_validate=True,
                           inherit=False)

    # connection/transport
    _connection = FieldAttribute(
        isa='string', default=context.cliargs_deferred_get('connection'))
    _port = FieldAttribute(isa='int')
    _remote_user = FieldAttribute(
        isa='string', default=context.cliargs_deferred_get('remote_user'))

    # variables
    _vars = FieldAttribute(isa='dict',
                           priority=100,
                           inherit=False,
                           static=True)

    # module default params
    _module_defaults = FieldAttribute(isa='list', extend=True, prepend=True)

    # flags and misc. settings
    _environment = FieldAttribute(isa='list', extend=True, prepend=True)
    _no_log = FieldAttribute(isa='bool')
    _run_once = FieldAttribute(isa='bool')
    _ignore_errors = FieldAttribute(isa='bool')
    _ignore_unreachable = FieldAttribute(isa='bool')
    _check_mode = FieldAttribute(isa='bool',
                                 default=context.cliargs_deferred_get('check'))
    _diff = FieldAttribute(isa='bool',
                           default=context.cliargs_deferred_get('diff'))
    _any_errors_fatal = FieldAttribute(isa='bool', default=C.ANY_ERRORS_FATAL)

    # explicitly invoke a debugger on tasks
    _debugger = FieldAttribute(isa='string')

    # param names which have been deprecated/removed
    DEPRECATED_ATTRIBUTES = [
        'sudo',
        'sudo_user',
        'sudo_pass',
        'sudo_exe',
        'sudo_flags',
        'su',
        'su_user',
        'su_pass',
        'su_exe',
        'su_flags',
    ]
示例#2
0
class Base(FieldAttributeBase):

    _name = FieldAttribute(isa='string',
                           default='',
                           always_post_validate=True,
                           inherit=False)

    # connection/transport
    _connection = FieldAttribute(
        isa='string', default=context.cliargs_deferred_get('connection'))
    _port = FieldAttribute(isa='int')
    _remote_user = FieldAttribute(
        isa='string', default=context.cliargs_deferred_get('remote_user'))

    # variables
    _vars = FieldAttribute(isa='dict',
                           priority=100,
                           inherit=False,
                           static=True)

    # module default params
    _module_defaults = FieldAttribute(isa='list', extend=True, prepend=True)

    # flags and misc. settings
    _environment = FieldAttribute(isa='list', extend=True, prepend=True)
    _no_log = FieldAttribute(isa='bool')
    _run_once = FieldAttribute(isa='bool')
    _ignore_errors = FieldAttribute(isa='bool')
    _ignore_unreachable = FieldAttribute(isa='bool')
    _check_mode = FieldAttribute(isa='bool',
                                 default=context.cliargs_deferred_get('check'))
    _diff = FieldAttribute(isa='bool',
                           default=context.cliargs_deferred_get('diff'))
    _any_errors_fatal = FieldAttribute(isa='bool', default=C.ANY_ERRORS_FATAL)
    _throttle = FieldAttribute(isa='int', default=0)
    _timeout = FieldAttribute(isa='int', default=C.TASK_TIMEOUT)

    # explicitly invoke a debugger on tasks
    _debugger = FieldAttribute(isa='string')

    # Privilege escalation
    _become = FieldAttribute(isa='bool',
                             default=context.cliargs_deferred_get('become'))
    _become_method = FieldAttribute(
        isa='string', default=context.cliargs_deferred_get('become_method'))
    _become_user = FieldAttribute(
        isa='string', default=context.cliargs_deferred_get('become_user'))
    _become_flags = FieldAttribute(
        isa='string', default=context.cliargs_deferred_get('become_flags'))
    _become_exe = FieldAttribute(
        isa='string', default=context.cliargs_deferred_get('become_exe'))

    # used to hold sudo/su stuff
    DEPRECATED_ATTRIBUTES = []
示例#3
0
文件: base.py 项目: phy1729/ansible
class Base(FieldAttributeBase):

    name = NonInheritableFieldAttribute(isa='string', default='', always_post_validate=True)

    # connection/transport
    connection = ConnectionFieldAttribute(isa='string', default=context.cliargs_deferred_get('connection'))
    port = FieldAttribute(isa='int')
    remote_user = FieldAttribute(isa='string', default=context.cliargs_deferred_get('remote_user'))

    # variables
    vars = NonInheritableFieldAttribute(isa='dict', priority=100, static=True)

    # module default params
    module_defaults = FieldAttribute(isa='list', extend=True, prepend=True)

    # flags and misc. settings
    environment = FieldAttribute(isa='list', extend=True, prepend=True)
    no_log = FieldAttribute(isa='bool')
    run_once = FieldAttribute(isa='bool')
    ignore_errors = FieldAttribute(isa='bool')
    ignore_unreachable = FieldAttribute(isa='bool')
    check_mode = FieldAttribute(isa='bool', default=context.cliargs_deferred_get('check'))
    diff = FieldAttribute(isa='bool', default=context.cliargs_deferred_get('diff'))
    any_errors_fatal = FieldAttribute(isa='bool', default=C.ANY_ERRORS_FATAL)
    throttle = FieldAttribute(isa='int', default=0)
    timeout = FieldAttribute(isa='int', default=C.TASK_TIMEOUT)

    # explicitly invoke a debugger on tasks
    debugger = FieldAttribute(isa='string')

    # Privilege escalation
    become = FieldAttribute(isa='bool', default=context.cliargs_deferred_get('become'))
    become_method = FieldAttribute(isa='string', default=context.cliargs_deferred_get('become_method'))
    become_user = FieldAttribute(isa='string', default=context.cliargs_deferred_get('become_user'))
    become_flags = FieldAttribute(isa='string', default=context.cliargs_deferred_get('become_flags'))
    become_exe = FieldAttribute(isa='string', default=context.cliargs_deferred_get('become_exe'))

    # used to hold sudo/su stuff
    DEPRECATED_ATTRIBUTES = []  # type: list[str]

    def get_path(self):
        ''' return the absolute path of the playbook object and its line number '''

        path = ""
        try:
            path = "%s:%s" % (self._ds._data_source, self._ds._line_number)
        except AttributeError:
            try:
                path = "%s:%s" % (self._parent._play._ds._data_source, self._parent._play._ds._line_number)
            except AttributeError:
                pass
        return path

    def get_dep_chain(self):

        if hasattr(self, '_parent') and self._parent:
            return self._parent.get_dep_chain()
        else:
            return None

    def get_search_path(self):
        '''
        Return the list of paths you should search for files, in order.
        This follows role/playbook dependency chain.
        '''
        path_stack = []

        dep_chain = self.get_dep_chain()
        # inside role: add the dependency chain from current to dependent
        if dep_chain:
            path_stack.extend(reversed([x._role_path for x in dep_chain if hasattr(x, '_role_path')]))

        # add path of task itself, unless it is already in the list
        task_dir = os.path.dirname(self.get_path())
        if task_dir not in path_stack:
            path_stack.append(task_dir)

        return path_stack
示例#4
0
class Play(Base, Taggable, CollectionSearch):
    """
    A play is a language feature that represents a list of roles and/or
    task/handler blocks to execute on a given set of hosts.

    Usage:

       Play.load(datastructure) -> Play
       Play.something(...)
    """

    # =================================================================================
    _hosts = FieldAttribute(isa='list',
                            required=True,
                            listof=string_types,
                            always_post_validate=True)

    # Facts
    _gather_facts = FieldAttribute(isa='bool',
                                   default=None,
                                   always_post_validate=True)
    _gather_subset = FieldAttribute(isa='list',
                                    default=(lambda: C.DEFAULT_GATHER_SUBSET),
                                    listof=string_types,
                                    always_post_validate=True)
    _gather_timeout = FieldAttribute(isa='int',
                                     default=C.DEFAULT_GATHER_TIMEOUT,
                                     always_post_validate=True)
    _fact_path = FieldAttribute(isa='string', default=C.DEFAULT_FACT_PATH)

    # Variable Attributes
    _vars_files = FieldAttribute(isa='list', default=list, priority=99)
    _vars_prompt = FieldAttribute(isa='list',
                                  default=list,
                                  always_post_validate=False)

    # Role Attributes
    _roles = FieldAttribute(isa='list', default=list, priority=90)

    # Block (Task) Lists Attributes
    _handlers = FieldAttribute(isa='list', default=list)
    _pre_tasks = FieldAttribute(isa='list', default=list)
    _post_tasks = FieldAttribute(isa='list', default=list)
    _tasks = FieldAttribute(isa='list', default=list)

    # Flag/Setting Attributes
    _force_handlers = FieldAttribute(
        isa='bool',
        default=context.cliargs_deferred_get('force_handlers'),
        always_post_validate=True)
    _max_fail_percentage = FieldAttribute(isa='percent',
                                          always_post_validate=True)
    _serial = FieldAttribute(isa='list',
                             default=list,
                             always_post_validate=True)
    _strategy = FieldAttribute(isa='string',
                               default=C.DEFAULT_STRATEGY,
                               always_post_validate=True)
    _order = FieldAttribute(isa='string', always_post_validate=True)

    # =================================================================================

    def __init__(self):
        super(Play, self).__init__()

        self._included_conditional = None
        self._included_path = None
        self._removed_hosts = []
        self.ROLE_CACHE = {}

        self.only_tags = set(context.CLIARGS.get('tags', [])) or frozenset(
            ('all', ))
        self.skip_tags = set(context.CLIARGS.get('skip_tags', []))

    def __repr__(self):
        return self.get_name()

    def get_name(self):
        ''' return the name of the Play '''
        return self.name

    @staticmethod
    def load(data, variable_manager=None, loader=None, vars=None):
        if ('name' not in data or data['name'] is None) and 'hosts' in data:
            if data['hosts'] is None or all(host is None
                                            for host in data['hosts']):
                raise AnsibleParserError(
                    "Hosts list cannot be empty - please check your playbook")
            if isinstance(data['hosts'], list):
                data['name'] = ','.join(data['hosts'])
            else:
                data['name'] = data['hosts']
        p = Play()
        if vars:
            p.vars = vars.copy()
        return p.load_data(data,
                           variable_manager=variable_manager,
                           loader=loader)

    def preprocess_data(self, ds):
        '''
        Adjusts play datastructure to cleanup old/legacy items
        '''

        if not isinstance(ds, dict):
            raise AnsibleAssertionError(
                'while preprocessing data (%s), ds should be a dict but was a %s'
                % (ds, type(ds)))

        # The use of 'user' in the Play datastructure was deprecated to
        # line up with the same change for Tasks, due to the fact that
        # 'user' conflicted with the user module.
        if 'user' in ds:
            # this should never happen, but error out with a helpful message
            # to the user if it does...
            if 'remote_user' in ds:
                raise AnsibleParserError(
                    "both 'user' and 'remote_user' are set for %s. "
                    "The use of 'user' is deprecated, and should be removed" %
                    self.get_name(),
                    obj=ds)

            ds['remote_user'] = ds['user']
            del ds['user']

        return super(Play, self).preprocess_data(ds)

    def _load_tasks(self, attr, ds):
        '''
        Loads a list of blocks from a list which may be mixed tasks/blocks.
        Bare tasks outside of a block are given an implicit block.
        '''
        try:
            return load_list_of_blocks(ds=ds,
                                       play=self,
                                       variable_manager=self._variable_manager,
                                       loader=self._loader)
        except AssertionError as e:
            raise AnsibleParserError(
                "A malformed block was encountered while loading tasks: %s" %
                to_native(e),
                obj=self._ds,
                orig_exc=e)

    def _load_pre_tasks(self, attr, ds):
        '''
        Loads a list of blocks from a list which may be mixed tasks/blocks.
        Bare tasks outside of a block are given an implicit block.
        '''
        try:
            return load_list_of_blocks(ds=ds,
                                       play=self,
                                       variable_manager=self._variable_manager,
                                       loader=self._loader)
        except AssertionError as e:
            raise AnsibleParserError(
                "A malformed block was encountered while loading pre_tasks",
                obj=self._ds,
                orig_exc=e)

    def _load_post_tasks(self, attr, ds):
        '''
        Loads a list of blocks from a list which may be mixed tasks/blocks.
        Bare tasks outside of a block are given an implicit block.
        '''
        try:
            return load_list_of_blocks(ds=ds,
                                       play=self,
                                       variable_manager=self._variable_manager,
                                       loader=self._loader)
        except AssertionError as e:
            raise AnsibleParserError(
                "A malformed block was encountered while loading post_tasks",
                obj=self._ds,
                orig_exc=e)

    def _load_handlers(self, attr, ds):
        '''
        Loads a list of blocks from a list which may be mixed handlers/blocks.
        Bare handlers outside of a block are given an implicit block.
        '''
        try:
            return self._extend_value(
                self.handlers,
                load_list_of_blocks(ds=ds,
                                    play=self,
                                    use_handlers=True,
                                    variable_manager=self._variable_manager,
                                    loader=self._loader),
                prepend=True)
        except AssertionError as e:
            raise AnsibleParserError(
                "A malformed block was encountered while loading handlers",
                obj=self._ds,
                orig_exc=e)

    def _load_roles(self, attr, ds):
        '''
        Loads and returns a list of RoleInclude objects from the datastructure
        list of role definitions and creates the Role from those objects
        '''

        if ds is None:
            ds = []

        try:
            role_includes = load_list_of_roles(
                ds,
                play=self,
                variable_manager=self._variable_manager,
                loader=self._loader,
                collection_search_list=self.collections)
        except AssertionError as e:
            raise AnsibleParserError(
                "A malformed role declaration was encountered.",
                obj=self._ds,
                orig_exc=e)

        roles = []
        for ri in role_includes:
            roles.append(Role.load(ri, play=self))

        self.roles[:0] = roles

        return self.roles

    def _load_vars_prompt(self, attr, ds):
        new_ds = preprocess_vars(ds)
        vars_prompts = []
        if new_ds is not None:
            for prompt_data in new_ds:
                if 'name' not in prompt_data:
                    raise AnsibleParserError(
                        "Invalid vars_prompt data structure", obj=ds)
                else:
                    vars_prompts.append(prompt_data)
        return vars_prompts

    def _compile_roles(self):
        '''
        Handles the role compilation step, returning a flat list of tasks
        with the lowest level dependencies first. For example, if a role R
        has a dependency D1, which also has a dependency D2, the tasks from
        D2 are merged first, followed by D1, and lastly by the tasks from
        the parent role R last. This is done for all roles in the Play.
        '''

        block_list = []

        if len(self.roles) > 0:
            for r in self.roles:
                # Don't insert tasks from ``import/include_role``, preventing
                # duplicate execution at the wrong time
                if r.from_include:
                    continue
                block_list.extend(r.compile(play=self))

        return block_list

    def compile_roles_handlers(self):
        '''
        Handles the role handler compilation step, returning a flat list of Handlers
        This is done for all roles in the Play.
        '''

        block_list = []

        if len(self.roles) > 0:
            for r in self.roles:
                if r.from_include:
                    continue
                block_list.extend(r.get_handler_blocks(play=self))

        return block_list

    def compile(self):
        '''
        Compiles and returns the task list for this play, compiled from the
        roles (which are themselves compiled recursively) and/or the list of
        tasks specified in the play.
        '''

        # create a block containing a single flush handlers meta
        # task, so we can be sure to run handlers at certain points
        # of the playbook execution
        flush_block = Block.load(data={'meta': 'flush_handlers'},
                                 play=self,
                                 variable_manager=self._variable_manager,
                                 loader=self._loader)

        block_list = []

        block_list.extend(self.pre_tasks)
        block_list.append(flush_block)
        block_list.extend(self._compile_roles())
        block_list.extend(self.tasks)
        block_list.append(flush_block)
        block_list.extend(self.post_tasks)
        block_list.append(flush_block)

        return block_list

    def get_vars(self):
        return self.vars.copy()

    def get_vars_files(self):
        if self.vars_files is None:
            return []
        elif not isinstance(self.vars_files, list):
            return [self.vars_files]
        return self.vars_files

    def get_handlers(self):
        return self.handlers[:]

    def get_roles(self):
        return self.roles[:]

    def get_tasks(self):
        tasklist = []
        for task in self.pre_tasks + self.tasks + self.post_tasks:
            if isinstance(task, Block):
                tasklist.append(task.block + task.rescue + task.always)
            else:
                tasklist.append(task)
        return tasklist

    def serialize(self):
        data = super(Play, self).serialize()

        roles = []
        for role in self.get_roles():
            roles.append(role.serialize())
        data['roles'] = roles
        data['included_path'] = self._included_path

        return data

    def deserialize(self, data):
        super(Play, self).deserialize(data)

        self._included_path = data.get('included_path', None)
        if 'roles' in data:
            role_data = data.get('roles', [])
            roles = []
            for role in role_data:
                r = Role()
                r.deserialize(role)
                roles.append(r)

            setattr(self, 'roles', roles)
            del data['roles']

    def copy(self):
        new_me = super(Play, self).copy()
        new_me.ROLE_CACHE = self.ROLE_CACHE.copy()
        new_me._included_conditional = self._included_conditional
        new_me._included_path = self._included_path
        return new_me
示例#5
0
文件: become.py 项目: zship/ansible
class Become:

    # Privilege escalation
    _become = FieldAttribute(isa='bool',
                             default=context.cliargs_deferred_get('become'))
    _become_method = FieldAttribute(
        isa='string', default=context.cliargs_deferred_get('become_method'))
    _become_user = FieldAttribute(
        isa='string', default=context.cliargs_deferred_get('become_user'))
    _become_flags = FieldAttribute(isa='string')

    def __init__(self):
        super(Become, self).__init__()

    def _detect_privilege_escalation_conflict(self, ds):

        # Fail out if user specifies conflicting privilege escalations
        has_become = 'become' in ds or 'become_user' in ds
        has_sudo = 'sudo' in ds or 'sudo_user' in ds
        has_su = 'su' in ds or 'su_user' in ds

        if has_become:
            msg = 'The become params ("become", "become_user") and'
            if has_sudo:
                raise AnsibleParserError(
                    '%s sudo params ("sudo", "sudo_user") cannot be used together'
                    % msg)
            elif has_su:
                raise AnsibleParserError(
                    '%s su params ("su", "su_user") cannot be used together' %
                    msg)
        elif has_sudo and has_su:
            raise AnsibleParserError(
                'sudo params ("sudo", "sudo_user") and su params ("su", "su_user") cannot be used together'
            )

    def _preprocess_data_become(self, ds):
        """Preprocess the playbook data for become attributes

        This is called from the Base object's preprocess_data() method which
        in turn is called pretty much anytime any sort of playbook object
        (plays, tasks, blocks, etc) is created.
        """

        self._detect_privilege_escalation_conflict(ds)

        # Privilege escalation, backwards compatibility for sudo/su
        if 'sudo' in ds or 'sudo_user' in ds:
            ds['become_method'] = 'sudo'
            if 'sudo' in ds:
                ds['become'] = ds['sudo']
                del ds['sudo']

            if 'sudo_user' in ds:
                ds['become_user'] = ds['sudo_user']
                del ds['sudo_user']

            display.deprecated(
                "Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default)",
                '2.9')

        elif 'su' in ds or 'su_user' in ds:
            ds['become_method'] = 'su'
            if 'su' in ds:
                ds['become'] = ds['su']
                del ds['su']

            if 'su_user' in ds:
                ds['become_user'] = ds['su_user']
                del ds['su_user']

            display.deprecated(
                "Instead of su/su_user, use become/become_user and set become_method to 'su' (default is sudo)",
                '2.9')

        return ds