def remote_run(unit, remote_cmd, timeout=None, fatal=None, model_name=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: bool :param model_name: Name of model to query. :type model_name: str :returns: Juju run output :rtype: string :raises: model.CommandRunFailed """ if fatal is None: fatal = True result = model.run_on_unit(unit, remote_cmd, model_name=model_name, timeout=timeout) if result: if int(result.get("Code")) == 0: return result.get("Stdout") else: if fatal: raise model.CommandRunFailed(remote_cmd, result) return result.get("Stderr")
def test_ceph_pool_creation_with_text_file(self): """Check the creation of a pool and a text file. Create a pool, add a text file to it and retrieve its content. Verify that the content matches the original file. """ issue = 'github.com/openstack-charmers/zaza-openstack-tests/issues/647' current_release = zaza_openstack.get_os_release() focal_victoria = zaza_openstack.get_os_release('focal_victoria') if current_release >= focal_victoria: logging.warn('Skipping test_ceph_pool_creation_with_text_file due' ' to issue {}'.format(issue)) return unit_name = 'ceph-mon/0' cmd = 'sudo ceph osd pool create test 128; \ echo 123456789 > /tmp/input.txt; \ rados put -p test test_input /tmp/input.txt; \ rados get -p test test_input /dev/stdout' logging.debug('Creating test pool and putting test file in pool...') result = zaza_model.run_on_unit(unit_name, cmd) code = result.get('Code') if code != '0': raise zaza_model.CommandRunFailed(cmd, result) output = result.get('Stdout').strip() logging.debug('Output received: {}'.format(output)) self.assertEqual(output, '123456789')
def get_ceph_pool_details(query_leader=True, unit_name=None, model_name=None): """Get ceph pool details. Return a list of ceph pools details dicts. :param query_leader: Whether to query the leader for pool details. :type query_leader: bool :param unit_name: Name of unit to get the pools on if query_leader is False :type unit_name: string :param model_name: Name of model to operate in :type model_name: str :returns: Dict of ceph pools :rtype: List[Dict,] :raise: zaza_model.CommandRunFailed """ cmd = 'sudo ceph osd pool ls detail -f json' if query_leader and unit_name: raise ValueError("Cannot set query_leader and unit_name") if query_leader: result = zaza_model.run_on_leader( 'ceph-mon', cmd, model_name=model_name) else: result = zaza_model.run_on_unit( unit_name, cmd, model_name=model_name) if int(result.get('Code')) != 0: raise zaza_model.CommandRunFailed(cmd, result) return json.loads(result.get('Stdout'))
def get_relation_from_unit(entity, remote_entity, remote_interface_name): """Get relation data passed between two units. Get relation data for relation with `remote_interface_name` between `entity` and `remote_entity` from the perspective of `entity`. `entity` and `remote_entity` may refer to either a application or a specific unit. If application name is given first unit is found in model. :param entity: Application or unit to get relation data from :type entity: str :param remote_entity: Application or Unit in the other end of the relation we want to query :type remote_entity: str :param remote_interface_name: Name of interface to query on remote end of relation :type remote_interface_name: str :returns: dict with relation data :rtype: dict :raises: model.CommandRunFailed """ application = entity.split('/')[0] remote_application = remote_entity.split('/')[0] rid = model.get_relation_id(application, remote_application, remote_interface_name=remote_interface_name) (unit, remote_unit) = _get_unit_names([entity, remote_entity]) cmd = 'relation-get --format=yaml -r "{}" - "{}"'.format(rid, remote_unit) result = model.run_on_unit(unit, cmd) if result and int(result.get('Code')) == 0: return yaml.safe_load(result.get('Stdout')) else: raise model.CommandRunFailed(cmd, result)
def test_01_nrpe_check(self): """Verify nrpe check exists.""" logging.debug( "Verify the nrpe checks are created and have the required content..." ) check_mysql_content = ( "command[check_mysql]=/usr/local/lib/nagios/plugins/check_systemd.py mysql" ) machine = list(juju_utils.get_machines_for_application("mysql"))[0] machine_series = juju_utils.get_machine_series(machine) if machine_series == "trusty": check_mysql_content = ( "command[check_mysql]=/usr/lib/nagios/plugins/check_mysql -u nagios" ) nrpe_checks = { "check_conntrack.cfg": "command[check_conntrack]=/usr/local/lib/nagios/plugins/" "check_conntrack.sh", "check_disk_root.cfg": "command[check_disk_root]=/usr/lib/nagios/plugins/check_disk", "check_load.cfg": "command[check_load]=/usr/lib/nagios/plugins/check_load", "check_mem.cfg": "command[check_mem]=/usr/local/lib/nagios/plugins/check_mem.pl", "check_mysql.cfg": check_mysql_content, "check_mysql_proc.cfg": "command[check_mysql_proc]=/usr/lib/nagios/plugins/" "check_procs -c 1:1 -C mysqld", "check_swap_activity.cfg": "command[check_swap_activity]=" "/usr/local/lib/nagios/plugins/check_swap_activity", "check_swap.cfg": "command[check_swap]=/usr/lib/nagios/plugins/check_swap", } for nrpe_check in nrpe_checks: logging.info( "Checking content of '{}' nrpe check".format(nrpe_check)) cmd = "cat /etc/nagios/nrpe.d/" + nrpe_check result = model.run_on_unit(self.lead_unit_name, cmd) code = result.get("Code") if code != "0": logging.warning( "Unable to find nrpe check {} at /etc/nagios/nrpe.d/". format(nrpe_check)) raise model.CommandRunFailed(cmd, result) content = result.get("Stdout") self.assertTrue(nrpe_checks[nrpe_check] in content)
def test_04_check_nagios_ip_is_allowed(self): """Verify nagios ip is allowed in nrpe.cfg.""" nagios_ip = model.get_app_ips("nagios")[0] line = "allowed_hosts=127.0.0.1,{}/32".format(nagios_ip) cmd = "cat /etc/nagios/nrpe.cfg" result = model.run_on_unit(self.lead_unit_name, cmd) code = result.get("Code") if code != "0": logging.warning( "Unable to find nrpe config file at /etc/nagios/nrpe.cfg") raise model.CommandRunFailed(cmd, result) content = result.get("Stdout") self.assertTrue(line in content)
def leader_get(application, key=''): """Get leader settings from leader unit of named application. :param application: Application to get leader settings from. :type application: str :returns: dict with leader settings :rtype: dict :raises: model.CommandRunFailed """ cmd = 'leader-get --format=yaml {}'.format(key) result = model.run_on_leader(application, cmd) if result and int(result.get('Code')) == 0: return yaml.safe_load(result.get('Stdout')) else: raise model.CommandRunFailed(cmd, result)
def get_ceph_df(unit_name, model_name=None): """Return dict of ceph df json output, including ceph pool state. :param unit_name: Name of the unit to get ceph df :type unit_name: string :param model_name: Name of model to operate in :type model_name: str :returns: Dict of ceph df output :rtype: dict :raise: zaza.model.CommandRunFailed """ cmd = 'sudo ceph df --format=json' result = zaza_model.run_on_unit(unit_name, cmd, model_name=model_name) if result.get('Code') != '0': raise zaza_model.CommandRunFailed(cmd, result) return json.loads(result.get('Stdout'))
def test_05_netlinks(self): """Check netlinks checks are applied.""" netlinks = "- eth0 mtu:9000 speed:10000" model.set_application_config(self.application_name, {"netlinks": netlinks}) model.block_until_all_units_idle() cmd = "cat /etc/nagios/nrpe.d/check_netlinks_eth0.cfg" line = ("command[check_netlinks_eth0]=/usr/local/lib/nagios/plugins/" "check_netlinks.py -i eth0 -m 9000 -s 1000") result = model.run_on_unit(self.lead_unit_name, cmd) code = result.get("Code") if code != "0": logging.warning("Unable to find nrpe check at " "/etc/nagios/nrpe.d/check_netlinks_eth0.cfg") raise model.CommandRunFailed(cmd, result) content = result.get("Stdout") self.assertTrue(line in content)
def leader_get(application, key='', model_name=None): """Get leader settings from leader unit of named application. :param application: Application to get leader settings from. :type application: str :param key: Key option requested :type key: string :param model_name: Name of model to query. :type model_name: str :returns: dict with leader settings :rtype: dict :raises: model.CommandRunFailed """ cmd = 'leader-get --format=yaml {}'.format(key) result = model.run_on_leader(application, cmd, model_name=model_name) if result and int(result.get('Code')) == 0: return yaml.safe_load(result.get('Stdout')) else: raise model.CommandRunFailed(cmd, result)
def test_ceph_pool_creation_with_text_file(self): """Check the creation of a pool and a text file. Create a pool, add a text file to it and retrieve its content. Verify that the content matches the original file. """ unit_name = 'ceph-mon/0' cmd = 'sudo ceph osd pool create test 128; \ echo 123456789 > /tmp/input.txt; \ rados put -p test test_input /tmp/input.txt; \ rados get -p test test_input /dev/stdout' logging.debug('Creating test pool and putting test file in pool...') result = zaza_model.run_on_unit(unit_name, cmd) code = result.get('Code') if code != '0': raise zaza_model.CommandRunFailed(cmd, result) output = result.get('Stdout').strip() logging.debug('Output received: {}'.format(output)) self.assertEqual(output, '123456789')
def get_rbd_hash(unit_name, pool, image, model_name=None): """Get SHA512 hash of RBD image. :param unit_name: Name of unit to execute ``rbd`` command on :type unit_name: str :param pool: Name of pool to export image from :type pool: str :param image: Name of image to export and compute checksum on :type image: str :param model_name: Name of Juju model to operate on :type model_name: str :returns: SHA512 hash of RBD image :rtype: str :raises: zaza.model.CommandRunFailed """ cmd = ('sudo rbd -p {} export --no-progress {} - | sha512sum' .format(pool, image)) result = zaza_model.run_on_unit(unit_name, cmd, model_name=model_name) if result.get('Code') != '0': raise zaza_model.CommandRunFailed(cmd, result) return result.get('Stdout').rstrip()
def get_ceph_pools(unit_name, model_name=None): """Get ceph pools. Return a dict of ceph pools from a single ceph unit, with pool name as keys, pool id as vals. :param unit_name: Name of the unit to get the pools on :type unit_name: string :param model_name: Name of model to operate in :type model_name: str :returns: Dict of ceph pools :rtype: dict :raise: zaza_model.CommandRunFailed """ pools = {} cmd = 'sudo ceph osd lspools' result = zaza_model.run_on_unit(unit_name, cmd, model_name=model_name) output = result.get('Stdout').strip() code = int(result.get('Code')) if code != 0: raise zaza_model.CommandRunFailed(cmd, result) # Example output: 0 data,1 metadata,2 rbd,3 cinder,4 glance, # It can also be something link 0 data\n1 metadata # First split on new lines osd_pools = str(output).split('\n') # If we have a len of 1, no new lines found -> splitting on commas if len(osd_pools) == 1: osd_pools = osd_pools[0].split(',') for pool in osd_pools: pool_id_name = pool.split(' ') if len(pool_id_name) == 2: pool_id = pool_id_name[0] pool_name = pool_id_name[1] pools[pool_name] = int(pool_id) logging.debug('Pools on {}: {}'.format(unit_name, pools)) return pools
def test_03_user_monitor(self): """Verify user monitors are applied.""" user_monitors = { "version": "0.3", "monitors": { "local": { "procrunning": { "rsync": { "max": 1, "executable": "rsync", "name": "RSYNc Running", "min": 1, }, "jujud": { "max": 1, "executable": "jujud", "name": "Juju Running", "min": 1, }, } }, "remote": { "tcp": { "ssh": { "warning": 2, "critical": 10, "name": "SSH Running", "timeout": 12, "port": 22, "string": "SSH.*", "expect": None, } } }, }, } model.set_application_config(self.application_name, {"monitors": yaml.dump(user_monitors)}) model.block_until_all_units_idle() local_nrpe_checks = { "check_proc_jujud_user.cfg": "command[check_proc_jujud_user]=/usr/lib/nagios/plugins/" "check_procs -w 1 -c 1 -C jujud", "check_proc_rsync_user.cfg": "command[check_proc_rsync_user]=/usr/lib/nagios/plugins/" "check_procs -w 1 -c 1 -C rsync", } for nrpe_check in local_nrpe_checks: logging.info( "Checking content of '{}' nrpe check".format(nrpe_check)) cmd = "cat /etc/nagios/nrpe.d/" + nrpe_check result = model.run_on_unit(self.lead_unit_name, cmd) code = result.get("Code") if code != "0": logging.warning( "Unable to find nrpe check {} at /etc/nagios/nrpe.d/". format(nrpe_check)) raise model.CommandRunFailed(cmd, result) content = result.get("Stdout") self.assertTrue(local_nrpe_checks[nrpe_check] in content) remote_nrpe_checks = { "check_tcp_H_HOSTADDRESS__E_p22_s_SSH____eNone_w2_c10_t12_t10.cfg": "/usr/lib/nagios/plugins/check_tcp -H $HOSTADDRESS$ " "-E -p 22 -s 'SSH.*' -e None -w 2 -c 10 -t 12 -t 10" } for nrpe_check in remote_nrpe_checks: logging.info( "Checking content of '{}' nrpe command in nagios unit".format( nrpe_check)) cmd = "cat /etc/nagios3/conf.d/commands/" + nrpe_check nagios_lead_unit_name = model.get_lead_unit_name( "nagios", model_name=self.model_name) result = model.run_on_unit(nagios_lead_unit_name, cmd) code = result.get("Code") if code != "0": logging.warning( "Unable to find nrpe command {} at " "/etc/nagios3/conf.d/commands/ in nagios unit".format( nrpe_check)) raise model.CommandRunFailed(cmd, result) content = result.get("Stdout") self.assertTrue(remote_nrpe_checks[nrpe_check] in content)