예제 #1
0
    def test_variable_manager_task_vars(self):
        # FIXME: BCS make this work
        return

        # pylint: disable=unreachable
        fake_loader = DictDataLoader({})

        mock_task = MagicMock()
        mock_task._role = None
        mock_task.loop = None
        mock_task.get_vars.return_value = dict(foo="bar")
        mock_task.get_include_params.return_value = dict()

        mock_all = MagicMock()
        mock_all.get_vars.return_value = {}
        mock_all.get_file_vars.return_value = {}

        mock_host = MagicMock()
        mock_host.get.name.return_value = 'test01'
        mock_host.get_vars.return_value = {}
        mock_host.get_host_vars.return_value = {}

        mock_inventory = MagicMock()
        mock_inventory.hosts.get.return_value = mock_host
        mock_inventory.hosts.get.name.return_value = 'test01'
        mock_inventory.get_host.return_value = mock_host
        mock_inventory.groups.__getitem__.return_value = mock_all

        v = VariableManager(loader=fake_loader, inventory=mock_inventory)
        self.assertEqual(v.get_vars(task=mock_task, use_cache=False).get("foo"), "bar")
예제 #2
0
    def test_variable_manager_play_vars(self):
        fake_loader = DictDataLoader({})

        mock_play = MagicMock()
        mock_play.get_vars.return_value = dict(foo="bar")
        mock_play.get_roles.return_value = []
        mock_play.get_vars_files.return_value = []

        mock_inventory = MagicMock()
        v = VariableManager(loader=fake_loader, inventory=mock_inventory)
        self.assertEqual(v.get_vars(play=mock_play, use_cache=False).get("foo"), "bar")
예제 #3
0
    def test_basic_manager(self):
        fake_loader = DictDataLoader({})

        mock_inventory = MagicMock()
        v = VariableManager(loader=fake_loader, inventory=mock_inventory)
        variables = v.get_vars(use_cache=False)

        # Check var manager expected values,  never check: ['omit', 'vars']
        # FIXME:  add the following ['assible_version', 'assible_playbook_python', 'groups']
        for varname, value in (('playbook_dir', os.path.abspath('.')), ):
            self.assertEqual(variables[varname], value)
예제 #4
0
    def test_variable_manager_role_vars_dependencies(self):
        '''
        Tests vars from role dependencies with duplicate dependencies.
        '''
        mock_inventory = MagicMock()

        fake_loader = DictDataLoader({
            # role common-role
            '/etc/assible/roles/common-role/tasks/main.yml': """
            - debug: msg="{{role_var}}"
            """,
            # We do not need allow_duplicates: yes for this role
            # because eliminating duplicates is done by the execution
            # strategy, which we do not test here.

            # role role1
            '/etc/assible/roles/role1/vars/main.yml': """
            role_var: "role_var_from_role1"
            """,
            '/etc/assible/roles/role1/meta/main.yml': """
            dependencies:
              - { role: common-role }
            """,

            # role role2
            '/etc/assible/roles/role2/vars/main.yml': """
            role_var: "role_var_from_role2"
            """,
            '/etc/assible/roles/role2/meta/main.yml': """
            dependencies:
              - { role: common-role }
            """,
        })

        v = VariableManager(loader=fake_loader, inventory=mock_inventory)

        play1 = Play.load(dict(
            hosts=['all'],
            roles=['role1', 'role2'],
        ), loader=fake_loader, variable_manager=v)

        # The task defined by common-role exists twice because role1
        # and role2 depend on common-role.  Check that the tasks see
        # different values of role_var.
        blocks = play1.compile()
        task = blocks[1].block[0]
        res = v.get_vars(play=play1, task=task)
        self.assertEqual(res['role_var'], 'role_var_from_role1')

        task = blocks[2].block[0]
        res = v.get_vars(play=play1, task=task)
        self.assertEqual(res['role_var'], 'role_var_from_role2')
