def generate_ifc_delta_cfg(ifc_cfg_dict, asa_clis, device=None, interfaces=None): '''Compare ifc configuration with asa configuration , and produce ifc configuration delta. @param asa_clis: list input/out list of CLI's read from ASA device @param ifc_cfg_dict: dict the configuration of ASA in IFC dictionary format. It will be modified after the comparison. @param device: dict to identify the ASA device, passed in from device_script APIs @param interfaces: list physical interfaces names passed in from device_script APIs @return dict a copy of ifc_cfg_dct but with the state of each entry set to indicate if a modification operation or create operation is required. ''' asa = DeviceModel(device, interfaces) def create_missing_ifc_delta(ifc_cfg): 'Transformer to fill in the missing folders. This is important for configuration deletion' asa.populate_model(ifc_cfg.keys()[0], ifc_cfg.values()[0]) 'The following call will modify ifc_cfg' asa.create_missing_ifc_delta_cfg() return ifc_cfg def set_cfg_state_2_CREATE(ifc_cfg): 'Transformer to set the State of each entry to CREATE, the default state of all entries' set_cfg_state(ifc_cfg, State.CREATE) return ifc_cfg 'ifc_cfg is a copy of ifc_cfg_dict suited for us.' ifc_cfg = massage_param_dict( asa, ifc_cfg_dict, transformers=[set_cfg_state_2_CREATE, create_missing_ifc_delta]) '''Since the input dictionary is in arbitrary order, we use two-pass approach to make sure resulting CLI list is in the right order given in the device model. ''' for cli in asa_clis: translator = asa.get_translator(cli) if translator: translator.diff_ifc_asa(cli) return ifc_cfg
def generate_ifc_delta_cfg(ifc_cfg_dict, asa_clis, device = None, interfaces = None): '''Compare ifc configuration with asa configuration , and produce ifc configuration delta. @param asa_clis: list input/out list of CLI's read from ASA device @param ifc_cfg_dict: dict the configuration of ASA in IFC dictionary format. It will be modified after the comparison. @param device: dict to identify the ASA device, passed in from device_script APIs @param interfaces: list physical interfaces names passed in from device_script APIs @return dict a copy of ifc_cfg_dct but with the state of each entry set to indicate if a modification operation or create operation is required. ''' asa = DeviceModel(device, interfaces) def create_missing_ifc_delta(ifc_cfg): 'Transformer to fill in the missing folders. This is important for configuration deletion' asa.populate_model(ifc_cfg.keys()[0], ifc_cfg.values()[0]) 'The following call will modify ifc_cfg' asa.create_missing_ifc_delta_cfg() return ifc_cfg def set_cfg_state_2_CREATE(ifc_cfg): 'Transformer to set the State of each entry to CREATE, the default state of all entries' set_cfg_state(ifc_cfg, State.CREATE) return ifc_cfg 'ifc_cfg is a copy of ifc_cfg_dict suited for us.' ifc_cfg = massage_param_dict(asa, ifc_cfg_dict, transformers=[set_cfg_state_2_CREATE, create_missing_ifc_delta]) '''Since the input dictionary is in arbitrary order, we use two-pass approach to make sure resulting CLI list is in the right order given in the device model. ''' for cli in asa_clis: translator = asa.get_translator(cli) if translator: translator.diff_ifc_asa(cli) return ifc_cfg
def ifc2asa(ifc_delta_cfg_dict, device = None, interfaces = None, sts = None, include_shared_config = True): '''Generate ASA delta configuration from configuration in IFC delta dictionary form. @param ifc_delta_cfg_dict: dict for serviceModiy, it is the form configuration = { (device) : { # Device Shared configuration (folders): { (folders): { (params): ... }, (params): ... } (functionGroup Config): { (connectors): (folders): { (folders): { (params): ... }, (params): ... } (function) : { (folders): { (folders): { (params): ... }, (params): ... } } } } for deviceModify, it is of the form configuration = { (folders): { (folders): { (params): ... }, (params): ... } } Configuration Dictionary Format: (Type, Key, Instance) : {'state': State, 'device': Device, 'connector': Connector, 'value': Value} # # Type of attribute # Type = Insieme.Fwk.Enum( DEV=0, GRP=1, CONN=2, FUNC=3, FOLDER=4, PARAM=5 ) # # State of the attribute # State = Insieme.Fwk.Enum( NOCHANGE=0, CREATE=1, MODIFY=2, DESTROY=3 Key: the key of the configuration element given in the device specification file Instance: the instance identifier of a configuration object, such the name of an ACL Connector: the connector name Device: the device name, such as the case in a HA configuration situation. @param device: dict to identify the ASA device, passed in from device_script APIs @param interfaces: dict The format is similar to configuration parameter. Interfaces = { (cifType, '', <interface name>) : { 'state': <state>, 'label': <label> }, ... } Example: { (11, '', 'Gig0_1'): { 'state': 1, 'label': 'external' }, (11,'', 'Gig0_2'): { 'state': 1, 'label': 'internal' }, (11, '', 'Gig0_3'): { 'state': 1, 'label': 'mgmt', }, (11, '', 'Gig0_4'): { 'state': 1. 'label': 'cluster' } } @param sts: dict to identify the STS external and internal tag @param include_shared_config: boolean Flag to indicate if the function configuration should be modified. @return list of CLI's ''' asa = DeviceModel(device, interfaces, include_shared_config) 'ifc_cfg is a copy of ifc_delta_cfg_dict suited for us.' ifc_cfg = massage_param_dict(asa, ifc_delta_cfg_dict) '''Since the input dictionary is in arbitrary order, we use two-pass approach to make sure resulting CLI list is in the right order given in the device model. ''' #1st pass asa.populate_model(ifc_cfg.keys()[0], ifc_cfg.values()[0]) faults = asa.validate_configuration() if faults: raise IFCConfigError(faults) #2nd pass cli_list = [] no_cli_stack = [] asa.ifc2asa(no_cli_stack, cli_list) #gather result from positive and negative forms for the CLIs result = no_cli_stack result.reverse() #last in first out for the 'no' CLIs result.extend(cli_list) format_cli(result) #update sts table if asa.sts_table: sts.sts_table = asa.sts_table return result
'state': 1}, (Type.CONN, 'internal', 'C4'): { 'transaction': 10000, 'value': {}, 'state': 1}}, 'state': 1}}, 'state': 1}}}} asa = DeviceModel() def create_missing_ifc_delta(ifc_cfg): 'Transformer to fill in the missing folders' asa.populate_model(ifc_cfg.keys()[0], ifc_cfg.values()[0]) asa.create_missing_ifc_delta_cfg() return ifc_cfg def set_cfg_state_2_DESTROY(ifc_cfg): 'Transformer to set the State of each entry to DETROY' set_cfg_state(ifc_cfg, State.DESTROY) return ifc_cfg ifc_cfg = massage_param_dict(asa, config, transformers=[set_cfg_state_2_DESTROY, create_missing_ifc_delta]) from utils.util import pretty_dict print pretty_dict(ifc_cfg) # print("Test functional configuration with Timeouts: %s" % [str(x) for x in clis])
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
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
def ifc2asa(ifc_delta_cfg_dict, device=None, interfaces=None, sts=None, include_shared_config=True): '''Generate ASA delta configuration from configuration in IFC delta dictionary form. @param ifc_delta_cfg_dict: dict for serviceModiy, it is the form configuration = { (device) : { # Device Shared configuration (folders): { (folders): { (params): ... }, (params): ... } (functionGroup Config): { (connectors): (folders): { (folders): { (params): ... }, (params): ... } (function) : { (folders): { (folders): { (params): ... }, (params): ... } } } } for deviceModify, it is of the form configuration = { (folders): { (folders): { (params): ... }, (params): ... } } Configuration Dictionary Format: (Type, Key, Instance) : {'state': State, 'device': Device, 'connector': Connector, 'value': Value} # # Type of attribute # Type = Insieme.Fwk.Enum( DEV=0, GRP=1, CONN=2, FUNC=3, FOLDER=4, PARAM=5 ) # # State of the attribute # State = Insieme.Fwk.Enum( NOCHANGE=0, CREATE=1, MODIFY=2, DESTROY=3 Key: the key of the configuration element given in the device specification file Instance: the instance identifier of a configuration object, such the name of an ACL Connector: the connector name Device: the device name, such as the case in a HA configuration situation. @param device: dict to identify the ASA device, passed in from device_script APIs @param interfaces: dict The format is similar to configuration parameter. Interfaces = { (cifType, '', <interface name>) : { 'state': <state>, 'label': <label> }, ... } Example: { (11, '', 'Gig0_1'): { 'state': 1, 'label': 'external' }, (11,'', 'Gig0_2'): { 'state': 1, 'label': 'internal' }, (11, '', 'Gig0_3'): { 'state': 1, 'label': 'mgmt', }, (11, '', 'Gig0_4'): { 'state': 1. 'label': 'cluster' } } @param sts: dict to identify the STS external and internal tag @param include_shared_config: boolean Flag to indicate if the function configuration should be modified. @return list of CLI's ''' asa = DeviceModel(device, interfaces, include_shared_config) 'ifc_cfg is a copy of ifc_delta_cfg_dict suited for us.' ifc_cfg = massage_param_dict(asa, ifc_delta_cfg_dict) '''Since the input dictionary is in arbitrary order, we use two-pass approach to make sure resulting CLI list is in the right order given in the device model. ''' #1st pass asa.populate_model(ifc_cfg.keys()[0], ifc_cfg.values()[0]) faults = asa.validate_configuration() if faults: raise IFCConfigError(faults) #2nd pass cli_list = [] no_cli_stack = [] asa.ifc2asa(no_cli_stack, cli_list) #gather result from positive and negative forms for the CLIs result = no_cli_stack result.reverse() #last in first out for the 'no' CLIs result.extend(cli_list) format_cli(result) #update sts table if asa.sts_table: sts.sts_table = asa.sts_table return result
'state': 1 } }, 'state': 1 } } } } asa = DeviceModel() def create_missing_ifc_delta(ifc_cfg): 'Transformer to fill in the missing folders' asa.populate_model(ifc_cfg.keys()[0], ifc_cfg.values()[0]) asa.create_missing_ifc_delta_cfg() return ifc_cfg def set_cfg_state_2_DESTROY(ifc_cfg): 'Transformer to set the State of each entry to DETROY' set_cfg_state(ifc_cfg, State.DESTROY) return ifc_cfg ifc_cfg = massage_param_dict( asa, config, transformers=[set_cfg_state_2_DESTROY, create_missing_ifc_delta]) from utils.util import pretty_dict print pretty_dict(ifc_cfg) # print("Test functional configuration with Timeouts: %s" % [str(x) for x in clis])