Esempio n. 1
0
    def test_ag_primary_replica_other_clustered_node(self, _is_ag_ready,
                                                     _clustered_nodes,
                                                     _mssql_db_client):

        _is_ag_ready.return_value = True
        _mssql_db_client.return_value.get_ag_primary_replica.return_value = \
            self.TEST_PRIMARY_REPLICA_NAME
        _clustered_nodes.return_value = {
            'node-1': {
                'address': '10.0.0.11',
                'clustered': True
            },
            'node-2': {
                'address': '10.0.0.12',
                'clustered': True
            }
        }
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        cluster.state.ag_configured = False
        primary_replica = cluster.ag_primary_replica

        _mssql_db_client.assert_called_once_with('node-2')
        mock_ret_value = _mssql_db_client.return_value
        mock_ret_value.get_ag_primary_replica.assert_called_once_with(
            cluster.AG_NAME)
        self.assertEqual(primary_replica, self.TEST_PRIMARY_REPLICA_NAME)
Esempio n. 2
0
    def test_sync_logins_from_primary_replica(self, _ag_primary_replica,
                                              _mssql_db_client):
        _ag_primary_replica.return_value = self.TEST_PRIMARY_REPLICA_NAME
        mocked_primary_db_client = mock.MagicMock()
        mocked_primary_db_client.get_sql_logins.return_value = \
            self.TEST_PRIMARY_LOGINS
        mocked_this_db_client = mock.MagicMock()
        mocked_this_db_client.get_sql_logins.return_value = \
            self.TEST_SECONDARY_LOGINS
        _mssql_db_client.side_effect = [
            mocked_primary_db_client, mocked_this_db_client
        ]
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        cluster.sync_logins_from_primary_replica()

        _mssql_db_client.assert_has_calls(
            [mock.call(self.TEST_PRIMARY_REPLICA_NAME),
             mock.call()])
        mocked_this_db_client.assert_has_calls([mock.call.get_sql_logins()])
        mocked_this_db_client.assert_has_calls([
            mock.call.get_sql_logins(),
            mock.call.create_login(name='test-login-3',
                                   sid='sid3',
                                   password='******',
                                   is_hashed_password=True,
                                   server_roles=['test-role3']),
            mock.call.create_login(name='test-login-4',
                                   sid='sid4',
                                   password='******',
                                   is_hashed_password=True,
                                   server_roles=['test-role4'])
        ])
Esempio n. 3
0
    def test_ready_nodes(self):
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        cluster.state.initialized_nodes['node-1'] = {
            'address': '10.0.0.11',
            'ready_to_cluster': True
        }
        cluster.state.initialized_nodes['node-2'] = {
            'address': '10.0.0.12',
            'ready_to_cluster': True,
            'clustered': True
        }
        cluster.state.initialized_nodes['node-3'] = {'address': '10.0.0.13'}
        ready_nodes = cluster.ready_nodes

        self.assertEqual(
            ready_nodes, {
                'node-1': {
                    'address': '10.0.0.11',
                    'ready_to_cluster': True
                },
                'node-2': {
                    'address': '10.0.0.12',
                    'ready_to_cluster': True,
                    'clustered': True
                }
            })
Esempio n. 4
0
    def test_configure_primary_replica_ag_ready(self, _is_ag_ready,
                                                _ready_nodes, _ag_replicas,
                                                _create_ag, _mssql_db_client):

        _is_ag_ready.return_value = True
        _ready_nodes.return_value = {
            'test-node-1': {
                'address': '10.0.0.11'
            },
            'test-node-2': {
                'address': '10.0.0.12'
            },
            'test-node-3': {
                'address': '10.0.0.13'
            }
        }
        _ag_replicas.return_value = ['test-node-1', 'test-node-2']
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        rel_id = self.harness.add_relation('cluster', 'mssql')
        self.harness.add_relation_unit(rel_id, 'mssql/1')
        cluster.configure_primary_replica()

        _create_ag.assert_not_called()
        _mssql_db_client.assert_called_once_with()
        mock_ret_value = _mssql_db_client.return_value
        mock_ret_value.add_replicas.assert_called_once_with(
            cluster.AG_NAME, {'test-node-3': {
                'address': '10.0.0.13'
            }})
        rel_data = self.harness.get_relation_data(rel_id, 'mssql/0')
        self.assertIsNotNone(rel_data.get('nonce'))
