def _get_vip_cidr(self, a10_context, os_context, vip, v1=False): db = NeutronDbWrapper(os_context.session) if v1 is True: sid = vip["subnet_id"] else: sid = vip.vip_subnet_id vip_subnet_info = db.get_subnet(sid) return self._format_cidr(vip_subnet_info.cidr)
def _get_vip_cidr(self, a10_context, os_context, vip, v1=False): db = NeutronDbWrapper(os_context.session) acos = AcosWrapper(a10_context.client) config = a10_context.a10_driver.config if v1 is True: sid = vip["subnet_id"] else: sid = vip.vip_subnet_id vip_subnet_info = db.get_subnet(sid) return self._format_cidr(vip_subnet_info.cidr)
def partition_delete_last(self, client, openstack_context, name, lbaas_obj): # After partition delete, remove any neutron ports created by this hook owned by the tenant # Make sure the last object is an LB. The data model ensures this but ... just in case. # or type(lbaas_obj).__name__ != "LoadBalancer": if not lbaas_obj: LOG.info("No lbaas obj was set for cleanup, exiting cleanup") return db = NeutronDbWrapper(openstack_context.session) LOG.info("Cleanup ports for {0}".format(name)) db.cleanup_vlan_ports(lbaas_obj)
def _create_nat_pool(self, a10_context, os_context, vip, v1=False): msg = "CREATE_NAT", (v1 is True), v1, type(v1) LOG.debug(msg) db = NeutronDbWrapper(os_context.session) acos = AcosWrapper(a10_context.client) config = a10_context.a10_driver.config vip_cidr = self._get_vip_cidr(a10_context, os_context, vip, v1=v1) if v1 is True: try: acos.create_nat_pool(vip['id'], vip['address'], vip['address'], vip_cidr) except Exception as ex: raise ex else: try: acos.create_nat_pool(vip.id, vip.vip_address, vip.vip_address, vip_cidr) except Exception as ex: raise ex
def after_vip_create(self, a10_context, os_context, vip): # Get the IDs of all the things we need. db = NeutronDbWrapper(os_context.session) acos = AcosWrapper(a10_context.client) config = a10_context.a10_driver.config # v2 obj model if hasattr(vip, "vip_port"): vip_port = vip.vip_port subnet_id = vip.vip_subnet_id subnet = db.get_subnet(subnet_id) port_id = vip_port.id network_id = vip_port.network_id tenant_id = vip.tenant_id vip_id = vip.id # v1 obj model else: subnet_id = vip["subnet_id"] port_id = vip["port_id"] subnet = db.get_subnet(subnet_id) network_id = subnet["network_id"] tenant_id = vip["tenant_id"] vip_id = vip["id"] try: binding_level = config.get("vlan_binding_level") except Exception as ex: # If binding_level isn't configured, there is a lot that can go wrong. # Log an error and bail. # TODO(mdurrant) Narrow exception handling retrieving binding level raise ex # Get {network_id} attached to the port.network_id # Get the segment associated to {network_id} with the network matching our criteria segment = db.get_segment(port_id, binding_level) # Get {vlan_id} from the segment vlan_id = segment.segmentation_id ve = None # Is there one assigned to the segment? if not vlan_id: LOG.info( "No VLAN ID for port {0} on segment {1}. Exiting hook.".format( port_id, segment.id)) return # Format the string we're going to use a gazillion times for logging. # Get the associated VE ve = acos.get_ve(vlan_id) # If the VE already exists, the VLAN already exists and in most cases we're done. # Log that this happened. # TODO(mdurrant) - Find a way to check if it's in another partition and gripe loudly. if ve: LOG.info( "Configuration for {0} previously created".format(vlan_id)) return # If DHCP, we can configure the interface with DHCP use_dhcp = config.get("plumb_vlan_dhcp") # Create the VLAN with configured interfaces interfaces = config.get("vlan_interfaces") acos.create_vlan(vlan_id, interfaces) # Get the MAC of the VE so we can create the port. ve_pre = acos.get_ve(vlan_id) ve_mac = ve_pre.get("ve", {}).get("oper", {}).get("mac") if not ve_mac: LOG.error( "Could not retrieve VE MAC, port binding operation failed.") return ve_mac = self._format_mac(ve_mac) # Create a neutron port for VE interface using returned VE MAC ve_nport = db.create_port(network_id, tenant_id, ve_mac, network_id) # Get the vips port from neutron vip_port = db.get_port(port_id) vip_mac = vip_port["mac_address"] acos.update_vip(vip_id, vip_mac, vlan_id) LOG.info("Updated VIP {0} with mac {1} vlan {2}".format( vip_id, vip_mac, vlan_id)) # TODO(mdurrant) - Should host be blank ve_portbinding = db.create_port_binding(ve_nport.id, "") assert (ve_portbinding is not None) # Set defaults ve_ip, ve_mask, ve_port = None, None, ve_nport.id if not use_dhcp: # Allocate IP from the subnet. ve_ip, ve_mask, ve_port = db.allocate_ip_for_subnet( subnet_id, ve_mac, ve_nport.id) LOG.info("Created VLAN {0} with interfaces {1}".format( str(vlan_id), str(interfaces))) ve_dict = self._build_ve_dict(vlan_id, ve_ip, ve_mask, use_dhcp) # Try to create it. If an exception is raised, it's logged and we stop here. ve_created = acos.create_ve(ve_dict) if not ve_created: LOG.error( "Exception creating VE interface for VLAN:{0}".format(vlan_id)) return # Log the created VE for troubleshooting purposes. LOG.info("Created VE {0}", str(vlan_id)) # Get the IP address of the port # if use_dhcp: # LOG.info("VE {0}", str(ve_created)) # Else, it already exists and we're good LOG.info("Configured {0} with interface IP: {1}".format( vlan_id, ve_ip))
def after_vip_create(self, a10_context, os_context, vip): # Get the IDs of all the things we need. db = NeutronDbWrapper(os_context.session) acos = AcosWrapper(a10_context.client) config = a10_context.a10_driver.config # v2 obj model if hasattr(vip, "vip_port"): vip_port = vip.vip_port subnet_id = vip.vip_subnet_id subnet = db.get_subnet(subnet_id) port_id = vip_port.id network_id = vip_port.network_id tenant_id = vip.tenant_id vip_id = vip.id # v1 obj model else: subnet_id = vip["subnet_id"] port_id = vip["port_id"] subnet = db.get_subnet(subnet_id) network_id = subnet["network_id"] tenant_id = vip["tenant_id"] vip_id = vip["id"] try: binding_level = config.get("vlan_binding_level") except Exception as ex: # If binding_level isn't configured, there is a lot that can go wrong. # Log an error and bail. # TODO(mdurrant) Narrow exception handling retrieving binding level raise ex # Get {network_id} attached to the port.network_id # Get the segment associated to {network_id} with the network matching our criteria segment = db.get_segment(port_id, binding_level) # Get {vlan_id} from the segment vlan_id = segment.segmentation_id ve = None # Is there one assigned to the segment? if not vlan_id: LOG.info( "No VLAN ID for port {0} on segment {1}. Exiting hook.".format(port_id, segment.id)) return # Format the string we're going to use a gazillion times for logging. # Get the associated VE ve = acos.get_ve(vlan_id) # If the VE already exists, the VLAN already exists and in most cases we're done. # Log that this happened. # TODO(mdurrant) - Find a way to check if it's in another partition and gripe loudly. if ve: LOG.info("Configuration for {0} previously created".format(vlan_id)) return # If DHCP, we can configure the interface with DHCP use_dhcp = config.get("plumb_vlan_dhcp") # Create the VLAN with configured interfaces interfaces = config.get("vlan_interfaces") acos.create_vlan(vlan_id, interfaces) # Get the MAC of the VE so we can create the port. ve_pre = acos.get_ve(vlan_id) ve_mac = ve_pre.get("ve", {}).get("oper", {}).get("mac") if not ve_mac: LOG.error("Could not retrieve VE MAC, port binding operation failed.") return ve_mac = self._format_mac(ve_mac) # Create a neutron port for VE interface using returned VE MAC ve_nport = db.create_port(network_id, tenant_id, ve_mac, network_id) # Get the vips port from neutron vip_port = db.get_port(port_id) vip_mac = vip_port["mac_address"] acos.update_vip(vip_id, vip_mac, vlan_id) LOG.info("Updated VIP {0} with mac {1} vlan {2}".format(vip_id, vip_mac, vlan_id)) # TODO(mdurrant) - Should host be blank ve_portbinding = db.create_port_binding(ve_nport.id, "") assert(ve_portbinding is not None) # Set defaults ve_ip, ve_mask, ve_port = None, None, ve_nport.id if not use_dhcp: # Allocate IP from the subnet. ve_ip, ve_mask, ve_port = db.allocate_ip_for_subnet(subnet_id, ve_mac, ve_nport.id) LOG.info("Created VLAN {0} with interfaces {1}".format(str(vlan_id), str(interfaces))) ve_dict = self._build_ve_dict(vlan_id, ve_ip, ve_mask, use_dhcp) # Try to create it. If an exception is raised, it's logged and we stop here. ve_created = acos.create_ve(ve_dict) if not ve_created: LOG.error("Exception creating VE interface for VLAN:{0}".format(vlan_id)) return # Log the created VE for troubleshooting purposes. LOG.info("Created VE {0}", str(vlan_id)) # Get the IP address of the port # if use_dhcp: # LOG.info("VE {0}", str(ve_created)) # Else, it already exists and we're good LOG.info("Configured {0} with interface IP: {1}".format( vlan_id, ve_ip))