Esempio n. 1
0
        def _validate_token_data(openrc):
            keystone_session = openstack_utils.get_keystone_session(openrc)
            keystone_client = openstack_utils.get_keystone_session_client(
                keystone_session)
            token = keystone_session.get_token()
            if (openstack_utils.get_os_release() <
                    openstack_utils.get_os_release('xenial_ocata')):
                if len(token) != 32:
                    raise zaza_exceptions.KeystoneWrongTokenProvider(
                        'We expected a UUID token and got this: "{}"'.format(
                            token))
            else:
                if len(token) < 180:
                    raise zaza_exceptions.KeystoneWrongTokenProvider(
                        'We expected a Fernet token and got this: "{}"'.format(
                            token))
            logging.info('token: "{}"'.format(pprint.pformat(token)))

            if (openstack_utils.get_os_release() <
                    openstack_utils.get_os_release('trusty_mitaka')):
                logging.info('skip: tokens.get_token_data() not allowed prior '
                             'to trusty_mitaka')
                return
            # get_token_data call also gets the service catalog
            token_data = keystone_client.tokens.get_token_data(token)
            if token_data.get('token', {}).get('catalog', None) is None:
                raise zaza_exceptions.KeystoneAuthorizationStrict(
                    # NOTE(fnordahl) the above call will probably throw a
                    # http.Forbidden exception, but just in case
                    'Regular end user not allowed to retrieve the service '
                    'catalog. ("{}")'.format(pprint.pformat(token_data)))
            logging.info('token_data: "{}"'.format(pprint.pformat(token_data)))
Esempio n. 2
0
 def setUpClass(cls):
     """Run class setup for running Keystone charm operation tests."""
     super(BaseKeystoneTest, cls).setUpClass()
     # Check if we are related to Vault TLS certificates
     cls.tls_rid = zaza.model.get_relation_id(
         'keystone', 'vault', remote_interface_name='certificates')
     # Check for VIP
     cls.vip = (zaza.model.get_application_config('keystone')
                .get('vip').get('value'))
     cls.keystone_ips = zaza.model.get_app_ips('keystone')
     # If we have a VIP set and we are using TLS only check the VIP
     # If you check the individual IP haproxy may send to a different
     # back end which leads to mismatched certificates.
     if cls.vip:
         if cls.tls_rid:
             cls.keystone_ips = [cls.vip]
         else:
             cls.keystone_ips.append(cls.vip)
     if (openstack_utils.get_os_release() <
             openstack_utils.get_os_release('xenial_queens')):
         cls.default_api_version = '2'
     else:
         cls.default_api_version = '3'
     cls.admin_keystone_session = (
         openstack_utils.get_overcloud_keystone_session())
     cls.admin_keystone_client = (
         openstack_utils.get_keystone_session_client(
             cls.admin_keystone_session,
             client_api_version=cls.default_api_version))
def main(argv):
    cli_utils.setup_logging()
    overcloud_novarc = openstack_utils.get_overcloud_auth()
    user_file = mojo_utils.get_mojo_file('keystone_users.yaml')
    user_config = generic_utils.get_yaml_config(user_file)
    try:
        cacert = os.path.join(os.environ.get('MOJO_LOCAL_DIR'), 'cacert.pem')
        os.stat(cacert)
    except FileNotFoundError:
        cacert = None
    keystone_session = openstack_utils.get_overcloud_keystone_session(
        verify=cacert)
    keystone_client = openstack_utils.get_keystone_session_client(
        keystone_session)
    if overcloud_novarc.get('API_VERSION', 2) == 2:
        projects = [user['project'] for user in user_config]
        mojo_os_utils.project_create(keystone_client, projects)
        mojo_os_utils.user_create_v2(keystone_client, user_config)
        # TODO validate this works without adding roles
        # mojo_os_utils.add_users_to_roles(keystone_client, user_config)
    else:
        for user in user_config:
            mojo_os_utils.domain_create(keystone_client, [user['domain']])
            mojo_os_utils.project_create(keystone_client, [user['project']],
                                         user['domain'])
        mojo_os_utils.user_create_v3(keystone_client, user_config)