Esempio n. 5
0
    def test_setup_pacemaker_mssql_login(self, _open, _chmod, _chown, _pwgen,
                                         _mssql_db_client):

        _pwgen.return_value = 'test-password'
        self.harness.begin()
        self.harness.charm.cluster = interface_mssql_cluster.MssqlCluster(
            self.harness.charm, 'cluster')
        self.harness.charm.ha = interface_hacluster.HaCluster(
            self.harness.charm, 'ha')
        self.harness.charm.ha.setup_pacemaker_mssql_login()

        _pwgen.assert_called_once_with(32)
        _mssql_db_client.assert_called_once_with()
        db_client_mock = _mssql_db_client.return_value
        db_client_mock.create_login.assert_called_once_with(
            name=self.harness.charm.ha.PACEMAKER_LOGIN_NAME,
            password='******',
            server_roles=['sysadmin'])
        _open.assert_called_once_with(
            self.harness.charm.ha.PACEMAKER_LOGIN_CREDS_FILE, 'w')
        _open.return_value.write.assert_called_once_with('{}\n{}\n'.format(
            self.harness.charm.ha.PACEMAKER_LOGIN_NAME, 'test-password'))
        _chmod.assert_called_once_with(
            self.harness.charm.ha.PACEMAKER_LOGIN_CREDS_FILE, 0o400)
        _chown.assert_called_once_with(
            self.harness.charm.ha.PACEMAKER_LOGIN_CREDS_FILE, 0, 0)
        self.assertTrue(self.harness.charm.ha.state.pacemaker_login_ready)
Esempio n. 6
0
    def test_configure_cluster_node_secondary_replica(
            self, _configure_master_cert, _mssql_db_client,
            _is_primary_replica, _configure_primary_replica,
            _configure_secondary_replica):

        _is_primary_replica.return_value = False
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        cluster.state.initialized_nodes[self.TEST_NODE_NAME] = {
            'address': self.TEST_BIND_ADDRESS
        }
        rel_id = self.harness.add_relation('cluster', 'mssql')
        self.harness.add_relation_unit(rel_id, 'mssql/1')
        cluster.configure_cluster_node()

        _configure_master_cert.assert_called_once_with()
        _mssql_db_client.assert_called_once_with()
        mock_ret_value = _mssql_db_client.return_value
        mock_ret_value.setup_db_mirroring_endpoint.assert_called_once_with()
        self.assertTrue(cluster.state.initialized_nodes[self.TEST_NODE_NAME]
                        ['ready_to_cluster'])
        rel_data = self.harness.get_relation_data(rel_id, 'mssql/0')
        self.assertEqual(rel_data.get('ready_to_cluster'), 'true')
        _configure_primary_replica.assert_not_called()
        _configure_secondary_replica.assert_called_once_with()
Esempio n. 7
0
    def test_on_changed(self, _master_cert, _set_sa_password,
                        _append_hosts_entry, _configure_cluster_node):
        _master_cert.return_value = self.TEST_MASTER_CERT
        self.harness.set_leader()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        rel_id = self.harness.add_relation('cluster', 'mssql')
        self.harness.add_relation_unit(rel_id, 'mssql/1')
        self.harness.update_relation_data(
            rel_id, 'mssql/1', {
                'node_name': self.TEST_NODE_NAME,
                'node_address': self.TEST_BIND_ADDRESS,
                'ready_to_cluster': 'true',
            })

        node_state = cluster.state.initialized_nodes.get(self.TEST_NODE_NAME)
        self.assertIsNotNone(node_state)
        self.assertEqual(node_state.get('address'), self.TEST_BIND_ADDRESS)
        self.assertTrue(node_state.get('ready_to_cluster'))
        self.assertIsNone(node_state.get('clustered'))
        _set_sa_password.assert_called_once_with()
        _append_hosts_entry.assert_called_once_with(self.TEST_BIND_ADDRESS,
                                                    [self.TEST_NODE_NAME])
        _configure_cluster_node.assert_called_once_with()
