Exemplo n.º 1
0
    def test_ha_relation_changed_pacemaker_remote(
            self, config, get_corosync_conf, relation_ids, relation_set,
            get_cluster_nodes, trigger_corosync_update_from_leader,
            relation_type, remote_unit):
        """Test pacemaker-remote-relation-changed.

        Validates that ha_relation_changed() doesn't call
        trigger_corosync_update_from_leader() when called from the
        pacemaker-remote-relation-changed hook. See lp:1920124
        """
        cfg = {'cluster_count': 3}
        config.side_effect = lambda key: cfg.get(key)

        # 2 out of 3 so that the function under test finishes early:
        get_cluster_nodes.return_value = ['10.0.3.2', '10.0.3.3']

        relation_ids.return_value = ['hanode:1']
        get_corosync_conf.return_value = True
        relation_type.return_value = 'pacemaker-remote'
        remote_unit.return_value = 'pacemaker-remote/0'

        hooks.ha_relation_changed()

        relation_set.assert_any_call(relation_id='hanode:1', ready=True)
        trigger_corosync_update_from_leader.assert_not_called()
Exemplo n.º 2
0
    def test_ha_relation_changed_dns_ha_missing(
            self, parse_data, config, commit, get_corosync_conf, relation_ids,
            relation_set, get_cluster_nodes, related_units, configure_stonith,
            configure_monitor_host, configure_cluster_global,
            configure_corosync, oldest_peer, crm_opt_exists, peer_units,
            wait_for_pcmk, validate_dns_ha, setup_maas_api):

        validate_dns_ha.return_value = False
        crm_opt_exists.return_value = False
        oldest_peer.return_value = True
        related_units.return_value = ['ha/0', 'ha/1', 'ha/2']
        get_cluster_nodes.return_value = ['10.0.3.2', '10.0.3.3', '10.0.3.4']
        relation_ids.return_value = ['ha:1']
        get_corosync_conf.return_value = True
        cfg = {
            'debug': False,
            'prefer-ipv6': False,
            'corosync_transport': 'udpu',
            'corosync_mcastaddr': 'corosync_mcastaddr',
            'cluster_count': 3,
            'maas_url': 'http://maas/MAAAS/',
            'maas_credentials': None
        }

        config.side_effect = lambda key: cfg.get(key)

        rel_get_data = {
            'locations': {
                'loc_foo': 'bar rule inf: meh eq 1'
            },
            'clones': {
                'cl_foo': 'res_foo meta interleave=true'
            },
            'groups': {
                'grp_foo': 'res_foo'
            },
            'colocations': {
                'co_foo': 'inf: grp_foo cl_foo'
            },
            'resources': {
                'res_foo_hostname': 'ocf:maas:dns'
            },
            'resource_params': {
                'res_foo_hostname': 'params bar'
            },
            'ms': {
                'ms_foo': 'res_foo meta notify=true'
            },
            'orders': {
                'foo_after': 'inf: res_foo ms_foo'
            }
        }

        def fake_parse_data(relid, unit, key):
            return rel_get_data.get(key, {})

        parse_data.side_effect = fake_parse_data

        with self.assertRaises(ValueError):
            hooks.ha_relation_changed()
    def test_ha_relation_changed(self, parse_data, config, commit,
                                 get_corosync_conf, relation_ids, relation_set,
                                 get_cluster_nodes, related_units,
                                 configure_stonith, configure_monitor_host,
                                 configure_cluster_global, configure_corosync,
                                 oldest_peer, crm_opt_exists, peer_units,
                                 wait_for_pcmk, write_maas_dns_address):
        crm_opt_exists.return_value = False
        oldest_peer.return_value = True
        related_units.return_value = ['ha/0', 'ha/1', 'ha/2']
        get_cluster_nodes.return_value = ['10.0.3.2', '10.0.3.3', '10.0.3.4']
        relation_ids.return_value = ['hanode:1']
        get_corosync_conf.return_value = True
        cfg = {'debug': False,
               'prefer-ipv6': False,
               'corosync_transport': 'udpu',
               'corosync_mcastaddr': 'corosync_mcastaddr',
               'cluster_count': 3}

        config.side_effect = lambda key: cfg.get(key)

        rel_get_data = {'locations': {'loc_foo': 'bar rule inf: meh eq 1'},
                        'clones': {'cl_foo': 'res_foo meta interleave=true'},
                        'groups': {'grp_foo': 'res_foo'},
                        'colocations': {'co_foo': 'inf: grp_foo cl_foo'},
                        'resources': {'res_foo': 'ocf:heartbeat:IPaddr2',
                                      'res_bar': 'ocf:heartbear:IPv6addr'},
                        'resource_params': {'res_foo': 'params bar'},
                        'ms': {'ms_foo': 'res_foo meta notify=true'},
                        'orders': {'foo_after': 'inf: res_foo ms_foo'}}

        def fake_parse_data(relid, unit, key):
            return rel_get_data.get(key, {})

        parse_data.side_effect = fake_parse_data

        hooks.ha_relation_changed()
        relation_set.assert_any_call(relation_id='hanode:1', ready=True)
        configure_stonith.assert_called_with()
        configure_monitor_host.assert_called_with()
        configure_cluster_global.assert_called_with()
        configure_corosync.assert_called_with()
        write_maas_dns_address.assert_not_called()

        for kw, key in [('location', 'locations'),
                        ('clone', 'clones'),
                        ('group', 'groups'),
                        ('colocation', 'colocations'),
                        ('primitive', 'resources'),
                        ('ms', 'ms'),
                        ('order', 'orders')]:
            for name, params in rel_get_data[key].items():
                if name in rel_get_data['resource_params']:
                    res_params = rel_get_data['resource_params'][name]
                    commit.assert_any_call(
                        'crm -w -F configure %s %s %s %s' % (kw, name, params,
                                                             res_params))
                else:
                    commit.assert_any_call(
                        'crm -w -F configure %s %s %s' % (kw, name, params))
    def test_ha_relation_changed_dns_ha(
            self, parse_data, config, commit, get_corosync_conf, relation_ids,
            relation_set, get_cluster_nodes, related_units, configure_stonith,
            configure_monitor_host, configure_cluster_global,
            configure_corosync, is_leader, crm_opt_exists, wait_for_pcmk,
            validate_dns_ha, setup_maas_api, write_maas_dns_addr,
            set_cluster_symmetry, configure_pacemaker_remote_resources,
            configure_pacemaker_remote_stonith_resource,
            configure_resources_on_remotes, get_member_ready_nodes):
        validate_dns_ha.return_value = True
        crm_opt_exists.return_value = False
        is_leader.return_value = True
        related_units.return_value = ['ha/0', 'ha/1', 'ha/2']
        get_cluster_nodes.return_value = ['10.0.3.2', '10.0.3.3', '10.0.3.4']
        get_member_ready_nodes.return_value = ['10.0.3.2', '10.0.3.3',
                                               '10.0.3.4']
        relation_ids.return_value = ['ha:1']
        get_corosync_conf.return_value = True
        cfg = {'debug': False,
               'prefer-ipv6': False,
               'corosync_transport': 'udpu',
               'corosync_mcastaddr': 'corosync_mcastaddr',
               'cluster_count': 3,
               'maas_url': 'http://maas/MAAAS/',
               'maas_credentials': 'secret'}

        config.side_effect = lambda key: cfg.get(key)

        rel_get_data = {'locations': {'loc_foo': 'bar rule inf: meh eq 1'},
                        'clones': {'cl_foo': 'res_foo meta interleave=true'},
                        'groups': {'grp_foo': 'res_foo'},
                        'colocations': {'co_foo': 'inf: grp_foo cl_foo'},
                        'resources': {'res_foo_hostname': 'ocf:maas:dns'},
                        'resource_params': {
                            'res_foo_hostname': 'params bar '
                                                'ip_address="172.16.0.1"'},
                        'ms': {'ms_foo': 'res_foo meta notify=true'},
                        'orders': {'foo_after': 'inf: res_foo ms_foo'}}

        def fake_parse_data(relid, unit, key):
            return rel_get_data.get(key, {})

        parse_data.side_effect = fake_parse_data

        hooks.ha_relation_changed()
        self.assertTrue(validate_dns_ha.called)
        self.assertTrue(setup_maas_api.called)
        write_maas_dns_addr.assert_called_with('res_foo_hostname',
                                               '172.16.0.1')
        # Validate maas_credentials and maas_url are added to params
        commit.assert_any_call(
            'crm -w -F configure primitive res_foo_hostname ocf:maas:dns '
            'params bar ip_address="172.16.0.1" maas_url="http://maas/MAAAS/" '
            'maas_credentials="secret"')
    def test_ha_relation_changed_dns_ha(
            self, parse_data, config, commit, get_corosync_conf, relation_ids,
            relation_set, get_cluster_nodes, related_units, configure_stonith,
            configure_monitor_host, configure_cluster_global,
            configure_corosync, is_leader, crm_opt_exists, wait_for_pcmk,
            validate_dns_ha, setup_maas_api, write_maas_dns_addr,
            set_cluster_symmetry, configure_pacemaker_remote_resources,
            configure_pacemaker_remote_stonith_resource,
            configure_resources_on_remotes, get_member_ready_nodes):
        validate_dns_ha.return_value = True
        crm_opt_exists.return_value = False
        is_leader.return_value = True
        related_units.return_value = ['ha/0', 'ha/1', 'ha/2']
        get_cluster_nodes.return_value = ['10.0.3.2', '10.0.3.3', '10.0.3.4']
        get_member_ready_nodes.return_value = ['10.0.3.2', '10.0.3.3',
                                               '10.0.3.4']
        relation_ids.return_value = ['ha:1']
        get_corosync_conf.return_value = True
        cfg = {'debug': False,
               'prefer-ipv6': False,
               'corosync_transport': 'udpu',
               'corosync_mcastaddr': 'corosync_mcastaddr',
               'cluster_count': 3,
               'maas_url': 'http://maas/MAAAS/',
               'maas_credentials': 'secret'}

        config.side_effect = lambda key: cfg.get(key)

        rel_get_data = {'locations': {'loc_foo': 'bar rule inf: meh eq 1'},
                        'clones': {'cl_foo': 'res_foo meta interleave=true'},
                        'groups': {'grp_foo': 'res_foo'},
                        'colocations': {'co_foo': 'inf: grp_foo cl_foo'},
                        'resources': {'res_foo_hostname': 'ocf:maas:dns'},
                        'resource_params': {
                            'res_foo_hostname': 'params bar '
                                                'ip_address="172.16.0.1"'},
                        'ms': {'ms_foo': 'res_foo meta notify=true'},
                        'orders': {'foo_after': 'inf: res_foo ms_foo'}}

        def fake_parse_data(relid, unit, key):
            return rel_get_data.get(key, {})

        parse_data.side_effect = fake_parse_data

        hooks.ha_relation_changed()
        self.assertTrue(validate_dns_ha.called)
        self.assertTrue(setup_maas_api.called)
        write_maas_dns_addr.assert_called_with('res_foo_hostname',
                                               '172.16.0.1')
        # Validate maas_credentials and maas_url are added to params
        commit.assert_any_call(
            'crm -w -F configure primitive res_foo_hostname ocf:maas:dns '
            'params bar ip_address="172.16.0.1" maas_url="http://maas/MAAAS/" '
            'maas_credentials="secret"')
