def hosts_facts(self): """Obtain the managed hosts detail raw facts.""" if self.inspect_scan_task is None: raise SatelliteException( 'hosts_facts cannot be called for a connection scan') systems_count = len( self.connect_scan_task.connection_result.systems.all()) self.inspect_scan_task.update_stats( 'INITIAL STATELLITE STATS', sys_count=systems_count) hosts = [] client, user, password = utils.get_sat5_client(self.inspect_scan_task) try: key = client.auth.login(user, password) hosts = client.system.list_user_systems(key) client.auth.logout(key) except xmlrpc.client.Fault as xml_error: raise SatelliteException(str(xml_error)) virtual_hosts, virtual_guests = self.virtual_hosts() physical_hosts = self.physical_hosts() for host in hosts: last_checkin = str(host.get(LAST_CHECKIN, '')) self.host_details(host.get(ID), host.get(NAME), last_checkin, virtual_hosts, virtual_guests, physical_hosts)
def hosts_facts(self): """Obtain the managed hosts detail raw facts.""" systems_count = len( self.connect_scan_task.connection_result.systems.all()) if self.inspect_scan_task is None: raise SatelliteException( 'hosts_facts cannot be called for a connection scan') self.inspect_scan_task.update_stats( 'INITIAL STATELLITE STATS', sys_count=systems_count) jsonresult = {} page = 0 per_page = 100 while (page == 0 or int(jsonresult.get(PER_PAGE, 0)) == len(jsonresult.get(RESULTS, []))): page += 1 params = {PAGE: page, PER_PAGE: per_page, THIN: 1} response, url = utils.execute_request(self.inspect_scan_task, url=HOSTS_V2_URL, query_params=params) # pylint: disable=no-member if response.status_code != requests.codes.ok: raise SatelliteException('Invalid response code %s' ' for url: %s' % (response.status_code, url)) jsonresult = response.json() for host in jsonresult.get(RESULTS, []): self.host_details(host.get(ID), host.get(NAME))
def hosts_facts(self, manager_interrupt): """Obtain the managed hosts detail raw facts.""" systems_count = len( self.connect_scan_task.connection_result.systems.all()) if self.inspect_scan_task is None: raise SatelliteException( 'hosts_facts cannot be called for a connection scan') self.inspect_scan_task.update_stats('INITIAL STATELLITE STATS', sys_count=systems_count) deduplicated_hosts = [] # pylint: disable=too-many-nested-blocks with Pool(processes=self.max_concurrency) as pool: orgs = self.get_orgs() for org_id in orgs: jsonresult = {} page = 0 per_page = 100 while (page == 0 or int(jsonresult.get(PER_PAGE, 0)) == len( jsonresult.get(RESULTS, []))): page += 1 params = {PAGE: page, PER_PAGE: per_page, THIN: 1} response, url = \ utils.execute_request(self.inspect_scan_task, url=HOSTS_V1_URL, org_id=org_id, query_params=params) # pylint: disable=no-member if response.status_code != requests.codes.ok: raise SatelliteException('Invalid response code %s' ' for url: %s' % (response.status_code, url)) jsonresult = response.json() hosts_before_dedup = jsonresult.get(RESULTS, []) hosts_after_dedup = [] for host in hosts_before_dedup: if host not in deduplicated_hosts: hosts_after_dedup.append(host) deduplicated_hosts.append(host) hosts = hosts_after_dedup chunks = [ hosts[i:i + self.max_concurrency] for i in range(0, len(hosts), self.max_concurrency) ] for chunk in chunks: if manager_interrupt.value == \ ScanJob.JOB_TERMINATE_CANCEL: raise SatelliteCancelException() if manager_interrupt.value == \ ScanJob.JOB_TERMINATE_PAUSE: raise SatellitePauseException() host_params = self.prepare_host(chunk) results = pool.starmap(request_host_details, host_params) process_results(self, results, 1) utils.validate_task_stats(self.inspect_scan_task)
def hosts_facts(self, manager_interrupt): """Obtain the managed hosts detail raw facts.""" systems_count = len( self.connect_scan_task.connection_result.systems.all()) if self.inspect_scan_task is None: raise SatelliteException( 'hosts_facts cannot be called for a connection scan') self.inspect_scan_task.update_stats('INITIAL STATELLITE STATS', sys_count=systems_count) with Pool(processes=self.max_concurrency) as pool: jsonresult = {} page = 0 per_page = 100 while (page == 0 or int(jsonresult.get(PER_PAGE, 0)) == len( jsonresult.get(RESULTS, []))): page += 1 params = {PAGE: page, PER_PAGE: per_page, THIN: 1} response, url = utils.execute_request(self.inspect_scan_task, url=HOSTS_V2_URL, query_params=params) # pylint: disable=no-member if response.status_code != requests.codes.ok: raise SatelliteException('Invalid response code %s' ' for url: %s' % (response.status_code, url)) jsonresult = response.json() hosts = jsonresult.get(RESULTS, []) chunks = [ hosts[i:i + self.max_concurrency] for i in range(0, len(hosts), self.max_concurrency) ] for chunk in chunks: if manager_interrupt.value == ScanJob.JOB_TERMINATE_CANCEL: raise SatelliteCancelException() if manager_interrupt.value == ScanJob.JOB_TERMINATE_PAUSE: raise SatellitePauseException() host_params = [(host.get(ID), host.get(NAME)) for host in chunk] results = pool.starmap(self.host_details, host_params) for result in results: if result is not None: self.record_inspect_result(result.get('name'), result.get('details'), result.get('status')) utils.validate_task_stats(self.inspect_scan_task)
def host_details(self, host_id, host_name): """Obtain the details for a given host id and name. :param host_id: The identifier of the host :param host_name: The name of the host :returns: dictionary of host details """ if self.inspect_scan_task is None: raise SatelliteException( 'host_details cannot be called for a connection scan') details = {} sys_result = self.inspect_scan_task.inspection_result.systems.filter( name=host_name).first() if sys_result: logger.debug('Results already captured for host_name=%s', host_name) return details try: details.update(host_fields(self.inspect_scan_task, 2, HOSTS_FIELDS_V2_URL, None, host_id)) details.update(host_subscriptions(self.inspect_scan_task, HOSTS_SUBS_V2_URL, None, host_id)) self.record_inspect_result(host_name, details) logger.debug('host_id=%s, host_details=%s', host_id, details) except SatelliteException as sat_error: error_message = 'Satellite error encountered: %s\n' % sat_error self.record_inspect_result(host_name, details, status=SystemInspectionResult.FAILED) logger.error(error_message) return details
def get_orgs(self): """Get the organization ids. :returns: List of organization ids """ if self.orgs: return self.orgs orgs = [] jsonresult = {} page = 0 per_page = 100 while (page == 0 or int(jsonresult.get(PER_PAGE, 0)) == len(jsonresult.get(RESULTS, []))): page += 1 params = {PAGE: page, PER_PAGE: per_page, THIN: 1} response, url = utils.execute_request(self.connect_scan_task, ORGS_V1_URL, params) # pylint: disable=no-member if response.status_code != requests.codes.ok: raise SatelliteException('Invalid response code %s' ' for url: %s' % (response.status_code, url)) jsonresult = response.json() for result in jsonresult.get(RESULTS, []): org_id = result.get(ID) if org_id is not None: orgs.append(org_id) self.orgs = orgs return self.orgs
def hosts(self): """Obtain the managed hosts.""" hosts = [] jsonresult = {} page = 0 per_page = 100 credential = utils.get_credential(self.connect_scan_task) while (page == 0 or int(jsonresult.get(PER_PAGE, 0)) == len(jsonresult.get(RESULTS, []))): page += 1 params = {PAGE: page, PER_PAGE: per_page, THIN: 1} response, url = utils.execute_request(self.connect_scan_task, url=HOSTS_V2_URL, query_params=params) # pylint: disable=no-member if response.status_code != requests.codes.ok: raise SatelliteException('Invalid response code %s' ' for url: %s' % (response.status_code, url)) jsonresult = response.json() for result in jsonresult.get(RESULTS, []): host_name = result.get(NAME) host_id = result.get(ID) if host_name is not None and host_id is not None: unique_name = '%s_%s' % (host_name, host_id) hosts.append(unique_name) self.record_conn_result(unique_name, credential) return hosts
def hosts_facts(self): """Obtain the managed hosts detail raw facts.""" systems_count = len(self.conn_result.systems.all()) self.initialize_stats(systems_count) orgs = self.get_orgs() for org_id in orgs: jsonresult = {} page = 0 per_page = 100 while (page == 0 or int(jsonresult.get(PER_PAGE, 0)) == len( jsonresult.get(RESULTS, []))): page += 1 params = {PAGE: page, PER_PAGE: per_page, THIN: 1} response, url = utils.execute_request(self.scan_task, url=HOSTS_V1_URL, org_id=org_id, query_params=params) # pylint: disable=no-member if response.status_code != requests.codes.ok: raise SatelliteException('Invalid response code %s' ' for url: %s' % (response.status_code, url)) jsonresult = response.json() for host in jsonresult.get(RESULTS, []): self.host_details(org_id, host.get(ID), host.get(NAME))
def prepare_host(self, chunk): """Prepare each host with necessary information. :param chunk: A list of hosts :returns A list of tuples that contain information about each host. """ if self.inspect_scan_task is None: raise SatelliteException( 'host_details cannot be called for a connection scan') defined_host, port, user, password = utils.get_connect_data( self.inspect_scan_task) ssl_cert_verify = True source_options = self.inspect_scan_task.source.options if source_options: ssl_cert_verify = source_options.ssl_cert_verify request_options = {'host': defined_host, 'port': port, 'user': user, 'password': password, 'ssl_cert_verify': ssl_cert_verify} logging_options = { 'job_id': self.scan_job.id, 'task_sequence_number': self.inspect_scan_task.sequence_number, 'scan_type': self.inspect_scan_task.scan_type, 'source_type': self.inspect_scan_task.source.source_type, 'source_name': self.inspect_scan_task.source.name} host_params = [(self.inspect_scan_task, logging_options, host.get(ID), host.get(NAME), HOSTS_FIELDS_V2_URL, HOSTS_SUBS_V2_URL, request_options) for host in chunk] return host_params
def virtual_hosts(self): """Obtain the virtual host data. :returns: tuple of (list of virtual host ids, dictionary of virtual guest id to virtual_host_id) """ virt_hosts = [] virtual_hosts = {} virtual_guests = {} client, user, password = utils.get_sat5_client(self.connect_scan_task) try: key = client.auth.login(user, password) virt_hosts = client.system.list_virtual_hosts(key) for virt_host in virt_hosts: virt_host_id = virt_host.get(ID) virt_host_name = virt_host.get(NAME) uuid = client.system.get_uuid(key, virt_host_id) if uuid is None or uuid == '': uuid = virt_host_id virtual_host = {ID: virt_host_id, NAME: virt_host_name, UUID: uuid} virtual_hosts[virt_host_id] = virtual_host client.auth.logout(key) except xmlrpc.client.Fault as xml_error: raise SatelliteException(str(xml_error)) for virt_host in virt_hosts: virt_host_id = virt_host.get(ID) virtual_host = virtual_hosts.get(virt_host_id) guests, guest_count = self.virtual_guests(virt_host_id) virtual_guests.update(guests) virtual_host[NUM_VIRTUAL_GUESTS] = guest_count return(virtual_hosts, virtual_guests)
def hosts_facts(self, manager_interrupt): """Obtain the managed hosts detail raw facts.""" if self.inspect_scan_task is None: raise SatelliteException( 'hosts_facts cannot be called for a connection scan') systems_count = len( self.connect_scan_task.connection_result.systems.all()) self.inspect_scan_task.update_stats( 'INITIAL STATELLITE STATS', sys_count=systems_count) hosts = [] client, user, password = utils.get_sat5_client(self.inspect_scan_task) with Pool(processes=self.max_concurrency) as pool: try: key = client.auth.login(user, password) hosts = client.system.list_user_systems(key) client.auth.logout(key) except xmlrpc.client.Fault as xml_error: raise SatelliteException(str(xml_error)) virtual_hosts, virtual_guests = self.virtual_hosts() physical_hosts = self.physical_hosts() chunks = [hosts[i:i + self.max_concurrency] for i in range(0, len(hosts), self.max_concurrency)] for chunk in chunks: if manager_interrupt.value == ScanJob.JOB_TERMINATE_CANCEL: raise SatelliteCancelException() if manager_interrupt.value == ScanJob.JOB_TERMINATE_PAUSE: raise SatellitePauseException() host_params = [(host.get(ID), host.get(NAME), str(host.get(LAST_CHECKIN, '')), virtual_hosts, virtual_guests, physical_hosts) for host in chunk] results = pool.starmap(self.host_details, host_params) for result in results: if result is not None: self.record_inspect_result( result.get('name'), result.get('details'), result.get('status')) utils.validate_task_stats(self.inspect_scan_task)
def hosts_facts(self, manager_interrupt): """Obtain the managed hosts detail raw facts.""" if self.inspect_scan_task is None: raise SatelliteException( 'hosts_facts cannot be called for a connection scan') systems_count = len( self.connect_scan_task.connection_result.systems.all()) self.inspect_scan_task.update_stats('INITIAL STATELLITE STATS', sys_count=systems_count) hosts_before_dedup = [] deduplicated_hosts = [] client, user, password = utils.get_sat5_client(self.inspect_scan_task) with Pool(processes=self.max_concurrency) as pool: try: key = client.auth.login(user, password) hosts_before_dedup = client.system.list_user_systems(key) client.auth.logout(key) except xmlrpc.client.Fault as xml_error: raise SatelliteException(str(xml_error)) virtual_hosts, virtual_guests = self.virtual_hosts() physical_hosts = self.physical_hosts() hosts_after_dedup = [] for host in hosts_before_dedup: if host not in deduplicated_hosts: hosts_after_dedup.append(host) deduplicated_hosts.append(host) hosts = hosts_before_dedup chunks = [ hosts[i:i + self.max_concurrency] for i in range(0, len(hosts), self.max_concurrency) ] for chunk in chunks: if manager_interrupt.value == ScanJob.JOB_TERMINATE_CANCEL: raise SatelliteCancelException() if manager_interrupt.value == ScanJob.JOB_TERMINATE_PAUSE: raise SatellitePauseException() host_params = self.prepare_host(chunk) results = pool.starmap(request_host_details, host_params) self.process_results(results, virtual_hosts, virtual_guests, physical_hosts) utils.validate_task_stats(self.inspect_scan_task)
def host_subscriptions(scan_task, url, org_id, host_id): """Obtain the subscriptions for a given host id. :param scan_task: The scan task being executed :param url: The endpoint URL to get data from :param org_id: The organization identifier :param host_id: The identifier of the host being queried. :returns: dictionary of facts from subscriptions endpoint """ response, url = utils.execute_request(scan_task, url=url, org_id=org_id, host_id=host_id) # pylint: disable=no-member if response.status_code == 400 or response.status_code == 404: content_type = response.headers.get(CONTENT_TYPE) if content_type and APP_JSON in content_type: message = 'Invalid status code %s for url: %s. Response: %s' %\ (response.status_code, url, response.json()) scan_task.log_message(message, log_level=logging.WARN) else: message = 'Invalid status code %s for url: %s. '\ 'Response not JSON' %\ (response.status_code, url) scan_task.log_message(message, log_level=logging.WARN) subs_dict = {ENTITLEMENTS: []} return subs_dict elif response.status_code != requests.codes.ok: raise SatelliteException('Invalid response code %s' ' for url: %s' % (response.status_code, url)) entitlements = response.json().get(RESULTS, []) subscriptons = [] for entitlement in entitlements: sub = { DERIVED_ENTITLEMENT: False, NAME: entitlement.get(PRODUCT_NAME), ACCOUNT_NUMBER: entitlement.get(ACCOUNT_NUMBER), CONTRACT_NUMBER: entitlement.get(CONTRACT_NUMBER), START_DATE: entitlement.get(START_DATE), END_DATE: entitlement.get(END_DATE), } amount = entitlement.get(QUANTITY_CONSUMED) if amount is None: amount = entitlement.get(AMOUNT) sub[AMOUNT] = amount entitlement_type = entitlement.get(ENTITLEMENT_TYPE) if (entitlement_type and entitlement_type in ENTITLEMENT_DERIVED_LIST): sub[DERIVED_ENTITLEMENT] = True subscriptons.append(sub) subs_dict = {ENTITLEMENTS: subscriptons} return subs_dict
def mock_sat_exception(param1, param2, param3, param4, param5, param6=None, param7=None, param8=None, param9=None, param10=None): """Mock method to throw satellite error.""" raise SatelliteException()
def host_count(self): """Obtain the count of managed hosts.""" params = {PAGE: 1, PER_PAGE: 10, THIN: 1} response, url = utils.execute_request(self.scan_task, url=HOSTS_V2_URL, query_params=params) # pylint: disable=no-member if response.status_code != requests.codes.ok: raise SatelliteException('Invalid response code %s for url: %s' % (response.status_code, url)) systems_count = response.json().get('total', 0) self.initialize_stats(systems_count) return systems_count
def _status5(scan_task): """Check Satellite status to get api_version and connectivity. :param scan_task: The scan task :returns: tuple (status_code, api_version or None) """ client, user, password = get_sat5_client(scan_task) try: key = client.auth.login(user, password) client.auth.logout(key) except xmlrpc.client.Fault as xml_error: invalid_auth = 'Either the password or username is incorrect.' if invalid_auth in str(xml_error): raise SatelliteAuthException(str(xml_error)) else: raise SatelliteException(str(xml_error)) except xmlrpc.client.ProtocolError as protocol_error: raise SatelliteException(str(protocol_error)) api_version = SATELLITE_VERSION_5 status_code = codes.HTTP_200_OK # pylint: disable=no-member return (status_code, api_version, SATELLITE_VERSION_5)
def host_count(self): """Obtain the count of managed hosts.""" systems_count = 0 client, user, password = utils.get_sat5_client(self.scan_task) try: key = client.auth.login(user, password) systems = client.system.list_user_systems(key) systems_count = len(systems) client.auth.logout(key) except xmlrpc.client.Fault as xml_error: raise SatelliteException(str(xml_error)) self.initialize_stats(systems_count) return systems_count
def _status5(scan_task): """Check Satellite status to get api_version and connectivity. :param scan_task: The scan task :returns: tuple (status_code, api_version or None) """ client, user, password = get_sat5_client(scan_task) try: key = client.auth.login(user, password) client.auth.logout(key) except xmlrpc.client.Fault as xml_error: raise SatelliteException(str(xml_error)) api_version = SourceOptions.SATELLITE_VERSION_5 status_code = requests.codes.ok # pylint: disable=no-member return (status_code, api_version)
def host_details(self, org_id, host_id, host_name): """Obtain the details for a given host id and name. :param org_id: The organization identifier :param host_id: The identifier of the host :param host_name: The name of the host :returns: dictionary of host details """ if self.inspect_scan_task is None: raise SatelliteException( 'host_details cannot be called for a connection scan') details = {} unique_name = '%s_%s' % (host_name, host_id) sys_result = self.inspect_scan_task.inspection_result.systems.filter( name=unique_name).first() if sys_result: logger.debug('Results already captured for host_name=%s', host_name) return None try: message = 'REQUESTING HOST DETAILS: %s' % unique_name self.inspect_scan_task.log_message(message) details.update( host_fields(self.inspect_scan_task, 1, HOSTS_FIELDS_V1_URL, org_id, host_id)) details.update( host_subscriptions(self.inspect_scan_task, HOSTS_SUBS_V1_URL, org_id, host_id)) logger.debug('host_id=%s, host_details=%s', host_id, details) return { 'name': unique_name, 'details': details, 'status': SystemInspectionResult.SUCCESS } except SatelliteException as sat_error: error_message = 'Satellite unknown 6v1 error encountered: %s\n' \ % sat_error logger.error(error_message) return { 'name': unique_name, 'details': details, 'status': SystemInspectionResult.FAILED } return details
def validate_task_stats(task): """Map data keys to new output. :param task: ScanTask to evaluate :throws: SatelliteException if task stats are not valid """ systems_count,\ systems_scanned, \ systems_failed, \ systems_unreachable = task.calculate_counts() totals = +systems_scanned + systems_failed + systems_unreachable if totals != systems_count: missing_sys = systems_count - totals error = 'Scan failed to inspect %d systems.' % missing_sys task.log_message(error, log_level=logging.ERROR) new_failed = missing_sys + systems_failed task.update_stats('Missed failed systems', sys_failed=new_failed) raise SatelliteException('hosts_facts could not scan all systems')
def physical_hosts(self): """Obtain the physical host data. :returns: list of phyiscal host ids """ physical_hosts = [] client, user, password = utils.get_sat5_client(self.connect_scan_task) try: key = client.auth.login(user, password) physical_systems = client.system.list_physical_systems(key) for system in physical_systems: host_id = system.get(ID) if host_id: physical_hosts.append(host_id) client.auth.logout(key) except xmlrpc.client.Fault as xml_error: raise SatelliteException(str(xml_error)) return physical_hosts
def host_count(self): """Obtain the count of managed hosts.""" systems_count = 0 orgs = self.get_orgs() for org_id in orgs: params = {PAGE: 1, PER_PAGE: 100, THIN: 1} response, url = utils.execute_request(self.connect_scan_task, url=HOSTS_V1_URL, org_id=org_id, query_params=params) # pylint: disable=no-member if response.status_code != requests.codes.ok: raise SatelliteException('Invalid response code %s' ' for url: %s' % (response.status_code, url)) systems_count += response.json().get('total', 0) self.connect_scan_task.update_stats( 'INITIAL STATELLITE STATS', sys_count=systems_count) return systems_count
def hosts_facts(self): """Obtain the managed hosts detail raw facts.""" systems_count = len(self.conn_result.systems.all()) self.initialize_stats(systems_count) hosts = [] client, user, password = utils.get_sat5_client(self.scan_task) try: key = client.auth.login(user, password) hosts = client.system.list_user_systems(key) client.auth.logout(key) except xmlrpc.client.Fault as xml_error: raise SatelliteException(str(xml_error)) virtual_hosts, virtual_guests = self.virtual_hosts() for host in hosts: last_checkin = str(host.get(LAST_CHECKIN, '')) self.host_details(host.get(ID), host.get(NAME), last_checkin, virtual_hosts, virtual_guests)
def hosts(self): """Obtain the managed hosts.""" hosts = [] credential = utils.get_credential(self.scan_task) client, user, password = utils.get_sat5_client(self.scan_task) try: key = client.auth.login(user, password) systems = client.system.list_user_systems(key) client.auth.logout(key) for system in systems: name = system.get(NAME) if name is not None: hosts.append(name) self.record_conn_result(name, credential) except xmlrpc.client.Fault as xml_error: raise SatelliteException(str(xml_error)) return hosts
def _status6(scan_task): """Check Satellite status to get api_version and connectivity. :param scan_task: The scan task :returns: tuple (status_code, api_version or None) """ status_url = 'https://{sat_host}:{port}/api/status' response, url = execute_request(scan_task, status_url) status_code = response.status_code api_version = None if status_code == codes.HTTP_200_OK: status_data = response.json() api_version = status_data.get('api_version') elif status_code == codes.HTTP_401_UNAUTHORIZED: err_msg = 'Unable to authenticate against ' + url raise SatelliteAuthException(err_msg) else: err_msg = 'Failure while attempting Satellite 6' ' status check at {} for task {} with status code {}.'.format( url, scan_task.id, status_code) raise SatelliteException(err_msg) return (status_code, api_version, SATELLITE_VERSION_6)
def virtual_guests(self, virtual_host_id): """Obtain the virtual guest information for a virtual host. :param virtual_host_id: The identifier for a virtual host :returns: a tuple of a dictionary of virtual guest id, virtual_host_id and the number of guests """ virtual_guests = {} virt_guests = [] client, user, password = utils.get_sat5_client(self.connect_scan_task) try: key = client.auth.login(user, password) virt_guests = client.system.list_virtual_guests( key, virtual_host_id) client.auth.logout(key) except xmlrpc.client.Fault as xml_error: raise SatelliteException(str(xml_error)) for guest in virt_guests: virt_id = guest.get(ID) virtual_guests[virt_id] = virtual_host_id return (virtual_guests, len(virt_guests))
def request_host_details(scan_task, logging_options, host_id, host_name, fields_url, subs_url, request_options): """Execute both http responses to gather satallite data. :param scan_task: The current scan task :param logging_options: The metadata for logging :param host_id: The id of the host we're inspecting :param host_name: The name of the host we're inspecting :param fields_url: The sat61 or sat62 fields url :param subs_url: The sat61 or sat62 subs url :param request_options: A dictionary containing host, port, ssl_cert_verify, user, and password :returns: A dictionary containing the unique name for the host, the response & url for host_fields request, and the response & url for the host_subs request. """ unique_name = '%s_%s' % (host_name, host_id) host_fields_json = {} host_subscriptions_json = {} results = {} try: message = 'REQUESTING HOST DETAILS: %s' % unique_name scan_task.log_message(message, logging.INFO, logging_options) host_fields_response, host_fields_url = \ utils.execute_request(scan_task, url=fields_url, org_id=None, host_id=host_id, query_params=QUERY_PARAMS_FIELDS, options=request_options) # pylint: disable=no-member if host_fields_response.status_code != requests.codes.ok: raise SatelliteException('Invalid response code %s' ' for url: %s' % (host_fields_response.status_code, host_fields_url)) host_subscriptions_response, host_subscriptions_url = \ utils.execute_request(scan_task, url=subs_url, org_id=None, host_id=host_id, options=request_options) # pylint: disable=no-member if host_subscriptions_response.status_code == 400 or \ host_subscriptions_response.status_code == 404: content_type = \ host_subscriptions_response.headers.get(CONTENT_TYPE) if content_type and APP_JSON in content_type: message = \ 'Invalid status code %s for url: %s. Response: %s' % \ (host_subscriptions_response.status_code, host_subscriptions_url, host_subscriptions_response.json()) scan_task.log_message(message, logging.WARN, logging_options) else: message = 'Invalid status code %s for url: %s. ' \ 'Response not JSON' % \ (host_subscriptions_response.status_code, host_subscriptions_url) scan_task.log_message(message, logging.WARN, logging_options) elif host_subscriptions_response.status_code != requests.codes.ok: raise SatelliteException( 'Invalid response code %s for url: %s' % ( host_subscriptions_response.status_code, host_subscriptions_url)) system_inspection_result = SystemInspectionResult.SUCCESS host_fields_json = host_fields_response.json() host_subscriptions_json = host_subscriptions_response.json() except SatelliteException as sat_error: error_message = 'Satellite 6 unknown error encountered: %s\n' \ % sat_error logger.error(error_message) system_inspection_result = SystemInspectionResult.FAILED except Timeout as timeout_error: error_message = 'Satellite 6 timeout error encountered: %s\n' \ % timeout_error logger.error(error_message) system_inspection_result = SystemInspectionResult.FAILED results['unique_name'] = unique_name results['system_inspection_result'] = system_inspection_result results['host_fields_response'] = host_fields_json results['host_subscriptions_response'] = host_subscriptions_json return results
def mock_sat_exception(param1): # pylint: disable=unused-argument """Mock method to throw satellite error.""" raise SatelliteException()
def host_fields(scan_task, api_version, url, org_id, host_id): """Obtain the fields for a given host id. :param scan_task: The scan task being executed :param api_version: The version of the Satellite api :param url: The endpoint URL to get data from :param org_id: The organization identifier :param host_id: The identifier of the host being queried. :returns: dictionary of facts from fields endpoint """ response, url = utils.execute_request(scan_task, url=url, org_id=org_id, host_id=host_id, query_params=QUERY_PARAMS_FIELDS) # pylint: disable=no-member if response.status_code != requests.codes.ok: raise SatelliteException('Invalid response code %s' ' for url: %s' % (response.status_code, url)) fields = response.json() host_info = {} sub_virt_host = None sub_virt_guest = None cf_errata_counts = None sub_facet_attributes = fields.get(SUBSCRIPTION_FACET) content_facet_attributes = fields.get(CONTENT_FACET) facts = fields.get(FACTS, {}) virtual_host = fields.get(VIRTUAL_HOST, {}) virtual_guests = fields.get(VIRTUAL_GUESTS) errata_counts = fields.get(ERRATA_COUNTS, {}) if sub_facet_attributes: sub_virt_host = sub_facet_attributes.get(VIRTUAL_HOST) sub_virt_guest = sub_facet_attributes.get(VIRTUAL_GUESTS) if content_facet_attributes: cf_errata_counts = content_facet_attributes.get(ERRATA_COUNTS) host_info.update(utils.data_map(FIELDS_MAPPING, fields)) host_info.update(utils.data_map(SUBS_FACET_MAPPING, sub_facet_attributes)) host_info.update(utils.data_map(VIRTUAL_HOST_MAPPING, sub_virt_host)) host_info.update( utils.data_map(CONTENT_FACET_MAPPING, content_facet_attributes)) host_info.update(utils.data_map(ERRATA_MAPPING, cf_errata_counts)) if api_version == 1: host_info.update(utils.data_map(FACTS_MAPPING, facts)) else: host_info.update(utils.data_map(FACTS_V2_MAPPING, facts)) host_info.update(utils.data_map(VIRTUAL_HOST_MAPPING, virtual_host)) host_info.update(utils.data_map(ERRATA_MAPPING, errata_counts)) if sub_virt_guest: host_info[VIRTUAL_GUESTS] = [x[NAME] for x in sub_virt_guest] host_info[NUM_VIRTUAL_GUESTS] = len(sub_virt_guest) if virtual_guests: host_info[VIRTUAL_GUESTS] = [x[NAME] for x in virtual_guests] host_info[NUM_VIRTUAL_GUESTS] = len(virtual_guests) if host_info.get(VIRTUAL_GUESTS): host_info[VIRTUAL] = HYPERVISOR host_info[LOCATION] = fields.get(LOCATION_NAME) ipv4s = [] macs = [] for key in facts: net_interface = (key.startswith(NET_INTER_PERIOD) or key.startswith(NET_INTER_COLON)) net_interface_lo = (key.startswith(NET_INTER_LO_PERIOD) or key.startswith(NET_INTER_LO_COLON)) if net_interface and not net_interface_lo: ipv4_addr = (key.endswith(IPV4_PERIOD) or key.endswith(IPV4_COLON)) mac_addr = (key.endswith(MAC_PERIOD) or key.endswith(MAC_COLON)) if ipv4_addr and facts[key]: ipv4s.append(facts[key]) if mac_addr and facts[key]: macs.append(facts[key]) host_info[IP_ADDRESSES] = ipv4s host_info[MAC_ADDRESSES] = macs os_release = host_info.get(OS_RELEASE) if os_release: os_name = os_release.split(' ')[0] if os_release.lower().startswith('red hat enterprise linux'): os_name = 'Red Hat Enterprise Linux' elif os_release.lower().startswith('red hat'): os_name = 'Red Hat' host_info[OS_NAME] = os_name host_info[OS_VERSION] = os_release.rsplit(' ').pop() host_info.pop(VIRTUAL_GUESTS, None) return host_info
def host_details(self, host_id, host_name, last_checkin, virtual_hosts, virtual_guests): """Obtain the details for a given host id and name. :param host_id: The identifier of the host :param host_name: The name of the host :param last_checkin: The date of last checkin :param virtual_hosts: A dictionary of virtual host data :param virtual_guests: A dictionary of guest to host data :returns: dictionary of host details """ details = {} sys_result = self.inspect_result.systems.filter(name=host_name).first() if sys_result: logger.debug('Results already captured for host_name=%s', host_name) return details client, user, password = utils.get_sat5_client(self.scan_task) try: key = client.auth.login(user, password) uuid = client.system.get_uuid(key, host_id) if uuid is None or uuid == '': uuid = host_id cpu = client.system.get_cpu(key, host_id) arch = cpu.get(ARCH, UNKNOWN) cpu_count = cpu.get(COUNT) cpu_core_count = cpu_count cpu_socket_count = cpu.get(SOCKET_COUNT) system_details = client.system.get_details(key, host_id) hostname = system_details.get(HOSTNAME) release = system_details.get(RELEASE) kernel = client.system.get_running_kernel(key, host_id) entitlements = [] subs = client.system.get_entitlements(key, host_id) for sub in subs: entitlement = {NAME: sub} entitlements.append(entitlement) network_devices = client.system.get_network_devices(key, host_id) ip_addresses = [] mac_addresses = [] for device in network_devices: interface = device.get(INTERFACE) if interface and interface.startswith(ETHERNET): ip_addr = device.get(IP) if ip_addr: ip_addresses.append(ip_addr) mac = device.get(HARDWARE_ADDRESS) if mac: mac_addresses.append(mac) registration_date = client.system.get_registration_date( key, host_id) details[UUID] = uuid details[NAME] = host_name details[HOSTNAME] = hostname details[LAST_CHECKIN_TIME] = last_checkin details[REGISTRATION_TIME] = str(registration_date) details[ARCHITECTURE] = arch details[KERNEL] = kernel details[CORES] = cpu_core_count details[SOCKETS] = cpu_socket_count details[OS_RELEASE] = release details[ENTITLEMENTS] = entitlements details[IP_ADDRESSES] = ip_addresses details[MAC_ADDRESSES] = mac_addresses if virtual_hosts.get(host_id): virtual_host = virtual_hosts.get(host_id) details[VIRTUAL] = HYPERVISOR guests = virtual_host.get(NUM_VIRTUAL_GUESTS, 0) details[NUM_VIRTUAL_GUESTS] = guests details[IS_VIRT] = False elif virtual_guests.get(host_id): virt_host_id = virtual_guests.get(host_id) virtual_host = virtual_hosts.get(virt_host_id) details[IS_VIRT] = True if virtual_host.get(UUID): details[VIRTUAL_HOST] = virtual_host.get(UUID) if virtual_host.get(NAME): details[VIRTUAL_HOST_NAME] = virtual_host.get(NAME) client.auth.logout(key) except xmlrpc.client.Fault as xml_error: raise SatelliteException(str(xml_error)) self.record_inspect_result(host_name, details) logger.debug('host_id=%s, host_details=%s', host_id, details) return details