def add_router(template_name, router_name, validationType='distributed'): logger.info("Adding config for router {0} using template {1}".format( router_name, template_name)) add_config = _create_add_config(template_name, router_name) if add_config: logger.debug("Rendered add router config: {0}".format(add_config)) if sys.version_info < (3, 6): cc = Config.Config() cc.load_t128_config_model('/var/model/consolidatedT128Model.xml') add_config_xml = cc.convert_config_to_netconf_xml( add_config.split('\n')) else: cc = NetconfConverter() cc.load_config_model('/var/model/consolidatedT128Model.xml') add_config_xml = cc.convert_config_to_netconf_xml( add_config.split('\n'), 'config') ch = t128_netconf_utilities.t128ConfigHelper() return ch.commit_config_xml(add_config_xml, validationType=validationType) else: ret = Returner( returner='saltstack', name="add_router", changes={}, result=False, comment="Could not find a router or template by the given name") return ret.getReturn()
def delete_router(delete_router_name, validationType='distributed'): logger.info("Deleting router {0}".format(delete_router_name)) delete_config = _create_delete_config(delete_router_name) if delete_config: logger.debug("Rendered delete router config: {0}".format(delete_config)) cc = Config.Config() cc.load_t128_config_model('/var/model/consolidatedT128Model.xml') delete_config_xml = cc.convert_config_to_netconf_xml(delete_config.split('\n')) ch = t128_netconf_utilities.t128ConfigHelper() return ch.commit_config_xml(delete_config_xml, validationType=validationType) else: ret = Returner(returner='saltstack', name="delete_router", changes={}, result=False, comment="Could not find a router by the given name")
def orchestrate_vpns(): logger.debug("Checking for new VPNs to orchestrate...") __salt__['file.mkdir']("{0}/{1}".format(PILLAR_DIRECTORY, AZURE_PILLAR_DIRECTORY)) config_xml = _get_current_config() vwh = azureVwanHelper() vwans = vwh.get_vwan_map() azure_top = "base:\n" for vwan, vwan_data in vwans.iteritems(): neighborhood = vwan_data[VWAN_NEIGHBORHOOD_TAG] azure_tenant = vwan_data[VWAN_TENANT_TAG] t128name = vwan_data[VWAN_SVC_AND_INT_TAG] sas_url = vwan_data[VWAN_SAS_URL_TAG] site_map = _get_site_map(config_xml, neighborhood) vwan_connections = vwh.get_vwan_conns(vwan, sas_url) vwan_address_space = vwh.get_vwan_address_space(vwan) for site_name, connection in vwan_connections.iteritems(): site_details = site_map[site_name] changes = {} if site_map[site_name].get('asset'): vpn_data = _create_minion_pillar( t128name, connection['PSK'], connection['SiteAddress'], connection['gateway']['Instance0'], connection['gateway']['Instance1']) manage_results = __salt__['file.manage_file']( "{0}/{1}/{2}.sls".format(PILLAR_DIRECTORY, AZURE_PILLAR_DIRECTORY, site_name), '', '', '', '', 'root', 'root', 644, '', 'base', False, contents=vpn_data) if manage_results['changes'] != {}: logger.debug( "Wrote pillar for site {}, pillar data changed".format( site_name)) changes[site_name] = site_details azure_top += " \'id:{}\':\n".format(site_details['asset']) # We use this matching because glob matching will conflict with the main top states azure_top += " - match: grain\n" azure_top += " - {0}.{1}".format(AZURE_PILLAR_DIRECTORY, site_name) __salt__['file.write']("{0}/{1}-top.sls".format( PILLAR_DIRECTORY, AZURE_PILLAR_DIRECTORY), args=azure_top) saltMaster = salt.client.LocalClient(c_path=MASTER_CONFIG) config = "config\n" config += " authority\n" for site_name, site_details in changes.iteritems(): # Make sure required modules are available sync_ret = saltMaster.cmd(site_details['asset'], 'saltutil.sync_all', ['saltenv=128T,base']) ipsec_sfc_ret = saltMaster.cmd(site_details['asset'], 'state.apply', ['setup-ipsec-sfc']) logger.debug("IPSec setup results:\n{}".format(ipsec_sfc_ret)) ipsec_conn_ret = saltMaster.cmd(site_details['asset'], 'state.apply', ['setup-ipsec-connections']) logger.debug( "IPSec connection setup:\n{}".format(ipsec_conn_ret)) # Setup IPSec config ipsec_config = _config_snippet_generate( router_name=site_name, node_name=site_details['node'], interface_name=IPSEC_INT_NAME, tenant=IPSEC_TENANT, interface_address=IPSEC_ADDRESS, interface_prefix=IPSEC_PREFIX, interface_gateway=IPSEC_GATWAY, service_name=IPSEC_SERVICE_NAME, service_addresses=IPSEC_SERVICE_ADDRESSES, access_tenant=IPSEC_TENANT, sr_name=IPSEC_SR_NAME, sr_node_name=site_details['node'], sr_interface_name=site_details['wan_interface'], sr_gateway=site_details.get('wan_gateway')) logger.debug("ipsec_config for site {0}:\n{1}".format( site_name, ipsec_config)) azure_config = _config_snippet_generate( router_name=site_name, node_name=site_details['node'], interface_name=t128name, tenant=azure_tenant, interface_address=AZURE_KNI_ADDRESS, interface_prefix=AZURE_KNI_PREFIX, interface_gateway=AZURE_KNI_GATEWAY, service_name=t128name, service_addresses=vwan_address_space, sr_name=t128name, sr_node_name=site_details['node'], sr_interface_name=t128name, sr_gateway=AZURE_KNI_GATEWAY) logger.debug("azure_config for site {0}:\n{1}".format( site_name, azure_config)) config += ipsec_config config += azure_config config += " exit\n" config += "exit" ch = t128_netconf_utilities.t128ConfigHelper() cc = Config.Config() cc.load_t128_config_model( '/var/model/consolidatedT128Model.xml') config_xml = cc.convert_config_to_netconf_xml( config.split('\n')) return ch.commit_config_xml(config_xml)
def zscaler_configure(username, password, apiKey): zscaler_data = __pillar__['zscaler_data'] zscaler_base_uri = "https://{}/api/v1".format(zscaler_data['zscaler_uri']) obfApiKey, timestamp = _obfuscateApiKey(apiKey) headers = { 'Content-Type': "application/json", 'Cache-Control': "no-cache", } payload = { "username": username, "password": password, "apiKey": obfApiKey, "timestamp": timestamp } s = requests.session() # Zscaler wants 1 request per second so we can expect occassional 429 responses from them. # Handle this automatically retries = Retry(total=5, backoff_factor=1, status_forcelist=[429, 502, 503, 504], method_whitelist=frozenset(['GET', 'POST'])) s.mount('https://', HTTPAdapter(max_retries=retries)) login = s.post("{0}/authenticatedSession".format(zscaler_base_uri), headers=headers, data=json.dumps(payload)) if (login.status_code >= 400 or login.status_code < 200): return "Error authenticating to Zscaler: {0}: {1}".format( login.status_code, login.json()) zdomain = zscaler_data['domain_name'] zscaler_routers = zscaler_data['routers'] ch = t128_netconf_utilities.t128ConfigHelper() config_xml = ch.get_current_config_xml() router_map = _create_asset_map(config_xml) zscaler_top = "base:\n" __salt__['file.mkdir']("{0}/{1}".format(PILLAR_DIRECTORY, 'zscaler')) ret_string = "" for router, nodes in zscaler_routers.iteritems(): vpns = [] for node, tunnels in nodes.iteritems(): psk = _generate_random_psk() userfqdn = "{0}@{1}".format(node, zdomain) vpnPayload = { "type": "UFQDN", "fqdn": userfqdn, "comments": "Created automatically", "preSharedKey": psk } vpn = s.post("{0}/vpnCredentials".format(zscaler_base_uri), headers=headers, data=json.dumps(vpnPayload)) if vpn.status_code == 200: vpns.append({"id": vpn.json()['id'], "type": "UFQDN"}) vpn_name = tunnels.get('vpn_name') if vpn_name is None: vpn_name = DEFAULT_VPN_NAME node_pillar = _create_minion_pillar(vpn_name, userfqdn, psk, tunnels['vpn_host1'], tunnels['vpn_host2']) __salt__['file.write']("{0}/zscaler/{1}.sls".format( PILLAR_DIRECTORY, node), args=node_pillar) zscaler_top += " \'{}\':\n".format(router_map[router][node]) # We use this matching because glob matching will conflict with the main top states zscaler_top += " - match: grain\n" zscaler_top += " - zscaler.{}\n".format(node) ret_string += "VPNs and pillar data successfully created for node {}\n".format( node) elif vpn.status_code == 409: zscaler_top += " \'id:{}\':\n".format( router_map[router][node]) zscaler_top += " - match: grain\n" zscaler_top += " - zscaler.{}\n".format(node) ret_string += "VPN already configured for node {0}, not re-writing pillar data, but keeping in top file.\n".format( node) else: ret_string += "Unhandled error adding VPN for node {0} not writing pillar data. Error code: {1}: {2}\n".format( node, vpn.status_code, vpn.json()) if len(vpns) > 0: locationPayload = {"name": router, "vpnCredentials": vpns} location = s.post("{0}/locations".format(zscaler_base_uri), headers=headers, data=json.dumps(locationPayload)) if location.status_code == 200: ret_string += "Location {0} added successfully.\n".format( router) elif location.status_code == 409: ret_string += "Location {0} already existed in Zscaler.\n".format( router) else: ret_string += "Unhandled error adding location {0}. Error code: {1}: {2}\n".format( router, location.status_code, location.json()) else: ret_string += "No new VPNs created, not attempting to add location {}".format( router) __salt__['file.write']("{0}/zscaler-top.sls".format(PILLAR_DIRECTORY), args=zscaler_top) return ret_string