Esempio n. 1
0
def database_pre_save(sender, **kwargs):
    database = kwargs.get('instance')
    if database.is_in_quarantine:
        if database.quarantine_dt is None:
            database.quarantine_dt = datetime.datetime.now().date()

        if not database.quarantine_user:
            from dbaas.middleware import UserMiddleware
            database.quarantine_user = UserMiddleware.current_user()
    else:
        database.quarantine_dt = None
        database.quarantine_user = None

    if database.id:
        saved_object = Database.objects.get(id=database.id)
        if database.name != saved_object.name:
            raise AttributeError(_("Attribute name cannot be edited"))
    else:
        # new database
        if database_name_evironment_constraint(database.name,
                                               database.environment.name):
            raise AttributeError(
                _('%s already exists in production!') % database.name)

        LOG.debug("slugfying database's name for %s" % database.name)
        database.name = slugify(database.name)
Esempio n. 2
0
    def clean(self):
        cleaned_data = super(CloneDatabaseForm, self).clean()
        if 'database_clone' in cleaned_data:

            origindatabase = Database.objects.get(
                pk=cleaned_data['origin_database_id'])

            # for infra in DatabaseInfra.objects.filter(environment=origindatabase.environment,plan=origindatabase.plan):
            #    if infra.databases.filter(name=cleaned_data['database_clone']):
            #        self._errors["database_clone"] = self.error_class([_("this name already exists in the selected environment")])

            if len(cleaned_data['database_clone']) > 40:
                self._errors["database_clone"] = self.error_class(
                    [_("Database name too long")])

            dbs = origindatabase.team.databases_in_use_for(
                origindatabase.environment)

            database_alocation_limit = origindatabase.team.database_alocation_limit
            LOG.debug("dbs: %s | type: %s" % (dbs, type(dbs)))
            if (database_alocation_limit != 0
                    and len(dbs) >= database_alocation_limit):
                LOG.warning(
                    "The database alocation limit of %s has been exceeded for the team: %s => %s"
                    %
                    (database_alocation_limit, origindatabase.team, list(dbs)))
                raise forms.ValidationError([
                    _("The database alocation limit of %s has been exceeded for the team:  %s => %s"
                      ) %
                    (database_alocation_limit, origindatabase.team, list(dbs))
                ])

            driver = DriverFactory.get_driver_class(
                origindatabase.plan.engines[0].name)
            if cleaned_data[
                    'database_clone'] in driver.RESERVED_DATABASES_NAME:
                raise forms.ValidationError(
                    _("%s is a reserved database name" %
                      cleaned_data['database_clone']))

            environment = cleaned_data.get('environment', None)
            database_name = cleaned_data.get('database_clone', None)

            if Database.objects.filter(name=database_name,
                                       environment=environment):
                raise forms.ValidationError(
                    _("There is already a database called {} on {}".format(
                        database_name, environment)))

        if database_name_evironment_constraint(database_name,
                                               environment.name):
            raise forms.ValidationError(
                _('%s already exists in production!') % database_name)

            if self._errors:
                return cleaned_data

        return cleaned_data
    def clean(self):
        cleaned_data = super(CloneDatabaseForm, self).clean()
        if 'database_clone' in cleaned_data:

            origindatabase = Database.objects.get(
                pk=cleaned_data['origin_database_id'])

            # for infra in DatabaseInfra.objects.filter(environment=origindatabase.environment,plan=origindatabase.plan):
            #    if infra.databases.filter(name=cleaned_data['database_clone']):
            #        self._errors["database_clone"] = self.error_class([_("this name already exists in the selected environment")])

            if len(cleaned_data['database_clone']) > 40:
                self._errors["database_clone"] = self.error_class(
                    [_("Database name too long")])

            dbs = origindatabase.team.databases_in_use_for(
                origindatabase.environment)

            database_alocation_limit = origindatabase.team.database_alocation_limit
            LOG.debug("dbs: %s | type: %s" % (dbs, type(dbs)))
            if (database_alocation_limit != 0 and len(dbs) >= database_alocation_limit):
                LOG.warning("The database alocation limit of %s has been exceeded for the team: %s => %s" % (
                    database_alocation_limit, origindatabase.team, list(dbs)))
                raise forms.ValidationError([_("The database alocation limit of %s has been exceeded for the team:  %s => %s") % (
                    database_alocation_limit, origindatabase.team, list(dbs))])

            driver = DriverFactory.get_driver_class(
                origindatabase.plan.engines[0].name)
            if cleaned_data['database_clone'] in driver.RESERVED_DATABASES_NAME:
                raise forms.ValidationError(
                    _("%s is a reserved database name" % cleaned_data['database_clone']))

            environment = cleaned_data.get('environment', None)
            database_name = cleaned_data.get('database_clone', None)

            if Database.objects.filter(name=database_name,
                                       environment=environment):
                raise forms.ValidationError(
                    _("There is already a database called {} on {}".format(database_name,
                                                                           environment)))

        if database_name_evironment_constraint(database_name, environment.name):
            raise forms.ValidationError(
                _('%s already exists in production!') % database_name
            )

            if self._errors:
                return cleaned_data

        return cleaned_data
