def validate(self): ''' Validate any of the provided params ''' super(Server, self).validate() # check validity of key key_name = self.properties.get('key_name', None) if key_name: nova_utils.get_keypair(self.nova(), key_name) # either volume_id or snapshot_id needs to be specified, but not both # for block device mapping. bdm = self.properties.get('block_device_mapping') or [] bootable_vol = False for mapping in bdm: if mapping['device_name'] == 'vda': bootable_vol = True if mapping.get('volume_id') and mapping.get('snapshot_id'): raise exception.ResourcePropertyConflict('volume_id', 'snapshot_id') if not mapping.get('volume_id') and not mapping.get('snapshot_id'): msg = _('Either volume_id or snapshot_id must be specified for' ' device mapping %s') % mapping['device_name'] raise exception.StackValidationFailed(message=msg) # make sure the image exists if specified. image = self.properties.get('image', None) if image: nova_utils.get_image_id(self.nova(), image) elif not image and not bootable_vol: msg = _('Neither image nor bootable volume is specified for' ' instance %s') % self.name raise exception.StackValidationFailed(message=msg)
def validate(self): ''' Validate any of the provided params ''' super(Server, self).validate() # check validity of key key_name = self.properties.get('key_name', None) if key_name: nova_utils.get_keypair(self.nova(), key_name) # either volume_id or snapshot_id needs to be specified, but not both # for block device mapping. bdm = self.properties.get('block_device_mapping') or [] bootable_vol = False for mapping in bdm: if mapping['device_name'] == 'vda': bootable_vol = True if mapping.get('volume_id') and mapping.get('snapshot_id'): raise exception.ResourcePropertyConflict( 'volume_id', 'snapshot_id') if not mapping.get('volume_id') and not mapping.get('snapshot_id'): msg = _('Either volume_id or snapshot_id must be specified for' ' device mapping %s') % mapping['device_name'] raise exception.StackValidationFailed(message=msg) # make sure the image exists if specified. image = self.properties.get('image', None) if image: nova_utils.get_image_id(self.nova(), image) elif not image and not bootable_vol: msg = _('Neither image nor bootable volume is specified for' ' instance %s') % self.name raise exception.StackValidationFailed(message=msg)
def validate(self, value, context): try: nova_client = clients.Clients(context).nova() nova_utils.get_image_id(nova_client, value) except Exception: return False else: return True
def validate(self, value, context): try: nova_client = clients.Clients(context).nova() nova_utils.get_image_id(nova_client, value) except exception.ImageNotFound: return False else: return True
def validate(self): ''' Validate any of the provided params ''' super(Server, self).validate() # check validity of key key_name = self.properties.get('key_name') if key_name: nova_utils.get_keypair(self.nova(), key_name) # either volume_id or snapshot_id needs to be specified, but not both # for block device mapping. bdm = self.properties.get('block_device_mapping') or [] bootable_vol = False for mapping in bdm: if mapping['device_name'] == 'vda': bootable_vol = True if mapping.get('volume_id') and mapping.get('snapshot_id'): raise exception.ResourcePropertyConflict('volume_id', 'snapshot_id') if not mapping.get('volume_id') and not mapping.get('snapshot_id'): msg = _('Either volume_id or snapshot_id must be specified for' ' device mapping %s') % mapping['device_name'] raise exception.StackValidationFailed(message=msg) # make sure the image exists if specified. image = self.properties.get('image') if image: nova_utils.get_image_id(self.nova(), image) elif not image and not bootable_vol: msg = _('Neither image nor bootable volume is specified for' ' instance %s') % self.name raise exception.StackValidationFailed(message=msg) # network properties 'uuid' and 'network' shouldn't be used # both at once for all networks networks = self.properties.get('networks') or [] for network in networks: if network.get('uuid') and network.get('network'): msg = _('Properties "uuid" and "network" are both set ' 'to the network "%(network)s" for the server ' '"%(server)s". The "uuid" property is deprecated. ' 'Use only "network" property.' '') % dict(network=network['network'], server=self.name) raise exception.StackValidationFailed(message=msg) elif network.get('uuid'): logger.info(_('For the server "%(server)s" the "uuid" ' 'property is set to network "%(network)s". ' '"uuid" property is deprecated. Use "network" ' 'property instead.' '') % dict(network=network['network'], server=self.name))
def test_get_image_id(self): """Tests the get_image_id function.""" my_image = self.m.CreateMockAnything() img_id = str(uuid.uuid4()) img_name = "myfakeimage" my_image.id = img_id my_image.name = img_name self.nova_client.images = self.m.CreateMockAnything() self.nova_client.images.get(img_id).AndReturn(my_image) self.nova_client.images.list().MultipleTimes().AndReturn([my_image]) self.m.ReplayAll() self.assertEqual(img_id, nova_utils.get_image_id(self.nova_client, img_id)) self.assertEqual(img_id, nova_utils.get_image_id(self.nova_client, "myfakeimage")) self.assertRaises(exception.ImageNotFound, nova_utils.get_image_id, self.nova_client, "noimage") self.m.VerifyAll()
def handle_create(self): security_groups = self.properties.get(self.SECURITY_GROUPS) user_data_format = self.properties.get(self.USER_DATA_FORMAT) userdata = nova_utils.build_userdata( self, self.properties.get(self.USER_DATA), instance_user=self.properties[self.ADMIN_USER], user_data_format=user_data_format) flavor = self.properties[self.FLAVOR] availability_zone = self.properties[self.AVAILABILITY_ZONE] key_name = self.properties[self.KEY_NAME] if key_name: # confirm keypair exists nova_utils.get_keypair(self.nova(), key_name) image = self.properties.get(self.IMAGE) if image: image = nova_utils.get_image_id(self.nova(), image) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) instance_meta = self.properties.get(self.METADATA) if instance_meta is not None: instance_meta = nova_utils.meta_serialize(instance_meta) scheduler_hints = self.properties.get(self.SCHEDULER_HINTS) nics = self._build_nics(self.properties.get(self.NETWORKS)) block_device_mapping = self._build_block_device_mapping( self.properties.get(self.BLOCK_DEVICE_MAPPING)) reservation_id = self.properties.get(self.RESERVATION_ID) config_drive = self.properties.get(self.CONFIG_DRIVE) disk_config = self.properties.get(self.DISK_CONFIG) server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=userdata, meta=instance_meta, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone, block_device_mapping=block_device_mapping, reservation_id=reservation_id, config_drive=config_drive, disk_config=disk_config) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server
def validate(self): ''' Validate any of the provided params ''' res = super(Instance, self).validate() if res: return res # check validity of security groups vs. network interfaces security_groups = self._get_security_groups() if security_groups and self.properties.get(self.NETWORK_INTERFACES): raise exception.ResourcePropertyConflict( '/'.join([self.SECURITY_GROUPS, self.SECURITY_GROUP_IDS]), self.NETWORK_INTERFACES) # make sure the image exists. nova_utils.get_image_id(self.nova(), self.properties[self.IMAGE_ID])
def handle_update(self, json_snippet, tmpl_diff, prop_diff): if 'Metadata' in tmpl_diff: self.metadata = tmpl_diff['Metadata'] checkers = [] server = None if self.METADATA in prop_diff: server = self.nova().servers.get(self.resource_id) nova_utils.meta_update(self.nova(), server, prop_diff[self.METADATA]) if self.FLAVOR in prop_diff: flavor_update_policy = (prop_diff.get(self.FLAVOR_UPDATE_POLICY) or self.properties.get( self.FLAVOR_UPDATE_POLICY)) if flavor_update_policy == 'REPLACE': raise resource.UpdateReplace(self.name) flavor = prop_diff[self.FLAVOR] flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) if not server: server = self.nova().servers.get(self.resource_id) checker = scheduler.TaskRunner(nova_utils.resize, server, flavor, flavor_id) checkers.append(checker) if self.IMAGE in prop_diff: image_update_policy = (prop_diff.get(self.IMAGE_UPDATE_POLICY) or self.properties.get( self.IMAGE_UPDATE_POLICY)) if image_update_policy == 'REPLACE': raise resource.UpdateReplace(self.name) image = prop_diff[self.IMAGE] image_id = nova_utils.get_image_id(self.nova(), image) if not server: server = self.nova().servers.get(self.resource_id) preserve_ephemeral = ( image_update_policy == 'REBUILD_PRESERVE_EPHEMERAL') checker = scheduler.TaskRunner( nova_utils.rebuild, server, image_id, preserve_ephemeral=preserve_ephemeral) checkers.append(checker) if self.NAME in prop_diff: if not server: server = self.nova().servers.get(self.resource_id) nova_utils.rename(server, prop_diff[self.NAME]) # Optimization: make sure the first task is started before # check_update_complete. if checkers: checkers[0].start() return checkers
def handle_update(self, json_snippet, tmpl_diff, prop_diff): if 'Metadata' in tmpl_diff: self.metadata = tmpl_diff['Metadata'] checkers = [] server = None if self.METADATA in prop_diff: server = self.nova().servers.get(self.resource_id) nova_utils.meta_update(self.nova(), server, prop_diff[self.METADATA]) if self.FLAVOR in prop_diff: flavor_update_policy = ( prop_diff.get(self.FLAVOR_UPDATE_POLICY) or self.properties.get(self.FLAVOR_UPDATE_POLICY)) if flavor_update_policy == 'REPLACE': raise resource.UpdateReplace(self.name) flavor = prop_diff[self.FLAVOR] flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) if not server: server = self.nova().servers.get(self.resource_id) checker = scheduler.TaskRunner(nova_utils.resize, server, flavor, flavor_id) checkers.append(checker) if self.IMAGE in prop_diff: image_update_policy = ( prop_diff.get(self.IMAGE_UPDATE_POLICY) or self.properties.get(self.IMAGE_UPDATE_POLICY)) if image_update_policy == 'REPLACE': raise resource.UpdateReplace(self.name) image = prop_diff[self.IMAGE] image_id = nova_utils.get_image_id(self.nova(), image) if not server: server = self.nova().servers.get(self.resource_id) preserve_ephemeral = ( image_update_policy == 'REBUILD_PRESERVE_EPHEMERAL') checker = scheduler.TaskRunner( nova_utils.rebuild, server, image_id, preserve_ephemeral=preserve_ephemeral) checkers.append(checker) if self.NAME in prop_diff: if not server: server = self.nova().servers.get(self.resource_id) nova_utils.rename(server, prop_diff[self.NAME]) # Optimization: make sure the first task is started before # check_update_complete. if checkers: checkers[0].start() return checkers
def test_get_image_id(self): """Tests the get_image_id function.""" my_image = self.m.CreateMockAnything() img_id = str(uuid.uuid4()) img_name = 'myfakeimage' my_image.id = img_id my_image.name = img_name self.nova_client.images = self.m.CreateMockAnything() self.nova_client.images.get(img_id).AndReturn(my_image) self.nova_client.images.list().MultipleTimes().AndReturn([my_image]) self.m.ReplayAll() self.assertEqual(img_id, nova_utils.get_image_id(self.nova_client, img_id)) self.assertEqual( img_id, nova_utils.get_image_id(self.nova_client, 'myfakeimage')) self.assertRaises(exception.ImageNotFound, nova_utils.get_image_id, self.nova_client, 'noimage') self.m.VerifyAll()
def handle_create(self): security_groups = self._get_security_groups() userdata = self.properties['UserData'] or '' flavor = self.properties['InstanceType'] availability_zone = self.properties['AvailabilityZone'] key_name = self.properties['KeyName'] if key_name: # confirm keypair exists nova_utils.get_keypair(self.nova(), key_name) image_name = self.properties['ImageId'] image_id = nova_utils.get_image_id(self.nova(), image_name) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) tags = {} if self.properties['Tags']: for tm in self.properties['Tags']: tags[tm['Key']] = tm['Value'] else: tags = None scheduler_hints = {} if self.properties['NovaSchedulerHints']: for tm in self.properties['NovaSchedulerHints']: scheduler_hints[tm['Key']] = tm['Value'] else: scheduler_hints = None nics = self._build_nics(self.properties['NetworkInterfaces'], security_groups=security_groups, subnet_id=self.properties['SubnetId']) server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image_id, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=self.get_mime_string(userdata), meta=tags, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server, scheduler.TaskRunner(self._attach_volumes_task())
def handle_create(self): security_groups = self.properties.get('security_groups', []) user_data_format = self.properties.get('user_data_format') userdata = nova_utils.build_userdata( self, self.properties.get('user_data', ''), instance_user=self.properties['admin_user'], user_data_format=user_data_format) flavor = self.properties['flavor'] availability_zone = self.properties['availability_zone'] key_name = self.properties['key_name'] if key_name: # confirm keypair exists nova_utils.get_keypair(self.nova(), key_name) image = self.properties.get('image') if image: image = nova_utils.get_image_id(self.nova(), image) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) instance_meta = self.properties.get('metadata') scheduler_hints = self.properties.get('scheduler_hints') nics = self._build_nics(self.properties.get('networks')) block_device_mapping = self._build_block_device_mapping( self.properties.get('block_device_mapping')) reservation_id = self.properties.get('reservation_id') config_drive = self.properties.get('config_drive') disk_config = self.properties.get('diskConfig') server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=userdata, meta=instance_meta, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone, block_device_mapping=block_device_mapping, reservation_id=reservation_id, config_drive=config_drive, disk_config=disk_config) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server
def handle_create(self): security_groups = self.properties.get('security_groups', []) user_data_format = self.properties.get('user_data_format') if user_data_format == 'HEAT_CFNTOOLS': userdata = self.get_mime_string( self.properties.get('user_data', '')) else: userdata = self.properties.get('user_data', '') flavor = self.properties['flavor'] availability_zone = self.properties['availability_zone'] key_name = self.properties['key_name'] if key_name: # confirm keypair exists nova_utils.get_keypair(self.nova(), key_name) image = self.properties.get('image') if image: image = nova_utils.get_image_id(self.nova(), image) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) instance_meta = self.properties.get('metadata') scheduler_hints = self.properties.get('scheduler_hints') nics = self._build_nics(self.properties.get('networks')) block_device_mapping = self._build_block_device_mapping( self.properties.get('block_device_mapping')) reservation_id = self.properties.get('reservation_id') config_drive = self.properties.get('config_drive') disk_config = self.properties.get('diskConfig') server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=userdata, meta=instance_meta, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone, block_device_mapping=block_device_mapping, reservation_id=reservation_id, config_drive=config_drive, disk_config=disk_config) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server
def _create_arguments(self): arguments = {"size": self.properties[self.SIZE], "availability_zone": self.properties[self.AVAILABILITY_ZONE]} if self.properties.get(self.IMAGE): arguments["imageRef"] = nova_utils.get_image_id(self.nova(), self.properties[self.IMAGE]) elif self.properties.get(self.IMAGE_REF): arguments["imageRef"] = self.properties[self.IMAGE_REF] optionals = (self.SNAPSHOT_ID, self.VOLUME_TYPE, self.SOURCE_VOLID, self.METADATA) arguments.update((prop, self.properties[prop]) for prop in optionals if self.properties[prop]) return arguments
def validate(self): ''' Validate any of the provided params ''' super(Server, self).validate() # check validity of key key_name = self.properties.get('key_name', None) if key_name: nova_utils.get_keypair(self.nova(), key_name) # make sure the image exists if specified. image = self.properties.get('image', None) if image: nova_utils.get_image_id(self.nova(), image) else: # TODO(sbaker) confirm block_device_mapping is populated # for boot-by-volume (see LP bug #1215267) pass
def _create_arguments(self): arguments = {"size": self.properties["size"], "availability_zone": self.properties["availability_zone"]} if self.properties.get("image"): arguments["imageRef"] = nova_utils.get_image_id(self.nova(), self.properties["image"]) elif self.properties.get("imageRef"): arguments["imageRef"] = self.properties["imageRef"] optionals = ["snapshot_id", "volume_type", "source_volid", "metadata"] arguments.update((prop, self.properties[prop]) for prop in optionals if self.properties[prop]) return arguments
def handle_create(self): security_groups = self._get_security_groups() userdata = self.properties['UserData'] or '' flavor = self.properties['InstanceType'] availability_zone = self.properties['AvailabilityZone'] key_name = self.properties['KeyName'] if key_name: # confirm keypair exists nova_utils.get_keypair(self.nova(), key_name) image_name = self.properties['ImageId'] image_id = nova_utils.get_image_id(self.nova(), image_name) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) tags = {} if self.properties['Tags']: for tm in self.properties['Tags']: tags[tm['Key']] = tm['Value'] else: tags = None scheduler_hints = {} if self.properties['NovaSchedulerHints']: for tm in self.properties['NovaSchedulerHints']: scheduler_hints[tm['Key']] = tm['Value'] else: scheduler_hints = None nics = self._build_nics(self.properties['NetworkInterfaces'], subnet_id=self.properties['SubnetId']) server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image_id, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=self.get_mime_string(userdata), meta=tags, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server, scheduler.TaskRunner(self._attach_volumes_task())
def validate(self): """ Validate any of the provided params """ res = super(Instance, self).validate() if res: return res # check validity of key key_name = self.properties.get("KeyName", None) if key_name: nova_utils.get_keypair(self.nova(), key_name) # check validity of security groups vs. network interfaces security_groups = self._get_security_groups() if security_groups and self.properties.get("NetworkInterfaces"): raise exception.ResourcePropertyConflict("SecurityGroups/SecurityGroupIds", "NetworkInterfaces") # make sure the image exists. nova_utils.get_image_id(self.nova(), self.properties["ImageId"])
def handle_create(self): security_groups = self._get_security_groups() userdata = self.properties[self.USER_DATA] or '' flavor = self.properties[self.INSTANCE_TYPE] availability_zone = self.properties[self.AVAILABILITY_ZONE] image_name = self.properties[self.IMAGE_ID] image_id = nova_utils.get_image_id(self.nova(), image_name) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) scheduler_hints = {} if self.properties[self.NOVA_SCHEDULER_HINTS]: for tm in self.properties[self.NOVA_SCHEDULER_HINTS]: scheduler_hints[tm[self.TAG_KEY]] = tm[self.TAG_VALUE] else: scheduler_hints = None nics = self._build_nics(self.properties[self.NETWORK_INTERFACES], security_groups=security_groups, subnet_id=self.properties[self.SUBNET_ID]) server = None # FIXME(shadower): the instance_user config option is deprecated. Once # it's gone, we should always use ec2-user for compatibility with # CloudFormation. if cfg.CONF.instance_user: instance_user = cfg.CONF.instance_user else: instance_user = '******' try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image_id, flavor=flavor_id, key_name=self.properties[self.KEY_NAME], security_groups=security_groups, userdata=nova_utils.build_userdata(self, userdata, instance_user), meta=self._get_nova_metadata(self.properties), scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server, scheduler.TaskRunner(self._attach_volumes_task())
def validate(self): ''' Validate any of the provided params ''' res = super(Instance, self).validate() if res: return res # check validity of key key_name = self.properties.get('KeyName', None) if key_name: nova_utils.get_keypair(self.nova(), key_name) # check validity of security groups vs. network interfaces security_groups = self._get_security_groups() if security_groups and self.properties.get('NetworkInterfaces'): raise exception.ResourcePropertyConflict( 'SecurityGroups/SecurityGroupIds', 'NetworkInterfaces') # make sure the image exists. nova_utils.get_image_id(self.nova(), self.properties['ImageId'])
def test_cinder_create_from_image(self): fv = FakeVolumeWithStateTransition('downloading', 'available') stack_name = 'test_volume_stack' clients.OpenStackClients.cinder().MultipleTimes().AndReturn( self.cinder_fc) clients.OpenStackClients.nova("compute").MultipleTimes().AndReturn( self.fc) clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) nova_utils.get_image_id( self.fc, '46988116-6703-4623-9dbc-2bc6d284021b').MultipleTimes().AndReturn( '46988116-6703-4623-9dbc-2bc6d284021b') self.cinder_fc.volumes.create( size=1, availability_zone='nova', display_description='ImageVolumeDescription', display_name='ImageVolume', imageRef='46988116-6703-4623-9dbc-2bc6d284021b').AndReturn(fv) self.m.ReplayAll() t = template_format.parse(volume_template) t['Resources']['DataVolume']['Properties'] = { 'size': '1', 'name': 'ImageVolume', 'description': 'ImageVolumeDescription', 'availability_zone': 'nova', 'image': '46988116-6703-4623-9dbc-2bc6d284021b', } stack = utils.parse_stack(t, stack_name=stack_name) rsrc = vol.CinderVolume('DataVolume', t['Resources']['DataVolume'], stack) self.assertIsNone(rsrc.validate()) scheduler.TaskRunner(rsrc.create)() self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertEqual('available', fv.status) self.m.VerifyAll()
def test_cinder_create_from_image(self): fv = FakeVolumeWithStateTransition('downloading', 'available') stack_name = 'test_volume_stack' clients.OpenStackClients.cinder().MultipleTimes().AndReturn( self.cinder_fc) clients.OpenStackClients.nova("compute").MultipleTimes().AndReturn( self.fc) clients.OpenStackClients.nova().MultipleTimes().AndReturn(self.fc) nova_utils.get_image_id( self.fc, '46988116-6703-4623-9dbc-2bc6d284021b' ).MultipleTimes().AndReturn('46988116-6703-4623-9dbc-2bc6d284021b') self.cinder_fc.volumes.create( size=1, availability_zone='nova', display_description='ImageVolumeDescription', display_name='ImageVolume', imageRef='46988116-6703-4623-9dbc-2bc6d284021b').AndReturn(fv) self.m.ReplayAll() t = template_format.parse(volume_template) t['Resources']['DataVolume']['Properties'] = { 'size': '1', 'name': 'ImageVolume', 'description': 'ImageVolumeDescription', 'availability_zone': 'nova', 'image': '46988116-6703-4623-9dbc-2bc6d284021b', } stack = utils.parse_stack(t, stack_name=stack_name) rsrc = vol.CinderVolume('DataVolume', t['Resources']['DataVolume'], stack) self.assertIsNone(rsrc.validate()) scheduler.TaskRunner(rsrc.create)() self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.assertEqual('available', fv.status) self.m.VerifyAll()
def handle_update(self, json_snippet, tmpl_diff, prop_diff): if 'Metadata' in tmpl_diff: self.metadata = tmpl_diff['Metadata'] checkers = [] server = None if 'metadata' in prop_diff: server = self.nova().servers.get(self.resource_id) nova_utils.meta_update(self.nova(), server, prop_diff['metadata']) if 'flavor' in prop_diff: flavor_update_policy = ( prop_diff.get('flavor_update_policy') or self.properties.get('flavor_update_policy')) if flavor_update_policy == 'REPLACE': raise resource.UpdateReplace(self.name) flavor = prop_diff['flavor'] flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) if not server: server = self.nova().servers.get(self.resource_id) checker = scheduler.TaskRunner(nova_utils.resize, server, flavor, flavor_id) checkers.append(checker) if 'image' in prop_diff: image_update_policy = ( prop_diff.get('image_update_policy') or self.properties.get('image_update_policy')) if image_update_policy == 'REPLACE': raise resource.UpdateReplace(self.name) image = prop_diff['image'] image_id = nova_utils.get_image_id(self.nova(), image) if not server: server = self.nova().servers.get(self.resource_id) checker = scheduler.TaskRunner(nova_utils.rebuild, server, image_id) checkers.append(checker) # Optimization: make sure the first task is started before # check_update_complete. if checkers: checkers[0].start() return checkers
def handle_create(self): security_groups = self._get_security_groups() userdata = self.properties[self.USER_DATA] or '' flavor = self.properties[self.INSTANCE_TYPE] availability_zone = self.properties[self.AVAILABILITY_ZONE] key_name = self.properties[self.KEY_NAME] if key_name: # confirm keypair exists nova_utils.get_keypair(self.nova(), key_name) image_name = self.properties[self.IMAGE_ID] image_id = nova_utils.get_image_id(self.nova(), image_name) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) scheduler_hints = {} if self.properties[self.NOVA_SCHEDULER_HINTS]: for tm in self.properties[self.NOVA_SCHEDULER_HINTS]: scheduler_hints[tm[self.TAG_KEY]] = tm[self.TAG_VALUE] else: scheduler_hints = None nics = self._build_nics(self.properties[self.NETWORK_INTERFACES], security_groups=security_groups, subnet_id=self.properties[self.SUBNET_ID]) server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image_id, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=nova_utils.build_userdata(self, userdata), meta=self._get_nova_metadata(self.properties), scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server, scheduler.TaskRunner(self._attach_volumes_task())
def _create_arguments(self): arguments = { 'size': self.properties['size'], 'availability_zone': self.properties['availability_zone'] } if self.properties.get('image'): arguments['imageRef'] = nova_utils.get_image_id( self.nova(), self.properties['image']) elif self.properties.get('imageRef'): arguments['imageRef'] = self.properties['imageRef'] optionals = ['snapshot_id', 'volume_type', 'source_volid', 'metadata'] arguments.update((prop, self.properties[prop]) for prop in optionals if self.properties[prop]) return arguments
def test_get_image_id_by_name_in_uuid(self): """Tests the get_image_id function by name in uuid.""" my_image = self.m.CreateMockAnything() img_id = str(uuid.uuid4()) img_name = str(uuid.uuid4()) my_image.id = img_id my_image.name = img_name self.nova_client.images = self.m.CreateMockAnything() self.nova_client.images.get(img_name).AndRaise( clients.novaclient.exceptions.NotFound(404)) self.nova_client.images.list().MultipleTimes().AndReturn([my_image]) self.m.ReplayAll() self.assertEqual(img_id, nova_utils.get_image_id(self.nova_client, img_name)) self.m.VerifyAll()
def _create_arguments(self): arguments = { 'size': self.properties[self.SIZE], 'availability_zone': self.properties[self.AVAILABILITY_ZONE] } if self.properties.get(self.IMAGE): arguments['imageRef'] = nova_utils.get_image_id( self.nova(), self.properties[self.IMAGE]) elif self.properties.get(self.IMAGE_REF): arguments['imageRef'] = self.properties[self.IMAGE_REF] optionals = (self.SNAPSHOT_ID, self.VOLUME_TYPE, self.SOURCE_VOLID, self.METADATA) arguments.update((prop, self.properties[prop]) for prop in optionals if self.properties[prop]) return arguments
def handle_update(self, json_snippet, tmpl_diff, prop_diff): if 'Metadata' in tmpl_diff: self.metadata = tmpl_diff['Metadata'] checkers = [] server = None if 'metadata' in prop_diff: server = self.nova().servers.get(self.resource_id) nova_utils.meta_update(self.nova(), server, prop_diff['metadata']) if 'flavor' in prop_diff: flavor_update_policy = ( prop_diff.get('flavor_update_policy') or self.properties.get('flavor_update_policy')) if flavor_update_policy == 'REPLACE': raise resource.UpdateReplace(self.name) flavor = prop_diff['flavor'] flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) if not server: server = self.nova().servers.get(self.resource_id) checker = scheduler.TaskRunner(nova_utils.resize, server, flavor, flavor_id) checkers.append(checker) if 'image' in prop_diff: image_update_policy = (prop_diff.get('image_update_policy') or self.properties.get('image_update_policy')) if image_update_policy == 'REPLACE': raise resource.UpdateReplace(self.name) image = prop_diff['image'] image_id = nova_utils.get_image_id(self.nova(), image) if not server: server = self.nova().servers.get(self.resource_id) checker = scheduler.TaskRunner(nova_utils.rebuild, server, image_id) checkers.append(checker) # Optimization: make sure the first task is started before # check_update_complete. if checkers: checkers[0].start() return checkers
def handle_update(self, json_snippet, tmpl_diff, prop_diff): if 'Metadata' in tmpl_diff: self.metadata = tmpl_diff['Metadata'] checkers = [] server = None if self.METADATA in prop_diff: server = self.nova().servers.get(self.resource_id) nova_utils.meta_update(self.nova(), server, prop_diff[self.METADATA]) if self.FLAVOR in prop_diff: flavor_update_policy = (prop_diff.get(self.FLAVOR_UPDATE_POLICY) or self.properties.get( self.FLAVOR_UPDATE_POLICY)) if flavor_update_policy == 'REPLACE': raise resource.UpdateReplace(self.name) flavor = prop_diff[self.FLAVOR] flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) if not server: server = self.nova().servers.get(self.resource_id) checker = scheduler.TaskRunner(nova_utils.resize, server, flavor, flavor_id) checkers.append(checker) if self.IMAGE in prop_diff: image_update_policy = (prop_diff.get(self.IMAGE_UPDATE_POLICY) or self.properties.get( self.IMAGE_UPDATE_POLICY)) if image_update_policy == 'REPLACE': raise resource.UpdateReplace(self.name) image = prop_diff[self.IMAGE] image_id = nova_utils.get_image_id(self.nova(), image) if not server: server = self.nova().servers.get(self.resource_id) preserve_ephemeral = ( image_update_policy == 'REBUILD_PRESERVE_EPHEMERAL') checker = scheduler.TaskRunner( nova_utils.rebuild, server, image_id, preserve_ephemeral=preserve_ephemeral) checkers.append(checker) if self.NAME in prop_diff: if not server: server = self.nova().servers.get(self.resource_id) nova_utils.rename(server, prop_diff[self.NAME]) if self.NETWORKS in prop_diff: new_networks = prop_diff.get(self.NETWORKS) attach_first_free_port = False if not new_networks: new_networks = [] attach_first_free_port = True old_networks = self.properties.get(self.NETWORKS) if not server: server = self.nova().servers.get(self.resource_id) interfaces = server.interface_list() # if old networks is None, it means that the server got first # free port. so we should detach this interface. if old_networks is None: for iface in interfaces: checker = scheduler.TaskRunner(server.interface_detach, iface.port_id) checkers.append(checker) # if we have any information in networks field, we should: # 1. find similar networks, if they exist # 2. remove these networks from new_networks and old_networks # lists # 3. detach unmatched networks, which were present in old_networks # 4. attach unmatched networks, which were present in new_networks else: # remove not updated networks from old and new networks lists, # also get list these networks not_updated_networks = \ self._get_network_matches(old_networks, new_networks) self.update_networks_matching_iface_port( old_networks + not_updated_networks, interfaces) # according to nova interface-detach command detached port # will be deleted for net in old_networks: checker = scheduler.TaskRunner(server.interface_detach, net.get('port')) checkers.append(checker) # attach section similar for both variants that # were mentioned above for net in new_networks: if net.get('port'): checker = scheduler.TaskRunner(server.interface_attach, net['port'], None, None) checkers.append(checker) elif net.get('network'): checker = scheduler.TaskRunner(server.interface_attach, None, net['network'], net.get('fixed_ip')) checkers.append(checker) # if new_networks is None, we should attach first free port, # according to similar behavior during instance creation if attach_first_free_port: checker = scheduler.TaskRunner(server.interface_attach, None, None, None) checkers.append(checker) # Optimization: make sure the first task is started before # check_update_complete. if checkers: checkers[0].start() return checkers
def image(self): if not self._image: self._image = nova_utils.get_image_id(self.nova(), self.properties["image"]) return self._image
def image(self): """Return the server's image ID.""" image = self.properties.get(self.IMAGE) if image and self._image is None: self._image = nova_utils.get_image_id(self.nova(), image) return self._image
def image(self): if not self._image: self._image = nova_utils.get_image_id(self.nova(), self.properties['image']) return self._image
def validate(self): ''' Validate any of the provided params ''' super(Server, self).validate() # either volume_id or snapshot_id needs to be specified, but not both # for block device mapping. bdm = self.properties.get(self.BLOCK_DEVICE_MAPPING) or [] bootable_vol = False for mapping in bdm: device_name = mapping[self.BLOCK_DEVICE_MAPPING_DEVICE_NAME] if device_name == 'vda': bootable_vol = True volume_id = mapping.get(self.BLOCK_DEVICE_MAPPING_VOLUME_ID) snapshot_id = mapping.get(self.BLOCK_DEVICE_MAPPING_SNAPSHOT_ID) if volume_id and snapshot_id: raise exception.ResourcePropertyConflict( self.BLOCK_DEVICE_MAPPING_VOLUME_ID, self.BLOCK_DEVICE_MAPPING_SNAPSHOT_ID) if not volume_id and not snapshot_id: msg = _('Either volume_id or snapshot_id must be specified for' ' device mapping %s') % device_name raise exception.StackValidationFailed(message=msg) # make sure the image exists if specified. image = self.properties.get(self.IMAGE) if image: nova_utils.get_image_id(self.nova(), image) elif not image and not bootable_vol: msg = _('Neither image nor bootable volume is specified for' ' instance %s') % self.name raise exception.StackValidationFailed(message=msg) # network properties 'uuid' and 'network' shouldn't be used # both at once for all networks networks = self.properties.get(self.NETWORKS) or [] for network in networks: if network.get(self.NETWORK_UUID) and network.get(self.NETWORK_ID): msg = _('Properties "%(uuid)s" and "%(id)s" are both set ' 'to the network "%(network)s" for the server ' '"%(server)s". The "%(uuid)s" property is deprecated. ' 'Use only "%(id)s" property.' '') % dict(uuid=self.NETWORK_UUID, id=self.NETWORK_ID, network=network[self.NETWORK_ID], server=self.name) raise exception.StackValidationFailed(message=msg) elif network.get(self.NETWORK_UUID): logger.info(_('For the server "%(server)s" the "%(uuid)s" ' 'property is set to network "%(network)s". ' '"%(uuid)s" property is deprecated. Use ' '"%(id)s" property instead.' '') % dict(uuid=self.NETWORK_UUID, id=self.NETWORK_ID, network=network[self.NETWORK_ID], server=self.name)) # retrieve provider's absolute limits if it will be needed metadata = self.properties.get(self.METADATA) personality = self._personality() if metadata is not None or personality is not None: limits = nova_utils.absolute_limits(self.nova()) # verify that the number of metadata entries is not greater # than the maximum number allowed in the provider's absolute # limits if metadata is not None: if len(metadata) > limits['maxServerMeta']: msg = _('Instance metadata must not contain greater than %s ' 'entries. This is the maximum number allowed by your ' 'service provider') % limits['maxServerMeta'] raise exception.StackValidationFailed(message=msg) # verify the number of personality files and the size of each # personality file against the provider's absolute limits if personality is not None: if len(personality) > limits['maxPersonality']: msg = _("The personality property may not contain " "greater than %s entries.") % limits['maxPersonality'] raise exception.StackValidationFailed(message=msg) for path, contents in personality.items(): if len(bytes(contents)) > limits['maxPersonalitySize']: msg = (_("The contents of personality file \"%(path)s\" " "is larger than the maximum allowed personality " "file size (%(max_size)s bytes).") % {'path': path, 'max_size': limits['maxPersonalitySize']}) raise exception.StackValidationFailed(message=msg)
def validate_with_client(self, client, value): nova_client = client.nova() nova_utils.get_image_id(nova_client, value)
def handle_update(self, json_snippet, tmpl_diff, prop_diff): if 'Metadata' in tmpl_diff: self.metadata_set(tmpl_diff['Metadata']) checkers = [] server = None if self.METADATA in prop_diff: server = self.nova().servers.get(self.resource_id) nova_utils.meta_update(self.nova(), server, prop_diff[self.METADATA]) if self.FLAVOR in prop_diff: flavor_update_policy = ( prop_diff.get(self.FLAVOR_UPDATE_POLICY) or self.properties.get(self.FLAVOR_UPDATE_POLICY)) if flavor_update_policy == 'REPLACE': raise resource.UpdateReplace(self.name) flavor = prop_diff[self.FLAVOR] flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) if not server: server = self.nova().servers.get(self.resource_id) checker = scheduler.TaskRunner(nova_utils.resize, server, flavor, flavor_id) checkers.append(checker) if self.IMAGE in prop_diff: image_update_policy = ( prop_diff.get(self.IMAGE_UPDATE_POLICY) or self.properties.get(self.IMAGE_UPDATE_POLICY)) if image_update_policy == 'REPLACE': raise resource.UpdateReplace(self.name) image = prop_diff[self.IMAGE] image_id = nova_utils.get_image_id(self.nova(), image) if not server: server = self.nova().servers.get(self.resource_id) preserve_ephemeral = ( image_update_policy == 'REBUILD_PRESERVE_EPHEMERAL') checker = scheduler.TaskRunner( nova_utils.rebuild, server, image_id, preserve_ephemeral=preserve_ephemeral) checkers.append(checker) if self.NAME in prop_diff: if not server: server = self.nova().servers.get(self.resource_id) nova_utils.rename(server, prop_diff[self.NAME]) if self.NETWORKS in prop_diff: new_networks = prop_diff.get(self.NETWORKS) attach_first_free_port = False if not new_networks: new_networks = [] attach_first_free_port = True old_networks = self.properties.get(self.NETWORKS) if not server: server = self.nova().servers.get(self.resource_id) interfaces = server.interface_list() # if old networks is None, it means that the server got first # free port. so we should detach this interface. if old_networks is None: for iface in interfaces: checker = scheduler.TaskRunner(server.interface_detach, iface.port_id) checkers.append(checker) # if we have any information in networks field, we should: # 1. find similar networks, if they exist # 2. remove these networks from new_networks and old_networks # lists # 3. detach unmatched networks, which were present in old_networks # 4. attach unmatched networks, which were present in new_networks else: # remove not updated networks from old and new networks lists, # also get list these networks not_updated_networks = \ self._get_network_matches(old_networks, new_networks) self.update_networks_matching_iface_port( old_networks + not_updated_networks, interfaces) # according to nova interface-detach command detached port # will be deleted for net in old_networks: checker = scheduler.TaskRunner(server.interface_detach, net.get('port')) checkers.append(checker) # attach section similar for both variants that # were mentioned above for net in new_networks: if net.get('port'): checker = scheduler.TaskRunner(server.interface_attach, net['port'], None, None) checkers.append(checker) elif net.get('network'): checker = scheduler.TaskRunner(server.interface_attach, None, net['network'], net.get('fixed_ip')) checkers.append(checker) # if new_networks is None, we should attach first free port, # according to similar behavior during instance creation if attach_first_free_port: checker = scheduler.TaskRunner(server.interface_attach, None, None, None) checkers.append(checker) # Optimization: make sure the first task is started before # check_update_complete. if checkers: checkers[0].start() return checkers
def handle_create(self): security_groups = self._get_security_groups() userdata = self.properties['UserData'] or '' flavor = self.properties['InstanceType'] availability_zone = self.properties['AvailabilityZone'] key_name = self.properties['KeyName'] if key_name: # confirm keypair exists nova_utils.get_keypair(self.nova(), key_name) image_name = self.properties['ImageId'] image_id = nova_utils.get_image_id(self.nova(), image_name) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) tags = {} if self.properties['Tags']: for tm in self.properties['Tags']: tags[tm['Key']] = tm['Value'] else: tags = None scheduler_hints = {} if self.properties['NovaSchedulerHints']: for tm in self.properties['NovaSchedulerHints']: scheduler_hints[tm['Key']] = tm['Value'] else: scheduler_hints = None nics = self._build_nics(self.properties['NetworkInterfaces'], security_groups=security_groups, subnet_id=self.properties['SubnetId']) server = None # TODO(sdake/shardy) ensure physical_resource_name() never returns a # string longer than 63 characters, as this is pretty inconvenient # behavior for autoscaling groups and nested stacks where instance # names can easily become quite long even with terse names. physical_resource_name_len = len(self.physical_resource_name()) if physical_resource_name_len > 63: raise exception.Error( _('Server %(server)s length %(length)d > 63' ' characters, please reduce the length of' ' stack or resource names') % dict(server=self.physical_resource_name(), length=physical_resource_name_len)) try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image_id, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=self.get_mime_string(userdata), meta=tags, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server, scheduler.TaskRunner(self._attach_volumes_task())
def validate(self): ''' Validate any of the provided params ''' super(Server, self).validate() # check validity of key key_name = self.properties.get(self.KEY_NAME) if key_name: nova_utils.get_keypair(self.nova(), key_name) # either volume_id or snapshot_id needs to be specified, but not both # for block device mapping. bdm = self.properties.get(self.BLOCK_DEVICE_MAPPING) or [] bootable_vol = False for mapping in bdm: device_name = mapping[self.BLOCK_DEVICE_MAPPING_DEVICE_NAME] if device_name == 'vda': bootable_vol = True volume_id = mapping.get(self.BLOCK_DEVICE_MAPPING_VOLUME_ID) snapshot_id = mapping.get(self.BLOCK_DEVICE_MAPPING_SNAPSHOT_ID) if volume_id and snapshot_id: raise exception.ResourcePropertyConflict( self.BLOCK_DEVICE_MAPPING_VOLUME_ID, self.BLOCK_DEVICE_MAPPING_SNAPSHOT_ID) if not volume_id and not snapshot_id: msg = _('Either volume_id or snapshot_id must be specified for' ' device mapping %s') % device_name raise exception.StackValidationFailed(message=msg) # make sure the image exists if specified. image = self.properties.get(self.IMAGE) if image: nova_utils.get_image_id(self.nova(), image) elif not image and not bootable_vol: msg = _('Neither image nor bootable volume is specified for' ' instance %s') % self.name raise exception.StackValidationFailed(message=msg) # network properties 'uuid' and 'network' shouldn't be used # both at once for all networks networks = self.properties.get(self.NETWORKS) or [] for network in networks: if network.get(self.NETWORK_UUID) and network.get(self.NETWORK_ID): msg = _('Properties "%(uuid)s" and "%(id)s" are both set ' 'to the network "%(network)s" for the server ' '"%(server)s". The "%(uuid)s" property is deprecated. ' 'Use only "%(id)s" property.' '') % dict(uuid=self.NETWORK_UUID, id=self.NETWORK_ID, network=network[self.NETWORK_ID], server=self.name) raise exception.StackValidationFailed(message=msg) elif network.get(self.NETWORK_UUID): logger.info(_('For the server "%(server)s" the "%(uuid)s" ' 'property is set to network "%(network)s". ' '"%(uuid)s" property is deprecated. Use ' '"%(id)s" property instead.' '') % dict(uuid=self.NETWORK_UUID, id=self.NETWORK_ID, network=network[self.NETWORK_ID], server=self.name)) # verify that the number of metadata entries is not greater # than the maximum number allowed in the provider's absolute # limits metadata = self.properties.get('metadata') if metadata is not None: limits = nova_utils.absolute_limits(self.nova()) if len(metadata) > limits['maxServerMeta']: msg = _('Instance metadata must not contain greater than %s ' 'entries. This is the maximum number allowed by your ' 'service provider') % limits['maxServerMeta'] raise exception.StackValidationFailed(message=msg)
def handle_create(self): security_groups = self.properties.get('security_groups', []) user_data_format = self.properties.get('user_data_format') if user_data_format == 'HEAT_CFNTOOLS': userdata = self.get_mime_string( self.properties.get('user_data', '')) else: userdata = self.properties.get('user_data', '') flavor = self.properties['flavor'] availability_zone = self.properties['availability_zone'] key_name = self.properties['key_name'] if key_name: # confirm keypair exists nova_utils.get_keypair(self.nova(), key_name) image = self.properties.get('image') if image: image = nova_utils.get_image_id(self.nova(), image) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) instance_meta = self.properties.get('metadata') scheduler_hints = self.properties.get('scheduler_hints') nics = self._build_nics(self.properties.get('networks')) block_device_mapping = self._build_block_device_mapping( self.properties.get('block_device_mapping')) reservation_id = self.properties.get('reservation_id') config_drive = self.properties.get('config_drive') disk_config = self.properties.get('diskConfig') # TODO(sdake/shardy) ensure physical_resource_name() never returns a # string longer than 63 characters, as this is pretty inconvenient # behavior for autoscaling groups and nested stacks where instance # names can easily become quite long even with terse names. physical_resource_name_len = len(self.physical_resource_name()) if physical_resource_name_len > 63: raise exception.Error( _('Server %(server)s length %(length)d > 63' ' characters, please reduce the length of' ' stack or resource names') % dict(server=self.physical_resource_name(), length=physical_resource_name_len)) server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=userdata, meta=instance_meta, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone, block_device_mapping=block_device_mapping, reservation_id=reservation_id, config_drive=config_drive, disk_config=disk_config) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server
def validate(self): ''' Validate any of the provided params ''' super(Server, self).validate() # either volume_id or snapshot_id needs to be specified, but not both # for block device mapping. bdm = self.properties.get(self.BLOCK_DEVICE_MAPPING) or [] bootable_vol = False for mapping in bdm: device_name = mapping[self.BLOCK_DEVICE_MAPPING_DEVICE_NAME] if device_name == 'vda': bootable_vol = True volume_id = mapping.get(self.BLOCK_DEVICE_MAPPING_VOLUME_ID) snapshot_id = mapping.get(self.BLOCK_DEVICE_MAPPING_SNAPSHOT_ID) if volume_id and snapshot_id: raise exception.ResourcePropertyConflict( self.BLOCK_DEVICE_MAPPING_VOLUME_ID, self.BLOCK_DEVICE_MAPPING_SNAPSHOT_ID) if not volume_id and not snapshot_id: msg = _('Either volume_id or snapshot_id must be specified for' ' device mapping %s') % device_name raise exception.StackValidationFailed(message=msg) # make sure the image exists if specified. image = self.properties.get(self.IMAGE) if image: nova_utils.get_image_id(self.nova(), image) elif not image and not bootable_vol: msg = _('Neither image nor bootable volume is specified for' ' instance %s') % self.name raise exception.StackValidationFailed(message=msg) # network properties 'uuid' and 'network' shouldn't be used # both at once for all networks networks = self.properties.get(self.NETWORKS) or [] for network in networks: if network.get(self.NETWORK_UUID) and network.get(self.NETWORK_ID): msg = _('Properties "%(uuid)s" and "%(id)s" are both set ' 'to the network "%(network)s" for the server ' '"%(server)s". The "%(uuid)s" property is deprecated. ' 'Use only "%(id)s" property.' '') % dict(uuid=self.NETWORK_UUID, id=self.NETWORK_ID, network=network[self.NETWORK_ID], server=self.name) raise exception.StackValidationFailed(message=msg) elif network.get(self.NETWORK_UUID): logger.info( _('For the server "%(server)s" the "%(uuid)s" ' 'property is set to network "%(network)s". ' '"%(uuid)s" property is deprecated. Use ' '"%(id)s" property instead.' '') % dict(uuid=self.NETWORK_UUID, id=self.NETWORK_ID, network=network[self.NETWORK_ID], server=self.name)) # retrieve provider's absolute limits if it will be needed metadata = self.properties.get(self.METADATA) personality = self._personality() if metadata is not None or personality is not None: limits = nova_utils.absolute_limits(self.nova()) # verify that the number of metadata entries is not greater # than the maximum number allowed in the provider's absolute # limits if metadata is not None: if len(metadata) > limits['maxServerMeta']: msg = _('Instance metadata must not contain greater than %s ' 'entries. This is the maximum number allowed by your ' 'service provider') % limits['maxServerMeta'] raise exception.StackValidationFailed(message=msg) # verify the number of personality files and the size of each # personality file against the provider's absolute limits if personality is not None: if len(personality) > limits['maxPersonality']: msg = _("The personality property may not contain " "greater than %s entries.") % limits['maxPersonality'] raise exception.StackValidationFailed(message=msg) for path, contents in personality.items(): if len(bytes(contents)) > limits['maxPersonalitySize']: msg = (_("The contents of personality file \"%(path)s\" " "is larger than the maximum allowed personality " "file size (%(max_size)s bytes).") % { 'path': path, 'max_size': limits['maxPersonalitySize'] }) raise exception.StackValidationFailed(message=msg)
def handle_create(self): security_groups = self.properties.get(self.SECURITY_GROUPS) user_data_format = self.properties.get(self.USER_DATA_FORMAT) ud_content = self.properties.get(self.USER_DATA) if self.user_data_software_config() or self.user_data_raw(): if uuidutils.is_uuid_like(ud_content): # attempt to load the userdata from software config try: ud_content = sc.SoftwareConfig.get_software_config( self.heat(), ud_content) except exception.SoftwareConfigMissing: # no config was found, so do not modify the user_data pass if self.user_data_software_config(): self._create_transport_credentials() if self.properties[self.ADMIN_USER]: instance_user = self.properties[self.ADMIN_USER] elif cfg.CONF.instance_user: instance_user = cfg.CONF.instance_user else: instance_user = None userdata = nova_utils.build_userdata(self, ud_content, instance_user=instance_user, user_data_format=user_data_format) flavor = self.properties[self.FLAVOR] availability_zone = self.properties[self.AVAILABILITY_ZONE] image = self.properties.get(self.IMAGE) if image: image = nova_utils.get_image_id(self.nova(), image) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) instance_meta = self.properties.get(self.METADATA) if instance_meta is not None: instance_meta = nova_utils.meta_serialize(instance_meta) scheduler_hints = self.properties.get(self.SCHEDULER_HINTS) nics = self._build_nics(self.properties.get(self.NETWORKS)) block_device_mapping = self._build_block_device_mapping( self.properties.get(self.BLOCK_DEVICE_MAPPING)) reservation_id = self.properties.get(self.RESERVATION_ID) config_drive = self.properties.get(self.CONFIG_DRIVE) disk_config = self.properties.get(self.DISK_CONFIG) admin_pass = self.properties.get(self.ADMIN_PASS) or None server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image, flavor=flavor_id, key_name=self._key_name(), security_groups=security_groups, userdata=userdata, meta=instance_meta, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone, block_device_mapping=block_device_mapping, reservation_id=reservation_id, config_drive=config_drive, disk_config=disk_config, files=self._personality(), admin_pass=admin_pass) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server
def handle_create(self): security_groups = self.properties.get(self.SECURITY_GROUPS) user_data_format = self.properties.get(self.USER_DATA_FORMAT) ud_content = self.properties.get(self.USER_DATA) if self.user_data_software_config() or self.user_data_raw(): if uuidutils.is_uuid_like(ud_content): # attempt to load the userdata from software config try: ud_content = sc.SoftwareConfig.get_software_config( self.heat(), ud_content) except exception.SoftwareConfigMissing: # no config was found, so do not modify the user_data pass if self.user_data_software_config(): self._create_transport_credentials() if self.properties[self.ADMIN_USER]: instance_user = self.properties[self.ADMIN_USER] elif cfg.CONF.instance_user: instance_user = cfg.CONF.instance_user else: instance_user = None userdata = nova_utils.build_userdata( self, ud_content, instance_user=instance_user, user_data_format=user_data_format) flavor = self.properties[self.FLAVOR] availability_zone = self.properties[self.AVAILABILITY_ZONE] image = self.properties.get(self.IMAGE) if image: image = nova_utils.get_image_id(self.nova(), image) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) instance_meta = self.properties.get(self.METADATA) if instance_meta is not None: instance_meta = nova_utils.meta_serialize(instance_meta) scheduler_hints = self.properties.get(self.SCHEDULER_HINTS) nics = self._build_nics(self.properties.get(self.NETWORKS)) block_device_mapping = self._build_block_device_mapping( self.properties.get(self.BLOCK_DEVICE_MAPPING)) reservation_id = self.properties.get(self.RESERVATION_ID) disk_config = self.properties.get(self.DISK_CONFIG) admin_pass = self.properties.get(self.ADMIN_PASS) or None personality_files = self.properties.get(self.PERSONALITY) key_name = self.properties.get(self.KEY_NAME) server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=userdata, meta=instance_meta, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone, block_device_mapping=block_device_mapping, reservation_id=reservation_id, config_drive=self._config_drive(), disk_config=disk_config, files=personality_files, admin_pass=admin_pass) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server
def handle_create(self): security_groups = self.properties.get('security_groups', []) userdata = self.properties.get('user_data', '') flavor = self.properties['flavor'] availability_zone = self.properties['availability_zone'] key_name = self.properties['key_name'] if key_name: # confirm keypair exists nova_utils.get_keypair(self.nova(), key_name) image = self.properties.get('image') if image: image = nova_utils.get_image_id(self.nova(), image) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) instance_meta = self.properties.get('metadata') scheduler_hints = self.properties.get('scheduler_hints') nics = self._build_nics(self.properties.get('networks')) block_device_mapping = self._build_block_device_mapping( self.properties.get('block_device_mapping')) reservation_id = self.properties.get('reservation_id') config_drive = self.properties.get('config_drive') disk_config = self.properties.get('diskConfig') # TODO(sdake/shardy) ensure physical_resource_name() never returns a # string longer than 63 characters, as this is pretty inconvenient # behavior for autoscaling groups and nested stacks where instance # names can easily become quite long even with terse names. physical_resource_name_len = len(self.physical_resource_name()) if physical_resource_name_len > 63: raise exception.Error(_('Server %(server)s length %(length)d > 63' ' characters, please reduce the length of' ' stack or resource names') % dict(server=self.physical_resource_name(), length=physical_resource_name_len)) server = None try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=self.get_mime_string(userdata), meta=instance_meta, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone, block_device_mapping=block_device_mapping, reservation_id=reservation_id, config_drive=config_drive, disk_config=disk_config) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server
def handle_create(self): security_groups = self._get_security_groups() userdata = self.properties['UserData'] or '' flavor = self.properties['InstanceType'] availability_zone = self.properties['AvailabilityZone'] key_name = self.properties['KeyName'] if key_name: # confirm keypair exists nova_utils.get_keypair(self.nova(), key_name) image_name = self.properties['ImageId'] image_id = nova_utils.get_image_id(self.nova(), image_name) flavor_id = nova_utils.get_flavor_id(self.nova(), flavor) tags = {} if self.properties['Tags']: for tm in self.properties['Tags']: tags[tm['Key']] = tm['Value'] else: tags = None scheduler_hints = {} if self.properties['NovaSchedulerHints']: for tm in self.properties['NovaSchedulerHints']: scheduler_hints[tm['Key']] = tm['Value'] else: scheduler_hints = None nics = self._build_nics(self.properties['NetworkInterfaces'], security_groups=security_groups, subnet_id=self.properties['SubnetId']) server = None # TODO(sdake/shardy) ensure physical_resource_name() never returns a # string longer than 63 characters, as this is pretty inconvenient # behavior for autoscaling groups and nested stacks where instance # names can easily become quite long even with terse names. physical_resource_name_len = len(self.physical_resource_name()) if physical_resource_name_len > 63: raise exception.Error(_('Server %(server)s length %(length)d > 63' ' characters, please reduce the length of' ' stack or resource names') % dict(server=self.physical_resource_name(), length=physical_resource_name_len)) try: server = self.nova().servers.create( name=self.physical_resource_name(), image=image_id, flavor=flavor_id, key_name=key_name, security_groups=security_groups, userdata=self.get_mime_string(userdata), meta=tags, scheduler_hints=scheduler_hints, nics=nics, availability_zone=availability_zone) finally: # Avoid a race condition where the thread could be cancelled # before the ID is stored if server is not None: self.resource_id_set(server.id) return server, scheduler.TaskRunner(self._attach_volumes_task())
def validate(self): ''' Validate any of the provided params ''' super(Server, self).validate() # check validity of key key_name = self.properties.get(self.KEY_NAME) if key_name: nova_utils.get_keypair(self.nova(), key_name) # either volume_id or snapshot_id needs to be specified, but not both # for block device mapping. bdm = self.properties.get(self.BLOCK_DEVICE_MAPPING) or [] bootable_vol = False for mapping in bdm: device_name = mapping[self.BLOCK_DEVICE_MAPPING_DEVICE_NAME] if device_name == 'vda': bootable_vol = True volume_id = mapping.get(self.BLOCK_DEVICE_MAPPING_VOLUME_ID) snapshot_id = mapping.get(self.BLOCK_DEVICE_MAPPING_SNAPSHOT_ID) if volume_id and snapshot_id: raise exception.ResourcePropertyConflict( self.BLOCK_DEVICE_MAPPING_VOLUME_ID, self.BLOCK_DEVICE_MAPPING_SNAPSHOT_ID) if not volume_id and not snapshot_id: msg = _('Either volume_id or snapshot_id must be specified for' ' device mapping %s') % device_name raise exception.StackValidationFailed(message=msg) # make sure the image exists if specified. image = self.properties.get(self.IMAGE) if image: nova_utils.get_image_id(self.nova(), image) elif not image and not bootable_vol: msg = _('Neither image nor bootable volume is specified for' ' instance %s') % self.name raise exception.StackValidationFailed(message=msg) # network properties 'uuid' and 'network' shouldn't be used # both at once for all networks networks = self.properties.get(self.NETWORKS) or [] for network in networks: if network.get(self.NETWORK_UUID) and network.get(self.NETWORK_ID): msg = _('Properties "%(uuid)s" and "%(id)s" are both set ' 'to the network "%(network)s" for the server ' '"%(server)s". The "%(uuid)s" property is deprecated. ' 'Use only "%(id)s" property.' '') % dict(uuid=self.NETWORK_UUID, id=self.NETWORK_ID, network=network[self.NETWORK_ID], server=self.name) raise exception.StackValidationFailed(message=msg) elif network.get(self.NETWORK_UUID): logger.info( _('For the server "%(server)s" the "%(uuid)s" ' 'property is set to network "%(network)s". ' '"%(uuid)s" property is deprecated. Use ' '"%(id)s" property instead.' '') % dict(uuid=self.NETWORK_UUID, id=self.NETWORK_ID, network=network[self.NETWORK_ID], server=self.name)) # verify that the number of metadata entries is not greater # than the maximum number allowed in the provider's absolute # limits metadata = self.properties.get('metadata') if metadata is not None: limits = nova_utils.absolute_limits(self.nova()) if len(metadata) > limits['maxServerMeta']: msg = _('Instance metadata must not contain greater than %s ' 'entries. This is the maximum number allowed by your ' 'service provider') % limits['maxServerMeta'] raise exception.StackValidationFailed(message=msg)