class UrlFreshForm(forms.Form): url_fresh = forms.URLField(label=_("Url Fresh"), max_length=64, widget=forms.Textarea(attrs={ 'cols': 70, 'rows': 10 }), required=True)
class DirFreshForm(forms.Form): Dir_fresh = forms.URLField(label=_("Directory Fresh"), max_length=64, widget=forms.Textarea(attrs={ 'cols': 70, 'rows': 10 }), required=True)
class CreateNotificationAction(workflows.Action): name = forms.CharField( max_length=constants.STRING_L, widget=forms.widgets.TextInput(attrs={'autocomplete': 'off'})) sender_address = forms.EmailField( max_length=constants.STRING_L, widget=forms.widgets.EmailInput(attrs={'autocomplete': 'off'})) recipient_address = forms.EmailField( max_length=constants.STRING_L, widget=forms.widgets.EmailInput(attrs={'autocomplete': 'off'})) smtp_server = forms.GenericIPAddressField(widget=forms.widgets.TextInput( attrs={'autocomplete': 'off'})) openstack_url = forms.URLField(widget=forms.widgets.TextInput( attrs={'autocomplete': 'off'}))
class TemplateForm(forms.SelfHandlingForm): class Meta: name = _('Select Template') help_text = _('Select a template to launch a stack.') # TODO(jomara) - update URL choice for template & environment files # w/ client side download when applicable base_choices = [('file', _('File')), ('raw', _('Direct Input'))] url_choice = [('url', _('URL'))] attributes = {'class': 'switchable', 'data-slug': 'templatesource'} template_source = forms.ChoiceField(label=_('Template Source'), choices=base_choices + url_choice, widget=forms.Select(attrs=attributes)) attributes = create_upload_form_attributes('template', 'file', _('Template File')) template_upload = forms.FileField( label=_('Template File'), help_text=_('A local template to upload.'), widget=forms.FileInput(attrs=attributes), required=False) attributes = create_upload_form_attributes('template', 'url', _('Template URL')) template_url = forms.URLField( label=_('Template URL'), help_text=_('An external (HTTP) URL to load the template from.'), widget=forms.TextInput(attrs=attributes), required=False) attributes = create_upload_form_attributes('template', 'raw', _('Template Data')) template_data = forms.CharField( label=_('Template Data'), help_text=_('The raw contents of the template.'), widget=forms.widgets.Textarea(attrs=attributes), required=False) attributes = {'data-slug': 'envsource', 'class': 'switchable'} environment_source = forms.ChoiceField( label=_('Environment Source'), choices=base_choices, widget=forms.Select(attrs=attributes), required=False) attributes = create_upload_form_attributes('env', 'file', _('Environment File')) environment_upload = forms.FileField( label=_('Environment File'), help_text=_('A local environment to upload.'), widget=forms.FileInput(attrs=attributes), required=False) attributes = create_upload_form_attributes('env', 'raw', _('Environment Data')) environment_data = forms.CharField( label=_('Environment Data'), help_text=_('The raw contents of the environment file.'), widget=forms.widgets.Textarea(attrs=attributes), required=False) def __init__(self, *args, **kwargs): self.next_view = kwargs.pop('next_view') super(TemplateForm, self).__init__(*args, **kwargs) def clean(self): cleaned = super(TemplateForm, self).clean() files = self.request.FILES self.clean_uploaded_files('template', _('template'), cleaned, files) self.clean_uploaded_files('environment', _('environment'), cleaned, files) # Validate the template and get back the params. kwargs = {} if cleaned['template_data']: kwargs['template'] = cleaned['template_data'] else: kwargs['template_url'] = cleaned['template_url'] if cleaned['environment_data']: kwargs['environment'] = cleaned['environment_data'] try: validated = api.heat.template_validate(self.request, **kwargs) cleaned['template_validate'] = validated except Exception as e: raise forms.ValidationError(unicode(e)) return cleaned def clean_uploaded_files(self, prefix, field_label, cleaned, files): """Cleans Template & Environment data from form upload. Does some of the crunchy bits for processing uploads vs raw data depending on what the user specified. Identical process for environment data & template data. :type prefix: str :param prefix: prefix (environment, template) of field :type field_label: str :param field_label: translated prefix str for messages :type input_type: dict :param prefix: existing cleaned fields from form :rtype: dict :return: cleaned dict including environment & template data """ upload_str = prefix + "_upload" data_str = prefix + "_data" url = cleaned.get(prefix + '_url') data = cleaned.get(prefix + '_data') has_upload = upload_str in files # Uploaded file handler if has_upload and not url: log_template_name = files[upload_str].name LOG.info('got upload %s' % log_template_name) tpl = files[upload_str].read() if tpl.startswith('{'): try: json.loads(tpl) except Exception as e: msg = _('There was a problem parsing the' ' %(prefix)s: %(error)s') msg = msg % {'prefix': prefix, 'error': e} raise forms.ValidationError(msg) cleaned[data_str] = tpl # URL handler elif url and (has_upload or data): msg = _('Please specify a %s using only one source method.') msg = msg % field_label raise forms.ValidationError(msg) elif prefix == 'template': # Check for raw template input - blank environment allowed if not url and not data: msg = _('You must specify a template via one of the ' 'available sources.') raise forms.ValidationError(msg) def create_kwargs(self, data): kwargs = { 'parameters': data['template_validate'], 'environment_data': data['environment_data'], 'template_data': data['template_data'], 'template_url': data['template_url'] } if data.get('stack_id'): kwargs['stack_id'] = data['stack_id'] return kwargs def handle(self, request, data): kwargs = self.create_kwargs(data) # NOTE (gabriel): This is a bit of a hack, essentially rewriting this # request so that we can chain it as an input to the next view... # but hey, it totally works. request.method = 'GET' return self.next_view.as_view()(request, **kwargs)
class TemplateForm(forms.SelfHandlingForm): class Meta: name = _('Select Template') help_text = _('From here you can select a template to launch ' 'a stack.') template_source = forms.ChoiceField(label=_('Template Source'), choices=[('url', _('URL')), ('file', _('File')), ('raw', _('Direct Input'))], widget=forms.Select(attrs={ 'class': 'switchable', 'data-slug': 'source'})) template_upload = forms.FileField( label=_('Template File'), help_text=_('A local template to upload.'), widget=forms.FileInput(attrs={'class': 'switched', 'data-switch-on': 'source', 'data-source-file': _('Template File')}), required=False) template_url = forms.URLField( label=_('Template URL'), help_text=_('An external (HTTP) URL to load the template from.'), widget=forms.TextInput(attrs={'class': 'switched', 'data-switch-on': 'source', 'data-source-url': _('Template URL')}), required=False) template_data = forms.CharField( label=_('Template Data'), help_text=_('The raw contents of the template.'), widget=forms.widgets.Textarea(attrs={ 'class': 'switched', 'data-switch-on': 'source', 'data-source-raw': _('Template Data')}), required=False) def __init__(self, *args, **kwargs): self.next_view = kwargs.pop('next_view') super(TemplateForm, self).__init__(*args, **kwargs) def clean(self): cleaned = super(TemplateForm, self).clean() template_url = cleaned.get('template_url') template_data = cleaned.get('template_data') files = self.request.FILES has_upload = 'template_upload' in files # Uploaded file handler if has_upload and not template_url: log_template_name = self.request.FILES['template_upload'].name LOG.info('got upload %s' % log_template_name) tpl = self.request.FILES['template_upload'].read() if tpl.startswith('{'): try: json.loads(tpl) except Exception as e: msg = _('There was a problem parsing the template: %s') % e raise forms.ValidationError(msg) cleaned['template_data'] = tpl # URL handler elif template_url and (has_upload or template_data): msg = _('Please specify a template using only one source method.') raise forms.ValidationError(msg) # Check for raw template input elif not template_url and not template_data: msg = _('You must specify a template via one of the ' 'available sources.') raise forms.ValidationError(msg) # Validate the template and get back the params. kwargs = {} if cleaned['template_data']: kwargs['template'] = cleaned['template_data'] else: kwargs['template_url'] = cleaned['template_url'] try: validated = api.heat.template_validate(self.request, **kwargs) cleaned['template_validate'] = validated except Exception as e: msg = exception_to_validation_msg(e) if not msg: msg = _('An unknown problem occurred validating the template.') LOG.exception(msg) raise forms.ValidationError(msg) return cleaned def handle(self, request, data): kwargs = {'parameters': data['template_validate'], 'template_data': data['template_data'], 'template_url': data['template_url']} # NOTE (gabriel): This is a bit of a hack, essentially rewriting this # request so that we can chain it as an input to the next view... # but hey, it totally works. request.method = 'GET' return self.next_view.as_view()(request, **kwargs)
class CreateImageForm(forms.SelfHandlingForm): name = forms.CharField(max_length=255, label=_("Name")) description = forms.CharField(max_length=255, label=_("Description"), required=False) source_type = forms.ChoiceField( label=_('Image Source'), required=False, choices=[('url', _('Image Location')), ('file', _('Image File'))], widget=forms.Select(attrs={ 'class': 'switchable', 'data-slug': 'source' })) image_url = forms.URLField( label=_("Image Location"), help_text=_("An external (HTTP) URL to load " "the image from."), widget=forms.TextInput( attrs={ 'class': 'switched', 'data-switch-on': 'source', 'data-source-url': _('Image Location'), 'ng-model': 'copyFrom', 'ng-change': 'ctrl.selectImageFormat(copyFrom)' }), required=False) image_file = forms.FileField( label=_("Image File"), help_text=_("A local image to upload."), widget=forms.FileInput( attrs={ 'class': 'switched', 'data-switch-on': 'source', 'data-source-file': _('Image File'), 'ng-model': 'imageFile', 'ng-change': 'ctrl.selectImageFormat(imageFile.name)', 'image-file-on-change': None }), required=False) kernel = forms.ChoiceField( label=_('Kernel'), required=False, widget=forms.SelectWidget(transform=lambda x: "%s (%s)" % ( x.name, defaultfilters.filesizeformat(x.size)))) ramdisk = forms.ChoiceField( label=_('Ramdisk'), required=False, widget=forms.SelectWidget(transform=lambda x: "%s (%s)" % ( x.name, defaultfilters.filesizeformat(x.size)))) disk_format = forms.ChoiceField( label=_('Format'), choices=[], widget=forms.Select(attrs={ 'class': 'switchable', 'ng-model': 'ctrl.diskFormat' })) architecture = forms.CharField(max_length=255, label=_("Architecture"), required=False) minimum_disk = forms.IntegerField( label=_("Minimum Disk (GB)"), min_value=0, help_text=_('The minimum disk size required to boot the image. ' 'If unspecified, this value defaults to 0 (no minimum).'), required=False) minimum_ram = forms.IntegerField( label=_("Minimum RAM (MB)"), min_value=0, help_text=_('The minimum memory size required to boot the image. ' 'If unspecified, this value defaults to 0 (no minimum).'), required=False) is_copying = forms.BooleanField( label=_("Copy Data"), initial=True, required=False, help_text=_('Specify this option to copy image data to the image ' 'service. If unspecified, image data will be used in its ' 'current location.'), widget=forms.CheckboxInput( attrs={ 'class': 'switched', 'data-source-url': _('Image Location'), 'data-switch-on': 'source' })) is_public = forms.BooleanField(label=_("Public"), required=False) protected = forms.BooleanField(label=_("Protected"), required=False) def __init__(self, request, *args, **kwargs): super(CreateImageForm, self).__init__(request, *args, **kwargs) if (not settings.HORIZON_IMAGES_ALLOW_UPLOAD or not policy.check( (("image", "upload_image"), ), request)): self._hide_file_source_type() if not policy.check((("image", "set_image_location"), ), request): self._hide_url_source_type() if not policy.check((("image", "publicize_image"), ), request): self._hide_is_public() self.fields['disk_format'].choices = IMAGE_FORMAT_CHOICES try: kernel_images = api.glance.image_list_detailed( request, filters={'disk_format': 'aki'})[0] except Exception: kernel_images = [] msg = _('Unable to retrieve image list.') messages.error(request, msg) if kernel_images: choices = [('', _("Choose an image"))] for image in kernel_images: choices.append((image.id, image)) self.fields['kernel'].choices = choices else: del self.fields['kernel'] try: ramdisk_images = api.glance.image_list_detailed( request, filters={'disk_format': 'ari'})[0] except Exception: ramdisk_images = [] msg = _('Unable to retrieve image list.') messages.error(request, msg) if ramdisk_images: choices = [('', _("Choose an image"))] for image in ramdisk_images: choices.append((image.id, image)) self.fields['ramdisk'].choices = choices else: del self.fields['ramdisk'] def _hide_file_source_type(self): self.fields['image_file'].widget = HiddenInput() source_type = self.fields['source_type'] source_type.choices = [ choice for choice in source_type.choices if choice[0] != 'file' ] if len(source_type.choices) == 1: source_type.widget = HiddenInput() def _hide_url_source_type(self): self.fields['image_url'].widget = HiddenInput() source_type = self.fields['source_type'] source_type.choices = [ choice for choice in source_type.choices if choice[0] != 'url' ] if len(source_type.choices) == 1: source_type.widget = HiddenInput() def _hide_is_public(self): self.fields['is_public'].widget = HiddenInput() self.fields['is_public'].initial = False def clean(self): data = super(CreateImageForm, self).clean() # The image_file key can be missing based on particular upload # conditions. Code defensively for it here... image_file = data.get('image_file', None) image_url = data.get('image_url', None) if not image_url and not image_file: raise ValidationError( _("A image or external image location must be specified.")) elif image_url and image_file: raise ValidationError( _("Can not specify both image and external image location.")) else: return data def handle(self, request, data): meta = create_image_metadata(data) # Add image source file or URL to metadata if (settings.HORIZON_IMAGES_ALLOW_UPLOAD and policy.check( (("image", "upload_image"), ), request) and data.get('image_file', None)): meta['data'] = self.files['image_file'] elif data['is_copying']: meta['copy_from'] = data['image_url'] else: meta['location'] = data['image_url'] try: image = api.glance.image_create(request, **meta) messages.success( request, _('Your image %s has been queued for creation.') % meta['name']) return image except Exception as e: msg = _('Unable to create new image') # TODO(nikunj2512): Fix this once it is fixed in glance client if hasattr(e, 'code') and e.code == 400: if "Invalid disk format" in e.details: msg = _('Unable to create new image: Invalid disk format ' '%s for image.') % meta['disk_format'] elif "Image name too long" in e.details: msg = _('Unable to create new image: Image name too long.') exceptions.handle(request, msg) return False
class CreateForm(forms.SelfHandlingForm): source = forms.ChoiceField(label=_('Source'), choices=[('app_file', _('App File')), ('input', _('Input'))], widget=forms.Select(attrs={ 'class': 'switchable', 'data-slug': 'source' })) app_file = forms.FileField( label=_("Local app file location"), required=False, widget=forms.FileInput( attrs={ 'class': 'switched', 'data-switch-on': 'source', 'data-source-app_file': _('Local app file location') })) name = forms.CharField(label=_("Application Name"), required=False, max_length=100) languagepack = forms.CharField(label=_("Languagepack"), required=False) git_url = forms.URLField(label=_("Source repository"), required=False) run_cmd = forms.CharField(label=_("Application entry point"), required=False) unittest_cmd = forms.CharField(label=_("Command to execute unit tests"), required=False) port = forms.IntegerField(label=_("The port your application listens on"), min_value=0, required=False) param_file = forms.FileField( label=_("A yaml file containing custom parameters"), required=False) def clean(self): cleaned_data = super(CreateForm, self).clean() import_type = cleaned_data.get('source') if import_type == 'app_file' and not cleaned_data.get('app_file'): msg = _('Please supply an app file') raise forms.ValidationError(msg) elif import_type == 'input': if not (cleaned_data.get('name')): msg = _('Please supply a name') raise forms.ValidationError(msg) elif not cleaned_data.get('languagepack'): msg = _('Please supply a languagepack') raise forms.ValidationError(msg) elif not cleaned_data.get('git_url'): msg = _('Please supply a github url') raise forms.ValidationError(msg) elif not cleaned_data.get('run_cmd'): msg = _('Please supply a run command') raise forms.ValidationError(msg) return cleaned_data def handle(self, request, data): LOG.info('CreateApplication %s' % data) solum = solumclient(request) app_data = None if data['source'] == 'app_file': inf = data['app_file'].read() app_data = yaml.load(inf) if 'repo_token' not in app_data: app_data['repo_token'] = '' else: app_data = { 'version': 1, 'description': 'default app description', 'source': { 'repository': '', 'revision': 'master', 'repo_token': '' }, 'workflow_config': { 'test_cmd': '', 'run_cmd': '' } } if data['name']: app_data['name'] = data['name'] if data['languagepack']: app_data['languagepack'] = data['languagepack'] if data['git_url']: app_data['source'] = dict() app_data['source']['repository'] = data['git_url'] app_data['source']['revision'] = 'master' if data['run_cmd']: if app_data.get('workflow_config') is None: app_data['workflow_config'] = dict() if not app_data['workflow_config']['run_cmd']: app_data['workflow_config']['run_cmd'] = data['run_cmd'] if data['unittest_cmd']: if app_data.get('workflow_config') is None: app_data['workflow_config'] = dict() if not app_data['workflow_config']['test_cmd']: app_data['workflow_config']['test_cmd'] = data['unittest_cmd'] if not app_data.get('ports'): app_data['ports'] = [] if data['port']: app_data['ports'].append(data['port']) else: app_data['ports'].append(80) if data['param_file']: param_def = data['param_file'].read() app_data['parameters'] = yaml.load(param_def) try: solum.apps.create(**app_data) messages.success(request, _('Application was successfully created.')) return True except Exception: msg = _('Unable to create application.') redirect = reverse("horizon:solum:applications:index") exceptions.handle(request, msg, redirect=redirect) return False
class RegisterVim(forms.SelfHandlingForm): vim_name = forms.CharField(max_length=255, label=_("Name")) vim_description = forms.CharField( widget=forms.widgets.Textarea(attrs={'rows': 4}), label=_("Description"), required=False) auth_url = forms.URLField(label=_("Auth URL")) username = forms.CharField(max_length=80, label=_("Username")) password = forms.CharField(label=_("Password"), widget=forms.PasswordInput(render_value=False)) project_name = forms.CharField(max_length=80, label=_("Project Name")) domain_name = forms.CharField(max_length=80, label=_("Domain Name"), help_text=_('Applicable for OpenStack site ' 'running keystone v3. Run ' 'openstack domain list from ' 'CLI to find domain name'), required=False) is_default = forms.BooleanField( label=_("Default"), initial=False, required=False, widget=forms.CheckboxInput(attrs={ 'class': 'switched', })) def __init__(self, request, *args, **kwargs): super(RegisterVim, self).__init__(request, *args, **kwargs) def clean(self): data = super(RegisterVim, self).clean() return data @sensitive_variables('data', 'password') def handle(self, request, data): try: vim_name = data['vim_name'] description = data['vim_description'] password = data['password'] username = data['username'] project_name = data['project_name'] is_default = data['is_default'] auth_url = data['auth_url'] vim_type = 'openstack' domain_name = data['domain_name'] vim_arg = { 'vim': { 'name': vim_name, 'description': description, 'type': vim_type, 'auth_url': auth_url, 'auth_cred': { 'username': username, 'password': password, 'user_domain_name': domain_name }, 'vim_project': { 'name': project_name, 'project_domain_name': domain_name }, 'is_default': is_default } } api.tacker.create_vim(request, vim_arg) messages.success( request, _('VIM %s create operation initiated.') % vim_name) return True except Exception as e: exceptions.handle(request, _('Failed to register VIM: %s') % e.message)
class SetTemplateAction(workflows.Action): class Meta: name = _('Select Template') help_text = _('From here you can select a template to launch ' 'a stack.') template_data = forms.CharField(widget=forms.HiddenInput(), required=False) stack_name = forms.CharField(max_length='255', label=_('Stack Name'), help_text=_('Name of the stack to create.'), required=True) template_upload = forms.FileField( label=_('Template File'), help_text=_('A local template to upload.'), required=False) template_url = forms.URLField( label=_('Template Location'), help_text=_('An external (HTTP) URL to load the template from.'), required=False) enable_rollback = forms.BooleanField( label=_('Rollback on failure'), help_text=_('Enable rollback on create/update failure.'), required=False) timeout_mins = forms.IntegerField( initial=60, label=_('Creation Timeout'), help_text=_('Stack creation timeout in minutes.'), required=True) def clean(self): cleaned = super(SetTemplateAction, self).clean() template_url = cleaned.get('template_url') template_data = cleaned.get('template_data') files = self.request.FILES has_upload = 'template_upload' in files if has_upload and not template_url: del cleaned['template_url'] tpl = self.request.FILES['template_upload'].read() self.data['template_data'] = tpl if tpl.startswith('{'): try: cleaned['template_data'] = json.loads(tpl) except Exception as e: msg = _('There was a problem parsing the template: %s') % e raise forms.ValidationError(msg) else: cleaned['template_data'] = tpl template_name = self.request.FILES['template_upload'].name LOG.info('got upload %s' % template_name) elif template_url and not has_upload: del cleaned['template_data'] del self.data['template_data'] elif not template_data: msg = _('Select either a "Template File" or "Template Location".') raise forms.ValidationError(msg) try: if cleaned.get('template_url'): cleaned['template_validate'] = api.heat.template_validate( self.request, template_url=cleaned['template_url']) elif cleaned.get('template_data'): cleaned['template_validate'] = api.heat.template_validate( self.request, template=cleaned['template_data']) except Exception as e: msg = exception_to_validation_msg(e) if not msg: msg = _('An unknown problem occurred validating the template.') LOG.exception(msg) raise forms.ValidationError(msg) return cleaned
class ImportPackageForm(forms.Form): import_type = forms.ChoiceField( label=_("Package Source"), choices=IMPORT_TYPE_CHOICES, widget=forms.Select(attrs={ 'class': 'switchable', 'data-slug': 'source' })) url = horizon_forms.URLField( label=_("Package URL"), required=False, widget=forms.TextInput( attrs={ 'class': 'switched', 'data-switch-on': 'source', 'data-source-by_url': _('Package URL') }), help_text=_('An external http/https URL to load the package from.')) repo_name = horizon_forms.CharField( label=_("Package Name"), required=False, widget=forms.TextInput( attrs={ 'class': 'switched', 'data-switch-on': 'source', 'data-source-by_name': _('Package Name') }), help_text=_( 'Package name in the repository, usually a fully qualified name'), ) package = forms.FileField( label=_('Application Package'), required=False, widget=forms.FileInput( attrs={ 'class': 'switched', 'data-switch-on': 'source', 'data-source-upload': _('Application Package') }), help_text=_('A local zip file to upload')) repo_version = horizon_forms.CharField( label=_("Package version"), widget=forms.TextInput( attrs={ 'class': 'switched', 'data-switch-on': 'source', 'data-source-by_name': _('Package version') }), required=False) def __init__(self, *args, **kwargs): super(ImportPackageForm, self).__init__(*args, **kwargs) self.fields['repo_version'].widget.attrs['placeholder'] = \ _('Optional') def clean_package(self): package = self.cleaned_data.get('package') if package: max_size_in_bytes = consts.MAX_FILE_SIZE_MB << 20 if package.size > max_size_in_bytes: msg = _('It is forbidden to upload files larger than ' '{0} MB.').format(consts.MAX_FILE_SIZE_MB) LOG.error(msg) raise forms.ValidationError(msg) return package def clean(self): cleaned_data = super(ImportPackageForm, self).clean() import_type = cleaned_data.get('import_type') if import_type == 'upload' and not cleaned_data.get('package'): msg = _('Please supply a package file') LOG.error(msg) raise forms.ValidationError(msg) elif import_type == 'by_name' and not cleaned_data.get('repo_name'): msg = _('Please supply a package name') LOG.error(msg) raise forms.ValidationError(msg) elif import_type == 'by_url' and not cleaned_data.get('url'): msg = _('Please supply a package url') LOG.error(msg) raise forms.ValidationError(msg) return cleaned_data
class CreateDatasource(forms.SelfHandlingForm): name = forms.CharField(max_length=255, label=_("Data Source Name"), help_text='Name of the data source') driver = forms.ThemableChoiceField(label=_("Driver"), help_text='Data Source driver') description = forms.CharField(label=_("Description"), required=False, help_text='Data Source Description') username = forms.CharField( max_length=255, label=_("UserName"), help_text='username to connect to the driver service') password = forms.CharField(widget=forms.PasswordInput(render_value=False), label=_('Password')) tenant_name = forms.CharField(max_length=255, label=_("Project Name")) # TODO(ramineni): support adding lazy tables # lazy_tables = forms.CharField(max_length=255, label=_("Lazy Tables")) auth_url = forms.URLField(max_length=255, label=_("Keystone Auth URL")) poll_time = forms.IntegerField( label=_("Poll Interval (in seconds)"), help_text='periodic interval congress needs to poll data') failure_url = 'horizon:admin:datasources:index' @classmethod def _instantiate(cls, request, *args, **kwargs): return cls(request, *args, **kwargs) def __init__(self, request, *args, **kwargs): super(CreateDatasource, self).__init__(request, *args, **kwargs) driver_choices = [('', _("Select a Driver"))] drivers = congress.supported_driver_list(request) driver_choices.extend(drivers) self.fields['driver'].choices = driver_choices def handle(self, request, data): datasource_name = data['name'] datasource_description = data.get('description') datasource_driver = data.pop('driver') config = { 'username': data['username'], 'password': data['password'], 'tenant_name': data['tenant_name'], 'auth_url': data['auth_url'], 'poll_time': data['poll_time'] } try: params = { 'name': datasource_name, 'driver': datasource_driver, 'description': datasource_description, 'config': config } datasource = congress.create_datasource(request, params) msg = _('Created Data Source "%s"') % datasource_name LOG.info(msg) messages.success(request, msg) except Exception as e: msg_args = {'datasource_name': datasource_name, 'error': str(e)} msg = _('Failed to create data source "%(datasource_name)s": ' '%(error)s') % msg_args LOG.error(msg) messages.error(self.request, msg) redirect = reverse(self.failure_url) raise exceptions.Http302(redirect) return datasource
class RegisterVim(forms.SelfHandlingForm): vim_type = forms.ChoiceField(choices=api.tacker.SUPPORTED_VIM_TYPES, label=_("VIM Type")) vim_name = forms.CharField(max_length=255, label=_("Name")) vim_description = forms.CharField(widget=forms.widgets.Textarea( attrs={'rows': 4}), label=_("Description"), required=False) auth_url = forms.URLField(label=_("Auth URL")) auth_method = forms.ChoiceField(widget=forms.widgets.RadioSelect, choices=api.tacker.AUTH_METHODS, initial="basic", label=_("Auth Method")) username = forms.CharField(max_length=80, initial="admin", label=_("Username")) password = forms.CharField(label=_("Password"), widget=forms.PasswordInput(render_value=False)) cert_verify = forms.ChoiceField(widget=forms.widgets.RadioSelect, choices=api.tacker.CERT_VERIFY_TYPES, initial="True", label=_("Cert Verify")) bearer_token = forms.CharField(widget=forms.widgets.Textarea( attrs={'rows': 4}), label=_("Bearer Token")) project_name = forms.CharField(max_length=80, label=_("Project Name")) domain_name = forms.CharField(max_length=80, label=_("Domain Name"), help_text=_('Applicable for OpenStack site ' 'running keystone v3. Run ' 'openstack domain list from ' 'CLI to find domain name'), required=False) ssl_ca_cert = forms.CharField(widget=forms.widgets.Textarea( attrs={'rows': 4}), label=_("SSL CA Certificate"), required=False) is_default = forms.BooleanField( label=_("Default"), initial=False, required=False, widget=forms.CheckboxInput( attrs={ 'class': 'switched', } ) ) def __init__(self, request, *args, **kwargs): super(RegisterVim, self).__init__(request, *args, **kwargs) def clean(self): data = super(RegisterVim, self).clean() return data @sensitive_variables('data', 'password') def handle(self, request, data): try: vim_name = data['vim_name'] description = data['vim_description'] password = data['password'] username = data['username'] project_name = data['project_name'] is_default = data['is_default'] auth_url = data['auth_url'] domain_name = data['domain_name'] cert_verify = data.get('cert_verify', api.tacker.CERT_TRUE_TYPE) if cert_verify not in [api.tacker.CERT_TRUE_TYPE, api.tacker.CERT_FALSE_TYPE]: raise forms.ValidationError("cert_verify type not supported.") auth_cred = {'username': username, 'password': password, 'user_domain_name': domain_name, 'cert_verify': cert_verify} bearer_token = data['bearer_token'].replace('None', '') ssl_ca_cert = data['ssl_ca_cert'].replace('\r\n', ' ') vim_type = data['vim_type'] if vim_type == 'kubernetes': auth_cred = {'username': username, 'password': password} # if bearer_token is provided, use it instead if bearer_token: auth_cred = {'bearer_token': bearer_token} # only k8s vim needs ssl_ca_cert and it's optional if ssl_ca_cert: auth_cred['ssl_ca_cert'] = ssl_ca_cert vim_arg = {'vim': {'name': vim_name, 'description': description, 'type': vim_type, 'auth_url': auth_url, 'auth_cred': auth_cred, 'vim_project': {'name': project_name, 'project_domain_name': domain_name}, 'is_default': is_default}} api.tacker.create_vim(request, vim_arg) messages.success(request, _('VIM %s create operation initiated.') % vim_name) return True except Exception as e: exceptions.handle(request, _('Failed to register VIM: %s') % e.message)
class TemplateForm(forms.SelfHandlingForm): class Meta(object): name = _('Select Template') help_text = _('Select a template to launch a stack.') # TODO(jomara) - update URL choice for template & environment files # w/ client side download when applicable base_choices = [('file', _('File')), ('raw', _('Direct Input'))] url_choice = [('url', _('URL'))] attributes = {'class': 'switchable', 'data-slug': 'templatesource'} template_source = forms.ChoiceField(label=_('Template Source'), choices=base_choices + url_choice, widget=forms.Select(attrs=attributes)) attributes = create_upload_form_attributes('template', 'file', _('Template File')) template_upload = forms.FileField( label=_('Template File'), help_text=_('A local template to upload.'), widget=forms.FileInput(attrs=attributes), required=False) attributes = create_upload_form_attributes('template', 'url', _('Template URL')) template_url = forms.URLField( label=_('Template URL'), help_text=_('An external (HTTP) URL to load the template from.'), widget=forms.TextInput(attrs=attributes), required=False) picklist = getattr(settings, 'OPENSTACK_HEAT_STACK_LIST', None) if (picklist != None): choices = [('', '')] base = (picklist) try: html_page = urllib2.urlopen(base) soup = BeautifulSoup(html_page, "html.parser") for link in soup.findAll('a'): choices.append( [urlparse.urljoin(base, link.get('href')), link.text]) template_url = forms.ChoiceField( label=_('Template URL'), choices=choices, widget=forms.Select(attrs=attributes), required=False) except: pass attributes = create_upload_form_attributes('template', 'raw', _('Template Data')) template_data = forms.CharField( label=_('Template Data'), help_text=_('The raw contents of the template.'), widget=forms.widgets.Textarea(attrs=attributes), required=False) attributes = {'data-slug': 'envsource', 'class': 'switchable'} environment_source = forms.ChoiceField( label=_('Environment Source'), choices=base_choices, widget=forms.Select(attrs=attributes), required=False) attributes = create_upload_form_attributes('env', 'file', _('Environment File')) environment_upload = forms.FileField( label=_('Environment File'), help_text=_('A local environment to upload.'), widget=forms.FileInput(attrs=attributes), required=False) attributes = create_upload_form_attributes('env', 'raw', _('Environment Data')) environment_data = forms.CharField( label=_('Environment Data'), help_text=_('The raw contents of the environment file.'), widget=forms.widgets.Textarea(attrs=attributes), required=False) if django.VERSION >= (1, 9): # Note(Itxaka): On django>=1.9 Charfield has an strip option that # we need to set to False as to not hit # https://bugs.launchpad.net/python-heatclient/+bug/1546166 environment_data.strip = False template_data.strip = False def __init__(self, *args, **kwargs): self.next_view = kwargs.pop('next_view') super(TemplateForm, self).__init__(*args, **kwargs) def clean(self): cleaned = super(TemplateForm, self).clean() files = self.request.FILES self.clean_uploaded_files('template', _('template'), cleaned, files) self.clean_uploaded_files('environment', _('environment'), cleaned, files) # Validate the template and get back the params. kwargs = {} if cleaned['environment_data']: kwargs['environment'] = cleaned['environment_data'] try: files, tpl =\ api.heat.get_template_files(cleaned.get('template_data'), cleaned.get('template_url')) kwargs['files'] = files kwargs['template'] = tpl validated = api.heat.template_validate(self.request, **kwargs) cleaned['template_validate'] = validated cleaned['template_validate']['files'] = files cleaned['template_validate']['template'] = tpl except Exception as e: raise forms.ValidationError(six.text_type(e)) return cleaned def clean_uploaded_files(self, prefix, field_label, cleaned, files): """Cleans Template & Environment data from form upload. Does some of the crunchy bits for processing uploads vs raw data depending on what the user specified. Identical process for environment data & template data. :type prefix: str :param prefix: prefix (environment, template) of field :type field_label: str :param field_label: translated prefix str for messages :type input_type: dict :param prefix: existing cleaned fields from form :rtype: dict :return: cleaned dict including environment & template data """ upload_str = prefix + "_upload" data_str = prefix + "_data" url = cleaned.get(prefix + '_url') data = cleaned.get(prefix + '_data') has_upload = upload_str in files # Uploaded file handler if has_upload and not url: log_template_name = files[upload_str].name LOG.info('got upload %s' % log_template_name) tpl = files[upload_str].read() if tpl.startswith('{'): try: json.loads(tpl) except Exception as e: msg = _('There was a problem parsing the' ' %(prefix)s: %(error)s') msg = msg % {'prefix': prefix, 'error': six.text_type(e)} raise forms.ValidationError(msg) cleaned[data_str] = tpl # URL handler elif url and (has_upload or data): msg = _('Please specify a %s using only one source method.') msg = msg % field_label raise forms.ValidationError(msg) elif prefix == 'template': # Check for raw template input - blank environment allowed if not url and not data: msg = _('You must specify a template via one of the ' 'available sources.') raise forms.ValidationError(msg) def create_kwargs(self, data): kwargs = { 'parameters': data['template_validate'], 'environment_data': data['environment_data'] } if data.get('stack_id'): kwargs['stack_id'] = data['stack_id'] return kwargs def handle(self, request, data): kwargs = self.create_kwargs(data) # NOTE (gabriel): This is a bit of a hack, essentially rewriting this # request so that we can chain it as an input to the next view... # but hey, it totally works. request.method = 'GET' return self.next_view.as_view()(request, **kwargs)