Example #1
0
    def convert(self, f5_config, avi_config, vs_state, user_ignore, tenant,
                cloud_name, controller_version):
        f5_snat_pools = f5_config.get("snatpool", {})
        vs_config = f5_config.get("virtual", {})
        avi_config['VirtualService'] = []
        avi_config['VSDataScriptSet'] = []
        avi_config['NetworkSecurityPolicy'] = []
        avi_config['VsVip'] = []

        for vs_name in vs_config.keys():
            try:
                LOG.debug("Converting VS: %s" % vs_name)
                f5_vs = vs_config[vs_name]
                vs_type = [key for key in f5_vs.keys()
                           if key in self.unsupported_types]
                if vs_type:
                    LOG.warn("VS type: %s not supported by Avi skipped VS: %s" %
                             (vs_type, vs_name))
                    conv_utils.add_status_row('virtual', None, vs_name,
                                              final.STATUS_SKIPPED)
                    continue
                # Added prefix for objects
                if self.prefix:
                    vs_name = self.prefix + '-' + vs_name
                vs_obj = self.convert_vs(vs_name, f5_vs, vs_state, avi_config,
                                         f5_snat_pools, user_ignore, tenant,
                                         cloud_name, controller_version)
                if vs_obj:
                    avi_config['VirtualService'].append(vs_obj)
                    LOG.debug("Conversion successful for VS: %s" % vs_name)
            except:
                LOG.error("Failed to convert VS: %s" % vs_name, exc_info=True)

        LOG.debug("Converted %s VS" % len(avi_config['VirtualService']))
        f5_config.pop("virtual", {})
Example #2
0
 def update_conv_status_for_error(self, name, persist_mode, key):
     if name:
         conv_utils.add_status_row("profile", 'persist', name,
                                   final.STATUS_ERROR)
     else:
         conv_utils.add_status_row("profile", 'persist', key,
                                   final.STATUS_ERROR)
Example #3
0
 def update_conv_status_for_error(self, name, persist_mode, key):
     if name:
         conv_utils.add_status_row("profile", 'persist', name,
                                   final.STATUS_ERROR)
     else:
         conv_utils.add_status_row("profile", 'persist', key,
                                   final.STATUS_ERROR)
Example #4
0
    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
Example #5
0
    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
Example #6
0
 def convert(self, f5_config, avi_config, input_dir, user_ignore, tenant,
             cloud_name, controller_version):
     LOG.debug("Converting health monitors")
     converted_objs = []
     m_user_ignore = user_ignore.get('monitor', {})
     monitor_config = f5_config.pop("monitor", {})
     for key in monitor_config.keys():
         f5_monitor = monitor_config[key]
         if not f5_monitor:
             if " " in key:
                 m_type, name = key.split(" ")
             else:
                 m_type = None
                 name = key
             conv_utils.add_status_row('monitor', m_type, name,
                                       conv_const.STATUS_SKIPPED)
             LOG.warn("Empty config for monitor: %s " % name)
             continue
         f5_monitor = self.get_defaults(monitor_config, key)
         monitor_type, name = self.get_name_type(f5_monitor, key)
         # Added prefix for objects
         if self.prefix:
             name = self.prefix + '-' + name
         try:
             LOG.debug("Converting monitor: %s" % name)
             if monitor_type not in self.supported_types:
                 LOG.warn("Monitor type not supported by Avi : "+name)
                 conv_utils.add_status_row(
                     'monitor', monitor_type, name,
                     conv_const.STATUS_EXTERNAL_MONITOR)
                 continue
             avi_monitor = self.convert_monitor(
                 f5_monitor, key, monitor_config, input_dir, m_user_ignore,
                 tenant, avi_config, cloud_name, controller_version)
             if not avi_monitor:
                 continue
             # code to merge health monitor.
             if self.object_merge_check:
                 conv_utils.update_skip_duplicates(avi_monitor,
                     avi_config['HealthMonitor'], 'health_monitor',
                         converted_objs, name, None)
                 self.mon_count += 1
             else:
                 avi_config["HealthMonitor"].append(avi_monitor)
             LOG.debug("Conversion successful for monitor: %s" % name)
         except:
             LOG.error("Failed to convert monitor: %s" % key, exc_info=True)
             if name:
                 conv_utils.add_status_row('monitor', monitor_type, name,
                                           conv_const.STATUS_ERROR)
             else:
                 conv_utils.add_status_row('monitor', key, key,
                                           conv_const.STATUS_ERROR)
     LOG.debug("Converted %s health monitors" %
               len(avi_config["HealthMonitor"]))
