Example #1
0
    def get(self, network, service_name):
        """
        Get a service in "network" named "service_name".
        """
        logger.debug('Discovering service %s, %s', network.name, service_name)

        # 1. Get list of instances
        instances = []
        node_name = "%s-%s" % (network.name, service_name)
        for node in self.driver.list_nodes():
            if node.name.startswith(node_name):
                instances.append(canonicalize_instance_info(node))

        # 2. Get List Of Subnets
        subnetworks = self.subnetwork.get(network, service_name)
        if not subnetworks:
            return None

        # 3. Group Services By Subnet
        for subnet_info in subnetworks:
            for instance in instances:
                if (instance.private_ip and ipaddress.IPv4Network(
                        subnet_info.cidr_block).overlaps(
                            ipaddress.IPv4Network(instance.private_ip))):
                    subnet_info.instances.append(instance)
        return Service(network=network,
                       name=service_name,
                       subnetworks=subnetworks)
Example #2
0
 def get(self, name):
     """
     Get a image named "name" and return some data about it.
     """
     for image in self.list():
         if image.name == name:
             logger.debug("Got image: %s", image)
             return image
     return None
Example #3
0
 def destroy(self, image):
     """
     Destroy a image given by "image".
     """
     for gce_image in self.driver.list_images(self.driver.project):
         logger.debug("Raw image destroy: %s", gce_image)
         if gce_image.id == image.image_id:
             logger.debug("Destroying image: %s", gce_image)
             return self.driver.ex_delete_image(gce_image)
     return None
Example #4
0
 def get(self, name):
     """
     Get a network named "name" and return some data about it.
     """
     try:
         network = self.driver.ex_get_network(name)
     except ResourceNotFoundError as not_found:
         logger.debug("Caught exception trying to get network: %s", not_found)
         return None
     return canonicalize_network_info(network)
Example #5
0
 def has_access(self, source, destination, port):
     """
     Return true if there's a path between the services.
     """
     logger.debug('Looking for path from %s to %s on port %s', source,
                  destination, 80)
     self._validate_args(source, destination)
     paths = self.list()
     logger.debug('Found paths %s', paths)
     return self._has_access(paths, source, destination, port)
Example #6
0
 def destroy(self, network):
     """
     Destroy a network given by "network".
     """
     try:
         network = self.driver.ex_get_network(network.name)
     except ResourceNotFoundError as not_found:
         logger.debug("Caught exception destroying network, ignoring: %s",
                      not_found)
         return None
     return self.driver.ex_destroy_network(network)
Example #7
0
 def list(self):
     """
     List all images.
     """
     images = []
     for gce_image in self.driver.list_images(self.driver.project):
         logger.debug("Raw image list: %s", gce_image)
         images.append(
             Image(name=gce_image.name,
                   image_id=gce_image.id,
                   created_at=str(gce_image.extra["creationTimestamp"])))
     return images
Example #8
0
def get_gce_driver(credentials):
    """
    Uses the given credentials to get a GCE driver object from libcloud.
    """
    # pylint:disable=global-statement
    global DRIVER
    if not DRIVER:
        logger.debug("GCE driver not initialized, creating.")
        compute_engine_driver = get_driver(Provider.GCE)
        DRIVER = compute_engine_driver(user_id=credentials["user_id"],
                                       key=credentials["key"],
                                       project=credentials["project"])
    return DRIVER
