def applyChanges(aclName, apiEndpoints, aclRules): """ Given the switch mapping and a list of the new ACL rules, apply the ACL to each switch """ cmdList = [ "enable", "configure", # Not the most efficient way to clear an ACL: "no ip access-list %s" % aclName, # Now enter configuration mode for the ACL: "ip access-list %s" % aclName ] cmdList = cmdList + aclRules + ["exit"] for hostname, apiEndpoint in apiEndpoints.iteritems(): print "Updating access list on switch", hostname, "....", try: apiEndpoint.runCmds(1, cmdList) except jsonrpclib.ProtocolError as e: print "[ERROR]" print " ", e # jsonrpclib isn't very friendly at getting the error data as # specified by the spec. This is a shortcut for getting the # last error: errorResponse = jsonrpclib.loads(jsonrpclib.history.response) print " Details:", errorResponse["error"]["data"][-1]["errors"] else: print "[SUCCESS]"
def _marshaled_dispatch(self, data, dispatch_method=None): response = None try: request = jsonrpclib.loads(data) except Exception as e: fault = Fault(-32700, 'Request %s invalid. (%s)' % (data, e)) response = fault.response() return response if not request: fault = Fault(-32600, 'Request invalid -- no request data.') return fault.response() if isinstance(request, list): # This SHOULD be a batch, by spec responses = [] for req_entry in request: result = validate_request(req_entry) if type(result) is Fault: responses.append(result.response()) continue resp_entry = self._marshaled_single_dispatch(req_entry) if resp_entry is not None: responses.append(resp_entry) if len(responses) > 0: response = '[%s]' % ','.join(responses) else: response = '' else: result = validate_request(request) if type(result) is Fault: return result.response() response = self._marshaled_single_dispatch(request) return response
def test_valid_two_requestz(self): request = '{ "jsonrpc": "2.0", "id": "123456", "method": "ping" }' json = loads(request) self.assertTrue(validate_request(json)) request = '{ "jsonrpc": "2.0", "method": "ping" }' json = loads(request) self.assertTrue(validate_request(json)) request = '{ "id": 123, "method": "ping" }' json = loads(request) self.assertTrue(validate_request(json)) request = '{ "id": 123, "method": "ping", "params": "foo" }' json = loads(request) self.assertTrue(validate_request(json)) request = '{ "id": 123, "method": "ping", "params": { "x": 5 } }' json = loads(request) self.assertTrue(validate_request(json))
def _marshaled_dispatch(self, data, dispatch_method=None): """Convert the data to a JSON RPC method request and dispatch it.""" try: request = jsonrpclib.loads(data) except Exception as e: fault = Fault(-32700, "Request %s invalid. (%s)" % (data, e)) response = fault.response() return response if not request: fault = Fault(-32600, "Request invalid -- no request data.") return fault.response() if isinstance(request, types.ListType): # batch of requests responses = [] for req_entry in request: result = validate_request(req_entry) if type(result) is Fault: responses.append(result.response()) continue resp_entry = self._marshaled_single_dispatch(req_entry) if resp_entry is not None: responses.append(resp_entry) if len(responses) > 0: response = "[%s]" % ",".join(responses) else: response = "" else: # single request result = validate_request(request) if type(result) is Fault: return result.response() response = self._marshaled_single_dispatch(request) return response
def post(self, *args, **kwargs): """ JSON-RPC 2.0 Request Object: {u'jsonrpc': u'2.0', u'params': [1, 2], u'id': u'3ebm619c', u'method': u'add'} Response Object: {"jsonrpc": "2.0", "result": 3, "id": "3ebm619c"} """ import jsonrpclib try: json_request = jsonrpclib.loads(self.request.body) params = json_request.get("params", []) method_name = json_request.get("method", "") except: # Bad request formatting, bad. raise Exception('Deal with how you want.') if method_name in dir(RequestHandler): # Pre-existing, not an implemented attribute raise AttributeError('%s is not implemented.' % method_name) try: method = getattr(self, method_name) except: # Attribute doesn't exist raise AttributeError('%s is not a valid method.' % method_name) if not callable(method): # Not callable, so not a method raise Exception('Attribute %s is not a method.' % method_name) if method_name.startswith('_') or \ ('private' in dir(method) and method.private is True): # No, no. That's private. raise Exception('Private function %s called.' % method_name) response = method(*params) response_json = jsonrpclib.dumps(response, methodresponse=True, rpcid=json_request["id"]) self.set_header("Content-Type", "text/json") self.write(response_json)
def _marshaled_dispatch(self, data, dispatch_method=None): """ Parses the request data (marshaled), calls method(s) and returns a JSON string (marshaled) :param data: A JSON request string :param dispatch_method: Custom dispatch method (for method resolution) :return: A JSON-RPC response string (marshaled) """ # Parse the request try: request = jsonrpclib.loads(data, self.json_config) except Exception as ex: # Parsing/loading error fault = Fault(-32700, 'Request {0} invalid. ({1}:{2})' \ .format(data, type(ex).__name__, ex), config=self.json_config) return fault.response() # Get the response dictionary try: response = self._unmarshaled_dispatch(request, dispatch_method) if response is not None: # Compute the string representation of the dictionary/list return jsonrpclib.jdumps(response, self.encoding) else: # No result (notification) return '' except NoMulticallResult: # Return an empty string (jsonrpclib internal behaviour) return ''
def get_method_name(request_body): try: data = jsonrpclib.loads(request_body) if not data or "method" not in data: return "" return data["method"] except ValueError: return ""
def test_invalid_request(self): # version is wrong request = '{ "jsonrpc": "3.0", "id": "123456", "method": "ping" }' json = loads(request) self.assertIsInstance(validate_request(json), Fault) request = '{ "jsonrpc": 2.0, "id": "123456", "method": "ping" }' json = loads(request) # no id nor jsonrpc self.assertIsInstance(validate_request(json), Fault) request = '{ "method": "ping" }' json = loads(request) self.assertIsInstance(validate_request(json), Fault) # no id nor jsonrpc self.assertIsInstance(validate_request(json), Fault) request = '{ "jsonrpc": "3.0", "id": "123456", "foo": 42 }' json = loads(request) self.assertIsInstance(validate_request(json), Fault)
def _marshaled_dispatch(self, session_id, data, dispatch_method=None): response = None try: request = jsonrpclib.loads(data) except Exception, e: fault = Fault(-32700, 'Request %s invalid. (%s)' % (data, e)) response = fault.response() return response
def _marshaled_dispatch(self, data, client_ip=None): response = None try: request = jsonrpclib.loads(data) if not request.has_key('params'): request['params'] = {} request['params']['client_ip'] = client_ip except Exception, e: fault = Fault(-32700, 'Request %s invalid. (%s)' % (data, e)) response = fault.response() return response
def _marshaled_dispatch(self, data, client_ip=None): response = None try: request = jsonrpclib.loads(data) if not request.has_key("params"): request["params"] = {} request["params"]["client_ip"] = client_ip except Exception, e: fault = Fault(-32700, "Request %s invalid. (%s)" % (data, e)) response = fault.response() return response
def provider(request): if request.uri == '/abc': headers = [("Content-Type", "application/json; charset=utf-8")] content = {"name": "Tomas", "surname": "Hanacek"} return Response(json.dumps(content), headers, 200) if request.uri == '/bugzilla': headers = [("Content-Type", request.headers["Content-Type"]+"; charset=utf-8")] method_name = '' if request.headers["Content-Type"].find('application/jsonrpc')>=0: data = jsonrpclib.loads(request.body) method_name = data["method"] elif request.headers["Content-Type"].find('text/xml')>=0: method_name = xmlrpclib.loads(request.body)[1] responseData = CustomResponse.callMethod(request.body,method_name) return Response(responseData, headers, 200)
def run_cmds(eapi, commands, format="json"): '''Log message to stdout and logging file Args: eapi: api connection to switch commands: commands to run format: format of response from switch, default is json Returns: None ''' log("Running command: %s" % commands) try: result = eapi.runCmds(1, commands, format) except ProtocolError: errorResponse = loads(history.response) log("Failed to run cmd:%s. %s" % (commands, errorResponse["error"]["data"][0]["errors"][-1])) sys.exit(1) return result
def provider(request): if request.uri == '/abc': headers = [("Content-Type", "application/json; charset=utf-8")] content = {"name": "Tomas", "surname": "Hanacek"} return Response(json.dumps(content), headers, 200) if request.uri == '/bugzilla': headers = [("Content-Type", request.headers["Content-Type"] + "; charset=utf-8")] method_name = '' if request.headers["Content-Type"].find('application/jsonrpc') >= 0: data = jsonrpclib.loads(request.body) method_name = data["method"] elif request.headers["Content-Type"].find('text/xml') >= 0: method_name = xmlrpclib.loads(request.body)[1] responseData = CustomResponse.callMethod(request.body, method_name) return Response(responseData, headers, 200)
def _marshaled_dispatch(self, session_id, data, dispatch_method=None): response = None try: request = jsonrpclib.loads(data) except Exception as e: fault = Fault(-32700, 'Request %s invalid. (%s)' % (data, e)) response = fault.response() return response session = self.dispatcher.get_session_by_address(session_id) if not session: return 'Error: session not found' session.time = time.time() responses = [] if not isinstance(request, types.ListType): request = [request] for req_entry in request: result = validate_request(req_entry) if type(result) is Fault: responses.append(result.response()) continue self.dispatcher.do_dispatch(session, req_entry) if req_entry['method'] == 'server.stop': return json.dumps({'result': 'ok'}) r = self.poll_session(session) for item in r: responses.append(json.dumps(item)) if len(responses) > 1: response = '[%s]' % ','.join(responses) elif len(responses) == 1: response = responses[0] else: response = '' return response
def _marshaled_dispatch(self, data, dispatch_method=None, path=None): """Dispatches an JSON-RPC method from marshalled (JSON) data. JSON-RPC methods are dispatched from the marshalled (JSON) data using the _dispatch method and the result is returned as marshalled data. For backwards compatibility, a dispatch function can be provided as an argument (see comment in SimpleJSONRPCRequestHandler.do_POST) but overriding the existing method through subclassing is the preferred means of changing method dispatch behavior. """ try: params, kwargs, method = jsonrpclib.loads(data) #print "method:", method # generate response if dispatch_method is not None: response = dispatch_method(method, params, kwargs) else: response = self._dispatch(method, params, kwargs) #print 333, response #sys.stdout.flush() if isinstance(response, self._type_function): return response # wrap response in a singleton tuple response = (response, ) response = jsonrpclib.dumps(response, None, methodresponse=1, allow_none=self.allow_none, encoding=self.encoding) except Fault, fault: response = jsonrpclib.dumps(fault, None, allow_none=self.allow_none, encoding=self.encoding)
def _marshaled_dispatch(self, data, dispatch_method = None): response = None try: request = jsonrpclib.loads(data) except: fault = Fault(-32600, 'Request %s invalid.' % data) response = fault.response() return response version = get_version(request) if not version: fault = Fault(-32600, 'Request %s invalid.' % data) response = fault.response() return response if type(request) is types.ListType: # This SHOULD be a batch, by spec responses = [] for req_entry in request: resp_entry = self._marshaled_single_dispatch(req_entry) if resp_entry is not None: responses.append(resp_entry) response = '[%s]' % ','.join(responses) else: response = self._marshaled_single_dispatch(request) return response
con_error = str("[Error:" + str(error_code) + "] No Route to Host(Switch powered off?)") elif error_code == errno.ECONNRESET: # Raise exception if connection is refset by the switch con_error = str("[Error:" + str(error_code) + "] Connection RST by peer (Restart eAPI)") elif error_code == 8: # Raise exception if switch hostname cannot be resolved in DNS con_error = str( "[Error:" + str(error_code) + "] Host/Server name not resolved (Check DNS or Host File)") else: # Unknown error - report error number and error string (should capture all) con_error = str("[Error:" + str(error_code) + "] " + error[1]) return con_error # Protcol errors - report error number and error string (catches command execution errors) except jsonrpclib.jsonrpc.ProtocolError: errorResponse = jsonrpclib.loads(jsonrpclib.history.response) prot_error = "[Protocol-Error:" + str( errorResponse["error"]["code"]) + "] " + str( errorResponse["error"]["message"]) return prot_error else: return response def parseArgs(): """Gathers comand line options for the script, generates help text and performs some error checking""" # Configure the option parser for CLI options to the script usage = "usage: %prog [options] userName password site" parser = argparse.ArgumentParser(description="LInk Ping Test") parser.add_argument( "--username", default=USER, help='Username to access switches'
# Socket Errors ErrorCode = ERR[0] if ErrorCode == errno.ECONNREFUSED: win.addstr(switchNumber, location -15, " [ Err " + str(ErrorCode) + ": No eAPI ] ") refresh() elif ErrorCode == errno.EHOSTUNREACH: # Never hit with lower socket timeout win.addstr(switchNumber, location -15, " [ Err " + str(ErrorCode) + ": Pwr off | Aboot ] ") refresh() elif ErrorCode == errno.ECONNRESET: win.addstr(switchNumber, location -15, " [ Err " + str(ErrorCode) + ": Con RST ] ") refresh() except jsonrpclib.ProtocolError: # Capture eAPI errors result = jsonrpclib.loads( jsonrpclib.history.response ) print result["error"]["message"] for error in result["error"]["data"][-1]["errors"]: print error except (xmlrpclib.ProtocolError, xmlrpclib.ResponseError), errormsg: # Capture XML Error (usually bad password) message = str(errormsg) message = message.replace(ScriptUser, "user") message = message.replace(ScriptPass, "pass") print message else: win.addstr(switchNumber, location, "[ Done ]") refresh()