Example #7
0
 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
Example #8
0
    def convert_external(self, monitor_dict, f5_monitor, skipped,
                         input_dir, name):
        script_vars = ""
        for key in f5_monitor.keys():
            if key not in ('args', 'run') and '\"' in f5_monitor[key]:
                self.ext_attr.append(key)
                param_value = f5_monitor[key].replace('\"', '')
                script_vars += "%s=%s," % (key, param_value)
        if script_vars:
            script_vars = script_vars[:-1]
        skipped = [key for key in skipped if key not in self.ext_attr]
        cmd_code = f5_monitor.get("run", None)
        cmd_params = f5_monitor.get("args", None)
        cmd_code = cmd_code.replace('\"', '') if cmd_code else None
        cmd_params = cmd_params.replace('\"', '') if cmd_params else None
        if cmd_code:
            cmd_code = conv_utils.upload_file(
                input_dir + os.path.sep + cmd_code)
        else:
            LOG.warn("Skipped monitor: %s for no value in run attribute" % name)
            conv_utils.add_status_row("monitor", "external", name,
                                      conv_const.STATUS_MISSING_FILE)
            monitor_dict['error'] = True
            return None
        monitor_dict["type"] = "HEALTH_MONITOR_EXTERNAL"
        if cmd_code:
            ext_monitor = {
                "command_code": cmd_code,
                "command_parameters": cmd_params,
                "command_variables": script_vars
            }
            monitor_dict["external_monitor"] = ext_monitor
        else:
            LOG.warn("MISSING File: %s" % name)
            conv_utils.add_status_row("monitor", "external", name,
                                      conv_const.STATUS_MISSING_FILE)
            monitor_dict['error'] = True
            return None

        return skipped
Example #9
0
 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
Example #10
0
    def convert(self, f5_config, avi_config, vs_state, user_ignore, tenant,
                cloud_name, controller_version):
        f5_snat_pools = f5_config.get("snatpool", {})
        vs_config = f5_config.get("virtual", {})
        avi_config['VirtualService'] = []
        avi_config['VSDataScriptSet'] = []
        avi_config['NetworkSecurityPolicy'] = []
        avi_config['VsVip'] = []

        for vs_name in vs_config.keys():
            try:
                LOG.debug("Converting VS: %s" % vs_name)
                f5_vs = vs_config[vs_name]
                vs_type = [
                    key for key in f5_vs.keys()
                    if key in self.unsupported_types
                ]
                if vs_type:
                    LOG.warn(
                        "VS type: %s not supported by Avi skipped VS: %s" %
                        (vs_type, vs_name))
                    conv_utils.add_status_row('virtual', None, vs_name,
                                              final.STATUS_SKIPPED)
                    continue
                # Added prefix for objects
                if self.prefix:
                    vs_name = self.prefix + '-' + vs_name
                vs_obj = self.convert_vs(vs_name, f5_vs, vs_state, avi_config,
                                         f5_snat_pools, user_ignore, tenant,
                                         cloud_name, controller_version)
                if vs_obj:
                    avi_config['VirtualService'].append(vs_obj)
                    LOG.debug("Conversion successful for VS: %s" % vs_name)
            except:
                LOG.error("Failed to convert VS: %s" % vs_name, exc_info=True)

        LOG.debug("Converted %s VS" % len(avi_config['VirtualService']))
        f5_config.pop("virtual", {})
