From fed57c47da49a0457fce8fec3b59c9142e62785e Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Thu, 23 Sep 2010 13:59:33 +0200 Subject: Address Vishy's comments. --- nova/api/ec2/cloud.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 046aee14a..0f0aa327c 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -725,9 +725,9 @@ class CloudController(object): security_groups = [] for security_group_name in security_group_arg: - group = db.security_group_get_by_project(context, - context.project.id, - security_group_name) + group = db.security_group_get_by_name(context, + context.project.id, + security_group_name) security_groups.append(group['id']) reservation_id = utils.generate_uid('r') @@ -744,6 +744,7 @@ class CloudController(object): base_options['user_data'] = kwargs.get('user_data', '') type_data = INSTANCE_TYPES[instance_type] + base_options['instance_type'] = instance_type base_options['memory_mb'] = type_data['memory_mb'] base_options['vcpus'] = type_data['vcpus'] base_options['local_gb'] = type_data['local_gb'] -- cgit From e6ada2403cb83070c270a96c7e371513d21e27f4 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 27 Sep 2010 15:13:11 +0200 Subject: If an instance never got scheduled for whatever reason, its host will turn up as None. Filter those out to make sure refresh works. --- nova/api/ec2/cloud.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 0f0aa327c..7330967fa 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -116,7 +116,8 @@ class CloudController(object): return result def _trigger_refresh_security_group(self, security_group): - nodes = set([instance.host for instance in security_group.instances]) + nodes = set([instance['host'] for instance in security_group.instances + if instance['host'] is not None]) for node in nodes: rpc.call('%s.%s' % (FLAGS.compute_topic, node), { "method": "refresh_security_group", -- cgit From 523f1c95ac12ed4782476c3273b337601ad8b6ae Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 27 Sep 2010 21:49:24 +0200 Subject: If neither a security group nor a cidr has been passed, assume cidr=0.0.0.0/0 --- nova/api/ec2/cloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 7330967fa..4cf2666a5 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -301,7 +301,7 @@ class CloudController(object): IPy.IP(cidr_ip) values['cidr'] = cidr_ip else: - return { 'return': False } + values['cidr'] = '0.0.0.0/0' if ip_protocol and from_port and to_port: from_port = int(from_port) -- cgit From 84fbad82d65b837d43f138e7a5acd24f182499e2 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 28 Sep 2010 12:09:17 -0700 Subject: move default group creation to api --- nova/api/ec2/cloud.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 4cf2666a5..d54562ec6 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -244,6 +244,7 @@ class CloudController(object): return True def describe_security_groups(self, context, group_name=None, **kwargs): + self._ensure_default_security_group(context) if context.user.is_admin(): groups = db.security_group_get_all(context) else: @@ -326,6 +327,7 @@ class CloudController(object): return values def revoke_security_group_ingress(self, context, group_name, **kwargs): + self._ensure_default_security_group(context) security_group = db.security_group_get_by_name(context, context.project.id, group_name) @@ -351,6 +353,7 @@ class CloudController(object): # for these operations, so support for newer API versions # is sketchy. def authorize_security_group_ingress(self, context, group_name, **kwargs): + self._ensure_default_security_group(context) security_group = db.security_group_get_by_name(context, context.project.id, group_name) @@ -383,6 +386,7 @@ class CloudController(object): def create_security_group(self, context, group_name, group_description): + self._ensure_default_security_group(context) if db.securitygroup_exists(context, context.project.id, group_name): raise exception.ApiError('group %s already exists' % group_name) @@ -673,6 +677,18 @@ class CloudController(object): "project_id": context.project.id}}) return db.queue_get_for(context, FLAGS.network_topic, host) + def _ensure_default_security_group(self, context): + try: + db.security_group_get_by_name(context, + context.project.id, + 'default') + except exception.NotFound: + values = { 'name' : 'default', + 'description' : 'default', + 'user_id' : context.user.id, + 'project_id' : context.project.id } + group = db.security_group_create({}, values) + def run_instances(self, context, **kwargs): instance_type = kwargs.get('instance_type', 'm1.small') if instance_type not in INSTANCE_TYPES: @@ -725,6 +741,7 @@ class CloudController(object): security_group_arg = [security_group_arg] security_groups = [] + self._ensure_default_security_group(context) for security_group_name in security_group_arg: group = db.security_group_get_by_name(context, context.project.id, -- cgit From c53af2fc9d9803cebc7f4078b8f772476a09df81 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 28 Sep 2010 18:47:47 -0700 Subject: fix security group revoke --- nova/api/ec2/cloud.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 4cf2666a5..6eea95f84 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -295,7 +295,7 @@ class CloudController(object): db.security_group_get_by_name(context, source_project_id, source_security_group_name) - values['group_id'] = source_security_group.id + values['group_id'] = source_security_group['id'] elif cidr_ip: # If this fails, it throws an exception. This is what we want. IPy.IP(cidr_ip) @@ -331,17 +331,19 @@ class CloudController(object): group_name) criteria = self._authorize_revoke_rule_args_to_dict(context, **kwargs) + if criteria == None: + raise exception.ApiError("No rule for the specified parameters.") for rule in security_group.rules: + match = True for (k,v) in criteria.iteritems(): if getattr(rule, k, False) != v: - break - # If we make it here, we have a match - db.security_group_rule_destroy(context, rule.id) + match = False + if match: + db.security_group_rule_destroy(context, rule['id']) + self._trigger_refresh_security_group(security_group) - self._trigger_refresh_security_group(security_group) - - return True + raise exception.ApiError("No rule for the specified parameters.") # TODO(soren): Dupe detection. Adding the same rule twice actually # adds the same rule twice to the rule set, which is -- cgit From 3124cf70c6ab2bcab570f0ffbcbe31672a9556f8 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Tue, 28 Sep 2010 21:03:45 -0700 Subject: fix join and misnamed method --- nova/api/ec2/cloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 6eea95f84..a1a3960f6 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -385,7 +385,7 @@ class CloudController(object): def create_security_group(self, context, group_name, group_description): - if db.securitygroup_exists(context, context.project.id, group_name): + if db.security_group_exists(context, context.project.id, group_name): raise exception.ApiError('group %s already exists' % group_name) group = {'user_id' : context.user.id, -- cgit From 970114e1729c35ebcc05930659bb5dfaf5b59d3d Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Wed, 29 Sep 2010 00:30:35 -0700 Subject: fix loading to ignore deleted items --- nova/api/ec2/cloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 4c27440dc..d85b8512a 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -342,7 +342,7 @@ class CloudController(object): if match: db.security_group_rule_destroy(context, rule['id']) self._trigger_refresh_security_group(security_group) - + return True raise exception.ApiError("No rule for the specified parameters.") # TODO(soren): Dupe detection. Adding the same rule twice actually -- cgit From ddaaebb28649811d723f93a89ee46d69cc3ecabc Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Thu, 30 Sep 2010 20:24:42 -0700 Subject: show project ids for groups instead of user ids --- nova/api/ec2/cloud.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 6c67db28d..8aa76a787 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -260,7 +260,7 @@ class CloudController(object): g = {} g['groupDescription'] = group.description g['groupName'] = group.name - g['ownerId'] = context.user.id + g['ownerId'] = group.project_id g['ipPermissions'] = [] for rule in group.rules: r = {} @@ -272,7 +272,7 @@ class CloudController(object): if rule.group_id: source_group = db.security_group_get(context, rule.group_id) r['groups'] += [{'groupName': source_group.name, - 'userId': source_group.user_id}] + 'userId': source_group.project_id}] else: r['ipRanges'] += [{'cidrIp': rule.cidr}] g['ipPermissions'] += [r] -- cgit From c9d2b8bcb365f326a47df93920c11be2ca054b18 Mon Sep 17 00:00:00 2001 From: Vishvananda Ishaya Date: Thu, 30 Sep 2010 23:04:53 -0700 Subject: Fixed flat network manager with network index gone. Both managers use ips created through nova manage. Use of project_get_network is minimized to make way for managers that would prefer to use cluste or host based ips instead of project based ips. --- nova/api/ec2/cloud.py | 11 ++++++----- nova/api/rackspace/servers.py | 37 ++++++++++++++++++------------------- 2 files changed, 24 insertions(+), 24 deletions(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 79c95788b..d8462f7a0 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -522,13 +522,13 @@ class CloudController(object): def _get_network_topic(self, context): """Retrieves the network host for a project""" - network_ref = db.project_get_network(context, context.project.id) + network_ref = self.network_manager.get_network(context) host = network_ref['host'] if not host: host = rpc.call(FLAGS.network_topic, {"method": "set_network_host", "args": {"context": None, - "project_id": context.project.id}}) + "network_id": network_ref['id']}}) return db.queue_get_for(context, FLAGS.network_topic, host) def run_instances(self, context, **kwargs): @@ -612,12 +612,13 @@ class CloudController(object): inst['launch_index'] = num inst['hostname'] = instance_ref['ec2_id'] db.instance_update(context, inst_id, inst) + # TODO(vish): This probably should be done in the scheduler + # or in compute as a call. The network should be + # allocated after the host is assigned and setup + # can happen at the same time. address = self.network_manager.allocate_fixed_ip(context, inst_id, vpn) - - # TODO(vish): This probably should be done in the scheduler - # network is setup when host is assigned network_topic = self._get_network_topic(context) rpc.call(network_topic, {"method": "setup_fixed_ip", diff --git a/nova/api/rackspace/servers.py b/nova/api/rackspace/servers.py index 11efd8aef..0606d14bb 100644 --- a/nova/api/rackspace/servers.py +++ b/nova/api/rackspace/servers.py @@ -64,8 +64,8 @@ def _entity_list(entities): def _entity_detail(inst): """ Maps everything to Rackspace-like attributes for return""" - power_mapping = { - power_state.NOSTATE: 'build', + power_mapping = { + power_state.NOSTATE: 'build', power_state.RUNNING: 'active', power_state.BLOCKED: 'active', power_state.PAUSED: 'suspended', @@ -75,7 +75,7 @@ def _entity_detail(inst): } inst_dict = {} - mapped_keys = dict(status='state', imageId='image_id', + mapped_keys = dict(status='state', imageId='image_id', flavorId='instance_type', name='server_name', id='id') for k, v in mapped_keys.iteritems(): @@ -98,7 +98,7 @@ class Controller(wsgi.Controller): _serialization_metadata = { 'application/xml': { "attributes": { - "server": [ "id", "imageId", "name", "flavorId", "hostId", + "server": [ "id", "imageId", "name", "flavorId", "hostId", "status", "progress", "progress" ] } } @@ -178,7 +178,7 @@ class Controller(wsgi.Controller): user_id = req.environ['nova.context']['user']['id'] inst_dict = self._deserialize(req.body, req) - + if not inst_dict: return faults.Fault(exc.HTTPUnprocessableEntity()) @@ -186,12 +186,12 @@ class Controller(wsgi.Controller): if not instance or instance.user_id != user_id: return faults.Fault(exc.HTTPNotFound()) - self.db_driver.instance_update(None, id, + self.db_driver.instance_update(None, id, _filter_params(inst_dict['server'])) return faults.Fault(exc.HTTPNoContent()) def action(self, req, id): - """ multi-purpose method used to reboot, rebuild, and + """ multi-purpose method used to reboot, rebuild, and resize a server """ input_dict = self._deserialize(req.body, req) try: @@ -217,13 +217,13 @@ class Controller(wsgi.Controller): if v['flavorid'] == flavor_id][0] image_id = env['server']['imageId'] - + img_service, image_id_trans = _image_service() - opaque_image_id = image_id_trans.to_rs_id(image_id) + opaque_image_id = image_id_trans.to_rs_id(image_id) image = img_service.show(opaque_image_id) - if not image: + if not image: raise Exception, "Image not found" inst['server_name'] = env['server']['name'] @@ -259,15 +259,15 @@ class Controller(wsgi.Controller): ref = self.db_driver.instance_create(None, inst) inst['id'] = inst_id_trans.to_rs_id(ref.ec2_id) - + # TODO(dietz): this isn't explicitly necessary, but the networking # calls depend on an object with a project_id property, and therefore # should be cleaned up later api_context = context.APIRequestContext(user_id) - + inst['mac_address'] = utils.generate_mac() - - #TODO(dietz) is this necessary? + + #TODO(dietz) is this necessary? inst['launch_index'] = 0 inst['hostname'] = ref.ec2_id @@ -279,21 +279,20 @@ class Controller(wsgi.Controller): # TODO(vish): This probably should be done in the scheduler # network is setup when host is assigned - network_topic = self._get_network_topic(user_id) + network_topic = self._get_network_topic(None) rpc.call(network_topic, {"method": "setup_fixed_ip", "args": {"context": None, "address": address}}) return inst - def _get_network_topic(self, user_id): + def _get_network_topic(self, context): """Retrieves the network host for a project""" - network_ref = self.db_driver.project_get_network(None, - user_id) + network_ref = self.network_manager.get_network(context) host = network_ref['host'] if not host: host = rpc.call(FLAGS.network_topic, {"method": "set_network_host", "args": {"context": None, - "project_id": user_id}}) + "network_id": network_ref['id']}}) return self.db_driver.queue_get_for(None, FLAGS.network_topic, host) -- cgit From a4720c03a8260fb920035d072799d3ecc478db99 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Mon, 4 Oct 2010 21:58:22 +0200 Subject: Merge security group related changes from lp:~anso/nova/deploy --- nova/api/ec2/cloud.py | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 839b84b4e..4cd4c78ae 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -327,6 +327,26 @@ class CloudController(object): return values + + def _security_group_rule_exists(self, security_group, values): + """Indicates whether the specified rule values are already + defined in the given security group. + """ + for rule in security_group.rules: + if 'group_id' in values: + if rule['group_id'] == values['group_id']: + return True + else: + is_duplicate = True + for key in ('cidr', 'from_port', 'to_port', 'protocol'): + if rule[key] != values[key]: + is_duplicate = False + break + if is_duplicate: + return True + return False + + def revoke_security_group_ingress(self, context, group_name, **kwargs): self._ensure_default_security_group(context) security_group = db.security_group_get_by_name(context, @@ -348,9 +368,6 @@ class CloudController(object): return True raise exception.ApiError("No rule for the specified parameters.") - # TODO(soren): Dupe detection. Adding the same rule twice actually - # adds the same rule twice to the rule set, which is - # pointless. # TODO(soren): This has only been tested with Boto as the client. # Unfortunately, it seems Boto is using an old API # for these operations, so support for newer API versions @@ -364,6 +381,10 @@ class CloudController(object): values = self._authorize_revoke_rule_args_to_dict(context, **kwargs) values['parent_group_id'] = security_group.id + if self._security_group_rule_exists(security_group, values): + raise exception.ApiError('This rule already exists in group %s' % + group_name) + security_group_rule = db.security_group_rule_create(context, values) self._trigger_refresh_security_group(security_group) @@ -709,7 +730,7 @@ class CloudController(object): 'description' : 'default', 'user_id' : context.user.id, 'project_id' : context.project.id } - group = db.security_group_create({}, values) + group = db.security_group_create(context, values) def run_instances(self, context, **kwargs): instance_type = kwargs.get('instance_type', 'm1.small') @@ -797,7 +818,7 @@ class CloudController(object): inst_id = instance_ref['id'] for security_group_id in security_groups: - db.instance_add_security_group(context, inst_id, + db.instance_add_security_group(context.admin(), inst_id, security_group_id) inst = {} -- cgit From 1158e1817b7d39e9655b219ede865f301153e713 Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Tue, 5 Oct 2010 11:17:03 +0200 Subject: Un-twistedify get_console_ouptut. --- nova/api/ec2/cloud.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 1f01731ae..e7147ec05 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -247,16 +247,16 @@ class CloudController(object): def get_console_output(self, context, instance_id, **kwargs): # instance_id is passed in as a list of instances instance_ref = db.instance_get_by_ec2_id(context, instance_id[0]) - d = rpc.call('%s.%s' % (FLAGS.compute_topic, + output = rpc.call('%s.%s' % (FLAGS.compute_topic, instance_ref['host']), { "method" : "get_console_output", "args" : { "context": None, "instance_id": instance_ref['id']}}) - d.addCallback(lambda output: { "InstanceId": instance_id, - "Timestamp": "2", - "output": base64.b64encode(output)}) - return d + now = datetime.datetime.utcnow() + return { "InstanceId" : instance_id, + "Timestamp" : now, + "output" : base64.b64encode(output) } def describe_volumes(self, context, **kwargs): if context.user.is_admin(): -- cgit From 10bbf9f638b5c8c9182984cc7e22f732b194476f Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Tue, 5 Oct 2010 15:21:31 +0200 Subject: Stub out ec2.images.list() for unit tests. --- nova/api/ec2/images.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'nova/api') diff --git a/nova/api/ec2/images.py b/nova/api/ec2/images.py index cb54cdda2..f0a43dad6 100644 --- a/nova/api/ec2/images.py +++ b/nova/api/ec2/images.py @@ -69,6 +69,9 @@ def list(context, filter_list=[]): optionally filtered by a list of image_id """ + if FLAGS.connection_type == 'fake': + return [{ 'imageId' : 'bar'}] + # FIXME: send along the list of only_images to check for response = conn(context).make_request( method='GET', -- cgit From da7fa3f388a45b3afca16dba6a59b68ea8804f7a Mon Sep 17 00:00:00 2001 From: Soren Hansen Date: Tue, 12 Oct 2010 09:24:33 +0200 Subject: APIRequestContext.admin is no more.. --- nova/api/ec2/cloud.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'nova/api') diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 555518448..7839dc92c 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -841,7 +841,7 @@ class CloudController(object): inst_id = instance_ref['id'] for security_group_id in security_groups: - db.instance_add_security_group(context.admin(), inst_id, + db.instance_add_security_group(context, inst_id, security_group_id) inst = {} -- cgit