예제 #1
0
    def get_form(self, request, obj=None, **kwargs):
        if 'fields' in kwargs:
            fields = kwargs.pop('fields')
        else:
            fields = flatten_fieldsets(self.get_fieldsets(request, obj))
        if self.exclude is None:
            exclude = []
        else:
            exclude = list(self.exclude)
        exclude.extend(self.get_readonly_fields(request, obj))
        if self.exclude is None and hasattr(
                self.form, '_meta') and self.form._meta.exclude:
            # Take the custom ModelForm's Meta.exclude into account only if the
            # ModelAdmin doesn't define its own.
            exclude.extend(self.form._meta.exclude)
        # if exclude is an empty list we pass None to be consistent with the
        # default on modelform_factory
        exclude = exclude or None

        if obj and obj.plan.provider == Plan.CLOUDSTACK:
            if 'offering' in self.fieldsets_change[0][1][
                    'fields'] and 'offering' in self.form.declared_fields:
                del self.form.declared_fields['offering']
            else:
                self.fieldsets_change[0][1]['fields'].append('offering')
            DatabaseForm.setup_offering_field(form=self.form, db_instance=obj)

        if obj:
            if 'disk_offering' in self.fieldsets_change[0][1]['fields']:
                self.fieldsets_change[0][1]['fields'].remove('disk_offering')

            self.fieldsets_change[0][1]['fields'].append('disk_offering')
            DatabaseForm.setup_disk_offering_field(form=self.form,
                                                   db_instance=obj)

        defaults = {
            "form":
            self.form,
            "fields":
            fields,
            "exclude":
            exclude,
            "formfield_callback":
            partial(self.formfield_for_dbfield, request=request),
        }
        defaults.update(kwargs)

        try:
            return modelform_factory(self.model, **defaults)
        except FieldError as e:
            raise FieldError(
                '%s. Check fields/fieldsets/exclude attributes of class %s.' %
                (e, self.__class__.__name__))
예제 #2
0
    def change_view(self, request, object_id, form_url='', extra_context=None):
        database = Database.objects.get(id=object_id)
        self.form = DatabaseForm
        extra_context = extra_context or {}

        extra_context['has_perm_upgrade_mongo'] = False
        extra_context['can_upgrade'] = False

        if database.is_mongodb_24():
            extra_context['has_perm_upgrade_mongo'] = request.user.has_perm(
                constants.PERM_UPGRADE_MONGO24_TO_30)
        else:
            has_permission = request.user.has_perm(
                constants.PERM_UPGRADE_DATABASE)
            has_equivalent_plan = bool(
                database.infra.plan.engine_equivalent_plan)
            extra_context[
                'can_upgrade'] = has_equivalent_plan and has_permission

        upgrades = database.upgrades.filter(source_plan=database.infra.plan)
        last_upgrade = upgrades.last()
        extra_context['last_upgrade'] = last_upgrade
        extra_context['retry_upgrade'] = False
        if last_upgrade:
            extra_context['retry_upgrade'] = last_upgrade.is_status_error

        if database.is_in_quarantine:
            extra_context['delete_button_name'] = self.delete_button_name
        else:
            extra_context['delete_button_name'] = "Delete"

        if request.user.team_set.filter(role__name="role_dba"):
            extra_context['is_dba'] = True
        else:
            extra_context['is_dba'] = False

        if request.method == 'POST':
            form = DatabaseForm(request.POST)
            if not form.is_valid():
                return super(DatabaseAdmin,
                             self).change_view(request,
                                               object_id,
                                               form_url,
                                               extra_context=extra_context)

        return super(DatabaseAdmin,
                     self).change_view(request,
                                       object_id,
                                       form_url,
                                       extra_context=extra_context)
예제 #3
0
    def create(self, request):
        serializer = self.get_serializer(data=request.DATA,
                                         files=request.FILES)

        if serializer.is_valid():
            self.pre_save(serializer.object)
            data = serializer.restore_fields(request.DATA, request.FILES)

            backup_hour, maintenance_hour, maintenance_day = (
                DatabaseForm.randomize_backup_and_maintenance_hour())
            LOG.error("{}".format(data))
            result = TaskRegister.database_create(
                name=data['name'],
                plan=data['plan'],
                environment=data['environment'],
                team=data['team'],
                project=data['project'],
                description=data['description'],
                backup_hour=data.get('backup_hour', backup_hour),
                maintenance_window=data.get('maintenance_window',
                                            maintenance_hour),
                maintenance_day=data.get('maintenance_day', maintenance_day),
                subscribe_to_email_events=data['subscribe_to_email_events'],
                user=request.user,
                register_user=False)
            headers = self.get_success_headers(data)
            task_url = Site.objects.get_current().domain + \
                '/api/task?task_id=%s' % str(result.id)

            return Response({"task": task_url},
                            status=status.HTTP_201_CREATED,
                            headers=headers)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