Example #9
0
    def remove(self, source, destination, port):
        """
        Remove path between two services on a given port.
        """
        logger.debug('Removing path from %s to %s on port %s', source,
                     destination, port)

        firewall_name = "bu-%s-%s-%s" % (destination.network.name,
                                         destination.name, port)

        def remove_from_ranges(to_remove, address_ranges):
            logger.debug("Removing %s from %s", to_remove, address_ranges)
            resulting_ranges = []
            if not address_ranges:
                return None
            for address_range in address_ranges:
                remove_net = ipaddress.IPv4Network(to_remove)
                address_range_network = ipaddress.IPv4Network(address_range)
                if remove_net.overlaps(address_range_network):
                    if remove_net.prefixlen > address_range_network.prefixlen:
                        new_range_networks = address_range_network.address_exclude(
                            remove_net)
                        resulting_ranges.extend([
                            str(new_range_network)
                            for new_range_network in new_range_networks
                        ])
                else:
                    resulting_ranges.extend([str(address_range_network)])
            logger.debug("New ranges: %s", resulting_ranges)
            return resulting_ranges

        try:
            firewall = self.driver.ex_get_firewall(firewall_name)
            if isinstance(source, CidrBlock):
                firewall.source_ranges = remove_from_ranges(
                    source.cidr_block, firewall.source_ranges)
            else:
                source_tag = "%s-%s" % (source.network.name, source.name)
                if firewall.source_tags:
                    firewall.source_tags = [
                        tag for tag in firewall.source_tags
                        if tag != source_tag
                    ]
        except ResourceNotFoundError:
            logger.debug("Firewall %s doesn't exist", firewall_name)
            return None

        # We need this because the default is to add "0.0.0.0/0" if these aren't set, which is bad.
        if not firewall.source_tags and not firewall.source_ranges:
            return self.driver.ex_destroy_firewall(firewall)
        return self.driver.ex_update_firewall(firewall)
Example #10
0
 def list(self):
     """
     List all instance groups.
     """
     logger.debug('Listing services')
     subnetworks = self.subnetwork.list()
     services = []
     for network_name, subnet_info in subnetworks.items():
         logger.debug("Subnets in network %s: %s", network_name,
                      subnet_info)
         for subnetwork_name, _ in subnet_info.items():
             # Things might have changed from the time we listed the services, so skip if we
             # can't find them anymore.
             network = self.network.get(network_name)
             if not network:
                 logger.debug("Network %s not found!  %s", network_name,
                              subnet_info)
                 continue
             service = self.get(network, subnetwork_name)
             if not service:
                 logger.debug("Service %s not found!  %s", subnetwork_name,
                              subnet_info)
                 continue
             services.append(service)
     return services
Example #11
0
 def add(self, source, destination, port):
     """
     Add path between two services on a given port.
     """
     logger.debug('Adding path from %s to %s on port %s', source,
                  destination, port)
     rules = [{"IPProtocol": "tcp", "ports": [int(port)]}]
     src_tags, dest_tags, src_ranges, _ = self._extract_service_info(
         source, destination)
     firewall_name = "bu-%s-%s-%s" % (destination.network.name,
                                      destination.name, port)
     try:
         firewall = self.driver.ex_get_firewall(firewall_name)
         if isinstance(source, CidrBlock):
             if not firewall.source_ranges:
                 firewall.source_ranges = []
             firewall.source_ranges.append(str(source.cidr_block))
             logger.debug(firewall.source_ranges)
         if isinstance(source, Service):
             if not firewall.source_tags:
                 firewall.source_tags = []
             source_tag = "%s-%s" % (source.network.name, source.name)
             firewall.source_tags.append(source_tag)
             logger.debug(firewall.source_tags)
         firewall = self.driver.ex_update_firewall(firewall)
     except ResourceNotFoundError:
         logger.debug("Firewall %s not found, creating.", firewall_name)
         firewall = self.driver.ex_create_firewall(
             firewall_name,
             allowed=rules,
             network=destination.network.name,
             source_ranges=src_ranges,
             source_tags=src_tags,
             target_tags=dest_tags)
     return Path(destination.network, source, destination, "tcp", port)