Esempio n. 8
0
    def test_on_initialized_unit(self, _master_cert, _set_master_cert,
                                 _append_hosts_entry, _configure_cluster_node):
        _master_cert.return_value = None
        self.harness.set_leader()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        rel_id = self.harness.add_relation('cluster', 'mssql')
        self.harness.add_relation_unit(rel_id, 'mssql/1')
        cluster.on.initialized_unit.emit()

        node_state = cluster.state.initialized_nodes.get(self.TEST_NODE_NAME)
        self.assertIsNotNone(node_state)
        self.assertEqual(node_state.get('address'), self.TEST_BIND_ADDRESS)
        self.assertIsNone(node_state.get('ready_to_cluster'))
        self.assertIsNone(node_state.get('clustered'))

        rel_data = self.harness.get_relation_data(rel_id, 'mssql/0')
        self.assertEqual(rel_data.get('node_name'), self.TEST_NODE_NAME)
        self.assertEqual(rel_data.get('node_address'), self.TEST_BIND_ADDRESS)
        self.assertIsNone(rel_data.get('ready_to_cluster'))
        self.assertIsNone(rel_data.get('clustered'))

        _append_hosts_entry.assert_called_once_with(self.TEST_BIND_ADDRESS,
                                                    [self.TEST_NODE_NAME])
        _set_master_cert.assert_called_once_with()
        _configure_cluster_node.assert_not_called()
Esempio n. 9
0
    def test_ag_replicas_other_clustered_node(self, _is_ag_ready,
                                              _clustered_nodes,
                                              _mssql_db_client):

        _is_ag_ready.return_value = True
        _mssql_db_client.return_value.get_ag_replicas.return_value = \
            ['node-1', 'node-2']
        _clustered_nodes.return_value = {
            'node-1': {
                'address': '10.0.0.11',
                'clustered': True
            },
            'node-2': {
                'address': '10.0.0.12',
                'clustered': True
            }
        }
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        cluster.state.ag_configured = False
        ag_replicas = cluster.ag_replicas

        _mssql_db_client.assert_called_once_with('node-2')
        mock_ret_value = _mssql_db_client.return_value
        mock_ret_value.get_ag_replicas.assert_called_once_with(cluster.AG_NAME)
        self.assertListEqual(ag_replicas, ['node-1', 'node-2'])
Esempio n. 10
0
    def test_set_master_cert(self, _pwgen, _mssql_db_client):
        _pwgen.side_effect = [
            'test-master-key-password', 'test-master-cert-key-password'
        ]
        _mssql_db_client.return_value.create_master_cert.return_value = \
            ('test-cert'.encode(), 'test-cert-key'.encode())
        self.harness.set_leader()
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        rel_id = self.harness.add_relation('cluster', 'mssql')
        self.harness.add_relation_unit(rel_id, 'mssql/1')
        cluster.set_master_cert()

        self.assertTrue(cluster.state.master_cert_configured)
        _pwgen.assert_has_calls([mock.call(32), mock.call(32)])
        _mssql_db_client.assert_called_once_with()
        mock_ret_value = _mssql_db_client.return_value
        mock_ret_value.create_master_encryption_key.assert_called_once_with(
            'test-master-key-password')
        mock_ret_value.create_master_cert.assert_called_once_with(
            'test-master-cert-key-password')
        app_rel_data = self.harness.get_relation_data(rel_id, 'mssql')
        self.assertEqual(app_rel_data.get('master_key_password'),
                         'test-master-key-password')
        self.assertEqual(app_rel_data.get('master_cert'),
                         b64encode('test-cert'.encode()).decode())
        self.assertEqual(app_rel_data.get('master_cert_key'),
                         b64encode('test-cert-key'.encode()).decode())
        self.assertEqual(app_rel_data.get('master_cert_key_password'),
                         'test-master-cert-key-password')