예제 #4
0
    def post(self, request, format=None):
        validations = (self._validate_required_params,
                       self._validate_search_metadata_params,
                       self._validate_env, self._validate_database,
                       self._validate_user, self._validate_team,
                       self._validate_database_alocation,
                       self._validate_if_kubernetes_env, self._validate_plan)

        for validation in validations:
            err = validation()
            if err is not None:
                return err

        backup_hour, maintenance_hour, maintenance_day = (
            DatabaseForm.randomize_backup_and_maintenance_hour())

        TaskRegister.database_create(name=self.name_param,
                                     plan=self.dbaas_plan,
                                     environment=self.env,
                                     team=self.dbaas_team,
                                     project=None,
                                     description=self.description_param,
                                     user=self.dbaas_user,
                                     is_protected=True,
                                     backup_hour=backup_hour,
                                     maintenance_window=maintenance_hour,
                                     maintenance_day=maintenance_day,
                                     **self.extra_params)

        return Response(status=status.HTTP_201_CREATED)
예제 #5
0
    def add_view(self, request, form_url='', extra_context=None):
        self.form = DatabaseForm

        try:

            if request.method == 'POST':

                teams = Team.objects.filter(users=request.user)
                LOG.info("user %s teams: %s" % (request.user, teams))
                if not teams:
                    self.message_user(
                        request, self.database_add_perm_message,
                        level=messages.ERROR
                    )
                    return HttpResponseRedirect(
                        reverse('admin:logical_database_changelist')
                    )

                # if no team is specified and the user has only one team, then
                # set it to the database
                if teams.count() == 1 and request.method == 'POST' and not request.user.has_perm(
                        self.perm_add_database_infra):

                    post_data = request.POST.copy()
                    if 'team' in post_data:
                        post_data['team'] = u"%s" % teams[0].pk

                    request.POST = post_data

                form = DatabaseForm(request.POST)

                if not form.is_valid():
                    return super(DatabaseAdmin, self).add_view(request, form_url, extra_context=extra_context)

                database_creation_message = "call create_database - name={}, plan={}, environment={}, team={}, project={}, description={}, backup_hour={}, maintenance_window={}, maintenance_day={}, user={}, subscribe_to_email_events {}".format(
                    form.cleaned_data['name'],
                    form.cleaned_data['plan'],
                    form.cleaned_data['environment'],
                    form.cleaned_data['team'],
                    form.cleaned_data['project'],
                    form.cleaned_data['description'],
                    form.cleaned_data['backup_hour'],
                    form.cleaned_data['maintenance_window'],
                    form.cleaned_data['maintenance_day'],
                    request.user,
                    form.cleaned_data['subscribe_to_email_events'],
                )
                LOG.debug(database_creation_message)

                TaskRegister.database_create(
                    name=form.cleaned_data['name'],
                    plan=form.cleaned_data['plan'],
                    environment=form.cleaned_data['environment'],
                    team=form.cleaned_data['team'],
                    project=form.cleaned_data['project'],
                    description=form.cleaned_data['description'],
                    backup_hour=form.cleaned_data['backup_hour'],
                    maintenance_window=form.cleaned_data['maintenance_window'],
                    maintenance_day=form.cleaned_data['maintenance_day'],
                    subscribe_to_email_events=form.cleaned_data['subscribe_to_email_events'],
                    user=request.user,
                    pool=form.cleaned_data['pool'],
                )
                url = reverse('admin:notification_taskhistory_changelist')
                # Redirect after POST
                return HttpResponseRedirect(url + "?user=%s" % request.user.username)

            else:
                return super(DatabaseAdmin, self).add_view(request, form_url, extra_context=extra_context)

        except DatabaseAlreadyExists:
            self.message_user(request, _(
                'An inconsistency was found: The database "%s" already exists in infra-structure but not in DBaaS.') %
                request.POST['name'], level=messages.ERROR)

            request.method = 'GET'
            return super(DatabaseAdmin, self).add_view(request, form_url, extra_context=extra_context)