Exemplo n.º 6
0
    def test_ha_relation_changed_dns_ha_missing(
            self, parse_data, config, commit, get_corosync_conf, relation_ids,
            relation_set, get_cluster_nodes, related_units, configure_stonith,
            configure_monitor_host, configure_cluster_global,
            configure_corosync, is_leader, crm_opt_exists,
            wait_for_pcmk, validate_dns_ha, setup_maas_api):

        def fake_validate():
            raise utils.MAASConfigIncomplete('DNS HA invalid config')

        validate_dns_ha.side_effect = fake_validate
        crm_opt_exists.return_value = False
        is_leader.return_value = True
        related_units.return_value = ['ha/0', 'ha/1', 'ha/2']
        get_cluster_nodes.return_value = ['10.0.3.2', '10.0.3.3', '10.0.3.4']
        relation_ids.return_value = ['ha:1']
        get_corosync_conf.return_value = True
        cfg = {'debug': False,
               'prefer-ipv6': False,
               'corosync_transport': 'udpu',
               'corosync_mcastaddr': 'corosync_mcastaddr',
               'cluster_count': 3,
               'maas_url': 'http://maas/MAAAS/',
               'maas_credentials': None}

        config.side_effect = lambda key: cfg.get(key)

        rel_get_data = {'locations': {'loc_foo': 'bar rule inf: meh eq 1'},
                        'clones': {'cl_foo': 'res_foo meta interleave=true'},
                        'groups': {'grp_foo': 'res_foo'},
                        'colocations': {'co_foo': 'inf: grp_foo cl_foo'},
                        'resources': {'res_foo_hostname': 'ocf:maas:dns'},
                        'resource_params': {'res_foo_hostname': 'params bar'},
                        'ms': {'ms_foo': 'res_foo meta notify=true'},
                        'orders': {'foo_after': 'inf: res_foo ms_foo'}}

        def fake_parse_data(relid, unit, key):
            return rel_get_data.get(key, {})

        parse_data.side_effect = fake_parse_data
        with mock.patch.object(hooks, 'status_set') as mock_status_set:
            hooks.ha_relation_changed()
            mock_status_set.assert_called_with('blocked',
                                               'DNS HA invalid config')