Esempio n. 11
0
    def test_is_primary_replica_current_node(self, _ag_primary_replica):
        _ag_primary_replica.return_value = self.TEST_NODE_NAME
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')

        self.assertTrue(cluster.is_primary_replica)
Esempio n. 12
0
    def test_is_primary_replica_other_node(self, _ag_primary_replica):
        _ag_primary_replica.return_value = 'mssql-primary-replica'
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')

        self.assertFalse(cluster.is_primary_replica)
Esempio n. 13
0
    def test_on_joined(self, _is_ag_ready, _apt_install,
                       _setup_pacemaker_mssql_login, _update_hacluster_vip):
        _is_ag_ready.return_value = True
        self.harness.begin()
        self.harness.charm.cluster = interface_mssql_cluster.MssqlCluster(
            self.harness.charm, 'cluster')
        self.harness.charm.ha = interface_hacluster.HaCluster(
            self.harness.charm, 'ha')
        rel_id = self.harness.add_relation('ha', 'hacluster')
        self.harness.add_relation_unit(rel_id, 'hacluster/0')

        _apt_install.assert_called_once_with(
            packages=self.harness.charm.ha.APT_PACKAGES, fatal=True)
        _setup_pacemaker_mssql_login.assert_called_once_with()
        _update_hacluster_vip.assert_called_once()

        rel_data = self.harness.get_relation_data(rel_id, 'mssql/0')
        expected_rel_data = {}
        keys = ['resources', 'resource_params', 'ms', 'colocations', 'orders']
        for key in keys:
            json_value = rel_data.get('json_{}'.format(key))
            self.assertIsNotNone(json_value)
            expected_rel_data.update({key: json.loads(json_value)})
        group_name = VIP_GROUP_NAME.format(service='mssql')
        self.assertDictEqual(
            expected_rel_data, {
                'resources': {
                    'ag_cluster': 'ocf:mssql:ag'
                },
                'resource_params': {
                    'ag_cluster':
                    'params ag_name="{}" '
                    'meta failure-timeout=60s '
                    'op start timeout=60s '
                    'op stop timeout=60s '
                    'op promote timeout=60s '
                    'op demote timeout=10s '
                    'op monitor timeout=60s interval=10s '
                    'op monitor timeout=60s interval=11s role="Master" '
                    'op monitor timeout=60s interval=12s role="Slave" '
                    'op notify timeout=60s'.format(
                        self.harness.charm.cluster.AG_NAME)
                },
                'ms': {
                    'ms-ag_cluster':
                    'ag_cluster meta '
                    'master-max="1" master-node-max="1" '
                    'clone-max="3" clone-node-max="1" notify="true"'
                },
                'colocations': {
                    'vip_on_master':
                    'inf: {} ms-ag_cluster:Master'.format(group_name)
                },
                'orders': {
                    'ag_first':
                    'inf: ms-ag_cluster:promote {}:start'.format(group_name)
                }
            })
Esempio n. 14
0
    def test_is_primary_replica_leader_node(self, _ag_primary_replica):
        _ag_primary_replica.return_value = None
        self.harness.set_leader()
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')

        self.assertTrue(cluster.is_primary_replica)
Esempio n. 15
0
 def test_configure_primary_replica_ag_not_ready(self, _is_ag_ready,
                                                 _create_ag):
     _is_ag_ready.return_value = False
     self.harness.disable_hooks()
     self.harness.begin()
     cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                    'cluster')
     cluster.configure_primary_replica()
     _create_ag.assert_called_once_with()
Esempio n. 16
0
    def test_ag_replicas_no_clustered_nodes(self, _is_ag_ready,
                                            _mssql_db_client):
        _is_ag_ready.return_value = True
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        ag_replicas = cluster.ag_replicas

        _mssql_db_client.assert_not_called()
        self.assertListEqual(ag_replicas, [])
Esempio n. 17
0
    def test_ag_primary_replica_no_clustered_nodes(self, _is_ag_ready,
                                                   _mssql_db_client):
        _is_ag_ready.return_value = True
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        cluster.state.ag_configured = False
        primary_replica = cluster.ag_primary_replica

        _mssql_db_client.assert_not_called()
        self.assertIsNone(primary_replica)