예제 #5
0
    def test_variable_manager_options_vars(self):
        fake_loader = DictDataLoader({})

        options_vars = dict(a=1, b=2, c=3)
        mock_inventory = MagicMock()
        v = VariableManager(loader=fake_loader, inventory=mock_inventory)

        # override internal options_vars loading
        v._extra_vars = options_vars

        myvars = v.get_vars(use_cache=False)
        for (key, val) in iteritems(options_vars):
            self.assertEqual(myvars.get(key), val)
예제 #6
0
    def test_flush_cache(self):
        cli = PlaybookCLI(
            args=["assible-playbook", "--flush-cache", "foobar.yml"])
        cli.parse()
        self.assertTrue(context.CLIARGS['flush_cache'])

        variable_manager = VariableManager()
        fake_loader = DictDataLoader({'foobar.yml': ""})
        inventory = InventoryManager(loader=fake_loader, sources='testhost,')

        variable_manager.set_host_facts('testhost', {'canary': True})
        self.assertTrue('testhost' in variable_manager._fact_cache)

        cli._flush_cache(inventory, variable_manager)
        self.assertFalse('testhost' in variable_manager._fact_cache)
예제 #7
0
    def _play_prereqs():
        options = context.CLIARGS

        # all needs loader
        loader = DataLoader()

        basedir = options.get('basedir', False)
        if basedir:
            loader.set_basedir(basedir)
            add_all_plugin_dirs(basedir)
            AssibleCollectionConfig.playbook_paths = basedir
            default_collection = _get_collection_name_from_path(basedir)
            if default_collection:
                display.warning(u'running with default collection {0}'.format(
                    default_collection))
                AssibleCollectionConfig.default_collection = default_collection

        vault_ids = list(options['vault_ids'])
        default_vault_ids = C.DEFAULT_VAULT_IDENTITY_LIST
        vault_ids = default_vault_ids + vault_ids

        vault_secrets = CLI.setup_vault_secrets(
            loader,
            vault_ids=vault_ids,
            vault_password_files=list(options['vault_password_files']),
            ask_vault_pass=options['ask_vault_pass'],
            auto_prompt=False)
        loader.set_vault_secrets(vault_secrets)

        # create the inventory, and filter it based on the subset specified (if any)
        inventory = InventoryManager(loader=loader,
                                     sources=options['inventory'])

        # create the variable manager, which will be shared throughout
        # the code, ensuring a consistent view of global variables
        variable_manager = VariableManager(
            loader=loader,
            inventory=inventory,
            version_info=CLI.version_info(gitinfo=False))

        return loader, inventory, variable_manager
예제 #8
0
    def test_bad_playbook_files(self):
        fake_loader = DictDataLoader({
            # represents a playbook which is not a list of plays
            "bad_list.yml":
            """
            foo: bar

            """,
            # represents a playbook where a play entry is mis-formatted
            "bad_entry.yml":
            """
            -
              - "This should be a mapping..."

            """,
        })
        vm = VariableManager()
        self.assertRaises(AssibleParserError, Playbook.load, "bad_list.yml",
                          vm, fake_loader)
        self.assertRaises(AssibleParserError, Playbook.load, "bad_entry.yml",
                          vm, fake_loader)