Example #11
0
 def convert_external(self, monitor_dict, f5_monitor, skipped,
                      input_dir, name):
     skipped = [key for key in skipped if key not in self.ext_attr]
     monitor_dict["type"] = "HEALTH_MONITOR_EXTERNAL"
     cmd_code = f5_monitor.get("run", 'none')
     user_defined_vars = ""
     for m_key in f5_monitor.keys():
         if 'user-defined_' in m_key:
             var_value = f5_monitor[m_key]
             var_key = m_key.replace('user-defined_', '')
             skipped.remove(m_key)
             user_defined_vars += '%s=%s,' % (var_key, var_value)
     user_defined_vars = user_defined_vars[:-1]
     cmd_code = None if cmd_code == 'none' else cmd_code
     if cmd_code:
         cmd_code = conv_utils.upload_file(
             input_dir + os.path.sep + cmd_code)
     else:
         LOG.warn("Skipped monitor: %s for no value in run attribute" % name)
         conv_utils.add_status_row("monitor", "external", name,
                                   conv_const.STATUS_MISSING_FILE)
         monitor_dict['error'] = True
         return None
     if cmd_code:
         ext_monitor = {
             "command_code": cmd_code,
             "command_parameters": f5_monitor.get("args", None),
             "command_variables": user_defined_vars
         }
         monitor_dict["external_monitor"] = ext_monitor
     else:
         LOG.warn("MISSING File: %s" % name)
         conv_utils.add_status_row("monitor", "external", name,
                                   conv_const.STATUS_MISSING_FILE)
         monitor_dict['error'] = True
         return None
     return skipped
Example #12
0
    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
Example #13
0
 def update_conv_status_for_skip(self, persist_mode, name):
     conv_utils.add_status_row("profile", 'persist', name,
                               final.STATUS_SKIPPED)
