コード例 #1
0
    def configure_ca(self):
        from keystone_utils import (
            SSH_USER,
            get_ca,
            ensure_permissions,
            is_ssl_cert_master,
        )

        if not is_cert_provided_in_config() and not is_ssl_cert_master():
            log(
                "Not ssl-cert-master - skipping apache ca config until "
                "master is elected",
                level=INFO)
            return

        ca_cert = config('ssl_ca')
        if ca_cert is None:
            ca = get_ca(user=SSH_USER)
            ca_cert = ca.get_ca_bundle()
        else:
            ca_cert = b64decode(ca_cert)

        # Ensure accessible by keystone ssh user and group (unison)
        install_ca_cert(ca_cert)
        ensure_permissions(CA_CERT_PATH,
                           user=SSH_USER,
                           group='keystone',
                           perms=0o0644)
コード例 #2
0
    def configure_cert(self, cn):
        from keystone_utils import (
            SSH_USER,
            get_ca,
            ensure_permissions,
            is_ssl_cert_master,
            KEYSTONE_USER,
        )

        # Ensure ssl dir exists whether master or not
        perms = 0o775
        mkdir(path=self.ssl_dir,
              owner=SSH_USER,
              group=KEYSTONE_USER,
              perms=perms)
        # Ensure accessible by keystone ssh user and group (for sync)
        ensure_permissions(self.ssl_dir,
                           user=SSH_USER,
                           group=KEYSTONE_USER,
                           perms=perms)

        if not is_cert_provided_in_config() and not is_ssl_cert_master():
            log(
                "Not ssl-cert-master - skipping apache cert config until "
                "master is elected",
                level=INFO)
            return

        log("Creating apache ssl certs in %s" % (self.ssl_dir), level=INFO)

        cert = config('ssl_cert')
        key = config('ssl_key')

        if not (cert and key):
            ca = get_ca(user=SSH_USER)
            cert, key = ca.get_cert_and_key(common_name=cn)
        else:
            cert = b64decode(cert)
            key = b64decode(key)

        write_file(path=os.path.join(self.ssl_dir, 'cert_{}'.format(cn)),
                   content=cert,
                   owner=SSH_USER,
                   group=KEYSTONE_USER,
                   perms=0o640)
        write_file(path=os.path.join(self.ssl_dir, 'key_{}'.format(cn)),
                   content=key,
                   owner=SSH_USER,
                   group=KEYSTONE_USER,
                   perms=0o640)
コード例 #3
0
    def configure_cert(self, cn):
        from keystone_utils import (
            SSH_USER,
            get_ca,
            ensure_permissions,
            is_ssl_cert_master,
        )

        # Ensure ssl dir exists whether master or not
        ssl_dir = os.path.join('/etc/apache2/ssl/', self.service_namespace)
        perms = 0o755
        mkdir(path=ssl_dir, owner=SSH_USER, group='keystone', perms=perms)
        # Ensure accessible by keystone ssh user and group (for sync)
        ensure_permissions(ssl_dir, user=SSH_USER, group='keystone',
                           perms=perms)

        if not is_cert_provided_in_config() and not is_ssl_cert_master():
            log("Not ssl-cert-master - skipping apache cert config until "
                "master is elected", level=INFO)
            return

        log("Creating apache ssl certs in %s" % (ssl_dir), level=INFO)

        cert = config('ssl_cert')
        key = config('ssl_key')

        if not (cert and key):
            ca = get_ca(user=SSH_USER)
            cert, key = ca.get_cert_and_key(common_name=cn)
        else:
            cert = b64decode(cert)
            key = b64decode(key)

        write_file(path=os.path.join(ssl_dir, 'cert_{}'.format(cn)),
                   content=cert, owner=SSH_USER, group='keystone', perms=0o644)
        write_file(path=os.path.join(ssl_dir, 'key_{}'.format(cn)),
                   content=key, owner=SSH_USER, group='keystone', perms=0o644)