예제 #9
0
def main():
    host_list = ['localhost', 'www.example.com', 'www.google.com']
    # since the API is constructed for CLI it expects certain options to always be set in the context object
    context.CLIARGS = ImmutableDict(
        connection='smart',
        module_path=['/to/mymodules', '/usr/share/assible'],
        forks=10,
        become=None,
        become_method=None,
        become_user=None,
        check=False,
        diff=False)
    # required for
    # https://github.com/assible/assible/blob/devel/lib/assible/inventory/manager.py#L204
    sources = ','.join(host_list)
    if len(host_list) == 1:
        sources += ','

    # initialize needed objects
    loader = DataLoader(
    )  # Takes care of finding and reading yaml, json and ini files
    passwords = dict(vault_pass='******')

    # Instantiate our ResultsCollectorJSONCallback for handling results as they come in. Assible expects this to be one of its main display outlets
    results_callback = ResultsCollectorJSONCallback()

    # create inventory, use path to host config file as source or hosts in a comma separated string
    inventory = InventoryManager(loader=loader, sources=sources)

    # variable manager takes care of merging all the different sources to give you a unified view of variables available in each context
    variable_manager = VariableManager(loader=loader, inventory=inventory)

    # instantiate task queue manager, which takes care of forking and setting up all objects to iterate over host list and tasks
    # IMPORTANT: This also adds library dirs paths to the module loader
    # IMPORTANT: and so it must be initialized before calling `Play.load()`.
    tqm = TaskQueueManager(
        inventory=inventory,
        variable_manager=variable_manager,
        loader=loader,
        passwords=passwords,
        stdout_callback=
        results_callback,  # Use our custom callback instead of the ``default`` callback plugin, which prints to stdout
    )

    # create data structure that represents our play, including tasks, this is basically what our YAML loader does internally.
    play_source = dict(
        name="Assible Play",
        hosts=host_list,
        gather_facts='no',
        tasks=[
            dict(action=dict(module='shell', args='ls'), register='shell_out'),
            dict(action=dict(module='debug',
                             args=dict(msg='{{shell_out.stdout}}'))),
            dict(
                action=dict(module='command', args=dict(
                    cmd='/usr/bin/uptime'))),
        ])

    # Create play object, playbook objects use .load instead of init or new methods,
    # this will also automatically create the task objects from the info provided in play_source
    play = Play().load(play_source,
                       variable_manager=variable_manager,
                       loader=loader)

    # Actually run it
    try:
        result = tqm.run(
            play
        )  # most interesting data for a play is actually sent to the callback's methods
    finally:
        # we always need to cleanup child procs and the structures we use to communicate with them
        tqm.cleanup()
        if loader:
            loader.cleanup_all_tmp_files()

    # Remove assible tmpdir
    shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)

    print("UP ***********")
    for host, result in results_callback.host_ok.items():
        print('{0} >>> {1}'.format(host, result._result['stdout']))

    print("FAILED *******")
    for host, result in results_callback.host_failed.items():
        print('{0} >>> {1}'.format(host, result._result['msg']))

    print("DOWN *********")
    for host, result in results_callback.host_unreachable.items():
        print('{0} >>> {1}'.format(host, result._result['msg']))
예제 #10
0
    def setUp(self):

        self.loader = DictDataLoader({
            '/etc/assible/roles/l1/tasks/main.yml':
            """
                - shell: echo 'hello world from l1'
                - include_role: name=l2
            """,
            '/etc/assible/roles/l1/tasks/alt.yml':
            """
                - shell: echo 'hello world from l1 alt'
                - include_role: name=l2 tasks_from=alt defaults_from=alt
            """,
            '/etc/assible/roles/l1/defaults/main.yml':
            """
                test_variable: l1-main
                l1_variable: l1-main
            """,
            '/etc/assible/roles/l1/defaults/alt.yml':
            """
                test_variable: l1-alt
                l1_variable: l1-alt
            """,
            '/etc/assible/roles/l2/tasks/main.yml':
            """
                - shell: echo 'hello world from l2'
                - include_role: name=l3
            """,
            '/etc/assible/roles/l2/tasks/alt.yml':
            """
                - shell: echo 'hello world from l2 alt'
                - include_role: name=l3 tasks_from=alt defaults_from=alt
            """,
            '/etc/assible/roles/l2/defaults/main.yml':
            """
                test_variable: l2-main
                l2_variable: l2-main
            """,
            '/etc/assible/roles/l2/defaults/alt.yml':
            """
                test_variable: l2-alt
                l2_variable: l2-alt
            """,
            '/etc/assible/roles/l3/tasks/main.yml':
            """
                - shell: echo 'hello world from l3'
            """,
            '/etc/assible/roles/l3/tasks/alt.yml':
            """
                - shell: echo 'hello world from l3 alt'
            """,
            '/etc/assible/roles/l3/defaults/main.yml':
            """
                test_variable: l3-main
                l3_variable: l3-main
            """,
            '/etc/assible/roles/l3/defaults/alt.yml':
            """
                test_variable: l3-alt
                l3_variable: l3-alt
            """
        })

        self.var_manager = VariableManager(loader=self.loader)
