Esempio n. 1
0
    def configure_tls(self, certificates_interface=None):
        if certificates_interface is None:
            certificates_interface = reactive.endpoint_from_flag(
                'certificates.available')
        tls_objects = super(
            charms_openstack.charm.OpenStackAPICharm, self).configure_tls(
                certificates_interface=certificates_interface)
        with is_data_changed(
                'configure_ssl.ssl_objects', tls_objects) as changed:
            if tls_objects:
                for tls_object in tls_objects:
                    self.set_state('ssl.requested', True)
                    path = NGINX_SSL_DIR
                    self.configure_cert(
                        path,
                        tls_object['cert'],
                        tls_object['key'],
                        cn=tls_object['cn'])

                    if 'chain' in tls_object:
                        self.configure_wsgate_ca(
                            tls_object["ca"], tls_object['chain'])
                    else:
                        self.configure_wsgate_ca(tls_object["ca"])
                    self.configure_nginx(path, tls_object['cn'])
                    self.service_reload('nginx')

                self.remove_state('ssl.requested')
                self.set_state('ssl.enabled', True)
            else:
                self.set_state('ssl.enabled', False)
Esempio n. 2
0
    def configure_ssl(self, keystone_interface=None):
        """Configure SSL certificates and keys

        NOTE(AJK): This function tries to minimise the work it does,
        particularly with writing files and restarting apache.

        @param keystone_interface KeystoneRequires class
        """
        keystone_interface = (
            relations.endpoint_from_flag('identity-service.available.ssl')
            or relations.endpoint_from_flag(
                'identity-service.available.ssl_legacy'))
        ssl_objects = self.get_certs_and_keys(
            keystone_interface=keystone_interface)
        with is_data_changed('configure_ssl.ssl_objects',
                             ssl_objects) as changed:
            if ssl_objects:
                if changed:
                    for ssl in ssl_objects:
                        self.set_state('ssl.requested', True)
                        self.configure_cert(ssl['cert'],
                                            ssl['key'],
                                            cn=ssl['cn'])
                        self.configure_ca(ssl['ca'])

                    if not os_utils.snap_install_requested():
                        self.configure_apache()

                    self.remove_state('ssl.requested')
                self.set_state('ssl.enabled', True)
            else:
                self.set_state('ssl.enabled', False)
        amqp_ssl = relations.endpoint_from_flag('amqp.available.ssl')
        if amqp_ssl:
            self.configure_rabbit_cert(amqp_ssl)
def maybe_setup_endpoint(keystone):
    """When the keystone interface connects, register this unit in the keystone
    catalogue.
    """
    with provide_charm_instance() as instance:
        args = [
            instance.service_type, instance.region, instance.public_url,
            instance.internal_url, instance.admin_url
        ]
        # This function checkes that the data has changed before sending it
        with is_data_changed('charms.openstack.register-endpoints', args) as c:
            if c:
                keystone.register_endpoints(*args)
Esempio n. 4
0
def register_endpoints(keystone):
    """Register the endpoints when the identity-service connects.
    Note that this charm doesn't use the default endpoint registration function
    as it needs to register multiple endpoints, and thus needs a custom
    function in the charm.
    """
    with charms_openstack.charm.provide_charm_instance() as congress_charm:
        args = [congress_charm.service_type, congress_charm.region,
                congress_charm.public_url, congress_charm.internal_url,
                congress_charm.admin_url]
        # This function checkes that the data has changed before sending it
        with is_data_changed('charms.openstack.register-endpoints', args) as c:
            if c:
                keystone.register_endpoints(*args)
Esempio n. 5
0
def register_endpoints(keystone):
    """Register the endpoints when the identity-service connects.
    Note that this charm doesn't use the default endpoint registration function
    as it needs to register multiple endpoints, and thus needs a custom
    function in the charm.
    """
    with charms_openstack.charm.provide_charm_instance() as congress_charm:
        args = [
            congress_charm.service_type, congress_charm.region,
            congress_charm.public_url, congress_charm.internal_url,
            congress_charm.admin_url
        ]
        # This function checkes that the data has changed before sending it
        with is_data_changed('charms.openstack.register-endpoints', args) as c:
            if c:
                keystone.register_endpoints(*args)
