def store_credentails(creds): """Store the supplied credentials on a vault unit. ONLY USE FOR FUNCTIONAL TESTING. :param creds: Keys and token to store :type creds: dict """ unit = zaza.model.get_first_unit_name(utils.get_juju_model(), 'vault') with tempfile.NamedTemporaryFile(mode='w') as fp: fp.write(yaml.dump(creds)) fp.flush() zaza.model.scp_to_unit(utils.get_juju_model(), unit, fp.name, '~/{}'.format(AUTH_FILE))
def get_credentails(): """Retrieve vault token and keys from unit. These are stored on a unit during functional tests. :returns: Tokens and keys for accessing test environment :rtype: dict """ unit = zaza.model.get_first_unit_name(utils.get_juju_model(), 'vault') with tempfile.TemporaryDirectory() as tmpdirname: tmp_file = '{}/{}'.format(tmpdirname, AUTH_FILE) zaza.model.scp_from_unit(utils.get_juju_model(), unit, '~/{}'.format(AUTH_FILE), tmp_file) with open(tmp_file, 'r') as stream: creds = yaml.load(stream) return creds
def remote_run(unit, remote_cmd, timeout=None, fatal=None): """Run command on unit and return the output NOTE: This function is pre-deprecated. As soon as libjuju unit.run is able to return output this functionality should move to model.run_on_unit. :param remote_cmd: Command to execute on unit :type remote_cmd: string :param timeout: Timeout value for the command :type arg: int :param fatal: Command failure condidered fatal or not :type fatal: boolean :returns: Juju run output :rtype: string """ if fatal is None: fatal = True result = model.run_on_unit(lifecycle_utils.get_juju_model(), unit, remote_cmd, timeout=timeout) if result: if int(result.get('Code')) == 0: return result.get('Stdout') else: if fatal: raise Exception('Error running remote command: {}'.format( result.get('Stderr'))) return result.get('Stderr')
def _skipIfNotHA_inner_2(*args, **kwargs): ips = zaza.model.get_app_ips(utils.get_juju_model(), service_name) if len(ips) > 1: return f(*args, **kwargs) else: logging.warn("Skipping HA test for non-ha service {}".format( service_name))
def get_full_juju_status(): """Return the full juju status output :returns: Full juju status output :rtype: dict """ status = model.get_status(lifecycle_utils.get_juju_model()) return status
def test_vault_authorize_charm_action(self): vault_actions = zaza.model.get_actions( lifecycle_utils.get_juju_model(), 'vault') if 'authorize-charm' not in vault_actions: raise unittest.SkipTest('Action not defined') action = vault_utils.run_charm_authorize( self.vault_creds['root_token']) self.assertEqual(action.status, 'completed') client = self.clients[0] self.assertIn('local-charm-policy', client.hvac_client.list_policies())
def test_get_juju_model(self): self.patch_object(lc_utils.os, 'environ') self.patch_object(lc_utils.model, 'get_current_model') self.get_current_model.return_value = 'modelsmodel' def _get_env(key): return _env.get(key) self.environ.__getitem__.side_effect = _get_env _env = {"JUJU_MODEL": 'envmodel'} # JUJU_ENV environment variable set self.assertEqual(lc_utils.get_juju_model(), 'envmodel') self.get_current_model.assert_not_called() # No envirnment variable self.environ.__getitem__.side_effect = KeyError self.assertEqual(lc_utils.get_juju_model(), 'modelsmodel') self.get_current_model.assert_called_once()
def get_application_config_keys(application): """Return application configuration keys :param application: Name of application :type application: string :returns: List of aplication configuration keys :rtype: list """ application_config = model.get_application_config( lifecycle_utils.get_juju_model(), application) return list(application_config.keys())
def test_bgp_routes(peer_application_name="quagga", keystone_session=None): """Test BGP routes :param peer_application_name: String name of BGP peer application :type peer_application_name: string :param keystone_session: Keystone session object for overcloud :type keystone_session: keystoneauth1.session.Session object :raises: AssertionError if expected BGP routes are not found :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 neutron_client = openstack_utils.get_neutron_session_client( keystone_session) # Get the peer unit peer_unit = model.get_units( lifecycle_utils.get_juju_model(), peer_application_name)[0].entity_id # Get expected advertised routes private_cidr = neutron_client.list_subnets( name="private_subnet")["subnets"][0]["cidr"] floating_ip_cidr = "{}/32".format( neutron_client.list_floatingips() ["floatingips"][0]["floating_ip_address"]) # This test may run immediately after configuration. It may take time for # routes to propogate via BGP. Do a binary backoff. @tenacity.retry(wait=tenacity.wait_exponential(multiplier=1, max=60), reraise=True, stop=tenacity.stop_after_attempt(8)) def _assert_cidr_in_peer_routing_table(peer_unit, cidr): logging.debug("Checking for {} on BGP peer {}" .format(cidr, peer_unit)) # Run show ip route bgp on BGP peer routes = _local_utils.remote_run( peer_unit, remote_cmd='vtysh -c "show ip route bgp"') logging.debug(routes) assert cidr in routes, ( "CIDR, {}, not found in BGP peer's routing table" .format(cidr)) _assert_cidr_in_peer_routing_table(peer_unit, private_cidr) logging.info("Private subnet CIDR, {}, found in routing table" .format(private_cidr)) _assert_cidr_in_peer_routing_table(peer_unit, floating_ip_cidr) logging.info("Floating IP CIDR, {}, found in routing table" .format(floating_ip_cidr))
def get_vip_client(): """Return CharmVaultClient for the vip if a vip is being used :returns: CharmVaultClient :rtype: CharmVaultClient or None """ client = None vault_config = zaza.model.get_application_config(utils.get_juju_model(), 'vault') vip = vault_config.get('vip', {}).get('value') if vip: client = CharmVaultClient(vip, get_hvac_client(get_unit_api_url(vip)), True) return client
def get_clients(units=None): """Create a list of clients, one per vault server :param units: List of IP addresses of vault endpoints :type units: [str, str, ...] :returns: List of CharmVaultClients :rtype: [CharmVaultClient, ...] """ if not units: units = zaza.model.get_app_ips(utils.get_juju_model(), 'vault') clients = [] for unit in units: vault_url = get_unit_api_url(unit) clients.append( CharmVaultClient(unit, get_hvac_client(vault_url), False)) return clients
def get_application_config_option(application, option): """Return application configuration :param application: Name of application :type application: string :param option: Specific configuration option :type option: string :returns: Value of configuration option :rtype: Configuration option value type """ application_config = model.get_application_config( lifecycle_utils.get_juju_model(), application) try: return application_config.get(option).get('value') except AttributeError: return None
def get_pkg_version(application, pkg): """Return package version :param application: Application name :type application: string :param pkg: Package name :type pkg: string :returns: List of package version :rtype: list """ versions = [] units = model.get_units(lifecycle_utils.get_juju_model(), application) for unit in units: cmd = 'dpkg -l | grep {}'.format(pkg) out = remote_run(unit.entity_id, cmd) versions.append(out.split('\n')[0].split()[2]) if len(set(versions)) != 1: raise Exception('Unexpected output from pkg version check') return versions[0]
def create_bgp_peer(neutron_client, peer_application_name='quagga', remote_as=10000, auth_type='none'): """Create BGP peer :param neutron_client: Authenticated neutronclient :type neutron_client: neutronclient.Client object :param peer_application_name: Application name of the BGP peer :type peer_application_name: string :param remote_as: Autonomous system number of the BGP peer :type local_as: int :param auth_type: BGP authentication type :type auth_type: string or None :returns: BGP peer object :rtype: dict """ peer_unit = model.get_units(lifecycle_utils.get_juju_model(), peer_application_name)[0] peer_ip = peer_unit.public_address bgp_peers = neutron_client.list_bgp_peers(name=peer_application_name) if len(bgp_peers['bgp_peers']) == 0: logging.info('Creating BGP Peer') bgp_peer_msg = { 'bgp_peer': { 'name': peer_application_name, 'peer_ip': peer_ip, 'remote_as': remote_as, 'auth_type': auth_type, } } bgp_peer = neutron_client.create_bgp_peer(bgp_peer_msg)['bgp_peer'] else: logging.warning('BGP Peer %s already exists.', peer_ip) bgp_peer = bgp_peers['bgp_peers'][0] return bgp_peer
def configure_gateway_ext_port(novaclient, neutronclient, dvr_mode=None, net_id=None): """Configure the neturong-gateway external port :param novaclient: Authenticated novaclient :type novaclient: novaclient.Client object :param neutronclient: Authenticated neutronclient :type neutronclient: neutronclient.Client object :param dvr_mode: Using DVR mode or not :type dvr_mode: boolean :param net_id: Network ID :type net_id: string :returns: Nothing: This fucntion is executed for its sideffect :rtype: None """ if dvr_mode: uuids = get_ovs_uuids() else: uuids = get_gateway_uuids() deprecated_extnet_mode = deprecated_external_networking(dvr_mode) config_key = 'data-port' if deprecated_extnet_mode: config_key = 'ext-port' if not net_id: net_id = get_admin_net(neutronclient)['id'] for uuid in uuids: server = novaclient.servers.get(uuid) ext_port_name = "{}_ext-port".format(server.name) for port in neutronclient.list_ports(device_id=server.id)['ports']: if port['name'] == ext_port_name: logging.warning('Neutron Gateway already has additional port') break else: logging.info('Attaching additional port to instance, ' 'connected to net id: {}'.format(net_id)) body_value = { "port": { "admin_state_up": True, "name": ext_port_name, "network_id": net_id, "port_security_enabled": False, } } port = neutronclient.create_port(body=body_value) server.interface_attach(port_id=port['port']['id'], net_id=None, fixed_ip=None) ext_br_macs = [] for port in neutronclient.list_ports(network_id=net_id)['ports']: if 'ext-port' in port['name']: if deprecated_extnet_mode: ext_br_macs.append(port['mac_address']) else: ext_br_macs.append('br-ex:{}'.format(port['mac_address'])) ext_br_macs.sort() ext_br_macs_str = ' '.join(ext_br_macs) if dvr_mode: application_name = 'neutron-openvswitch' else: application_name = 'neutron-gateway' if ext_br_macs: logging.info('Setting {} on {} external port to {}'.format( config_key, application_name, ext_br_macs_str)) current_data_port = get_application_config_option( application_name, config_key) if current_data_port == ext_br_macs_str: logging.info('Config already set to value') return model.set_application_config( lifecycle_utils.get_juju_model(), application_name, configuration={config_key: ext_br_macs_str}) juju_wait.wait(wait_for_workload=True)
def get_keystone_ip(): if get_application_config_option('keystone', 'vip'): return get_application_config_option('keystone', 'vip') unit = model.get_units(lifecycle_utils.get_juju_model(), 'keystone')[0] return unit.public_address
def run_charm_authorize(token): return zaza.model.run_action_on_leader(utils.get_juju_model(), 'vault', 'authorize-charm', action_params={'token': token})