예제 #6
0
    def post(self, request, format=None):
        data = request.DATA
        name = data['name']
        user = data['user']
        team = data['team']
        env = get_url_env(request)

        try:
            description = data['description']
            if not description:
                raise Exception("A description must be provided")
        except Exception as e:
            msg = "A description must be provided."
            return log_and_response(
                msg=msg, http_status=status.HTTP_400_BAD_REQUEST
            )

        name_regexp = re.compile('^[a-z][a-z0-9_]+$')
        if name_regexp.match(name) is None:
            msg = "Your database name must match /^[a-z][a-z0-9_]+$/ ."
            return log_and_response(
                msg=msg, http_status=status.HTTP_400_BAD_REQUEST
            )

        try:
            Database.objects.get(name=name, environment__name=env)
            msg = "There is already a database called {} in {}.".format(
                name, env
            )
            return log_and_response(
                msg=msg, http_status=status.HTTP_400_BAD_REQUEST
            )

        except ObjectDoesNotExist:
            pass

        if database_name_evironment_constraint(name, env):
            msg = "{} already exists in env {}!".format(name, env)
            return log_and_response(
                msg=msg, http_status=status.HTTP_400_BAD_REQUEST
            )

        try:
            dbaas_user = AccountUser.objects.get(email=user)
        except ObjectDoesNotExist as e:
            msg = "User does not exist."
            return log_and_response(
                msg=msg, e=e, http_status=status.HTTP_400_BAD_REQUEST
            )
        except MultipleObjectsReturned as e:
            msg = "There are multiple user for {} email.".format(user)
            return log_and_response(
                msg=msg, e=e, http_status=status.HTTP_500_INTERNAL_SERVER_ERROR
            )

        try:
            dbaas_team = Team.objects.get(name=team)
        except ObjectDoesNotExist as e:
            msg = "Team does not exist."
            return log_and_response(
                msg=msg, e=e, http_status=status.HTTP_400_BAD_REQUEST
            )

        try:
            dbaas_user.team_set.get(name=dbaas_team.name)
        except ObjectDoesNotExist as e:
            msg = "The user is not on {} team.".format(dbaas_team.name)
            return log_and_response(
                msg=msg, e=e, http_status=status.HTTP_400_BAD_REQUEST
            )

        try:
            dbaas_environment = Environment.objects.get(name=env)
        except(ObjectDoesNotExist) as e:
            msg = "Environment does not exist."
            return log_and_response(
                msg=msg, http_status=status.HTTP_400_BAD_REQUEST
            )

        databases_used_by_team = dbaas_team.count_databases_in_use(
            environment=dbaas_environment
        )
        database_alocation_limit = dbaas_team.database_alocation_limit

        if databases_used_by_team >= database_alocation_limit:
            msg = ("The database alocation limit of {} has been exceeded for "
                   "the selected team: {}").format(
                database_alocation_limit, dbaas_team
            )
            return log_and_response(
                msg=msg, http_status=status.HTTP_400_BAD_REQUEST
            )

        if 'plan' not in data:
            msg = "Plan was not found"
            return log_and_response(
                msg=msg, http_status=status.HTTP_400_BAD_REQUEST
            )

        plan = data['plan']
        hard_plans = Plan.objects.values(
            'name', 'description', 'pk', 'environments__name'
        ).extra(
            where=['is_active=True', 'provider={}'.format(Plan.CLOUDSTACK)]
        )
        plans = get_plans_dict(hard_plans)
        plan = [splan for splan in plans if splan['name'] == plan]
        LOG.info("Plan: {}".format(plan))

        if any(plan):
            dbaas_plan = Plan.objects.get(pk=plan[0]['pk'])
        else:
            msg = "Plan was not found"
            return log_and_response(
                msg=msg, http_status=status.HTTP_400_BAD_REQUEST
            )

        if dbaas_environment not in dbaas_plan.environments.all():
            msg = 'Plan "{}" is not available to "{}" environment'.format(
                dbaas_plan, dbaas_environment
            )
            return log_and_response(
                msg=msg, http_status=status.HTTP_400_BAD_REQUEST
            )

        backup_hour, maintenance_hour, maintenance_day = (
            DatabaseForm.randomize_backup_and_maintenance_hour()
        )
        TaskRegister.database_create(
            name=name, plan=dbaas_plan, environment=dbaas_environment,
            team=dbaas_team, project=None, description=description,
            user=dbaas_user, is_protected=True, backup_hour=backup_hour,
            maintenance_window=maintenance_hour,
            maintenance_day=maintenance_day
        )

        return Response(status=status.HTTP_201_CREATED)