コード例 #4
0
    def configure_ca(self):
        from keystone_utils import (
            SSH_USER,
            get_ca,
            ensure_permissions,
            is_ssl_cert_master,
            KEYSTONE_USER,
        )

        if not is_cert_provided_in_config() and not is_ssl_cert_master():
            log(
                "Not ssl-cert-master - skipping apache ca config until "
                "master is elected",
                level=INFO)
            return

        cert = config('ssl_cert')
        key = config('ssl_key')

        ca_cert = config('ssl_ca')
        if ca_cert:
            ca_cert = b64decode(ca_cert)
        elif not (cert and key):
            # NOTE(hopem): if a cert and key are provided as config we don't
            # mandate that a CA is also provided since it isn't necessarily
            # needed. As a result we only generate a custom CA if we are also
            # generating cert and key.
            ca = get_ca(user=SSH_USER)
            ca_cert = ca.get_ca_bundle()

        if ca_cert:
            # Ensure accessible by keystone ssh user and group (unison)
            install_ca_cert(ca_cert)
            ensure_permissions(CA_CERT_PATH,
                               user=SSH_USER,
                               group=KEYSTONE_USER,
                               perms=0o0644)
コード例 #5
0
    def configure_ca(self):
        from keystone_utils import (
            SSH_USER,
            get_ca,
            ensure_permissions,
            is_ssl_cert_master,
        )

        if not is_cert_provided_in_config() and not is_ssl_cert_master():
            log("Not ssl-cert-master - skipping apache ca config until "
                "master is elected", level=INFO)
            return

        ca_cert = config('ssl_ca')
        if ca_cert is None:
            ca = get_ca(user=SSH_USER)
            ca_cert = ca.get_ca_bundle()
        else:
            ca_cert = b64decode(ca_cert)

        # Ensure accessible by keystone ssh user and group (unison)
        install_ca_cert(ca_cert)
        ensure_permissions(CA_CERT_PATH, user=SSH_USER, group='keystone',
                           perms=0o0644)