예제 #11
0
class TestIncludeRole(unittest.TestCase):
    def setUp(self):

        self.loader = DictDataLoader({
            '/etc/assible/roles/l1/tasks/main.yml':
            """
                - shell: echo 'hello world from l1'
                - include_role: name=l2
            """,
            '/etc/assible/roles/l1/tasks/alt.yml':
            """
                - shell: echo 'hello world from l1 alt'
                - include_role: name=l2 tasks_from=alt defaults_from=alt
            """,
            '/etc/assible/roles/l1/defaults/main.yml':
            """
                test_variable: l1-main
                l1_variable: l1-main
            """,
            '/etc/assible/roles/l1/defaults/alt.yml':
            """
                test_variable: l1-alt
                l1_variable: l1-alt
            """,
            '/etc/assible/roles/l2/tasks/main.yml':
            """
                - shell: echo 'hello world from l2'
                - include_role: name=l3
            """,
            '/etc/assible/roles/l2/tasks/alt.yml':
            """
                - shell: echo 'hello world from l2 alt'
                - include_role: name=l3 tasks_from=alt defaults_from=alt
            """,
            '/etc/assible/roles/l2/defaults/main.yml':
            """
                test_variable: l2-main
                l2_variable: l2-main
            """,
            '/etc/assible/roles/l2/defaults/alt.yml':
            """
                test_variable: l2-alt
                l2_variable: l2-alt
            """,
            '/etc/assible/roles/l3/tasks/main.yml':
            """
                - shell: echo 'hello world from l3'
            """,
            '/etc/assible/roles/l3/tasks/alt.yml':
            """
                - shell: echo 'hello world from l3 alt'
            """,
            '/etc/assible/roles/l3/defaults/main.yml':
            """
                test_variable: l3-main
                l3_variable: l3-main
            """,
            '/etc/assible/roles/l3/defaults/alt.yml':
            """
                test_variable: l3-alt
                l3_variable: l3-alt
            """
        })

        self.var_manager = VariableManager(loader=self.loader)

    def tearDown(self):
        pass

    def flatten_tasks(self, tasks):
        for task in tasks:
            if isinstance(task, IncludeRole):
                blocks, handlers = task.get_block_list(loader=self.loader)
                for block in blocks:
                    for t in self.flatten_tasks(block.block):
                        yield t
            elif isinstance(task, Task):
                yield task
            else:
                for t in self.flatten_tasks(task.block):
                    yield t

    def get_tasks_vars(self, play, tasks):
        for task in self.flatten_tasks(tasks):
            role = task._role
            if not role:
                continue

            yield (role.get_name(),
                   self.var_manager.get_vars(play=play, task=task))

    @patch('assible.playbook.role.definition.unfrackpath',
           mock_unfrackpath_noop)
    def test_simple(self):
        """Test one-level include with default tasks and variables"""

        play = Play.load(dict(name="test play",
                              hosts=['foo'],
                              gather_facts=False,
                              tasks=[{
                                  'include_role': 'name=l3'
                              }]),
                         loader=self.loader,
                         variable_manager=self.var_manager)

        tasks = play.compile()
        tested = False
        for role, task_vars in self.get_tasks_vars(play, tasks):
            tested = True
            self.assertEqual(task_vars.get('l3_variable'), 'l3-main')
            self.assertEqual(task_vars.get('test_variable'), 'l3-main')
        self.assertTrue(tested)

    @patch('assible.playbook.role.definition.unfrackpath',
           mock_unfrackpath_noop)
    def test_simple_alt_files(self):
        """Test one-level include with alternative tasks and variables"""

        play = Play.load(dict(name="test play",
                              hosts=['foo'],
                              gather_facts=False,
                              tasks=[{
                                  'include_role':
                                  'name=l3 tasks_from=alt defaults_from=alt'
                              }]),
                         loader=self.loader,
                         variable_manager=self.var_manager)

        tasks = play.compile()
        tested = False
        for role, task_vars in self.get_tasks_vars(play, tasks):
            tested = True
            self.assertEqual(task_vars.get('l3_variable'), 'l3-alt')
            self.assertEqual(task_vars.get('test_variable'), 'l3-alt')
        self.assertTrue(tested)

    @patch('assible.playbook.role.definition.unfrackpath',
           mock_unfrackpath_noop)
    def test_nested(self):
        """
        Test nested includes with default tasks and variables.

        Variables from outer roles should be inherited, but overridden in inner
        roles.
        """

        play = Play.load(dict(name="test play",
                              hosts=['foo'],
                              gather_facts=False,
                              tasks=[{
                                  'include_role': 'name=l1'
                              }]),
                         loader=self.loader,
                         variable_manager=self.var_manager)

        tasks = play.compile()
        expected_roles = ['l1', 'l2', 'l3']
        for role, task_vars in self.get_tasks_vars(play, tasks):
            expected_roles.remove(role)
            # Outer-most role must not have variables from inner roles yet
            if role == 'l1':
                self.assertEqual(task_vars.get('l1_variable'), 'l1-main')
                self.assertEqual(task_vars.get('l2_variable'), None)
                self.assertEqual(task_vars.get('l3_variable'), None)
                self.assertEqual(task_vars.get('test_variable'), 'l1-main')
            # Middle role must have variables from outer role, but not inner
            elif role == 'l2':
                self.assertEqual(task_vars.get('l1_variable'), 'l1-main')
                self.assertEqual(task_vars.get('l2_variable'), 'l2-main')
                self.assertEqual(task_vars.get('l3_variable'), None)
                self.assertEqual(task_vars.get('test_variable'), 'l2-main')
            # Inner role must have variables from both outer roles
            elif role == 'l3':
                self.assertEqual(task_vars.get('l1_variable'), 'l1-main')
                self.assertEqual(task_vars.get('l2_variable'), 'l2-main')
                self.assertEqual(task_vars.get('l3_variable'), 'l3-main')
                self.assertEqual(task_vars.get('test_variable'), 'l3-main')
            else:
                self.fail()
        self.assertFalse(expected_roles)

    @patch('assible.playbook.role.definition.unfrackpath',
           mock_unfrackpath_noop)
    def test_nested_alt_files(self):
        """
        Test nested includes with alternative tasks and variables.

        Variables from outer roles should be inherited, but overridden in inner
        roles.
        """

        play = Play.load(dict(name="test play",
                              hosts=['foo'],
                              gather_facts=False,
                              tasks=[{
                                  'include_role':
                                  'name=l1 tasks_from=alt defaults_from=alt'
                              }]),
                         loader=self.loader,
                         variable_manager=self.var_manager)

        tasks = play.compile()
        expected_roles = ['l1', 'l2', 'l3']
        for role, task_vars in self.get_tasks_vars(play, tasks):
            expected_roles.remove(role)
            # Outer-most role must not have variables from inner roles yet
            if role == 'l1':
                self.assertEqual(task_vars.get('l1_variable'), 'l1-alt')
                self.assertEqual(task_vars.get('l2_variable'), None)
                self.assertEqual(task_vars.get('l3_variable'), None)
                self.assertEqual(task_vars.get('test_variable'), 'l1-alt')
            # Middle role must have variables from outer role, but not inner
            elif role == 'l2':
                self.assertEqual(task_vars.get('l1_variable'), 'l1-alt')
                self.assertEqual(task_vars.get('l2_variable'), 'l2-alt')
                self.assertEqual(task_vars.get('l3_variable'), None)
                self.assertEqual(task_vars.get('test_variable'), 'l2-alt')
            # Inner role must have variables from both outer roles
            elif role == 'l3':
                self.assertEqual(task_vars.get('l1_variable'), 'l1-alt')
                self.assertEqual(task_vars.get('l2_variable'), 'l2-alt')
                self.assertEqual(task_vars.get('l3_variable'), 'l3-alt')
                self.assertEqual(task_vars.get('test_variable'), 'l3-alt')
            else:
                self.fail()
        self.assertFalse(expected_roles)
