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