Example #14
0
def convert(f5_config,
            output_dir,
            vs_state,
            input_dir,
            version,
            object_merge_check,
            controller_version,
            report_name,
            prefix,
            con_snatpool,
            user_ignore,
            profile_path,
            tenant='admin',
            cloud_name='Default-Cloud'):
    """
    Converts f5 config to avi config pops the config lists for conversion of
    each type from f5 config and remaining marked as skipped in the
    conversion status file
    :param f5_config: dict representation of f5 config from the file
    :param output_dir: Folder path to put output files
    :param vs_state: State of created Avi VS object
    :param input_dir: Location of cert and external monitor script files
    :param version: Version of F5 config
    :param object_merge_check: Flag for object merge
    :param controller_version: Version of controller
    :param user_ignore: Ignore config defined by user
    :param tenant: Tenant for which config need to be converted
    :param cloud_name: cloud for which config need to be converted
    :param prefix : prefix for objects
    :param con_snatpool : flag for snat conversion
    :return: Converted avi objects
    """

    avi_config_dict = {}
    try:
        # load the yaml file attribute in f5_attributes.
        f5_attributes = conv_const.init(version)
        if profile_path and os.path.exists(profile_path):
            with open(profile_path) as data:
                prof_data = json.load(data)
                avi_config_dict['ApplicationProfile'] = \
                    prof_data.get('ApplicationProfile',[])
                avi_config_dict['NetworkProfile'] = prof_data.get(
                    'NetworkProfile', [])
                avi_config_dict["SSLProfile"] = prof_data.get('SSLProfile', [])
                avi_config_dict['PKIProfile'] = prof_data.get('PKIProfile', [])
                avi_config_dict['ApplicationPersistenceProfile'] = \
                    prof_data.get('ApplicationPersistenceProfile',[])
                avi_config_dict['HealthMonitor'] = \
                    prof_data.get('HealthMonitor', [])
        else:
            avi_config_dict['ApplicationProfile'] = []
            avi_config_dict['NetworkProfile'] = []
            avi_config_dict["SSLProfile"] = []
            avi_config_dict['PKIProfile'] = []
            avi_config_dict['ApplicationPersistenceProfile'] = []
            avi_config_dict['HealthMonitor'] = []

        profile_conv = ProfileConfigConv.get_instance(version, f5_attributes,
                                                      object_merge_check,
                                                      prefix)
        profile_conv.convert(f5_config, avi_config_dict, input_dir,
                             user_ignore, tenant, cloud_name)

        # Added ssl profile merge flag.
        mon_conv = MonitorConfigConv.get_instance(version, f5_attributes,
                                                  prefix, object_merge_check)
        mon_conv.convert(f5_config, avi_config_dict, input_dir, user_ignore,
                         tenant, cloud_name, controller_version)

        pool_conv = PoolConfigConv.get_instance(version, f5_attributes, prefix)
        pool_conv.convert(f5_config, avi_config_dict, user_ignore, tenant,
                          cloud_name)

        persist_conv = PersistenceConfigConv.get_instance(
            version, f5_attributes, prefix, object_merge_check)
        persist_conv.convert(f5_config, avi_config_dict, user_ignore, tenant)

        vs_conv = VSConfigConv.get_instance(version, f5_attributes, prefix,
                                            con_snatpool)
        vs_conv.convert(f5_config, avi_config_dict, vs_state, user_ignore,
                        tenant, cloud_name, controller_version)

        conv_utils.net_to_static_route(f5_config, avi_config_dict)
        conv_utils.cleanup_config(avi_config_dict)
        conv_utils.add_tenants(avi_config_dict)

    except:
        LOG.error("Conversion error", exc_info=True)
    datascript_objs = ['data-group']
    # Added support node as not applicable
    na_list_objs = f5_attributes['na_list_objs']
    for f5_type in f5_config.keys():
        f5_obj = f5_config[f5_type]
        for key in f5_obj.keys():
            sub_type = None
            if ' ' in key:
                sub_type, key = key.rsplit(' ', 1)
            if f5_type in datascript_objs:
                conv_utils.add_status_row(f5_type, sub_type, key,
                                          conv_const.STATUS_DATASCRIPT)
            elif f5_type in na_list_objs:
                conv_utils.add_status_row(f5_type, sub_type, key,
                                          conv_const.STATUS_NOT_APPLICABLE)
            else:
                conv_utils.add_status_row(f5_type, sub_type, key,
                                          conv_const.STATUS_SKIPPED)

    # Add f5 converter status report in xslx report
    conv_utils.add_complete_conv_status(output_dir, avi_config_dict,
                                        report_name)
    for key in avi_config_dict:
        if key != 'META':
            if key == 'VirtualService':
                LOG.info('Total Objects of %s : %s (%s full conversions)' %
                         (key, len(
                             avi_config_dict[key]), conv_utils.fully_migrated))
                print 'Total Objects of %s : %s (%s full conversions)' \
                      % (
                      key, len(avi_config_dict[key]), conv_utils.fully_migrated)
                continue
            # Added code to print merged count.
            elif object_merge_check and key == 'SSLProfile':
                mergedfile = len(avi_config_dict[key]) - \
                             profile_conv.ssl_count
                profile_merged_message = \
                    'Total Objects of %s : %s (%s/%s profile merged)' % \
                    (key, len(avi_config_dict[key]), abs(mergedfile),
                     profile_conv.ssl_count)
                LOG.info(profile_merged_message)
                print profile_merged_message
                continue
            elif object_merge_check and key == 'ApplicationProfile':
                mergedfile = len(avi_config_dict[key]) - \
                             profile_conv.app_count
                profile_merged_message = \
                    'Total Objects of %s : %s (%s/%s profile merged)' % \
                    (key, len(avi_config_dict[key]), abs(mergedfile),
                     profile_conv.app_count)
                LOG.info(profile_merged_message)
                print profile_merged_message
                continue
            elif object_merge_check and key == 'NetworkProfile':
                mergedfile = len(avi_config_dict[key]) - \
                             profile_conv.net_count
                profile_merged_message = \
                    'Total Objects of %s : %s (%s/%s profile merged)' % \
                    (key, len(avi_config_dict[key]), abs(mergedfile),
                     profile_conv.net_count)
                LOG.info(profile_merged_message)
                print profile_merged_message
                continue
            elif object_merge_check and key == 'HealthMonitor':
                mergedmon = len(avi_config_dict[key]) - mon_conv.mon_count
                monitor_merged_message = \
                    'Total Objects of %s : %s (%s/%s monitor merged)' % \
                    (key, len(avi_config_dict[key]), abs(mergedmon),
                     mon_conv.mon_count)
                LOG.info(monitor_merged_message)
                print monitor_merged_message
                continue
            elif object_merge_check and key == 'PKIProfile':
                mergedfile = len(avi_config_dict[key]) - \
                             profile_conv.pki_count
                profile_merged_message = \
                    'Total Objects of %s : %s (%s/%s profile merged)' % \
                    (key, len(avi_config_dict[key]), abs(mergedfile),
                     profile_conv.pki_count)
                LOG.info(profile_merged_message)
                print profile_merged_message
                continue
            elif object_merge_check and key == 'ApplicationPersistenceProfile':
                mergedfile = len(avi_config_dict[key]) - \
                             persist_conv.app_per_count
                profile_merged_message = \
                    'Total Objects of %s : %s (%s/%s profile merged)' % \
                    (key, len(avi_config_dict[key]), abs(mergedfile),
                     persist_conv.app_per_count)
                LOG.info(profile_merged_message)
                print profile_merged_message
                continue
            LOG.info('Total Objects of %s : %s' %
                     (key, len(avi_config_dict[key])))
            print 'Total Objects of %s : %s' % (key, len(avi_config_dict[key]))
    return avi_config_dict
