Example #1
0
    def add_item(self, context, name, body, scope=None):
        routes, dummy = self._sync_routes(context)
        if name in routes:
            raise exception.InvalidInput(
                    _("The resource '%s' already exists.") % name)

        # NOTE(ft): check network is plugged to router
        network_name = utils._extract_name_from_url(body["network"])
        network = network_api.API().get_item(context, network_name)

        nexthop = body.get("nextHopGateway")
        if (nexthop is not None and
                (utils._extract_name_from_url(nexthop) ==
                 "default-internet-gateway") and
                # NOTE(ft): OS doesn't support IP mask for external gateway
                body.get("destRange") == ALL_IP_CIDR):
            operation_util.start_operation(context)
            return self._create_internet_route(context, network, body)

        nexthop = body.get("nextHopIp")
        if nexthop is not None:
            operation_util.start_operation(context)
            return self._create_custom_route(context, network, body)

        raise exception.InvalidInput(_("Unsupported route."))
Example #2
0
    def add_item(self, context, name, body, scope=None):
        sizeGb = int(body['sizeGb']) if 'sizeGb' in body else None

        snapshot_uri = body.get("sourceSnapshot")
        image_uri = body.get("sourceImage")
        snapshot_id = None
        image_id = None

        client = clients.cinder(context)
        if snapshot_uri:
            snapshot_name = utils._extract_name_from_url(snapshot_uri)
            snapshots = client.volume_snapshots.list(
                search_opts={"display_name": snapshot_name})
            if not snapshots or len(snapshots) != 1:
                raise exception.NotFound
            snapshot_id = snapshots[0].id
        elif image_uri:
            image_name = utils._extract_name_from_url(image_uri)
            image = image_api.API().get_item(context, image_name, scope)
            image_id = image['id']
            # Cinder API doesn't get size from image, so we do this
            image_size_in_gb = (int(image['size']) + GB - 1) / GB
            if not sizeGb or sizeGb < image_size_in_gb:
                sizeGb = image_size_in_gb

        operation_util.start_operation(context, self._get_add_item_progress)
        volume = client.volumes.create(
            sizeGb, snapshot_id=snapshot_id,
            display_name=body.get('name'),
            display_description=body.get('description'),
            imageRef=image_id,
            availability_zone=scope.get_name())
        operation_util.set_item_id(context, volume.id)

        return self._prepare_item(client, utils.to_dict(volume))
Example #3
0
    def add_item(self, context, instance_name, params, source, name,
                 auto_delete, scope):
        # NOTE(apavlov): name is a 'device_name' here
        if not name:
            msg = _("There is no name to assign.")
            raise exception.InvalidRequest(msg)

        nova_client = clients.nova(context)
        instances = nova_client.servers.list(
            search_opts={"name": instance_name})
        if not instances or len(instances) != 1:
            raise exception.NotFound
        instance = instances[0]

        devices = list()
        volumes_client = nova_client.volumes
        for server_volume in volumes_client.get_server_volumes(instance.id):
            devices.append(server_volume.device)
        device_name = None
        for letter in string.ascii_lowercase[1:]:
            device_name = "vd" + letter
            for device in devices:
                if device_name in device:
                    break
            else:
                break
        else:
            raise exception.OverQuota
        context.operation_data["device_name"] = device_name

        if source:
            volume_name = utils._extract_name_from_url(source)
            if not volume_name:
                msg = _("There is no volume to assign.")
                raise exception.NotFound(msg)
            volume = disk_api.API().get_item(context, volume_name, scope)
            context.operation_data["volume_id"] = volume["id"]
        elif params:
            params.setdefault("diskName", instance_name)
            context.operation_data["params"] = params
            context.operation_data["scope"] = scope
        else:
            msg = _('Disk config must contain either "source" or '
                    '"initializeParams".')
            raise exception.InvalidRequest(msg)

        context.operation_data["instance_id"] = instance.id
        context.operation_data["register_args"] = [
            instance_name, name, auto_delete
        ]
        operation_util.start_operation(
            context, base_api.API._get_complex_operation_progress)
        operation_util.continue_operation(context,
                                          lambda: self._attach_volume(context),
                                          timeout=0)
