def _disassociate_floatingip(self, context, id):
        l3db_fip = self._get_floatingip(context, id)
        db_namespace = fortinet_db.query_record(context,
                                    fortinet_db.Fortinet_ML2_Namespace,
                                    tenant_id=l3db_fip.tenant_id)
        db_fip = fortinet_db.query_record(context,
                            fortinet_db.Fortinet_FloatingIP_Allocation,
                            floating_ip_address=l3db_fip.floating_ip_address,
                            allocated=True)
        int_intf, ext_intf = utils.get_vlink_intf(self, context,
                                               vdom=db_namespace.vdom)
        db_ip = fortinet_db.query_record(context, models_v2.IPAllocation,
                                         port_id=l3db_fip.fixed_port_id)
        vlan_inf = utils.get_intf(context, db_ip.network_id)
        mappedip = utils.get_ipaddr(db_fip.ip_subnet, 0)
        utils.delete_fwpolicy(self, context,
                              vdom=db_namespace.vdom,
                              srcintf=vlan_inf,
                              srcaddr=l3db_fip.fixed_ip_address,
                              dstintf=int_intf,
                              poolname=mappedip)

        utils.delete_fwaddress(self, context,
                               name=l3db_fip.fixed_ip_address,
                               vdom=db_namespace.vdom)

        utils.delete_fwpolicy(self, context,
                              vdom=db_namespace.vdom,
                              dstaddr=db_fip.floating_ip_address)

        utils.delete_vip(self, context,
                         vdom=db_namespace.vdom,
                         name=db_fip.floating_ip_address)
    def add_router_interface(self, context, router_id, interface_info):
        """creates vlnk on the fortinet device."""
        LOG.debug("FortinetL3ServicePlugin.add_router_interface: "
                  "router_id=%(router_id)s "
                  "interface_info=%(interface_info)r",
                  {'router_id': router_id, 'interface_info': interface_info})
        with context.session.begin(subtransactions=True):
            info = super(FortinetL3ServicePlugin, self).add_router_interface(
                context, router_id, interface_info)
            port = db.get_port(context, info['port_id'])
            port['admin_state_up'] = True
            port['port'] = port
            LOG.debug("FortinetL3ServicePlugin: "
                      "context=%(context)s"
                      "port=%(port)s "
                      "info=%(info)r",
                      {'context': context, 'port': port, 'info': info})
            interface_info = info
            subnet = self._core_plugin._get_subnet(context,
                                                   interface_info['subnet_id'])
            network_id = subnet['network_id']
            tenant_id = port['tenant_id']
            port_filters = {'network_id': [network_id],
                            'device_owner': [DEVICE_OWNER_ROUTER_INTF]}
            port_count = self._core_plugin.get_ports_count(context,
                                                           port_filters)
            # port count is checked against 2 since the current port is already
            # added to db
            if port_count == 2:
                # This subnet is already part of some router
                LOG.error(_LE("FortinetL3ServicePlugin: adding redundant "
                              "router interface is not supported"))
                raise Exception(_("FortinetL3ServicePlugin:adding redundant "
                                  "router interface is not supported"))
            try:
                db_namespace = fortinet_db.query_record(context,
                                        fortinet_db.Fortinet_ML2_Namespace,
                                        tenant_id=tenant_id)
                vlan_inf = utils.get_intf(context, network_id)
                int_intf, ext_intf = utils.get_vlink_intf(self, context,
                                               vdom=db_namespace.vdom)
                utils.add_fwpolicy(self, context,
                                   vdom=db_namespace.vdom,
                                   srcintf=vlan_inf,
                                   dstintf=int_intf,
                                   nat='enable')

            except Exception as e:
                LOG.error(_LE("Failed to create Fortinet resources to add "
                            "router interface. info=%(info)s, "
                            "router_id=%(router_id)s"),
                          {"info": info, "router_id": router_id})
                utils._rollback_on_err(self, context, e)
                with excutils.save_and_reraise_exception():
                    self.remove_router_interface(context, router_id,
                                                 interface_info)
        utils.update_status(self, context, t_consts.TaskStatus.COMPLETED)
        return info
Example #3
0
 def add_router_interface(self, context, port):
     """creates vlnk on the fortinet device."""
     db_namespace = fortinet_db.query_record(context,
                                             fortinet_db.Fortinet_ML2_Namespace,
                                             tenant_id=port['tenant_id'])
     vlan_inf = utils.get_intf(context, port['network_id'])
     int_intf, ext_intf = utils.get_vlink_intf(self, context,
                                               vdom=db_namespace.vdom)
     utils.add_fwpolicy(self, context,
                        vdom=db_namespace.vdom,
                        srcintf=vlan_inf,
                        dstintf=int_intf,
                        nat='enable')