Esempio n. 6
0
    def test_is_data_changed(self):
        class FakeKV(object):
            def __init__(self):
                self.store = {}

            def get(self, key):
                return self.store.get(key, None)

            def set(self, key, value):
                self.store[key] = value

        store = FakeKV()
        self.patch_object(utils.core.unitdata, "kv", new=lambda: store)
        with utils.is_data_changed('foo', {
                'foo': 'FOO',
                'bar': u'\ua000BAR'
        }) as f:
            self.assertTrue(f)
        with utils.is_data_changed('foo', {
                'foo': 'FOO',
                'bar': u'\ua000BAR'
        }) as f:
            self.assertFalse(f)
        with utils.is_data_changed('bar', {
                'foo': 'FOO',
                'bar': u'\ua000BAR'
        }) as f:
            self.assertTrue(f)
        with utils.is_data_changed('bar', {
                'foo': 'FOO',
                'bar': u'\ua000BAR'
        }) as f:
            self.assertFalse(f)
        # check that raising an exception doesn't cause a data change
        hash = store.get('charms.openstack.data_changed.bar')
        try:
            with utils.is_data_changed('bar', "string") as f:
                self.assertTrue(f)
                raise Exception()
        except Exception:
            pass
        self.assertEqual(hash, store.get('charms.openstack.data_changed.bar'))
        # check that raising an exception AND having the flag set causes a
        # change
        try:
            with utils.is_data_changed('bar',
                                       "string",
                                       no_change_on_exception=False) as f:
                self.assertTrue(f)
                raise Exception()
        except Exception:
            pass
        self.assertNotEqual(hash,
                            store.get('charms.openstack.data_changed.bar'))
Esempio n. 7
0
    def configure_ssl(self, keystone_interface=None):
        """Configure SSL certificates and keys

        NOTE(AJK): This function tries to minimise the work it does,
        particularly with writing files and restarting apache.

        @param keystone_interface KeystoneRequires class
        """
        keystone_interface = (
            relations.endpoint_from_flag('identity-service.available.ssl') or
            relations
            .endpoint_from_flag('identity-service.available.ssl_legacy'))
        certificates_interface = relations.endpoint_from_flag(
            'certificates.batch.cert.available')
        ssl_objects = self.get_certs_and_keys(
            keystone_interface=keystone_interface,
            certificates_interface=certificates_interface)
        with is_data_changed('configure_ssl.ssl_objects',
                             ssl_objects) as changed:
            if ssl_objects:
                # NOTE(fnordahl): regardless of changes to data we may
                # have other changes we want to apply to the files.
                # (e.g. ownership, permissions)
                #
                # Also note that c-h.host.write_file used in configure_cert()
                # has it's own logic to detect data changes.
                #
                # LP: #1821314
                for ssl in ssl_objects:
                    self.set_state('ssl.requested', True)
                    self.configure_cert(
                        ssl['cert'], ssl['key'], cn=ssl['cn'])
                    self.configure_ca(ssl['ca'])
                cert_utils.create_ip_cert_links(
                    os.path.join('/etc/apache2/ssl/', self.name))
                if not os_utils.snap_install_requested() and changed:
                    self.configure_apache()
                    ch_host.service_reload('apache2')

                self.remove_state('ssl.requested')
                self.set_state('ssl.enabled', True)
            else:
                self.set_state('ssl.enabled', False)
        amqp_ssl = relations.endpoint_from_flag('amqp.available.ssl')
        if amqp_ssl:
            self.configure_rabbit_cert(amqp_ssl)
Esempio n. 8
0
    def configure_tls(self, certificates_interface=None):
        """Configure TLS certificates and keys

        NOTE(AJK): This function tries to minimise the work it does,
        particularly with writing files and restarting apache.

        :param certificates_interface: certificates relation endpoint
        :type certificates_interface: TlsRequires(Endpoint) object
        """
        # this takes care of writing out the CA certificate
        tls_objects = super().configure_tls(
            certificates_interface=certificates_interface)
        with is_data_changed(
                'configure_ssl.ssl_objects', tls_objects) as changed:
            if tls_objects:
                # NOTE(fnordahl): regardless of changes to data we may
                # have other changes we want to apply to the files.
                # (e.g. ownership, permissions)
                #
                # Also note that c-h.host.write_file used in configure_cert()
                # has it's own logic to detect data changes.
                #
                # LP: #1821314
                for tls_object in tls_objects:
                    self.set_state('ssl.requested', True)
                    if os_utils.snap_install_requested():
                        path = ('/var/snap/{snap_name}/common/etc/nginx/ssl'
                                .format(snap_name=self.primary_snap))
                    else:
                        path = os.path.join('/etc/apache2/ssl/', self.name)
                    self.configure_cert(
                        path,
                        tls_object['cert'],
                        tls_object['key'],
                        cn=tls_object['cn'])
                cert_utils.create_ip_cert_links(
                    os.path.join('/etc/apache2/ssl/', self.name))
                if not os_utils.snap_install_requested() and changed:
                    self.configure_apache()
                    ch_host.service_reload('apache2')

                self.remove_state('ssl.requested')
                self.set_state('ssl.enabled', True)
            else:
                self.set_state('ssl.enabled', False)
