Ejemplo n.º 1
0
def query_asa(device, query_cmd):
    '''Read information back from the given device
    @param device: dict
        a device dictionary
    @param query: str, a show command cli, like "show run access-list bla"
    @return tuple with:
        1) response string from ASA; or None if cannot connect to the device
        2) any error or exception string, otherwise None
    @attention:  PLEASE do not use this API to make configuration change on the device
    '''
    if not device:
        error = "query_asa: fails to read response for command '%s'. Error: %s" % (query_cmd, 'empty device dictionary')
        env.debug(error)
        return (None, error)
    if not query_cmd.strip().startswith('show'):
        error = "query_asa: '%s' is not a show command, discarded" % query_cmd
        env.debug(error)
        return (None, error)
    try:
        dispatcher = HttpDispatch(device)
        messenger = dispatcher.make_shows_messenger([query_cmd])
        result =  messenger.read()
        if result == 'Command failed\n':
            return None, None
        if '\nERROR: %' in result:
            return None,None
        return result, None
    except Exception as e:
        env.debug("query_asa: fails to read response for command '%s'. Error: %s" % (query_cmd, e))
        return (None, str(e))
Ejemplo n.º 2
0
Archivo: util.py Proyecto: 3pings/aci
def query_asa(device, query_cmd):
    '''Read information back from the given device
    @param device: dict
        a device dictionary
    @param query: str, a show command cli, like "show run access-list bla"
    @return tuple with:
        1) response string from ASA; or None if cannot connect to the device
        2) any error or exception string, otherwise None
    @attention:  PLEASE do not use this API to make configuration change on the device
    '''
    if not device:
        error = "query_asa: fails to read response for command '%s'. Error: %s" % (
            query_cmd, 'empty device dictionary')
        env.debug(error)
        return (None, error)
    if not query_cmd.strip().startswith('show'):
        error = "query_asa: '%s' is not a show command, discarded" % query_cmd
        env.debug(error)
        return (None, error)
    try:
        dispatcher = HttpDispatch(device)
        messenger = dispatcher.make_shows_messenger([query_cmd])
        result = messenger.read()
        if result == 'Command failed\n':
            return None, None
        if '\nERROR: %' in result:
            return None, None
        return result, None
    except Exception as e:
        env.debug(
            "query_asa: fails to read response for command '%s'. Error: %s" %
            (query_cmd, e))
        return (None, str(e))
Ejemplo n.º 3
0
Archivo: util.py Proyecto: 3pings/aci
def deliver_sts_table(device, sts, is_audit):
    '''
    Send STS table to ASA device
    @param device: dict
        a device dictionary
    @param table; dict
        an STS dictionary
    @param is_audit: boolean
        True if this is an audit operation else False
    '''
    table = sts.sts_table
    if not deliver_clis.enabled:
        env.debug("[STS table would be delivered]\n\n")
        return True
    if not table:
        return True
    dispatcher = HttpDispatch(device)
    if is_audit:
        messenger = dispatcher.make_sts_audit_write_messenger(sts)
    else:
        messenger = dispatcher.make_sts_write_messenger(sts)
    results = messenger.get_results()
    if results:
        faults = []
        faults.append(('STS', 0, results))
        raise ASACommandError(faults)
Ejemplo n.º 4
0
def deliver_sts_table(device, sts, is_audit):
    '''
    Send STS table to ASA device
    @param device: dict
        a device dictionary
    @param table; dict
        an STS dictionary
    @param is_audit: boolean
        True if this is an audit operation else False
    '''
    table = sts.sts_table
    if not deliver_clis.enabled:
        env.debug("[STS table would be delivered]\n\n")
        return True
    if not table:
        return True
    dispatcher = HttpDispatch(device)
    if is_audit:
        messenger = dispatcher.make_sts_audit_write_messenger(sts)
    else:
        messenger = dispatcher.make_sts_write_messenger(sts)
    results = messenger.get_results()
    if results:
        faults = []
        faults.append(('STS', 0, results))
        raise ASACommandError(faults)
