Beispiel #1
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')
Beispiel #2
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")
Beispiel #3
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")
Beispiel #4
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)
Beispiel #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)
Beispiel #6
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)
Beispiel #7
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')