Пример #1
0
class UrlFreshForm(forms.Form):
    url_fresh = forms.URLField(label=_("Url Fresh"),
                               max_length=64,
                               widget=forms.Textarea(attrs={
                                   'cols': 70,
                                   'rows': 10
                               }),
                               required=True)
Пример #2
0
class DirFreshForm(forms.Form):
    Dir_fresh = forms.URLField(label=_("Directory Fresh"),
                               max_length=64,
                               widget=forms.Textarea(attrs={
                                   'cols': 70,
                                   'rows': 10
                               }),
                               required=True)
Пример #3
0
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'}))
Пример #4
0
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)
Пример #5
0
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)
Пример #6
0
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
Пример #7
0
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
Пример #8
0
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)
Пример #9
0
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
Пример #10
0
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
Пример #11
0
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
Пример #12
0
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)
Пример #13
0
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)