Ejemplo n.º 5
0
def read_clis(device, transformers=[convert_to_structured_commands, lambda x: x.split('\n')]):
    '''Read running-configuration from ASA device
    @param device: dict
        a device dictionary
    @param transformers: list of function that takes one argument and return an object
        the purpose of a transformer is to transform ASA configuration to a desired format.
        The order of the application of the transformer is the reverse given in the parameter,
        i.e. if the transformers is [a, b], the result will be a(b(config)).
    @return: list of CLI's
    '''
    dispatcher = HttpDispatch(device)
    messenger = dispatcher.make_read_config_messenger()
    result = messenger.read()
    if result and transformers:
        for transformer in reversed(transformers):
            result = transformer(result)
    return result
Ejemplo n.º 6
0
Archivo: util.py Proyecto: 3pings/aci
def query_sts_audit_table(device, sts):
    '''
    Query STS table from ASA device
    @param device: dict
        a device dictionary
    @param table; dict
        an STS dictionary
    '''
    table = sts.sts_table
    if not device:
        error = "query_sts_table: fails to read response for quering sts table"
        env.debug(error)
        return (None, error)
    dispatcher = HttpDispatch(device)
    messenger = dispatcher.make_sts_audit_read_messenger(sts)
    results = messenger.get_results()
    if results:
        faults = []
        faults.append(('STS', 0, results))
        raise ASACommandError(faults)
Ejemplo n.º 7
0
Archivo: util.py Proyecto: 3pings/aci
def read_clis(
        device,
        transformers=[convert_to_structured_commands,
                      lambda x: x.split('\n')]):
    '''Read running-configuration from ASA device
    @param device: dict
        a device dictionary
    @param transformers: list of function that takes one argument and return an object
        the purpose of a transformer is to transform ASA configuration to a desired format.
        The order of the application of the transformer is the reverse given in the parameter,
        i.e. if the transformers is [a, b], the result will be a(b(config)).
    @return: list of CLI's
    '''
    dispatcher = HttpDispatch(device)
    messenger = dispatcher.make_read_config_messenger()
    result = messenger.read()
    if result and transformers:
        for transformer in reversed(transformers):
            result = transformer(result)
    return result
Ejemplo n.º 8
0
def query_sts_audit_table(device, sts):
    '''
    Query STS table from ASA device
    @param device: dict
        a device dictionary
    @param table; dict
        an STS dictionary
    '''
    table = sts.sts_table
    if not device:
        error = "query_sts_table: fails to read response for quering sts table"
        env.debug(error)
        return (None, error)
    dispatcher = HttpDispatch(device)
    messenger = dispatcher.make_sts_audit_read_messenger(sts)
    results = messenger.get_results()
    if results:
        faults = []
        faults.append(('STS', 0, results))
        raise ASACommandError(faults)
Ejemplo n.º 9
0
Archivo: util.py Proyecto: 3pings/aci
def deliver_clis(device,
                 clis,
                 transformers=[filter_out_sacred_commands],
                 save_config=True):
    '''Deliver a list of CLI's to an ASA device
    @param device: dict
        a device dictionary
    @param clis: list of CLIIneraction's
    @param transformers: list of function that takes one argument and return an object
        the purpose of a transformer is to transform ASA configuration to a desired format
        before actually sending them down to the ASA device.
        The order of the application of the transformer is the reverse given in the parameter,
        i.e. if the transformers is [a, b], the result will be a(b(config)).
        a list of CLI objects.
    @param save_config: boolean
        indicate if the running-config should be saved to startup-config if the configuration
        is delivered successfully.
    @return: True if successful in delivery, or ASACommandError or ConnectionError exception will be raised.
    '''
    if not deliver_clis.enabled:
        env.debug("[CLIs would be delivered]\n%s\n" %
                  '\n'.join([str(cli) for cli in clis]))
        return True
    if not clis:
        return True

    if transformers:
        for transformer in reversed(transformers):
            clis = transformer(clis)
    dispatcher = HttpDispatch(device)

    def dispatch(clis):
        'deliver a list of CLIInteraction, and return list errors if any'
        messenger = dispatcher.make_command_messenger(clis)
        results = messenger.get_results()
        errs = filter(
            lambda x: x != None and x.err_msg != None and len(x.err_msg.strip(
            )) > 0, results)
        return errs

    errs = dispatch(clis)
    if not errs:

        def is_cluster_config(clis):
            return any(str(cli).find('cluster group') >= 0 for cli in clis)

        if save_config and not is_cluster_config(clis):
            # 'wr mem' will fail during cluster setup so bypass now. Defer till cluster state is stable.
            write_mem = CLIInteraction("write mem",
                                       response_parser=lambda response: None
                                       if '[OK]' in response else response)
            errs = dispatch([write_mem])
            if not errs:
                return True
        else:
            return True

    faults = []
    for err in errs:
        faults.append((err.model_key, 0, err.err_msg))
    raise ASACommandError(faults)
