class Example(object): def __init__(self): self.client = CiscoGRPCClient('127.0.0.1', 57777, 10, 'vagrant', 'vagrant') def get(self): path = '{"Cisco-IOS-XR-ipv4-bgp-cfg:bgp": [null]}' result = self.client.getconfig(path) try: err, result = self.client.getconfig(path) if err: print err print json.dumps(json.loads(result)) except AbortionError: print( 'Unable to connect to local box, check your gRPC destination.' ) def replace(self): path = open('snips/bgp_start.json').read() try: response = self.client.replaceconfig(path) if response.errors: err = json.loads(response.errors) print err except AbortionError: print( 'Unable to connect to local box, check your gRPC destination.' ) def merge(self): path = open('snips/bgp_merge.json').read() try: response = self.client.mergeconfig(path) if response.errors: err = json.loads(response.errors) print err except AbortionError: print( 'Unable to connect to local box, check your gRPC destination.' ) def delete(self): path = open('snips/bgp_start.json').read() try: response = self.client.deleteconfig(path) if response.errors: err = json.loads(response.errors) print err except AbortionError: print( 'Unable to connect to local box, check your gRPC destination.' )
class RoutePolicy(object): """Class to manipulate route policy and bgp neighbors using openconfig """ def __init__(self, host, port, username, password): """This class creates a grpc client for the functions to use. :param host: The ip address for the device. :param port: The port for the device. :param user: Username for device login. :param password: Password for device login. :type host: str :type port: int :type password: str :type username: str """ self.client = CiscoGRPCClient(host, port, 10, username, password) def get_policies(self): """sends a gRPC request and returns openconfig json of policies :return: Json string of policies :rtype: json object """ path = '{"openconfig-routing-policy:routing-policy": [null]}' err, result = self.client.getconfig(path) if err: print err policies = json.loads(result, object_pairs_hook=OrderedDict) return policies def list_policies(self): """Prints a list policies names for a router """ bgp_policies = self.get_policies() policy_definitions = bgp_policies[ 'openconfig-routing-policy:routing-policy']['policy-definitions'][ 'policy-definition'] print '\nPolicy Names:\n' for policy in policy_definitions: print 'Name: %s' % policy['name'] def detail_policy(self, policy_name): """Prints the full json of a policy in Openconfig and returns it :param policy_name: Policy Name on the box (case sensative). :type policy_name: str :return: Json string of policy :rtype: str """ bgp_policies = self.get_policies() policy_definitions = bgp_policies[ 'openconfig-routing-policy:routing-policy']['policy-definitions'][ 'policy-definition'] for policy in policy_definitions: if policy_name == policy['name']: print json.dumps(policy, indent=4, separators=(',', ': ')) inner = json.dumps(policy) template = '{"openconfig-routing-policy:routing-policy": {"policy-definitions": {"policy-definition": [%s]}}}' % inner return json.dumps(json.loads(template, object_pairs_hook=OrderedDict), indent=4, separators=(',', ': ')) def get_neighbors(self): """sends a gRPC request and returns openconfig json of BGP :return: Json string of policies :rtype: json object """ path = '{"openconfig-bgp:bgp": [null]}' err, result = self.client.getconfig(path) if err: print err bgp = json.loads(result, object_pairs_hook=OrderedDict) return bgp def list_neighbors(self): """Prints a list bgp neighbors for a router """ bgp = self.get_neighbors() bgp_neighbors = bgp['openconfig-bgp:bgp']['neighbors']['neighbor'] print "\nNeighbor's\n" for neighbor in bgp_neighbors: print 'Neighbor: %s AS: %s' % (neighbor['neighbor-address'], neighbor['config']['peer-as']) def detail_neighbor(self, neighbor_address): """Prints the full json of a neighbor in Openconfig format :param policy_name: Neighbor Address on the box. :type policy_name: str """ bgp = self.get_neighbors() bgp_neighbors = bgp['openconfig-bgp:bgp']['neighbors']['neighbor'] for neighbor in bgp_neighbors: if neighbor_address == neighbor['neighbor-address']: print json.dumps(neighbor, indent=4, separators=(',', ': ')) inner = json.dumps(neighbor) template = '{"openconfig-bgp:bgp": {"neighbors": {"neighbor" : [%s]}}}' % inner return json.dumps(json.loads(template, object_pairs_hook=OrderedDict), indent=4, separators=(',', ': ')) def is_int(self, num): """Helper function to see if value is a integer. Used to figure if its an AS or Neighbor Address :param num: A number or str :type: int or str :rtype boolean """ try: int(num) return True except ValueError: return False def merge_config(self, config): """gRPC merge call to push config changes to Router :param config: yang structured config in json :type config: str :return error if applicable :rtype str """ try: response = self.client.mergeconfig(config) if response.errors: err = json.loads(response.errors) return json.dumps(err, indent=4, separators=(',', ': ')) except ValueError as err: return err def neighbor_policy(self, neighbor_address, policy, direction): """Function to update a neighbors or AS policy :param neighbor_address: neighbor address or AS for policy :param policy: name of policy to be applied :param direction: export-policy or import-policy :type neighbor_address: str or int :type policy: str :type direction: str :returns: Prints neighbors it is applied to, and new bgp neighbor config """ updated_neighbors = [] bgp = self.get_neighbors() bgp_neighbors = bgp['openconfig-bgp:bgp']['neighbors']['neighbor'] for neighbor in bgp_neighbors: if self.is_int(neighbor_address): val = neighbor['config']['peer-as'] else: val = neighbor['neighbor-address'] if val in neighbor_address: if len(policy) > 1 and isinstance(policy, list): policy = self.multiple_policies(policy, neighbor_address) # Change the policy to drop. ipvs = neighbor['afi-safis']['afi-safi'] for ipv in ipvs: curr_policy = ipv['apply-policy']['config'][direction] ipv['apply-policy']['config']['export-policy'] = policy ip_type = ipv['afi-safi-name'] # Add the removed neighbors to list. updated_neighbors.append( (neighbor['neighbor-address'], ip_type, curr_policy)) updated_neighbors = json.dumps(updated_neighbors) print updated_neighbors bgp_config = json.dumps(bgp) err = self.merge_config(bgp_config) if not err: print err print '\nNew Neighbor Detail:\n' self.detail_neighbor(neighbor_address) def multiple_policies(self, policies, neighbor): """Creates a new policy that applies list of policies to it. :param policies: list of policies that you want applied to a single policy :param neighbor: the neighbor you are going to apply these policies (used for naming) :type policies: list :type neighbor: str :return: Name of the policy that is created :rtype: str """ policy_name = neighbor.replace('.', '_') policy_name = 'multi_policy_' + policy_name shell = '{"openconfig-routing-policy:routing-policy": {"policy-definitions": {"policy-definition": [{"name": "%s","statements": {"statement": []}}]}}}' % policy_name shell = json.loads(shell, object_pairs_hook=OrderedDict) conditions = shell['openconfig-routing-policy:routing-policy'][ 'policy-definitions']['policy-definition'][0]['statements'][ 'statement'] for policy in policies: policy_nm = 'Policy_' + policy json_policy = '{"name": "%s", "conditions": {"call-policy": "%s"}}' % ( policy_nm, policy) json_policy = json.loads(json_policy, object_pairs_hook=OrderedDict) conditions.append(json_policy) multi_policy = json.dumps(shell) print self.merge_config(multi_policy) return policy_name
def main(): __version__ = 'GRPC_Client 1.0' arguments = docopt(__doc__, version=__version__) IP = arguments['<router_IP>'] TCP_PORT = int(arguments['<port>']) user = arguments['<user>'] password = arguments['<password>'] RPC = arguments['<rpc>'] client = CiscoGRPCClient(IP, TCP_PORT, 10, user, password) if RPC == "get-oper": if arguments['--file']: file = arguments['--file'] path = open(file).read() # path = open('json/' + file).read() else: path = 'Error' print( 'get-oper argument must include --file option and json file to filter yang operational namespace' ) try: err, result = client.getoper(path) if err: print err print result except AbortionError: print( 'Unable to connect to local box, check your gRPC destination.') if RPC == "get-config": if arguments['--file']: file = arguments['--file'] path = open(file).read() # path = open('json/' + file).read() else: path = "" try: err, result = client.getconfig(path) if err: print err print result except AbortionError: print( 'Unable to connect to local box, check your gRPC destination.') if RPC == "merge-config": if arguments['--file']: file = arguments['--file'] path = open(file).read() else: path = 'Error' print( 'get-oper argument must include --file option and json file to filter yang operational namespace' ) try: err = client.mergeconfig(path) if err: print err #print result except AbortionError: print( 'Unable to connect to local box, check your gRPC destination.') if RPC == "replace-config": if arguments['--file']: file = arguments['--file'] path = open(file).read() else: path = 'Error' print( 'get-oper argument must include --file option and json file to filter yang operational namespace' ) try: err = client.replaceconfig(path) if err: print err except AbortionError: print( 'Unable to connect to local box, check your gRPC destination.')