Example #1
0
def setup_tenants_and_users():
    tenants = []
    users = {}
    tenant_a = "tenant_" + gen_rnd_string()
    tenant_b = "tenant_" + gen_rnd_string()
    _, content = keystone_utils.create_tenant(tenant_a, ADMIN_AUTH_TOKEN,
                                              keystone_api_url)
    tenants.append(_get_id(content,'tenant', tenant_a))
    
    _, content = keystone_utils.create_tenant(tenant_b, ADMIN_AUTH_TOKEN,
                                              keystone_api_url)
    tenants.append(_get_id(content,'tenant', tenant_b))
    
    user_a = "user_" + gen_rnd_string()
    user_b = "user_" + gen_rnd_string()
    
    _, content = keystone_utils.create_user(tenants[0], user_a,
                                            ADMIN_AUTH_TOKEN,
                                            keystone_api_url,
                                            gen_rnd_string(4) + "@test.com",
                                            user_a)
    users[_get_id(content,'user', user_a)] = [user_a, tenants[0], tenant_a]

    _, content = keystone_utils.create_user(tenants[1], user_b,
                                            ADMIN_AUTH_TOKEN,
                                            keystone_api_url,
                                            gen_rnd_string(4) + "@test.com",
                                            user_b)
    users[_get_id(content,'user', user_b)] = [user_b, tenants[1], tenant_b]
    
    for user in users:
        keystone_utils.create_role_ref(user,  "4", users[user][1],
                                       ADMIN_AUTH_TOKEN, keystone_api_url)
    for tenant in tenants:
        keystone_utils.create_endpoint(tenant, 1, 
                                       ADMIN_AUTH_TOKEN, keystone_api_url)
        keystone_utils.create_endpoint(tenant, 2,
                                       ADMIN_AUTH_TOKEN, keystone_api_url)
        keystone_utils.create_endpoint(tenant, 3,
                                       ADMIN_AUTH_TOKEN, keystone_api_url)
        keystone_utils.create_endpoint(tenant, 4,
                                       ADMIN_AUTH_TOKEN, keystone_api_url)
        keystone_utils.create_endpoint(tenant, 5,
                                       ADMIN_AUTH_TOKEN, keystone_api_url)
    
    return tenants, users
Example #2
0
def setup_tenants_and_users():
    tenants = []
    users = {}
    tenant_a = "tenant_" + gen_rnd_string()
    tenant_b = "tenant_" + gen_rnd_string()
    _, content = keystone_utils.create_tenant(tenant_a, ADMIN_AUTH_TOKEN,
                                              keystone_api_url)
    tenants.append(_get_id(content, 'tenant', tenant_a))

    _, content = keystone_utils.create_tenant(tenant_b, ADMIN_AUTH_TOKEN,
                                              keystone_api_url)
    tenants.append(_get_id(content, 'tenant', tenant_b))

    user_a = "user_" + gen_rnd_string()
    user_b = "user_" + gen_rnd_string()

    _, content = keystone_utils.create_user(tenants[0], user_a,
                                            ADMIN_AUTH_TOKEN, keystone_api_url,
                                            gen_rnd_string(4) + "@test.com",
                                            user_a)
    users[_get_id(content, 'user', user_a)] = [user_a, tenants[0], tenant_a]

    _, content = keystone_utils.create_user(tenants[1], user_b,
                                            ADMIN_AUTH_TOKEN, keystone_api_url,
                                            gen_rnd_string(4) + "@test.com",
                                            user_b)
    users[_get_id(content, 'user', user_b)] = [user_b, tenants[1], tenant_b]

    for user in users:
        keystone_utils.create_role_ref(user, "4", users[user][1],
                                       ADMIN_AUTH_TOKEN, keystone_api_url)
    for tenant in tenants:
        keystone_utils.create_endpoint(tenant, 1, ADMIN_AUTH_TOKEN,
                                       keystone_api_url)
        keystone_utils.create_endpoint(tenant, 2, ADMIN_AUTH_TOKEN,
                                       keystone_api_url)
        keystone_utils.create_endpoint(tenant, 3, ADMIN_AUTH_TOKEN,
                                       keystone_api_url)
        keystone_utils.create_endpoint(tenant, 4, ADMIN_AUTH_TOKEN,
                                       keystone_api_url)
        keystone_utils.create_endpoint(tenant, 5, ADMIN_AUTH_TOKEN,
                                       keystone_api_url)

    return tenants, users
Example #3
0
    def test_create_user_case_sensitivity(self, KeystoneManager):
        """ Test case sensitivity of check for existence in
            the user creation process """
        mock_keystone = MagicMock()
        KeystoneManager.return_value = mock_keystone

        mock_user = MagicMock()
        mock_keystone.resolve_user_id.return_value = mock_user
        mock_keystone.api.users.list.return_value = [mock_user]

        # User found is the same i.e. userA == userA
        mock_user.name = 'userA'
        utils.create_user('userA', 'passA')
        mock_keystone.resolve_user_id.assert_called_with('userA',
                                                         user_domain=None)
        mock_keystone.create_user.assert_not_called()

        # User found has different case but is the same
        # i.e. Usera != userA
        mock_user.name = 'Usera'
        utils.create_user('userA', 'passA')
        mock_keystone.resolve_user_id.assert_called_with('userA',
                                                         user_domain=None)
        mock_keystone.create_user.assert_not_called()

        # User is different i.e. UserB != userA
        mock_user.name = 'UserB'
        utils.create_user('userA', 'passA')
        mock_keystone.resolve_user_id.assert_called_with('userA',
                                                         user_domain=None)
        mock_keystone.create_user.assert_called_with(name='userA',
                                                     password='******',
                                                     tenant_id=None,
                                                     domain_id=None,
                                                     email='juju@localhost')
    def test_create_user_case_sensitivity(self, KeystoneManager):
        """ Test case sensitivity of check for existence in
            the user creation process """
        mock_keystone = MagicMock()
        KeystoneManager.return_value = mock_keystone

        mock_user = MagicMock()
        mock_keystone.resolve_user_id.return_value = mock_user
        mock_keystone.api.users.list.return_value = [mock_user]

        # User found is the same i.e. userA == userA
        mock_user.name = 'userA'
        utils.create_user('userA', 'passA')
        mock_keystone.resolve_user_id.assert_called_with('userA',
                                                         user_domain=None)
        mock_keystone.create_user.assert_not_called()

        # User found has different case but is the same
        # i.e. Usera != userA
        mock_user.name = 'Usera'
        utils.create_user('userA', 'passA')
        mock_keystone.resolve_user_id.assert_called_with('userA',
                                                         user_domain=None)
        mock_keystone.create_user.assert_not_called()

        # User is different i.e. UserB != userA
        mock_user.name = 'UserB'
        utils.create_user('userA', 'passA')
        mock_keystone.resolve_user_id.assert_called_with('userA',
                                                         user_domain=None)
        mock_keystone.create_user.assert_called_with(name='userA',
                                                     password='******',
                                                     tenant_id=None,
                                                     domain_id=None,
                                                     email='juju@localhost')
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()