Esempio n. 4
0
    def clean(self):
        cleaned_data = super(DatabaseForm, self).clean()

        # if there is an instance, that means that we are in a edit page and therefore
        # it should return the default cleaned_data
        if self.instance and self.instance.id:
            self._validate_project(cleaned_data)
            self._validate_description(cleaned_data)
            self._validate_contacts(cleaned_data)
            self._validate_team(cleaned_data)
            return cleaned_data

        if not self.is_valid():
            raise forms.ValidationError(self.errors)

        if 'plan' in cleaned_data:
            plan = cleaned_data.get('plan', None)
            if not plan:
                self._errors["plan"] = self.error_class(
                    [_("Plan: This field is required.")])

        self._validate_name(cleaned_data)
        self._validate_project(cleaned_data)
        self._validate_description(cleaned_data)
        self._validate_contacts(cleaned_data)
        self._validate_team(cleaned_data)

        if 'environment' in cleaned_data:
            environment = cleaned_data.get('environment', None)
            database_name = cleaned_data.get('name', None)
            if not environment or environment not in plan.environments.all():
                raise forms.ValidationError(
                    _("Invalid plan for selected environment."))

            if Database.objects.filter(name=database_name,
                                       environment=environment):
                self._errors["name"] = self.error_class(
                    [_("this name already exists in the selected environment")])
                del cleaned_data["name"]

        self._validate_team_resources(cleaned_data)
        if database_name_evironment_constraint(database_name, environment.name):
            raise forms.ValidationError(
                _('%s already exists in production!') % database_name
            )

        if self._errors:
            return cleaned_data

        return cleaned_data
Esempio n. 5
0
def database_pre_save(sender, **kwargs):
    from notification.tasks import TaskRegister

    database = kwargs.get('instance')
    if database.is_in_quarantine:
        if database.quarantine_dt is None:
            database.quarantine_dt = datetime.datetime.now().date()

        if not database.quarantine_user:
            from dbaas.middleware import UserMiddleware
            database.quarantine_user = UserMiddleware.current_user()
    else:
        database.quarantine_dt = None
        database.quarantine_user = None

    if database.id:
        saved_object = Database.objects.get(id=database.id)
        if database.name != saved_object.name:
            raise AttributeError(_("Attribute name cannot be edited"))

        if database.team and saved_object.team:
            if database.team.organization != saved_object.team.organization:
                TaskRegister.update_organization_name_monitoring(
                    database=database,
                    organization_name=database.team.organization.name)
                if saved_object.team.external:
                    TaskRegister.update_database_monitoring(
                        database=database,
                        hostgroup=(saved_object.team.organization
                                   .grafana_hostgroup),
                        action='remove')
                if database.team.external:
                    TaskRegister.update_database_monitoring(
                        database=database,
                        hostgroup=database.team.organization.grafana_hostgroup,
                        action='add')

    else:
        # new database
        if database_name_evironment_constraint(
           database.name, database.environment.name):
            raise AttributeError(
                _('%s already exists in production!') % database.name
            )

        LOG.debug("slugfying database's name for %s" % database.name)
        database.name = slugify(database.name)
Esempio n. 6
0
 def _validate_database(self):
     msg = ''
     if DATABASE_NAME_REGEX.match(self.name_param) is None:
         msg = "Your database name must match /^[a-z][a-z0-9_]+$/ ."
     try:
         Database.objects.get(name=self.name_param,
                              environment__name=self.env_param)
         msg = "There is already a database called {} in {}.".format(
             self.name_param, self.env)
     except Database.DoesNotExist:
         pass
     if database_name_evironment_constraint(self.name_param, self.env):
         msg = "{} already exists in env {}!".format(
             self.name_param, self.env_param)
     if msg:
         return log_and_response(msg=msg,
                                 http_status=status.HTTP_400_BAD_REQUEST)
