def test_create_ip_cert_links(self, get_hostname, resolve_address, isfile, symlink, unit_get): unit_get.return_value = '10.1.2.3' get_hostname.return_value = 'juju-unit-2' _resolve_address = { 'int': '10.0.0.2', 'admin': '10.10.0.2', 'public': '10.20.0.2', } resolve_address.side_effect = \ lambda endpoint_type: _resolve_address[endpoint_type] _files = { '/etc/ssl/cert_juju-unit-2': True, '/etc/ssl/cert_10.0.0.2': False, '/etc/ssl/cert_10.10.0.2': True, '/etc/ssl/cert_10.20.0.2': False, '/etc/ssl/cert_funky-name': False, } isfile.side_effect = lambda x: _files[x] expected = [ mock.call('/etc/ssl/cert_juju-unit-2', '/etc/ssl/cert_10.0.0.2'), mock.call('/etc/ssl/key_juju-unit-2', '/etc/ssl/key_10.0.0.2'), mock.call('/etc/ssl/cert_juju-unit-2', '/etc/ssl/cert_10.20.0.2'), mock.call('/etc/ssl/key_juju-unit-2', '/etc/ssl/key_10.20.0.2'), ] cert_utils.create_ip_cert_links('/etc/ssl') symlink.assert_has_calls(expected) symlink.reset_mock() cert_utils.create_ip_cert_links('/etc/ssl', custom_hostname_link='funky-name') expected.extend([ mock.call('/etc/ssl/cert_juju-unit-2', '/etc/ssl/cert_funky-name'), mock.call('/etc/ssl/key_juju-unit-2', '/etc/ssl/key_funky-name'), ]) symlink.assert_has_calls(expected)
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)
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)
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)
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)
def test_create_ip_cert_links_bindings( self, get_hostname, isfile, symlink, local_address, get_cert_request): cert_request = {'cert_requests': { 'admin.openstack.local': { 'sans': ['10.10.0.100', '10.10.0.2', '10.10.0.3']}, 'internal.openstack.local': { 'sans': ['10.0.0.100', '10.0.0.2', '10.0.0.3']}, 'juju-unit-2': {'sans': ['10.1.2.3']}, 'public.openstack.local': { 'sans': ['10.20.0.100', '10.20.0.2', '10.20.0.3']}}} get_cert_request.return_value = cert_request _files = { '/etc/ssl/cert_juju-unit-2': True, '/etc/ssl/cert_10.1.2.3': False, '/etc/ssl/cert_admin.openstack.local': True, '/etc/ssl/cert_10.10.0.100': False, '/etc/ssl/cert_10.10.0.2': False, '/etc/ssl/cert_10.10.0.3': False, '/etc/ssl/cert_internal.openstack.local': True, '/etc/ssl/cert_10.0.0.100': False, '/etc/ssl/cert_10.0.0.2': False, '/etc/ssl/cert_10.0.0.3': False, '/etc/ssl/cert_public.openstack.local': True, '/etc/ssl/cert_10.20.0.100': False, '/etc/ssl/cert_10.20.0.2': False, '/etc/ssl/cert_10.20.0.3': False, '/etc/ssl/cert_funky-name': False, } isfile.side_effect = lambda x: _files[x] expected = [ mock.call('/etc/ssl/cert_admin.openstack.local', '/etc/ssl/cert_10.10.0.100'), mock.call('/etc/ssl/key_admin.openstack.local', '/etc/ssl/key_10.10.0.100'), mock.call('/etc/ssl/cert_admin.openstack.local', '/etc/ssl/cert_10.10.0.2'), mock.call('/etc/ssl/key_admin.openstack.local', '/etc/ssl/key_10.10.0.2'), mock.call('/etc/ssl/cert_admin.openstack.local', '/etc/ssl/cert_10.10.0.3'), mock.call('/etc/ssl/key_admin.openstack.local', '/etc/ssl/key_10.10.0.3'), mock.call('/etc/ssl/cert_internal.openstack.local', '/etc/ssl/cert_10.0.0.100'), mock.call('/etc/ssl/key_internal.openstack.local', '/etc/ssl/key_10.0.0.100'), mock.call('/etc/ssl/cert_internal.openstack.local', '/etc/ssl/cert_10.0.0.2'), mock.call('/etc/ssl/key_internal.openstack.local', '/etc/ssl/key_10.0.0.2'), mock.call('/etc/ssl/cert_internal.openstack.local', '/etc/ssl/cert_10.0.0.3'), mock.call('/etc/ssl/key_internal.openstack.local', '/etc/ssl/key_10.0.0.3'), mock.call('/etc/ssl/cert_juju-unit-2', '/etc/ssl/cert_10.1.2.3'), mock.call('/etc/ssl/key_juju-unit-2', '/etc/ssl/key_10.1.2.3'), mock.call('/etc/ssl/cert_public.openstack.local', '/etc/ssl/cert_10.20.0.100'), mock.call('/etc/ssl/key_public.openstack.local', '/etc/ssl/key_10.20.0.100'), mock.call('/etc/ssl/cert_public.openstack.local', '/etc/ssl/cert_10.20.0.2'), mock.call('/etc/ssl/key_public.openstack.local', '/etc/ssl/key_10.20.0.2'), mock.call('/etc/ssl/cert_public.openstack.local', '/etc/ssl/cert_10.20.0.3'), mock.call('/etc/ssl/key_public.openstack.local', '/etc/ssl/key_10.20.0.3')] cert_utils.create_ip_cert_links('/etc/ssl', bindings=['mybindings']) symlink.assert_has_calls(expected, any_order=True) # Customer hostname symlink.reset_mock() get_hostname.return_value = 'juju-unit-2' cert_utils.create_ip_cert_links( '/etc/ssl', custom_hostname_link='funky-name', bindings=['mybinding']) expected.extend([ mock.call('/etc/ssl/cert_juju-unit-2', '/etc/ssl/cert_funky-name'), mock.call('/etc/ssl/key_juju-unit-2', '/etc/ssl/key_funky-name'), ]) symlink.assert_has_calls(expected, any_order=True) get_cert_request.assert_called_with( json_encode=False, bindings=['mybinding', 'internal', 'admin', 'public'])