Esempio n. 9
0
    def configure_ssl(self, keystone_interface=None):
        """Configure SSL certificates and keys

        NOTE(AJK): This function tries to minimise the work it does,
        particularly with writing files and restarting apache.

        @param keystone_interface KeystoneRequires class
        """
        keystone_interface = (
            relations.endpoint_from_flag('identity-service.available.ssl')
            or relations.endpoint_from_flag(
                'identity-service.available.ssl_legacy'))
        certificates_interface = relations.endpoint_from_flag(
            'certificates.batch.cert.available')
        ssl_objects = self.get_certs_and_keys(
            keystone_interface=keystone_interface,
            certificates_interface=certificates_interface)
        with is_data_changed('configure_ssl.ssl_objects',
                             ssl_objects) as changed:
            if ssl_objects:
                # NOTE(fnordahl): regardless of changes to data we may
                # have other changes we want to apply to the files.
                # (e.g. ownership, permissions)
                #
                # Also note that c-h.host.write_file used in configure_cert()
                # has it's own logic to detect data changes.
                #
                # LP: #1821314
                for ssl in ssl_objects:
                    self.set_state('ssl.requested', True)
                    self.configure_cert(ssl['cert'], ssl['key'], cn=ssl['cn'])
                    self.configure_ca(ssl['ca'])
                cert_utils.create_ip_cert_links(
                    os.path.join('/etc/apache2/ssl/', self.name))
                if not os_utils.snap_install_requested() and changed:
                    self.configure_apache()
                    ch_host.service_reload('apache2')

                self.remove_state('ssl.requested')
                self.set_state('ssl.enabled', True)
            else:
                self.set_state('ssl.enabled', False)
        amqp_ssl = relations.endpoint_from_flag('amqp.available.ssl')
        if amqp_ssl:
            self.configure_rabbit_cert(amqp_ssl)
Esempio n. 10
0
    def update_peers(self, cluster):
        """Update peers in the cluster about the addresses that this unit
        holds.

        NOTE(AJK): This uses the helper is_data_changed() to track whether this
        has already been done, and doesn't re-advertise the changes if nothing
        has changed.

        @param cluster: the interface object for the cluster relation
        """
        laddrs = []
        for addr_type in sorted(os_ip.ADDRESS_MAP.keys()):
            cidr = self.config.get(os_ip.ADDRESS_MAP[addr_type]['config'])
            laddr = ch_ip.get_relation_ip(
                os_ip.ADDRESS_MAP[addr_type]['binding'], cidr)
            laddrs.append((addr_type, laddr))
        with is_data_changed('update_peers.laddrs', laddrs) as changed:
            if changed:
                for (addr_type, laddr) in laddrs:
                    cluster.set_address(
                        os_ip.ADDRESS_MAP[addr_type]['binding'], laddr)
Esempio n. 11
0
    def configure_ssl(self, keystone_interface=None):
        """Configure SSL certificates and keys

        NOTE(AJK): This function tries to minimise the work it does,
        particularly with writing files and restarting apache.

        @param keystone_interface KeystoneRequires class
        """
        keystone_interface = (
            relations.endpoint_from_flag('identity-service.available.ssl') or
            relations
            .endpoint_from_flag('identity-service.available.ssl_legacy'))
        certificates_interface = relations.endpoint_from_flag(
            'certificates.batch.cert.available')
        ssl_objects = self.get_certs_and_keys(
            keystone_interface=keystone_interface,
            certificates_interface=certificates_interface)
        with is_data_changed('configure_ssl.ssl_objects',
                             ssl_objects) as changed:
            if ssl_objects:
                if changed:
                    for ssl in ssl_objects:
                        self.set_state('ssl.requested', True)
                        self.configure_cert(
                            ssl['cert'], ssl['key'], cn=ssl['cn'])
                        self.configure_ca(ssl['ca'])
                    cert_utils.create_ip_cert_links(
                        os.path.join('/etc/apache2/ssl/', self.name))
                    if not os_utils.snap_install_requested():
                        self.configure_apache()
                        ch_host.service_reload('apache2')

                    self.remove_state('ssl.requested')
                self.set_state('ssl.enabled', True)
            else:
                self.set_state('ssl.enabled', False)
        amqp_ssl = relations.endpoint_from_flag('amqp.available.ssl')
        if amqp_ssl:
            self.configure_rabbit_cert(amqp_ssl)
Esempio n. 12
0
    def update_peers(self, cluster):
        """Update peers in the cluster about the addresses that this unit
        holds.

        NOTE(AJK): This uses the helper is_data_changed() to track whether this
        has already been done, and doesn't re-advertise the changes if nothing
        has changed.

        @param cluster: the interface object for the cluster relation
        """
        laddrs = []
        for addr_type in sorted(os_ip.ADDRESS_MAP.keys()):
            cidr = self.config.get(os_ip.ADDRESS_MAP[addr_type]['config'])
            laddr = ch_ip.get_relation_ip(
                os_ip.ADDRESS_MAP[addr_type]['binding'],
                cidr)
            laddrs.append((addr_type, laddr))
        with is_data_changed('update_peers.laddrs', laddrs) as changed:
            if changed:
                for (addr_type, laddr) in laddrs:
                    cluster.set_address(
                        os_ip.ADDRESS_MAP[addr_type]['binding'],
                        laddr)