Esempio n. 7
0
def database_pre_save(sender, **kwargs):
    from notification.tasks import TaskRegister

    database = kwargs.get('instance')
    if database.is_in_quarantine:
        if database.quarantine_dt is None:
            database.quarantine_dt = datetime.datetime.now().date()

        if not database.quarantine_user:
            from dbaas.middleware import UserMiddleware
            database.quarantine_user = UserMiddleware.current_user()
    else:
        database.quarantine_dt = None
        database.quarantine_user = None

    if database.id:
        saved_object = Database.objects.get(id=database.id)
        if database.name != saved_object.name:
            raise AttributeError(_("Attribute name cannot be edited"))

        if database.team and saved_object.team:
            if database.team.organization != saved_object.team.organization:
                TaskRegister.update_organization_name_monitoring(
                    database=database,
                    organization_name=database.team.organization.name)
                if saved_object.team.external:
                    TaskRegister.update_database_monitoring(
                        database=database,
                        hostgroup=saved_object.team.organization.grafana_hostgroup,
                        action='remove')
                if database.team.external:
                    TaskRegister.update_database_monitoring(
                        database=database,
                        hostgroup=database.team.organization.grafana_hostgroup,
                        action='add')

    else:
        # new database
        if database_name_evironment_constraint(
           database.name, database.environment.name):
            raise AttributeError(
                _('%s already exists in production!') % database.name
            )

        LOG.debug("slugfying database's name for %s" % database.name)
        database.name = slugify(database.name)
Esempio n. 8
0
    def clean(self):
        cleaned_data = super(DatabaseForm, self).clean()

        if not self.is_valid():
            raise forms.ValidationError(self.errors)

        if 'plan' in cleaned_data:
            plan = cleaned_data.get('plan', None)
            if not plan:
                self._errors["plan"] = self.error_class(
                    [_("Plan: This field is required.")])

        self._validate_name(cleaned_data)
        self._validate_project(cleaned_data)
        self._validate_description(cleaned_data)
        self._validate_team(cleaned_data)
        self._validate_backup_hour(cleaned_data)
        self._validate_pool(cleaned_data)

        if 'environment' in cleaned_data:
            environment = cleaned_data.get('environment', None)
            database_name = cleaned_data.get('name', None)
            if not environment or environment not in plan.environments.all():
                raise forms.ValidationError(
                    _("Invalid plan for selected environment."))

            if Database.objects.filter(name=database_name,
                                       environment__name=environment):
                self._errors["name"] = self.error_class([
                    _(("this name already exists in the selected "
                       "environment"))
                ])
                del cleaned_data["name"]

        self._validate_team_resources(cleaned_data)
        if database_name_evironment_constraint(database_name,
                                               environment.name):
            raise forms.ValidationError(
                _('%s already exists in production!') % database_name)

        if self._errors:
            return cleaned_data

        return cleaned_data
def database_pre_save(sender, **kwargs):
    database = kwargs.get('instance')
    if database.is_in_quarantine:
        if database.quarantine_dt is None:
            database.quarantine_dt = datetime.datetime.now().date()
    else:
        database.quarantine_dt = None

    if database.id:
        saved_object = Database.objects.get(id=database.id)
        if database.name != saved_object.name:
            raise AttributeError(_("Attribute name cannot be edited"))
    else:
        # new database
        if database_name_evironment_constraint(
           database.name, database.environment.name):
            raise AttributeError(
                _('%s already exists in production!') % database.name
            )

        LOG.debug("slugfying database's name for %s" % database.name)
        database.name = slugify(database.name)