Example #4
0
    def add_item(self, context, instance_name, params, source, name,
                 auto_delete, scope):
        # NOTE(apavlov): name is a 'device_name' here
        if not name:
            msg = _("There is no name to assign.")
            raise exception.InvalidRequest(msg)

        nova_client = clients.nova(context)
        instances = nova_client.servers.list(
            search_opts={"name": instance_name})
        if not instances or len(instances) != 1:
            raise exception.NotFound
        instance = instances[0]

        devices = list()
        volumes_client = nova_client.volumes
        for server_volume in volumes_client.get_server_volumes(instance.id):
            devices.append(server_volume.device)
        device_name = None
        for letter in string.ascii_lowercase[1:]:
            device_name = "vd" + letter
            for device in devices:
                if device_name in device:
                    break
            else:
                break
        else:
            raise exception.OverQuota
        context.operation_data["device_name"] = device_name

        if source:
            volume_name = utils._extract_name_from_url(source)
            if not volume_name:
                msg = _("There is no volume to assign.")
                raise exception.NotFound(msg)
            volume = disk_api.API().get_item(context, volume_name, scope)
            context.operation_data["volume_id"] = volume["id"]
        elif params:
            params.setdefault("diskName", instance_name)
            context.operation_data["params"] = params
            context.operation_data["scope"] = scope
        else:
            msg = _('Disk config must contain either "source" or '
                    '"initializeParams".')
            raise exception.InvalidRequest(msg)

        context.operation_data["instance_id"] = instance.id
        context.operation_data["register_args"] = [instance_name, name,
                                                   auto_delete]
        operation_util.start_operation(
            context, base_api.API._get_complex_operation_progress)
        operation_util.continue_operation(
            context, lambda: self._attach_volume(context), timeout=0)
Example #5
0
    def add_item(self, context, name, body, scope=None):
        sizeGb = body.get("sizeGb")
        sizeGb = int(sizeGb) if sizeGb else None

        snapshot_uri = body.get("sourceSnapshot")
        image_uri = body.get("sourceImage")
        snapshot_id = None
        image_id = None

        client = clients.cinder(context)
        if snapshot_uri:
            snapshot_name = utils._extract_name_from_url(snapshot_uri)
            snapshots = client.volume_snapshots.list(
                search_opts={"display_name": snapshot_name})
            if not snapshots or len(snapshots) != 1:
                raise exception.NotFound
            snapshot_id = snapshots[0].id
        elif image_uri:
            image_name = utils._extract_name_from_url(image_uri)
            image = image_api.API().get_item(context, image_name, scope)
            image_id = image['id']
            # Cinder API doesn't get size from image, so we do this
            image_size_in_gb = (int(image['size']) + GB - 1) / GB
            if not sizeGb or sizeGb < image_size_in_gb:
                sizeGb = image_size_in_gb
        else:
            if not sizeGb:
                sizeGb = CONF.default_volume_size_gb

        operation_util.start_operation(context, self._get_add_item_progress)
        volume = client.volumes.create(
            sizeGb, snapshot_id=snapshot_id,
            display_name=body.get('name', name),
            display_description=body.get('description'),
            imageRef=image_id,
            availability_zone=scope.get_name())
        operation_util.set_item_id(context, volume.id, self.KIND)

        return self._prepare_item(client, utils.to_dict(volume))
Example #6
0
    def add_item(self, context, name, body, scope=None):
        routes, dummy = self._sync_routes(context)
        if name in routes:
            raise exception.InvalidInput(
                _("The resource '%s' already exists.") % name)

        # NOTE(ft): check network is plugged to router
        network_name = utils._extract_name_from_url(body["network"])
        network = network_api.API().get_item(context, network_name)

        nexthop = body.get("nextHopGateway")
        if (nexthop is not None and (utils._extract_name_from_url(nexthop)
                                     == "default-internet-gateway") and
                # NOTE(ft): OS doesn't support IP mask for external gateway
                body.get("destRange") == ALL_IP_CIDR):
            operation_util.start_operation(context)
            return self._create_internet_route(context, network, body)

        nexthop = body.get("nextHopIp")
        if nexthop is not None:
            operation_util.start_operation(context)
            return self._create_custom_route(context, network, body)

        raise exception.InvalidInput(_("Unsupported route."))
