def wan_vm_mac(self): tags = Tag.select_by_content_object(self.instance).filter(name="vm_vrouter_tenant") if tags: tenant = VRouterTenant.objects.get(id=tags[0].value) return tenant.public_mac else: raise Exception("no vm_vrouter_tenant tag for instance %s" % o.instance)
def wan_vm_mac(self): tags = Tag.select_by_content_object(self.instance).filter(name="vm_vrouter_tenant") if tags: tenant = VRouterTenant.objects.get(id=tags[0].value) return tenant.public_mac else: raise Exception("no vm_vrouter_tenant tag for instance %s" % o.instance)
def get_extra_attributes(self, o): vtr_service = self.get_vtr_service(o) vcpe_service = self.get_vcpe_service(o) if not vcpe_service: raise Exception("No vcpeservice") instance = self.get_instance(o) if not instance: raise Exception("No instance") s_tags = [] c_tags = [] if o.target and o.target.volt: s_tags.append(o.target.volt.s_tag) c_tags.append(o.target.volt.c_tag) wan_vm_ip="" wan_vm_mac="" tags = Tag.select_by_content_object(instance).filter(name="vm_wan_addr") if tags: parts=tags[0].value.split(",") if len(parts)!=3: raise Exception("vm_wan_addr tag is malformed: %s" % value) wan_vm_ip = parts[1] wan_vm_mac = parts[2] else: if CORD_USE_VTN: raise Exception("no vm_wan_addr tag for instance %s" % instance) fields = {"s_tags": s_tags, "c_tags": c_tags, "isolation": instance.isolation, "wan_container_gateway_mac": vcpe_service.wan_container_gateway_mac, "wan_container_gateway_ip": vcpe_service.wan_container_gateway_ip, "wan_container_netbits": vcpe_service.wan_container_netbits, "wan_vm_mac": wan_vm_mac, "wan_vm_ip": wan_vm_ip, "container_name": "vcpe-%s-%s" % (s_tags[0], c_tags[0]), "dns_servers": [x.strip() for x in vcpe_service.dns_servers.split(",")], "result_fn": "%s-vcpe-%s-%s" % (o.test, s_tags[0], c_tags[0]), "resultcode_fn": "code-%s-vcpe-%s-%s" % (o.test, s_tags[0], c_tags[0]) } # add in the sync_attributes that come from the SubscriberRoot object if o.target and hasattr(o.target, "sync_attributes"): for attribute_name in o.target.sync_attributes: fields[attribute_name] = getattr(o.target, attribute_name) for attribute_name in o.sync_attributes: fields[attribute_name] = getattr(o,attribute_name) return fields
def node_tag_default(self, o, node, tagname, default): tags = Tag.select_by_content_object(node).filter(name=tagname) if tags: value = tags[0].value else: value = default logger.info("node %s: saving default value %s for tag %s" % (node.name, value, tagname)) service = self.get_onos_service(o) tag = Tag(service=service, content_object=node, name=tagname, value=value) tag.save() return value
def save_instance(self, instance): with transaction.atomic(): instance.volumes = "/etc/dnsmasq.d,/etc/ufw" super(VSGTenant, self).save_instance(instance) if instance.isolation in ["container", "container_vm"]: lan_network = self.get_lan_network(instance) port = self.find_or_make_port(instance, lan_network, ip="192.168.0.1", port_id="unmanaged") port.set_parameter("c_tag", self.volt.c_tag) port.set_parameter("s_tag", self.volt.s_tag) port.set_parameter("device", "eth1") port.set_parameter("bridge", "br-lan") wan_networks = [x for x in instance.slice.networks.all() if "wan" in x.name] if not wan_networks: raise XOSProgrammingError("No wan_network") port = self.find_or_make_port(instance, wan_networks[0]) port.set_parameter("next_hop", value="10.0.1.253") # FIX ME port.set_parameter("device", "eth0") if instance.isolation in ["vm"]: lan_network = self.get_lan_network(instance) port = self.find_or_make_port(instance, lan_network) port.set_parameter("c_tag", self.volt.c_tag) port.set_parameter("s_tag", self.volt.s_tag) port.set_parameter("neutron_port_name", "stag-%s" % self.volt.s_tag) port.save() # tag the instance with the s-tag, so we can easily find the # instance later if self.volt and self.volt.s_tag: tags = Tag.objects.filter(name="s_tag", value=self.volt.s_tag) if not tags: tag = Tag(service=self.provider_service, content_object=instance, name="s_tag", value=self.volt.s_tag) tag.save() # VTN-CORD needs a WAN address for the VM, so that the VM can # be configured. if CORD_USE_VTN: tags = Tag.select_by_content_object(instance).filter(name="vm_vrouter_tenant") if not tags: vrouter = self.get_vrouter_service().get_tenant(address_pool_name="addresses_vsg", subscriber_service = self.provider_service) vrouter.set_attribute("tenant_for_instance_id", instance.id) vrouter.save() tag = Tag(service=self.provider_service, content_object=instance, name="vm_vrouter_tenant", value="%d" % vrouter.id) tag.save()
def save_instance(self, instance): with transaction.atomic(): instance.volumes = "/etc/dnsmasq.d,/etc/ufw" super(VSGTenant, self).save_instance(instance) if instance.isolation in ["container", "container_vm"]: lan_network = self.get_lan_network(instance) port = self.find_or_make_port(instance, lan_network, ip="192.168.0.1", port_id="unmanaged") port.set_parameter("c_tag", self.volt.c_tag) port.set_parameter("s_tag", self.volt.s_tag) port.set_parameter("device", "eth1") port.set_parameter("bridge", "br-lan") wan_networks = [x for x in instance.slice.networks.all() if "wan" in x.name] if not wan_networks: raise XOSProgrammingError("No wan_network") port = self.find_or_make_port(instance, wan_networks[0]) port.set_parameter("next_hop", value="10.0.1.253") # FIX ME port.set_parameter("device", "eth0") if instance.isolation in ["vm"]: lan_network = self.get_lan_network(instance) port = self.find_or_make_port(instance, lan_network) port.set_parameter("c_tag", self.volt.c_tag) port.set_parameter("s_tag", self.volt.s_tag) port.set_parameter("neutron_port_name", "stag-%s" % self.volt.s_tag) port.save() # tag the instance with the s-tag, so we can easily find the # instance later if self.volt and self.volt.s_tag: tags = Tag.objects.filter(name="s_tag", value=self.volt.s_tag) if not tags: tag = Tag(service=self.provider_service, content_object=instance, name="s_tag", value=self.volt.s_tag) tag.save() # VTN-CORD needs a WAN address for the VM, so that the VM can # be configured. if CORD_USE_VTN: tags = Tag.select_by_content_object(instance).filter(name="vm_vrouter_tenant") if not tags: vrouter = self.get_vrouter_service().get_tenant(address_pool_name="addresses_vsg", subscriber_service = self.provider_service) vrouter.set_attribute("tenant_for_instance_id", instance.id) vrouter.save() tag = Tag(service=self.provider_service, content_object=instance, name="vm_vrouter_tenant", value="%d" % vrouter.id) tag.save()
def manage_vcpe(self): # Each VOLT object owns exactly one VCPE object if self.deleted: return # Check to see if the wrong s-tag is set. This can only happen if the # user changed the s-tag after the VoltTenant object was created. if self.vcpe and self.vcpe.instance: s_tags = Tag.select_by_content_object(self.vcpe.instance).filter(name="s_tag") if s_tags and (s_tags[0].value != str(self.s_tag)): self.vcpe.delete() if self.vcpe is None: from services.vsg.models import VSGService, VSGTenant vsgServices = VSGService.get_service_objects().all() if not vsgServices: raise XOSConfigurationError("No VSG Services available") vcpe = VSGTenant(provider_service = vsgServices[0], subscriber_tenant = self) vcpe.caller = self.creator vcpe.save()
def get_node_tag(self, o, node, tagname): tags = Tag.select_by_content_object(node).filter(name=tagname) return tags[0].value
def get_node_tag(self, o, node, tagname): tags = Tag.select_by_content_object(node).filter(name=tagname) return tags[0].value
def call(self, **args): global glo_saved_vtn_maps logger.info("sync'ing vsg tenant to port addresses") # build up a dictionary of port-->[wan_addrs] mappings port_addrs = {} for vsg in VSGTenant.get_tenant_objects().all(): if not vsg.instance: logger.info("skipping vsg %s because it has no instance" % vsg) wan_ip = vsg.wan_container_ip if not wan_ip: logger.info("skipping vsg %s because it has no wan_container_ip" % vsg) wan_mac = vsg.wan_container_mac if not wan_mac: logger.info("skipping vsg %s because it has no wan_container_mac" % vsg) lan_network = vsg.get_lan_network(vsg.instance) if not lan_network: logger.info("skipping vsg %s because it has no lan_network" % vsg) lan_port = Port.objects.filter(instance = vsg.instance, network=lan_network) if not lan_port: logger.info("skipping vsg %s because it has no lan_port" % vsg) lan_port = lan_port[0] if not lan_port.port_id: logger.info("skipping vsg %s because its lan_port has no port_id" % vsg) if not (lan_port.pk in port_addrs): port_addrs[lan_port.pk] = [] entry = {"mac_address": wan_mac, "ip_address": wan_ip} addr_pairs = port_addrs[lan_port.pk] if not entry in addr_pairs: addr_pairs.append(entry) # now do the VM_WAN_IP from the instance if vsg.instance: tags=Tag.select_by_content_object(vsg.instance).filter(name="vm_wan_addr") if tags: parts=tags[0].value.split(",") if len(parts)!=3: raise Exception("vm_wan_addr tag is malformed: %s" % value) entry = {"mac_address": parts[2], "ip_address": parts[1]} if not entry in addr_pairs: addr_pairs.append(entry) # Get all ports in all controllers ports_by_id = {} for controller in Controller.objects.all(): if not controller.admin_tenant: logger.info("controller %s has no admin_tenant" % controller) continue try: driver = self.driver.admin_driver(controller = controller) ports = driver.shell.quantum.list_ports()["ports"] except: logger.log_exc("failed to get ports from controller %s" % controller) continue for port in ports: ports_by_id[port["id"]] = port for port_pk in port_addrs.keys(): port = Port.objects.get(pk=port_pk) addr_pairs = port_addrs[port_pk] neutron_port = ports_by_id.get(port.port_id,None) if not neutron_port: logger.info("failed to get neutron port for port %s" % port) continue ips = [x["ip_address"] for x in addr_pairs] changed = False # delete addresses in neutron that don't exist in XOS aaps = neutron_port.get("allowed_address_pairs", []) for aap in aaps[:]: if not aap["ip_address"] in ips: logger.info("removing address %s from port %s" % (aap["ip_address"], port)) aaps.remove(aap) changed = True aaps_ips = [x["ip_address"] for x in aaps] # add addresses in XOS that don't exist in neutron for addr in addr_pairs: if not addr["ip_address"] in aaps_ips: logger.info("adding address %s to port %s" % (addr, port)) aaps.append( addr ) aaps_ips.append(addr["ip_address"]) changed = True if changed: logger.info("updating port %s" % port) driver.shell.quantum.update_port(port.port_id, {"port": {"allowed_address_pairs": aaps}})
def get_extra_attributes(self, o): # This is a place to include extra attributes that aren't part of the # object itself. In the case of vCPE, we need to know: # 1) the addresses of dnsdemux, to setup dnsmasq in the vCPE # 2) CDN prefixes, so we know what URLs to send to dnsdemux # 3) BroadBandShield server addresses, for parental filtering # 4) vlan_ids, for setting up networking in the vCPE VM vcpe_service = self.get_vcpe_service(o) dnsdemux_ip = None cdn_prefixes = [] cdn_config_fn = "/opt/xos/synchronizers/vcpe/cdn_config" if os.path.exists(cdn_config_fn): # manual CDN configuration # the first line is the address of dnsredir # the remaining lines are domain names, one per line lines = file(cdn_config_fn).readlines() if len(lines)>=2: dnsdemux_ip = lines[0].strip() cdn_prefixes = [x.strip() for x in lines[1:] if x.strip()] else: # automatic CDN configuiration # it learns everything from CDN objects in XOS # not tested on pod. if vcpe_service.backend_network_label: # Connect to dnsdemux using the network specified by # vcpe_service.backend_network_label for service in HpcService.objects.all(): for slice in service.slices.all(): if "dnsdemux" in slice.name: for instance in slice.instances.all(): for ns in instance.ports.all(): if ns.ip and ns.network.labels and (vcpe_service.backend_network_label in ns.network.labels): dnsdemux_ip = ns.ip if not dnsdemux_ip: logger.info("failed to find a dnsdemux on network %s" % vcpe_service.backend_network_label) else: # Connect to dnsdemux using the instance's public address for service in HpcService.objects.all(): for slice in service.slices.all(): if "dnsdemux" in slice.name: for instance in slice.instances.all(): if dnsdemux_ip=="none": try: dnsdemux_ip = socket.gethostbyname(instance.node.name) except: pass if not dnsdemux_ip: logger.info("failed to find a dnsdemux with a public address") for prefix in CDNPrefix.objects.all(): cdn_prefixes.append(prefix.prefix) dnsdemux_ip = dnsdemux_ip or "none" # Broadbandshield can either be set up internally, using vcpe_service.bbs_slice, # or it can be setup externally using vcpe_service.bbs_server. bbs_addrs = [] if vcpe_service.bbs_slice: if vcpe_service.backend_network_label: for bbs_instance in vcpe_service.bbs_slice.instances.all(): for ns in bbs_instance.ports.all(): if ns.ip and ns.network.labels and (vcpe_service.backend_network_label in ns.network.labels): bbs_addrs.append(ns.ip) else: logger.info("unsupported configuration -- bbs_slice is set, but backend_network_label is not") if not bbs_addrs: logger.info("failed to find any usable addresses on bbs_slice") elif vcpe_service.bbs_server: bbs_addrs.append(vcpe_service.bbs_server) else: logger.info("neither bbs_slice nor bbs_server is configured in the vCPE") vlan_ids = [] s_tags = [] c_tags = [] if o.volt: vlan_ids.append(o.volt.vlan_id) # XXX remove this s_tags.append(o.volt.s_tag) c_tags.append(o.volt.c_tag) try: full_setup = Config().observer_full_setup except: full_setup = True safe_macs=[] if vcpe_service.url_filter_kind == "safebrowsing": if o.volt and o.volt.subscriber: for user in o.volt.subscriber.users: level = user.get("level",None) mac = user.get("mac",None) if level in ["G", "PG"]: if mac: safe_macs.append(mac) wan_vm_ip="" wan_vm_mac="" tags = Tag.select_by_content_object(o.instance).filter(name="vm_wan_addr") if tags: parts=tags[0].value.split(",") if len(parts)!=3: raise Exception("vm_wan_addr tag is malformed: %s" % value) wan_vm_ip = parts[1] wan_vm_mac = parts[2] else: if CORD_USE_VTN: raise Exception("no vm_wan_addr tag for instance %s" % o.instance) fields = {"vlan_ids": vlan_ids, # XXX remove this "s_tags": s_tags, "c_tags": c_tags, "dnsdemux_ip": dnsdemux_ip, "cdn_prefixes": cdn_prefixes, "bbs_addrs": bbs_addrs, "full_setup": full_setup, "isolation": o.instance.isolation, "wan_container_gateway_mac": vcpe_service.wan_container_gateway_mac, "wan_container_gateway_ip": vcpe_service.wan_container_gateway_ip, "wan_container_netbits": vcpe_service.wan_container_netbits, "wan_vm_mac": wan_vm_mac, "wan_vm_ip": wan_vm_ip, "safe_browsing_macs": safe_macs, "container_name": "vcpe-%s-%s" % (s_tags[0], c_tags[0]), "dns_servers": [x.strip() for x in vcpe_service.dns_servers.split(",")], "url_filter_kind": vcpe_service.url_filter_kind } # add in the sync_attributes that come from the SubscriberRoot object if o.volt and o.volt.subscriber and hasattr(o.volt.subscriber, "sync_attributes"): for attribute_name in o.volt.subscriber.sync_attributes: fields[attribute_name] = getattr(o.volt.subscriber, attribute_name) return fields