Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(schedule_service): implement UpdateBackupSchedule #81

Merged
merged 1 commit into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions cmd/integration/make_backup/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,44 @@ func main() {
if schedules.Schedules[0].Id != schedule.Id {
log.Panicf("schedule and listed schedule ids does not match: %s, %s", schedules.Schedules[0].Id, schedule.Id)
}

newScheduleName := "schedule-2.0"
newSourcePath := databaseName + "/kv_test"
newSchedule, err := scheduleClient.UpdateBackupSchedule(
context.Background(), &pb.UpdateBackupScheduleRequest{
Id: schedule.Id,
ScheduleName: newScheduleName,
SourcePaths: []string{newSourcePath},
},
)
if err != nil {
log.Panicf("failed to update backup schedule: %v", err)
}
if newSchedule.Id != schedule.Id {
log.Panicf("schedule and updated schedule ids does not match: %s != %s", schedule.Id, newSchedule.Id)
}
if newSchedule.ScheduleName != newScheduleName {
log.Panicf("schedule name does not match: %s != %s", newSchedule.ScheduleName, newScheduleName)
}
schedules, err = scheduleClient.ListBackupSchedules(
context.Background(), &pb.ListBackupSchedulesRequest{
ContainerId: containerID,
DatabaseNameMask: "%",
},
)
if err != nil {
log.Panicf("failed to list backup schedules: %v", err)
}
if len(schedules.Schedules) != 1 {
log.Panicln("unexpected number of schedules")
}
if schedules.Schedules[0].ScheduleName != newScheduleName {
log.Panicf("schedule name does not match: %s != %s", schedules.Schedules[0].ScheduleName, newScheduleName)
}
if len(schedules.Schedules[0].SourcePaths) != 1 {
log.Panicf("unexpected number of source paths: %d", len(schedules.Schedules[0].SourcePaths))
}
if schedules.Schedules[0].SourcePaths[0] != newSourcePath {
log.Panicf("source paths not match: %s != %s", schedules.Schedules[0].ScheduleName, newScheduleName)
}
}
15 changes: 5 additions & 10 deletions internal/connectors/db/yql/queries/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,16 +335,11 @@ func BuildUpdateBackupScheduleQuery(schedule types.BackupSchedule, index int) Wr
d.AddUpdateId(table_types.StringValueFromString(schedule.ID))
d.AddValueParam("$active", table_types.BoolValue(schedule.Active))
d.AddValueParam("$crontab", table_types.StringValueFromString(schedule.ScheduleSettings.SchedulePattern.Crontab))

if len(schedule.SourcePaths) > 0 {
d.AddValueParam("$paths", table_types.StringValueFromString(strings.Join(schedule.SourcePaths, ",")))
}
if len(schedule.SourcePathsToExclude) > 0 {
d.AddValueParam(
"$paths_to_exclude",
table_types.StringValueFromString(strings.Join(schedule.SourcePathsToExclude, ",")),
)
}
d.AddValueParam("$paths", table_types.StringValueFromString(strings.Join(schedule.SourcePaths, ",")))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to somehow verify that for each WithUpdateBackupSchedule call, correct SourcePaths and SourcePathsToExclude are set. It is hard, maybe we need some kind of integration test for schedules, that verifies that non-empty SourcePaths are not overrided by empty strings

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I looked through the code and it seems that it is ok for now, but we need a ticket for adding schedules to integration test

d.AddValueParam(
"$paths_to_exclude",
table_types.StringValueFromString(strings.Join(schedule.SourcePathsToExclude, ",")),
)
if schedule.Name != nil {
d.AddValueParam("$name", table_types.StringValueFromString(*schedule.Name))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,75 @@ func (s *BackupScheduleService) CreateBackupSchedule(
}

func (s *BackupScheduleService) UpdateBackupSchedule(
ctx context.Context, in *pb.UpdateBackupScheduleRequest,
ctx context.Context, request *pb.UpdateBackupScheduleRequest,
) (*pb.BackupSchedule, error) {
ctx = grpcinfo.WithGRPCInfo(ctx)
ctx = xlog.With(ctx, zap.String("BackupScheduleID", in.GetId()))
xlog.Error(ctx, "UpdateBackupSchedule not implemented")
//TODO implement me
return nil, status.Error(codes.Internal, "not implemented")

scheduleID := request.GetId()
ctx = xlog.With(ctx, zap.String("BackupScheduleID", scheduleID))

xlog.Debug(ctx, "UpdateBackupSchedule", zap.Stringer("request", request))

schedules, err := s.driver.SelectBackupSchedulesWithRPOInfo(
ctx, queries.NewReadTableQuery(
queries.WithRawQuery(GetScheduleQuery),
queries.WithParameters(
table.ValueParam("$schedule_id", table_types.StringValueFromString(scheduleID)),
),
),
)

if err != nil {
xlog.Error(ctx, "error getting backup schedule", zap.Error(err))
return nil, status.Error(codes.Internal, "error getting backup schedule")
}
if len(schedules) == 0 {
xlog.Error(ctx, "backup schedule not found")
return nil, status.Error(codes.NotFound, "backup schedule not found")
}

schedule := schedules[0]
ctx = xlog.With(ctx, zap.String("ContainerID", schedule.ContainerID))
// TODO: Need to check access to backup schedule not by container id?
subject, err := auth.CheckAuth(ctx, s.auth, auth.PermissionBackupGet, schedule.ContainerID, "")
if err != nil {
return nil, err
}
ctx = xlog.With(ctx, zap.String("SubjectID", subject))

schedule.SourcePaths = request.SourcePaths
schedule.SourcePathsToExclude = request.SourcePathsToExclude

if len(request.ScheduleName) > 0 {
schedule.Name = &request.ScheduleName
}

if request.ScheduleSettings != nil {
if request.ScheduleSettings.SchedulePattern != nil {
_, err = cronexpr.Parse(request.ScheduleSettings.SchedulePattern.Crontab)
if err != nil {
return nil, status.Error(codes.FailedPrecondition, "failed to parse crontab")
}
}

if request.ScheduleSettings.RecoveryPointObjective != nil && request.ScheduleSettings.RecoveryPointObjective.Seconds == 0 {
return nil, status.Error(codes.FailedPrecondition, "recovery point objective should be greater than 0")
}

schedule.ScheduleSettings = request.ScheduleSettings
}

err = s.driver.ExecuteUpsert(ctx, queries.NewWriteTableQuery().WithUpdateBackupSchedule(*schedule))
if err != nil {
xlog.Error(
ctx, "can't update backup schedule", zap.String("backup schedule", schedule.Proto().String()),
zap.Error(err),
)
return nil, status.Error(codes.Internal, "can't update backup schedule")
}

xlog.Info(ctx, "UpdateBackupSchedule was completed successfully", zap.Stringer("schedule", schedule))
return schedule.Proto(), nil
}

func (s *BackupScheduleService) GetBackupSchedule(
Expand Down
Loading