diff --git a/cmd/harbor/root/schedule/cmd.go b/cmd/harbor/root/schedule/cmd.go index b0e4bb976..c304e4a86 100644 --- a/cmd/harbor/root/schedule/cmd.go +++ b/cmd/harbor/root/schedule/cmd.go @@ -24,6 +24,8 @@ func Schedule() *cobra.Command { } cmd.AddCommand( ListScheduleCommand(), + CreateScheduleCommand(), + DeleteScheduleCommand(), ) return cmd diff --git a/cmd/harbor/root/schedule/create.go b/cmd/harbor/root/schedule/create.go new file mode 100644 index 000000000..b3168e9f5 --- /dev/null +++ b/cmd/harbor/root/schedule/create.go @@ -0,0 +1,53 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package schedule + +import ( + "fmt" + + "github.com/goharbor/harbor-cli/pkg/api" + "github.com/spf13/cobra" +) + +func CreateScheduleCommand() *cobra.Command { + var jobType string + var cronString string + + cmd := &cobra.Command{ + Use: "create", + Short: "Create a schedule job (e.g. gc, scan-all)", + RunE: func(cmd *cobra.Command, args []string) error { + if jobType == "" { + return fmt.Errorf("--type flag is required") + } + if cronString == "" { + return fmt.Errorf("--cron flag is required") + } + + err := api.CreateSchedule(jobType, cronString) + if err != nil { + return fmt.Errorf("failed to create %s schedule: %v", jobType, err) + } + + fmt.Printf("Successfully created schedule for %s with cron: %s\n", jobType, cronString) + return nil + }, + } + + cmd.Flags().StringVar(&jobType, "type", "", "Type of job (gc, scan-all)") + cmd.Flags().StringVar(&cronString, "cron", "", "Cron string for the schedule (e.g. '0 0 * * *')") + + return cmd +} diff --git a/cmd/harbor/root/schedule/delete.go b/cmd/harbor/root/schedule/delete.go new file mode 100644 index 000000000..b10741141 --- /dev/null +++ b/cmd/harbor/root/schedule/delete.go @@ -0,0 +1,48 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package schedule + +import ( + "fmt" + + "github.com/goharbor/harbor-cli/pkg/api" + "github.com/spf13/cobra" +) + +func DeleteScheduleCommand() *cobra.Command { + var jobType string + + cmd := &cobra.Command{ + Use: "delete", + Short: "Delete a schedule job (e.g. gc, scan-all)", + RunE: func(cmd *cobra.Command, args []string) error { + if jobType == "" { + return fmt.Errorf("--type flag is required") + } + + err := api.DeleteSchedule(jobType) + if err != nil { + return fmt.Errorf("failed to delete %s schedule: %v", jobType, err) + } + + fmt.Printf("Successfully deleted schedule for %s\n", jobType) + return nil + }, + } + + cmd.Flags().StringVar(&jobType, "type", "", "Type of job to delete schedule for (gc, scan-all)") + + return cmd +} diff --git a/pkg/api/schedule_handler.go b/pkg/api/schedule_handler.go index 94841d2ad..eff139c41 100644 --- a/pkg/api/schedule_handler.go +++ b/pkg/api/schedule_handler.go @@ -14,10 +14,80 @@ package api import ( + "fmt" + + "github.com/goharbor/go-client/pkg/sdk/v2.0/client/gc" + "github.com/goharbor/go-client/pkg/sdk/v2.0/client/scan_all" "github.com/goharbor/go-client/pkg/sdk/v2.0/client/schedule" + "github.com/goharbor/go-client/pkg/sdk/v2.0/models" "github.com/goharbor/harbor-cli/pkg/utils" ) +// CreateSchedule acts as a smart router, sending the schedule to the correct Harbor API +func CreateSchedule(jobType string, cronString string) error { + ctx, client, err := utils.ContextWithClient() + if err != nil { + return err + } + + // Build the generic schedule payload + schedulePayload := &models.Schedule{ + Parameters: map[string]interface{}{ + "delete_untagged": false, + }, + Schedule: &models.ScheduleObj{ + Type: "Custom", + Cron: cronString, + }, + } + + // Route to the correct API based on the type + switch jobType { + case "gc": + _, err = client.GC.UpdateGCSchedule(ctx, &gc.UpdateGCScheduleParams{ + Schedule: schedulePayload, + }) + case "scan-all": + _, err = client.ScanAll.UpdateScanAllSchedule(ctx, &scan_all.UpdateScanAllScheduleParams{ + Schedule: schedulePayload, + }) + default: + return fmt.Errorf("unsupported schedule type: %s. Supported types are: gc, scan-all", jobType) + } + + return err +} + +// DeleteSchedule acts as a smart router to delete a schedule +func DeleteSchedule(jobType string) error { + ctx, client, err := utils.ContextWithClient() + if err != nil { + return err + } + + // To delete a schedule in Harbor, we send a PUT request with Type "None" + schedulePayload := &models.Schedule{ + Schedule: &models.ScheduleObj{ + Type: "None", + }, + } + + switch jobType { + case "gc": + _, err = client.GC.UpdateGCSchedule(ctx, &gc.UpdateGCScheduleParams{ + Schedule: schedulePayload, + }) + case "scan-all": + _, err = client.ScanAll.UpdateScanAllSchedule(ctx, &scan_all.UpdateScanAllScheduleParams{ + Schedule: schedulePayload, + }) + default: + return fmt.Errorf("unsupported schedule type: %s. Supported types are: gc, scan-all", jobType) + } + + return err +} + func ListSchedule(opts ...ListFlags) (schedule.ListSchedulesOK, error) { ctx, client, err := utils.ContextWithClient() if err != nil {