Esempio n. 18
0
    def test_on_changed(self):
        self.harness.begin()
        self.harness.charm.cluster = interface_mssql_cluster.MssqlCluster(
            self.harness.charm, 'cluster')
        self.harness.charm.ha = interface_hacluster.HaCluster(
            self.harness.charm, 'ha')
        rel_id = self.harness.add_relation('ha', 'hacluster')
        self.harness.add_relation_unit(rel_id, 'hacluster/0')
        self.harness.update_relation_data(rel_id, 'hacluster/0',
                                          {'clustered': 'yes'})

        self.assertEqual(self.harness.charm.unit.status,
                         self.harness.charm.ha.UNIT_ACTIVE_STATUS)
        self.assertTrue(self.harness.charm.ha.state.ha_cluster_ready)
Esempio n. 19
0
    def test_ag_replicas_ag_configured(self, _is_ag_ready, _mssql_db_client):
        _is_ag_ready.return_value = True
        _mssql_db_client.return_value.get_ag_replicas.return_value = \
            ['node-1', 'node-2', 'node-3']
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        cluster.state.ag_configured = True
        ag_replicas = cluster.ag_replicas

        _mssql_db_client.assert_called_once_with()
        mock_ret_value = _mssql_db_client.return_value
        mock_ret_value.get_ag_replicas.assert_called_once_with(cluster.AG_NAME)
        self.assertListEqual(ag_replicas, ['node-1', 'node-2', 'node-3'])
Esempio n. 20
0
    def test_add_to_initialized_nodes(self, _append_hosts_entry):
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        cluster.add_to_initialized_nodes(self.TEST_NODE_NAME,
                                         self.TEST_BIND_ADDRESS,
                                         ready_to_cluster=True,
                                         clustered=True)

        node_state = cluster.state.initialized_nodes.get(self.TEST_NODE_NAME)
        self.assertIsNotNone(node_state)
        self.assertEqual(node_state.get('address'), self.TEST_BIND_ADDRESS)
        self.assertTrue(node_state.get('ready_to_cluster'))
        self.assertTrue(node_state.get('clustered'))
Esempio n. 21
0
    def test_join_existing_ag(self, _mssql_db_client):
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        rel_id = self.harness.add_relation('cluster', 'mssql')
        self.harness.add_relation_unit(rel_id, 'mssql/1')
        cluster.join_existing_ag()

        self.assertTrue(cluster.state.ag_configured)
        self.assertEqual(self.harness.charm.unit.status,
                         cluster.UNIT_ACTIVE_STATUS)
        _mssql_db_client.assert_called_once_with()
        _mssql_db_client.return_value.join_ag.assert_called_once_with(
            cluster.AG_NAME)
        unit_rel_data = self.harness.get_relation_data(rel_id, 'mssql/0')
        self.assertEqual(unit_rel_data.get('clustered'), 'true')
Esempio n. 22
0
    def test_ag_primary_replica_ag_configured(self, _is_ag_ready,
                                              _mssql_db_client):

        _is_ag_ready.return_value = True
        _mssql_db_client.return_value.get_ag_primary_replica.return_value = \
            self.TEST_PRIMARY_REPLICA_NAME
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        cluster.state.ag_configured = True
        primary_replica = cluster.ag_primary_replica

        _mssql_db_client.assert_called_once_with()
        mock_ret_value = _mssql_db_client.return_value
        mock_ret_value.get_ag_primary_replica.assert_called_once_with(
            cluster.AG_NAME)
        self.assertEqual(primary_replica, self.TEST_PRIMARY_REPLICA_NAME)
Esempio n. 23
0
    def test_on_joined(self):
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        cluster.state.initialized_nodes = {
            self.TEST_NODE_NAME: {
                'address': self.TEST_BIND_ADDRESS,
                'ready_to_cluster': 'true',
            }
        }
        rel_id = self.harness.add_relation('cluster', 'mssql')
        self.harness.add_relation_unit(rel_id, 'mssql/1')

        rel_data = self.harness.get_relation_data(rel_id, 'mssql/0')
        self.assertEqual(rel_data.get('node_name'), self.TEST_NODE_NAME)
        self.assertEqual(rel_data.get('node_address'), self.TEST_BIND_ADDRESS)
        self.assertEqual(rel_data.get('ready_to_cluster'), 'true')
        self.assertIsNone(rel_data.get('clustered'))
