def test_get_by_name(self): self.mox.StubOutWithMock(db, "security_group_get_by_name") db.security_group_get_by_name(self.context, "fake-project", "fake-name").AndReturn(fake_secgroup) self.mox.ReplayAll() secgroup = security_group.SecurityGroup.get_by_name(self.context, "fake-project", "fake-name") self.assertEqual(self._fix_deleted(fake_secgroup), dict(secgroup.items())) self.assertEqual(secgroup.obj_what_changed(), set()) self.assertRemotes()
def test_get_by_name(self): self.mox.StubOutWithMock(db, 'security_group_get_by_name') db.security_group_get_by_name(self.context, 'fake-project', 'fake-name').AndReturn(fake_secgroup) self.mox.ReplayAll() secgroup = security_group.SecurityGroup.get_by_name( self.context, 'fake-project', 'fake-name') self.assertEqual(self._fix_deleted(fake_secgroup), dict(secgroup.items())) self.assertEqual(secgroup.obj_what_changed(), set()) self.assertRemotes()
def test_get_by_name(self): self.mox.StubOutWithMock(db, 'security_group_get_by_name') db.security_group_get_by_name(self.context, 'fake-project', 'fake-name').AndReturn(fake_secgroup) self.mox.ReplayAll() secgroup = security_group.SecurityGroup.get_by_name(self.context, 'fake-project', 'fake-name') ovo_fixture.compare_obj(self, secgroup, self._fix_deleted(fake_secgroup)) self.assertEqual(secgroup.obj_what_changed(), set())
def test_get_by_name(self): ctxt = context.get_admin_context() self.mox.StubOutWithMock(db, 'security_group_get_by_name') db.security_group_get_by_name(ctxt, 'fake-project', 'fake-name').AndReturn(fake_secgroup) self.mox.ReplayAll() secgroup = security_group.SecurityGroup.get_by_name(ctxt, 'fake-project', 'fake-name') self.assertEqual(self._fix_deleted(fake_secgroup), dict(secgroup.items())) self.assertEqual(secgroup.obj_what_changed(), set()) self.assertRemotes()
def test_cidr_rule_nwfilter_xml(self): cloud_controller = cloud.CloudController() cloud_controller.create_security_group(self.context, 'testgroup', 'test group description') cloud_controller.authorize_security_group_ingress(self.context, 'testgroup', from_port='80', to_port='81', ip_protocol='tcp', cidr_ip='0.0.0.0/0') db.security_group_get_by_name(self.context, 'fake', 'testgroup') self.teardown_security_group()
def delete_security_group(self, context, group_name, **kwargs): LOG.audit(_("Delete security group %s"), group_name, context=context) security_group = db.security_group_get_by_name(context, context.project_id, group_name) db.security_group_destroy(context, security_group.id) return True
def test_cidr_rule_nwfilter_xml(self): cloud_controller = cloud.CloudController() cloud_controller.create_security_group(self.context, "testgroup", "test group description") cloud_controller.authorize_security_group_ingress( self.context, "testgroup", from_port="80", to_port="81", ip_protocol="tcp", cidr_ip="0.0.0.0/0" ) security_group = db.security_group_get_by_name(self.context, "fake", "testgroup") xml = self.fw.security_group_to_nwfilter_xml(security_group.id) dom = xml_to_dom(xml) self.assertEqual(dom.firstChild.tagName, "filter") rules = dom.getElementsByTagName("rule") self.assertEqual(len(rules), 1) # It's supposed to allow inbound traffic. self.assertEqual(rules[0].getAttribute("action"), "accept") self.assertEqual(rules[0].getAttribute("direction"), "in") # Must be lower priority than the base filter (which blocks everything) self.assertTrue(int(rules[0].getAttribute("priority")) < 1000) ip_conditions = rules[0].getElementsByTagName("tcp") self.assertEqual(len(ip_conditions), 1) self.assertEqual(ip_conditions[0].getAttribute("srcipaddr"), "0.0.0.0") self.assertEqual(ip_conditions[0].getAttribute("srcipmask"), "0.0.0.0") self.assertEqual(ip_conditions[0].getAttribute("dstportstart"), "80") self.assertEqual(ip_conditions[0].getAttribute("dstportend"), "81") self.teardown_security_group()
def revoke_security_group_ingress(self, context, group_name, **kwargs): LOG.audit(_("Revoke security group ingress %s"), group_name, context=context) self.compute_api.ensure_default_security_group(context) security_group = db.security_group_get_by_name(context, context.project_id, group_name) criteria = self._revoke_rule_args_to_dict(context, **kwargs) 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']) return True raise exception.ApiError(_("No rule for the specified parameters."))
def authorize_security_group_ingress(self, context, group_name, **kwargs): LOG.audit(_("Authorize security group ingress %s"), group_name, context=context) self.compute_api.ensure_default_security_group(context) security_group = db.security_group_get_by_name(context, context.project_id, group_name) values = self._revoke_rule_args_to_dict(context, **kwargs) if values is None: raise exception.ApiError( _("Not enough parameters to build a " "valid rule.")) 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.compute_api.trigger_security_group_rules_refresh( context, security_group['id']) return True
def ensure_default_security_group(self, context): """ Create security group for the security context if it does not already exist :param context: the security 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} db.security_group_create(context, values)
def ensure_default_security_group(self, context): """ Create security group for the security context if it does not already exist :param context: the security 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, } db.security_group_create(context, values)
def setup_and_return_security_group(self): cloud_controller = cloud.CloudController() cloud_controller.create_security_group(self.context, "testgroup", "test group description") cloud_controller.authorize_security_group_ingress( self.context, "testgroup", from_port="80", to_port="81", ip_protocol="tcp", cidr_ip="0.0.0.0/0" ) return db.security_group_get_by_name(self.context, "fake", "testgroup")
def ensure_default_security_group(self, context): """ Create security group for the security context if it does not already exist :param context: the security 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 } db.security_group_create(context, values)
def create_db_entry_for_new_instance(self, context, image, base_options, security_group, block_device_mapping, num=1): """Create an entry in the DB for this new instance, including any related table updates (such as security group, etc). This will called by create() in the majority of situations, but create_all_at_once() style Schedulers may initiate the call. If you are changing this method, be sure to update both call paths. """ instance = dict(launch_index=num, **base_options) instance = self.db.instance_create(context, instance) instance_id = instance['id'] elevated = context.elevated() if security_group is None: security_group = ['default'] if not isinstance(security_group, list): security_group = [security_group] security_groups = [] for security_group_name in security_group: group = db.security_group_get_by_name(context, context.project_id, security_group_name) security_groups.append(group['id']) for security_group_id in security_groups: self.db.instance_add_security_group(elevated, instance_id, security_group_id) # BlockDeviceMapping table self._update_image_block_device_mapping(elevated, instance_id, image['properties'].get('mappings', [])) self._update_block_device_mapping(elevated, instance_id, image['properties'].get('block_device_mapping', [])) # override via command line option self._update_block_device_mapping(elevated, instance_id, block_device_mapping) # Set sane defaults if not specified updates = {} if (not hasattr(instance, 'display_name') or instance.display_name is None): updates['display_name'] = "Server %s" % instance_id instance['display_name'] = updates['display_name'] updates['hostname'] = self.hostname_factory(instance) instance = self.update(context, instance_id, **updates) for group_id in security_groups: self.trigger_security_group_members_refresh(elevated, group_id) return instance
def setup_and_return_security_group(self): cloud_controller = cloud.CloudController() cloud_controller.create_security_group(self.context, 'testgroup', 'test group description') cloud_controller.authorize_security_group_ingress(self.context, 'testgroup', from_port='80', to_port='81', ip_protocol='tcp', cidr_ip='0.0.0.0/0') return db.security_group_get_by_name(self.context, 'fake', 'testgroup')
def _revoke_rule_args_to_dict(self, context, to_port=None, from_port=None, ip_protocol=None, cidr_ip=None, user_id=None, source_security_group_name=None, source_security_group_owner_id=None): values = {} if source_security_group_name: source_project_id = self._get_source_project_id( context, source_security_group_owner_id) source_security_group = \ db.security_group_get_by_name(context.elevated(), source_project_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. cidr_ip = urllib.unquote(cidr_ip).decode() IPy.IP(cidr_ip) values['cidr'] = cidr_ip else: values['cidr'] = '0.0.0.0/0' if ip_protocol and from_port and to_port: from_port = int(from_port) to_port = int(to_port) ip_protocol = str(ip_protocol) if ip_protocol.upper() not in ['TCP', 'UDP', 'ICMP']: raise exception.InvalidIpProtocol(protocol=ip_protocol) if ((min(from_port, to_port) < -1) or (max(from_port, to_port) > 65535)): raise exception.InvalidPortRange(from_port=from_port, to_port=to_port) values['protocol'] = ip_protocol values['from_port'] = from_port values['to_port'] = to_port else: # If cidr based filtering, protocol and ports are mandatory if 'cidr' in values: return None return values
def retrieve_group(mixin_term, context): """ Retrieve the security group associated with the security mixin. mixin_term -- The term of the mixin representing the group. context -- The os context. """ try: sec_group = db.security_group_get_by_name(context, context.project_id, mixin_term) except Exception as err: msg = err.message raise AttributeError(msg) return sec_group
def trigger_security_group_create_refresh(self, context, group): """Create a chain and port group for the security group.""" LOG.debug('group=%r', group) ctxt = context.elevated() sg_ref = db.security_group_get_by_name(ctxt, group['project_id'], group['name']) tenant_id = context.to_dict()['project_id'] sg_id = sg_ref['id'] sg_name = group['name'] # create a chain for the security group self.chain_manager.create_for_sg(tenant_id, sg_id, sg_name) # create a port group for the security group self.pg_manager.create(tenant_id, sg_id, sg_name)
def _revoke_rule_args_to_dict(self, context, to_port=None, from_port=None, ip_protocol=None, cidr_ip=None, user_id=None, source_security_group_name=None, source_security_group_owner_id=None): values = {} if source_security_group_name: source_project_id = self._get_source_project_id(context, source_security_group_owner_id) source_security_group = \ db.security_group_get_by_name(context.elevated(), source_project_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. cidr_ip = urllib.unquote(cidr_ip).decode() IPy.IP(cidr_ip) values['cidr'] = cidr_ip else: values['cidr'] = '0.0.0.0/0' if ip_protocol and from_port and to_port: from_port = int(from_port) to_port = int(to_port) ip_protocol = str(ip_protocol) if ip_protocol.upper() not in ['TCP', 'UDP', 'ICMP']: raise InvalidInputException(_('%s is not a valid ipProtocol') % (ip_protocol,)) if ((min(from_port, to_port) < -1) or (max(from_port, to_port) > 65535)): raise InvalidInputException(_('Invalid port range')) values['protocol'] = ip_protocol values['from_port'] = from_port values['to_port'] = to_port else: # If cidr based filtering, protocol and ports are mandatory if 'cidr' in values: return None return values
def describe_security_groups(self, context, group_name=None, **kwargs): self.compute_api.ensure_default_security_group(context) if group_name: groups = [] for name in group_name: group = db.security_group_get_by_name(context, context.project_id, name) groups.append(group) elif context.is_admin: groups = db.security_group_get_all(context) else: groups = db.security_group_get_by_project(context, context.project_id) groups = [self._format_security_group(context, g) for g in groups] return {'securityGroupInfo': list(sorted(groups, key=lambda k: (k['ownerId'], k['groupName'])))}
def describe_security_groups(self, context, group_name=None, **kwargs): self.compute_api.ensure_default_security_group(context) if group_name: groups = [] for name in group_name: group = db.security_group_get_by_name(context, context.project_id, name) groups.append(group) elif context.is_admin: groups = db.security_group_get_all(context) else: groups = db.security_group_get_by_project(context, context.project_id) groups = [self._format_security_group(context, g) for g in groups] return { 'securityGroupInfo': list(sorted(groups, key=lambda k: (k['ownerId'], k['groupName']))) }
def test_launch_default_security_group(self): sg = utils.create_security_group(self.context, {'name': 'test-sg', 'description': 'test security group'}) instance_uuid = utils.create_instance(self.context, {'security_groups': [sg['name']]}) blessed_instance = self.cobalt_api.bless_instance(self.context, instance_uuid) blessed_instance_uuid = blessed_instance['uuid'] inst = self.cobalt_api.launch_instance(self.context, blessed_instance_uuid, params={}) self.assertEqual(len(inst['security_groups']), 1) # Ensure that with not security group provided, the existing one is not # inherited, but the 'default' security group is applied to the # instance. self.assertNotEqual(inst['security_groups'][0].id, sg.id) default_sg = db.security_group_get_by_name(self.context, self.context.project_id, 'default') self.assertEqual(inst['security_groups'][0].id, default_sg.id)
def retrieve_group(mixin_term, project_id, context): """ Retrieve the security group associated with the security mixin. mixin_term -- The term of the mixin representing the group. project_id -- The project id. context -- The os context. """ try: sec_group = db.security_group_get_by_name(context, project_id, mixin_term) except Exception: # ensure that an OpenStack sec group matches the mixin # if not, create one. # This has to be done as pyssf has no way to associate # a handler for the creation of mixins at the query interface msg = 'Security group does not exist.' raise AttributeError(msg) return sec_group
def test_cidr_rule_nwfilter_xml(self): cloud_controller = cloud.CloudController() cloud_controller.create_security_group(self.context, 'testgroup', 'test group description') cloud_controller.authorize_security_group_ingress(self.context, 'testgroup', from_port='80', to_port='81', ip_protocol='tcp', cidr_ip='0.0.0.0/0') security_group = db.security_group_get_by_name(self.context, 'fake', 'testgroup') xml = self.fw.security_group_to_nwfilter_xml(security_group.id) dom = xml_to_dom(xml) self.assertEqual(dom.firstChild.tagName, 'filter') rules = dom.getElementsByTagName('rule') self.assertEqual(len(rules), 1) # It's supposed to allow inbound traffic. self.assertEqual(rules[0].getAttribute('action'), 'accept') self.assertEqual(rules[0].getAttribute('direction'), 'in') # Must be lower priority than the base filter (which blocks everything) self.assertTrue(int(rules[0].getAttribute('priority')) < 1000) ip_conditions = rules[0].getElementsByTagName('tcp') self.assertEqual(len(ip_conditions), 1) self.assertEqual(ip_conditions[0].getAttribute('srcipaddr'), '0.0.0.0') self.assertEqual(ip_conditions[0].getAttribute('srcipmask'), '0.0.0.0') self.assertEqual(ip_conditions[0].getAttribute('dstportstart'), '80') self.assertEqual(ip_conditions[0].getAttribute('dstportend'), '81') self.teardown_security_group()
def authorize_security_group_ingress(self, context, group_name, **kwargs): LOG.audit(_("Authorize security group ingress %s"), group_name, context=context) self.compute_api.ensure_default_security_group(context) security_group = db.security_group_get_by_name(context, context.project_id, group_name) values = self._revoke_rule_args_to_dict(context, **kwargs) if values is None: raise exception.ApiError(_("Not enough parameters to build a " "valid rule.")) 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.compute_api.trigger_security_group_rules_refresh(context, security_group['id']) return True
def revoke_security_group_ingress(self, context, group_name, **kwargs): LOG.audit(_("Revoke security group ingress %s"), group_name, context=context) self.compute_api.ensure_default_security_group(context) security_group = db.security_group_get_by_name(context, context.project_id, group_name) criteria = self._revoke_rule_args_to_dict(context, **kwargs) if criteria == 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']) return True raise exception.ApiError(_("No rule for the specified parameters."))
def get_by_name(cls, context, project_id, group_name): db_secgroup = db.security_group_get_by_name(context, project_id, group_name) return cls._from_db_object(context, cls(), db_secgroup)
def create( self, context, instance_type, image_id, kernel_id=None, ramdisk_id=None, min_count=1, max_count=1, display_name="", display_description="", key_name=None, key_data=None, security_group="default", availability_zone=None, user_data=None, metadata={}, injected_files=None, admin_password=None, ): """Create the number and type of instances requested. Verifies that quota and other arguments are valid. """ if not instance_type: instance_type = instance_types.get_default_instance_type() num_instances = quota.allowed_instances(context, max_count, instance_type) if num_instances < min_count: pid = context.project_id LOG.warn(_("Quota exceeeded for %(pid)s," " tried to run %(min_count)s instances") % locals()) if num_instances <= 0: message = _("Instance quota exceeded. You cannot run any " "more instances of this type.") else: message = ( _("Instance quota exceeded. You can only run %s " "more instances of this type.") % num_instances ) raise quota.QuotaError(message, "InstanceLimitExceeded") self._check_metadata_properties_quota(context, metadata) self._check_injected_file_quota(context, injected_files) image = self.image_service.show(context, image_id) os_type = None if "properties" in image and "os_type" in image["properties"]: os_type = image["properties"]["os_type"] if kernel_id is None: kernel_id = image["properties"].get("kernel_id", None) if ramdisk_id is None: ramdisk_id = image["properties"].get("ramdisk_id", None) # FIXME(sirp): is there a way we can remove null_kernel? # No kernel and ramdisk for raw images if kernel_id == str(FLAGS.null_kernel): kernel_id = None ramdisk_id = None LOG.debug(_("Creating a raw instance")) # Make sure we have access to kernel and ramdisk (if not raw) logging.debug("Using Kernel=%s, Ramdisk=%s" % (kernel_id, ramdisk_id)) if kernel_id: self.image_service.show(context, kernel_id) if ramdisk_id: self.image_service.show(context, ramdisk_id) if security_group is None: security_group = ["default"] if not type(security_group) is list: security_group = [security_group] security_groups = [] self.ensure_default_security_group(context) for security_group_name in security_group: group = db.security_group_get_by_name(context, context.project_id, security_group_name) security_groups.append(group["id"]) if key_data is None and key_name: key_pair = db.key_pair_get(context, context.user_id, key_name) key_data = key_pair["public_key"] base_options = { "reservation_id": utils.generate_uid("r"), "image_id": image_id, "kernel_id": kernel_id or "", "ramdisk_id": ramdisk_id or "", "state": 0, "state_description": "scheduling", "user_id": context.user_id, "project_id": context.project_id, "launch_time": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), "instance_type_id": instance_type["id"], "memory_mb": instance_type["memory_mb"], "vcpus": instance_type["vcpus"], "local_gb": instance_type["local_gb"], "display_name": display_name, "display_description": display_description, "user_data": user_data or "", "key_name": key_name, "key_data": key_data, "locked": False, "metadata": metadata, "availability_zone": availability_zone, "os_type": os_type, } elevated = context.elevated() instances = [] LOG.debug(_("Going to run %s instances..."), num_instances) for num in range(num_instances): instance = dict(mac_address=utils.generate_mac(), launch_index=num, **base_options) instance = self.db.instance_create(context, instance) instance_id = instance["id"] elevated = context.elevated() if not security_groups: security_groups = [] for security_group_id in security_groups: self.db.instance_add_security_group(elevated, instance_id, security_group_id) # Set sane defaults if not specified updates = dict(hostname=self.hostname_factory(instance_id)) if not hasattr(instance, "display_name") or instance.display_name is None: updates["display_name"] = "Server %s" % instance_id instance = self.update(context, instance_id, **updates) instances.append(instance) pid = context.project_id uid = context.user_id LOG.debug(_("Casting to scheduler for %(pid)s/%(uid)s's" " instance %(instance_id)s") % locals()) # NOTE(sandy): For now we're just going to pass in the # instance_type record to the scheduler. In a later phase # we'll be ripping this whole for-loop out and deferring the # creation of the Instance record. At that point all this will # change. rpc.cast( context, FLAGS.scheduler_topic, { "method": "run_instance", "args": { "topic": FLAGS.compute_topic, "instance_id": instance_id, "instance_type": instance_type, "availability_zone": availability_zone, "injected_files": injected_files, "admin_password": admin_password, }, }, ) for group_id in security_groups: self.trigger_security_group_members_refresh(elevated, group_id) return [dict(x.iteritems()) for x in instances]
def create(self, context, instance_type, image_id, kernel_id=None, ramdisk_id=None, min_count=1, max_count=1, display_name='', display_description='', key_name=None, key_data=None, security_group='default', availability_zone=None, user_data=None, metadata={}, injected_files=None): """Create the number and type of instances requested. Verifies that quota and other arguments are valid. """ if not instance_type: instance_type = instance_types.get_default_instance_type() num_instances = quota.allowed_instances(context, max_count, instance_type) if num_instances < min_count: pid = context.project_id LOG.warn( _("Quota exceeeded for %(pid)s," " tried to run %(min_count)s instances") % locals()) raise quota.QuotaError( _("Instance quota exceeded. You can only " "run %s more instances of this type.") % num_instances, "InstanceLimitExceeded") self._check_metadata_properties_quota(context, metadata) self._check_injected_file_quota(context, injected_files) image = self.image_service.show(context, image_id) os_type = None if 'properties' in image and 'os_type' in image['properties']: os_type = image['properties']['os_type'] if kernel_id is None: kernel_id = image['properties'].get('kernel_id', None) if ramdisk_id is None: ramdisk_id = image['properties'].get('ramdisk_id', None) # FIXME(sirp): is there a way we can remove null_kernel? # No kernel and ramdisk for raw images if kernel_id == str(FLAGS.null_kernel): kernel_id = None ramdisk_id = None LOG.debug(_("Creating a raw instance")) # Make sure we have access to kernel and ramdisk (if not raw) logging.debug("Using Kernel=%s, Ramdisk=%s" % (kernel_id, ramdisk_id)) if kernel_id: self.image_service.show(context, kernel_id) if ramdisk_id: self.image_service.show(context, ramdisk_id) if security_group is None: security_group = ['default'] if not type(security_group) is list: security_group = [security_group] security_groups = [] self.ensure_default_security_group(context) for security_group_name in security_group: group = db.security_group_get_by_name(context, context.project_id, security_group_name) security_groups.append(group['id']) if key_data is None and key_name: key_pair = db.key_pair_get(context, context.user_id, key_name) key_data = key_pair['public_key'] base_options = { 'reservation_id': utils.generate_uid('r'), 'image_id': image_id, 'kernel_id': kernel_id or '', 'ramdisk_id': ramdisk_id or '', 'state': 0, 'state_description': 'scheduling', 'user_id': context.user_id, 'project_id': context.project_id, 'launch_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()), 'instance_type_id': instance_type['id'], 'memory_mb': instance_type['memory_mb'], 'vcpus': instance_type['vcpus'], 'local_gb': instance_type['local_gb'], 'display_name': display_name, 'display_description': display_description, 'user_data': user_data or '', 'key_name': key_name, 'key_data': key_data, 'locked': False, 'metadata': metadata, 'availability_zone': availability_zone, 'os_type': os_type } elevated = context.elevated() instances = [] LOG.debug(_("Going to run %s instances..."), num_instances) for num in range(num_instances): instance = dict(mac_address=utils.generate_mac(), launch_index=num, **base_options) instance = self.db.instance_create(context, instance) instance_id = instance['id'] elevated = context.elevated() if not security_groups: security_groups = [] for security_group_id in security_groups: self.db.instance_add_security_group(elevated, instance_id, security_group_id) # Set sane defaults if not specified updates = dict(hostname=self.hostname_factory(instance_id)) if (not hasattr(instance, 'display_name') or instance.display_name is None): updates['display_name'] = "Server %s" % instance_id instance = self.update(context, instance_id, **updates) instances.append(instance) pid = context.project_id uid = context.user_id LOG.debug( _("Casting to scheduler for %(pid)s/%(uid)s's" " instance %(instance_id)s") % locals()) rpc.cast( context, FLAGS.scheduler_topic, { "method": "run_instance", "args": { "topic": FLAGS.compute_topic, "instance_id": instance_id, "availability_zone": availability_zone, "injected_files": injected_files } }) for group_id in security_groups: self.trigger_security_group_members_refresh(elevated, group_id) return [dict(x.iteritems()) for x in instances]
def create( self, context, instance_type, image_id, kernel_id=None, ramdisk_id=None, min_count=1, max_count=1, display_name="", display_description="", key_name=None, key_data=None, security_group="default", availability_zone=None, user_data=None, onset_files=None, ): """Create the number of instances requested if quota and other arguments check out ok. """ type_data = instance_types.INSTANCE_TYPES[instance_type] num_instances = quota.allowed_instances(context, max_count, type_data) if num_instances < min_count: pid = context.project_id LOG.warn(_("Quota exceeeded for %(pid)s," " tried to run %(min_count)s instances") % locals()) raise quota.QuotaError( _("Instance quota exceeded. You can only " "run %s more instances of this type.") % num_instances, "InstanceLimitExceeded", ) image = self.image_service.show(context, image_id) if kernel_id is None: kernel_id = image.get("kernel_id", None) if ramdisk_id is None: ramdisk_id = image.get("ramdisk_id", None) # No kernel and ramdisk for raw images if kernel_id == str(FLAGS.null_kernel): kernel_id = None ramdisk_id = None LOG.debug(_("Creating a raw instance")) # Make sure we have access to kernel and ramdisk (if not raw) logging.debug("Using Kernel=%s, Ramdisk=%s" % (kernel_id, ramdisk_id)) if kernel_id: self.image_service.show(context, kernel_id) if ramdisk_id: self.image_service.show(context, ramdisk_id) if security_group is None: security_group = ["default"] if not type(security_group) is list: security_group = [security_group] security_groups = [] self.ensure_default_security_group(context) for security_group_name in security_group: group = db.security_group_get_by_name(context, context.project_id, security_group_name) security_groups.append(group["id"]) if key_data is None and key_name: key_pair = db.key_pair_get(context, context.user_id, key_name) key_data = key_pair["public_key"] base_options = { "reservation_id": utils.generate_uid("r"), "image_id": image_id, "kernel_id": kernel_id or "", "ramdisk_id": ramdisk_id or "", "state_description": "scheduling", "user_id": context.user_id, "project_id": context.project_id, "launch_time": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), "instance_type": instance_type, "memory_mb": type_data["memory_mb"], "vcpus": type_data["vcpus"], "local_gb": type_data["local_gb"], "display_name": display_name, "display_description": display_description, "user_data": user_data or "", "key_name": key_name, "key_data": key_data, "locked": False, "availability_zone": availability_zone, } elevated = context.elevated() instances = [] LOG.debug(_("Going to run %s instances..."), num_instances) for num in range(num_instances): instance = dict(mac_address=utils.generate_mac(), launch_index=num, **base_options) instance = self.db.instance_create(context, instance) instance_id = instance["id"] elevated = context.elevated() if not security_groups: security_groups = [] for security_group_id in security_groups: self.db.instance_add_security_group(elevated, instance_id, security_group_id) # Set sane defaults if not specified updates = dict(hostname=self.hostname_factory(instance_id)) if not hasattr(instance, "display_name") or instance.display_name == None: updates["display_name"] = "Server %s" % instance_id instance = self.update(context, instance_id, **updates) instances.append(instance) pid = context.project_id uid = context.user_id LOG.debug(_("Casting to scheduler for %(pid)s/%(uid)s's" " instance %(instance_id)s") % locals()) rpc.cast( context, FLAGS.scheduler_topic, { "method": "run_instance", "args": { "topic": FLAGS.compute_topic, "instance_id": instance_id, "availability_zone": availability_zone, "onset_files": onset_files, }, }, ) for group_id in security_groups: self.trigger_security_group_members_refresh(elevated, group_id) return [dict(x.iteritems()) for x in instances]
def create(self, context, instance_type, image_id, kernel_id=None, ramdisk_id=None, min_count=1, max_count=1, display_name='', display_description='', key_name=None, key_data=None, security_group='default', availability_zone=None, user_data=None, metadata={}, injected_files=None): """Create the number and type of instances requested. Verifies that quota and other arguments are valid. """ if not instance_type: instance_type = instance_types.get_default_instance_type() num_instances = quota.allowed_instances(context, max_count, instance_type) if num_instances < min_count: pid = context.project_id LOG.warn(_("Quota exceeeded for %(pid)s," " tried to run %(min_count)s instances") % locals()) raise quota.QuotaError(_("Instance quota exceeded. You can only " "run %s more instances of this type.") % num_instances, "InstanceLimitExceeded") self._check_metadata_properties_quota(context, metadata) self._check_injected_file_quota(context, injected_files) image = self.image_service.show(context, image_id) os_type = None if 'properties' in image and 'os_type' in image['properties']: os_type = image['properties']['os_type'] if kernel_id is None: kernel_id = image['properties'].get('kernel_id', None) if ramdisk_id is None: ramdisk_id = image['properties'].get('ramdisk_id', None) # FIXME(sirp): is there a way we can remove null_kernel? # No kernel and ramdisk for raw images if kernel_id == str(FLAGS.null_kernel): kernel_id = None ramdisk_id = None LOG.debug(_("Creating a raw instance")) # Make sure we have access to kernel and ramdisk (if not raw) logging.debug("Using Kernel=%s, Ramdisk=%s" % (kernel_id, ramdisk_id)) if kernel_id: self.image_service.show(context, kernel_id) if ramdisk_id: self.image_service.show(context, ramdisk_id) if security_group is None: security_group = ['default'] if not type(security_group) is list: security_group = [security_group] security_groups = [] self.ensure_default_security_group(context) for security_group_name in security_group: group = db.security_group_get_by_name(context, context.project_id, security_group_name) security_groups.append(group['id']) if key_data is None and key_name: key_pair = db.key_pair_get(context, context.user_id, key_name) key_data = key_pair['public_key'] base_options = { 'reservation_id': utils.generate_uid('r'), 'image_id': image_id, 'kernel_id': kernel_id or '', 'ramdisk_id': ramdisk_id or '', 'state': 0, 'state_description': 'scheduling', 'user_id': context.user_id, 'project_id': context.project_id, 'launch_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()), 'instance_type_id': instance_type['id'], 'memory_mb': instance_type['memory_mb'], 'vcpus': instance_type['vcpus'], 'local_gb': instance_type['local_gb'], 'display_name': display_name, 'display_description': display_description, 'user_data': user_data or '', 'key_name': key_name, 'key_data': key_data, 'locked': False, 'metadata': metadata, 'availability_zone': availability_zone, 'os_type': os_type} elevated = context.elevated() instances = [] LOG.debug(_("Going to run %s instances..."), num_instances) for num in range(num_instances): instance = dict(mac_address=utils.generate_mac(), launch_index=num, **base_options) instance = self.db.instance_create(context, instance) instance_id = instance['id'] elevated = context.elevated() if not security_groups: security_groups = [] for security_group_id in security_groups: self.db.instance_add_security_group(elevated, instance_id, security_group_id) # Set sane defaults if not specified updates = dict(hostname=self.hostname_factory(instance_id)) if (not hasattr(instance, 'display_name') or instance.display_name is None): updates['display_name'] = "Server %s" % instance_id instance = self.update(context, instance_id, **updates) instances.append(instance) pid = context.project_id uid = context.user_id LOG.debug(_("Casting to scheduler for %(pid)s/%(uid)s's" " instance %(instance_id)s") % locals()) rpc.cast(context, FLAGS.scheduler_topic, {"method": "run_instance", "args": {"topic": FLAGS.compute_topic, "instance_id": instance_id, "availability_zone": availability_zone, "injected_files": injected_files}}) for group_id in security_groups: self.trigger_security_group_members_refresh(elevated, group_id) return [dict(x.iteritems()) for x in instances]
def create(self, context, instance_type, image_id, kernel_id=None, ramdisk_id=None, min_count=1, max_count=1, display_name='', display_description='', key_name=None, key_data=None, security_group='default', availability_zone=None, user_data=None, metadata=[], onset_files=None): """Create the number of instances requested if quota and other arguments check out ok.""" type_data = instance_types.get_instance_type(instance_type) num_instances = quota.allowed_instances(context, max_count, type_data) if num_instances < min_count: pid = context.project_id LOG.warn(_("Quota exceeeded for %(pid)s," " tried to run %(min_count)s instances") % locals()) raise quota.QuotaError(_("Instance quota exceeded. You can only " "run %s more instances of this type.") % num_instances, "InstanceLimitExceeded") num_metadata = len(metadata) quota_metadata = quota.allowed_metadata_items(context, num_metadata) if quota_metadata < num_metadata: pid = context.project_id msg = (_("Quota exceeeded for %(pid)s," " tried to set %(num_metadata)s metadata properties") % locals()) LOG.warn(msg) raise quota.QuotaError(msg, "MetadataLimitExceeded") # Because metadata is stored in the DB, we hard-code the size limits # In future, we may support more variable length strings, so we act # as if this is quota-controlled for forwards compatibility for metadata_item in metadata: k = metadata_item['key'] v = metadata_item['value'] if len(k) > 255 or len(v) > 255: pid = context.project_id msg = (_("Quota exceeeded for %(pid)s," " metadata property key or value too long") % locals()) LOG.warn(msg) raise quota.QuotaError(msg, "MetadataLimitExceeded") image = self.image_service.show(context, image_id) if kernel_id is None: kernel_id = image.get('kernel_id', None) if ramdisk_id is None: ramdisk_id = image.get('ramdisk_id', None) # FIXME(sirp): is there a way we can remove null_kernel? # No kernel and ramdisk for raw images if kernel_id == str(FLAGS.null_kernel): kernel_id = None ramdisk_id = None LOG.debug(_("Creating a raw instance")) # Make sure we have access to kernel and ramdisk (if not raw) logging.debug("Using Kernel=%s, Ramdisk=%s" % (kernel_id, ramdisk_id)) if kernel_id: self.image_service.show(context, kernel_id) if ramdisk_id: self.image_service.show(context, ramdisk_id) if security_group is None: security_group = ['default'] if not type(security_group) is list: security_group = [security_group] security_groups = [] self.ensure_default_security_group(context) for security_group_name in security_group: group = db.security_group_get_by_name(context, context.project_id, security_group_name) security_groups.append(group['id']) if key_data is None and key_name: key_pair = db.key_pair_get(context, context.user_id, key_name) key_data = key_pair['public_key'] base_options = { 'reservation_id': utils.generate_uid('r'), 'image_id': image_id, 'kernel_id': kernel_id or '', 'ramdisk_id': ramdisk_id or '', 'state_description': 'scheduling', 'user_id': context.user_id, 'project_id': context.project_id, 'launch_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()), 'instance_type': instance_type, 'memory_mb': type_data['memory_mb'], 'vcpus': type_data['vcpus'], 'local_gb': type_data['local_gb'], 'display_name': display_name, 'display_description': display_description, 'user_data': user_data or '', 'key_name': key_name, 'key_data': key_data, 'locked': False, 'metadata': metadata, 'availability_zone': availability_zone} elevated = context.elevated() instances = [] LOG.debug(_("Going to run %s instances..."), num_instances) for num in range(num_instances): instance = dict(mac_address=utils.generate_mac(), launch_index=num, **base_options) instance = self.db.instance_create(context, instance) instance_id = instance['id'] elevated = context.elevated() if not security_groups: security_groups = [] for security_group_id in security_groups: self.db.instance_add_security_group(elevated, instance_id, security_group_id) # Set sane defaults if not specified updates = dict(hostname=self.hostname_factory(instance_id)) if (not hasattr(instance, 'display_name') or instance.display_name == None): updates['display_name'] = "Server %s" % instance_id instance = self.update(context, instance_id, **updates) instances.append(instance) pid = context.project_id uid = context.user_id LOG.debug(_("Casting to scheduler for %(pid)s/%(uid)s's" " instance %(instance_id)s") % locals()) rpc.cast(context, FLAGS.scheduler_topic, {"method": "run_instance", "args": {"topic": FLAGS.compute_topic, "instance_id": instance_id, "availability_zone": availability_zone, "onset_files": onset_files}}) for group_id in security_groups: self.trigger_security_group_members_refresh(elevated, group_id) return [dict(x.iteritems()) for x in instances]