diff options
| author | William Wolf <throughnothing@gmail.com> | 2011-07-27 12:06:59 -0400 |
|---|---|---|
| committer | William Wolf <throughnothing@gmail.com> | 2011-07-27 12:06:59 -0400 |
| commit | dd72466c12ab6d64ee56257befe7e13cfd3ff5fa (patch) | |
| tree | ad6ed97de62398cbff519cdc18319b6959bbb9d6 /nova/api | |
| parent | 6dead0b1706f3b2279504437aca63a3291dc2347 (diff) | |
| parent | a1152e7361ed887fc38de42e8fc770cf2f7df7cb (diff) | |
merge from trunk
Diffstat (limited to 'nova/api')
| -rw-r--r-- | nova/api/ec2/cloud.py | 70 | ||||
| -rw-r--r-- | nova/api/openstack/contrib/volumes.py | 53 | ||||
| -rw-r--r-- | nova/api/openstack/servers.py | 6 | ||||
| -rw-r--r-- | nova/api/openstack/views/servers.py | 45 |
4 files changed, 136 insertions, 38 deletions
diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 10720a804..0294c09c5 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -539,15 +539,18 @@ class CloudController(object): return rules if 'ip_ranges' in kwargs: rules = self._cidr_args_split(kwargs) + else: + rules = [kwargs] finalset = [] for rule in rules: if 'groups' in rule: groups_values = self._groups_args_split(rule) for groups_value in groups_values: - finalset.append(groups_value) + final = self._rule_dict_last_step(context, **groups_value) + finalset.append(final) else: - if rule: - finalset.append(rule) + final = self._rule_dict_last_step(context, **rule) + finalset.append(final) return finalset def _cidr_args_split(self, kwargs): @@ -590,6 +593,9 @@ class CloudController(object): db.security_group_get_by_name(context.elevated(), source_project_id, source_security_group_name) + notfound = exception.SecurityGroupNotFound + if not source_security_group: + raise notfound(security_group_id=source_security_group_name) values['group_id'] = source_security_group['id'] elif cidr_ip: # If this fails, it throws an exception. This is what we want. @@ -628,7 +634,7 @@ class CloudController(object): for rule in security_group.rules: if 'group_id' in values: if rule['group_id'] == values['group_id']: - return True + return rule['id'] else: is_duplicate = True for key in ('cidr', 'from_port', 'to_port', 'protocol'): @@ -636,7 +642,7 @@ class CloudController(object): is_duplicate = False break if is_duplicate: - return True + return rule['id'] return False def revoke_security_group_ingress(self, context, group_name=None, @@ -659,22 +665,30 @@ class CloudController(object): msg = "Revoke security group ingress %s" LOG.audit(_(msg), security_group['name'], context=context) + prevalues = [] + try: + prevalues = kwargs['ip_permissions'] + except KeyError: + prevalues.append(kwargs) + rule_id = None + for values in prevalues: + rulesvalues = self._rule_args_to_dict(context, values) + if not rulesvalues: + err = "%s Not enough parameters to build a valid rule" + raise exception.ApiError(_(err % rulesvalues)) - criteria = self._rule_args_to_dict(context, kwargs)[0] - if criteria is None: - raise exception.ApiError(_("Not enough parameters to build a " - "valid rule.")) - - for rule in security_group.rules: - match = True - for (k, v) in criteria.iteritems(): - if getattr(rule, k, False) != v: - match = False - if match: - db.security_group_rule_destroy(context, rule['id']) - self.compute_api.trigger_security_group_rules_refresh(context, - security_group_id=security_group['id']) - return True + for values_for_rule in rulesvalues: + values_for_rule['parent_group_id'] = security_group.id + rule_id = self._security_group_rule_exists(security_group, + values_for_rule) + if rule_id: + db.security_group_rule_destroy(context, rule_id) + if rule_id: + # NOTE(vish): we removed a rule, so refresh + self.compute_api.trigger_security_group_rules_refresh( + context, + security_group_id=security_group['id']) + return True raise exception.ApiError(_("No rule for the specified parameters.")) # TODO(soren): This has only been tested with Boto as the client. @@ -721,15 +735,17 @@ class CloudController(object): postvalues.append(values_for_rule) for values_for_rule in postvalues: - security_group_rule = db.security_group_rule_create(context, - values_for_rule) + security_group_rule = db.security_group_rule_create( + context, + values_for_rule) - self.compute_api.trigger_security_group_rules_refresh(context, - security_group_id=security_group['id']) + if postvalues: + self.compute_api.trigger_security_group_rules_refresh( + context, + security_group_id=security_group['id']) + return True - group = db.security_group_get_by_name(context, context.project_id, - security_group['name']) - return True + raise exception.ApiError(_("No rule for the specified parameters.")) def _get_source_project_id(self, context, source_security_group_owner_id): if source_security_group_owner_id: diff --git a/nova/api/openstack/contrib/volumes.py b/nova/api/openstack/contrib/volumes.py index 827e36097..867fe301e 100644 --- a/nova/api/openstack/contrib/volumes.py +++ b/nova/api/openstack/contrib/volumes.py @@ -22,10 +22,12 @@ from nova import compute from nova import exception from nova import flags from nova import log as logging +from nova import quota from nova import volume from nova.api.openstack import common from nova.api.openstack import extensions from nova.api.openstack import faults +from nova.api.openstack import servers LOG = logging.getLogger("nova.api.volumes") @@ -297,6 +299,53 @@ class VolumeAttachmentController(object): return {'volumeAttachments': res} +class BootFromVolumeController(servers.ControllerV11): + """The boot from volume API controller for the Openstack API.""" + + def _create_instance(self, context, instance_type, image_href, **kwargs): + try: + return self.compute_api.create(context, instance_type, + image_href, **kwargs) + except quota.QuotaError as error: + self.helper._handle_quota_error(error) + except exception.ImageNotFound as error: + msg = _("Can not find requested image") + raise faults.Fault(exc.HTTPBadRequest(explanation=msg)) + + def create(self, req, body): + """ Creates a new server for a given user """ + extra_values = None + try: + + def get_kwargs(context, instance_type, image_href, **kwargs): + kwargs['context'] = context + kwargs['instance_type'] = instance_type + kwargs['image_href'] = image_href + return kwargs + + extra_values, kwargs = self.helper.create_instance(req, body, + get_kwargs) + + block_device_mapping = body['server'].get('block_device_mapping') + kwargs['block_device_mapping'] = block_device_mapping + + instances = self._create_instance(**kwargs) + except faults.Fault, f: + return f + + # We can only return 1 instance via the API, if we happen to + # build more than one... instances is a list, so we'll just + # use the first one.. + inst = instances[0] + for key in ['instance_type', 'image_ref']: + inst[key] = extra_values[key] + + builder = self._get_view_builder(req) + server = builder.build(inst, is_detail=True) + server['server']['adminPass'] = extra_values['password'] + return server + + class Volumes(extensions.ExtensionDescriptor): def get_name(self): return "Volumes" @@ -330,4 +379,8 @@ class Volumes(extensions.ExtensionDescriptor): collection_name='servers')) resources.append(res) + res = extensions.ResourceExtension('os-volumes_boot', + BootFromVolumeController()) + resources.append(res) + return resources diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 7bef1d9b2..d7cabb067 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -447,7 +447,6 @@ class ControllerV10(Controller): def _action_rebuild(self, info, request, instance_id): context = request.environ['nova.context'] - instance_id = int(instance_id) try: image_id = info["rebuild"]["imageId"] @@ -459,7 +458,7 @@ class ControllerV10(Controller): try: self.compute_api.rebuild(context, instance_id, image_id) except exception.BuildInProgress: - msg = _("Instance %d is currently being rebuilt.") % instance_id + msg = _("Instance %s is currently being rebuilt.") % instance_id LOG.debug(msg) raise exc.HTTPConflict(explanation=msg) @@ -560,7 +559,6 @@ class ControllerV11(Controller): def _action_rebuild(self, info, request, instance_id): context = request.environ['nova.context'] - instance_id = int(instance_id) try: image_href = info["rebuild"]["imageRef"] @@ -581,7 +579,7 @@ class ControllerV11(Controller): self.compute_api.rebuild(context, instance_id, image_href, name, metadata, personalities) except exception.BuildInProgress: - msg = _("Instance %d is currently being rebuilt.") % instance_id + msg = _("Instance %s is currently being rebuilt.") % instance_id LOG.debug(msg) raise exc.HTTPConflict(explanation=msg) diff --git a/nova/api/openstack/views/servers.py b/nova/api/openstack/views/servers.py index 7131db088..be25e1e40 100644 --- a/nova/api/openstack/views/servers.py +++ b/nova/api/openstack/views/servers.py @@ -50,7 +50,7 @@ class ViewBuilder(object): else: server = self._build_simple(inst) - self._build_extra(server, inst) + self._build_extra(server['server'], inst) return server @@ -99,7 +99,6 @@ class ViewBuilder(object): self._build_flavor(inst_dict, inst) self._build_addresses(inst_dict, inst) - inst_dict['uuid'] = inst['uuid'] return dict(server=inst_dict) def _build_addresses(self, response, inst): @@ -121,6 +120,9 @@ class ViewBuilder(object): class ViewBuilderV10(ViewBuilder): """Model an Openstack API V1.0 server response.""" + def _build_extra(self, response, inst): + response['uuid'] = inst['uuid'] + def _build_image(self, response, inst): if 'image_ref' in dict(inst): image_ref = inst['image_ref'] @@ -145,18 +147,46 @@ class ViewBuilderV11(ViewBuilder): self.image_builder = image_builder self.base_url = base_url + def _build_detail(self, inst): + response = super(ViewBuilderV11, self)._build_detail(inst) + response['server']['created'] = inst['created_at'] + response['server']['updated'] = inst['updated_at'] + if 'status' in response['server']: + if response['server']['status'] == "ACTIVE": + response['server']['progress'] = 100 + elif response['server']['status'] == "BUILD": + response['server']['progress'] = 0 + return response + def _build_image(self, response, inst): if 'image_ref' in dict(inst): image_href = inst['image_ref'] - if str(image_href).isdigit(): - image_href = int(image_href) - response['imageRef'] = image_href + image_id = str(common.get_id_from_href(image_href)) + _bookmark = self.image_builder.generate_bookmark(image_id) + response['image'] = { + "id": image_id, + "links": [ + { + "rel": "bookmark", + "href": _bookmark, + }, + ] + } def _build_flavor(self, response, inst): if "instance_type" in dict(inst): flavor_id = inst["instance_type"]['flavorid'] flavor_ref = self.flavor_builder.generate_href(flavor_id) - response["flavorRef"] = flavor_ref + flavor_bookmark = self.flavor_builder.generate_bookmark(flavor_id) + response["flavor"] = { + "id": str(common.get_id_from_href(flavor_ref)), + "links": [ + { + "rel": "bookmark", + "href": flavor_bookmark, + }, + ] + } def _build_addresses(self, response, inst): interfaces = inst.get('virtual_interfaces', []) @@ -164,6 +194,7 @@ class ViewBuilderV11(ViewBuilder): def _build_extra(self, response, inst): self._build_links(response, inst) + response['uuid'] = inst['uuid'] def _build_links(self, response, inst): href = self.generate_href(inst["id"]) @@ -180,7 +211,7 @@ class ViewBuilderV11(ViewBuilder): }, ] - response["server"]["links"] = links + response["links"] = links def generate_href(self, server_id): """Create an url that refers to a specific server id.""" |