Example #4
0
 def add_router_interface(self, context, port):
     """creates vlnk on the fortinet device."""
     db_namespace = fortinet_db.query_record(
         context,
         fortinet_db.Fortinet_ML2_Namespace,
         tenant_id=port['tenant_id'])
     vlan_inf = utils.get_intf(context, port['network_id'])
     int_intf, ext_intf = utils.get_vlink_intf(self,
                                               context,
                                               vdom=db_namespace.vdom)
     utils.add_fwpolicy(self,
                        context,
                        vdom=db_namespace.vdom,
                        srcintf=vlan_inf,
                        dstintf=int_intf,
                        nat='enable')
    def _disassociate_floatingip(self, context, id):
        l3db_fip = self._get_floatingip(context, id)
        db_namespace = fortinet_db.query_record(
            context,
            fortinet_db.Fortinet_ML2_Namespace,
            tenant_id=l3db_fip.tenant_id)
        db_fip = fortinet_db.query_record(
            context,
            fortinet_db.Fortinet_FloatingIP_Allocation,
            floating_ip_address=l3db_fip.floating_ip_address,
            allocated=True)
        int_intf, ext_intf = utils.get_vlink_intf(self,
                                                  context,
                                                  vdom=db_namespace.vdom)
        db_ip = fortinet_db.query_record(context,
                                         models_v2.IPAllocation,
                                         port_id=l3db_fip.fixed_port_id)
        vlan_inf = utils.get_intf(context, db_ip.network_id)
        mappedip = utils.get_ipaddr(db_fip.ip_subnet, 0)
        utils.delete_fwpolicy(self,
                              context,
                              vdom=db_namespace.vdom,
                              srcintf=vlan_inf,
                              srcaddr=l3db_fip.fixed_ip_address,
                              dstintf=int_intf,
                              poolname=mappedip)

        utils.delete_fwaddress(self,
                               context,
                               name=l3db_fip.fixed_ip_address,
                               vdom=db_namespace.vdom)

        utils.delete_fwpolicy(self,
                              context,
                              vdom=db_namespace.vdom,
                              dstaddr=db_fip.floating_ip_address)

        utils.delete_vip(self,
                         context,
                         vdom=db_namespace.vdom,
                         name=db_fip.floating_ip_address)
 def _update_firewall_rule(self, context, id, firewall_rule):
     LOG.debug("# _add_firewall_rule() called")
     fwps_int = fortinet_db.Fortinet_FW_Rule_Association.query_all(
         context, fwr_id=id, type=constants.TYPE_INT)
     fwps_ext = fortinet_db.Fortinet_FW_Rule_Association.query_all(
         context, fwr_id=id, type=constants.TYPE_EXT)
     if fwps_ext and fwps_int:
         fwps = fwps_int + fwps_ext
     else:
         fwps = fwps_int or fwps_ext
     if not fwps:
         return
     firewall_rule.setdefault('id', id)
     srcaddr = self._make_fortinet_fwaddress_dict(
         place='source_ip_address', **firewall_rule)
     dstaddr = self._make_fortinet_fwaddress_dict(
         place='destination_ip_address', **firewall_rule)
     service = self._make_fortinet_fwservice_dict(**firewall_rule)
     action = self._get_fwr_action(**firewall_rule)
     profiles = self._get_fwp_profiles(action)
     for fwp in fwps_int:
         vdom = fwp.fortinet_policy.vdom
         if service['name'] != 'ALL':
             utils.set_fwservice(self, context, vdom=vdom, **service)
         if srcaddr['name'] != 'all':
             utils.set_fwaddress(self, context, vdom=vdom, **srcaddr)
         if dstaddr['name'] != 'all':
             utils.set_fwaddress(self, context, vdom=vdom, **dstaddr)
     # check whether related firewall policies need to update
     fwp = fwps_int[0].fortinet_policy
     name = firewall_rule.setdefault('name', fwp.comments)
     if fwp.srcaddr == srcaddr['name'] and fwp.action == action and \
         fwp.dstaddr == dstaddr['name'] and fwp.service == service['name']:
         return
     if action in ['accept']:
         for fwp in fwps:
             fortinet_fwp = utils.set_fwpolicy(self, context,
                                               id=fwp.fortinet_pid,
                                               srcaddr=srcaddr['name'],
                                               dstaddr=dstaddr['name'],
                                               service=service['name'],
                                               action=action,
                                               comments=name,
                                               **profiles)
             if not fwps_ext:
                 inf_int, inf_ext = utils.get_vlink_intf(
                     self, context, vdom=fortinet_fwp.vdom)
                 utils.add_fwaas_subpolicy(self, context,
                                           before=fortinet_fwp.edit_id,
                                           vdom=fortinet_fwp.vdom,
                                           srcaddr=srcaddr['name'],
                                           dstaddr=dstaddr['name'],
                                           dstintf=inf_int,
                                           nat='enable',
                                           service=service['name'],
                                           action=action,
                                           comments=name,
                                           fwr_id=id,
                                           type=constants.TYPE_EXT,
                                           **profiles)
     elif action in ['deny']:
         for fwp_ext in fwps_ext:
             utils.delete_fwaas_subpolicy(self, context,
                                          fwr_id=fwp_ext.fwr_id,
                                          fortinet_pid=fwp_ext.fortinet_pid)
         for fwp in fwps_int:
             utils.set_fwpolicy(self, context,
                                id=fwp.fortinet_pid,
                                srcaddr=srcaddr['name'],
                                dstaddr=dstaddr['name'],
                                service=service['name'],
                                action=action,
                                comments=name,
                                **profiles)
     for fwp in fwps_int:
         vdom = fwp.fortinet_policy.vdom
         if service['name'] == 'ALL':
             #delete all old services if exist
             utils.delete_fwservice(self, context, vdom=vdom, name=id)
         if srcaddr['name'] == 'all':
             name = constants.PREFIX['source_ip_address'] + id
             utils.delete_fwaddress(self, context, vdom=vdom, name=name)
         if dstaddr['name'] == 'all':
             name = constants.PREFIX['destination_ip_address'] + id
             utils.delete_fwaddress(self, context, vdom=vdom, name=name)
    def _add_firewall_rule(self, context, fwp_tenant_id, **fwr):
        """
        :param obj:
        :param context:
        :param kwargs: dictionary, firewall rule
        firewall_rule: {'source_ip_address': u'192.176.10.0/24',... }
        :return:
        """
        LOG.debug("# _add_firewall_rule() called")
        namespace = fortinet_db.Fortinet_ML2_Namespace.query_one(
            context, tenant_id=fwp_tenant_id)
        vdom = getattr(namespace, 'vdom', None)
        if not vdom or not fwr:
            return None
        inf_int, inf_ext = utils.get_vlink_intf(
            self, context, vdom=namespace.vdom)
        srcaddr = self._add_fwr_ip_address(
            context, vdom, place='source_ip_address', **fwr)
        dstaddr = self._add_fwr_ip_address(
            context, vdom, place='destination_ip_address', **fwr)
        service = self._add_fwr_service(context, vdom, **fwr)
        action = self._get_fwr_action(**fwr)
        profiles = self._get_fwp_profiles(action)
        match_vip = 'enable'
        name = fwr.get('name', '')
        # add a basic firewall rule('accept': incoming, 'deny': bidirectional)
        fortinet_fwp = utils.add_fwpolicy_to_head(self, context,
                                                  vdom=vdom,
                                                  srcaddr=srcaddr['name'],
                                                  srcintf='any',
                                                  dstaddr=dstaddr['name'],
                                                  dstintf='any',
                                                  service=service['name'],
                                                  match_vip=match_vip,
                                                  action=action,
                                                  comments=name,
                                                  **profiles)
        utils.add_record(self, context,
                         fortinet_db.Fortinet_FW_Rule_Association,
                         fwr_id=fwr['id'],
                         fortinet_pid=fortinet_fwp.id,
                         type=constants.TYPE_INT)

        if action in ['accept']:
            # if allow, for the outgoing traffic it need to enable nat
            fortinet_fwp = utils.add_fwpolicy_to_head(self, context,
                                                      vdom=vdom,
                                                      srcaddr=srcaddr['name'],
                                                      srcintf='any',
                                                      dstaddr=dstaddr['name'],
                                                      dstintf=inf_int,
                                                      nat='enable',
                                                      service=service['name'],
                                                      action=action,
                                                      comments=name,
                                                      **profiles)
            utils.add_record(self, context,
                             fortinet_db.Fortinet_FW_Rule_Association,
                             fwr_id=fwr['id'],
                             fortinet_pid=fortinet_fwp.id,
                             type=constants.TYPE_EXT)
    def _release_floatingip(self, context, id):
        """
        :param context:
        :param id: the floatingip id in neutron.db.l3_db.FloatingIP.
        {
                tenant_id=u'3998b33381fb48f694369689065a3760',
                id=u'25e1588a-5ec5-4fbc-bdef-eff8713da8f8',
                floating_ip_address=u'10.160.37.111',
                floating_network_id=u'1c1dbecc-9dac-4311-a346-f147a04c8dc8',
                floating_port_id=u'4b4120d4-77f9-4f82-b823-05876929a1c4',
                fixed_port_id=None,
                fixed_ip_address=None,
                router_id=None,
                last_known_router_id=None,
                status=u'DOWN'
        }
        :return:
        """
        with context.session.begin(subtransactions=True):
            l3db_fip = self._get_floatingip(context, id)
            tenant_id = l3db_fip.tenant_id
            db_namespace = fortinet_db.query_record(context,
                                    fortinet_db.Fortinet_ML2_Namespace,
                                    tenant_id=tenant_id)

            db_fip = fortinet_db.query_record(context,
                            fortinet_db.Fortinet_FloatingIP_Allocation,
                            floating_ip_address=l3db_fip.floating_ip_address,
                            allocated=True)
            if not db_fip or not db_namespace:
                return

            int_intf, ext_intf = utils.get_vlink_intf(self, context,
                                                     vdom=db_namespace.vdom)
            mappedip = utils.get_ipaddr(db_fip.ip_subnet, 0)

            utils.delete_fwippool(self, context,
                                  name=mappedip,
                                  vdom=db_namespace.vdom,
                                  startip=mappedip)

            utils.delete_fwpolicy(self, context,
                                  vdom=const.EXT_VDOM,
                                  srcintf=ext_intf,
                                  srcaddr=mappedip,
                                  dstintf=self._fortigate['ext_interface'],
                                  poolname=db_fip.floating_ip_address)

            utils.delete_fwaddress(self, context,
                                   name=mappedip,
                                   vdom=const.EXT_VDOM,
                                   subnet="%s 255.255.255.255" % mappedip)

            utils.delete_fwippool(self, context,
                                  name=db_fip.floating_ip_address,
                                  vdom=const.EXT_VDOM,
                                  startip=db_fip.floating_ip_address)

            utils.delete_routerstatic(self, context,
                                      vdom=const.EXT_VDOM,
                                      dst="%s 255.255.255.255" % mappedip,
                                      device=ext_intf,
                                      gateway=const.DEF_GW)

            utils.delete_fwpolicy(self, context,
                                  vdom=const.EXT_VDOM,
                                  dstintf=ext_intf,
                                  dstaddr=l3db_fip.floating_ip_address)

            utils.delete_vip(self, context,
                             vdom=const.EXT_VDOM,
                             name=db_fip.vip_name,
                             extip=db_fip.floating_ip_address,
                             extintf='any',
                             mappedip=mappedip)

            fortinet_db.delete_record(context,
                            fortinet_db.Fortinet_FloatingIP_Allocation,
                            vdom=db_namespace.vdom,
                            floating_ip_address=db_fip.floating_ip_address,
                            vip_name=db_fip.floating_ip_address)
            # TODO(jerryz): move this out of transaction.
            setattr(context, 'GUARD_TRANSACTION', False)
            super(FortinetL3ServicePlugin, self).delete_floatingip(context, id)
            utils.delete_vlink(self, context, tenant_id)
            utils.delete_vdom(self, context, tenant_id=tenant_id)
    def _allocate_floatingip(self, context, obj):
        """
        1. mapping floatingip to the one of a pair of internal ips based on
           the vip function.
        2. add another ip of the ip pair to the secondaryip list of
           the external interface.

        obj example:
        {
            'floating_network_id': u'1c1dbecc-9dac-4311-a346-f147a04c8dc8',
            'router_id': None,
            'fixed_ip_address': None,
            'floating_ip_address': u'10.160.37.113',
            'tenant_id': u'3998b33381fb48f694369689065a3760',
            'status': 'DOWN',
            'port_id': None,
            'id': '5ec1b08b-77c1-4e39-80ac-224ee937ee9f'
        }

        The floatingip is a instance of neutron.db.l3_db.FloatingIP, example:
        {
            tenant_id=u'3998b33381fb48f694369689065a3760',
            id=u'25e1588a-5ec5-4fbc-bdef-eff8713da8f8',
            floating_ip_address=u'10.160.37.111',
            floating_network_id=u'1c1dbecc-9dac-4311-a346-f147a04c8dc8',
            floating_port_id=u'4b4120d4-77f9-4f82-b823-05876929a1c4',
            fixed_port_id=None,
            fixed_ip_address=None,
            router_id=None,
            last_known_router_id=None,
            status=u'DOWN'
        }
        """
        with context.session.begin(subtransactions=True):
            try:
                db_namespace = utils.add_vdom(self, context,
                                              tenant_id=obj['tenant_id'])

                db_fip = utils.add_record(self, context,
                                fortinet_db.Fortinet_FloatingIP_Allocation,
                                vdom=db_namespace.vdom,
                                floating_ip_address=obj['floating_ip_address'],
                                vip_name=obj['floating_ip_address'])
                mappedip = utils.get_ipaddr(db_fip.ip_subnet, 0)
                utils.add_vip(self, context,
                              vdom=const.EXT_VDOM,
                              name=db_fip.vip_name,
                              extip=db_fip.floating_ip_address,
                              extintf='any',
                              mappedip=mappedip)

                int_intf, ext_intf = utils.get_vlink_intf(self, context,
                                                       vdom=db_namespace.vdom)

                utils.add_fwpolicy(self, context,
                                   vdom=const.EXT_VDOM,
                                   dstintf=ext_intf,
                                   dstaddr=db_fip.vip_name,
                                   nat='enable')

                utils.add_routerstatic(self, context,
                                       vdom=const.EXT_VDOM,
                                       dst="%s 255.255.255.255" % mappedip,
                                       device=ext_intf,
                                       gateway=const.DEF_GW)

                utils.add_fwippool(self, context,
                                   name=db_fip.floating_ip_address,
                                   vdom=const.EXT_VDOM,
                                   startip=db_fip.floating_ip_address)

                utils.add_fwaddress(self, context,
                                    name=mappedip,
                                    vdom=const.EXT_VDOM,
                                    subnet="%s 255.255.255.255" % mappedip)

                db_fwpolicy = utils.add_fwpolicy(self, context,
                                   vdom=const.EXT_VDOM,
                                   srcintf=ext_intf,
                                   srcaddr=mappedip,
                                   dstintf=self._fortigate['ext_interface'],
                                   poolname=db_fip.floating_ip_address)
                utils.head_firewall_policy(self, context,
                                           vdom=const.EXT_VDOM,
                                           id=db_fwpolicy.edit_id)

                utils.add_fwippool(self, context,
                                   name=mappedip,
                                   vdom=db_namespace.vdom,
                                   startip=mappedip)
            except Exception as e:
                with excutils.save_and_reraise_exception():
                    utils._rollback_on_err(self, context, e)
        utils.update_status(self, context, t_consts.TaskStatus.COMPLETED)
    def _associate_floatingip(self, context, id, floatingip):
        try:
            l3db_fip = self._get_floatingip(context, id)
            db_namespace = fortinet_db.query_record(context,
                                    fortinet_db.Fortinet_ML2_Namespace,
                                    tenant_id=l3db_fip.tenant_id)

            db_fip = fortinet_db.query_record(context,
                            fortinet_db.Fortinet_FloatingIP_Allocation,
                            floating_ip_address=l3db_fip.floating_ip_address,
                            allocated=True)
            int_intf, ext_intf = utils.get_vlink_intf(self, context,
                                                      vdom=db_namespace.vdom)
            mappedip = utils.get_ipaddr(db_fip.ip_subnet, 0)
            fixed_ip_address = floatingip['floatingip']['fixed_ip_address']
            utils.add_vip(self, context,
                          vdom=db_namespace.vdom,
                          name=db_fip.floating_ip_address,
                          extip=mappedip,
                          extintf=int_intf,
                          mappedip=fixed_ip_address)

            db_ip = fortinet_db.query_record(context, models_v2.IPAllocation,
                                port_id=floatingip['floatingip']['port_id'])
            vlan_inf = utils.get_intf(context, db_ip.network_id)
            utils.add_fwpolicy(self, context,
                               vdom=db_namespace.vdom,
                               srcintf=int_intf,
                               dstintf=vlan_inf,
                               dstaddr=db_fip.floating_ip_address,
                               nat='enable')

            utils.add_fwaddress(self, context,
                                name=fixed_ip_address,
                                vdom=db_namespace.vdom,
                                subnet="%s 255.255.255.255" % fixed_ip_address,
                                associated_interface=vlan_inf)

            db_fwpolicy = utils.add_fwpolicy(self, context,
                               vdom=db_namespace.vdom,
                               srcintf=vlan_inf,
                               srcaddr=fixed_ip_address,
                               dstintf=int_intf,
                               poolname=mappedip)

            if self.enable_fwaas:
                fwrass = fortinet_db.Fortinet_FW_Rule_Association.query_one(
                    context, fwr_id=db_namespace.tenant_id)
                default_fwp = getattr(fwrass, 'fortinet_policy', None)
                if getattr(default_fwp, 'edit_id', None):
                    utils.head_firewall_policy(self, context,
                                               vdom=db_namespace.vdom,
                                               id=db_fwpolicy.edit_id,
                                               after=default_fwp.edit_id)
                    _headed = True
            if '_headed' not in locals():
                utils.head_firewall_policy(self, context,
                                           vdom=db_namespace.vdom,
                                           id=db_fwpolicy.edit_id)
        except Exception as e:
            with excutils.save_and_reraise_exception():
                utils._rollback_on_err(self, context, e)
        utils.update_status(self, context, t_consts.TaskStatus.COMPLETED)
    def _release_floatingip(self, context, id):
        """
        :param context:
        :param id: the floatingip id in neutron.db.l3_db.FloatingIP.
        {
                tenant_id=u'3998b33381fb48f694369689065a3760',
                id=u'25e1588a-5ec5-4fbc-bdef-eff8713da8f8',
                floating_ip_address=u'10.160.37.111',
                floating_network_id=u'1c1dbecc-9dac-4311-a346-f147a04c8dc8',
                floating_port_id=u'4b4120d4-77f9-4f82-b823-05876929a1c4',
                fixed_port_id=None,
                fixed_ip_address=None,
                router_id=None,
                last_known_router_id=None,
                status=u'DOWN'
        }
        :return:
        """
        with context.session.begin(subtransactions=True):
            l3db_fip = self._get_floatingip(context, id)
            tenant_id = l3db_fip.tenant_id
            db_namespace = fortinet_db.query_record(
                context,
                fortinet_db.Fortinet_ML2_Namespace,
                tenant_id=tenant_id)

            db_fip = fortinet_db.query_record(
                context,
                fortinet_db.Fortinet_FloatingIP_Allocation,
                floating_ip_address=l3db_fip.floating_ip_address,
                allocated=True)
            if not db_fip or not db_namespace:
                return

            int_intf, ext_intf = utils.get_vlink_intf(self,
                                                      context,
                                                      vdom=db_namespace.vdom)
            mappedip = utils.get_ipaddr(db_fip.ip_subnet, 0)

            utils.delete_fwippool(self,
                                  context,
                                  name=mappedip,
                                  vdom=db_namespace.vdom,
                                  startip=mappedip)

            utils.delete_fwpolicy(self,
                                  context,
                                  vdom=const.EXT_VDOM,
                                  srcintf=ext_intf,
                                  srcaddr=mappedip,
                                  dstintf=self._fortigate['ext_interface'],
                                  poolname=db_fip.floating_ip_address)

            utils.delete_fwaddress(self,
                                   context,
                                   name=mappedip,
                                   vdom=const.EXT_VDOM,
                                   subnet="%s 255.255.255.255" % mappedip)

            utils.delete_fwippool(self,
                                  context,
                                  name=db_fip.floating_ip_address,
                                  vdom=const.EXT_VDOM,
                                  startip=db_fip.floating_ip_address)

            utils.delete_routerstatic(self,
                                      context,
                                      vdom=const.EXT_VDOM,
                                      dst="%s 255.255.255.255" % mappedip,
                                      device=ext_intf,
                                      gateway=const.DEF_GW)

            utils.delete_fwpolicy(self,
                                  context,
                                  vdom=const.EXT_VDOM,
                                  dstintf=ext_intf,
                                  dstaddr=l3db_fip.floating_ip_address)

            utils.delete_vip(self,
                             context,
                             vdom=const.EXT_VDOM,
                             name=db_fip.vip_name,
                             extip=db_fip.floating_ip_address,
                             extintf='any',
                             mappedip=mappedip)

            fortinet_db.delete_record(
                context,
                fortinet_db.Fortinet_FloatingIP_Allocation,
                vdom=db_namespace.vdom,
                floating_ip_address=db_fip.floating_ip_address,
                vip_name=db_fip.floating_ip_address)
            # TODO(jerryz): move this out of transaction.
            setattr(context, 'GUARD_TRANSACTION', False)
            super(FortinetL3ServicePlugin, self).delete_floatingip(context, id)
            utils.delete_vlink(self, context, tenant_id)
            utils.delete_vdom(self, context, tenant_id=tenant_id)
    def _allocate_floatingip(self, context, obj):
        """
        1. mapping floatingip to the one of a pair of internal ips based on
           the vip function.
        2. add another ip of the ip pair to the secondaryip list of
           the external interface.

        obj example:
        {
            'floating_network_id': u'1c1dbecc-9dac-4311-a346-f147a04c8dc8',
            'router_id': None,
            'fixed_ip_address': None,
            'floating_ip_address': u'10.160.37.113',
            'tenant_id': u'3998b33381fb48f694369689065a3760',
            'status': 'DOWN',
            'port_id': None,
            'id': '5ec1b08b-77c1-4e39-80ac-224ee937ee9f'
        }

        The floatingip is a instance of neutron.db.l3_db.FloatingIP, example:
        {
            tenant_id=u'3998b33381fb48f694369689065a3760',
            id=u'25e1588a-5ec5-4fbc-bdef-eff8713da8f8',
            floating_ip_address=u'10.160.37.111',
            floating_network_id=u'1c1dbecc-9dac-4311-a346-f147a04c8dc8',
            floating_port_id=u'4b4120d4-77f9-4f82-b823-05876929a1c4',
            fixed_port_id=None,
            fixed_ip_address=None,
            router_id=None,
            last_known_router_id=None,
            status=u'DOWN'
        }
        """
        with context.session.begin(subtransactions=True):
            try:
                db_namespace = utils.add_vdom(self,
                                              context,
                                              tenant_id=obj['tenant_id'])

                db_fip = utils.add_record(
                    self,
                    context,
                    fortinet_db.Fortinet_FloatingIP_Allocation,
                    vdom=db_namespace.vdom,
                    floating_ip_address=obj['floating_ip_address'],
                    vip_name=obj['floating_ip_address'])
                mappedip = utils.get_ipaddr(db_fip.ip_subnet, 0)
                utils.add_vip(self,
                              context,
                              vdom=const.EXT_VDOM,
                              name=db_fip.vip_name,
                              extip=db_fip.floating_ip_address,
                              extintf='any',
                              mappedip=mappedip)

                int_intf, ext_intf = utils.get_vlink_intf(
                    self, context, vdom=db_namespace.vdom)

                utils.add_fwpolicy(self,
                                   context,
                                   vdom=const.EXT_VDOM,
                                   dstintf=ext_intf,
                                   dstaddr=db_fip.vip_name,
                                   nat='enable')

                utils.add_routerstatic(self,
                                       context,
                                       vdom=const.EXT_VDOM,
                                       dst="%s 255.255.255.255" % mappedip,
                                       device=ext_intf,
                                       gateway=const.DEF_GW)

                utils.add_fwippool(self,
                                   context,
                                   name=db_fip.floating_ip_address,
                                   vdom=const.EXT_VDOM,
                                   startip=db_fip.floating_ip_address)

                utils.add_fwaddress(self,
                                    context,
                                    name=mappedip,
                                    vdom=const.EXT_VDOM,
                                    subnet="%s 255.255.255.255" % mappedip)

                db_fwpolicy = utils.add_fwpolicy(
                    self,
                    context,
                    vdom=const.EXT_VDOM,
                    srcintf=ext_intf,
                    srcaddr=mappedip,
                    dstintf=self._fortigate['ext_interface'],
                    poolname=db_fip.floating_ip_address)
                utils.head_firewall_policy(self,
                                           context,
                                           vdom=const.EXT_VDOM,
                                           id=db_fwpolicy.edit_id)

                utils.add_fwippool(self,
                                   context,
                                   name=mappedip,
                                   vdom=db_namespace.vdom,
                                   startip=mappedip)
            except Exception as e:
                with excutils.save_and_reraise_exception():
                    utils._rollback_on_err(self, context, e)
        utils.update_status(self, context, t_consts.TaskStatus.COMPLETED)
    def _associate_floatingip(self, context, id, floatingip):
        try:
            l3db_fip = self._get_floatingip(context, id)
            db_namespace = fortinet_db.query_record(
                context,
                fortinet_db.Fortinet_ML2_Namespace,
                tenant_id=l3db_fip.tenant_id)

            db_fip = fortinet_db.query_record(
                context,
                fortinet_db.Fortinet_FloatingIP_Allocation,
                floating_ip_address=l3db_fip.floating_ip_address,
                allocated=True)
            int_intf, ext_intf = utils.get_vlink_intf(self,
                                                      context,
                                                      vdom=db_namespace.vdom)
            mappedip = utils.get_ipaddr(db_fip.ip_subnet, 0)
            fixed_ip_address = floatingip['floatingip']['fixed_ip_address']
            utils.add_vip(self,
                          context,
                          vdom=db_namespace.vdom,
                          name=db_fip.floating_ip_address,
                          extip=mappedip,
                          extintf=int_intf,
                          mappedip=fixed_ip_address)

            db_ip = fortinet_db.query_record(
                context,
                models_v2.IPAllocation,
                port_id=floatingip['floatingip']['port_id'])
            vlan_inf = utils.get_intf(context, db_ip.network_id)
            utils.add_fwpolicy(self,
                               context,
                               vdom=db_namespace.vdom,
                               srcintf=int_intf,
                               dstintf=vlan_inf,
                               dstaddr=db_fip.floating_ip_address,
                               nat='enable')

            utils.add_fwaddress(self,
                                context,
                                name=fixed_ip_address,
                                vdom=db_namespace.vdom,
                                subnet="%s 255.255.255.255" % fixed_ip_address,
                                associated_interface=vlan_inf)

            db_fwpolicy = utils.add_fwpolicy(self,
                                             context,
                                             vdom=db_namespace.vdom,
                                             srcintf=vlan_inf,
                                             srcaddr=fixed_ip_address,
                                             dstintf=int_intf,
                                             poolname=mappedip)

            if self.enable_fwaas:
                fwrass = fortinet_db.Fortinet_FW_Rule_Association.query_one(
                    context, fwr_id=db_namespace.tenant_id)
                default_fwp = getattr(fwrass, 'fortinet_policy', None)
                if getattr(default_fwp, 'edit_id', None):
                    utils.head_firewall_policy(self,
                                               context,
                                               vdom=db_namespace.vdom,
                                               id=db_fwpolicy.edit_id,
                                               after=default_fwp.edit_id)
                    _headed = True
            if '_headed' not in locals():
                utils.head_firewall_policy(self,
                                           context,
                                           vdom=db_namespace.vdom,
                                           id=db_fwpolicy.edit_id)
        except Exception as e:
            with excutils.save_and_reraise_exception():
                utils._rollback_on_err(self, context, e)
        utils.update_status(self, context, t_consts.TaskStatus.COMPLETED)
    def add_router_interface(self, context, router_id, interface_info):
        """creates vlnk on the fortinet device."""
        LOG.debug(
            "FortinetL3ServicePlugin.add_router_interface: "
            "router_id=%(router_id)s "
            "interface_info=%(interface_info)r", {
                'router_id': router_id,
                'interface_info': interface_info
            })
        with context.session.begin(subtransactions=True):
            info = super(FortinetL3ServicePlugin,
                         self).add_router_interface(context, router_id,
                                                    interface_info)
            port = db.get_port(context, info['port_id'])
            port['admin_state_up'] = True
            port['port'] = port
            LOG.debug(
                "FortinetL3ServicePlugin: "
                "context=%(context)s"
                "port=%(port)s "
                "info=%(info)r", {
                    'context': context,
                    'port': port,
                    'info': info
                })
            interface_info = info
            subnet = self._core_plugin._get_subnet(context,
                                                   interface_info['subnet_id'])
            network_id = subnet['network_id']
            tenant_id = port['tenant_id']
            port_filters = {
                'network_id': [network_id],
                'device_owner': [DEVICE_OWNER_ROUTER_INTF]
            }
            port_count = self._core_plugin.get_ports_count(
                context, port_filters)
            # port count is checked against 2 since the current port is already
            # added to db
            if port_count == 2:
                # This subnet is already part of some router
                LOG.error(
                    _LE("FortinetL3ServicePlugin: adding redundant "
                        "router interface is not supported"))
                raise Exception(
                    _("FortinetL3ServicePlugin:adding redundant "
                      "router interface is not supported"))
            try:
                db_namespace = fortinet_db.query_record(
                    context,
                    fortinet_db.Fortinet_ML2_Namespace,
                    tenant_id=tenant_id)
                vlan_inf = utils.get_intf(context, network_id)
                int_intf, ext_intf = utils.get_vlink_intf(
                    self, context, vdom=db_namespace.vdom)
                utils.add_fwpolicy(self,
                                   context,
                                   vdom=db_namespace.vdom,
                                   srcintf=vlan_inf,
                                   dstintf=int_intf,
                                   nat='enable')

            except Exception as e:
                LOG.error(
                    _LE("Failed to create Fortinet resources to add "
                        "router interface. info=%(info)s, "
                        "router_id=%(router_id)s"), {
                            "info": info,
                            "router_id": router_id
                        })
                utils._rollback_on_err(self, context, e)
                with excutils.save_and_reraise_exception():
                    self.remove_router_interface(context, router_id,
                                                 interface_info)
        utils.update_status(self, context, t_consts.TaskStatus.COMPLETED)
        return info
 def _update_firewall_rule(self, context, id, firewall_rule):
     LOG.debug("# _add_firewall_rule() called")
     fwps_int = fortinet_db.Fortinet_FW_Rule_Association.query_all(
         context, fwr_id=id, type=constants.TYPE_INT)
     fwps_ext = fortinet_db.Fortinet_FW_Rule_Association.query_all(
         context, fwr_id=id, type=constants.TYPE_EXT)
     if fwps_ext and fwps_int:
         fwps = fwps_int + fwps_ext
     else:
         fwps = fwps_int or fwps_ext
     if not fwps:
         return
     firewall_rule.setdefault('id', id)
     srcaddr = self._make_fortinet_fwaddress_dict(
         place='source_ip_address', **firewall_rule)
     dstaddr = self._make_fortinet_fwaddress_dict(
         place='destination_ip_address', **firewall_rule)
     service = self._make_fortinet_fwservice_dict(**firewall_rule)
     action = self._get_fwr_action(**firewall_rule)
     profiles = self._get_fwp_profiles(action)
     for fwp in fwps_int:
         vdom = fwp.fortinet_policy.vdom
         if service['name'] != 'ALL':
             utils.set_fwservice(self, context, vdom=vdom, **service)
         if srcaddr['name'] != 'all':
             utils.set_fwaddress(self, context, vdom=vdom, **srcaddr)
         if dstaddr['name'] != 'all':
             utils.set_fwaddress(self, context, vdom=vdom, **dstaddr)
     # check whether related firewall policies need to update
     fwp = fwps_int[0].fortinet_policy
     name = firewall_rule.setdefault('name', fwp.comments)
     if fwp.srcaddr == srcaddr['name'] and fwp.action == action and \
         fwp.dstaddr == dstaddr['name'] and fwp.service == service['name']:
         return
     if action in ['accept']:
         for fwp in fwps:
             fortinet_fwp = utils.set_fwpolicy(self, context,
                                               id=fwp.fortinet_pid,
                                               srcaddr=srcaddr['name'],
                                               dstaddr=dstaddr['name'],
                                               service=service['name'],
                                               action=action,
                                               comments=name,
                                               **profiles)
             if not fwps_ext:
                 inf_int, inf_ext = utils.get_vlink_intf(
                     self, context, vdom=fortinet_fwp.vdom)
                 utils.add_fwaas_subpolicy(self, context,
                                           before=fortinet_fwp.edit_id,
                                           vdom=fortinet_fwp.vdom,
                                           srcaddr=srcaddr['name'],
                                           dstaddr=dstaddr['name'],
                                           dstintf=inf_int,
                                           nat='enable',
                                           service=service['name'],
                                           action=action,
                                           comments=name,
                                           fwr_id=id,
                                           type=constants.TYPE_EXT,
                                           **profiles)
     elif action in ['deny']:
         for fwp_ext in fwps_ext:
             utils.delete_fwaas_subpolicy(self, context,
                                          fwr_id=fwp_ext.fwr_id,
                                          fortinet_pid=fwp_ext.fortinet_pid)
         for fwp in fwps_int:
             utils.set_fwpolicy(self, context,
                                id=fwp.fortinet_pid,
                                srcaddr=srcaddr['name'],
                                dstaddr=dstaddr['name'],
                                service=service['name'],
                                action=action,
                                comments=name,
                                **profiles)
     for fwp in fwps_int:
         vdom = fwp.fortinet_policy.vdom
         if service['name'] == 'ALL':
             #delete all old services if exist
             utils.delete_fwservice(self, context, vdom=vdom, name=id)
         if srcaddr['name'] == 'all':
             name = constants.PREFIX['source_ip_address'] + id
             utils.delete_fwaddress(self, context, vdom=vdom, name=name)
         if dstaddr['name'] == 'all':
             name = constants.PREFIX['destination_ip_address'] + id
             utils.delete_fwaddress(self, context, vdom=vdom, name=name)
    def _add_firewall_rule(self, context, fwp_tenant_id, **fwr):
        """
        :param obj:
        :param context:
        :param kwargs: dictionary, firewall rule
        firewall_rule: {'source_ip_address': u'192.176.10.0/24',... }
        :return:
        """
        LOG.debug("# _add_firewall_rule() called")
        namespace = fortinet_db.Fortinet_ML2_Namespace.query_one(
            context, tenant_id=fwp_tenant_id)
        vdom = getattr(namespace, 'vdom', None)
        if not vdom or not fwr:
            return None
        inf_int, inf_ext = utils.get_vlink_intf(
            self, context, vdom=namespace.vdom)
        srcaddr = self._add_fwr_ip_address(
            context, vdom, place='source_ip_address', **fwr)
        dstaddr = self._add_fwr_ip_address(
            context, vdom, place='destination_ip_address', **fwr)
        service = self._add_fwr_service(context, vdom, **fwr)
        action = self._get_fwr_action(**fwr)
        profiles = self._get_fwp_profiles(action)
        match_vip = 'enable'
        name = fwr.get('name', '')
        # add a basic firewall rule('accept': incoming, 'deny': bidirectional)
        fortinet_fwp = utils.add_fwpolicy_to_head(self, context,
                                                  vdom=vdom,
                                                  srcaddr=srcaddr['name'],
                                                  srcintf='any',
                                                  dstaddr=dstaddr['name'],
                                                  dstintf='any',
                                                  service=service['name'],
                                                  match_vip=match_vip,
                                                  action=action,
                                                  comments=name,
                                                  **profiles)
        utils.add_record(self, context,
                         fortinet_db.Fortinet_FW_Rule_Association,
                         fwr_id=fwr['id'],
                         fortinet_pid=fortinet_fwp.id,
                         type=constants.TYPE_INT)

        if action in ['accept']:
            # if allow, for the outgoing traffic it need to enable nat
            fortinet_fwp = utils.add_fwpolicy_to_head(self, context,
                                                      vdom=vdom,
                                                      srcaddr=srcaddr['name'],
                                                      srcintf='any',
                                                      dstaddr=dstaddr['name'],
                                                      dstintf=inf_int,
                                                      nat='enable',
                                                      service=service['name'],
                                                      action=action,
                                                      comments=name,
                                                      **profiles)
            utils.add_record(self, context,
                             fortinet_db.Fortinet_FW_Rule_Association,
                             fwr_id=fwr['id'],
                             fortinet_pid=fortinet_fwp.id,
                             type=constants.TYPE_EXT)