예제 #1
0
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.'
                )
예제 #2
0
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
예제 #3
0
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.')