Exemplo n.º 7
0
    def test_ha_relation_changed(
            self, parse_data, config, commit, get_corosync_conf, relation_ids,
            relation_set, get_cluster_nodes, related_units, configure_stonith,
            configure_monitor_host, configure_cluster_global,
            configure_corosync, is_leader, crm_opt_exists, wait_for_pcmk,
            write_maas_dns_address, set_cluster_symmetry,
            configure_pacemaker_remote_resources,
            configure_pacemaker_remote_stonith_resource,
            configure_resources_on_remotes, get_member_ready_nodes,
            configure_peer_stonith_resource, is_stonith_configured,
            trigger_corosync_update_from_leader, relation_type, remote_unit,
            mock_kv):
        def fake_crm_opt_exists(res_name):
            # res_ubuntu will take the "update resource" route
            # res_nova_eth0_vip will take the delete resource route
            return res_name in ["res_ubuntu", "res_nova_eth0_vip"]

        db = test_utils.FakeKvStore()
        mock_kv.return_value = db
        crm_opt_exists.side_effect = fake_crm_opt_exists
        commit.return_value = 0
        is_stonith_configured.return_value = False
        is_leader.return_value = True
        related_units.return_value = ['ha/0', 'ha/1', 'ha/2']
        get_cluster_nodes.return_value = ['10.0.3.2', '10.0.3.3', '10.0.3.4']
        get_member_ready_nodes.return_value = [
            '10.0.3.2', '10.0.3.3', '10.0.3.4'
        ]
        relation_ids.return_value = ['hanode:1']
        get_corosync_conf.return_value = True
        cfg = {
            'debug': False,
            'prefer-ipv6': False,
            'corosync_transport': 'udpu',
            'corosync_mcastaddr': 'corosync_mcastaddr',
            'cluster_count': 3,
            'failure_timeout': 180,
            'cluster_recheck_interval': 60
        }
        trigger_corosync_update_from_leader.return_value = False
        relation_type.return_value = "hanode"
        remote_unit.return_value = "hacluster/0"

        config.side_effect = lambda key: cfg.get(key)

        rel_get_data = {
            'locations': {
                'loc_foo': 'bar rule inf: meh eq 1'
            },
            'clones': {
                'cl_foo': 'res_foo meta interleave=true'
            },
            'groups': {
                'grp_foo': 'res_foo'
            },
            'colocations': {
                'co_foo': 'inf: grp_foo cl_foo'
            },
            'resources': {
                'res_foo': 'ocf:heartbeat:IPaddr2',
                'res_bar': 'ocf:heartbear:IPv6addr',
                'res_ubuntu': 'IPaddr2'
            },
            'resource_params': {
                'res_foo': 'params bar',
                'res_ubuntu': 'params ubuntu=42'
            },
            'ms': {
                'ms_foo': 'res_foo meta notify=true'
            },
            'orders': {
                'foo_after': 'inf: res_foo ms_foo'
            },
            'delete_resources': ['res_nova_eth0_vip']
        }

        def fake_parse_data(relid, unit, key):
            return rel_get_data.get(key, {})

        parse_data.side_effect = fake_parse_data

        with mock.patch.object(tempfile,
                               "NamedTemporaryFile",
                               side_effect=lambda: self.tmpfile):
            hooks.ha_relation_changed()

        relation_set.assert_any_call(relation_id='hanode:1', ready=True)
        configure_stonith.assert_called_with()
        configure_monitor_host.assert_called_with()
        configure_cluster_global.assert_called_with(180, 60)
        configure_corosync.assert_called_with()
        set_cluster_symmetry.assert_called_with()
        configure_pacemaker_remote_resources.assert_called_with()
        write_maas_dns_address.assert_not_called()

        # verify deletion of resources.
        crm_opt_exists.assert_any_call('res_nova_eth0_vip')
        commit.assert_any_call('crm resource cleanup res_nova_eth0_vip')
        commit.assert_any_call('crm -w -F resource stop res_nova_eth0_vip')
        commit.assert_any_call('crm -w -F configure delete res_nova_eth0_vip')

        for kw, key in [('location', 'locations'), ('clone', 'clones'),
                        ('group', 'groups'), ('colocation', 'colocations'),
                        ('primitive', 'resources'), ('ms', 'ms'),
                        ('order', 'orders')]:
            for name, params in rel_get_data[key].items():
                if name == "res_ubuntu":
                    commit.assert_any_call('crm configure load update %s' %
                                           self.tmpfile.name)

                elif name in rel_get_data['resource_params']:
                    res_params = rel_get_data['resource_params'][name]
                    commit.assert_any_call('crm -w -F configure %s %s %s %s' %
                                           (kw, name, params, res_params))
                else:
                    commit.assert_any_call('crm -w -F configure %s %s %s' %
                                           (kw, name, params))