Esempio n. 4
0
 def _v2():
     keystone_session = openstack_utils.get_overcloud_keystone_session()
     keystone_client = openstack_utils.get_keystone_session_client(
         keystone_session, client_api_version=2)
     tenant = keystone_client.tenants.create(tenant_name=DEMO_TENANT,
                                             description='Demo Tenant',
                                             enabled=True)
     keystone_client.users.create(name=DEMO_USER,
                                  password=DEMO_PASSWORD,
                                  tenant_id=tenant.id)
Esempio n. 5
0
 def _v3():
     keystone_session = openstack_utils.get_overcloud_keystone_session()
     keystone_client = openstack_utils.get_keystone_session_client(
         keystone_session)
     domain = keystone_client.domains.create(
         DEMO_DOMAIN,
         description='Demo Domain',
         enabled=True)
     project = keystone_client.projects.create(
         DEMO_PROJECT,
         domain,
         description='Demo Project',
         enabled=True)
     demo_user = keystone_client.users.create(
         DEMO_USER,
         domain=domain,
         project=project,
         password=DEMO_PASSWORD,
         email='*****@*****.**',
         description='Demo User',
         enabled=True)
     member_role = keystone_client.roles.find(name='Member')
     keystone_client.roles.grant(
         member_role,
         user=demo_user,
         project_domain=domain,
         project=project)
     demo_admin_user = keystone_client.users.create(
         DEMO_ADMIN_USER,
         domain=domain,
         project=project,
         password=DEMO_ADMIN_USER_PASSWORD,
         email='*****@*****.**',
         description='Demo Admin User',
         enabled=True)
     admin_role = keystone_client.roles.find(name='Admin')
     keystone_client.roles.grant(
         admin_role,
         user=demo_admin_user,
         domain=domain)
     keystone_client.roles.grant(
         member_role,
         user=demo_admin_user,
         project_domain=domain,
         project=project)
     keystone_client.roles.grant(
         admin_role,
         user=demo_admin_user,
         project_domain=domain,
         project=project)
Esempio n. 6
0
 def setUpClass(cls):
     """Run class setup for running Keystone charm operation tests."""
     super(BaseKeystoneTest, cls).setUpClass()
     cls.keystone_ips = zaza.model.get_app_ips('keystone')
     if (openstack_utils.get_os_release() <
             openstack_utils.get_os_release('xenial_queens')):
         cls.default_api_version = '2'
     else:
         cls.default_api_version = '3'
     cls.admin_keystone_session = (
         openstack_utils.get_overcloud_keystone_session())
     cls.admin_keystone_client = (
         openstack_utils.get_keystone_session_client(
             cls.admin_keystone_session,
             client_api_version=cls.default_api_version))
Esempio n. 7
0
    def test_admin_project_scoped_access(self):
        """Verify cloud admin access using project scoped token.

        `admin` user in `admin_domain` should be able to access API methods
        guarded by `rule:cloud_admin` policy using a token scoped to `admin`
        project in `admin_domain`.

        We implement a policy that enables domain segregation and
        administration delegation [0].  It is important to understand that this
        differs from the default policy.

        In the initial implementation it was necessary to switch between using
        a `domain` scoped and `project` scoped token to successfully manage a
        cloud, but since the introduction of `is_admin` functionality in
        Keystone [1][2][3] and our subsequent adoption of it in Keystone charm
        [4], this is no longer necessary.

        This test here to validate this behaviour.

        0: https://github.com/openstack/keystone/commit/c7a5c6c
        1: https://github.com/openstack/keystone/commit/e702369
        2: https://github.com/openstack/keystone/commit/e923a14
        3: https://github.com/openstack/keystone/commit/9804081
        4: https://github.com/openstack/charm-keystone/commit/10e3d84
        """
        if (openstack_utils.get_os_release() <
                openstack_utils.get_os_release('trusty_mitaka')):
            logging.info('skipping test < trusty_mitaka')
            return
        with self.config_change(
            {'preferred-api-version': self.default_api_version},
            {'preferred-api-version': '3'},
                application_name="keystone"):
            for ip in self.keystone_ips:
                try:
                    logging.info('keystone IP {}'.format(ip))
                    ks_session = openstack_utils.get_keystone_session(
                        openstack_utils.get_overcloud_auth(address=ip))
                    ks_client = openstack_utils.get_keystone_session_client(
                        ks_session)
                    result = ks_client.domains.list()
                    logging.info('.domains.list: "{}"'.format(
                        pprint.pformat(result)))
                except keystoneauth1.exceptions.http.Forbidden as e:
                    raise zaza_exceptions.KeystoneAuthorizationStrict(
                        'Retrieve domain list as admin with project scoped '
                        'token FAILED. ({})'.format(e))
            logging.info('OK')
