def check_odl_shutdown_state(node): """Check the status of ODL client shutdown. :param node: Honeycomb node. :type node: dict :returns: True when ODL is stopped. :rtype: bool :raises HoneycombError: When the response is not code 200: OK. """ cmd = "pgrep -f karaf" path = HcUtil.read_path_from_url_file( "odl_client/odl_netconf_connector") try: HTTPRequest.get(node, path, timeout=10, enable_logging=False) raise HoneycombError("ODL client is still running.") except HTTPRequestError: logger.debug("Connection refused, checking process state....") ssh = SSH() ssh.connect(node) ret_code, _, _ = ssh.exec_command(cmd) if ret_code == 0: raise HoneycombError("ODL client is still running.") return True
def check_odl_startup_state(node): """Check the status of ODL client startup. :param node: Honeycomb node. :param node: dict :returns: True when ODL is started. :rtype: bool :raises HoneycombError: When the response is not code 200: OK. """ path = HcUtil.read_path_from_url_file( "odl_client/odl_netconf_connector") expected_status_codes = (HTTPCodes.UNAUTHORIZED, HTTPCodes.FORBIDDEN, HTTPCodes.NOT_FOUND, HTTPCodes.SERVICE_UNAVAILABLE, HTTPCodes.INTERNAL_SERVER_ERROR) status_code, _ = HTTPRequest.get(node, path, timeout=10, enable_logging=False) if status_code == HTTPCodes.OK: logger.info("ODL client on node {0} is up and running".format( node['host'])) elif status_code in expected_status_codes: if status_code == HTTPCodes.UNAUTHORIZED: logger.info('Unauthorized. If this triggers keyword ' 'timeout, verify username and password.') raise HoneycombError('ODL client on node {0} running but ' 'not yet ready.'.format(node['host']), enable_logging=False) else: raise HoneycombError( 'Unexpected return code: {0}.'.format(status_code)) return True
def mount_honeycomb_on_odl(node): """Tell ODL client to mount Honeycomb instance over netconf. :param node: Honeycomb node. :type node: dict :raises HoneycombError: When the response is not code 200: OK. """ path = HcUtil.read_path_from_url_file( "odl_client/odl_netconf_connector") url_file = "{0}/{1}".format(Const.RESOURCES_TPL_HC, "odl_client/mount_honeycomb.xml") with open(url_file) as template: data = template.read() status_code, _ = HTTPRequest.post( node, path, headers={"Content-Type": "application/xml"}, payload=data, timeout=10, enable_logging=False) if status_code == HTTPCodes.OK: logger.info("ODL mount point configured successfully.") elif status_code == HTTPCodes.CONFLICT: logger.info("ODL mount point was already configured.") else: raise HoneycombError('Mount point configuration not successful')
def post_honeycomb_data(node, url_file, data=None, data_representation=DataRepresentation.JSON, timeout=10): """Send a POST request and return the status code and response content. :param node: Honeycomb node. :param url_file: URL file. The argument contains only the name of file without extension, not the full path. :param data: Configuration data to be sent to Honeycomb. :param data_representation: How the data is represented. :param timeout: How long to wait for the server to send data before giving up. :type node: dict :type url_file: str :type data: dict, str :type data_representation: DataRepresentation :type timeout: int :returns: Status code and content of response. :rtype: tuple :raises HoneycombError: If the given data representation is not defined in HEADERS. """ try: header = HEADERS[data_representation] except AttributeError as err: raise HoneycombError("Wrong data representation: {0}.". format(data_representation), repr(err)) if data_representation == DataRepresentation.JSON: data = dumps(data) path = HoneycombUtil.read_path_from_url_file(url_file) return HTTPRequest.post( node=node, path=path, headers=header, payload=data, timeout=timeout)
def get_honeycomb_data(node, url_file, path=""): """Retrieve data from Honeycomb according to given URL. :param node: Honeycomb node. :param url_file: URL file. The argument contains only the name of file without extension, not the full path. :param path: Path which is added to the base path to identify the data. :type node: dict :type url_file: str :type path: str :returns: Status code and content of response. :rtype: tuple """ base_path = HoneycombUtil.read_path_from_url_file(url_file) path = base_path + path status_code, resp = HTTPRequest.get(node, path) try: data = loads(resp) except ValueError: logger.debug("Failed to deserialize JSON data.") data = None return status_code, data
def check_honeycomb_startup_state(*nodes): """Check state of Honeycomb service during startup on specified nodes. Reads html path from template file oper_vpp_version.url. Honeycomb nodes reply with connection refused or the following status codes depending on startup progress: codes 200, 401, 403, 404, 500, 503 :param nodes: List of DUT nodes starting Honeycomb. :type nodes: list :return: True if all GETs returned code 200(OK). :rtype bool """ path = HcUtil.read_path_from_url_file("oper_vpp_version") expected_status_codes = (HTTPCodes.UNAUTHORIZED, HTTPCodes.FORBIDDEN, HTTPCodes.NOT_FOUND, HTTPCodes.SERVICE_UNAVAILABLE, HTTPCodes.INTERNAL_SERVER_ERROR) for node in nodes: if node['type'] == NodeType.DUT: HoneycombSetup.print_ports(node) try: status_code, _ = HTTPRequest.get(node, path, enable_logging=False) except HTTPRequestError: ssh = SSH() ssh.connect(node) ret_code, _, _ = ssh.exec_command_sudo( "tail -n 100 /var/log/syslog") if ret_code != 0: # It's probably Centos ssh.exec_command_sudo("tail -n 100 /var/log/messages") raise if status_code == HTTPCodes.OK: logger.info( "Honeycomb on node {0} is up and running".format( node['host'])) elif status_code in expected_status_codes: if status_code == HTTPCodes.UNAUTHORIZED: logger.info('Unauthorized. If this triggers keyword ' 'timeout, verify Honeycomb username and ' 'password.') raise HoneycombError('Honeycomb on node {0} running but ' 'not yet ready.'.format(node['host']), enable_logging=False) else: raise HoneycombError( 'Unexpected return code: {0}.'.format(status_code)) status_code, _ = HcUtil.get_honeycomb_data( node, "config_vpp_interfaces") if status_code != HTTPCodes.OK: raise HoneycombError('Honeycomb on node {0} running but ' 'not yet ready.'.format(node['host']), enable_logging=False) return True
def delete_honeycomb_data(node, url_file, path=""): """Delete data from Honeycomb according to given URL. :param node: Honeycomb node. :param url_file: URL file. The argument contains only the name of file without extension, not the full path. :param path: Path which is added to the base path to identify the data. :type node: dict :type url_file: str :type path: str :returns: Status code and content of response. :rtype tuple """ base_path = HoneycombUtil.read_path_from_url_file(url_file) path = base_path + path return HTTPRequest.delete(node, path)
def check_honeycomb_shutdown_state(*nodes): """Check state of Honeycomb service during shutdown on specified nodes. Honeycomb nodes reply with connection refused or the following status codes depending on shutdown progress: codes 200, 404. :param nodes: List of DUT nodes stopping Honeycomb. :type nodes: list :return: True if all GETs fail to connect. :rtype bool """ cmd = "ps -ef | grep -v grep | grep honeycomb" for node in nodes: if node['type'] == NodeType.DUT: try: status_code, _ = HTTPRequest.get(node, '/index.html', enable_logging=False) if status_code == HTTPCodes.OK: raise HoneycombError('Honeycomb on node {0} is still ' 'running.'.format(node['host']), enable_logging=False) elif status_code == HTTPCodes.NOT_FOUND: raise HoneycombError( 'Honeycomb on node {0} is shutting' ' down.'.format(node['host']), enable_logging=False) else: raise HoneycombError( 'Unexpected return code: {0}.'.format(status_code)) except HTTPRequestError: logger.debug('Connection refused, checking the process ' 'state ...') ssh = SSH() ssh.connect(node) (ret_code, _, _) = ssh.exec_command_sudo(cmd) if ret_code == 0: raise HoneycombError('Honeycomb on node {0} is still ' 'running.'.format(node['host']), enable_logging=False) else: logger.info("Honeycomb on node {0} has stopped".format( node['host'])) return True
def put_honeycomb_data(node, url_file, data, path="", data_representation=DataRepresentation.JSON): """Send configuration data using PUT request and return the status code and response content. :param node: Honeycomb node. :param url_file: URL file. The argument contains only the name of file without extension, not the full path. :param data: Configuration data to be sent to Honeycomb. :param path: Path which is added to the base path to identify the data. :param data_representation: How the data is represented. :type node: dict :type url_file: str :type data: dict, str :type path: str :type data_representation: DataRepresentation :returns: Status code and content of response. :rtype: tuple :raises HoneycombError: If the given data representation is not defined in HEADERS. """ try: header = HEADERS[data_representation] except AttributeError as err: raise HoneycombError( "Wrong data representation: {0}.".format(data_representation), repr(err)) if data_representation == DataRepresentation.JSON: data = dumps(data) logger.trace(data) base_path = HoneycombUtil.read_path_from_url_file(url_file) path = base_path + path logger.trace(path) return HTTPRequest.put(node=node, path=path, headers=header, payload=data)