Esempio n. 24
0
    def test_on_created_ag(self, _setup_pacemaker_mssql_login,
                           _mssql_db_client):
        self.harness.begin()
        self.harness.charm.cluster = interface_mssql_cluster.MssqlCluster(
            self.harness.charm, 'cluster')
        self.harness.charm.ha = interface_hacluster.HaCluster(
            self.harness.charm, 'ha')
        self.harness.charm.cluster.on.created_ag.emit()

        _setup_pacemaker_mssql_login.assert_called_once_with()
        _mssql_db_client.assert_called_once_with()
        db_client_mock = _mssql_db_client.return_value
        db_client_mock.return_value.exec_t_sql.assert_called_once_with("""
        GRANT ALTER, CONTROL, VIEW DEFINITION
            ON AVAILABILITY GROUP::[{ag_name}] TO [{login_name}]
        GRANT VIEW SERVER STATE TO [{login_name}]
        """.format(ag_name=self.harness.charm.cluster.AG_NAME,
                   login_name=self.harness.charm.ha.PACEMAKER_LOGIN_NAME))
Esempio n. 25
0
    def test_set_sa_password(self, _choice):
        _choice.return_value = 'p'
        self.harness.set_leader()
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        rel_id = self.harness.add_relation('cluster', 'mssql')
        self.harness.add_relation_unit(rel_id, 'mssql/1')
        cluster.set_sa_password()

        _choice_calls = []
        _choice_calls += [mock.call(string.ascii_lowercase)] * 8
        _choice_calls += [mock.call(string.ascii_uppercase)] * 8
        _choice_calls += [mock.call(string.digits)] * 8
        _choice_calls += [mock.call(string.punctuation)] * 8
        _choice.assert_has_calls(_choice_calls)
        app_rel_data = self.harness.get_relation_data(rel_id, 'mssql')
        self.assertEqual(app_rel_data.get('sa_password'), 'p' * 32)
Esempio n. 26
0
    def test_on_changed(self, _is_ag_ready, _is_ha_cluster_ready,
                        _is_primary_replica, _pwgen, _mssql_db_client,
                        _set_unit_rel_nonce):
        _is_ag_ready.return_value = True
        _is_ha_cluster_ready.return_value = True
        _is_primary_replica.return_value = True
        _pwgen.return_value = 'test-password'
        self.harness.set_leader()
        self.harness.begin()
        self.harness.charm.cluster = interface_mssql_cluster.MssqlCluster(
            self.harness.charm, 'cluster')
        self.harness.charm.ha = interface_hacluster.HaCluster(
            self.harness.charm, 'ha')
        self.harness.charm.db_provider = \
            interface_mssql_provider.MssqlDBProvider(self.harness.charm, 'db')
        rel_id = self.harness.add_relation('db', 'mssqlconsumer')
        self.harness.add_relation_unit(rel_id, 'mssqlconsumer/0')
        self.harness.update_relation_data(rel_id, 'mssqlconsumer/0', {
            'database': 'testdb',
            'username': '******'
        })

        _pwgen.assert_called_once_with(32)
        _mssql_db_client.assert_called_once_with()
        db_client_mock = _mssql_db_client.return_value
        db_client_mock.create_database.assert_called_once_with(
            db_name='testdb', ag_name=self.harness.charm.cluster.AG_NAME)
        db_client_mock.create_login.assert_called_once_with(
            name='testuser', password='******')
        db_client_mock.grant_access.assert_called_once_with(
            db_name='testdb', db_user_name='testuser')
        _set_unit_rel_nonce.assert_called_once_with()

        rel_unit_data = self.harness.get_relation_data(rel_id, 'mssql/0')
        self.assertEqual(rel_unit_data.get('db_host'),
                         self.harness.charm.ha.bind_address)
        self.assertEqual(rel_unit_data.get('password'), 'test-password')
        rel_app_data = self.harness.get_relation_data(rel_id, 'mssql')
        self.assertEqual(rel_app_data.get('db_host'),
                         self.harness.charm.ha.bind_address)
        self.assertEqual(rel_app_data.get('password'), 'test-password')
