Skip to content

Commit

Permalink
feat(backup_schedule_service): add limit for number of schedules per …
Browse files Browse the repository at this point in the history
…database (#113)
  • Loading branch information
ulya-sidorina authored Dec 10, 2024
1 parent e14d0d6 commit 93964f2
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 2 deletions.
17 changes: 17 additions & 0 deletions cmd/integration/make_backup/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,23 @@ func main() {
if err != nil {
log.Panicf("failed to create backup schedule: %v", err)
}

// local config has schedules_limit_per_db = 1, so we should not be able to create another schedule for this db
_, err = scheduleClient.CreateBackupSchedule(
context.Background(), &pb.CreateBackupScheduleRequest{
ContainerId: containerID,
DatabaseName: databaseName,
Endpoint: databaseEndpoint,
ScheduleName: "anotherSchedule",
ScheduleSettings: &pb.BackupScheduleSettings{
SchedulePattern: &pb.BackupSchedulePattern{Crontab: "* * * * *"},
},
},
)
if err == nil {
log.Panicf("we've created more schedules than schedules_limit_per_db")
}

schedules, err = scheduleClient.ListBackupSchedules(
context.Background(), &pb.ListBackupSchedulesRequest{
ContainerId: containerID,
Expand Down
2 changes: 1 addition & 1 deletion cmd/ydbcp/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ func main() {
configInstance.ClientConnection.AllowInsecureEndpoint,
).Register(server)
operation.NewOperationService(dbConnector, authProvider).Register(server)
backup_schedule.NewBackupScheduleService(dbConnector, clientConnector, authProvider).Register(server)
backup_schedule.NewBackupScheduleService(dbConnector, clientConnector, authProvider, configInstance).Register(server)
if err := server.Start(ctx, &wg); err != nil {
xlog.Error(ctx, "Error start GRPC server", zap.Error(err))
os.Exit(1)
Expand Down
1 change: 1 addition & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ type Config struct {
Auth AuthConfig `yaml:"auth"`
GRPCServer GRPCServerConfig `yaml:"grpc_server"`
MetricsServer MetricsServerConfig `yaml:"metrics_server"`
SchedulesLimitPerDB int `yaml:"schedules_limit_per_db" default:"10"`
}

var (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"
"ydbcp/internal/auth"
"ydbcp/internal/backup_operations"
"ydbcp/internal/config"
"ydbcp/internal/connectors/client"
"ydbcp/internal/connectors/db"
"ydbcp/internal/connectors/db/yql/queries"
Expand All @@ -32,6 +33,7 @@ type BackupScheduleService struct {
clientConn client.ClientConnector
auth ap.AuthProvider
clock clockwork.Clock
config config.Config
}

func (s *BackupScheduleService) IncApiCallsCounter(methodName string, code codes.Code) {
Expand Down Expand Up @@ -76,6 +78,49 @@ func (s *BackupScheduleService) CreateBackupSchedule(
s.IncApiCallsCounter(methodName, status.Code(err))
return nil, err
}

schedules, err := s.driver.SelectBackupSchedules(
ctx, queries.NewReadTableQuery(
queries.WithTableName("BackupSchedules"),
queries.WithQueryFilters(
queries.QueryFilter{
Field: "container_id",
Values: []table_types.Value{
table_types.StringValueFromString(request.ContainerId),
},
},
queries.QueryFilter{
Field: "database",
Values: []table_types.Value{
table_types.StringValueFromString(request.DatabaseName),
},
},
),
),
)

if err != nil {
xlog.Error(ctx, "error getting backup schedules", zap.Error(err))
s.IncApiCallsCounter(methodName, codes.Internal)
return nil, status.Error(codes.Internal, "error getting backup schedules")
}

if len(schedules)+1 > s.config.SchedulesLimitPerDB {
xlog.Error(ctx, "can't create backup schedule, limit exceeded for database",
zap.String("database", request.DatabaseName),
zap.String("container", request.ContainerId),
zap.Int("limit", s.config.SchedulesLimitPerDB),
)
s.IncApiCallsCounter(methodName, codes.FailedPrecondition)
return nil, status.Errorf(
codes.FailedPrecondition,
"can't create backup schedule, limit exceeded for database: %s, container: %s, limit: %d",
request.DatabaseName,
request.ContainerId,
s.config.SchedulesLimitPerDB,
)
}

if request.ScheduleSettings == nil {
xlog.Error(
ctx, "no backup schedule settings for CreateBackupSchedule", zap.String("request", request.String()),
Expand Down Expand Up @@ -525,11 +570,13 @@ func NewBackupScheduleService(
driver db.DBConnector,
clientConn client.ClientConnector,
auth ap.AuthProvider,
config config.Config,
) *BackupScheduleService {
return &BackupScheduleService{
driver: driver,
clientConn: clientConn,
auth: auth,
clock: clockwork.NewRealClock(),
config: config,
}
}
4 changes: 3 additions & 1 deletion local_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ grpc_server:

metrics_server:
bind_address: 127.0.0.1
bind_port: 9090
bind_port: 9090

schedules_limit_per_db: 1

0 comments on commit 93964f2

Please sign in to comment.