Esempio n. 8
0
    def test_end_user_domain_admin_access(self):
        """Verify that end-user domain admin does not have elevated privileges.

        In additon to validating that the `policy.json` is written and the
        service is restarted on config-changed, the test validates that our
        `policy.json` is correct.

        Catch regressions like LP: #1651989
        """
        if (openstack_utils.get_os_release() <
                openstack_utils.get_os_release('xenial_ocata')):
            logging.info('skipping test < xenial_ocata')
            return
        with self.config_change(
            {'preferred-api-version': self.default_api_version},
            {'preferred-api-version': '3'},
                application_name="keystone"):
            for ip in self.keystone_ips:
                openrc = {
                    'API_VERSION': 3,
                    'OS_USERNAME': DEMO_ADMIN_USER,
                    'OS_PASSWORD': DEMO_ADMIN_USER_PASSWORD,
                    'OS_AUTH_URL': 'http://{}:5000/v3'.format(ip),
                    'OS_USER_DOMAIN_NAME': DEMO_DOMAIN,
                    'OS_DOMAIN_NAME': DEMO_DOMAIN,
                }
                if self.tls_rid:
                    openrc['OS_CACERT'] = openstack_utils.KEYSTONE_LOCAL_CACERT
                    openrc['OS_AUTH_URL'] = (openrc['OS_AUTH_URL'].replace(
                        'http', 'https'))
                logging.info('keystone IP {}'.format(ip))
                keystone_session = openstack_utils.get_keystone_session(
                    openrc, scope='DOMAIN')
                keystone_client = openstack_utils.get_keystone_session_client(
                    keystone_session)
                try:
                    # expect failure
                    keystone_client.domains.list()
                except keystoneauth1.exceptions.http.Forbidden as e:
                    logging.debug('Retrieve domain list as end-user domain '
                                  'admin NOT allowed...OK ({})'.format(e))
                    pass
                else:
                    raise zaza_exceptions.KeystoneAuthorizationPermissive(
                        'Retrieve domain list as end-user domain admin '
                        'allowed when it should not be.')
        logging.info('OK')