Ejemplo n.º 10
0
def serviceCounters(device, configuration):
    '''
    This function is called periodically to report statistics associated with
    the service functions rendered on the device.

    @param device:
        a device dictionary
    @param configuration: dict
        It contains device configuration, group configuration for a particular
        graph instance and function configuration. The configuration dictionary follows
        the format described above.
    @return: dict
            The format of the dictionary is as follows
            {
              'state': <state>
              'counters': [(path, counters), ...]
            }

            path: Identifies the object to which the counter is associated.
              The path is a list identifying a specific instance of a connector.
              It includes device name, group name, etc. as shown below:

              path = [ vdev, vgrp, vfunc, conn ]

              vdev - Device Name. Passed in the configuration dictionary
              vgrp - Function Group name passed in the configuration dictionary
              vfunc - function name passed in configuration dictionary
              conn - connector name within the function

            counters: {
              'rxpackets': <rxpackets>,
              'rxerrors': <rxerrors>,
              'rxdrops': <rxdrops>,
              'txpackets': <txpackets>,
              'txerrors': <txerrors>,
              'txdrops': <txdrops>
            }
    '''
    result = {'counters': []}

    asa = DeviceModel()
    ifc_cfg = massage_param_dict(asa, configuration)
    asa.populate_model(ifc_cfg.keys()[0], ifc_cfg.values()[0])

    connectors = get_all_connectors(asa)
    if connectors:
        cli_holder = []
        for connector in connectors:
            cli_holder.append(
                CLIInteraction('show interface ' + connector.get_nameif()))
        dispatcher = HttpDispatch(device)
        try:
            messenger = dispatcher.make_command_messenger(cli_holder)
            cli_results = messenger.get_results()
        except HTTPError as e:
            env.debug('serviceCounters: %s' % e)
            result['state'] = Status.TRANSIENT
            return result

        result['state'] = Status.SUCCESS
        for connector, cli_result in zip(connectors, cli_results):
            path = connector.get_config_path()
            counters = parse_connector_counters(cli_result.err_msg)
            result['counters'].append((path, counters))
    else:
        # Check if there is connectivity to the device
        version = read_asa_version(device)[0]
        result['state'] = Status.SUCCESS if version else Status.TRANSIENT

    return result
Ejemplo n.º 11
0
def deviceCounters(device, interfaces, configuration):
    '''
    This function is called periodically to report statistics associated with
    the physical interfaces of the device.

    @param device:
        a device dictionary
    @param interfaces:
        A list of the physical interfaces
        The format is:
            {
                (cifType, '', <interface name>) : {
                    'state': <state>,
                    'label': <label>
                },
                ...
            }
    @param configuration: dict
        It contains device configuration. The configuration dictionary follows
        the format described above.
    @return: dict
            The format of the dictionary is as follows
            {
              'state': <state>
              'counters': [(path, counters), ...]
            }

            path: Identifies the object to which the counter is associated.

            counters: {
              'rxpackets': <rxpackets>,
              'rxerrors': <rxerrors>,
              'rxdrops': <rxdrops>,
              'txpackets': <txpackets>,
              'txerrors': <txerrors>,
              'txdrops': <txdrops>
            }
    '''
    env.debug("[Interfaces argument]\n%s" % pretty_dict(interfaces))

    result = {'counters': []}
    if interfaces:
        cli_holder = []
        for interface in interfaces:
            cli_holder.append(
                CLIInteraction('show interface ' +
                               interface[2].replace('_', '/')))
        dispatcher = HttpDispatch(device)
        try:
            messenger = dispatcher.make_command_messenger(cli_holder)
            cli_results = messenger.get_results()
        except HTTPError as e:
            env.debug('deviceCounters: %s' % e)
            result['state'] = Status.TRANSIENT
            return result

        result['state'] = Status.SUCCESS
        for interface, cli_result in zip(interfaces, cli_results):
            if cli_result and cli_result.err_type == CLIResult.INFO:
                path = [(Type.CIF, '', interface[2])]
                counters = parse_interface_counters(cli_result.err_msg)
                result['counters'].append((path, counters))
    else:
        # Check if there is connectivity to the device
        version = read_asa_version(device)[0]
        result['state'] = Status.SUCCESS if version else Status.TRANSIENT

    return result
