class PolicyAddAction(workflows.Action): id= forms.CharField(widget=forms.HiddenInput(), required=False) cloudids = forms.ChoiceField( label=_("Cloud Name"), required=True, widget=fields.SelectWidget( data_attrs=('platform','allowed'), transform=lambda x: ("%s" % (x.name))) ) providers = forms.ChoiceField(label=_("Provider"), required=False, help_text=_("Choose Your Provider" "."), widget=fields.SelectWidget(data_attrs=('provider',), transform=lambda x: ("%s" % (x.provider)))) regions = forms.ChoiceField(label=_("Region"), required=False, help_text=_("Choose Your Region" "."), widget=fields.SelectWidget(data_attrs=('provider','name','allowed',), transform=lambda x: ("%s(%s)" % ((x.name).title(),(x.provider).title())))) allowed = forms.MultipleChoiceField(label=_("Allowed Actions"), required=False, initial=["default"], widget=forms.CheckboxSelectMultiple(), help_text=_("Allowed Action for the Role.")) def populate_cloudids_choices(self, request, context): try: cloudid = [] cloudlist = tenantclouds.objects(tenantid=self.request.user.tenantid.id) roles = roledetail.objects(id = context['id']).first() for cloud in cloudlist: if roles.policy: for a in roles.policy: if cloud.name == a.cloudid.name: if a.cloudid.platform != "Cnext": cloud.__dict__['allowed'] = a.allowed else: pass cloudid.append((cloud.id,cloud)) else: cloudid.append((cloud.id,cloud)) else: cloudid.append((cloud.id,cloud)) cloudid = set(cloudid) cloudid = list(cloudid) cloudid.insert(0, ("", _("Select Cloud"))) except Exception,e: messages.error(request,_(e.message)) LOG.error(e.message) cloudid = [] return cloudid
class CreateCloudAction(workflows.Action): cloudtype = forms.ChoiceField(label=_("Platform"), required=True, widget=fields.SelectWidget( data_attrs=( 'name', 'type', ), transform=lambda x: ("%s " % (x.name)))) cloudlist = forms.ChoiceField(label=_("Cloud Type"), required=True, widget=fields.SelectWidget( data_attrs=( 'name', 'type', ), transform=lambda x: ("%s " % (x.type)))) cloudname = forms.CharField(label=_("Cloud Name"), max_length=80) cloud_id = forms.CharField(required=False, widget=forms.HiddenInput()) publickey = forms.CharField(label=_("Public Key"), max_length=None) secretkey = forms.RegexField( label=_("Secret Key"), widget=forms.PasswordInput(render_value=False), regex=validators.password_validator(), error_messages={'invalid': validators.password_validator_msg()}) endpoint = forms.CharField(max_length=80, label=_("Endpoint(IP with HTTP)")) class Meta: name = _("ADD Cloud") def __init__(self, *args, **kwargs): super(CreateCloudAction, self).__init__(*args, **kwargs) try: region_list = get_regions_wo_connection() cloud_id = args[-1]["cloud_id"] cloud_obj = clouds.objects(id=cloud_id).first() self.fields['publickey'].label = _(cloud_obj.credential_fields[0]) self.fields["secretkey"].label = _(cloud_obj.credential_fields[1]) if cloud_obj.name == "Amazon": self.fields["endpoint"] = forms.ChoiceField( label=_("Default Region"), choices=region_list, help_text=_("Select default region")) self.fields["endpoint"].label = _( cloud_obj.credential_fields[2]) else: self.fields["endpoint"].label = _( cloud_obj.credential_fields[2]) except Exception, e: messages.error(self.request, _(e.message)) LOG.error(e.message)
class AccessEditAction(workflows.Action): roleid = forms.ChoiceField( label=_("Role Name"), required=True, widget=fields.SelectWidget(data_attrs=('access',), transform=lambda x: ("%s" % (x.name))) ) access = forms.MultipleChoiceField(label=_("Access"), required=False, initial=["default"], widget=forms.CheckboxSelectMultiple(), help_text=_("Create Access for the Role.")) def populate_roleid_choices(self, request, context): try: role = [] roles = roledetail.objects(id = context['roleid']).first() role.append((roles.id,roles)) role.insert(0, ("", _("Select Role"))) except Exception, e: messages.error(request,_(e.message)) LOG.error(e.message) role =[] return role
class SetAccessControlsAction(workflows.Action): keypair = forms.DynamicChoiceField( label=_("Keypair"), required=False, help_text=_("Which keypair to use for " "authentication."), widget=fields.SelectWidget(data_attrs=('provider', 'region', 'instanceId'), transform=lambda x: ("%s (%s)(%s)" % (x.name, x.provider, x.region))), add_item_link=KEYPAIR_IMPORT_URL) admin_pass = forms.RegexField( label=_("Admin Password"), required=False, widget=forms.PasswordInput(render_value=False), regex=validators.password_validator(), error_messages={'invalid': validators.password_validator_msg()}) confirm_admin_pass = forms.CharField( label=_("Confirm Admin Password"), required=False, widget=forms.PasswordInput(render_value=False)) groups = forms.MultipleChoiceField(label=_("Security Groups"), required=False, initial=["default"], widget=forms.CheckboxSelectMultiple(), help_text=_("Launch instance in these " "security groups.")) class Meta: name = _("Access & Security") help_text = _("Control access to your instance via keypairs, " "security groups, and other mechanisms.") def populate_keypair_choices(self, request, context): try: keypairs = capi.keypairs(request) keypair_list = [(kp.id, kp) for kp in keypairs] except Exception: keypair_list = [] exceptions.handle(request, _('Unable to retrieve keypairs.')) if keypair_list: keypair_list.insert(0, ("", _("Select a keypair"))) else: keypair_list = (("", _("No keypairs available.")), ) return keypair_list def populate_groups_choices(self, request, context): try: groups = capi.securitygroups(request) if groups: security_group_list = [(sg.id, sg.name) for sg in groups] else: security_group_list = [] except Exception: exceptions.handle(request, _('Unable to retrieve list of security groups')) security_group_list = [] return security_group_list
class RebuildInstanceForm(forms.SelfHandlingForm): instance_id = forms.CharField(widget=forms.HiddenInput()) image = forms.ChoiceField(label=_("Select Image"), widget=fields.SelectWidget( attrs={'class': 'image-selector'}, data_attrs=('size', 'display-name'), transform=_image_choice_title)) password = forms.RegexField( label=_("Rebuild Password"), required=False, widget=forms.PasswordInput(render_value=False), regex=validators.password_validator(), error_messages={'invalid': validators.password_validator_msg()}) confirm_password = forms.CharField( label=_("Confirm Rebuild Password"), required=False, widget=forms.PasswordInput(render_value=False)) def __init__(self, request, *args, **kwargs): super(RebuildInstanceForm, self).__init__(request, *args, **kwargs) instance_id = kwargs.get('initial', {}).get('instance_id') self.fields['instance_id'].initial = instance_id images = utils.get_available_images(request, request.user.tenant_id) choices = [(image.id, image.name) for image in images] if choices: choices.insert(0, ("", _("Select Image"))) else: choices.insert(0, ("", _("No images available."))) self.fields['image'].choices = choices def clean(self): cleaned_data = super(RebuildInstanceForm, self).clean() if 'password' in cleaned_data: passwd = cleaned_data.get('password') confirm = cleaned_data.get('confirm_password') if passwd is not None and confirm is not None: if passwd != confirm: raise forms.ValidationError(_("Passwords do not match.")) return cleaned_data # We have to protect the entire "data" dict because it contains the # password and confirm_password strings. @sensitive_variables('data', 'password') def handle(self, request, data): instance = data.get('instance_id') image = data.get('image') password = data.get('password') or None try: api.nova.server_rebuild(request, instance, image, password) messages.success(request, _('Rebuilding instance %s.') % instance) except Exception: redirect = reverse('horizon:project:instances:index') exceptions.handle(request, _("Unable to rebuild instance."), redirect=redirect) return True
def __init__(self, *args, **kwargs): instance_choice = kwargs["initial"]["instance_choices"] super(AssociateAddress, self).__init__(*args, **kwargs) self.fields['instance_id'] = forms.ChoiceField( label=_("Instance"), widget=fields.SelectWidget(data_attrs=(), transform=lambda x: ("%s (%s) (%s)" % (x.id, x.state, x.tags['Name']))), choices=instance_choice)
class CnextTabAction(workflows.Action): cloudid = forms.ChoiceField( label=_("Cloud Name"), required=False, widget=fields.SelectWidget( data_attrs=('platform',), transform=lambda x: ("%s" % (x.name))) ) provider = forms.ChoiceField(label=_("Provider"), required=False, help_text=_("Choose Your Provider" "."), widget=fields.SelectWidget(data_attrs=('provider',), transform=lambda x: ("%s" % (x.provider)))) region = forms.ChoiceField(label=_("Region"), required=False, help_text=_("Choose Your Region" "."), widget=fields.SelectWidget(data_attrs=('provider','name',), transform=lambda x: ("%s(%s)" % ((x.name).title(),(x.provider).title())))) allowed = forms.MultipleChoiceField(label=_("Allowed Actions"), required=False, initial=["default"], widget=forms.CheckboxSelectMultiple(), help_text=_("Allowed Action for the Role.")) def populate_cloudid_choices(self, request, context): try: cloudid = [] cloudlist = tenantclouds.objects(tenantid=self.request.user.tenantid.id) cloudid = [(cloud.id,cloud) for cloud in cloudlist] cloudid.insert(0, ("", _("Select Cloud"))) except Exception, e: messages.error(request,_(e.message)) LOG.error(e.message) cloudid = [] return cloudid
class CreateKeypair(forms.SelfHandlingForm): name = forms.CharField(max_length="20", label=_("Keypair Name"), validators=[validators.validate_slug], error_messages={ 'invalid': _('Keypair names may ' 'only contain letters, numbers, underscores ' 'and hyphens.') }) key_provider_list = forms.ChoiceField( label=_("Providers List"), required=True, ) key_region_list = forms.ChoiceField( label=_("Regions List"), required=True, widget=fields.SelectWidget(data_attrs=( 'provider', 'region', ), transform=lambda x: ("%s " % (x.name)))) def handle(self, request, data): return True # We just redirect to the download view. def __init__(self, request, *args, **kwargs): forms.SelfHandlingForm.__init__(self, request, *args, **kwargs) provider_list = api.providers(self.request) region_list = api.region(self.request) p = [("", _("Select Provider"))] for provider in provider_list: if provider.provider in provider_keypairs_choices: p.append((provider.provider.lower(), provider.provider)) t = tuple(p) tuple_providers = t self.fields['key_provider_list'].choices = tuple_providers r = [("", _("Select Region"))] for region in region_list: if region.name in region_keypairs_choices: r.append((region.name, Regionlist(region.provider, region.name))) r = tuple(r) tuple_regions = r self.fields['key_region_list'].choices = tuple_regions
class AssociateAddress(forms.SelfHandlingForm): instance_choice = [] def __init__(self, *args, **kwargs): instance_choice = kwargs["initial"]["instance_choices"] super(AssociateAddress, self).__init__(*args, **kwargs) self.fields['instance_id'] = forms.ChoiceField( label=_("Instance"), widget=fields.SelectWidget(data_attrs=(), transform=lambda x: ("%s (%s) (%s)" % (x.id, x.state, x.tags['Name']))), choices=instance_choice) id = forms.CharField(label=_("id"), widget=forms.HiddenInput(), required=False) instance_id = forms.ChoiceField(label=_("Instance"), widget=fields.SelectWidget( data_attrs=(), transform=lambda x: ("%s (%s)" % (x.id, x.state))), help_text=_("Search Instance" "ID"), choices=instance_choice) def handle(self, request, data): try: associate = ElasticIPs(request).associate_addr( data['id'], data['instance_id']) if associate == True: messages.success(request, _('Successfully Associated: %s') % data['id']) else: messages.error( request, _('Unable to associate address: %s') % data['id']) return True except Exception, e: redirect = reverse("horizon:amazon:elastic_ip:index") messages.error(request, _(e.message)) LOG.error(e.message) exceptions.handle_redirect(request, redirect)
class CreateGroup(forms.SelfHandlingForm): name = forms.CharField(label=_("Name"), error_messages={ 'required': _('This field is required.'), 'invalid': _("The string may only contain" " ASCII characters and numbers.")}, validators=[validators.validate_slug]) description = forms.CharField(label=_("Description")) key_provider_list = forms.ChoiceField( label=_("Providers List"), required=True, ) key_region_list = forms.ChoiceField( label=_("Regions List"), required=True, widget=fields.SelectWidget(data_attrs=('provider','region',),transform=lambda x: ("%s " % (x.name))) ) def handle(self, request, data): try: sg = api.create_securitygroups(request, data['name'], data['description'], data['key_provider_list'], data['key_region_list']) if sg == True: messages.success(request, _('Successfully created security group: %s') % data['name']) return sg except Exception,e: print e redirect = reverse("horizon:cnext:securitygroups:index") exceptions.handle(request, _('Unable to create security group.'), redirect=redirect)
class SetInstanceDetailsAction(workflows.Action): availability_zone = forms.ChoiceField(label=_("Availability Zone"), required=False) name = forms.CharField(max_length=80, label=_("Instance Name")) flavor = forms.ChoiceField(label=_("Flavor"), help_text=_("Size of image to launch.")) count = forms.IntegerField(label=_("Instance Count"), min_value=1, initial=1, help_text=_("Number of instances to launch.")) source_type = forms.ChoiceField(label=_("Instance Boot Source"), required=True, help_text=_("Choose Your Boot Source " "Type.")) instance_snapshot_id = forms.ChoiceField(label=_("Instance Snapshot"), required=False) volume_id = forms.ChoiceField(label=_("Volume"), required=False) volume_snapshot_id = forms.ChoiceField(label=_("Volume Snapshot"), required=False) image_id = forms.ChoiceField( label=_("Image Name"), required=False, widget=fields.SelectWidget( data_attrs=('volume_size',), transform=lambda x: ("%s (%s)" % (x.name, filesizeformat(x.bytes))))) volume_size = forms.CharField(label=_("Device size (GB)"), required=False, help_text=_("Volume size in gigabytes " "(integer value).")) device_name = forms.CharField(label=_("Device Name"), required=False, initial="vda", help_text=_("Volume mount point (e.g. 'vda' " "mounts at '/dev/vda').")) delete_on_terminate = forms.BooleanField(label=_("Delete on Terminate"), initial=False, required=False, help_text=_("Delete volume on " "instance terminate")) class Meta: name = _("Details") help_text_template = ("project/instances/" "_launch_details_help.html") def __init__(self, request, context, *args, **kwargs): self._init_images_cache() super(SetInstanceDetailsAction, self).__init__( request, context, *args, **kwargs) source_type_choices = [ ('', _("--- Select source ---")), ("image_id", _("Boot from image.")), ("instance_snapshot_id", _("Boot from snapshot.")), ("volume_id", _("Boot from volume.")), ] try: if api.nova.extension_supported("BlockDeviceMappingV2Boot", request): source_type_choices.append(("volume_image_id", _("Boot from image (creates a new volume)."))) except Exception: exceptions.handle(request, _('Unable to retrieve extensions ' 'information.')) source_type_choices.append(("volume_snapshot_id", _("Boot from volume snapshot (creates a new volume)."))) self.fields['source_type'].choices = source_type_choices def clean(self): cleaned_data = super(SetInstanceDetailsAction, self).clean() count = cleaned_data.get('count', 1) # Prevent launching more instances than the quota allows usages = quotas.tenant_quota_usages(self.request) available_count = usages['instances']['available'] if available_count < count: error_message = ungettext_lazy('The requested instance ' 'cannot be launched as you only ' 'have %(avail)i of your quota ' 'available. ', 'The requested %(req)i instances ' 'cannot be launched as you only ' 'have %(avail)i of your quota ' 'available.', count) params = {'req': count, 'avail': available_count} raise forms.ValidationError(error_message % params) # Validate our instance source. source_type = self.data.get('source_type', None) if source_type == 'image_id': if not cleaned_data.get('image_id'): msg = _("You must select an image.") self._errors['image_id'] = self.error_class([msg]) elif source_type == 'instance_snapshot_id': if not cleaned_data['instance_snapshot_id']: msg = _("You must select a snapshot.") self._errors['instance_snapshot_id'] = self.error_class([msg]) elif source_type == 'volume_id': if not cleaned_data.get('volume_id'): msg = _("You must select a volume.") self._errors['volume_id'] = self.error_class([msg]) # Prevent launching multiple instances with the same volume. # TODO(gabriel): is it safe to launch multiple instances with # a snapshot since it should be cloned to new volumes? if count > 1: msg = _('Launching multiple instances is only supported for ' 'images and instance snapshots.') raise forms.ValidationError(msg) elif source_type == 'volume_image_id': if not cleaned_data['image_id']: msg = _("You must select an image.") self._errors['image_id'] = self.error_class([msg]) if not self.data.get('volume_size', None): msg = _("You must set volume size") self._errors['volume_size'] = self.error_class([msg]) if not cleaned_data.get('device_name'): msg = _("You must set device name") self._errors['device_name'] = self.error_class([msg]) elif source_type == 'volume_snapshot_id': if not cleaned_data.get('volume_snapshot_id'): msg = _("You must select a snapshot.") self._errors['volume_snapshot_id'] = self.error_class([msg]) if not cleaned_data.get('device_name'): msg = _("You must set device name") self._errors['device_name'] = self.error_class([msg]) return cleaned_data def populate_flavor_choices(self, request, context): """By default, returns the available flavors, sorted by RAM usage (ascending). Override these behaviours with a CREATE_INSTANCE_FLAVOR_SORT dict in local_settings.py. """ try: flavors = api.nova.flavor_list(request) flavor_sort = getattr(settings, 'CREATE_INSTANCE_FLAVOR_SORT', {}) rev = flavor_sort.get('reverse', False) key = flavor_sort.get('key', lambda flavor: flavor.ram) flavor_list = [(flavor.id, "%s" % flavor.name) for flavor in sorted(flavors, key=key, reverse=rev)] except Exception: flavor_list = [] exceptions.handle(request, _('Unable to retrieve instance flavors.')) return flavor_list def populate_availability_zone_choices(self, request, context): try: zones = api.nova.availability_zone_list(request) except Exception: zones = [] exceptions.handle(request, _('Unable to retrieve availability zones.')) zone_list = [(zone.zoneName, zone.zoneName) for zone in zones if zone.zoneState['available']] zone_list.sort() if not zone_list: zone_list.insert(0, ("", _("No availability zones found."))) elif len(zone_list) > 1: zone_list.insert(0, ("", _("Any Availability Zone"))) return zone_list def get_help_text(self): extra = {} try: extra['usages'] = api.nova.tenant_absolute_limits(self.request) extra['usages_json'] = json.dumps(extra['usages']) flavors = json.dumps([f._info for f in api.nova.flavor_list(self.request)]) extra['flavors'] = flavors images = utils.get_available_images(self.request, self.initial['project_id'], self._images_cache) if images is not None: attrs = [{'id': i.id, 'min_disk': getattr(i, 'min_disk', 0), 'min_ram': getattr(i, 'min_ram', 0)} for i in images] extra['images'] = json.dumps(attrs) except Exception: exceptions.handle(self.request, _("Unable to retrieve quota information.")) return super(SetInstanceDetailsAction, self).get_help_text(extra) def _init_images_cache(self): if not hasattr(self, '_images_cache'): self._images_cache = {} def _get_volume_display_name(self, volume): if hasattr(volume, "volume_id"): vol_type = "snap" visible_label = _("Snapshot") else: vol_type = "vol" visible_label = _("Volume") return (("%s:%s" % (volume.id, vol_type)), (_("%(name)s - %(size)s GB (%(label)s)") % {'name': volume.display_name or volume.id, 'size': volume.size, 'label': visible_label})) def populate_image_id_choices(self, request, context): choices = [] images = utils.get_available_images(request, context.get('project_id'), self._images_cache) for image in images: image.bytes = image.size image.volume_size = functions.bytes_to_gigabytes(image.bytes) choices.append((image.id, image)) if choices: choices.insert(0, ("", _("Select Image"))) else: choices.insert(0, ("", _("No images available"))) return choices def populate_instance_snapshot_id_choices(self, request, context): images = utils.get_available_images(request, context.get('project_id'), self._images_cache) choices = [(image.id, image.name) for image in images if image.properties.get("image_type", '') == "snapshot"] if choices: choices.insert(0, ("", _("Select Instance Snapshot"))) else: choices.insert(0, ("", _("No snapshots available."))) return choices def populate_volume_id_choices(self, request, context): try: volumes = [self._get_volume_display_name(v) for v in cinder.volume_list(self.request) if v.status == api.cinder.VOLUME_STATE_AVAILABLE] except Exception: volumes = [] exceptions.handle(self.request, _('Unable to retrieve list of volumes.')) if volumes: volumes.insert(0, ("", _("Select Volume"))) else: volumes.insert(0, ("", _("No volumes available."))) return volumes def populate_volume_snapshot_id_choices(self, request, context): try: snapshots = cinder.volume_snapshot_list(self.request) snapshots = [self._get_volume_display_name(s) for s in snapshots if s.status == api.cinder.VOLUME_STATE_AVAILABLE] except Exception: snapshots = [] exceptions.handle(self.request, _('Unable to retrieve list of volume ' 'snapshots.')) if snapshots: snapshots.insert(0, ("", _("Select Volume Snapshot"))) else: snapshots.insert(0, ("", _("No volume snapshots available."))) return snapshots
class CreateForm(forms.SelfHandlingForm): name = forms.CharField(max_length="255", label=_("Volume Name")) description = forms.CharField(widget=forms.Textarea, label=_("Description"), required=False) type = forms.ChoiceField(label=_("Type"), required=False) size = forms.IntegerField(min_value=1, label=_("Size (GB)")) volume_source_type = forms.ChoiceField(label=_("Volume Source"), required=False, widget=forms.Select(attrs={ 'class': 'switchable', 'data-slug': 'source'})) snapshot_source = forms.ChoiceField( label=_("Use snapshot as a source"), widget=fields.SelectWidget( attrs={'class': 'snapshot-selector'}, data_attrs=('size', 'display_name'), transform=lambda x: "%s (%sGB)" % (x.display_name, x.size)), required=False) image_source = forms.ChoiceField( label=_("Use image as a source"), widget=fields.SelectWidget( attrs={'class': 'image-selector'}, data_attrs=('size', 'name', 'min_disk'), transform=lambda x: "%s (%s)" % (x.name, filesizeformat(x.bytes))), required=False) volume_source = forms.ChoiceField( label=_("Use a volume as source"), widget=fields.SelectWidget( attrs={'class': 'image-selector'}, data_attrs=('size', 'display_name'), transform=lambda x: "%s (%s)" % (x.display_name, filesizeformat(x.size * 1024 * 1024 * 1024))), required=False) availability_zone = forms.ChoiceField( label=_("Availability Zone"), required=False, widget=forms.Select( attrs={'class': 'switched', 'data-switch-on': 'source', 'data-source-no_source_type': _('Availability Zone'), 'data-source-image_source': _('Availability Zone')})) def __init__(self, request, *args, **kwargs): super(CreateForm, self).__init__(request, *args, **kwargs) volume_types = cinder.volume_type_list(request) self.fields['type'].choices = [("", "")] + \ [(type.name, type.name) for type in volume_types] if "snapshot_id" in request.GET: try: snapshot = self.get_snapshot(request, request.GET["snapshot_id"]) self.fields['name'].initial = snapshot.display_name self.fields['size'].initial = snapshot.size self.fields['snapshot_source'].choices = ((snapshot.id, snapshot),) try: # Set the volume type from the original volume orig_volume = cinder.volume_get(request, snapshot.volume_id) self.fields['type'].initial = orig_volume.volume_type except Exception: pass self.fields['size'].help_text = _('Volume size must be equal ' 'to or greater than the snapshot size (%sGB)') \ % snapshot.size del self.fields['image_source'] del self.fields['volume_source_type'] del self.fields['availability_zone'] except Exception: exceptions.handle(request, _('Unable to load the specified snapshot.')) elif 'image_id' in request.GET: self.fields['availability_zone'].choices = \ self.availability_zones(request) try: image = self.get_image(request, request.GET["image_id"]) image.bytes = image.size self.fields['name'].initial = image.name min_vol_size = functions.bytes_to_gigabytes( image.size) size_help_text = _('Volume size must be equal to or greater ' 'than the image size (%s)') \ % filesizeformat(image.size) min_disk_size = getattr(image, 'min_disk', 0) if (min_disk_size > min_vol_size): min_vol_size = min_disk_size size_help_text = _('Volume size must be equal to or ' 'greater than the image minimum ' 'disk size (%sGB)') \ % min_disk_size self.fields['size'].initial = min_vol_size self.fields['size'].help_text = size_help_text self.fields['image_source'].choices = ((image.id, image),) del self.fields['snapshot_source'] del self.fields['volume_source_type'] except Exception: msg = _('Unable to load the specified image. %s') exceptions.handle(request, msg % request.GET['image_id']) elif 'volume_id' in request.GET: self.fields['availability_zone'].choices = \ self.availability_zones(request) volume = None try: volume = self.get_volume(request, request.GET["volume_id"]) except Exception: msg = _('Unable to load the specified volume. %s') exceptions.handle(request, msg % request.GET['volume_id']) if volume is not None: self.fields['name'].initial = volume.display_name self.fields['description'].initial = volume.display_description min_vol_size = volume.size size_help_text = _('Volume size must be equal to or greater ' 'than the origin volume size (%s)') \ % filesizeformat(volume.size) self.fields['size'].initial = min_vol_size self.fields['size'].help_text = size_help_text self.fields['volume_source'].choices = ((volume.id, volume),) self.fields['type'].initial = volume.type del self.fields['snapshot_source'] del self.fields['image_source'] del self.fields['volume_source_type'] else: source_type_choices = [] self.fields['availability_zone'].choices = \ self.availability_zones(request) try: snapshot_list = cinder.volume_snapshot_list(request) snapshots = [s for s in snapshot_list if s.status == 'available'] if snapshots: source_type_choices.append(("snapshot_source", _("Snapshot"))) choices = [('', _("Choose a snapshot"))] + \ [(s.id, s) for s in snapshots] self.fields['snapshot_source'].choices = choices else: del self.fields['snapshot_source'] except Exception: exceptions.handle(request, _("Unable to retrieve " "volume snapshots.")) images = utils.get_available_images(request, request.user.tenant_id) if images: source_type_choices.append(("image_source", _("Image"))) choices = [('', _("Choose an image"))] for image in images: image.bytes = image.size image.size = functions.bytes_to_gigabytes(image.bytes) choices.append((image.id, image)) self.fields['image_source'].choices = choices else: del self.fields['image_source'] volumes = self.get_volumes(request) if volumes: source_type_choices.append(("volume_source", _("Volume"))) choices = [('', _("Choose a volume"))] for volume in volumes: choices.append((volume.id, volume)) self.fields['volume_source'].choices = choices else: del self.fields['volume_source'] if source_type_choices: choices = ([('no_source_type', _("No source, empty volume"))] + source_type_choices) self.fields['volume_source_type'].choices = choices else: del self.fields['volume_source_type'] # Determine whether the extension for Cinder AZs is enabled def cinder_az_supported(self, request): try: return cinder.extension_supported(request, 'AvailabilityZones') except Exception: exceptions.handle(request, _('Unable to determine if ' 'availability zones extension ' 'is supported.')) return False def availability_zones(self, request): zone_list = [] if self.cinder_az_supported(request): try: zones = api.cinder.availability_zone_list(request) zone_list = [(zone.zoneName, zone.zoneName) for zone in zones if zone.zoneState['available']] zone_list.sort() except Exception: exceptions.handle(request, _('Unable to retrieve availability ' 'zones.')) if not zone_list: zone_list.insert(0, ("", _("No availability zones found"))) elif len(zone_list) > 0: zone_list.insert(0, ("", _("Any Availability Zone"))) return zone_list def get_volumes(self, request): volumes = [] try: volume_list = cinder.volume_list(self.request) if volume_list is not None: volumes = [v for v in volume_list if v.status == api.cinder.VOLUME_STATE_AVAILABLE] except Exception: exceptions.handle(request, _('Unable to retrieve list of volumes.')) return volumes def handle(self, request, data): try: usages = quotas.tenant_limit_usages(self.request) availableGB = usages['maxTotalVolumeGigabytes'] - \ usages['gigabytesUsed'] availableVol = usages['maxTotalVolumes'] - usages['volumesUsed'] snapshot_id = None image_id = None volume_id = None source_type = data.get('volume_source_type', None) az = data.get('availability_zone', None) or None if (data.get("snapshot_source", None) and source_type in [None, 'snapshot_source']): # Create from Snapshot snapshot = self.get_snapshot(request, data["snapshot_source"]) snapshot_id = snapshot.id if (data['size'] < snapshot.size): error_message = _('The volume size cannot be less than ' 'the snapshot size (%sGB)') % snapshot.size raise ValidationError(error_message) az = None elif (data.get("image_source", None) and source_type in [None, 'image_source']): # Create from Snapshot image = self.get_image(request, data["image_source"]) image_id = image.id image_size = functions.bytes_to_gigabytes(image.size) if (data['size'] < image_size): error_message = _('The volume size cannot be less than ' 'the image size (%s)') % filesizeformat(image.size) raise ValidationError(error_message) min_disk_size = getattr(image, 'min_disk', 0) if (min_disk_size > 0 and data['size'] < image.min_disk): error_message = _('The volume size cannot be less than ' 'the image minimum disk size (%sGB)') % min_disk_size raise ValidationError(error_message) elif (data.get("volume_source", None) and source_type in [None, 'volume_source']): # Create from volume volume = self.get_volume(request, data["volume_source"]) volume_id = volume.id if data['size'] < volume.size: error_message = _('The volume size cannot be less than ' 'the volume size (%sGB)') % volume.size raise ValidationError(error_message) else: if type(data['size']) is str: data['size'] = int(data['size']) if availableGB < data['size']: error_message = _('A volume of %(req)iGB cannot be created as ' 'you only have %(avail)iGB of your quota ' 'available.') params = {'req': data['size'], 'avail': availableGB} raise ValidationError(error_message % params) elif availableVol <= 0: error_message = _('You are already using all of your available' ' volumes.') raise ValidationError(error_message) metadata = {} volume = cinder.volume_create(request, data['size'], data['name'], data['description'], data['type'], snapshot_id=snapshot_id, image_id=image_id, metadata=metadata, availability_zone=az, source_volid=volume_id) message = _('Creating volume "%s"') % data['name'] messages.info(request, message) return volume except ValidationError as e: self.api_error(e.messages[0]) return False except Exception: exceptions.handle(request, ignore=True) self.api_error(_("Unable to create volume.")) return False @memoized def get_snapshot(self, request, id): return cinder.volume_snapshot_get(request, id) @memoized def get_image(self, request, id): return glance.image_get(request, id) @memoized def get_volume(self, request, id): return cinder.volume_get(request, id)
class SetInstanceDetailsAction(workflows.Action): PROVIDER_TYPE_CHOICES = (('provider_list', _("--- PROVIDER LISTS---")), ) CPU_TYPE_CHOICES = (('cpu_list', _("--- CPU LISTS---")), ) name = forms.CharField(max_length=80, label=_("Instance Name")) count = forms.IntegerField(label=_("Instance Count"), min_value=1, initial=1, help_text=_("Number of instances to launch.")) provider = forms.ChoiceField( label=_("Provider"), required=True, help_text=_("Choose Your Provider" "."), widget=fields.SelectWidget(data_attrs=('provider', ), transform=lambda x: ("%s" % (x.provider.title())))) region = forms.ChoiceField(label=_("Region"), required=True, help_text=_("Choose Your Region" "."), widget=fields.SelectWidget(data_attrs=( 'provider', 'name', ), transform=lambda x: ("%s" % (x.name.title())))) cnext_images_id = forms.ChoiceField( label=_("Image Name"), required=True, choices=PROVIDER_TYPE_CHOICES, help_text=_("Choose Your Image Name" "."), widget=fields.SelectWidget(data_attrs=('provider', 'region', 'cost'), transform=lambda x: ("%s (%s)" % (x.name, x.provider)))) provider_list = forms.ChoiceField( label=_("Instance Type"), required=True, choices=CPU_TYPE_CHOICES, widget=fields.SelectWidget( data_attrs=('provider', 'region', 'cpuCount', 'ram', 'localStorage', 'cost'), transform=lambda x: ("%s (%s)(cpucount=%s,RAM=%sGB,localstorage=%sGB)" % (x.name, x.provider, x.cpuCount, x.ram, x.localStorage)))) cpu_list = forms.ChoiceField(label=_("CPU Count"), required=False, widget=fields.SelectWidget(data_attrs=( 'provider', 'region', ), transform=lambda x: ("%s " % (x.attr)))) ram_list = forms.ChoiceField(label=_("RAM (in GB)"), required=False, widget=fields.SelectWidget(data_attrs=( 'provider', 'region', ), transform=lambda x: ("%s " % (x.attr)))) localstorage_list = forms.ChoiceField( label=_("Local storage (in GB)"), required=False, widget=fields.SelectWidget(data_attrs=( 'provider', 'region', ), transform=lambda x: ("%s " % (x.attr)))) class Meta: name = _("Details") help_text_template = ("cnext/instances/" "_launch_details_help.html") def __init__(self, request, context, *args, **kwargs): #self._init_images_cache() super(SetInstanceDetailsAction, self).__init__(request, context, *args, **kwargs) self.provider_list_choices = [] self.check_list = [] def populate_provider_choices(self, request, context): cnext_tuples = [] self.check_list = [] for role in request.user.roles: for policy in role.policy: if ((policy.provider).lower(), (policy.region).lower(), policy.allowed) in self.check_list: pass else: self.check_list.append( ((policy.provider).lower(), (policy.region).lower(), policy.allowed)) policy_allow = [[ i.roletype if i.roletype == "Tenant Admin" else "Member" ] for i in request.user.roles] if "Tenant Admin" in policy_allow[0]: cnext_provider = capi.providers(request) if "provider" in context: cprovider = context["provider"].lower() cnext_provider = list( filter((lambda x: x.__dict__["provider"].lower() \ == cprovider ), cnext_provider )) for cprovider in cnext_provider: cnid = cprovider.__dict__['provider'] cnext_tuples.append((cnid, cprovider)) if "provider" not in context: if cnext_tuples: cnext_tuples.insert(0, ("", _("Select Provider"))) else: cnext_tuples.insert(0, ("", _("No provider available"))) return cnext_tuples else: pro_check_list = [] pro_list = [] if "provider" in context: cprovider = context["provider"].lower() for pro in self.check_list: print pro[0] in self.check_list if (pro[0] == cprovider) & (pro[0] not in pro_check_list): pro_check_list.append(pro) else: pass if pro_check_list: self.check_list = pro_check_list for provider in self.check_list: if "Create Instance" in provider[2]: pro_list.append(provider[0]) else: pass pro_list = list(set(pro_list)) print pro_list for pro in pro_list: cnext_tuples.append((pro, capi.Provider(pro))) if "provider" not in context: if cnext_tuples: cnext_tuples.insert(0, ("", _("Select Provider"))) else: cnext_tuples.insert(0, ("", _("No provider available"))) return cnext_tuples def populate_region_choices(self, request, context): cnext_tuples = [] policy_allow = [[ i.roletype if i.roletype == "Tenant Admin" else "Member" ] for i in request.user.roles] if "Tenant Admin" in policy_allow[0]: cnext_region = capi.region(request) if "region" in context: cregion = context["region"].lower() cnext_region = list( filter((lambda x: x.__dict__["name"].lower() \ == cregion ), cnext_region )) for cregion in cnext_region: cnid = cregion.__dict__['name'] cnext_tuples.append((cnid, cregion)) if "region" not in context: if cnext_tuples: cnext_tuples.insert(0, ("", _("Select Region"))) else: cnext_tuples.insert(0, ("", _("No Region available"))) return cnext_tuples else: if "region" in context: cregion = context["region"].lower() self.check_list = list( filter((lambda x: x[1].lower() \ == cregion ), self.check_list )) for region in self.check_list: if "Create Instance" in region[2]: cnext_tuples.append( (region[1], capi.Region(region[1], region[0]))) else: pass if "region" not in context: if cnext_tuples: cnext_tuples.insert(0, ("", _("Select Region"))) else: cnext_tuples.insert(0, ("", _("No Region available"))) return cnext_tuples # def populate_cnext_images_id_choices(self, request, context): cnext_tuples = [] cnext_images = capi.images(request) if "cnext_images_id" in context: cimage_id = context["cnext_images_id"] cnext_images = list( filter((lambda x: x.__dict__["id"].lower() \ == cimage_id ), cnext_images )) for cimage in cnext_images: cnid = cimage.__dict__['uri'] cnext_tuples.append((cnid, cimage)) if "cnext_images_id" not in context: if cnext_tuples: cnext_tuples.insert(0, ("", _("Select Image"))) else: cnext_tuples.insert(0, ("", _("No images available"))) return cnext_tuples def populate_provider_list_choices(self, request, context): cnext_tuples = [] cnext_instances = capi.instances_list(request) self.provider_list_choices = cnext_instances ##adding to global variable if "cnext_images_id" in context: pop_provider = context["cnext_images_id"].split("_")[1].lower() pop_region = context["cnext_images_id"].split("_")[2].lower() cnext_instances = list( filter((lambda x: x.__dict__ \ ["provider"].lower() == pop_provider \ and x.__dict__["region"].lower() == \ pop_region), cnext_instances) ) for cinstances in cnext_instances: cnid = cinstances.__dict__['uri'] cnext_tuples.append((cnid, cinstances)) if cnext_tuples: cnext_tuples.insert(0, ("", _("Select Instance Type"))) else: cnext_tuples.insert(0, ("", _("No images available"))) return cnext_tuples def populate_cpu_list_choices(self, request, context): print "cpulistcontext:", context cnext_tuples = [] for cinstances in self.provider_list_choices: cnid = cinstances.__dict__['uri'] cnid = str(cnid) a = cnid.split("/") if a[-1] == "configurable": b = cinstances.__dict__['cpuCount'] b = str(b) b = b.split("-") class SimpleClass(object): pass for count in xrange(int(b[0][0])): x = SimpleClass() simplelist = [] x.attr = count + 1 x.provider = cinstances.__dict__['provider'] x.region = cinstances.__dict__['region'] simplelist.append(x) cnext_tuples.append((x.attr, simplelist[0])) if cnext_tuples: cnext_tuples.insert(0, ("", _("Select CPU count"))) else: cnext_tuples.insert(0, ("", _("No images available"))) return cnext_tuples def populate_ram_list_choices(self, request, context): cnext_tuples = [] for cinstances in self.provider_list_choices: cnid = cinstances.__dict__['uri'] cnid = str(cnid) a = cnid.split("/") if a[-1] == "configurable": b = cinstances.__dict__['ram'] b = str(b) b = b.split("-") class SimpleClass(object): pass for count in xrange(int(b[0][0])): x = SimpleClass() simplelist = [] x.attr = count + 1 x.provider = cinstances.__dict__['provider'] x.region = cinstances.__dict__['region'] simplelist.append(x) cnext_tuples.append((x.attr, simplelist[0])) if cnext_tuples: cnext_tuples.insert(0, ("", _("Select CPU count"))) else: cnext_tuples.insert(0, ("", _("No images available"))) return cnext_tuples def populate_localstorage_list_choices(self, request, context): cnext_tuples = [] for cinstances in self.provider_list_choices: cnid = cinstances.__dict__['uri'] cnid = str(cnid) a = cnid.split("/") if a[-1] == "configurable": b = cinstances.__dict__['localStorage'] b = str(b) if "," in b: b = b.split(",") class SimpleClass(object): pass for i in b: x = SimpleClass() simplelist = [] x.attr = i x.provider = cinstances.__dict__['provider'] x.region = cinstances.__dict__['region'] simplelist.append(x) cnext_tuples.append((x.attr, simplelist[0])) else: b = b.split("-") class SimpleClass(object): pass for count in range(0, int(b[1]), 10): x = SimpleClass() simplelist = [] x.attr = count x.provider = cinstances.__dict__['provider'] x.region = cinstances.__dict__['region'] simplelist.append(x) cnext_tuples.append((x.attr, simplelist[0])) if cnext_tuples: cnext_tuples.insert(0, ("", _("Select CPU count"))) else: cnext_tuples.insert(0, ("", _("No images available"))) return cnext_tuples
class AddPort(forms.SelfHandlingForm): instanceid= forms.CharField(label=_("instanceId"), widget=forms.HiddenInput(), required=False) protocoldetail_choices = ( ("", _("Select Protocoldetails")), ('ssh','ssh'), ('http','http'), ('rdp','rdp'), ('https','https'), ('mysql','mysql'), ('ldap','ldap'), ('microsoftsql','microsoftsql'), ('pop3','pop3'), ('pop3s','pop3s'), ('imap','imap'), ('imaps','imaps'), ('smtp','smtp'), ('smtps','smtps'), ('other','other'),) protocoldetail_details = forms.ChoiceField( label=_("ProtocolDetails"), required=True, choices=protocoldetail_choices ) fromport_choices = ( ('22',portlist('ssh','22')), ('80',portlist('http','80')), ('3389',portlist('rdp','3389')), ('443',portlist('https','443')), ('3306',portlist('mysql','3306')), ('389',portlist('ldap','389')), ('1433',portlist('microsoftsql','1433')), ('110',portlist('pop3','110')), ('995',portlist('pop3s','995')), ('220',portlist('imap','220')), ('993',portlist('imaps','993')), ('25',portlist('smtp','25')), ('465',portlist('smtps','465')),) fromport_details = forms.ChoiceField( label=_("From_Port"), required=True, choices=fromport_choices, widget=fields.SelectWidget(data_attrs=('protocoldetail','fromport',),transform=lambda x: ("%s " % (x.fromport))) ) toport_choices = ( ('22',portlist('ssh','22')), ('80',portlist('http','80')), ('3389',portlist('rdp','3389')), ('443',portlist('https','443')), ('3306',portlist('mysql','3306')), ('389',portlist('ldap','389')), ('1433',portlist('microsoftsql','1433')), ('110',portlist('pop3','110')), ('995',portlist('pop3s','995')), ('220',portlist('imap','220')), ('993',portlist('imaps','993')), ('25',portlist('smtp','25')), ('465',portlist('smtps','465')),) toport_details = forms.ChoiceField( label=_("To_Port"), required=True, choices=fromport_choices, widget=fields.SelectWidget(data_attrs=('protocoldetail','toport',),transform=lambda x: ("%s " % (x.toport))) ) protocol_choices = ( ('tcp','tcp'), ('udp','udp'), ('icmp','icmp'),) protocol_list = forms.ChoiceField( label=_("Protocols"), required=True, choices=protocol_choices ) cidr_ip = forms.CharField(label=_("CIDR")) def handle(self, request, data): try: cidr = [] cidr.append(data['cidr_ip']) ports = api.add_securitygroups(request,data['instanceid'],data['fromport_details'],data['toport_details'],data['protocol_list'],cidr) messages.success(request, _('Successfully added port: %s') % data['instanceid']) return ports except Exception,e: redirect = reverse("horizon:cnext:" "securitygroups:index", args=[data['id']]) exceptions.handle(request, _('Unable to add rule to security group.'), redirect=redirect)
class SetInstanceDetailsAction(workflows.Action): SOURCE_TYPE_CHOICES = ( ('', _("--- Select source ---")), ("owned_images_id", _("My Image.")), ("amazon_images_id", _("Amazon Image.")), ) name = forms.CharField(max_length=80, label=_("Instance Name")) count = forms.IntegerField(label=_("Instance Count"), min_value=1, initial=1, help_text=_("Number of instances to launch.")) availability_zone = forms.ChoiceField(label=_("Availability Zone"), required=True, help_text=_("Choose Your Zone ")) source_types = forms.ChoiceField(label=_("Instance Boot Source"), required=True, choices = SOURCE_TYPE_CHOICES, help_text=_("Choose Your Boot Source " "Type.")) owned_images_id = forms.ChoiceField( label=_("Owned Images"), required=False, widget=fields.SelectWidget( data_attrs=('id','name','root_device_name','architecture','region','state','kernel_id','virtualization_type','root_device_type',), transform=lambda x: ("%s" % (x.name)))) amazon_images_id = forms.ChoiceField( label=_("Amazon Images"), widget=fields.SelectWidget( data_attrs=('id','name','root_device_name','architecture','region','state','kernel_id','virtualization_type','root_device_type',), transform=lambda x: ("%s" % (str(x.id) + " - (" + str(x.name) + ")",))), required=False) imagetype = forms.CharField(label=_("Image Type"), widget=forms.HiddenInput(), required=False ) instance_type = forms.ChoiceField(label = _("Instance Type"), required = True, help_text=_("Choose Your Instance Type."), choices = instance_type_choices, widget=fields.SelectWidget(data_attrs=('imagetype', 'instancetype', ), transform=lambda x: ("%s " % (x.name))) ) class Meta: name = _("Details") help_text_template = ("amazon/instances/" "_launch_details_help.html") def __init__(self, request, context, *args, **kwargs): super(SetInstanceDetailsAction, self).__init__( request, context, *args, **kwargs) def clean(self): cleaned_data = super(SetInstanceDetailsAction, self).clean() # Validate our instance source. source_type = self.data.get('source_type', None) if source_type == "owned_images_id": if not cleaned_data.get('owned_images_id'): msg = _("You must select an image.") self._errors['owned_images_id'] = self.error_class([msg]) elif source_type == 'amazon_images_id': if not cleaned_data['amazon_images_id']: msg = _("You must select a image.") self._errors['amazon_images_id'] = self.error_class([msg]) return cleaned_data def populate_owned_images_id_choices(self, request, context): aws_tuples = [] aws_images = Images(request).get_images('self') if "owned_images_id" in context: cimage_id = context["owned_images_id"] aws_images = list( filter((lambda x: x.__dict__["id"].lower() \ == cimage_id ), aws_images )) for cimage in aws_images: cnid = cimage.__dict__['id'] aws_tuples.append((cnid, cimage)) aws_tuples.insert(0, ("", _("Select Image"))) return aws_tuples def populate_amazon_images_id_choices(self, request, context): aws_tuples = [] aws_images = Images(request).get_images('amazon') if "amazon_images_id" in context: cimage_id = context["amazon_images_id"] aws_images = list( filter((lambda x: x.__dict__["id"].lower() \ == cimage_id ), aws_images )) for cimage in aws_images: cnid = cimage.__dict__['id'] aws_tuples.append((cnid, cimage)) aws_tuples.insert(0, ("", _("Select Image"))) return aws_tuples def populate_availability_zone_choices(self, request, context): aws_tuples = [] aws_zone = Instances(request).get_zone() for zone in aws_zone: aws_tuples.append((str(zone.name), str(zone.name))) aws_tuples.insert(0, ("", _("Select Zone"))) return aws_tuples
class SetInstanceDetailsAction(workflows.Action): SOURCE_TYPE_CHOICES = ( ('', _("--- Select source ---")), ("image_id", _("Boot from image.")), ("instance_snapshot_id", _("Boot from snapshot.")), ("volume_id", _("Boot from volume.")), ("volume_image_id", _("Boot from image " "(creates a new volume).")), ("volume_snapshot_id", _("Boot from volume snapshot " "(creates a new volume).")), ) availability_zone = forms.ChoiceField(label=_("Availability Zone"), required=False) name = forms.CharField(max_length=80, label=_("Instance Name")) flavor = forms.ChoiceField(label=_("Flavor"), help_text=_("Size of image to launch.")) count = forms.IntegerField(label=_("Instance Count"), min_value=1, initial=1, help_text=_("Number of instances to launch.")) source_type = forms.ChoiceField(label=_("Instance Boot Source"), required=True, choices=SOURCE_TYPE_CHOICES, help_text=_("Choose Your Boot Source " "Type.")) instance_snapshot_id = forms.ChoiceField(label=_("Instance Snapshot"), required=False) volume_id = forms.ChoiceField(label=_("Volume"), required=False) volume_snapshot_id = forms.ChoiceField(label=_("Volume Snapshot"), required=False) image_id = forms.ChoiceField( label=_("Image Name"), required=False, widget=fields.SelectWidget(data_attrs=('volume_size', ), transform=lambda x: ("%s (%s)" % (x.name, filesizeformat(x.bytes))))) volume_size = forms.CharField(label=_("Device size (GB)"), required=False, help_text=_("Volume size in gigabytes " "(integer value).")) device_name = forms.CharField(label=_("Device Name"), required=False, initial="vda", help_text=_("Volume mount point (e.g. 'vda' " "mounts at '/dev/vda').")) delete_on_terminate = forms.BooleanField(label=_("Delete on Terminate"), initial=False, required=False, help_text=_("Delete volume on " "instance terminate")) class Meta: name = _("Details") help_text_template = ("project/instances/" "_launch_details_help.html") def __init__(self, request, context, *args, **kwargs): self._init_images_cache() super(SetInstanceDetailsAction, self).__init__(request, context, *args, **kwargs) def clean(self): cleaned_data = super(SetInstanceDetailsAction, self).clean() count = cleaned_data.get('count', 1) # Prevent launching more instances than the quota allows usages = quotas.tenant_quota_usages(self.request) available_count = usages['instances']['available'] if available_count < count: error_message = ungettext_lazy( 'The requested instance ' 'cannot be launched as you only ' 'have %(avail)i of your quota ' 'available. ', 'The requested %(req)i instances ' 'cannot be launched as you only ' 'have %(avail)i of your quota ' 'available.', count) params = {'req': count, 'avail': available_count} raise forms.ValidationError(error_message % params) # Validate our instance source. source_type = self.data.get('source_type', None) if source_type == 'image_id': if not cleaned_data.get('image_id'): msg = _("You must select an image.") self._errors['image_id'] = self.error_class([msg]) elif source_type == 'instance_snapshot_id': if not cleaned_data['instance_snapshot_id']: msg = _("You must select a snapshot.") self._errors['instance_snapshot_id'] = self.error_class([msg]) elif source_type == 'volume_id': if not cleaned_data.get('volume_id'): msg = _("You must select a volume.") self._errors['volume_id'] = self.error_class([msg]) # Prevent launching multiple instances with the same volume. # TODO(gabriel): is it safe to launch multiple instances with # a snapshot since it should be cloned to new volumes? if count > 1: msg = _('Launching multiple instances is only supported for ' 'images and instance snapshots.') raise forms.ValidationError(msg) elif source_type == 'volume_image_id': if not cleaned_data['image_id']: msg = _("You must select an image.") self._errors['image_id'] = self.error_class([msg]) if not self.data.get('volume_size', None): msg = _("You must set volume size") self._errors['volume_size'] = self.error_class([msg]) if not cleaned_data.get('device_name'): msg = _("You must set device name") self._errors['device_name'] = self.error_class([msg]) elif source_type == 'volume_snapshot_id': if not cleaned_data.get('volume_snapshot_id'): msg = _("You must select a snapshot.") self._errors['volume_snapshot_id'] = self.error_class([msg]) if not cleaned_data.get('device_name'): msg = _("You must set device name") self._errors['device_name'] = self.error_class([msg]) return cleaned_data def _init_images_cache(self): if not hasattr(self, '_images_cache'): self._images_cache = {} def _get_volume_display_name(self, volume): if hasattr(volume, "volume_id"): vol_type = "snap" visible_label = _("Snapshot") else: vol_type = "vol" visible_label = _("Volume") return (("%s:%s" % (volume.id, vol_type)), (_("%(name)s - %(size)s GB (%(label)s)") % { 'name': volume.display_name or volume.id, 'size': volume.size, 'label': visible_label })) def populate_image_id_choices(self, request, context): choices = [] images = api.images(request) for image in images: image.bytes = image.size image.volume_size = functions.bytes_to_gigabytes(image.bytes) choices.append((image.id, image)) if choices: choices.insert(0, ("", _("Select Image"))) else: choices.insert(0, ("", _("No images available"))) return choices def populate_instance_snapshot_id_choices(self, request, context): images = api.images(request) choices = [(image.id, image.name) for image in images if image.properties.get("image_type", '') == "snapshot"] if choices: choices.insert(0, ("", _("Select Instance Snapshot"))) else: choices.insert(0, ("", _("No snapshots available."))) return choices
class CreateVolume(forms.SelfHandlingForm): volume_name = forms.CharField(max_length="60", label=_("Volume Name"), required=False) description = forms.CharField(max_length="200", label=_("Volume Description"), required=False) name = forms.IntegerField(min_value=1, label=_("Volume Size (in GB)")) key_provider_list = forms.ChoiceField( label=_("Providers List"), required=True, ) key_region_list = forms.ChoiceField( label=_("Regions List"), required=True, widget=fields.SelectWidget(data_attrs=( 'provider', 'region', ), transform=lambda x: ("%s " % (x.name)))) def handle(self, request, data): try: volume = api.volume_create(request,data['name'],data['volume_name'],data['description'], \ data['key_provider_list'],data['key_region_list']) if volume == True: messages.success( request, _('Schedule to create a volume: %s') % data['volume_name']) else: messages.error( request, _('Unable to create a volume: %s') % data['volume_name']) return True except Exception: exceptions.handle( request, _('Unable to create volume.'), ) redirect = reverse("horizon:cnext:volume:index") def __init__(self, request, *args, **kwargs): forms.SelfHandlingForm.__init__(self, request, *args, **kwargs) provider_list = api.providers(self.request) region_list = api.region(self.request) p = [("", _("Select Provider"))] for provider in provider_list: if provider.provider in provider_volume_choices: p.append((provider.provider.lower(), provider.provider)) t = tuple(p) tuple_providers = t self.fields['key_provider_list'].choices = tuple_providers r = [("", _("Select Region"))] for region in region_list: if region.name in region_volume_choices: r.append((region.name, Regionlist(region.provider, region.name))) r = tuple(r) tuple_regions = r self.fields['key_region_list'].choices = tuple_regions
class SetInstanceDetailsAction(workflows.Action): availability_zone = forms.ChoiceField(label=_("Availability Zone"), required=False) name = forms.CharField(label=_("Instance Name"), max_length=255) flavor = forms.ChoiceField(label=_("Flavor"), help_text=_("Size of image to launch.")) count = forms.IntegerField(label=_("Instance Count"), min_value=1, initial=1, help_text=_("Number of instances to launch.")) source_type = forms.ChoiceField(label=_("Instance Boot Source"), required=True, help_text=_("Choose Your Boot Source " "Type.")) instance_snapshot_id = forms.ChoiceField(label=_("Instance Snapshot"), required=False) volume_id = forms.ChoiceField(label=_("Volume"), required=False) volume_snapshot_id = forms.ChoiceField(label=_("Volume Snapshot"), required=False) image_id = forms.ChoiceField( label=_("Image Name"), required=False, widget=fields.SelectWidget(data_attrs=('volume_size', ), transform=lambda x: ("%s (%s)" % (x.name, filesizeformat(x.bytes))))) volume_size = forms.IntegerField(label=_("Device size (GB)"), required=False, help_text=_("Volume size in gigabytes " "(integer value).")) device_name = forms.CharField(label=_("Device Name"), required=False, initial="vda", help_text=_("Volume mount point (e.g. 'vda' " "mounts at '/dev/vda').")) delete_on_terminate = forms.BooleanField(label=_("Delete on Terminate"), initial=False, required=False, help_text=_("Delete volume on " "instance terminate")) class Meta: name = _("Details") help_text_template = ("project/instances/" "_launch_details_help.html") def __init__(self, request, context, *args, **kwargs): self._init_images_cache() self.request = request self.context = context super(SetInstanceDetailsAction, self).__init__(request, context, *args, **kwargs) source_type_choices = [ ('', _("--- Select source ---")), ("image_id", _("Boot from image")), ("instance_snapshot_id", _("Boot from snapshot")), ] if base.is_service_enabled(request, 'volume'): source_type_choices.append(("volume_id", _("Boot from volume"))) try: if api.nova.extension_supported("BlockDeviceMappingV2Boot", request): source_type_choices.append( ("volume_image_id", _("Boot from image (creates a new volume)"))) except Exception: exceptions.handle( request, _('Unable to retrieve extensions ' 'information.')) source_type_choices.append( ("volume_snapshot_id", _("Boot from volume snapshot (creates a new volume)"))) self.fields['source_type'].choices = source_type_choices def clean(self): cleaned_data = super(SetInstanceDetailsAction, self).clean() count = cleaned_data.get('count', 1) # Prevent launching more instances than the quota allows usages = quotas.tenant_quota_usages(self.request) available_count = usages['instances']['available'] if available_count < count: error_message = ungettext_lazy( 'The requested instance ' 'cannot be launched as you only ' 'have %(avail)i of your quota ' 'available. ', 'The requested %(req)i instances ' 'cannot be launched as you only ' 'have %(avail)i of your quota ' 'available.', count) params = {'req': count, 'avail': available_count} raise forms.ValidationError(error_message % params) # Validate our instance source. source_type = self.data.get('source_type', None) if source_type in ('image_id', 'volume_image_id'): if not cleaned_data.get('image_id'): msg = _("You must select an image.") self._errors['image_id'] = self.error_class([msg]) else: # Prevents trying to launch an image needing more resources. try: image_id = cleaned_data.get('image_id') # We want to retrieve details for a given image, # however get_available_images uses a cache of image list, # so it is used instead of image_get to reduce the number # of API calls. images = image_utils.get_available_images( self.request, self.context.get('project_id'), self._images_cache) image = [x for x in images if x.id == image_id][0] except IndexError: image = None try: flavor_id = cleaned_data.get('flavor') # We want to retrieve details for a given flavor, # however flavor_list uses a memoized decorator # so it is used instead of flavor_get to reduce the number # of API calls. flavors = instance_utils.flavor_list(self.request) flavor = [x for x in flavors if x.id == flavor_id][0] except IndexError: flavor = None if image and flavor: props_mapping = (("min_ram", "ram"), ("min_disk", "disk")) for iprop, fprop in props_mapping: if getattr(image, iprop) > 0 and \ getattr(image, iprop) > getattr(flavor, fprop): msg = _( "The flavor '%(flavor)s' is too small for " "requested image.\n" "Minimum requirements: " "%(min_ram)s MB of RAM and " "%(min_disk)s GB of Root Disk." % { 'flavor': flavor.name, 'min_ram': image.min_ram, 'min_disk': image.min_disk }) self._errors['image_id'] = self.error_class([msg]) break # Not necessary to continue the tests. volume_size = cleaned_data.get('volume_size') if volume_size and source_type == 'volume_image_id': volume_size = int(volume_size) img_gigs = functions.bytes_to_gigabytes(image.size) smallest_size = max(img_gigs, image.min_disk) if volume_size < smallest_size: msg = _( "The Volume size is too small for the" " '%(image_name)s' image and has to be" " greater than or equal to " "'%(smallest_size)d' GB." % { 'image_name': image.name, 'smallest_size': smallest_size }) self._errors['volume_size'] = self.error_class( [msg]) elif source_type == 'instance_snapshot_id': if not cleaned_data['instance_snapshot_id']: msg = _("You must select a snapshot.") self._errors['instance_snapshot_id'] = self.error_class([msg]) elif source_type == 'volume_id': if not cleaned_data.get('volume_id'): msg = _("You must select a volume.") self._errors['volume_id'] = self.error_class([msg]) # Prevent launching multiple instances with the same volume. # TODO(gabriel): is it safe to launch multiple instances with # a snapshot since it should be cloned to new volumes? if count > 1: msg = _('Launching multiple instances is only supported for ' 'images and instance snapshots.') raise forms.ValidationError(msg) elif source_type == 'volume_image_id': if not cleaned_data['image_id']: msg = _("You must select an image.") self._errors['image_id'] = self.error_class([msg]) if not self.data.get('volume_size', None): msg = _("You must set volume size") self._errors['volume_size'] = self.error_class([msg]) if not cleaned_data.get('device_name'): msg = _("You must set device name") self._errors['device_name'] = self.error_class([msg]) elif source_type == 'volume_snapshot_id': if not cleaned_data.get('volume_snapshot_id'): msg = _("You must select a snapshot.") self._errors['volume_snapshot_id'] = self.error_class([msg]) if not cleaned_data.get('device_name'): msg = _("You must set device name") self._errors['device_name'] = self.error_class([msg]) return cleaned_data def populate_flavor_choices(self, request, context): flavors = instance_utils.flavor_list(request) if flavors: return instance_utils.sort_flavor_list(request, flavors) return [] def populate_availability_zone_choices(self, request, context): try: zones = api.nova.availability_zone_list(request) except Exception: zones = [] exceptions.handle(request, _('Unable to retrieve availability zones.')) zone_list = [(zone.zoneName, zone.zoneName) for zone in zones if zone.zoneState['available']] zone_list.sort() if not zone_list: zone_list.insert(0, ("", _("No availability zones found"))) elif len(zone_list) > 1: zone_list.insert(0, ("", _("Any Availability Zone"))) return zone_list def get_help_text(self): extra = {} try: extra['usages'] = api.nova.tenant_absolute_limits(self.request) extra['usages_json'] = json.dumps(extra['usages']) flavors = json.dumps( [f._info for f in instance_utils.flavor_list(self.request)]) extra['flavors'] = flavors images = image_utils.get_available_images( self.request, self.initial['project_id'], self._images_cache) if images is not None: attrs = [{ 'id': i.id, 'min_disk': getattr(i, 'min_disk', 0), 'min_ram': getattr(i, 'min_ram', 0) } for i in images] extra['images'] = json.dumps(attrs) except Exception: exceptions.handle(self.request, _("Unable to retrieve quota information.")) return super(SetInstanceDetailsAction, self).get_help_text(extra) def _init_images_cache(self): if not hasattr(self, '_images_cache'): self._images_cache = {} def _get_volume_display_name(self, volume): if hasattr(volume, "volume_id"): vol_type = "snap" visible_label = _("Snapshot") else: vol_type = "vol" visible_label = _("Volume") return (("%s:%s" % (volume.id, vol_type)), (_("%(name)s - %(size)s GB (%(label)s)") % { 'name': volume.name, 'size': volume.size, 'label': visible_label })) def populate_image_id_choices(self, request, context): choices = [] images = image_utils.get_available_images(request, context.get('project_id'), self._images_cache) for image in images: image.bytes = image.size image.volume_size = max(image.min_disk, functions.bytes_to_gigabytes(image.bytes)) choices.append((image.id, image)) if context.get('image_id') == image.id and \ 'volume_size' not in context: context['volume_size'] = image.volume_size if choices: choices.sort(key=lambda c: c[1].name) choices.insert(0, ("", _("Select Image"))) else: choices.insert(0, ("", _("No images available"))) return choices def populate_instance_snapshot_id_choices(self, request, context): images = image_utils.get_available_images(request, context.get('project_id'), self._images_cache) choices = [(image.id, image.name) for image in images if image.properties.get("image_type", '') == "snapshot"] if choices: choices.insert(0, ("", _("Select Instance Snapshot"))) else: choices.insert(0, ("", _("No snapshots available"))) return choices def populate_volume_id_choices(self, request, context): try: volumes = [ self._get_volume_display_name(v) for v in cinder.volume_list(self.request) if v.status == api.cinder.VOLUME_STATE_AVAILABLE ] except Exception: volumes = [] exceptions.handle(self.request, _('Unable to retrieve list of volumes.')) if volumes: volumes.insert(0, ("", _("Select Volume"))) else: volumes.insert(0, ("", _("No volumes available"))) return volumes def populate_volume_snapshot_id_choices(self, request, context): try: snapshots = cinder.volume_snapshot_list(self.request) snapshots = [ self._get_volume_display_name(s) for s in snapshots if s.status == api.cinder.VOLUME_STATE_AVAILABLE ] except Exception: snapshots = [] exceptions.handle( self.request, _('Unable to retrieve list of volume ' 'snapshots.')) if snapshots: snapshots.insert(0, ("", _("Select Volume Snapshot"))) else: snapshots.insert(0, ("", _("No volume snapshots available"))) return snapshots
class CreateForm(forms.SelfHandlingForm): name = forms.CharField(max_length="255", label=_("Volume Name")) description = forms.CharField(widget=forms.Textarea, label=_("Description"), required=False) type = forms.ChoiceField(label=_("Type"), required=False) size = forms.IntegerField(min_value=1, label=_("Size (GB)")) volume_source_type = forms.ChoiceField(label=_("Volume Source"), required=False) snapshot_source = forms.ChoiceField( label=_("Use snapshot as a source"), widget=fields.SelectWidget(attrs={'class': 'snapshot-selector'}, data_attrs=('size', 'display_name'), transform=lambda x: "%s (%sGB)" % (x.display_name, x.size)), required=False) image_source = forms.ChoiceField( label=_("Use image as a source"), widget=fields.SelectWidget(attrs={'class': 'image-selector'}, data_attrs=('size', 'name'), transform=lambda x: "%s (%s)" % (x.name, filesizeformat(x.bytes))), required=False) def __init__(self, request, *args, **kwargs): super(CreateForm, self).__init__(request, *args, **kwargs) volume_types = cinder.volume_type_list(request) self.fields['type'].choices = [("", "")] + \ [(type.name, type.name) for type in volume_types] if ("snapshot_id" in request.GET): try: snapshot = self.get_snapshot(request, request.GET["snapshot_id"]) self.fields['name'].initial = snapshot.display_name self.fields['size'].initial = snapshot.size self.fields['snapshot_source'].choices = ((snapshot.id, snapshot), ) try: # Set the volume type from the original volume orig_volume = cinder.volume_get(request, snapshot.volume_id) self.fields['type'].initial = orig_volume.volume_type except Exception: pass self.fields['size'].help_text = _( 'Volume size must be equal ' 'to or greater than the snapshot size (%sGB)' % snapshot.size) del self.fields['image_source'] del self.fields['volume_source_type'] except Exception: exceptions.handle(request, _('Unable to load the specified snapshot.')) elif ('image_id' in request.GET): try: image = self.get_image(request, request.GET["image_id"]) image.bytes = image.size self.fields['name'].initial = image.name self.fields['size'].initial = functions.bytes_to_gigabytes( image.size) self.fields['image_source'].choices = ((image.id, image), ) self.fields['size'].help_text = _( 'Volume size must be equal ' 'to or greater than the image size (%s)' % filesizeformat(image.size)) del self.fields['snapshot_source'] del self.fields['volume_source_type'] except Exception: msg = _('Unable to load the specified image. %s') exceptions.handle(request, msg % request.GET['image_id']) else: source_type_choices = [] try: snapshots = cinder.volume_snapshot_list(request) if snapshots: source_type_choices.append( ("snapshot_source", _("Snapshot"))) choices = [('', _("Choose a snapshot"))] + \ [(s.id, s) for s in snapshots] self.fields['snapshot_source'].choices = choices else: del self.fields['snapshot_source'] except Exception: exceptions.handle(request, _("Unable to retrieve " "volume snapshots.")) images = utils.get_available_images(request, request.user.tenant_id) if images: source_type_choices.append(("image_source", _("Image"))) choices = [('', _("Choose an image"))] for image in images: image.bytes = image.size image.size = functions.bytes_to_gigabytes(image.bytes) choices.append((image.id, image)) self.fields['image_source'].choices = choices else: del self.fields['image_source'] if source_type_choices: choices = ( [('no_source_type', _("No source, empty volume."))] + source_type_choices) self.fields['volume_source_type'].choices = choices else: del self.fields['volume_source_type'] def handle(self, request, data): try: usages = quotas.tenant_limit_usages(self.request) availableGB = usages['maxTotalVolumeGigabytes'] - \ usages['gigabytesUsed'] availableVol = usages['maxTotalVolumes'] - usages['volumesUsed'] snapshot_id = None image_id = None source_type = data.get('volume_source_type', None) if (data.get("snapshot_source", None) and source_type in [None, 'snapshot_source']): # Create from Snapshot snapshot = self.get_snapshot(request, data["snapshot_source"]) snapshot_id = snapshot.id if (data['size'] < snapshot.size): error_message = _('The volume size cannot be less than ' 'the snapshot size (%sGB)' % snapshot.size) raise ValidationError(error_message) elif (data.get("image_source", None) and source_type in [None, 'image_source']): # Create from Snapshot image = self.get_image(request, data["image_source"]) image_id = image.id image_size = functions.bytes_to_gigabytes(image.size) if (data['size'] < image_size): error_message = _('The volume size cannot be less than ' 'the image size (%s)' % filesizeformat(image.size)) raise ValidationError(error_message) else: if type(data['size']) is str: data['size'] = int(data['size']) if availableGB < data['size']: error_message = _('A volume of %(req)iGB cannot be created as ' 'you only have %(avail)iGB of your quota ' 'available.') params = {'req': data['size'], 'avail': availableGB} raise ValidationError(error_message % params) elif availableVol <= 0: error_message = _('You are already using all of your available' ' volumes.') raise ValidationError(error_message) metadata = {} volume = cinder.volume_create(request, data['size'], data['name'], data['description'], data['type'], snapshot_id=snapshot_id, image_id=image_id, metadata=metadata) message = _('Creating volume "%s"') % data['name'] messages.info(request, message) return volume except ValidationError as e: self.api_error(e.messages[0]) return False except Exception: exceptions.handle(request, ignore=True) self.api_error(_("Unable to create volume.")) return False @memoized def get_snapshot(self, request, id): return cinder.volume_snapshot_get(request, id) @memoized def get_image(self, request, id): return glance.image_get(request, id)
class CloudEditAction(workflows.Action): id= forms.CharField(widget=forms.HiddenInput(), required=False) cloudtype_choices = ( ("", _("Select CloudType")), ('private','Private'), ('public','Public'),) cloudtype = forms.ChoiceField( label=_("Cloud Type"), required=False, widget=forms.HiddenInput(), choices=cloudtype_choices ) cloudslist = forms.ChoiceField( label=_("Platform"), required=False, widget=fields.SelectWidget( data_attrs=('platform',), transform=lambda x: ("%s " % (x.platform))) ) cloudname1 = forms.CharField(label=_("Cloud Name"),max_length=80) username1 = forms.CharField(max_length=80, label=_("User Name")) password1 = forms.RegexField( label=_("Password"), widget=forms.PasswordInput(render_value=True), regex=validators.password_validator(), error_messages={'invalid': validators.password_validator_msg()}) endpoint1 = forms.CharField(max_length=80, label=_("Endpoint(IP with HTTP)")) def populate_cloudslist_choices(self, request, context): try: roles = [] id = context.get('id', None) cloud = tenantclouds.objects(id = id).first() roles.append((cloud.id,cloud)) except Exception: exceptions.handle(request, _('Unable to retrieve list of Cloud Details')) roles = [] return roles class Meta: name = _("Edit Cloud") def __init__(self, *args, **kwargs): super(CloudEditAction, self).__init__(*args, **kwargs) try: region_list = get_regions_wo_connection() tenantcloud_id = args[-1]["id"] cloud = tenantclouds.objects(id = tenantcloud_id).first() cloud_obj = clouds.objects(id=cloud.cloudid.id).first() self.fields['username1'].label = _(cloud_obj.credential_fields[0]) self.fields["password1"].label = _(cloud_obj.credential_fields[1]) if cloud_obj.name == "Amazon": self.fields["endpoint1"] = forms.ChoiceField(label=_("Default Region"), choices = region_list, help_text=_("Select default region")) self.fields["endpoint1"].label = _(cloud_obj.credential_fields[2]) else: self.fields["endpoint1"].label = _(cloud_obj.credential_fields[2]) except Exception, e: messages.error(self.request,_(e.message)) LOG.error(e.message)