コード例 #6
0
def identity_changed(relation_id=None, remote_unit=None):
    """ A service has advertised its API endpoints, create an entry in the
        service catalog.
        Optionally allow this hook to be re-fired for an existing
        relation+unit, for context see see db_changed().
    """
    if not cluster.eligible_leader(CLUSTER_RES):
        utils.juju_log('INFO',
                       'Deferring identity_changed() to service leader.')
        return

    settings = utils.relation_get_dict(relation_id=relation_id,
                                       remote_unit=remote_unit)

    # the minimum settings needed per endpoint
    single = set(['service', 'region', 'public_url', 'admin_url',
                  'internal_url'])
    if single.issubset(settings):
        # other end of relation advertised only one endpoint
        if 'None' in [v for k, v in settings.iteritems()]:
            # Some backend services advertise no endpoint but require a
            # hook execution to update auth strategy.
            relation_data = {}
            # Check if clustered and use vip + haproxy ports if so
            if cluster.is_clustered():
                relation_data["auth_host"] = config['vip']
                relation_data["service_host"] = config['vip']
            else:
                relation_data["auth_host"] = config['hostname']
                relation_data["service_host"] = config['hostname']
            relation_data["auth_port"] = config['admin-port']
            relation_data["service_port"] = config['service-port']
            if config['https-service-endpoints'] in ['True', 'true']:
                # Pass CA cert as client will need it to
                # verify https connections
                ca = get_ca(user=SSH_USER)
                ca_bundle = ca.get_ca_bundle()
                relation_data['https_keystone'] = 'True'
                relation_data['ca_cert'] = b64encode(ca_bundle)
            if relation_id:
                relation_data['rid'] = relation_id
            # Allow the remote service to request creation of any additional
            # roles. Currently used by Horizon
            for role in get_requested_roles(settings):
                utils.juju_log('INFO',
                               "Creating requested role: %s" % role)
                create_role(role)
            utils.relation_set(**relation_data)
            return
        else:
            ensure_valid_service(settings['service'])
            add_endpoint(region=settings['region'],
                         service=settings['service'],
                         publicurl=settings['public_url'],
                         adminurl=settings['admin_url'],
                         internalurl=settings['internal_url'])
            service_username = settings['service']
            https_cn = urlparse.urlparse(settings['internal_url'])
            https_cn = https_cn.hostname
    else:
        # assemble multiple endpoints from relation data. service name
        # should be prepended to setting name, ie:
        #  realtion-set ec2_service=$foo ec2_region=$foo ec2_public_url=$foo
        #  relation-set nova_service=$foo nova_region=$foo nova_public_url=$foo
        # Results in a dict that looks like:
        # { 'ec2': {
        #       'service': $foo
        #       'region': $foo
        #       'public_url': $foo
        #   }
        #   'nova': {
        #       'service': $foo
        #       'region': $foo
        #       'public_url': $foo
        #   }
        # }
        endpoints = {}
        for k, v in settings.iteritems():
            ep = k.split('_')[0]
            x = '_'.join(k.split('_')[1:])
            if ep not in endpoints:
                endpoints[ep] = {}
            endpoints[ep][x] = v
        services = []
        https_cn = None
        for ep in endpoints:
            # weed out any unrelated relation stuff Juju might have added
            # by ensuring each possible endpiont has appropriate fields
            #  ['service', 'region', 'public_url', 'admin_url', 'internal_url']
            if single.issubset(endpoints[ep]):
                ep = endpoints[ep]
                ensure_valid_service(ep['service'])
                add_endpoint(region=ep['region'], service=ep['service'],
                             publicurl=ep['public_url'],
                             adminurl=ep['admin_url'],
                             internalurl=ep['internal_url'])
                services.append(ep['service'])
                if not https_cn:
                    https_cn = urlparse.urlparse(ep['internal_url'])
                    https_cn = https_cn.hostname
        service_username = '******'.join(services)

    if 'None' in [v for k, v in settings.iteritems()]:
        return

    if not service_username:
        return

    token = get_admin_token()
    utils.juju_log('INFO',
                   "Creating service credentials for '%s'" % service_username)

    service_password = get_service_password(service_username)
    create_user(service_username, service_password, config['service-tenant'])
    grant_role(service_username, config['admin-role'],
               config['service-tenant'])

    # Allow the remote service to request creation of any additional roles.
    # Currently used by Swift and Ceilometer.
    for role in get_requested_roles(settings):
        utils.juju_log('INFO',
                       "Creating requested role: %s" % role)
        create_role(role, service_username,
                    config['service-tenant'])

    # As of https://review.openstack.org/#change,4675, all nodes hosting
    # an endpoint(s) needs a service username and password assigned to
    # the service tenant and granted admin role.
    # note: config['service-tenant'] is created in utils.ensure_initial_admin()
    # we return a token, information about our API endpoints, and the generated
    # service credentials
    relation_data = {
        "admin_token": token,
        "service_host": config["hostname"],
        "service_port": config["service-port"],
        "auth_host": config["hostname"],
        "auth_port": config["admin-port"],
        "service_username": service_username,
        "service_password": service_password,
        "service_tenant": config['service-tenant'],
        "https_keystone": "False",
        "ssl_cert": "",
        "ssl_key": "",
        "ca_cert": ""
    }

    if relation_id:
        relation_data['rid'] = relation_id

    # Check if clustered and use vip + haproxy ports if so
    if cluster.is_clustered():
        relation_data["auth_host"] = config['vip']
        relation_data["service_host"] = config['vip']

    # generate or get a new cert/key for service if set to manage certs.
    if config['https-service-endpoints'] in ['True', 'true']:
        ca = get_ca(user=SSH_USER)
        cert, key = ca.get_cert_and_key(common_name=https_cn)
        ca_bundle = ca.get_ca_bundle()
        relation_data['ssl_cert'] = b64encode(cert)
        relation_data['ssl_key'] = b64encode(key)
        relation_data['ca_cert'] = b64encode(ca_bundle)
        relation_data['https_keystone'] = 'True'
        unison.sync_to_peers(peer_interface='cluster',
                             paths=[SSL_DIR], user=SSH_USER, verbose=True)
    utils.relation_set(**relation_data)
    synchronize_service_credentials()