Exemplo n.º 1
0
 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)
Exemplo n.º 2
0
 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)
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
 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
Exemplo n.º 5
0
    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()
Exemplo n.º 6
0
    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()
Exemplo n.º 7
0
    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()
Exemplo n.º 8
0
 def get_node_tag(self, o, node, tagname):
     tags = Tag.select_by_content_object(node).filter(name=tagname)
     return tags[0].value
Exemplo n.º 9
0
 def get_node_tag(self, o, node, tagname):
     tags = Tag.select_by_content_object(node).filter(name=tagname)
     return tags[0].value
Exemplo n.º 10
0
    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}})
Exemplo n.º 11
0
    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