Ejemplo n.º 12
0
def serviceCounters(device,
                    configuration):
    '''
    This function is called periodically to report statistics associated with
    the service functions rendered on the device.

    @param device:
        a device dictionary
    @param configuration: dict
        It contains device configuration, group configuration for a particular
        graph instance and function configuration. The configuration dictionary follows
        the format described above.
    @return: dict
            The format of the dictionary is as follows
            {
              'state': <state>
              'counters': [(path, counters), ...]
            }

            path: Identifies the object to which the counter is associated.
              The path is a list identifying a specific instance of a connector.
              It includes device name, group name, etc. as shown below:

              path = [ vdev, vgrp, vfunc, conn ]

              vdev - Device Name. Passed in the configuration dictionary
              vgrp - Function Group name passed in the configuration dictionary
              vfunc - function name passed in configuration dictionary
              conn - connector name within the function

            counters: {
              'rxpackets': <rxpackets>,
              'rxerrors': <rxerrors>,
              'rxdrops': <rxdrops>,
              'txpackets': <txpackets>,
              'txerrors': <txerrors>,
              'txdrops': <txdrops>
            }
    '''
    result = {'counters': []}

    asa = DeviceModel()
    ifc_cfg = massage_param_dict(asa, configuration)
    asa.populate_model(ifc_cfg.keys()[0], ifc_cfg.values()[0])

    connectors = get_all_connectors(asa)
    if connectors:
        cli_holder = []
        for connector in connectors:
            cli_holder.append(CLIInteraction('show interface '
                                             + connector.get_nameif()))
        dispatcher = HttpDispatch(device)
        try:
            messenger = dispatcher.make_command_messenger(cli_holder)
            cli_results = messenger.get_results()
        except HTTPError as e:
            env.debug('serviceCounters: %s' % e)
            result['state'] = Status.TRANSIENT
            return result

        result['state'] = Status.SUCCESS
        for connector, cli_result in zip(connectors, cli_results):
            path = connector.get_config_path()
            counters = parse_connector_counters(cli_result.err_msg)
            result['counters'].append((path, counters))
    else:
        # Check if there is connectivity to the device
        version = read_asa_version(device)[0]
        result['state'] = Status.SUCCESS if version else Status.TRANSIENT

    return result
Ejemplo n.º 13
0
def deviceCounters(device,
                   interfaces,
                   configuration):
    '''
    This function is called periodically to report statistics associated with
    the physical interfaces of the device.

    @param device:
        a device dictionary
    @param interfaces:
        A list of the physical interfaces
        The format is:
            {
                (cifType, '', <interface name>) : {
                    'state': <state>,
                    'label': <label>
                },
                ...
            }
    @param configuration: dict
        It contains device configuration. The configuration dictionary follows
        the format described above.
    @return: dict
            The format of the dictionary is as follows
            {
              'state': <state>
              'counters': [(path, counters), ...]
            }

            path: Identifies the object to which the counter is associated.

            counters: {
              'rxpackets': <rxpackets>,
              'rxerrors': <rxerrors>,
              'rxdrops': <rxdrops>,
              'txpackets': <txpackets>,
              'txerrors': <txerrors>,
              'txdrops': <txdrops>
            }
    '''
    env.debug("[Interfaces argument]\n%s" % pretty_dict(interfaces))

    result = {'counters': []}
    if interfaces:
        cli_holder = []
        for interface in interfaces:
            cli_holder.append(CLIInteraction('show interface ' +
                                             interface[2].replace('_', '/')))
        dispatcher = HttpDispatch(device)
        try:
            messenger = dispatcher.make_command_messenger(cli_holder)
            cli_results = messenger.get_results()
        except HTTPError as e:
            env.debug('deviceCounters: %s' % e)
            result['state'] = Status.TRANSIENT
            return result

        result['state'] = Status.SUCCESS
        for interface, cli_result in zip(interfaces, cli_results):
            if cli_result and cli_result.err_type == CLIResult.INFO:
                path = [(Type.CIF, '', interface[2])]
                counters = parse_interface_counters(cli_result.err_msg)
                result['counters'].append((path, counters))
    else:
        # Check if there is connectivity to the device
        version = read_asa_version(device)[0]
        result['state'] = Status.SUCCESS if version else Status.TRANSIENT

    return result