Exemplo n.º 8
0
    def test_ha_relation_changed_dns_ha_missing(
            self, parse_data, config, commit, get_corosync_conf, relation_ids,
            relation_set, get_cluster_nodes, related_units, configure_stonith,
            configure_monitor_host, configure_cluster_global,
            configure_corosync, is_leader, crm_opt_exists, wait_for_pcmk,
            validate_dns_ha, setup_maas_api,
            trigger_corosync_update_from_leader, relation_type, remote_unit):
        def fake_validate():
            raise utils.MAASConfigIncomplete('DNS HA invalid config')

        validate_dns_ha.side_effect = fake_validate
        crm_opt_exists.return_value = False
        is_leader.return_value = True
        related_units.return_value = ['ha/0', 'ha/1', 'ha/2']
        get_cluster_nodes.return_value = ['10.0.3.2', '10.0.3.3', '10.0.3.4']
        relation_ids.return_value = ['ha:1']
        get_corosync_conf.return_value = True
        cfg = {
            'debug': False,
            'prefer-ipv6': False,
            'corosync_transport': 'udpu',
            'corosync_mcastaddr': 'corosync_mcastaddr',
            'cluster_count': 3,
            'maas_url': 'http://maas/MAAAS/',
            'maas_credentials': None
        }
        trigger_corosync_update_from_leader.return_value = False
        relation_type.return_value = "hanode"
        remote_unit.return_value = "hacluster/0"

        config.side_effect = lambda key: cfg.get(key)

        rel_get_data = {
            'locations': {
                'loc_foo': 'bar rule inf: meh eq 1'
            },
            'clones': {
                'cl_foo': 'res_foo meta interleave=true'
            },
            'groups': {
                'grp_foo': 'res_foo'
            },
            'colocations': {
                'co_foo': 'inf: grp_foo cl_foo'
            },
            'resources': {
                'res_foo_hostname': 'ocf:maas:dns'
            },
            'resource_params': {
                'res_foo_hostname': 'params bar'
            },
            'ms': {
                'ms_foo': 'res_foo meta notify=true'
            },
            'orders': {
                'foo_after': 'inf: res_foo ms_foo'
            }
        }

        def fake_parse_data(relid, unit, key):
            return rel_get_data.get(key, {})

        parse_data.side_effect = fake_parse_data
        with mock.patch.object(hooks, 'status_set') as mock_status_set:
            hooks.ha_relation_changed()
            mock_status_set.assert_called_with('blocked',
                                               'DNS HA invalid config')