Esempio n. 10
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_500_INTERNAL_SERVER_ERROR)

        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_500_INTERNAL_SERVER_ERROR)

        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_500_INTERNAL_SERVER_ERROR)

        except ObjectDoesNotExist:
            pass

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

        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_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_500_INTERNAL_SERVER_ERROR)

        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_500_INTERNAL_SERVER_ERROR)

        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_500_INTERNAL_SERVER_ERROR)

        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_500_INTERNAL_SERVER_ERROR)

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

        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_500_INTERNAL_SERVER_ERROR)

        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)

        task_history = TaskHistory()
        task_history.task_name = "create_database"
        task_history.arguments = "Database name: {}".format(name)
        task_history.save()

        create_database.delay(name=name,
                              plan=dbaas_plan,
                              environment=dbaas_environment,
                              team=dbaas_team,
                              project=None,
                              description=description,
                              task_history=task_history,
                              user=dbaas_user,
                              is_protected=True)

        return Response(status=status.HTTP_201_CREATED)
    def clean(self):
        cleaned_data = super(DatabaseForm, self).clean()

        # if there is an instance, that means that we are in a edit page and therefore
        # it should return the default cleaned_data
        if self.instance and self.instance.id:
            return cleaned_data

        # TODO: change model field to blank=False
        if 'team' in cleaned_data:
            team = cleaned_data['team']
            LOG.debug("team: %s" % team)

            if not team:
                LOG.warning("No team specified in database form")
                self._errors["team"] = self.error_class(
                    [_("Team: This field is required.")])

        if not self.is_valid():
            raise forms.ValidationError(self.errors)

        if len(cleaned_data['name']) > 40:
            self._errors["name"] = self.error_class(
                [_("Database name too long")])

        if 'plan' in cleaned_data:
            plan = cleaned_data.get('plan', None)
            if not plan:
                self._errors["plan"] = self.error_class(
                    [_("Plan: This field is required.")])

        if 'project' in cleaned_data:
            project = cleaned_data.get('project', None)
            if not project:
                self._errors["project"] = self.error_class(
                    [_("Project: This field is required.")])

        if 'description' in cleaned_data:
            description = cleaned_data.get('description', None)
            if not description:
                self._errors["description"] = self.error_class(
                    [_("Description: This field is required.")])

        if 'environment' in cleaned_data:
            environment = cleaned_data.get('environment', None)
            database_name = cleaned_data.get('name', None)
            if not environment or environment not in plan.environments.all():
                raise forms.ValidationError(
                    _("Invalid plan for selected environment."))

            if Database.objects.filter(name=database_name,
                                       environment=environment):
                self._errors["name"] = self.error_class(
                    [_("this name already exists in the selected environment")])
                del cleaned_data["name"]

            # validate if the team has available resources
            dbs = team.databases_in_use_for(environment)
            database_alocation_limit = team.database_alocation_limit
            LOG.debug("dbs: %s | type: %s" % (dbs, type(dbs)))
            if (database_alocation_limit != 0 and len(dbs) >= database_alocation_limit):
                LOG.warning("The database alocation limit of %s has been exceeded for the selected team %s => %s" % (
                    database_alocation_limit, team, list(dbs)))
                self._errors["team"] = self.error_class(
                    [_("The database alocation limit of %s has been exceeded for the selected team: %s") % (database_alocation_limit, list(dbs))])

        driver = DriverFactory.get_driver_class(plan.engines[0].name)
        if 'name' in cleaned_data and cleaned_data['name'] in driver.RESERVED_DATABASES_NAME:
            raise forms.ValidationError(
                _("%s is a reserved database name" % cleaned_data['name']))

        if database_name_evironment_constraint(database_name, environment.name):
            raise forms.ValidationError(
                _('%s already exists in production!') % database_name
            )

        if self._errors:
            return cleaned_data

        return cleaned_data
Esempio n. 12
0
    def post(self, request, format=None):
        data = request.DATA
        name = data['name']
        user = data['user']
        team = data['team']
        env = get_url_env(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_500_INTERNAL_SERVER_ERROR)

        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_500_INTERNAL_SERVER_ERROR)

        except ObjectDoesNotExist:
            pass

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

        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_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_500_INTERNAL_SERVER_ERROR)

        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_500_INTERNAL_SERVER_ERROR)

        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_500_INTERNAL_SERVER_ERROR)

        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_500_INTERNAL_SERVER_ERROR)

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

        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_500_INTERNAL_SERVER_ERROR)

        task_history = TaskHistory()
        task_history.task_name = "create_database"
        task_history.arguments = "Database name: {}".format(name)
        task_history.save()

        create_database.delay(name=name, plan=dbaas_plan,
                              environment=dbaas_environment, team=dbaas_team,
                              project=None, description='Database from Tsuru',
                              task_history=task_history, user=dbaas_user)

        return Response(status=status.HTTP_201_CREATED,)