Example #15
0
    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
Example #16
0
def convert(f5_config, output_dir, vs_state, input_dir, version,
            object_merge_check, controller_version, report_name, prefix,
            con_snatpool, user_ignore, profile_path, tenant='admin',
            cloud_name='Default-Cloud'):
    """
    Converts f5 config to avi config pops the config lists for conversion of
    each type from f5 config and remaining marked as skipped in the
    conversion status file
    :param f5_config: dict representation of f5 config from the file
    :param output_dir: Folder path to put output files
    :param vs_state: State of created Avi VS object
    :param input_dir: Location of cert and external monitor script files
    :param version: Version of F5 config
    :param object_merge_check: Flag for object merge
    :param controller_version: Version of controller
    :param user_ignore: Ignore config defined by user
    :param tenant: Tenant for which config need to be converted
    :param cloud_name: cloud for which config need to be converted
    :param prefix : prefix for objects
    :param con_snatpool : flag for snat conversion
    :return: Converted avi objects
    """

    avi_config_dict = {}
    try:
        # load the yaml file attribute in f5_attributes.
        f5_attributes = conv_const.init(version)
        if profile_path and os.path.exists(profile_path):
            with open(profile_path) as data:
                prof_data = json.load(data)
                avi_config_dict['ApplicationProfile'] = \
                    prof_data.get('ApplicationProfile',[])
                avi_config_dict['NetworkProfile'] = prof_data.get(
                    'NetworkProfile',[])
                avi_config_dict["SSLProfile"] = prof_data.get('SSLProfile',[])
                avi_config_dict['PKIProfile'] = prof_data.get('PKIProfile',[])
                avi_config_dict['ApplicationPersistenceProfile'] = \
                    prof_data.get('ApplicationPersistenceProfile',[])
                avi_config_dict['HealthMonitor'] = \
                    prof_data.get('HealthMonitor', [])
        else:
            avi_config_dict['ApplicationProfile'] = []
            avi_config_dict['NetworkProfile'] = []
            avi_config_dict["SSLProfile"] = []
            avi_config_dict['PKIProfile'] = []
            avi_config_dict['ApplicationPersistenceProfile'] = []
            avi_config_dict['HealthMonitor'] = []

        profile_conv = ProfileConfigConv.get_instance(
            version, f5_attributes, object_merge_check, prefix)
        profile_conv.convert(f5_config, avi_config_dict, input_dir,
                             user_ignore, tenant, cloud_name)

        # Added ssl profile merge flag.
        mon_conv = MonitorConfigConv.get_instance(
            version, f5_attributes, prefix, object_merge_check)
        mon_conv.convert(f5_config, avi_config_dict, input_dir, user_ignore,
                         tenant, cloud_name, controller_version)

        pool_conv = PoolConfigConv.get_instance(version, f5_attributes, prefix)
        pool_conv.convert(f5_config, avi_config_dict, user_ignore, tenant,
                          cloud_name)

        persist_conv = PersistenceConfigConv.get_instance(
            version, f5_attributes, prefix, object_merge_check)
        persist_conv.convert(f5_config, avi_config_dict, user_ignore, tenant)

        vs_conv = VSConfigConv.get_instance(version, f5_attributes, prefix, con_snatpool)
        vs_conv.convert(f5_config, avi_config_dict, vs_state, user_ignore,
                        tenant, cloud_name, controller_version)

        conv_utils.net_to_static_route(f5_config, avi_config_dict)
        conv_utils.cleanup_config(avi_config_dict)
        conv_utils.add_tenants(avi_config_dict)

    except:
        LOG.error("Conversion error", exc_info=True)
    datascript_objs = ['data-group']
    # Added support node as not applicable
    na_list_objs = f5_attributes['na_list_objs']
    for f5_type in f5_config.keys():
        f5_obj = f5_config[f5_type]
        for key in f5_obj.keys():
            sub_type = None
            if ' ' in key:
                sub_type, key = key.rsplit(' ', 1)
            if f5_type in datascript_objs:
                conv_utils.add_status_row(f5_type, sub_type, key,
                                          conv_const.STATUS_DATASCRIPT)
            elif f5_type in na_list_objs:
                conv_utils.add_status_row(f5_type, sub_type, key,
                                          conv_const.STATUS_NOT_APPLICABLE)
            else:
                conv_utils.add_status_row(f5_type, sub_type, key,
                                          conv_const.STATUS_SKIPPED)

    # Add f5 converter status report in xslx report
    conv_utils.add_complete_conv_status(
        output_dir, avi_config_dict, report_name)
    for key in avi_config_dict:
        if key != 'META':
            if key == 'VirtualService':
                LOG.info('Total Objects of %s : %s (%s full conversions)'
                         % (key, len(avi_config_dict[key]),
                            conv_utils.fully_migrated))
                print 'Total Objects of %s : %s (%s full conversions)' \
                      % (
                      key, len(avi_config_dict[key]), conv_utils.fully_migrated)
                continue
            # Added code to print merged count.
            elif object_merge_check and key == 'SSLProfile':
                mergedfile = len(avi_config_dict[key]) - \
                             profile_conv.ssl_count
                profile_merged_message = \
                    'Total Objects of %s : %s (%s/%s profile merged)' % \
                    (key, len(avi_config_dict[key]), abs(mergedfile),
                     profile_conv.ssl_count)
                LOG.info(profile_merged_message)
                print profile_merged_message
                continue
            elif object_merge_check and key == 'ApplicationProfile':
                mergedfile = len(avi_config_dict[key]) - \
                             profile_conv.app_count
                profile_merged_message = \
                    'Total Objects of %s : %s (%s/%s profile merged)' % \
                    (key, len(avi_config_dict[key]), abs(mergedfile),
                     profile_conv.app_count)
                LOG.info(profile_merged_message)
                print profile_merged_message
                continue
            elif object_merge_check and key == 'NetworkProfile':
                mergedfile = len(avi_config_dict[key]) - \
                             profile_conv.net_count
                profile_merged_message = \
                    'Total Objects of %s : %s (%s/%s profile merged)' % \
                    (key, len(avi_config_dict[key]), abs(mergedfile),
                     profile_conv.net_count)
                LOG.info(profile_merged_message)
                print profile_merged_message
                continue
            elif object_merge_check and key == 'HealthMonitor':
                mergedmon = len(avi_config_dict[key]) - mon_conv.mon_count
                monitor_merged_message = \
                    'Total Objects of %s : %s (%s/%s monitor merged)' % \
                    (key, len(avi_config_dict[key]), abs(mergedmon),
                     mon_conv.mon_count)
                LOG.info(monitor_merged_message)
                print monitor_merged_message
                continue
            elif object_merge_check and key == 'PKIProfile':
                mergedfile = len(avi_config_dict[key]) - \
                             profile_conv.pki_count
                profile_merged_message = \
                    'Total Objects of %s : %s (%s/%s profile merged)' % \
                    (key, len(avi_config_dict[key]), abs(mergedfile),
                     profile_conv.pki_count)
                LOG.info(profile_merged_message)
                print profile_merged_message
                continue
            elif object_merge_check and key == 'ApplicationPersistenceProfile':
                mergedfile = len(avi_config_dict[key]) - \
                             persist_conv.app_per_count
                profile_merged_message = \
                    'Total Objects of %s : %s (%s/%s profile merged)' % \
                    (key, len(avi_config_dict[key]), abs(mergedfile),
                     persist_conv.app_per_count)
                LOG.info(profile_merged_message)
                print profile_merged_message
                continue
            LOG.info('Total Objects of %s : %s' % (key, len(
                avi_config_dict[key])))
            print 'Total Objects of %s : %s' % (key, len(
                avi_config_dict[key]))
    return avi_config_dict
Example #17
0
 def update_conv_status_for_skip(self, persist_mode, name):
     conv_utils.add_status_row("profile", 'persist', name,
                               final.STATUS_SKIPPED)
Example #18
0
    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
Example #19
0
    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', {})