Exemplo n.º 9
0
 def test_ha_relation_changed(self):
     _id_joined = self.patch('identity_joined')
     self.relation_get.return_value = True
     self.relation_ids.return_value = ['rid']
     ceph_hooks.ha_relation_changed()
     _id_joined.assert_called_with(relid='rid')
Exemplo n.º 10
0
 def test_ha_relation_changed(self):
     _id_joined = self.patch('identity_joined')
     self.relation_get.return_value = True
     self.relation_ids.return_value = ['rid']
     ceph_hooks.ha_relation_changed()
     _id_joined.assert_called_with(relid='rid')
Exemplo n.º 11
0
    def test_ha_relation_changed(self, parse_data, config, commit,
                                 get_corosync_conf, relation_ids, relation_set,
                                 get_cluster_nodes, related_units,
                                 configure_stonith, configure_monitor_host,
                                 configure_cluster_global, configure_corosync,
                                 is_leader, crm_opt_exists,
                                 wait_for_pcmk, write_maas_dns_address):

        def fake_crm_opt_exists(res_name):
            # res_ubuntu will take the "update resource" route
            return res_name == "res_ubuntu"

        crm_opt_exists.side_effect = fake_crm_opt_exists
        commit.return_value = 0
        is_leader.return_value = True
        related_units.return_value = ['ha/0', 'ha/1', 'ha/2']
        get_cluster_nodes.return_value = ['10.0.3.2', '10.0.3.3', '10.0.3.4']
        relation_ids.return_value = ['hanode:1']
        get_corosync_conf.return_value = True
        cfg = {'debug': False,
               'prefer-ipv6': False,
               'corosync_transport': 'udpu',
               'corosync_mcastaddr': 'corosync_mcastaddr',
               'cluster_count': 3}

        config.side_effect = lambda key: cfg.get(key)

        rel_get_data = {'locations': {'loc_foo': 'bar rule inf: meh eq 1'},
                        'clones': {'cl_foo': 'res_foo meta interleave=true'},
                        'groups': {'grp_foo': 'res_foo'},
                        'colocations': {'co_foo': 'inf: grp_foo cl_foo'},
                        'resources': {'res_foo': 'ocf:heartbeat:IPaddr2',
                                      'res_bar': 'ocf:heartbear:IPv6addr',
                                      'res_ubuntu': 'IPaddr2'},
                        'resource_params': {'res_foo': 'params bar',
                                            'res_ubuntu': 'params ubuntu=42'},
                        'ms': {'ms_foo': 'res_foo meta notify=true'},
                        'orders': {'foo_after': 'inf: res_foo ms_foo'}}

        def fake_parse_data(relid, unit, key):
            return rel_get_data.get(key, {})

        parse_data.side_effect = fake_parse_data

        with mock.patch.object(tempfile, "NamedTemporaryFile",
                               side_effect=lambda: self.tmpfile):
            hooks.ha_relation_changed()

        relation_set.assert_any_call(relation_id='hanode:1', ready=True)
        configure_stonith.assert_called_with()
        configure_monitor_host.assert_called_with()
        configure_cluster_global.assert_called_with()
        configure_corosync.assert_called_with()
        write_maas_dns_address.assert_not_called()

        for kw, key in [('location', 'locations'),
                        ('clone', 'clones'),
                        ('group', 'groups'),
                        ('colocation', 'colocations'),
                        ('primitive', 'resources'),
                        ('ms', 'ms'),
                        ('order', 'orders')]:
            for name, params in rel_get_data[key].items():
                if name == "res_ubuntu":
                    commit.assert_any_call(
                        'crm configure load update %s' % self.tmpfile.name)

                elif name in rel_get_data['resource_params']:
                    res_params = rel_get_data['resource_params'][name]
                    commit.assert_any_call(
                        'crm -w -F configure %s %s %s %s' % (kw, name, params,
                                                             res_params))
                else:
                    commit.assert_any_call(
                        'crm -w -F configure %s %s %s' % (kw, name, params))