Esempio n. 9
0
def keystone_federation_setup():
    """Configure Keystone Federation."""
    cli_utils.setup_logging()
    keystone_session = openstack_utils.get_overcloud_keystone_session()
    keystone_client = openstack_utils.get_keystone_session_client(
        keystone_session)

    try:
        domain = keystone_client.domains.find(name=FEDERATED_DOMAIN)
    except keystoneauth1.exceptions.http.NotFound:
        domain = keystone_client.domains.create(FEDERATED_DOMAIN,
                                                description="Federated Domain",
                                                enabled=True)

    try:
        group = keystone_client.groups.find(name=FEDERATED_GROUP,
                                            domain=domain)
    except keystoneauth1.exceptions.http.NotFound:
        group = keystone_client.groups.create(FEDERATED_GROUP,
                                              domain=domain,
                                              enabled=True)

    role = keystone_client.roles.find(name=MEMBER)
    keystone_client.roles.grant(role, group=group, domain=domain)

    try:
        idp = keystone_client.federation.identity_providers.find(
            name=IDP, domain_id=domain.id)
    except keystoneauth1.exceptions.http.NotFound:
        idp = keystone_client.federation.identity_providers.create(
            IDP, remote_ids=[REMOTE_ID], domain_id=domain.id, enabled=True)

    JSON_RULES = json.loads(MAP_TEMPLATE.format(domain_id=domain.id))

    try:
        keystone_client.federation.mappings.find(name=MAP_NAME)
    except keystoneauth1.exceptions.http.NotFound:
        keystone_client.federation.mappings.create(MAP_NAME, rules=JSON_RULES)

    try:
        keystone_client.federation.protocols.get(IDP, PROTOCOL_NAME)
    except keystoneauth1.exceptions.http.NotFound:
        keystone_client.federation.protocols.create(PROTOCOL_NAME,
                                                    mapping=MAP_NAME,
                                                    identity_provider=idp)
def keystone_v3_domain_setup():
    overcloud_novarc = openstack_utils.get_overcloud_auth()
    if overcloud_novarc.get('API_VERSION', 2) == 3:
        try:
            cacert = os.path.join(os.environ.get('MOJO_LOCAL_DIR'),
                                  'cacert.pem')
            os.stat(cacert)
        except FileNotFoundError:
            cacert = None

        keystone_session = openstack_utils.get_overcloud_keystone_session(
            verify=cacert)
        keystone_client = openstack_utils.get_keystone_session_client(
            keystone_session)
        mojo_os_utils.project_create(keystone_client, ['admin'],
                                     'admin_domain')
        admin_project_id = openstack_utils.get_project_id(
            keystone_client,
            'admin',
            api_version=3,
            domain_name='admin_domain')
        role = keystone_client.roles.find(name='admin')
        user = keystone_client.users.find(name='admin')
        keystone_client.roles.grant(role, user=user, project=admin_project_id)
def main(argv):
    cli_utils.setup_logging()
    parser = argparse.ArgumentParser()
    default_machines = ["cirros:m1.tiny:1"]
    parser.add_argument("machines", default=default_machines, nargs="*")
    parser.add_argument("--active_wait", default=180)
    parser.add_argument("--cloudinit_wait", default=180)
    parser.add_argument("--ping_wait", default=180)
    options = parser.parse_args()
    machines = cli_utils.parse_arg(options, 'machines', multiargs=True)
    active_wait = int(cli_utils.parse_arg(options, 'active_wait'))
    cloudinit_wait = int(cli_utils.parse_arg(options, 'cloudinit_wait'))
    ping_wait = int(cli_utils.parse_arg(options, 'ping_wait'))
    overcloud_novarc = openstack_utils.get_overcloud_auth()
    try:
        cacert = os.path.join(os.environ.get('MOJO_LOCAL_DIR'), 'cacert.pem')
        os.stat(cacert)
    except FileNotFoundError:
        cacert = None
    keystone_session = openstack_utils.get_overcloud_keystone_session(
        verify=cacert)
    keystonec = openstack_utils.get_keystone_session_client(keystone_session)
    domain = overcloud_novarc.get('OS_PROJECT_DOMAIN_NAME')
    project_id = openstack_utils.get_project_id(
        keystonec,
        'admin',
        api_version=overcloud_novarc['API_VERSION'],
        domain_name=domain)
    novac = openstack_utils.get_nova_session_client(keystone_session)
    neutronc = openstack_utils.get_neutron_session_client(keystone_session)

    init_flavors(novac)

    priv_key = mojo_os_utils.create_keypair(novac, 'mojo')
    openstack_utils.add_neutron_secgroup_rules(neutronc, project_id)
    for server in novac.servers.list():
        novac.servers.delete(server.id)
    for instanceset in machines:
        image_name, flavor_name, count = instanceset.split(":")
        # when instance count allows boot instances off both regular instance
        # storage and volume storage
        #
        # account for count=1 and odd numbers

        # NOTE(fnordahl) temporarilly disable test while tests settle
        # regular_boot_count = int(int(count) / 2) + (int(count) % 2)
        # volume_boot_count = int(int(count) / 2)
        regular_boot_count = int(count)
        volume_boot_count = 0
        mojo_os_utils.boot_and_test(
            novac,
            neutronc,
            image_name=image_name,
            flavor_name=flavor_name,
            number=regular_boot_count,
            privkey=priv_key,
            active_wait=active_wait,
            cloudinit_wait=cloudinit_wait,
            ping_wait=ping_wait,
        )
        mojo_os_utils.boot_and_test(
            novac,
            neutronc,
            image_name=image_name,
            flavor_name=flavor_name,
            number=volume_boot_count,
            privkey=priv_key,
            active_wait=active_wait,
            cloudinit_wait=cloudinit_wait,
            ping_wait=ping_wait,
            boot_from_volume=True,
        )