Example #12
0
 def remove_from_ranges(to_remove, address_ranges):
     logger.debug("Removing %s from %s", to_remove, address_ranges)
     resulting_ranges = []
     if not address_ranges:
         return None
     for address_range in address_ranges:
         remove_net = ipaddress.IPv4Network(to_remove)
         address_range_network = ipaddress.IPv4Network(address_range)
         if remove_net.overlaps(address_range_network):
             if remove_net.prefixlen > address_range_network.prefixlen:
                 new_range_networks = address_range_network.address_exclude(
                     remove_net)
                 resulting_ranges.extend([
                     str(new_range_network)
                     for new_range_network in new_range_networks
                 ])
         else:
             resulting_ranges.extend([str(address_range_network)])
     logger.debug("New ranges: %s", resulting_ranges)
     return resulting_ranges
Example #13
0
 def destroy(self, service):
     """
     Destroy a service described by "service".
     """
     logger.debug('Destroying service: %s', service)
     destroy_results = []
     for node in self.driver.list_nodes():
         metadata = node.extra.get("metadata", {}).get("items", [])
         node_network_name = None
         node_subnetwork_name = None
         for item in metadata:
             logger.debug("Found metadata item %s for node %s", item, node)
             if item["key"] == "network":
                 node_network_name = item["value"]
             if item["key"] == "subnetwork":
                 node_subnetwork_name = item["value"]
         if (service.network.name == node_network_name
                 and service.name == node_subnetwork_name):
             logger.info('Destroying instance: %s', node.name)
             destroy_results.append(self.driver.destroy_node(node))
     subnetwork_destroy = self.subnetwork.destroy(service.network.name,
                                                  service.name)
     self.firewalls.delete_firewall(service.network.name, service.name)
     return {"Subnetwork": subnetwork_destroy, "Instances": destroy_results}
Example #14
0
    def create(self, network, service_name, blueprint, template_vars, count):
        """
        Create a service in "network" named "service_name" with blueprint file at "blueprint".
        """
        logger.debug(
            'Creating service %s, %s with blueprint %s and '
            'template_vars %s', network.name, service_name, blueprint,
            template_vars)
        self.subnetwork.create(network.name, service_name, blueprint=blueprint)
        instances_blueprint = ServiceBlueprint.from_file(blueprint)
        az_count = instances_blueprint.availability_zone_count()
        availability_zones = list(
            itertools.islice(self._get_availability_zones(), az_count))
        if len(availability_zones) < az_count:
            raise DisallowedOperationException(
                "Do not have %s availability zones: %s" %
                (az_count, availability_zones))
        instance_count = az_count
        if count:
            instance_count = count

        def get_image(image_specifier):
            images = [
                image for image in self.driver.list_images()
                if re.match(image_specifier, image.name)
            ]
            if not images:
                raise DisallowedOperationException(
                    "Could not find image named %s" % image_specifier)
            if len(images) > 1:
                raise DisallowedOperationException(
                    "Found multiple images for specifier %s: %s" %
                    (image_specifier, images))
            return images[0]

        image = get_image(instances_blueprint.image())
        instance_type = get_fitting_instance(self, instances_blueprint)
        for availability_zone, instance_num in zip(
                itertools.cycle(availability_zones), range(0, instance_count)):
            full_subnetwork_name = "%s-%s" % (network.name, service_name)
            instance_name = "%s-%s" % (full_subnetwork_name, instance_num)
            metadata = [{
                "key":
                "startup-script",
                "value":
                instances_blueprint.runtime_scripts(template_vars)
            }, {
                "key": "network",
                "value": network.name
            }, {
                "key": "subnetwork",
                "value": service_name
            }]
            logger.info('Creating instance %s in zone %s', instance_name,
                        availability_zone.name)
            self.driver.create_node(instance_name,
                                    instance_type,
                                    image,
                                    location=availability_zone,
                                    ex_network=network.name,
                                    ex_subnetwork=full_subnetwork_name,
                                    external_ip="ephemeral",
                                    ex_metadata=metadata,
                                    ex_tags=[full_subnetwork_name])
        return self.get(network, service_name)