def Fortinet_init(self): """Fortinet specific initialization for this class.""" LOG.debug("FortinetMechanismDriver_init") self._fortigate = config.fgt_info self._driver = config.get_apiclient() for key in const.FORTINET_PARAMS: self.sync_conf_to_db(key) session = db_api.get_session() try: LOG.error(">>>---<<<<<<<<<<") LOG.error(session) LOG.error(const.EXT_VDOM) LOG.error(const.FAKE_TENANT_ID) utils.add_vdom(self, session, vdom=const.EXT_VDOM, tenant_id=const.FAKE_TENANT_ID) LOG.error(">>>---<<<<<<<<<<") LOG.error(self._fortigate['ext_interface']) utils.set_vlanintf(self, session, vdom=const.EXT_VDOM, name=self._fortigate['ext_interface']) except Exception as e: utils._rollback_on_err(self, session, e) raise ml2_exc.MechanismDriverError( method=sys._getframe().f_code.co_name) utils.update_status(self, session, t_consts.TaskStatus.COMPLETED)
def insert_rule(self, context, id, rule_info): self._ensure_update_firewall_policy(context, id) try: fwp = super(FortinetFirewallPlugin, self).insert_rule(context, id, rule_info) self._rpc_update_firewall_policy(context, id) utils.update_status(self, context, t_consts.TaskStatus.COMPLETED) return fwp except Exception as e: with excutils.save_and_reraise_exception(): self.remove_rule(context, id, rule_info) utils._rollback_on_err(self, context, e)
def create_router(self, context, router): LOG.info("create_router: router=%s" % (router)) # Limit one router per tenant if not router.get('router', None): return tenant_id = router['router']['tenant_id'] with context.session.begin(subtransactions=True): try: namespace = utils.add_vdom(self, context, tenant_id=tenant_id) utils.add_vlink(self, context, namespace.vdom) except Exception as e: LOG.error("Failed to create_router router=%(router)s", {"router": router}) resources.Exinfo(e) utils._rollback_on_err(self, context, e) utils.update_status(self, context, t_consts.TaskStatus.COMPLETED)
def update_firewall_rule(self, context, id, firewall_rule): LOG.debug( "update_firewall_rule() id: %(id)s, " "firewall_rule: %(firewall_rule)s", { 'id': id, 'firewall_rule': firewall_rule }) try: fwr = self._update_firewall_rule_dict(context, id, firewall_rule) self._update_firewall_rule(context, id, fwr) self._ensure_update_firewall_rule(context, id) fwr = super(FortinetFirewallPlugin, self).update_firewall_rule(context, id, firewall_rule) utils.update_status(self, context, t_consts.TaskStatus.COMPLETED) return fwr except Exception as e: with excutils.save_and_reraise_exception(): LOG.error(_LE("update_firewall_rule %(fwr)s failed"), {'fwr': firewall_rule}) utils._rollback_on_err(self, context, e)
def create_network_postcommit(self, mech_context): """Create Network as a portprofile on the fortigate.""" LOG.debug("create_network_postcommit: called") network = mech_context.current if network["router:external"]: # TODO(samsu) return # use network_id to get the network attributes # ONLY depend on our db for getting back network attributes # this is so we can replay postcommit from db network_name = network['name'] tenant_id = network['tenant_id'] segment = mech_context.network_segments[0] LOG.debug("network is created in tenant %(tenant_id)s," "segment id is %(segment)s", {"tenant_id": tenant_id, "segment": segment['segmentation_id']}) # currently supports only one segment per network if segment['network_type'] != 'vlan': raise Exception(_("Fortinet Mechanism: failed to create network," "only network type vlan is supported")) vlanid = segment['segmentation_id'] context = mech_context._plugin_context try: namespace = utils.add_vdom(self, context, tenant_id=tenant_id) if not namespace: raise # TODO(samsu): type driver support vlan only, # need to check later inf_name = const.PREFIX['inf'] + str(vlanid) utils.add_vlanintf(self, context, name=inf_name, vdom=namespace.vdom, vlanid=vlanid, interface=self._fortigate['int_interface'], alias=network_name) except Exception as e: utils._rollback_on_err(self, context, e) raise ml2_exc.MechanismDriverError( method=sys._getframe().f_code.co_name) utils.update_status(self, context, t_consts.TaskStatus.COMPLETED)
def create_router(self, context, router): LOG.debug("create_router: router=%s", router) # Limit one router per tenant if not router.get('router', None): return tenant_id = router['router']['tenant_id'] if fortinet_db.query_count(context, l3_db.Router, tenant_id=tenant_id): raise Exception( _("FortinetL3ServicePlugin:create_router " "Only support one router per tenant")) with context.session.begin(subtransactions=True): try: namespace = utils.add_vdom(self, context, tenant_id=tenant_id) utils.add_vlink(self, context, namespace.vdom) except Exception as e: with excutils.save_and_reraise_exception(): LOG.error(_LE("Failed to create_router router=%(router)s"), {"router": router}) utils._rollback_on_err(self, context, e) utils.update_status(self, context, t_consts.TaskStatus.COMPLETED) return super(FortinetL3ServicePlugin, self).\ create_router(context, router)
def _apply_firewall(self, context, **fw_with_rules): tenant_id = fw_with_rules['tenant_id'] default_fwr = self._make_default_firewall_rule_dict(tenant_id) try: if fw_with_rules.get('del-router-ids', None): for fwr in list(fw_with_rules.get('firewall_rule_list', None)): self._delete_firewall_rule(context, tenant_id, **fwr) if default_fwr: self._delete_firewall_rule(context, tenant_id, **default_fwr) self.update_firewall_status(context, fw_with_rules['id'], const.INACTIVE) if fw_with_rules.get('add-router-ids', None): vdom = getattr( fortinet_db.Fortinet_ML2_Namespace.query_one( context, tenant_id=tenant_id), 'vdom', None) if not vdom: raise fw_ext.FirewallInternalDriverError( driver='Fortinet_fwaas_plugin') if default_fwr: self._add_firewall_rule(context, tenant_id, **default_fwr) for fwr in reversed( list(fw_with_rules.get('firewall_rule_list', None))): self._add_firewall_rule(context, tenant_id, **fwr) self.update_firewall_status(context, fw_with_rules['id'], const.ACTIVE) else: self.update_firewall_status(context, fw_with_rules['id'], const.INACTIVE) except Exception as e: with excutils.save_and_reraise_exception(): LOG.error(_LE("apply_firewall %(fws)s failed"), {'fws': fw_with_rules}) utils._rollback_on_err(self, context, e) utils.update_status(self, context, t_consts.TaskStatus.COMPLETED)
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 create_port_postcommit(self, mech_context): """Associate the assigned MAC address to the portprofile.""" LOG.debug("create_port_postcommit: called") context = mech_context._plugin_context utils.update_status(self, context, t_consts.TaskStatus.COMPLETED)
def create_subnet_postcommit(self, mech_context, update=False): if not update: # log the context for debugging LOG.debug("create_subnetwork_postcommit: called, context %(ctx)s", {'ctx': mech_context.current}) gateway = mech_context.current['gateway_ip'] network_id = mech_context.current['network_id'] subnet_id = mech_context.current['id'] tenant_id = mech_context.current['tenant_id'] context = mech_context._plugin_context dns_nameservers = mech_context.current.setdefault( 'dns_nameservers', []) if update: router_func = utils.set_routerstatic dhcp_func = utils.set_dhcpserver else: router_func = utils.add_routerstatic dhcp_func = utils.add_dhcpserver try: if fortinet_db.query_record(context, ext_db.ExternalNetwork, network_id=network_id): router_func(self, context, subnet_id=subnet_id, vdom=const.EXT_VDOM, dst=const.EXT_DEF_DST, device=self._fortigate['ext_interface'], gateway=gateway) else: namespace = fortinet_db.query_record(context, fortinet_db.Fortinet_ML2_Namespace, tenant_id=tenant_id) interface = utils.get_intf(context, mech_context.current['network_id']) netmask = str(netaddr. IPNetwork(mech_context.current['cidr']).netmask) start_ip = mech_context.current['allocation_pools'][0]['start'] end_ip = mech_context.current['allocation_pools'][0]['end'] dhcp_func(self, context, subnet_id=subnet_id, vdom=namespace.vdom, interface=interface, dns_nameservers=dns_nameservers, gateway=gateway, netmask=netmask, start_ip=start_ip, end_ip=end_ip) # TODO(samsu): need to add rollback for the update and set cls = fortinet_db.Fortinet_Interface record = fortinet_db.query_record(context, cls, name=interface, vdom=namespace.vdom) if gateway: cls.update_record(context, record, ip="%s %s" % (gateway, netmask)) utils.op(self, context, resources.VlanInterface.set, name=interface, vdom=namespace.vdom, ip="%s %s" % (gateway, netmask)) except Exception as e: utils._rollback_on_err(self, context, e) raise ml2_exc.MechanismDriverError( method=sys._getframe().f_code.co_name) if not update: utils.update_status(self, context, t_consts.TaskStatus.COMPLETED)