Esempio n. 12
0
def setup_sdn(network_config, keystone_session=None):
    """Perform setup for Software Defined Network.

    :param network_config: Network configuration settings dictionary
    :type network_config: dict
    :param keystone_session: Keystone session object for overcloud
    :type keystone_session: keystoneauth1.session.Session object
    :returns: None
    :rtype: None
    """
    # If a session has not been provided, acquire one
    if not keystone_session:
        keystone_session = openstack_utils.get_overcloud_keystone_session()

    # Get authenticated clients
    keystone_client = openstack_utils.get_keystone_session_client(
        keystone_session)
    neutron_client = openstack_utils.get_neutron_session_client(
        keystone_session)

    admin_domain = None
    if openstack_utils.get_keystone_api_version() > 2:
        admin_domain = "admin_domain"
    # Resolve the project name from the overcloud openrc into a project id
    project_id = openstack_utils.get_project_id(
        keystone_client,
        "admin",
        domain_name=admin_domain,
    )
    # Network Setup
    subnetpools = False
    if network_config.get("subnetpool_prefix"):
        subnetpools = True

    logging.info("Configuring overcloud network")
    # Create the external network
    ext_network = openstack_utils.create_external_network(
        neutron_client, project_id, network_config.get("dvr_enabled", False),
        network_config["external_net_name"])
    openstack_utils.create_external_subnet(
        neutron_client, project_id, ext_network,
        network_config["default_gateway"], network_config["external_net_cidr"],
        network_config["start_floating_ip"], network_config["end_floating_ip"],
        network_config["external_subnet_name"])
    provider_router = (openstack_utils.create_provider_router(
        neutron_client, project_id))
    openstack_utils.plug_extnet_into_router(neutron_client, provider_router,
                                            ext_network)
    ip_version = network_config.get("ip_version") or 4
    subnetpool = None
    if subnetpools:
        address_scope = openstack_utils.create_address_scope(
            neutron_client,
            project_id,
            network_config.get("address_scope"),
            ip_version=ip_version)
        subnetpool = openstack_utils.create_subnetpool(
            neutron_client, project_id, network_config.get("subnetpool_name"),
            network_config.get("subnetpool_prefix"), address_scope)
    project_network = openstack_utils.create_project_network(
        neutron_client,
        project_id,
        shared=False,
        network_type=network_config["network_type"])
    project_subnet = openstack_utils.create_project_subnet(
        neutron_client,
        project_id,
        project_network,
        network_config.get("private_net_cidr"),
        subnetpool=subnetpool,
        ip_version=ip_version)
    openstack_utils.update_subnet_dns(neutron_client, project_subnet,
                                      network_config["external_dns"])
    openstack_utils.plug_subnet_into_router(neutron_client,
                                            network_config["router_name"],
                                            project_network, project_subnet)
    openstack_utils.add_neutron_secgroup_rules(neutron_client, project_id)