Example #7
0
    def add_item(self, context, name, body, scope=None):
        name = body['name']
        client = clients.nova(context)

        flavor_name = utils._extract_name_from_url(body['machineType'])
        flavor_id = machine_type_api.API().get_item(
            context, flavor_name, scope)["id"]

        nics = []
        #NOTE(ft) 'default' security group contains output rules
        #but output rules doesn't configurable by GCE API
        #all outgoing traffic permitted
        #so we support this behaviour
        groups_names = set(['default'])
        acs = dict()
        for net_iface in body['networkInterfaces']:
            net_name = utils._extract_name_from_url(net_iface["network"])
            ac = net_iface.get("accessConfigs")
            if ac:
                if len(ac) > 1:
                    msg = _('At most one access config currently supported.')
                    raise exception.InvalidRequest(msg)
                else:
                    acs[net_name] = ac[0]

            network = network_api.API().get_item(context, net_name, None)
            nics.append({"net-id": network["id"]})
            for sg in firewall_api.API().get_network_firewalls(
                    context, net_name):
                groups_names.add(sg["name"])
        groups_names = list(groups_names)

        try:
            metadatas = body['metadata']['items']
        except KeyError:
            metadatas = []
        instance_metadata = dict([(x['key'], x['value']) for x in metadatas])

        disks = body.get('disks', [])
        for disk in disks:
            disk["boot"] = True if "initializeParams" in disk else False
            if "source" in disk:
                volume_name = utils._extract_name_from_url(disk["source"])
                volume = disk_api.API().get_item(context, volume_name, scope)
                disk["id"] = volume["id"]
            elif "initializeParams" not in disk:
                msg = _('Disk config must contain either "source" or '
                        '"initializeParams".')
                raise exception.InvalidRequest(msg)
        disks.sort(None, lambda x: x.get("boot", False), True)

        ssh_keys = instance_metadata.pop('sshKeys', None)
        if ssh_keys is not None:
            key = ssh_keys.split('\n')[0].split(":")
            key_name = key[0] + "-" + str(random.randint(10000, 99999))
            key_data = key[1]
            client.keypairs.create(key_name, key_data)
        else:
            key_name = project_api.API().get_gce_user_keypair_name(context)

        operation_util.start_operation(
            context, base_api.API._get_complex_operation_progress)

        context.operation_data["acs"] = acs
        context.operation_data["ssh_keys"] = ssh_keys

        context.operation_data["bdm"] = dict()
        context.operation_data["disk_device"] = 0
        context.operation_data["disks"] = disks

        context.operation_data["scope"] = scope
        context.operation_data["args"] = [name, None, flavor_id]
        context.operation_data["kwargs"] = {"meta": instance_metadata,
            "min_count": 1, "max_count": 1, "nics": nics,
            "security_groups": groups_names, "key_name": key_name}
        context.operation_data["description"] = body.get("description")

        operation_util.continue_operation(
            context, lambda: self._create_instance(context))
Example #8
0
    def add_item(self, context, name, body, scope=None):
        name = body['name']
        client = clients.nova(context)

        flavor_name = utils._extract_name_from_url(body['machineType'])
        flavor_id = machine_type_api.API().get_item(
            context, flavor_name, scope)["id"]

        try:
            metadatas = body['metadata']['items']
        except KeyError:
            metadatas = []
        instance_metadata = dict([(x['key'], x['value']) for x in metadatas])

        ssh_keys = instance_metadata.pop('sshKeys', None)
        if ssh_keys is not None:
            key_name = ssh_keys.split('\n')[0].split(":")[0]
        else:
            key_name = project_api.API().get_gce_user_keypair_name(context)

        disks = body.get('disks', [])
        disks.sort(None, lambda x: x.get("boot", False), True)
        bdm = dict()
        diskDevice = 0
        for disk in disks:
            device_name = "vd" + string.ascii_lowercase[diskDevice]
            volume_name = utils._extract_name_from_url(disk["source"])
            volume = disk_api.API().get_item(context, volume_name, scope)
            disk["id"] = volume["id"]
            bdm[device_name] = volume["id"]
            diskDevice += 1

        nics = []
        #NOTE(ft) 'default' security group contains output rules
        #but output rules doesn't configurable by GCE API
        #all outgoing traffic permitted
        #so we support this behaviour
        groups_names = set(['default'])
        acs = dict()
        for net_iface in body['networkInterfaces']:
            net_name = utils._extract_name_from_url(net_iface["network"])
            ac = net_iface.get("accessConfigs")
            if ac:
                if len(ac) > 1:
                    msg = _('At most one access config currently supported.')
                    raise exception.InvalidRequest(msg)
                else:
                    acs[net_name] = ac[0]

            network = network_api.API().get_item(context, net_name, None)
            nics.append({"net-id": network["id"]})
            for sg in firewall_api.API().get_network_firewalls(
                    context, net_name):
                groups_names.add(sg["name"])
        groups_names = list(groups_names)

        operation_util.start_operation(context, self._get_add_item_progress)
        instance = client.servers.create(name, None, flavor_id,
            meta=instance_metadata, min_count=1, max_count=1,
            security_groups=groups_names, key_name=key_name,
            availability_zone=scope.get_name(), block_device_mapping=bdm,
            nics=nics)
        if not acs:
            operation_util.set_item_id(context, instance.id)

        for disk in disks:
            instance_disk_api.API().register_item(context, name,
                disk["id"], disk["deviceName"])

        instance = utils.to_dict(client.servers.get(instance.id))
        instance = self._prepare_instance(client, context, instance)
        if "descripton" in body:
            instance["description"] = body["description"]
        instance = self._add_db_item(context, instance)

        if acs:
            operation_util.continue_operation(
                    context,
                    lambda: self._add_access_config(context, instance,
                                                    scope, acs))

        return instance
Example #9
0
 def _get_network_by_url(self, context, url):
     # NOTE(apavlov): Check existence of such network
     network_name = utils._extract_name_from_url(url)
     return network_api.API().get_item(context, network_name)
Example #10
0
 def _get_network_by_url(self, context, url):
     # NOTE(apavlov): Check existence of such network
     network_name = utils._extract_name_from_url(url)
     return network_api.API().get_item(context, network_name)