예제 #12
0
    def test_variable_manager_precedence(self):
        # FIXME: this needs to be redone as dataloader is not the automatic source of data anymore
        return

        # pylint: disable=unreachable
        '''
        Tests complex variations and combinations of get_vars() with different
        objects to modify the context under which variables are merged.
        '''
        # FIXME: BCS makethiswork
        # return True

        mock_inventory = MagicMock()

        inventory1_filedata = """
            [group2:children]
            group1

            [group1]
            host1 host_var=host_var_from_inventory_host1

            [group1:vars]
            group_var = group_var_from_inventory_group1

            [group2:vars]
            group_var = group_var_from_inventory_group2
            """

        fake_loader = DictDataLoader({
            # inventory1
            '/etc/assible/inventory1': inventory1_filedata,
            # role defaults_only1
            '/etc/assible/roles/defaults_only1/defaults/main.yml': """
            default_var: "default_var_from_defaults_only1"
            host_var: "host_var_from_defaults_only1"
            group_var: "group_var_from_defaults_only1"
            group_var_all: "group_var_all_from_defaults_only1"
            extra_var: "extra_var_from_defaults_only1"
            """,
            '/etc/assible/roles/defaults_only1/tasks/main.yml': """
            - debug: msg="here i am"
            """,

            # role defaults_only2
            '/etc/assible/roles/defaults_only2/defaults/main.yml': """
            default_var: "default_var_from_defaults_only2"
            host_var: "host_var_from_defaults_only2"
            group_var: "group_var_from_defaults_only2"
            group_var_all: "group_var_all_from_defaults_only2"
            extra_var: "extra_var_from_defaults_only2"
            """,
        })

        inv1 = InventoryManager(loader=fake_loader, sources=['/etc/assible/inventory1'])
        v = VariableManager(inventory=mock_inventory, loader=fake_loader)

        play1 = Play.load(dict(
            hosts=['all'],
            roles=['defaults_only1', 'defaults_only2'],
        ), loader=fake_loader, variable_manager=v)

        # first we assert that the defaults as viewed as a whole are the merged results
        # of the defaults from each role, with the last role defined "winning" when
        # there is a variable naming conflict
        res = v.get_vars(play=play1)
        self.assertEqual(res['default_var'], 'default_var_from_defaults_only2')

        # next, we assert that when vars are viewed from the context of a task within a
        # role, that task will see its own role defaults before any other role's
        blocks = play1.compile()
        task = blocks[1].block[0]
        res = v.get_vars(play=play1, task=task)
        self.assertEqual(res['default_var'], 'default_var_from_defaults_only1')

        # next we assert the precedence of inventory variables
        v.set_inventory(inv1)
        h1 = inv1.get_host('host1')

        res = v.get_vars(play=play1, host=h1)
        self.assertEqual(res['group_var'], 'group_var_from_inventory_group1')
        self.assertEqual(res['host_var'], 'host_var_from_inventory_host1')

        # next we test with group_vars/ files loaded
        fake_loader.push("/etc/assible/group_vars/all", """
        group_var_all: group_var_all_from_group_vars_all
        """)
        fake_loader.push("/etc/assible/group_vars/group1", """
        group_var: group_var_from_group_vars_group1
        """)
        fake_loader.push("/etc/assible/group_vars/group3", """
        # this is a dummy, which should not be used anywhere
        group_var: group_var_from_group_vars_group3
        """)
        fake_loader.push("/etc/assible/host_vars/host1", """
        host_var: host_var_from_host_vars_host1
        """)
        fake_loader.push("group_vars/group1", """
        playbook_group_var: playbook_group_var
        """)
        fake_loader.push("host_vars/host1", """
        playbook_host_var: playbook_host_var
        """)

        res = v.get_vars(play=play1, host=h1)
        # self.assertEqual(res['group_var'], 'group_var_from_group_vars_group1')
        # self.assertEqual(res['group_var_all'], 'group_var_all_from_group_vars_all')
        # self.assertEqual(res['playbook_group_var'], 'playbook_group_var')
        # self.assertEqual(res['host_var'], 'host_var_from_host_vars_host1')
        # self.assertEqual(res['playbook_host_var'], 'playbook_host_var')

        # add in the fact cache
        v._fact_cache['host1'] = dict(fact_cache_var="fact_cache_var_from_fact_cache")

        res = v.get_vars(play=play1, host=h1)
        self.assertEqual(res['fact_cache_var'], 'fact_cache_var_from_fact_cache')