def create_pool_object(self, name, desc, servers, pd_action, algo, ramp_time, limits, tenant_ref, cloud_ref): tenant, name = conv_utils.get_tenant_ref(name) # Added prefix for objects if self.prefix: name = self.prefix + '-' + name pool_obj = { 'name': name, 'description': desc, 'servers': servers, 'fail_action': pd_action, 'lb_algorithm': algo, 'cloud_ref': conv_utils.get_object_ref(cloud_ref, 'cloud') } if not tenant_ref == 'admin': tenant = tenant_ref pool_obj['tenant_ref'] = conv_utils.get_object_ref(tenant, 'tenant') if ramp_time: pool_obj['connection_ramp_duration'] = ramp_time if limits.get('connection_limit', 0) > 0: pool_obj['max_concurrent_connections_per_server'] = \ limits['connection_limit'] if limits.get('rate_limit', 0) > 0: pool_obj['max_conn_rate_per_server'] = { 'count': limits['rate_limit'] } return pool_obj
def create_sslkeyandcert(self, monitor_dict, f5_monitor, avi_config, tenant, input_dir, cloud_name): """ :param monitor_dict: :param f5_monitor: :param skipped: :param avi_config: :param tenant: :param input_dir: :param cloud_name: :param controller_version: :return: """ # Condition create sslkeyandcert. converted_objs = [] key_file_name = f5_monitor.get('key', None) cert_file_name = f5_monitor.get('cert', None) folder_path = input_dir + os.path.sep key = conv_utils.upload_file(folder_path + key_file_name) cert = conv_utils.upload_file(folder_path + cert_file_name) name = monitor_dict['name'] if not key or not cert: key, cert = conv_utils.create_self_signed_cert() name = monitor_dict['name'] + '-dummy' LOG.warning( 'Create self cerificate and key for : %s' % key_file_name) ssl_kc_obj = None if key and cert: cert = {"certificate": cert} ssl_kc_obj = { 'name': name, 'tenant_ref': conv_utils.get_object_ref(tenant, 'tenant'), 'key': key, 'certificate': cert, 'key_passphrase': '', 'type': 'SSL_CERTIFICATE_TYPE_VIRTUALSERVICE' } # Added condition for merging sslkeyandcert if ssl_kc_obj and 'dummy' not in ssl_kc_obj['name']: conv_utils.update_skip_duplicates( ssl_kc_obj, avi_config['SSLKeyAndCertificate'], 'key_cert', converted_objs, name, None) else: avi_config['SSLKeyAndCertificate'].append(ssl_kc_obj) ssl_key_cert_list = avi_config.get("SSLKeyAndCertificate", []) key_cert = [obj for obj in ssl_key_cert_list if (obj['name'] == name or obj['name'] == name + '-dummy' or name in obj.get("dup_of", []))] if key_cert: name = key_cert[0]['name'] ref = conv_utils.get_object_ref( name, "sslkeyandcertificate", tenant, cloud_name) monitor_dict["https_monitor"]['ssl_attributes'][ 'ssl_key_and_certificate_ref'] = ref LOG.info('Added new SSL key and certificate for %s' % name)
def get_monitor_refs(self, monitor_names, monitor_config_list, pool_name, tenant_ref): skipped_monitors = [] monitors = monitor_names.split(" ") monitor_refs = [] garbage_val = ["and", "all", "min", "of", "{", "}", "none"] for monitor in monitors: monitor = monitor.strip() if not monitor or monitor in garbage_val or \ monitor.isdigit(): continue if self.prefix: monitor = '%s-%s' % (self.prefix, monitor) tenant, monitor = conv_utils.get_tenant_ref(monitor) monitor_obj = [obj for obj in monitor_config_list if (obj["name"] == monitor or monitor in obj.get( "dup_of", []))] if monitor_obj: tenant = conv_utils.get_name_from_ref( monitor_obj[0]['tenant_ref']) monitor_refs.append(conv_utils.get_object_ref( monitor_obj[0]['name'], 'healthmonitor', tenant=tenant)) else: LOG.warning("Monitor not found: %s for pool %s" % (monitor, pool_name)) skipped_monitors.append(monitor) return skipped_monitors, monitor_refs
def convert_cookie(self, name, profile, skipped, tenant): method = profile.get('method', 'insert') if not method == 'insert': LOG.warn("Skipped cookie method not supported for profile '%s' " % name) conv_utils.add_status_row('persistence', 'cookie', name, final.STATUS_SKIPPED) return None #supported_attr = ["cookie-name", "defaults-from", "expiration", #"method"] ignore_lst = ['always-send'] parent_obj = super(PersistenceConfigConvV11, self) self.supported_attr += ignore_lst skipped += [ attr for attr in profile.keys() if attr not in self.supported_attr ] cookie_name = profile.get("cookie-name", name + ':cookie-name') timeout = profile.get("expiration", '1') timeout = parent_obj.convert_timeout(timeout) persist_profile = { "name": name, "app_cookie_persistence_profile": { "prst_hdr_name": cookie_name, "timeout": timeout }, "server_hm_down_recovery": "HM_DOWN_PICK_NEW_SERVER", "persistence_type": "PERSISTENCE_TYPE_APP_COOKIE", } persist_profile['tenant_ref'] = conv_utils.get_object_ref( tenant, 'tenant') return persist_profile
def convert_cookie(self, name, profile, skipped, tenant): method = profile.get('method', 'insert') if not method == 'insert': LOG.warn("Skipped cookie method not supported for profile '%s' " % name) conv_utils.add_status_row('persistence', 'cookie', name, final.STATUS_SKIPPED) return None #supported_attr = ["cookie-name", "defaults-from", "expiration", #"method"] ignore_lst = ['always-send'] parent_obj = super(PersistenceConfigConvV11, self) self.supported_attr += ignore_lst skipped += [attr for attr in profile.keys() if attr not in self.supported_attr] cookie_name = profile.get("cookie-name", name+':cookie-name') timeout = profile.get("expiration", '1') timeout = parent_obj.convert_timeout(timeout) persist_profile = { "name": name, "app_cookie_persistence_profile": { "prst_hdr_name": cookie_name, "timeout": timeout }, "server_hm_down_recovery": "HM_DOWN_PICK_NEW_SERVER", "persistence_type": "PERSISTENCE_TYPE_APP_COOKIE", } persist_profile['tenant_ref'] = conv_utils.get_object_ref( tenant, 'tenant') return persist_profile
def convert_for_pg(self, pg_dict, pool_obj, name, tenant, avi_config, cloud_ref): """ Creates a pool group object :param pg_dict: priority wise sorted dict of pools :param pool_obj: Converted f5 pool object :param name: name of the pool :param tenant: tenant name for tenant reference :param avi_config: Avi config to add temporary labels :return: """ pg_members = [] pools = [] for priority in pg_dict: priority_pool = copy.deepcopy(pool_obj) priority_pool['servers'] = pg_dict[priority] priority_pool_ref = '%s-%s' % (name, priority) # Added prefix for objects if self.prefix: priority_pool_ref = self.prefix + '-' + priority_pool_ref priority_pool['name'] = priority_pool_ref pools.append(priority_pool) if priority_pool_ref: member = { 'pool_ref': conv_utils.get_object_ref( priority_pool_ref, 'pool', tenant=tenant, cloud_name=cloud_ref) } pg_members.append(member) # Added prefix for objects if self.prefix: name = self.prefix + "-" + name pg_obj = { 'name': name, 'members': pg_members, 'cloud_ref': conv_utils.get_object_ref(cloud_ref, 'cloud') } pg_obj['tenant_ref'] = conv_utils.get_object_ref(tenant, 'tenant') converted_objs = { 'pools': pools, 'pg_obj': pg_obj } return converted_objs
def create_sslprofile(self, monitor_dict, f5_monitor, avi_config, tenant, cloud_name): """ :param monitor_dict: :param f5_monitor: :param skipped: :param avi_config: :param tenant: :param input_dir: :param cloud_name: :param controller_version: :return: """ # Condition to create ssl profile. converted_objs = [] cipher = f5_monitor.get('cipherlist', None) ssl_profile = dict() ssl_profile["accepted_versions"] = [ {"type": "SSL_VERSION_TLS1"}, {"type": "SSL_VERSION_TLS1_1"}, {"type": "SSL_VERSION_TLS1_2"} ] ssl_profile['name'] = '%s-%s' % (monitor_dict['name'], 'sslprofile') ssl_profile['tenant_ref'] = conv_utils.get_object_ref( tenant, 'tenant') ssl_profile['accepted_ciphers'] = cipher if self.object_merge_check: conv_utils.update_skip_duplicates( ssl_profile, avi_config['SSLProfile'], 'ssl_profile', converted_objs, ssl_profile['name'], None) else: avi_config['SSLProfile'].append(ssl_profile) sname = [sname for sname in avi_config['SSLProfile'] if (sname['name'] == ssl_profile['name'] or ssl_profile[ 'name'] in sname.get('dup_of', []))] ref = conv_utils.get_object_ref( sname[0]['name'], "sslprofile", tenant, cloud_name) monitor_dict["https_monitor"]['ssl_attributes'][ 'ssl_profile_ref'] = ref
def convert_ssl(self, name, profile, skipped, indirect, tenant): supported_attr = ["mode", 'defaults-from'] skipped += [attr for attr in profile.keys() if attr not in supported_attr] indirect.append("timeout") persist_profile = { "server_hm_down_recovery": "HM_DOWN_PICK_NEW_SERVER", "persistence_type": "PERSISTENCE_TYPE_TLS", "name": name } persist_profile['tenant_ref'] = conv_utils.get_object_ref( tenant, 'tenant') return persist_profile
def convert_ssl(self, name, profile, skipped, indirect, tenant): supported_attr = ["mode", 'defaults-from'] skipped += [ attr for attr in profile.keys() if attr not in supported_attr ] indirect.append("timeout") persist_profile = { "server_hm_down_recovery": "HM_DOWN_PICK_NEW_SERVER", "persistence_type": "PERSISTENCE_TYPE_TLS", "name": name } persist_profile['tenant_ref'] = conv_utils.get_object_ref( tenant, 'tenant') return persist_profile
def convert_source_addr(self, name, profile, skipped, tenant): supported_attr = self.supported_attr_conver skipped += [attr for attr in profile.keys() if attr not in supported_attr] timeout = profile.get("timeout", final.SOURCE_ADDR_TIMEOUT) if timeout > 0: timeout = int(timeout)/final.SEC_IN_MIN persist_profile = { "server_hm_down_recovery": "HM_DOWN_PICK_NEW_SERVER", "persistence_type": "PERSISTENCE_TYPE_CLIENT_IP_ADDRESS", "ip_persistence_profile": { "ip_persistent_timeout": timeout }, "name": name } persist_profile['tenant_ref'] = conv_utils.get_object_ref( tenant, 'tenant') return persist_profile
def convert_source_addr(self, name, profile, skipped, tenant): supported_attr = self.supported_attr_conver skipped += [ attr for attr in profile.keys() if attr not in supported_attr ] timeout = profile.get("timeout", final.SOURCE_ADDR_TIMEOUT) if timeout > 0: timeout = int(timeout) / final.SEC_IN_MIN persist_profile = { "server_hm_down_recovery": "HM_DOWN_PICK_NEW_SERVER", "persistence_type": "PERSISTENCE_TYPE_CLIENT_IP_ADDRESS", "ip_persistence_profile": { "ip_persistent_timeout": timeout }, "name": name } persist_profile['tenant_ref'] = conv_utils.get_object_ref( tenant, 'tenant') return persist_profile
def convert_cookie(self, name, profile, skipped, tenant): method = profile.get('cookie mode', 'insert') if not method == 'insert': LOG.warn("Skipped cookie method not supported for profile '%s' " % name) conv_utils.add_conv_status('persistence', 'cookie', name, 'skipped') return None #supported_attr = ["cookie name", "mode", "defaults from", "cookie mode", #"cookie hash offset", "cookie hash length", #"cookie expiration"] skipped += [ attr for attr in profile.keys() if attr not in self.supported_attr ] cookie_name = profile.get("cookie name", name + ':-cookie') if not cookie_name: LOG.error("Missing Required field cookie name in: %s", name) conv_utils.add_status_row('profile', 'persist-cookie', name, final.STATUS_SKIPPED) return None timeout = profile.get("cookie expiration", '1') if timeout == 'immediate': timeout = '0' parent_obj = super(PersistenceConfigConvV10, self) if 'd ' in timeout: timeout = timeout.replace('d ', ':') elif 'd' in timeout: timeout = timeout.replace('d', '') timeout = parent_obj.convert_timeout(timeout) persist_profile = { "name": name, "app_cookie_persistence_profile": { "prst_hdr_name": cookie_name, "timeout": timeout }, "server_hm_down_recovery": "HM_DOWN_PICK_NEW_SERVER", "persistence_type": "PERSISTENCE_TYPE_APP_COOKIE", } persist_profile['tenant_ref'] = conv_utils.get_object_ref( tenant, 'tenant') return persist_profile
def convert_cookie(self, name, profile, skipped, tenant): method = profile.get('cookie mode', 'insert') if not method == 'insert': LOG.warn("Skipped cookie method not supported for profile '%s' " % name) conv_utils.add_conv_status('persistence', 'cookie', name, 'skipped') return None #supported_attr = ["cookie name", "mode", "defaults from", "cookie mode", #"cookie hash offset", "cookie hash length", #"cookie expiration"] skipped += [attr for attr in profile.keys() if attr not in self.supported_attr] cookie_name = profile.get("cookie name", name+':-cookie') if not cookie_name: LOG.error("Missing Required field cookie name in: %s", name) conv_utils.add_status_row('profile', 'persist-cookie', name, final.STATUS_SKIPPED) return None timeout = profile.get("cookie expiration", '1') if timeout == 'immediate': timeout = '0' parent_obj = super(PersistenceConfigConvV10, self) if 'd ' in timeout: timeout = timeout.replace('d ', ':') elif 'd' in timeout: timeout = timeout.replace('d', '') timeout = parent_obj.convert_timeout(timeout) persist_profile = { "name": name, "app_cookie_persistence_profile": { "prst_hdr_name": cookie_name, "timeout": timeout }, "server_hm_down_recovery": "HM_DOWN_PICK_NEW_SERVER", "persistence_type": "PERSISTENCE_TYPE_APP_COOKIE", } persist_profile['tenant_ref'] = conv_utils.get_object_ref( tenant, 'tenant') return persist_profile
def convert_vs(self, vs_name, f5_vs, vs_state, avi_config, snat_config, user_ignore, tenant_ref, cloud_name, controller_version): tenant, vs_name = conv_utils.get_tenant_ref(vs_name) if not tenant_ref == 'admin': tenant = tenant_ref hash_profiles = avi_config.get('hash_algorithm', []) description = f5_vs.get("description", None) skipped = [key for key in f5_vs.keys() if key not in self.supported_attr] enabled = (vs_state == 'enable') if enabled: enabled = False if "disabled" in f5_vs.keys() else True profiles = f5_vs.get("profiles", {}) ssl_vs, ssl_pool = conv_utils.get_vs_ssl_profiles(profiles, avi_config, self.prefix) oc_prof = False for prof in profiles: if prof in avi_config.get('OneConnect', []): oc_prof = True app_prof, f_host, realm, policy_set = conv_utils.get_vs_app_profiles( profiles, avi_config, tenant, self.prefix, oc_prof) if not app_prof: LOG.warning('Profile type not supported by Avi Skipping VS : %s' % vs_name) conv_utils.add_status_row('virtual', None, vs_name, final.STATUS_SKIPPED) return None ntwk_prof = conv_utils.get_vs_ntwk_profiles(profiles, avi_config, self.prefix) # If one connect profile is not assigned to f5 VS and avi app profile # assigned to VS has connection_multiplexing_enabled value True then # clone profile and make connection_multiplexing_enabled as False pool_ref = f5_vs.get("pool", None) app_prof_obj = [obj for obj in avi_config['ApplicationProfile'] if obj['name'] == app_prof[0]] cme = True app_prof_type = None if app_prof_obj: app_prof_type = app_prof_obj[0].get('type') if app_prof_type == 'APPLICATION_PROFILE_TYPE_HTTP': cme = app_prof_obj[0]['http_profile'].get( 'connection_multiplexing_enabled', False) if not (cme or oc_prof): # Check if already cloned profile present app_prof_cmd = [obj for obj in avi_config['ApplicationProfile'] if obj['name'] == '%s-cmd' % app_prof[0]] if app_prof_cmd: app_prof[0] = app_prof_cmd[0]['name'] else: app_prof_cmd = copy.deepcopy(app_prof_obj[0]) app_prof_cmd['name'] = '%s-cmd' % app_prof_cmd['name'] app_prof_cmd['connection_multiplexing_enabled'] = False avi_config['ApplicationProfile'].append(app_prof_cmd) app_prof[0] = app_prof_cmd['name'] enable_ssl = False if ssl_vs: enable_ssl = True destination = f5_vs.get("destination", None) d_tenant, destination = conv_utils.get_tenant_ref(destination) # if destination is not present then skip vs. services_obj, ip_addr, vsvip_ref, vrf_ref = conv_utils.get_service_obj( destination, avi_config, enable_ssl, controller_version, tenant, cloud_name, self.prefix, vs_name) # Added Check for if port is no digit skip vs. if not services_obj and not ip_addr and not vsvip_ref: LOG.debug("Skipped: Virtualservice: %s" % vs_name) conv_utils.add_status_row('virtual', None, vs_name, final.STATUS_SKIPPED) return is_pool_group = False if pool_ref: p_tenant, pool_ref = conv_utils.get_tenant_ref(pool_ref) # TODO: need to revisit after shared pool support implemented pool_ref, is_pool_group = conv_utils.clone_pool_if_shared( pool_ref, avi_config, vs_name, tenant, p_tenant, cloud_name=cloud_name, prefix=self.prefix) if ssl_pool: if is_pool_group: conv_utils.add_ssl_to_pool_group(avi_config, pool_ref, ssl_pool[0], tenant) conv_utils.remove_http_mon_from_pool_group( avi_config, pool_ref, tenant) else: conv_utils.add_ssl_to_pool(avi_config['Pool'], pool_ref, ssl_pool[0], tenant) conv_utils.remove_http_mon_from_pool( avi_config, pool_ref, tenant) else: # TODO Remove this once controller support this scenario. if is_pool_group: conv_utils.remove_https_mon_from_pool_group( avi_config, pool_ref, tenant) else: conv_utils.remove_https_mon_from_pool( avi_config, pool_ref, tenant) persist_ref = self.get_persist_ref(f5_vs) if persist_ref: avi_persistence = avi_config.get( 'ApplicationPersistenceProfile', []) if is_pool_group: pool_updated = conv_utils.update_pool_group_for_persist( avi_config, pool_ref, persist_ref, hash_profiles, avi_persistence, tenant) else: pool_updated = conv_utils.update_pool_for_persist( avi_config['Pool'], pool_ref, persist_ref, hash_profiles, avi_persistence, tenant) if not pool_updated: skipped.append("persist") LOG.warning( "persist profile %s not found for vs:%s" % (persist_ref, vs_name)) if f_host: conv_utils.update_pool_for_fallback( f_host, avi_config['Pool'], pool_ref) ip_addr = ip_addr.strip() matches = re.findall('^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$', ip_addr) if not matches or ip_addr == '0.0.0.0': LOG.warning('Avi does not support IPv6 : %s. ' 'Generated random ipv4 for vs: %s' % (ip_addr, vs_name)) vs_name += '-needs-ipv6-ip' ip_addr = ".".join(map(str, ( random.randint(0, 255) for _ in range(4)))) # VIP object for virtual service vip = { 'ip_address': { 'addr': ip_addr, 'type': 'V4' }, 'vip_id': 0 } vs_obj = { 'name': vs_name, 'description': description, 'type': 'VS_TYPE_NORMAL', 'enabled': enabled, 'cloud_ref': conv_utils.get_object_ref( cloud_name, 'cloud', tenant=tenant), 'services': services_obj, 'application_profile_ref': app_prof[0], 'vs_datascripts': [], 'tenant_ref': conv_utils.get_object_ref(tenant, 'tenant') } if vrf_ref: vs_obj['vrf_context_ref'] = vrf_ref if parse_version(controller_version) >= parse_version('17.1'): vs_obj['vip'] = [vip] vs_obj['vsvip_ref'] = vsvip_ref else: vs_obj['ip_address'] = vip['ip_address'] vs_ds_rules = None if 'rules' in f5_vs: if isinstance(f5_vs['rules'], basestring): vs_ds_rules = [f5_vs['rules']] else: vs_ds_rules = f5_vs['rules'].keys() for index, rule in enumerate(vs_ds_rules): # converted _sys_https_redirect data script to rule in # http policy if rule == '_sys_https_redirect': # Added prefix for objects if self.prefix: policy_name = self.prefix + '-' + rule + '-' + vs_name else: policy_name = rule + '-' + vs_name policy = { "name": policy_name, "http_request_policy": { "rules": [ { "index": 1, "redirect_action": { "keep_query": True, "status_code": "HTTP_REDIRECT_STATUS_CODE_302", "protocol": "HTTPS", "port": 443 }, "enable": True, "name": policy_name + "-Redirect", "match": { "protocol": { "protocols": "HTTP", "match_criteria": "IS_IN" } } } ] }, 'tenant_ref': conv_utils.get_object_ref(tenant, 'tenant'), "is_internal_policy": False } http_policies = { 'index': 11, 'http_policy_set_ref': conv_utils.get_object_ref(policy_name, 'httppolicyset', tenant=tenant) } vs_obj['http_policies'] = [] vs_obj['http_policies'].append(http_policies) avi_config['HTTPPolicySet'].append(policy) if is_pool_group: vs_obj['pool_group_ref'] = conv_utils.get_object_ref( pool_ref, 'poolgroup', tenant=tenant, cloud_name=cloud_name) elif pool_ref: vs_obj['pool_ref'] = conv_utils.get_object_ref( pool_ref, 'pool', tenant=tenant, cloud_name=cloud_name) self.convert_translate_port(avi_config, f5_vs, app_prof[0], pool_ref, skipped) conn_limit = int(f5_vs.get(self.connection_limit, '0')) if conn_limit > 0: vs_obj["performance_limits"] = { "max_concurrent_connections": conn_limit } rate_limit = int(f5_vs.get('rate-limit', '0')) if rate_limit > 0: vs_obj["connections_rate_limit"] = { "count": rate_limit } if realm: vs_obj['client_auth'] = realm if policy_set: vs_obj['http_policies'] = policy_set source = f5_vs.get('source', '0.0.0.0/0') if '%' in source: s_parts = source.split('%') elif '/' in source: s_parts = source.split('/') else: s_parts = [source] if not s_parts[0] == '0.0.0.0': parts = source.split('/') if '%' in parts[0]: parts[0] = parts[0].split('%')[0] mask = 24 if len(parts) > 1: mask = parts[1] policy_name = ('vs-%s-ns' % vs_name) policy = conv_utils.create_network_security_rule( policy_name, parts[0], mask, tenant) avi_config['NetworkSecurityPolicy'].append(policy) vs_obj['network_security_policy_ref'] = conv_utils.get_object_ref( policy_name, 'networksecuritypolicy', tenant=tenant) # Checking snat conversion flag and snat info for creating snat ip object snat = f5_vs.get("source-address-translation", {}) snat_pool_name = snat.get("pool", f5_vs.get("snatpool", None)) snat_pool = snat_config.pop(snat_pool_name, None) if snat_pool: if self.con_snatpool: LOG.debug("Converting the snat as input flag and snat information is set") snat_list = conv_utils.get_snat_list_for_vs(snat_pool) if len(snat_list) > 32: vs_obj["snat_ip"] = snat_list[0:32] LOG.warning( 'Ignore the snat IPs, its count is beyond 32 for vs : %s' % vs_name) else: vs_obj["snat_ip"] = snat_list conv_status = {'status': final.STATUS_SUCCESSFUL} message = 'Mapped indirectly to VS -> SNAT IP Address' conv_utils.add_conv_status('snatpool', '', snat_pool_name, conv_status, message) else: LOG.debug("Skipped: snat conversion as input flag is not set for vs : %s" % vs_name) skipped.append("source-address-translation" if f5_vs.get( "source-address-translation") else "snatpool" if f5_vs.get( "snatpool") else None) if ntwk_prof: vs_obj['network_profile_ref'] = ntwk_prof[0] if enable_ssl: vs_obj['ssl_profile_ref'] = ssl_vs[0]["profile"] if ssl_vs[0]["cert"]: vs_obj['ssl_key_and_certificate_refs'] = [ssl_vs[0]["cert"]] if ssl_vs[0]["pki"] and app_prof[0] != "http": app_profiles = [obj for obj in avi_config["ApplicationProfile"] if obj['name'] == conv_utils.get_name_from_ref(app_prof[0])] if app_profiles[0]["type"] == \ 'APPLICATION_PROFILE_TYPE_HTTP': app_profiles[0]["http_profile"][ "ssl_client_certificate_mode"] = ssl_vs[0]["mode"] app_profiles[0]["http_profile"]["pki_profile_ref"] = \ ssl_vs[0]["pki"] # Added code to skipped L4 VS if pool or pool group not present if vs_obj['application_profile_ref']: app_profile_name = \ str(vs_obj['application_profile_ref']).split( '&name=')[1] application_profile_obj = \ [obj for obj in avi_config['ApplicationProfile'] if obj['name'] == app_profile_name] if application_profile_obj and application_profile_obj[0]['type'] \ == 'APPLICATION_PROFILE_TYPE_L4': if not 'pool_ref' and not 'pool_group_ref' in vs_obj: LOG.debug("Failed to convert L4 VS dont have " "pool or pool group ref: %s" % vs_name) conv_utils.add_status_row('virtual', None, vs_name, final.STATUS_SKIPPED) return for attr in self.ignore_for_value: ignore_val = self.ignore_for_value[attr] actual_val = f5_vs.get(attr, None) if not actual_val: continue if isinstance(ignore_val, str) and actual_val == ignore_val: skipped.remove(attr) elif isinstance(ignore_val, list) and actual_val in ignore_val: skipped.remove(attr) conv_status = dict() conv_status['user_ignore'] = [val for val in skipped if val in user_ignore] if vs_ds_rules: skipped_rules = [rule for rule in vs_ds_rules if rule != '_sys_https_redirect'] if skipped_rules: skipped.append('rules: %s' % skipped_rules) conv_status['na_list'] = [val for val in skipped if val in self.vs_na_attr] skipped = [attr for attr in skipped if attr not in self.vs_na_attr] skipped = [attr for attr in skipped if attr not in user_ignore] conv_status['skipped'] = skipped status = final.STATUS_SUCCESSFUL if skipped: status = final.STATUS_PARTIAL conv_status['status'] = status conv_utils.add_conv_status('virtual', None, vs_name, conv_status, vs_obj) return vs_obj
def convert_monitor(self, f5_monitor, key, monitor_config, input_dir, user_ignore, tenant_ref, avi_config, cloud_name, controller_version): monitor_type, name = self.get_name_type(f5_monitor, key) skipped = [val for val in f5_monitor.keys() if val not in self.supported_attributes] indirect = copy.deepcopy(self.indirect_mappings) timeout = int(f5_monitor.get("timeout", conv_const.DEFAULT_TIMEOUT)) interval = int(f5_monitor.get("interval", conv_const.DEFAULT_INTERVAL)) time_until_up = int(f5_monitor.get(self.tup, conv_const.DEFAULT_TIME_UNTIL_UP)) # Fixed Successful interval and failed checks failed_checks = int(timeout/interval) successful_checks = conv_const.DEFAULT_FAILED_CHECKS if time_until_up > 0: successful_checks = int(time_until_up/interval) successful_checks = 1 \ if successful_checks == 0 else successful_checks description = f5_monitor.get("description", None) monitor_dict = dict() tenant, name = conv_utils.get_tenant_ref(name) # Added prefix for objects if self.prefix: name = self.prefix + '-' + name if tenant_ref != 'admin': tenant = tenant_ref monitor_dict['tenant_ref'] = conv_utils.get_object_ref(tenant, 'tenant') monitor_dict["name"] = name monitor_dict["receive_timeout"] = interval-1 monitor_dict["failed_checks"] = failed_checks monitor_dict["send_interval"] = interval monitor_dict["successful_checks"] = successful_checks if description: monitor_dict["description"] = description # transparent : Only flag if destination or port are set, else ignore transparent = f5_monitor.get("transparent", 'disabled') transparent = False if transparent == 'disabled' else True destination = f5_monitor.get(self.dest_key, '*:*') if destination in ['*', '*:0']: destination = '*:*' f5_monitor[self.dest_key] = destination if not transparent or destination == '*:*': if 'transparent' in skipped: indirect.append('transparent') ignore_for_defaults = {} defaults = self.get_default_monitor(monitor_type, monitor_config) if defaults: ignore_for_defaults = copy.deepcopy(defaults) ignore_for_defaults.update(self.ignore) u_ignore = [] na_list = [] if monitor_type == "http": u_ignore = user_ignore.get("http", []) na_list = self.na_http skipped = self.convert_http(monitor_dict, f5_monitor, skipped) elif monitor_type == "https": na_list = self.na_https u_ignore = user_ignore.get("https", []) skipped = self.convert_https( monitor_dict, f5_monitor, skipped, avi_config, tenant_ref, input_dir, cloud_name, controller_version) elif monitor_type == "dns": na_list = self.na_dns u_ignore = user_ignore.get("dns", []) if f5_monitor.get('qname', None) and (not f5_monitor.get( 'qname') == 'none'): skipped = self.convert_dns(monitor_dict, f5_monitor, skipped) ignore_for_defaults.update({'qtype': 'a'}) else: LOG.warning('No value for mandatory field query_name, skipped ' 'DNS Monitor %s' % key) conv_utils.add_status_row('monitor', monitor_type, name, conv_const.STATUS_SKIPPED) return None elif monitor_type in ["tcp", "tcp_half_open", "tcp-half-open"]: na_list = self.na_tcp u_ignore = user_ignore.get("tcp", []) skipped = self.convert_tcp(monitor_dict, f5_monitor, skipped, monitor_type) elif monitor_type == "udp": na_list = self.na_udp u_ignore = user_ignore.get("udp", []) skipped = self.convert_udp(monitor_dict, f5_monitor, skipped) elif monitor_type in ["icmp", "gateway-icmp", "gateway_icmp"]: na_list = self.na_icmp u_ignore = user_ignore.get("icmp", []) u_ignore += user_ignore.get("gateway-icmp", []) u_ignore += user_ignore.get("gateway_icmp", []) skipped = self.convert_icmp(monitor_dict, f5_monitor, skipped) elif monitor_type == "external": na_list = self.na_external u_ignore = user_ignore.get("external", []) skipped = self.convert_external(monitor_dict, f5_monitor, skipped, input_dir, name) if monitor_dict.get('error', False): return [] conv_status = conv_utils.get_conv_status( skipped, indirect, ignore_for_defaults, f5_monitor, u_ignore, na_list) conv_utils.add_conv_status('monitor', monitor_type, name, conv_status, monitor_dict) return monitor_dict
def convert(self, f5_config, avi_config, user_ignore, tenant_ref, cloud_name): pool_list = [] pool_config = f5_config.get('pool', {}) user_ignore = user_ignore.get('pool', {}) avi_config['VrfContext'] = [] avi_config['PoolGroup'] = [] avi_config['PriorityLabels'] = {} # Initialize Global vrf context object vrf_context = { "name": 'global', "system_default": True, "tenant_ref": conv_utils.get_object_ref(tenant_ref, 'tenant'), "cloud_ref": conv_utils.get_object_ref(cloud_name, 'cloud'), "static_routes": [] } avi_config['VrfContext'].append(vrf_context) for pool_name in pool_config.keys(): LOG.debug("Converting Pool: %s" % pool_name) f5_pool = pool_config[pool_name] if not f5_pool: LOG.debug("Empty pool skipped for conversion :%s" % pool_name) conv_utils.add_status_row('pool', None, pool_name, conv_const.STATUS_SKIPPED) continue if 'gateway-failsafe-device' in f5_pool: LOG.debug("Not supported gateway-failsafe-device, pool skipped " "for conversion :%s" % pool_name) conv_utils.add_status_row('pool', None, pool_name, conv_const.STATUS_SKIPPED) continue try: converted_objs = self.convert_pool( pool_name, f5_config, avi_config, user_ignore, tenant_ref, cloud_name) pool_list += converted_objs['pools'] if 'pg_obj' in converted_objs: avi_config['PoolGroup'].append(converted_objs['pg_obj']) LOG.debug("Conversion successful for Pool: %s" % pool_name) except: LOG.error("Failed to convert pool: %s" % pool_name, exc_info=True) conv_utils.add_status_row('pool', None, pool_name, conv_const.STATUS_ERROR) # labels_dict = avi_config.pop('PriorityLabels', None) # if labels_dict: # for tenant in labels_dict: # labels = labels_dict[tenant] # if not tenant_ref == 'admin': # tenant = tenant_ref # labels = list(set(labels)) # labels = map(int, labels) # labels.sort(reverse=True) # labels = map(str, labels) # priority_labels = { # "name": "numeric_priority_labels", # "equivalent_labels": [ # { # "labels": labels # } # ], # 'tenant_ref': conv_utils.get_object_ref(tenant, 'tenant') # } # avi_config['PriorityLabels'] = [priority_labels] avi_config['Pool'] = pool_list LOG.debug("Converted %s pools" % len(pool_list)) f5_config.pop('pool', {})
def convert_vs(self, vs_name, f5_vs, vs_state, avi_config, snat_config, user_ignore, tenant_ref, cloud_name, controller_version): tenant, vs_name = conv_utils.get_tenant_ref(vs_name) if not tenant_ref == 'admin': tenant = tenant_ref hash_profiles = avi_config.get('hash_algorithm', []) description = f5_vs.get("description", None) skipped = [ key for key in f5_vs.keys() if key not in self.supported_attr ] enabled = (vs_state == 'enable') if enabled: enabled = False if "disabled" in f5_vs.keys() else True profiles = f5_vs.get("profiles", {}) ssl_vs, ssl_pool = conv_utils.get_vs_ssl_profiles( profiles, avi_config, self.prefix) oc_prof = False for prof in profiles: if prof in avi_config.get('OneConnect', []): oc_prof = True app_prof, f_host, realm, policy_set = conv_utils.get_vs_app_profiles( profiles, avi_config, tenant, self.prefix, oc_prof) if not app_prof: LOG.warning('Profile type not supported by Avi Skipping VS : %s' % vs_name) conv_utils.add_status_row('virtual', None, vs_name, final.STATUS_SKIPPED) return None ntwk_prof = conv_utils.get_vs_ntwk_profiles(profiles, avi_config, self.prefix) # If one connect profile is not assigned to f5 VS and avi app profile # assigned to VS has connection_multiplexing_enabled value True then # clone profile and make connection_multiplexing_enabled as False pool_ref = f5_vs.get("pool", None) app_prof_obj = [ obj for obj in avi_config['ApplicationProfile'] if obj['name'] == app_prof[0] ] cme = True app_prof_type = None if app_prof_obj: app_prof_type = app_prof_obj[0].get('type') if app_prof_type == 'APPLICATION_PROFILE_TYPE_HTTP': cme = app_prof_obj[0]['http_profile'].get( 'connection_multiplexing_enabled', False) if not (cme or oc_prof): # Check if already cloned profile present app_prof_cmd = [ obj for obj in avi_config['ApplicationProfile'] if obj['name'] == '%s-cmd' % app_prof[0] ] if app_prof_cmd: app_prof[0] = app_prof_cmd[0]['name'] else: app_prof_cmd = copy.deepcopy(app_prof_obj[0]) app_prof_cmd['name'] = '%s-cmd' % app_prof_cmd['name'] app_prof_cmd['connection_multiplexing_enabled'] = False avi_config['ApplicationProfile'].append(app_prof_cmd) app_prof[0] = app_prof_cmd['name'] enable_ssl = False if ssl_vs: enable_ssl = True destination = f5_vs.get("destination", None) d_tenant, destination = conv_utils.get_tenant_ref(destination) # if destination is not present then skip vs. services_obj, ip_addr, vsvip_ref, vrf_ref = conv_utils.get_service_obj( destination, avi_config, enable_ssl, controller_version, tenant, cloud_name, self.prefix, vs_name) # Added Check for if port is no digit skip vs. if not services_obj and not ip_addr and not vsvip_ref: LOG.debug("Skipped: Virtualservice: %s" % vs_name) conv_utils.add_status_row('virtual', None, vs_name, final.STATUS_SKIPPED) return is_pool_group = False if pool_ref: p_tenant, pool_ref = conv_utils.get_tenant_ref(pool_ref) # TODO: need to revisit after shared pool support implemented pool_ref, is_pool_group = conv_utils.clone_pool_if_shared( pool_ref, avi_config, vs_name, tenant, p_tenant, cloud_name=cloud_name, prefix=self.prefix) if ssl_pool: if is_pool_group: conv_utils.add_ssl_to_pool_group(avi_config, pool_ref, ssl_pool[0], tenant) conv_utils.remove_http_mon_from_pool_group( avi_config, pool_ref, tenant) else: conv_utils.add_ssl_to_pool(avi_config['Pool'], pool_ref, ssl_pool[0], tenant) conv_utils.remove_http_mon_from_pool( avi_config, pool_ref, tenant) else: # TODO Remove this once controller support this scenario. if is_pool_group: conv_utils.remove_https_mon_from_pool_group( avi_config, pool_ref, tenant) else: conv_utils.remove_https_mon_from_pool( avi_config, pool_ref, tenant) persist_ref = self.get_persist_ref(f5_vs) if persist_ref: avi_persistence = avi_config.get( 'ApplicationPersistenceProfile', []) if is_pool_group: pool_updated = conv_utils.update_pool_group_for_persist( avi_config, pool_ref, persist_ref, hash_profiles, avi_persistence, tenant) else: pool_updated = conv_utils.update_pool_for_persist( avi_config['Pool'], pool_ref, persist_ref, hash_profiles, avi_persistence, tenant) if not pool_updated: skipped.append("persist") LOG.warning("persist profile %s not found for vs:%s" % (persist_ref, vs_name)) if f_host: conv_utils.update_pool_for_fallback(f_host, avi_config['Pool'], pool_ref) ip_addr = ip_addr.strip() matches = re.findall('^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$', ip_addr) if not matches or ip_addr == '0.0.0.0': LOG.warning('Avi does not support IPv6 : %s. ' 'Generated random ipv4 for vs: %s' % (ip_addr, vs_name)) vs_name += '-needs-ipv6-ip' ip_addr = ".".join( map(str, (random.randint(0, 255) for _ in range(4)))) # VIP object for virtual service vip = {'ip_address': {'addr': ip_addr, 'type': 'V4'}, 'vip_id': 0} vs_obj = { 'name': vs_name, 'description': description, 'type': 'VS_TYPE_NORMAL', 'enabled': enabled, 'cloud_ref': conv_utils.get_object_ref(cloud_name, 'cloud', tenant=tenant), 'services': services_obj, 'application_profile_ref': app_prof[0], 'vs_datascripts': [], 'tenant_ref': conv_utils.get_object_ref(tenant, 'tenant') } if vrf_ref: vs_obj['vrf_context_ref'] = vrf_ref if parse_version(controller_version) >= parse_version('17.1'): vs_obj['vip'] = [vip] vs_obj['vsvip_ref'] = vsvip_ref else: vs_obj['ip_address'] = vip['ip_address'] vs_ds_rules = None if 'rules' in f5_vs: if isinstance(f5_vs['rules'], basestring): vs_ds_rules = [f5_vs['rules']] else: vs_ds_rules = f5_vs['rules'].keys() for index, rule in enumerate(vs_ds_rules): # converted _sys_https_redirect data script to rule in # http policy if rule == '_sys_https_redirect': # Added prefix for objects if self.prefix: policy_name = self.prefix + '-' + rule + '-' + vs_name else: policy_name = rule + '-' + vs_name policy = { "name": policy_name, "http_request_policy": { "rules": [{ "index": 1, "redirect_action": { "keep_query": True, "status_code": "HTTP_REDIRECT_STATUS_CODE_302", "protocol": "HTTPS", "port": 443 }, "enable": True, "name": policy_name + "-Redirect", "match": { "protocol": { "protocols": "HTTP", "match_criteria": "IS_IN" } } }] }, 'tenant_ref': conv_utils.get_object_ref(tenant, 'tenant'), "is_internal_policy": False } http_policies = { 'index': 11, 'http_policy_set_ref': conv_utils.get_object_ref(policy_name, 'httppolicyset', tenant=tenant) } vs_obj['http_policies'] = [] vs_obj['http_policies'].append(http_policies) avi_config['HTTPPolicySet'].append(policy) if is_pool_group: vs_obj['pool_group_ref'] = conv_utils.get_object_ref( pool_ref, 'poolgroup', tenant=tenant, cloud_name=cloud_name) elif pool_ref: vs_obj['pool_ref'] = conv_utils.get_object_ref( pool_ref, 'pool', tenant=tenant, cloud_name=cloud_name) self.convert_translate_port(avi_config, f5_vs, app_prof[0], pool_ref, skipped) conn_limit = int(f5_vs.get(self.connection_limit, '0')) if conn_limit > 0: vs_obj["performance_limits"] = { "max_concurrent_connections": conn_limit } rate_limit = int(f5_vs.get('rate-limit', '0')) if rate_limit > 0: vs_obj["connections_rate_limit"] = {"count": rate_limit} if realm: vs_obj['client_auth'] = realm if policy_set: vs_obj['http_policies'] = policy_set source = f5_vs.get('source', '0.0.0.0/0') if '%' in source: s_parts = source.split('%') elif '/' in source: s_parts = source.split('/') else: s_parts = [source] if not s_parts[0] == '0.0.0.0': parts = source.split('/') if '%' in parts[0]: parts[0] = parts[0].split('%')[0] mask = 24 if len(parts) > 1: mask = parts[1] policy_name = ('vs-%s-ns' % vs_name) policy = conv_utils.create_network_security_rule( policy_name, parts[0], mask, tenant) avi_config['NetworkSecurityPolicy'].append(policy) vs_obj['network_security_policy_ref'] = conv_utils.get_object_ref( policy_name, 'networksecuritypolicy', tenant=tenant) # Checking snat conversion flag and snat info for creating snat ip object snat = f5_vs.get("source-address-translation", {}) snat_pool_name = snat.get("pool", f5_vs.get("snatpool", None)) snat_pool = snat_config.pop(snat_pool_name, None) if snat_pool: if self.con_snatpool: LOG.debug( "Converting the snat as input flag and snat information is set" ) snat_list = conv_utils.get_snat_list_for_vs(snat_pool) if len(snat_list) > 32: vs_obj["snat_ip"] = snat_list[0:32] LOG.warning( 'Ignore the snat IPs, its count is beyond 32 for vs : %s' % vs_name) else: vs_obj["snat_ip"] = snat_list conv_status = {'status': final.STATUS_SUCCESSFUL} message = 'Mapped indirectly to VS -> SNAT IP Address' conv_utils.add_conv_status('snatpool', '', snat_pool_name, conv_status, message) else: LOG.debug( "Skipped: snat conversion as input flag is not set for vs : %s" % vs_name) skipped.append("source-address-translation" if f5_vs.get( "source-address-translation") else "snatpool" if f5_vs. get("snatpool") else None) if ntwk_prof: vs_obj['network_profile_ref'] = ntwk_prof[0] if enable_ssl: vs_obj['ssl_profile_ref'] = ssl_vs[0]["profile"] if ssl_vs[0]["cert"]: vs_obj['ssl_key_and_certificate_refs'] = [ssl_vs[0]["cert"]] if ssl_vs[0]["pki"] and app_prof[0] != "http": app_profiles = [ obj for obj in avi_config["ApplicationProfile"] if obj['name'] == conv_utils.get_name_from_ref(app_prof[0]) ] if app_profiles[0]["type"] == \ 'APPLICATION_PROFILE_TYPE_HTTP': app_profiles[0]["http_profile"][ "ssl_client_certificate_mode"] = ssl_vs[0]["mode"] app_profiles[0]["http_profile"]["pki_profile_ref"] = \ ssl_vs[0]["pki"] # Added code to skipped L4 VS if pool or pool group not present if vs_obj['application_profile_ref']: app_profile_name = \ str(vs_obj['application_profile_ref']).split( '&name=')[1] application_profile_obj = \ [obj for obj in avi_config['ApplicationProfile'] if obj['name'] == app_profile_name] if application_profile_obj and application_profile_obj[0]['type'] \ == 'APPLICATION_PROFILE_TYPE_L4': if not 'pool_ref' and not 'pool_group_ref' in vs_obj: LOG.debug("Failed to convert L4 VS dont have " "pool or pool group ref: %s" % vs_name) conv_utils.add_status_row('virtual', None, vs_name, final.STATUS_SKIPPED) return for attr in self.ignore_for_value: ignore_val = self.ignore_for_value[attr] actual_val = f5_vs.get(attr, None) if not actual_val: continue if isinstance(ignore_val, str) and actual_val == ignore_val: skipped.remove(attr) elif isinstance(ignore_val, list) and actual_val in ignore_val: skipped.remove(attr) conv_status = dict() conv_status['user_ignore'] = [ val for val in skipped if val in user_ignore ] if vs_ds_rules: skipped_rules = [ rule for rule in vs_ds_rules if rule != '_sys_https_redirect' ] if skipped_rules: skipped.append('rules: %s' % skipped_rules) conv_status['na_list'] = [ val for val in skipped if val in self.vs_na_attr ] skipped = [attr for attr in skipped if attr not in self.vs_na_attr] skipped = [attr for attr in skipped if attr not in user_ignore] conv_status['skipped'] = skipped status = final.STATUS_SUCCESSFUL if skipped: status = final.STATUS_PARTIAL conv_status['status'] = status conv_utils.add_conv_status('virtual', None, vs_name, conv_status, vs_obj) return vs_obj