Esempio n. 27
0
    def test_configure_secondary_replica(self, _ag_primary_replica,
                                         _is_ag_ready, _mssql_db_client,
                                         _join_existing_ag,
                                         _sync_logins_from_primary_replica):

        _is_ag_ready.return_value = True
        _ag_primary_replica.return_value = self.TEST_PRIMARY_REPLICA_NAME
        _mssql_db_client.return_value.get_ag_replicas.return_value = \
            [self.TEST_PRIMARY_REPLICA_NAME, self.TEST_NODE_NAME]
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        cluster.configure_secondary_replica()

        _mssql_db_client.assert_called_once_with(
            self.TEST_PRIMARY_REPLICA_NAME)
        mock_ret_value = _mssql_db_client.return_value
        mock_ret_value.get_ag_replicas.assert_called_once_with(cluster.AG_NAME)
        _join_existing_ag.assert_called_once_with()
        _sync_logins_from_primary_replica.assert_called_once_with()
Esempio n. 28
0
    def test_configure_master_cert(self, _master_cert, _mssql_db_client):
        _master_cert.return_value = self.TEST_MASTER_CERT
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        cluster.state.initialized_nodes = {
            self.TEST_NODE_NAME: {
                'address': self.TEST_BIND_ADDRESS,
                'ready_to_cluster': 'true',
            }
        }
        cluster.configure_master_cert()

        self.assertTrue(cluster.state.master_cert_configured)
        _mssql_db_client.assert_called_once_with()
        mock_ret_value = _mssql_db_client.return_value
        mock_ret_value.create_master_encryption_key.assert_called_once_with(
            'test_key_password')
        mock_ret_value.setup_master_cert.assert_called_once_with(
            'test_master_cert'.encode(), 'test_master_cert_key'.encode(),
            'test_cert_key_password')
Esempio n. 29
0
    def test_create_ag(self, _ready_nodes, _mssql_db_client):
        _ready_nodes.return_value = ['node1', 'node2', 'node3']
        self.harness.set_leader()
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        rel_id = self.harness.add_relation('cluster', 'mssql')
        self.harness.add_relation_unit(rel_id, 'mssql/1')
        cluster.create_ag()

        self.assertTrue(cluster.state.ag_configured)
        self.assertEqual(self.harness.charm.unit.status,
                         cluster.UNIT_ACTIVE_STATUS)
        _mssql_db_client.assert_called_once_with()
        _mssql_db_client.return_value.create_ag.assert_called_once_with(
            cluster.AG_NAME, ['node1', 'node2', 'node3'])
        unit_rel_data = self.harness.get_relation_data(rel_id, 'mssql/0')
        self.assertEqual(unit_rel_data.get('clustered'), 'true')
        self.assertIsNotNone(unit_rel_data.get('nonce'))
        app_rel_data = self.harness.get_relation_data(rel_id, 'mssql')
        self.assertEqual(app_rel_data.get('ag_ready'), 'true')
Esempio n. 30
0
    def test_master_cert(self):
        self.harness.disable_hooks()
        self.harness.begin()
        cluster = interface_mssql_cluster.MssqlCluster(self.harness.charm,
                                                       'cluster')
        rel_id = self.harness.add_relation('cluster', 'mssql')
        self.harness.add_relation_unit(rel_id, 'mssql/1')
        self.harness.update_relation_data(
            rel_id, 'mssql', {
                'master_key_password': '******',
                'master_cert': 'test-cert',
                'master_cert_key': 'test-cert-key',
                'master_cert_key_password': '******',
            })
        master_cert = cluster.master_cert

        self.assertEqual(
            master_cert, {
                'master_key_password': '******',
                'master_cert': 'test-cert',
                'master_cert_key': 'test-cert-key',
                'master_cert_key_password': '******',
            })