def __init__(self, session, host, port=443): """Initialize Files object with session parameters. Args: session (obj): Requests Session object host (str): hostname or IP address of vManage port (int): default HTTPS 443 """ self.session = session self.host = host self.port = port self.base_url = f'https://{self.host}:{self.port}/dataservice/' self.device_templates = DeviceTemplates(self.session, self.host, self.port) self.feature_templates = FeatureTemplates(self.session, self.host, self.port) self.template_data = TemplateData(self.session, self.host, self.port) self.policy_data = PolicyData(self.session, self.host, self.port) self.policy_lists = PolicyLists(self.session, self.host, self.port) self.policy_definitions = PolicyDefinitions(self.session, self.host, self.port) self.local_policy = LocalPolicy(self.session, self.host, self.port) self.central_policy = CentralPolicy(self.session, self.host, self.port) self.vmanage_device = Device(self.session, self.host, self.port)
def run_module(): # define available arguments/parameters a user can pass to the module argument_spec = vmanage_argument_spec() argument_spec.update(factory_default=dict(type='bool', default=False), ) # seed the result dict in the object # we primarily care about changed and state # change is if this module effectively modified the target # state will include any data that you want your module to pass back # for consumption, for example, in a subsequent task result = dict( changed=False, original_message='', message='' ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True, ) vmanage = Vmanage(module) device_templates = DeviceTemplates(vmanage.auth, vmanage.host) vmanage.result['device_templates'] = device_templates.get_device_template_list(factory_default=vmanage.params['factory_default']) vmanage.exit_json(**vmanage.result)
def import_attachments_from_file(self, file, update=False, check_mode=False, name_list=None, template_type=None): vmanage_device_templates = DeviceTemplates(self.session, self.host, self.port) template_data = {} # Read in the datafile if not os.path.exists(file): raise Exception(f"Cannot find file {file}") with open(file) as f: if file.endswith('.yaml') or file.endswith('.yml'): template_data = yaml.safe_load(f) else: template_data = json.load(f) if 'vmanage_attachments' in template_data: imported_attachment_list = template_data['vmanage_attachments'] else: imported_attachment_list = [] # Process the device templates result = vmanage_device_templates.import_attachment_list( imported_attachment_list, check_mode=check_mode, update=update) return result
def import_policy_list_list(self, policy_list_list, push=False, update=False, check_mode=False, force=False): """Import a list of policyies lists into vManage. Object Names are translated to IDs. Args: policy_list_list: A list of polcies push (bool): Whether to push a change out update (bool): Whether to update when the list exists check_mode (bool): Report what updates would happen, but don't update Returns: result (dict): All data associated with a response. """ # Policy Lists diff = [] policy_list_updates = [] #pylint: disable=too-many-nested-blocks for policy_list in policy_list_list: policy_list_dict = self.policy_lists.get_policy_list_dict(policy_list['type'], remove_key=False, cache=False) if policy_list['name'] in policy_list_dict: existing_list = policy_list_dict[policy_list['name']] diff_ignore = set( ['listId', 'references', 'lastUpdated', 'activatedId', 'policyId', 'listId', 'isActivatedByVsmart']) diff = list(dictdiffer.diff(existing_list, policy_list, ignore=diff_ignore)) if diff: policy_list_updates.append({'name': policy_list['name'], 'diff': diff}) policy_list['listId'] = policy_list_dict[policy_list['name']]['listId'] # If description is not specified, try to get it from the existing information if not policy_list['description']: policy_list['description'] = policy_list_dict[policy_list['name']]['description'] if not check_mode and update: response = self.policy_lists.update_policy_list(policy_list) if response['json']: # Updating the policy list returns a `processId` that locks the list and 'masterTemplatesAffected' # that lists the templates affected by the change. if 'error' in response['json']: raise Exception(response['json']['error']['message']) elif 'processId' in response['json']: if push: vmanage_device_templates = DeviceTemplates(self.session, self.host) # If told to push out the change, we need to reattach each template affected by the change for template_id in response['json']['masterTemplatesAffected']: vmanage_device_templates.reattach_device_template(template_id) else: raise Exception("Did not get a process id when updating policy list") else: diff = list(dictdiffer.diff({}, policy_list)) policy_list_updates.append({'name': policy_list['name'], 'diff': diff}) if not check_mode: self.policy_lists.add_policy_list(policy_list) return policy_list_updates
def export_attachments_to_file(self, export_file, name_list=None, device_type=None): device_templates = DeviceTemplates(self.session, self.host, self.port) vmanage_device = Device(self.session, self.host, self.port) if name_list is None: name_list = [] device_template_dict = device_templates.get_device_template_dict() attachments_list = [] # Create a device config of the right type of things device_list = [] if device_type in (None, 'controllers'): device_list = vmanage_device.get_device_config_list('controllers') if device_type in (None, 'vedges'): edge_list = vmanage_device.get_device_config_list('vedges') device_list = device_list + edge_list for device_config in device_list: if 'configStatusMessage' in device_config and device_config['configStatusMessage'] != 'In Sync': continue if 'template' in device_config: if device_config['template'] in device_template_dict: template_id = device_template_dict[device_config['template']]['templateId'] else: raise Exception(f"Could not find ID for template {device_config['template']}") if name_list == [] or device_config['host-name'] in name_list: variable_dict = {} template_input = device_templates.get_template_input(template_id, device_id_list=[device_config['uuid']]) data = template_input['data'][0] for column in template_input['columns']: variable_dict[column['variable']] = data[column['property']] entry = { 'host_name': device_config['host-name'], 'device_type': device_config['deviceType'], 'uuid': device_config['chasisNumber'], 'system_ip': device_config['deviceIP'], 'site_id': device_config['site-id'], 'template': device_config['template'], 'variables': variable_dict } attachments_list.append(entry) attachment_export = {'vmanage_attachments': attachments_list} if export_file.endswith('.json'): with open(export_file, 'w') as outfile: json.dump(attachment_export, outfile, indent=4, sort_keys=False) elif export_file.endswith(('.yaml', 'yml')): with open(export_file, 'w') as outfile: yaml.dump(attachment_export, outfile, indent=4, sort_keys=False) else: raise Exception("File format not supported") return (len(attachments_list))
def import_feature_template_list(self, feature_template_list, push=False, check_mode=False, update=False): """Import a list of feature templates from list to vManage. Object Names are converted to IDs. Args: feature_template_list (list): List of feature templates check_mode (bool): Only check to see if changes would be made update (bool): Update the template if it exists Returns: result (list): Returns the diffs of the updates. """ # Process the feature templates feature_template_updates = [] feature_template_dict = self.feature_templates.get_feature_template_dict(factory_default=True, remove_key=False) #pylint: disable=too-many-nested-blocks for feature_template in feature_template_list: if 'templateId' in feature_template: feature_template.pop('templateId') if feature_template['templateName'] in feature_template_dict: existing_template = feature_template_dict[feature_template['templateName']] feature_template['templateId'] = existing_template['templateId'] diff = list( dictdiffer.diff(existing_template['templateDefinition'], feature_template['templateDefinition'])) if len(diff): feature_template_updates.append({'name': feature_template['templateName'], 'diff': diff}) if not check_mode and update: response = self.feature_templates.update_feature_template(feature_template) if response['json']: # Updating the policy list returns a `processId` that locks the list and 'masterTemplatesAffected' # that lists the templates affected by the change. if 'error' in response['json']: raise RuntimeError(response['json']['error']['message']) elif 'processId' in response['json']: if push: vmanage_device_templates = DeviceTemplates(self.session, self.host) # If told to push out the change, we need to reattach each template affected by the change vmanage_device_templates.reattach_multi_device_templates( response['json']['masterTemplatesAffected']) else: raise RuntimeError("Did not get a process id when updating policy list") else: diff = list(dictdiffer.diff({}, feature_template['templateDefinition'])) feature_template_updates.append({'name': feature_template['templateName'], 'diff': diff}) if not check_mode: self.feature_templates.add_feature_template(feature_template) return feature_template_updates
def export_templates_to_file(self, export_file, name_list=None, template_type=None): device_templates = DeviceTemplates(self.session, self.host, self.port) feature_templates = FeatureTemplates(self.session, self.host, self.port) template_export = {} #pylint: disable=too-many-nested-blocks if template_type != 'feature': # Export the device templates and associated feature templates device_template_list = device_templates.get_device_template_list( name_list=name_list) template_export.update( {'vmanage_device_templates': device_template_list}) feature_name_list = [] if name_list: for device_template in device_template_list: if 'generalTemplates' in device_template: for general_template in device_template[ 'generalTemplates']: if 'templateName' in general_template: feature_name_list.append( general_template['templateName']) if 'subTemplates' in general_template: for sub_template in general_template[ 'subTemplates']: if 'templateName' in sub_template: feature_name_list.append( sub_template['templateName']) name_list = list(set(feature_name_list)) # Since device templates depend on feature templates, we always add them. feature_templates = FeatureTemplates(self.session, self.host, self.port) feature_template_list = feature_templates.get_feature_template_list( name_list=name_list) template_export.update( {'vmanage_feature_templates': feature_template_list}) if export_file.endswith('.json'): with open(export_file, 'w') as outfile: json.dump(template_export, outfile, indent=4, sort_keys=False) elif export_file.endswith('.yaml') or export_file.endswith('.yml'): with open(export_file, 'w') as outfile: yaml.dump(template_export, outfile, indent=4, sort_keys=False) else: raise Exception("File format not supported")
def __init__(self, session, host, port=443): """Initialize Templates Method object with session parameters. Args: session (obj): Requests Session object host (str): hostname or IP address of vManage port (int): default HTTPS 443 """ self.session = session self.host = host self.port = port self.base_url = f'https://{self.host}:{self.port}/dataservice/' self.device_templates = DeviceTemplates(self.session, self.host, self.port) self.feature_templates = FeatureTemplates(self.session, self.host, self.port)
def __init__(self, session, host, port=443): """Initialize Reset vManage object with session parameters. Args: session (obj): Requests Session object host (str): hostname or IP address of vManage port (int): default HTTPS 443 """ self.session = session self.host = host self.port = port self.base_url = f'https://{self.host}:{self.port}/dataservice/' self.utilities = Utilities(self.session, self.host) self.cen_pol = CentralizedPolicy(self.session, self.host) self.inventory = DeviceInventory(self.session, self.host) self.dev_temps = DeviceTemplates(self.session, self.host) self.fet_temps = FeatureTemplates(self.session, self.host) self.loc_pol = LocalizedPolicy(self.session, self.host) self.sec_pol = SecurityPolicy(self.session, self.host) self.pol_lists = PolicyLists(self.session, self.host)
def run_module(): # define available arguments/parameters a user can pass to the module argument_spec = vmanage_argument_spec() argument_spec.update(state=dict(type='str', choices=['absent', 'present'], default='present'), name=dict(type='str', alias='templateName'), description=dict(type='str', alias='templateDescription'), templates=dict(type='str', alias='generalTemplates'), device_type=dict(type='list', alias='deviceType'), config_type=dict(type='list', alias='configType'), update=dict(type='bool', defaut=True), factory_default=dict(type='bool', alias='factoryDefault'), aggregate=dict(type='list'), push=dict(type='bool', default=False)) # seed the result dict in the object # we primarily care about changed and state # change is if this module effectively modified the target # state will include any data that you want your module to pass back # for consumption, for example, in a subsequent task result = dict(changed=False, ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True, ) vmanage = Vmanage(module) vmanage_device_templates = DeviceTemplates(vmanage.auth, vmanage.host) vmanage_template_data = TemplateData(vmanage.auth, vmanage.host) # Always as an aggregate... make a list if just given a single entry if vmanage.params['aggregate']: device_template_list = vmanage.params['aggregate'] else: if vmanage.params['state'] == 'present': device_template_list = [{ 'templateName': vmanage.params['name'], 'templateDescription': vmanage.params['description'], 'deviceType': vmanage.params['device_type'], 'configType': vmanage.params['config_type'], 'factoryDefault': vmanage.params['factory_default'], 'generalTemplates': vmanage.params['templates'], }] else: device_template_list = [{ 'templateName': vmanage.params['name'], 'state': 'absent' }] device_template_updates = [] if vmanage.params['state'] == 'present': device_template_updates = vmanage_template_data.import_device_template_list( device_template_list, check_mode=module.check_mode, update=vmanage.params['update'], push=vmanage.params['push']) if device_template_updates: vmanage.result['changed'] = True else: device_template_dict = vmanage_device_templates.get_device_template_dict( factory_default=True, remove_key=False) for device_template in device_template_list: if device_template['templateName'] in device_template_dict: if not module.check_mode: vmanage_device_templates.delete_device_template( device_template_dict[ device_template['templateName']]['templateId']) vmanage.result['changed'] = True vmanage.result['updates'] = device_template_updates vmanage.exit_json(**vmanage.result)
class ResetVmanage(object): """Reset all configuratios on a vManage instance. Executes the necessary REST calls in specific order to remove configurations applied to a vManage instance. """ def __init__(self, session, host, port=443): """Initialize Reset vManage object with session parameters. Args: session (obj): Requests Session object host (str): hostname or IP address of vManage port (int): default HTTPS 443 """ self.session = session self.host = host self.port = port self.base_url = f'https://{self.host}:{self.port}/dataservice/' self.utilities = Utilities(self.session, self.host) self.cen_pol = CentralizedPolicy(self.session, self.host) self.inventory = DeviceInventory(self.session, self.host) self.dev_temps = DeviceTemplates(self.session, self.host) self.fet_temps = FeatureTemplates(self.session, self.host) self.loc_pol = LocalizedPolicy(self.session, self.host) self.sec_pol = SecurityPolicy(self.session, self.host) self.pol_lists = PolicyLists(self.session, self.host) def active_count_delay(self): activeCount = 1 while activeCount != 0: time.sleep(1.0) data = self.utilities.get_active_count() activeCount = data["activeTaskCount"] def execute(self): # Step 1 - Deactivate Centralized Policy data = self.cen_pol.get_centralized_policy() for policy in data: if policy['isPolicyActivated']: policyId = policy['policyId'] self.cen_pol.deactivate_centralized_policy(policyId) self.active_count_delay() # Step 2 - Detach vedges from template data = self.inventory.get_device_list('vedges') for device in data: if (('deviceIP' in device) and (device['configOperationMode'] == 'vmanage')): deviceId = device['uuid'] deviceIP = device['deviceIP'] deviceType = device['deviceType'] self.inventory.post_device_cli_mode(deviceId, deviceIP, deviceType) self.active_count_delay() # Step 3 - Detach controllers from template data = self.inventory.get_device_list('controllers') for device in data: if (('deviceIP' in device) and (device['configOperationMode'] == 'vmanage')): deviceId = device['uuid'] deviceIP = device['deviceIP'] deviceType = device['deviceType'] self.inventory.post_device_cli_mode(deviceId, deviceIP, deviceType) # Requires pause between controllers self.active_count_delay() self.active_count_delay() # Step 4 - Delete All Device Templates data = self.dev_temps.get_device_templates() for device in data: templateId = device['templateId'] self.dev_temps.delete_device_template(templateId) self.active_count_delay() # Step 5 - Delete All Feature Templates data = self.fet_temps.get_feature_templates() for device in data: #pylint: disable=no-else-continue if device['factoryDefault']: continue else: templateId = device['templateId'] self.fet_temps.delete_feature_template(templateId) self.active_count_delay() # Step 6 - Delete All Centralized Policies data = self.cen_pol.get_centralized_policy() for policy in data: policyId = policy['policyId'] self.cen_pol.delete_centralized_policy(policyId) self.active_count_delay() # Step 7 - Delete All Topology, Traffic, Cflowd Policies definitionList = [ 'control', 'mesh', 'hubandspoke', 'vpnmembershipgroup', 'approute', 'data', 'cflowd' ] for definition in definitionList: data = self.cen_pol.get_policy_definition(definition) if data: for policy in data: definitionId = policy['definitionId'] self.cen_pol.delete_policy_definition( definition, definitionId) self.active_count_delay() # Step 8 - Delete All Localized Policies data = self.loc_pol.get_localized_policy() for policy in data: policyId = policy['policyId'] self.loc_pol.delete_localized_policy(policyId) self.active_count_delay() # Step 9 - Delete All Localized Specific Definitions definitionList = [ 'qosmap', 'rewriterule', 'acl', 'aclv6', 'vedgeroute' ] for definition in definitionList: data = self.loc_pol.get_localized_definition(definition) if data: for policy in data: definitionId = policy['definitionId'] self.loc_pol.delete_localized_definition( definition, definitionId) self.active_count_delay() # Step 10 - Delete All Security Policies version = self.utilities.get_vmanage_version() if version >= '18.2.0': data = self.sec_pol.get_security_policy() for policy in data: policyId = policy['policyId'] self.sec_pol.delete_security_policy(policyId) self.active_count_delay() # Step 11 - Delete All UTD Specific Security Policies version = self.utilities.get_vmanage_version() definitionList = [] # TODO: implement a proper semver comparison, this will fail if version is 18.30.0 if version >= '18.4.0': definitionList = [ 'zonebasedfw', 'urlfiltering', 'dnssecurity', 'intrusionprevention', 'advancedMalwareProtection' ] #pylint: disable=chained-comparison if version < '18.4.0' and version >= '18.2.0': definitionList = ['zonebasedfw'] if definitionList: for definition in definitionList: data = self.sec_pol.get_security_definition(definition) if data: for policy in data: definitionId = policy['definitionId'] self.sec_pol.delete_security_definition( definition, definitionId) self.active_count_delay() # Step 12 - Delete All Lists data = self.pol_lists.get_policy_list_all() for policy_list in data: owner = policy_list['owner'] if owner != 'system': listType = policy_list['type'].lower() listId = policy_list['listId'] self.pol_lists.delete_policy_list(listType, listId) return ('Reset Complete')
def templates(ctx, template_type, diff, default, name, json): """ Show template information """ device_templates = DeviceTemplates(ctx.auth, ctx.host, ctx.port) feature_templates = FeatureTemplates(ctx.auth, ctx.host, ctx.port) template_data = TemplateData(ctx.auth, ctx.host, ctx.port) pp = pprint.PrettyPrinter(indent=2) if name: if template_type == 'device': template_list = template_data.export_device_template_list(name_list=[name]) elif template_type == 'feature': template_list = feature_templates.get_feature_template_list(name_list=[name]) else: raise click.ClickException("Must specify template type with name") template = template_list[0] if template_list else None if template: if diff: diff_template = {} if template_type == 'device': diff_template_list = template_data.export_device_template_list(name_list=[diff]) if diff_template_list: diff_template = diff_template_list[0] else: click.secho(f"Cannot find device template {diff}", fg="red") elif template_type == 'feature': diff_template_list = feature_templates.get_feature_template_list(name_list=[diff]) if diff_template_list: diff_template = diff_template_list[0] else: click.secho(f"Cannot find feature template {diff}", fg="red") else: # Should not get here raise click.ClickException(f"Unknown template type {template_type}") if diff_template: diff_ignore = set([ 'templateId', 'policyId', 'connectionPreferenceRequired', 'connectionPreference', 'templateName', 'attached_devices', 'input' ]) diff = dictdiffer.diff(template, diff_template, ignore=diff_ignore) pp.pprint(list(diff)) else: pp.pprint(template) else: click.secho(f"Cannot find template named {name}", fg="red") else: if template_type in ['device', None]: device_template_list = template_data.export_device_template_list(factory_default=default) if not json: click.echo(" DEVICES") click.echo("NAME TYPE ATTACHED DEVICE TYPES") click.echo("--------------------------------------------------------------------------") for template in device_template_list: attached_devices = device_templates.get_template_attachments(template['templateId']) click.echo( f"{template['templateName'][:30]:30} {template['configType'][:10]:10} {len(attached_devices):<9} {template['deviceType'][:16]:16} " ) click.echo() else: pp.pprint(device_template_list) if template_type in ['feature', None]: feature_template_list = feature_templates.get_feature_template_list(factory_default=default) if not json: click.echo(" DEVICE DEVICES DEVICE") click.echo("NAME TYPE TEMPLATES ATTACHED MODELS") click.echo("------------------------------------------------------------------------------------") for template in feature_template_list: click.echo( f"{template['templateName'][:30]:30} {template['templateType'][:20]:20} {template['attachedMastersCount']:<10} {template['devicesAttached']:<9} {','.join(template['deviceType'])[:16]:16}" ) else: pp.pprint(feature_template_list)
class TemplateData(object): """Methods that deal with importing, exporting, and converting data from templates. """ def __init__(self, session, host, port=443): """Initialize Templates Method object with session parameters. Args: session (obj): Requests Session object host (str): hostname or IP address of vManage port (int): default HTTPS 443 """ self.session = session self.host = host self.port = port self.base_url = f'https://{self.host}:{self.port}/dataservice/' self.device_templates = DeviceTemplates(self.session, self.host, self.port) self.feature_templates = FeatureTemplates(self.session, self.host, self.port) def convert_device_template_to_name(self, device_template): """Convert a device template objects from IDs to Names. Args: device_template (dict): Device Template Returns: result (dict): Converted Device Template. """ feature_template_dict = self.feature_templates.get_feature_template_dict( factory_default=True, key_name='templateId') if 'policyId' in device_template and device_template['policyId']: policy_id = device_template['policyId'] vmanage_local_policy = LocalPolicy(self.session, self.host, self.port) local_policy_dict = vmanage_local_policy.get_local_policy_dict( key_name='policyId') if policy_id in list(local_policy_dict.keys()): device_template['policyName'] = local_policy_dict[policy_id][ 'policyName'] else: raise Exception(f"Could not find local policy {policy_id}") if 'securityPolicyId' in device_template and device_template[ 'securityPolicyId']: security_policy_id = device_template['securityPolicyId'] vmanage_security_policy = SecurityPolicy(self.session, self.host, self.port) security_policy_dict = vmanage_security_policy.get_security_policy_dict( key_name='policyId') if security_policy_id in list(security_policy_dict.keys()): device_template['securityPolicyName'] = security_policy_dict[ security_policy_id]['policyName'] else: raise Exception( f"Could not find security policy {security_policy_id}") if 'generalTemplates' in device_template: generalTemplates = [] for old_template in device_template.pop('generalTemplates'): new_template = { 'templateName': feature_template_dict[old_template['templateId']] ['templateName'], 'templateType': old_template['templateType'] } if 'subTemplates' in old_template: subTemplates = self.subTemplates_to_name( old_template, feature_template_dict) new_template['subTemplates'] = subTemplates generalTemplates.append(new_template) device_template['generalTemplates'] = generalTemplates return device_template def convert_device_template_to_id(self, device_template): """Convert a device template objects from Names to IDs. Args: device_template (dict): Device Template Returns: result (dict): Converted Device Template. """ if 'policyName' in device_template: vmanage_local_policy = LocalPolicy(self.session, self.host, self.port) local_policy_dict = vmanage_local_policy.get_local_policy_dict( key_name='policyName') if device_template['policyName'] in local_policy_dict: device_template['policyId'] = local_policy_dict[ device_template['policyName']]['policyId'] device_template.pop('policyName') else: raise Exception( f"Could not find local policy {device_template['policyName']}" ) else: device_template['policyId'] = '' if 'securityPolicyName' in device_template: vmanage_security_policy = SecurityPolicy(self.session, self.host, self.port) security_policy_dict = vmanage_security_policy.get_security_policy_dict( key_name='policyName') if device_template['securityPolicyName'] in security_policy_dict: device_template['securityPolicyId'] = security_policy_dict[ device_template['securityPolicyName']]['policyId'] device_template.pop('securityPolicyName') else: raise Exception( f"Could not find security policy {device_template['securityPolicyName']}" ) else: device_template['securityPolicyId'] = '' if 'generalTemplates' in device_template: device_template['generalTemplates'] = self.generalTemplates_to_id( device_template['generalTemplates']) return device_template def generalTemplates_to_id(self, generalTemplates): """Convert a generalTemplates object from Names to IDs. Args: generalTemplates (dict): generalTemplates object Returns: result (dict): Converted generalTemplates object. """ converted_generalTemplates = [] feature_template_dict = self.feature_templates.get_feature_template_dict( factory_default=True) for template in generalTemplates: if 'templateName' not in template: self.result['generalTemplates'] = generalTemplates self.fail_json(msg="Bad template") if template['templateName'] in feature_template_dict: template_item = { 'templateId': feature_template_dict[template['templateName']] ['templateId'], 'templateType': template['templateType'] } if 'subTemplates' in template: subTemplates = self.subTemplates_to_id( template, feature_template_dict) template_item['subTemplates'] = subTemplates converted_generalTemplates.append(template_item) else: self.fail_json( msg="There is no existing feature template named {0}". format(template['templateName'])) return converted_generalTemplates def import_feature_template_list(self, feature_template_list, check_mode=False, update=False): """Import a list of feature templates from list to vManage. Object Names are converted to IDs. Args: feature_template_list (list): List of feature templates check_mode (bool): Only check to see if changes would be made update (bool): Update the template if it exists Returns: result (list): Returns the diffs of the updates. """ # Process the feature templates feature_template_updates = [] feature_template_dict = self.feature_templates.get_feature_template_dict( factory_default=True, remove_key=False) for feature_template in feature_template_list: if 'templateId' in feature_template: feature_template.pop('templateId') if feature_template['templateName'] in feature_template_dict: existing_template = feature_template_dict[ feature_template['templateName']] feature_template['templateId'] = existing_template[ 'templateId'] diff = list( dictdiffer.diff(existing_template['templateDefinition'], feature_template['templateDefinition'])) if len(diff): feature_template_updates.append({ 'name': feature_template['templateName'], 'diff': diff }) if not check_mode and update: self.feature_templates.update_feature_template( feature_template) else: diff = list( dictdiffer.diff({}, feature_template['templateDefinition'])) feature_template_updates.append({ 'name': feature_template['templateName'], 'diff': diff }) if not check_mode: self.feature_templates.add_feature_template( feature_template) return feature_template_updates def export_device_template_list(self, factory_default=False, name_list=None): """Export device templates from vManage into a list. Object IDs are converted to Names. Args: factory_default (bool): Include factory default name_list (list of strings): A list of template names to retreive. Returns: result (dict): All data associated with a response. """ if name_list is None: name_list = [] device_template_list = self.device_templates.get_device_templates() return_list = [] #pylint: disable=too-many-nested-blocks for device_template in device_template_list: # If there is a list of template name, only return the ones asked for. # Otherwise, return them all if name_list and device_template['templateName'] not in name_list: continue obj = self.device_templates.get_device_template_object( device_template['templateId']) if obj: if not factory_default and obj['factoryDefault']: continue obj['templateId'] = device_template['templateId'] # obj['attached_devices'] = self.get_template_attachments(device['templateId']) # obj['input'] = self.get_template_input(device['templateId']) converted_device_template = self.convert_device_template_to_name( obj) return_list.append(converted_device_template) return return_list def import_device_template_list(self, device_template_list, check_mode=False, update=False): """Import a list of device templates from list to vManage. Object Names are converted to IDs. Args: device_template_list (list): List of device templates check_mode (bool): Only check to see if changes would be made update (bool): Update the template if it exists Returns: result (list): Returns the diffs of the updates. """ device_template_updates = [] device_template_dict = self.device_templates.get_device_template_dict() diff = [] for device_template in device_template_list: if 'policyId' in device_template: device_template.pop('policyId') if 'securityPolicyId' in device_template: device_template.pop('securityPolicyId') if device_template['templateName'] in device_template_dict: existing_template = self.convert_device_template_to_name( device_template_dict[device_template['templateName']]) device_template['templateId'] = existing_template['templateId'] # Just check the things that we care about changing. diff_ignore = set([ 'templateId', 'policyId', 'connectionPreferenceRequired', 'connectionPreference', 'templateName', 'attached_devices', 'input', 'securityPolicyId' ]) diff = list( dictdiffer.diff(existing_template, device_template, ignore=diff_ignore)) if len(diff): device_template_updates.append({ 'name': device_template['templateName'], 'diff': diff }) if not check_mode and update: if not check_mode: converted_device_template = self.convert_device_template_to_id( device_template) self.device_templates.update_device_template( converted_device_template) else: if 'generalTemplates' in device_template: diff = list( dictdiffer.diff({}, device_template['generalTemplates'])) elif 'templateConfiguration' in device_template: diff = list( dictdiffer.diff( {}, device_template['templateConfiguration'])) else: raise Exception("Template {0} is of unknown type".format( device_template['templateName'])) device_template_updates.append({ 'name': device_template['templateName'], 'diff': diff }) if not check_mode: converted_device_template = self.convert_device_template_to_id( device_template) self.device_templates.add_device_template( converted_device_template) return device_template_updates def import_attachment_list(self, attachment_list, check_mode=False, update=False): """Import a list of device attachments to vManage. Args: attachment_list (list): List of attachments check_mode (bool): Only check to see if changes would be made update (bool): Update the template if it exists Returns: result (list): Returns the diffs of the updates. """ attachment_updates = {} attachment_failures = {} action_id_list = [] device_template_dict = self.device_templates.get_device_template_dict() vmanage_device = Device(self.session, self.host, self.port) for attachment in attachment_list: if attachment['template'] in device_template_dict: if attachment['device_type'] == 'vedge': # The UUID is fixes from the serial file/upload device_uuid = attachment['uuid'] else: # If this is not a vedge, we need to get the UUID from the vmanage since # it is generated by that vmanage device_status = vmanage_device.get_device_status( attachment['host_name'], key='host-name') if device_status: device_uuid = device_status['uuid'] else: raise Exception( f"Cannot find UUID for {attachment['host_name']}") template_id = device_template_dict[ attachment['template']]['templateId'] attached_uuid_list = self.device_templates.get_attachments( template_id, key='uuid') if device_uuid in attached_uuid_list: # The device is already attached to the template. We need to see if any of # the input changed, so we make an API call to get the input on last attach existing_template_input = self.device_templates.get_template_input( device_template_dict[attachment['template']] ['templateId'], [device_uuid]) current_variables = existing_template_input['data'][0] changed = False for property_name in attachment['variables']: # Check to see if any of the passed in varibles have changed from what is # already on the attachment. We are are not checking to see if the # correct variables are here. That will be done on attachment. if ((property_name in current_variables) and (str(attachment['variables'][property_name]) != str(current_variables[property_name]))): changed = True if changed: if not check_mode and update: action_id = self.device_templates.attach_to_template( template_id, device_uuid, attachment['system_ip'], attachment['host_name'], attachment['site_id'], attachment['variables']) action_id_list.append(action_id) else: if not check_mode: action_id = self.device_templates.attach_to_template( template_id, device_uuid, attachment['system_ip'], attachment['host_name'], attachment['site_id'], attachment['variables']) action_id_list.append(action_id) else: raise Exception(f"No template named {attachment['template']}") utilities = Utilities(self.session, self.host) # Batch the waits so that the peocessing of the attachments is in parallel for action_id in action_id_list: result = utilities.waitfor_action_completion(action_id) data = result['action_response']['data'][0] if result['action_status'] == 'failure': attachment_failures.update( {data['uuid']: data['currentActivity']}) else: attachment_updates.update( {data['uuid']: data['currentActivity']}) result = { 'updates': attachment_updates, 'failures': attachment_failures } return result def subTemplates_to_name(self, old_template, feature_template_dict): """Convert a Sub Template objects from IDs to Names. Args: old_template (dict): a device template feature_template_dict (dict): dict of all the feature templates Returns: result (dict): Converted Device Template. """ subTemplates = [] for sub_template in old_template['subTemplates']: if 'subTemplates' in sub_template: subsubTemplates = [] for sub_sub_template in sub_template['subTemplates']: subsubTemplates.append({ 'templateName': feature_template_dict[sub_sub_template['templateId']] ['templateName'], 'templateType': sub_sub_template['templateType'] }) subTemplates.append({ 'templateName': feature_template_dict[sub_template['templateId']] ['templateName'], 'templateType': sub_template['templateType'], 'subTemplates': subsubTemplates }) else: subTemplates.append({ 'templateName': feature_template_dict[sub_template['templateId']] ['templateName'], 'templateType': sub_template['templateType'] }) return (subTemplates) def subTemplates_to_id(self, template, feature_template_dict): """Convert a Sub Template objects from IDs to Names. Args: template (dict): a device template feature_template_dict (dict): dict of all the feature templates Returns: result (dict): Converted Device Template. """ subTemplates = [] for sub_template in template['subTemplates']: if sub_template[ 'templateName'] in feature_template_dict and 'subTemplates' in sub_template: subsubTemplates = [] for sub_sub_template in sub_template['subTemplates']: if sub_sub_template[ 'templateName'] in feature_template_dict: subsubTemplates.append({ 'templateId': feature_template_dict[sub_sub_template[ 'templateName']]['templateId'], 'templateType': sub_sub_template['templateType'] }) else: self.fail_json( msg="There is no existing feature template named {0}" .format(sub_sub_template['templateName'])) subTemplates.append({ 'templateId': feature_template_dict[sub_template['templateName']] ['templateId'], 'templateType': sub_template['templateType'], 'subTemplates': subsubTemplates }) elif sub_template['templateName'] in feature_template_dict: subTemplates.append({ 'templateId': feature_template_dict[sub_template['templateName']] ['templateId'], 'templateType': sub_template['templateType'] }) else: self.fail_json( msg="There is no existing feature template named {0}". format(sub_template['templateName'])) return (subTemplates)
def import_policy_definition_list(self, policy_definition_list, update=False, push=False, check_mode=False, force=False): """Import Policy Definitions into vManage. Object names are converted to IDs. Returns: response (dict): A list of all policy lists currently in vManage. """ policy_definition_updates = [] #pylint: disable=too-many-nested-blocks for definition in policy_definition_list: policy_definition_dict = self.policy_definitions.get_policy_definition_dict( definition['type'], remove_key=False) diff = [] payload = { "name": definition['name'], "description": definition['description'], "type": definition['type'], } if 'defaultAction' in definition: payload.update({'defaultAction': definition['defaultAction']}) if 'sequences' in definition: payload.update({'sequences': definition['sequences']}) if 'definition' in definition: payload.update({'definition': definition['definition']}) if definition['name'] in policy_definition_dict: existing_definition = self.convert_policy_definition_to_name( policy_definition_dict[definition['name']]) # Just check the things that we care about changing. diff_ignore = set([ 'lastUpdated', 'definitionId', 'referenceCount', 'references', 'owner', 'isActivatedByVsmart', 'infoTag', 'activatedId' ]) diff = list( dictdiffer.diff(existing_definition, payload, ignore=diff_ignore)) if diff: converted_definition = self.convert_policy_definition_to_id( definition) policy_definition_updates.append({ 'name': converted_definition['name'], 'diff': diff }) if not check_mode and update: response = self.policy_definitions.update_policy_definition( converted_definition, policy_definition_dict[ converted_definition['name']]['definitionId']) if response['json']: # Updating the policy defin returns a `processId` that locks the list and 'masterTemplatesAffected' # that lists the templates affected by the change. if 'error' in response['json']: raise RuntimeError( response['json']['error']['message']) elif 'processId' in response['json']: if push: vmanage_device_templates = DeviceTemplates( self.session, self.host) # If told to push out the change, we need to reattach each template affected by the change for template_id in response['json'][ 'masterTemplatesAffected']: obj = vmanage_device_templates.get_device_template_object( template_id) vmanage_device_templates.reattach_device_template( template_id, obj['configType']) else: raise RuntimeError( "Did not get a process id when updating policy definition" ) else: # Policy definition does not exist diff = list(dictdiffer.diff({}, payload)) policy_definition_updates.append({ 'name': definition['name'], 'diff': diff }) converted_definition = self.convert_policy_definition_to_id( definition) if not check_mode: self.policy_definitions.add_policy_definition( converted_definition) return policy_definition_updates
def import_templates_from_file(self, file, update=False, check_mode=False, name_list=None, template_type=None): vmanage_device_templates = DeviceTemplates(self.session, self.host, self.port) vmanage_feature_templates = FeatureTemplates(self.session, self.host, self.port) feature_template_updates = [] device_template_updates = [] template_data = {} # Read in the datafile if not os.path.exists(file): raise Exception(f"Cannot find file {file}") with open(file) as f: if file.endswith('.yaml') or file.endswith('.yml'): template_data = yaml.safe_load(f) else: template_data = json.load(f) if 'vmanage_feature_templates' in template_data: imported_feature_template_list = template_data[ 'vmanage_feature_templates'] else: imported_feature_template_list = [] imported_device_template_list = [] #pylint: disable=too-many-nested-blocks if template_type != 'feature': # Import the device templates and associated feature templates if 'vmanage_device_templates' in template_data: imported_device_template_list = template_data[ 'vmanage_device_templates'] if name_list: feature_name_list = [] pruned_device_template_list = [] for device_template in imported_device_template_list: if device_template['templateName'] in name_list: pruned_device_template_list.append(device_template) if 'generalTemplates' in device_template: for general_template in device_template[ 'generalTemplates']: if 'templateName' in general_template: feature_name_list.append( general_template['templateName']) if 'subTemplates' in general_template: for sub_template in general_template[ 'subTemplates']: if 'templateName' in sub_template: feature_name_list.append( sub_template['templateName']) imported_device_template_list = pruned_device_template_list name_list = list(set(feature_name_list)) # Since device templates depend on feature templates, we always add them. if name_list: pruned_feature_template_list = [] imported_feature_template_dict = self.list_to_dict( imported_feature_template_list, key_name='templateName', remove_key=False) for feature_template_name in name_list: if feature_template_name in imported_feature_template_dict: pruned_feature_template_list.append( imported_feature_template_dict[feature_template_name]) # Otherwise, we hope the feature list is already there (e.g. Factory Default) imported_feature_template_list = pruned_feature_template_list # Process the feature templates feature_template_updates = vmanage_feature_templates.import_feature_template_list( imported_feature_template_list, check_mode=check_mode, update=update) # Process the device templates device_template_updates = vmanage_device_templates.import_device_template_list( imported_device_template_list, check_mode=check_mode, update=update) return { 'feature_template_updates': feature_template_updates, 'device_template_updates': device_template_updates, }
def import_local_policy_list(self, local_policy_list, update=False, push=False, check_mode=False, force=False): """Import Local Policies into vManage. Object names are converted to IDs. Returns: response (dict): A list of all policy lists currently in vManage. """ local_policy_dict = self.local_policy.get_local_policy_dict( remove_key=False) diff = [] local_policy_updates = [] #pylint: disable=too-many-nested-blocks for local_policy in local_policy_list: payload = {'policyName': local_policy['policyName']} payload['policyDescription'] = local_policy['policyDescription'] payload['policyType'] = local_policy['policyType'] payload['policyDefinition'] = local_policy['policyDefinition'] if payload['policyName'] in local_policy_dict: # A policy by that name already exists existing_policy = self.convert_policy_to_name( local_policy_dict[payload['policyName']]) diff_ignore = set([ 'lastUpdated', 'policyVersion', 'createdOn', 'references', 'isPolicyActivated', '@rid', 'policyId', 'createdBy', 'lastUpdatedBy', 'lastUpdatedOn', 'mastersAttached', 'policyDefinitionEdit', 'devicesAttached' ]) diff = list( dictdiffer.diff(existing_policy, payload, ignore=diff_ignore)) if diff: local_policy_updates.append({ 'name': local_policy['policyName'], 'diff': diff }) if 'policyDefinition' in payload: self.convert_definition_name_to_id( payload['policyDefinition']) if not check_mode and update: response = self.local_policy.update_local_policy( payload, existing_policy['policyId']) if response['json']: # Updating the policy defin returns a `processId` that locks the list and 'masterTemplatesAffected' # that lists the templates affected by the change. if 'error' in response['json']: raise RuntimeError( response['json']['error']['message']) elif 'processId' in response['json']: if push: vmanage_device_templates = DeviceTemplates( self.session, self.host) # If told to push out the change, we need to reattach each template affected by the change vmanage_device_templates.reattach_multi_device_templates( response['json'] ['masterTemplatesAffected']) else: raise RuntimeError( "Did not get a process id when updating local policy" ) else: diff = list(dictdiffer.diff({}, payload['policyDefinition'])) local_policy_updates.append({ 'name': local_policy['policyName'], 'diff': diff }) if 'policyDefinition' in payload: # Convert list and definition names to template IDs self.convert_definition_name_to_id( payload['policyDefinition']) if not check_mode: self.local_policy.add_local_policy(payload) return local_policy_updates
class CleanVmanage(object): """Reset all configuratios on a vManage instance. Executes the necessary REST calls in specific order to remove configurations applied to a vManage instance. """ def __init__(self, session, host, port=443): """Initialize Reset vManage object with session parameters. Args: session (obj): Requests Session object host (str): hostname or IP address of vManage port (int): default HTTPS 443 """ self.session = session self.host = host self.port = port self.base_url = f'https://{self.host}:{self.port}/dataservice/' self.utilities = Utilities(self.session, self.host) self.central_policy = CentralPolicy(self.session, self.host) self.local_policy = LocalPolicy(self.session, self.host) self.device = Device(self.session, self.host) self.device_templates = DeviceTemplates(self.session, self.host) self.feature_templates = FeatureTemplates(self.session, self.host) self.sec_pol = SecurityPolicy(self.session, self.host) self.policy_definitions = PolicyDefinitions(self.session, self.host) self.policy_lists = PolicyLists(self.session, self.host) def active_count_delay(self): """Delay while there are active tasks. """ activeCount = 1 while activeCount != 0: time.sleep(1.0) data = self.utilities.get_active_count() activeCount = data["activeTaskCount"] def clean_vedge_attachments(self): """Clean all vedge attachments """ data = self.device.get_device_list('vedges') for device in data: if (('deviceIP' in device) and (device['configOperationMode'] == 'vmanage')): deviceId = device['uuid'] deviceIP = device['deviceIP'] deviceType = device['deviceType'] self.device.post_device_cli_mode(deviceId, deviceIP, deviceType) self.active_count_delay() def clean_controller_attachments(self): """Clean all controller attachments """ data = self.device.get_device_list('controllers') for device in data: if (('deviceIP' in device) and (device['configOperationMode'] == 'vmanage')): deviceId = device['uuid'] deviceIP = device['deviceIP'] deviceType = device['deviceType'] self.device.post_device_cli_mode(deviceId, deviceIP, deviceType) # Requires pause between controllers self.active_count_delay() self.active_count_delay() def clean_device_templates(self): """Clean all device templates """ data = self.device_templates.get_device_templates() for device in data: templateId = device['templateId'] self.device_templates.delete_device_template(templateId) self.active_count_delay() def clean_feature_templates(self): """Clean all feature templates """ data = self.feature_templates.get_feature_templates() for device in data: #pylint: disable=no-else-continue if device['factoryDefault']: continue else: templateId = device['templateId'] self.feature_templates.delete_feature_template(templateId) self.active_count_delay() def clean_central_policy(self): """Clean all central policy """ data = self.central_policy.get_central_policy() for policy in data: policy_id = policy['policyId'] if policy['isPolicyActivated']: action_id = self.central_policy.deactivate_central_policy(policy_id) if action_id: self.utilities.waitfor_action_completion(action_id) self.central_policy.delete_central_policy(policy_id) self.active_count_delay() def clean_local_policy(self): """Clean all local policy """ data = self.local_policy.get_local_policy() for policy in data: policyId = policy['policyId'] self.local_policy.delete_local_policy(policyId) self.active_count_delay() def clean_policy_definitions(self): """Clean all policy definitions """ policy_definition_list = self.policy_definitions.get_policy_definition_list() for policy_definition in policy_definition_list: self.policy_definitions.delete_policy_definition(policy_definition['type'], policy_definition['definitionId']) self.active_count_delay() def clean_policy_lists(self): """Clean all policy lists """ policy_list_list = self.policy_lists.get_policy_list_list() for policy_list in policy_list_list: if not policy_list['readOnly'] and policy_list['owner'] != 'system': self.policy_lists.delete_policy_list(policy_list['type'], policy_list['listId']) self.active_count_delay() def clean_security_policy(self): """Clean all security policy """ version = self.utilities.get_vmanage_version() if version >= '18.2.0': data = self.sec_pol.get_security_policy() for policy in data: policyId = policy['policyId'] self.sec_pol.delete_security_policy(policyId) self.active_count_delay() # # Step 11 - Delete All UTD Specific Security Policies # version = self.utilities.get_vmanage_version() # definitionList = [] # # TODO: implement a proper semver comparison, this will fail if version is 18.30.0 # if version >= '18.4.0': # definitionList = [ # 'zonebasedfw', 'urlfiltering', 'dnssecurity', 'intrusionprevention', 'advancedMalwareProtection' # ] # #pylint: disable=chained-comparison # if version < '18.4.0' and version >= '18.2.0': # definitionList = ['zonebasedfw'] # if definitionList: # for definition in definitionList: # data = self.sec_pol.get_security_definition(definition) # if data: # for policy in data: # definitionId = policy['definitionId'] # self.sec_pol.delete_security_definition(definition, definitionId) # self.active_count_delay() # # Step 12 - Delete All Lists # data = self.pol_lists.get_policy_list_all() # for policy_list in data: # owner = policy_list['owner'] # if owner != 'system': # listType = policy_list['type'].lower() # listId = policy_list['listId'] # self.pol_lists.delete_policy_list(listType, listId) def clean_all(self): """Clean everything in vManage """ # Step 1 - Deactivate Central Policy self.clean_central_policy() # Step 2 - Detach vedges from template self.clean_vedge_attachments() # Step 3 - Detach controllers from template self.clean_controller_attachments() # Step 4 - Delete All Device Templates self.clean_device_templates() # Step 5 - Delete All Feature Templates self.clean_feature_templates() # Step 6 - Delete All Centralized Policies self.clean_central_policy() # Step 7 - Delete All Policy Definitions self.clean_policy_definitions() # Step 8 - Delete All Policy Lists self.clean_policy_lists() # Step 9 - Delete All Local Policies self.clean_local_policy() # Step 10 - Delete All Security Policies self.clean_security_policy() return ('Reset Complete')
class Files(object): """Read and write data to file. """ def __init__(self, session, host, port=443): """Initialize Files object with session parameters. Args: session (obj): Requests Session object host (str): hostname or IP address of vManage port (int): default HTTPS 443 """ self.session = session self.host = host self.port = port self.base_url = f'https://{self.host}:{self.port}/dataservice/' self.device_templates = DeviceTemplates(self.session, self.host, self.port) self.feature_templates = FeatureTemplates(self.session, self.host, self.port) self.template_data = TemplateData(self.session, self.host, self.port) self.policy_data = PolicyData(self.session, self.host, self.port) self.policy_lists = PolicyLists(self.session, self.host, self.port) self.policy_definitions = PolicyDefinitions(self.session, self.host, self.port) self.local_policy = LocalPolicy(self.session, self.host, self.port) self.central_policy = CentralPolicy(self.session, self.host, self.port) self.security_policy = SecurityPolicy(self.session, self.host, self.port) self.vmanage_device = Device(self.session, self.host, self.port) def export_templates_to_file(self, export_file, name_list=None, template_type=None): """Export templates to a file. All object IDs will be translated to names. Use a '.yml' extention to export as YAML and a '.json' extension to export as JSON. Args: export_file (str): The name of the export file name_list (list): List of device templates to export template_type (str): Template type: device or template """ template_export = {} #pylint: disable=too-many-nested-blocks if template_type != 'feature': # Export the device templates and associated feature templates device_template_list = self.template_data.export_device_template_list(name_list=name_list) template_export.update({'vmanage_device_templates': device_template_list}) feature_name_list = [] if name_list: for device_template in device_template_list: if 'generalTemplates' in device_template: for general_template in device_template['generalTemplates']: if 'templateName' in general_template: feature_name_list.append(general_template['templateName']) if 'subTemplates' in general_template: for sub_template in general_template['subTemplates']: if 'templateName' in sub_template: feature_name_list.append(sub_template['templateName']) name_list = list(set(feature_name_list)) # Since device templates depend on feature templates, we always add them. feature_template_list = self.feature_templates.get_feature_template_list(name_list=name_list) template_export.update({'vmanage_feature_templates': feature_template_list}) if export_file.endswith('.json'): with open(export_file, 'w') as outfile: json.dump(template_export, outfile, indent=4, sort_keys=False) elif export_file.endswith('.yaml') or export_file.endswith('.yml'): with open(export_file, 'w') as outfile: yaml.dump(template_export, outfile, indent=4, sort_keys=False) else: raise Exception("File format not supported") #pylint: disable=unused-argument def import_templates_from_file(self, import_file, update=False, check_mode=False, name_list=None, template_type=None): """Import templates from a file. All object Names will be translated to IDs. Args: import_file (str): The name of the import file name_list (list): List of device templates to export template_type (str): Template type: device or template check_mode (bool): Try the import, but don't make changes (default: False) update (bool): Update existing templates (default: False) """ feature_template_updates = [] device_template_updates = [] imported_template_data = {} # Read in the datafile if not os.path.exists(import_file): raise Exception(f"Cannot find file {import_file}") with open(import_file) as f: if import_file.endswith('.yaml') or import_file.endswith('.yml'): imported_template_data = yaml.safe_load(f) else: imported_template_data = json.load(f) if 'vmanage_feature_templates' in imported_template_data: imported_feature_template_list = imported_template_data['vmanage_feature_templates'] else: imported_feature_template_list = [] imported_device_template_list = [] #pylint: disable=too-many-nested-blocks if template_type != 'feature': # Import the device templates and associated feature templates if 'vmanage_device_templates' in imported_template_data: imported_device_template_list = imported_template_data['vmanage_device_templates'] if name_list: feature_name_list = [] pruned_device_template_list = [] for device_template in imported_device_template_list: if device_template['templateName'] in name_list: pruned_device_template_list.append(device_template) if 'generalTemplates' in device_template: for general_template in device_template['generalTemplates']: if 'templateName' in general_template: feature_name_list.append(general_template['templateName']) if 'subTemplates' in general_template: for sub_template in general_template['subTemplates']: if 'templateName' in sub_template: feature_name_list.append(sub_template['templateName']) imported_device_template_list = pruned_device_template_list name_list = list(set(feature_name_list)) # Since device templates depend on feature templates, we always add them. if name_list: pruned_feature_template_list = [] imported_feature_template_dict = list_to_dict(imported_feature_template_list, key_name='templateName', remove_key=False) for feature_template_name in name_list: if feature_template_name in imported_feature_template_dict: pruned_feature_template_list.append(imported_feature_template_dict[feature_template_name]) # Otherwise, we hope the feature list is already there (e.g. Factory Default) imported_feature_template_list = pruned_feature_template_list # Process the feature templates feature_template_updates = self.template_data.import_feature_template_list(imported_feature_template_list, check_mode=check_mode, update=update) # Process the device templates device_template_updates = self.template_data.import_device_template_list(imported_device_template_list, check_mode=check_mode, update=update) return { 'feature_template_updates': feature_template_updates, 'device_template_updates': device_template_updates, } # # Policy # def export_policy_to_file(self, export_file): """Export policy to a file. All object IDs will be translated to names. Use a '.yml' extention to export as YAML and a '.json' extension to export as JSON. Args: export_file (str): The name of the export file """ policy_lists_list = self.policy_lists.get_policy_list_list() policy_definitions_list = self.policy_data.export_policy_definition_list() central_policies_list = self.policy_data.export_central_policy_list() local_policies_list = self.local_policy.get_local_policy_list() security_policies_list = self.policy_data.export_security_policy_list() policy_export = { 'vmanage_policy_lists': policy_lists_list, 'vmanage_policy_definitions': policy_definitions_list, 'vmanage_central_policies': central_policies_list, 'vmanage_local_policies': local_policies_list, 'vmanage_security_policies': security_policies_list } if export_file.endswith('.json'): with open(export_file, 'w') as outfile: json.dump(policy_export, outfile, indent=4, sort_keys=False) elif export_file.endswith(('.yaml', 'yml')): with open(export_file, 'w') as outfile: yaml.dump(policy_export, outfile, default_flow_style=False) else: raise Exception("File format not supported") def import_policy_from_file(self, file, update=False, check_mode=False, push=False): """Import policy from a file. All object Names will be translated to IDs. Args: import_file (str): The name of the import file check_mode (bool): Try the import, but don't make changes (default: False) update (bool): Update existing templates (default: False) push (bool): Push tempaltes to devices if changed (default: False) """ policy_list_updates = [] policy_definition_updates = [] central_policy_updates = [] local_policy_updates = [] security_policy_updates = [] # Read in the datafile if not os.path.exists(file): raise Exception('Cannot find file {0}'.format(file)) with open(file) as f: if file.endswith('.yaml') or file.endswith('.yml'): policy_data = yaml.safe_load(f) else: policy_data = json.load(f) # Separate the feature template data from the device template data if 'vmanage_policy_lists' in policy_data: policy_list_data = policy_data['vmanage_policy_lists'] else: policy_list_data = [] if 'vmanage_policy_definitions' in policy_data: policy_definition_data = policy_data['vmanage_policy_definitions'] else: policy_definition_data = [] if 'vmanage_central_policies' in policy_data: central_policy_data = policy_data['vmanage_central_policies'] else: central_policy_data = [] if 'vmanage_local_policies' in policy_data: local_policy_data = policy_data['vmanage_local_policies'] else: local_policy_data = [] if 'vmanage_security_policies' in policy_data: security_policy_data = policy_data['vmanage_security_policies'] else: security_policy_data = [] policy_list_updates = self.policy_data.import_policy_list_list(policy_list_data, check_mode=check_mode, update=update, push=push) self.policy_lists.clear_policy_list_cache() policy_definition_updates = self.policy_data.import_policy_definition_list(policy_definition_data, check_mode=check_mode, update=update, push=push) central_policy_updates = self.policy_data.import_central_policy_list(central_policy_data, check_mode=check_mode, update=update, push=push) local_policy_updates = self.policy_data.import_local_policy_list(local_policy_data, check_mode=check_mode, update=update, push=push) security_policy_updates = self.policy_data.import_security_policy_list(security_policy_data, check_mode=check_mode, update=update, push=push) return { 'policy_list_updates': policy_list_updates, 'policy_definition_updates': policy_definition_updates, 'central_policy_updates': central_policy_updates, 'local_policy_updates': local_policy_updates, 'security_policy_updates': security_policy_updates } def export_attachments_to_file(self, export_file, name_list=None, device_type=None): """Export attachments to a file. All object IDs will be translated to names. Use a '.yml' extention to export as YAML and a '.json' extension to export as JSON. Args: export_file (str): The name of the export file """ if name_list is None: name_list = [] device_template_dict = self.device_templates.get_device_template_dict() attachments_list = [] # Create a device config of the right type of things device_list = [] if device_type in (None, 'controllers'): device_list = self.vmanage_device.get_device_config_list('controllers') if device_type in (None, 'vedges'): edge_list = self.vmanage_device.get_device_config_list('vedges') device_list = device_list + edge_list for device_config in device_list: if 'configStatusMessage' in device_config and device_config['configStatusMessage'] != 'In Sync': continue if 'template' in device_config: if device_config['template'] in device_template_dict: template_id = device_template_dict[device_config['template']]['templateId'] else: raise Exception(f"Could not find ID for template {device_config['template']}") if name_list == [] or device_config.get('host-name') in name_list: variable_dict = {} template_input = self.device_templates.get_template_input(template_id, device_id_list=[device_config['uuid']]) data = template_input['data'][0] for column in template_input['columns']: variable_dict[column['variable']] = data[column['property']] entry = { 'host_name': device_config.get('host-name'), 'device_type': device_config['deviceType'], 'uuid': device_config['chasisNumber'], 'system_ip': device_config['deviceIP'], 'site_id': device_config.get('site-id'), 'template': device_config['template'], 'variables': variable_dict } attachments_list.append(entry) attachment_export = {'vmanage_attachments': attachments_list} if export_file.endswith('.json'): with open(export_file, 'w') as outfile: json.dump(attachment_export, outfile, indent=4, sort_keys=False) elif export_file.endswith(('.yaml', 'yml')): with open(export_file, 'w') as outfile: yaml.dump(attachment_export, outfile, indent=4, sort_keys=False) else: raise Exception("File format not supported") return (len(attachments_list)) def import_attachments_from_file(self, import_file, update=False, check_mode=False, name_list=None, template_type=None): """Import policy from a file. All object Names will be translated to IDs. Args: import_file (str): The name of the import file check_mode (bool): Try the import, but don't make changes (default: False) update (bool): Update existing templates (default: False) """ template_data = {} # Read in the datafile if not os.path.exists(import_file): raise Exception(f"Cannot find file {import_file}") with open(import_file) as f: if import_file.endswith('.yaml') or import_file.endswith('.yml'): template_data = yaml.safe_load(f) else: template_data = json.load(f) if 'vmanage_attachments' in template_data: imported_attachment_list = template_data['vmanage_attachments'] else: imported_attachment_list = [] # Process the device templates result = self.template_data.import_attachment_list(imported_attachment_list, check_mode=check_mode, update=update) return result