Skip to content

Commit

Permalink
feat: Add update command for cron,template,cluster-template. Fixes: a…
Browse files Browse the repository at this point in the history
…rgoproj#5464 argoproj#7344 (argoproj#12803)

Signed-off-by: shuangkun <[email protected]>
Co-authored-by: Simon Behar <[email protected]>
  • Loading branch information
shuangkun and simster7 authored Mar 24, 2024
1 parent bcc483e commit 2e5fb3b
Show file tree
Hide file tree
Showing 25 changed files with 780 additions and 65 deletions.
20 changes: 1 addition & 19 deletions cmd/argo/commands/clustertemplate/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/argoproj/argo-workflows/v3/pkg/apiclient/clusterworkflowtemplate"
wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
"github.com/argoproj/argo-workflows/v3/workflow/common"
"github.com/argoproj/argo-workflows/v3/workflow/util"
)

type cliCreateOpts struct {
Expand Down Expand Up @@ -59,24 +58,7 @@ func createClusterWorkflowTemplates(ctx context.Context, filePaths []string, cli
log.Fatal(err)
}

fileContents, err := util.ReadManifest(filePaths...)
if err != nil {
log.Fatal(err)
}

var clusterWorkflowTemplates []wfv1.ClusterWorkflowTemplate
for _, body := range fileContents {
cwftmpls, err := unmarshalClusterWorkflowTemplates(body, cliOpts.strict)
if err != nil {
log.Fatalf("Failed to parse cluster workflow template: %v", err)
}
clusterWorkflowTemplates = append(clusterWorkflowTemplates, cwftmpls...)
}

if len(clusterWorkflowTemplates) == 0 {
log.Println("No cluster workflow template found in given files")
os.Exit(1)
}
clusterWorkflowTemplates := generateClusterWorkflowTemplates(filePaths, cliOpts.strict)

for _, wftmpl := range clusterWorkflowTemplates {
created, err := serviceClient.CreateClusterWorkflowTemplate(ctx, &clusterworkflowtemplate.ClusterWorkflowTemplateCreateRequest{
Expand Down
1 change: 1 addition & 0 deletions cmd/argo/commands/clustertemplate/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func NewClusterTemplateCommand() *cobra.Command {
command.AddCommand(NewCreateCommand())
command.AddCommand(NewDeleteCommand())
command.AddCommand(NewLintCommand())
command.AddCommand(NewUpdateCommand())

return command
}
75 changes: 75 additions & 0 deletions cmd/argo/commands/clustertemplate/update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package clustertemplate

import (
"context"
"log"
"os"

"github.com/spf13/cobra"

"github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client"
"github.com/argoproj/argo-workflows/v3/pkg/apiclient/clusterworkflowtemplate"
)

type cliUpdateOpts struct {
output string // --output
strict bool // --strict
}

func NewUpdateCommand() *cobra.Command {
var cliUpdateOpts cliUpdateOpts
command := &cobra.Command{
Use: "update FILE1 FILE2...",
Short: "update a cluster workflow template",
Example: `# Update a Cluster Workflow Template:
argo cluster-template update FILE1
# Update a Cluster Workflow Template and print it as YAML:
argo cluster-template update FILE1 --output yaml
# Update a Cluster Workflow Template with relaxed validation:
argo cluster-template update FILE1 --strict false
`,
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
cmd.HelpFunc()(cmd, args)
os.Exit(1)
}

updateClusterWorkflowTemplates(cmd.Context(), args, &cliUpdateOpts)
},
}
command.Flags().StringVarP(&cliUpdateOpts.output, "output", "o", "", "Output format. One of: name|json|yaml|wide")
command.Flags().BoolVar(&cliUpdateOpts.strict, "strict", true, "perform strict workflow validation")
return command
}

func updateClusterWorkflowTemplates(ctx context.Context, filePaths []string, cliOpts *cliUpdateOpts) {
if cliOpts == nil {
cliOpts = &cliUpdateOpts{}
}
ctx, apiClient := client.NewAPIClient(ctx)
serviceClient, err := apiClient.NewClusterWorkflowTemplateServiceClient()
if err != nil {
log.Fatal(err)
}

clusterWorkflowTemplates := generateClusterWorkflowTemplates(filePaths, cliOpts.strict)

for _, wftmpl := range clusterWorkflowTemplates {
current, err := serviceClient.GetClusterWorkflowTemplate(ctx, &clusterworkflowtemplate.ClusterWorkflowTemplateGetRequest{
Name: wftmpl.Name,
})
if err != nil {
log.Fatalf("Failed to get existing cluster workflow template %q to update: %v", wftmpl.Name, err)
}
wftmpl.ResourceVersion = current.ResourceVersion
updated, err := serviceClient.UpdateClusterWorkflowTemplate(ctx, &clusterworkflowtemplate.ClusterWorkflowTemplateUpdateRequest{
Template: &wftmpl,
})
if err != nil {
log.Fatalf("Failed to update cluster workflow template: %s, %v", wftmpl.Name, err)
}
printClusterWorkflowTemplate(updated, cliOpts.output)
}
}
30 changes: 30 additions & 0 deletions cmd/argo/commands/clustertemplate/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package clustertemplate

import (
"log"

wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
"github.com/argoproj/argo-workflows/v3/workflow/util"
)

func generateClusterWorkflowTemplates(filePaths []string, strict bool) []wfv1.ClusterWorkflowTemplate {
fileContents, err := util.ReadManifest(filePaths...)
if err != nil {
log.Fatal(err)
}

var clusterWorkflowTemplates []wfv1.ClusterWorkflowTemplate
for _, body := range fileContents {
cwftmpls, err := unmarshalClusterWorkflowTemplates(body, strict)
if err != nil {
log.Fatalf("Failed to parse cluster workflow template: %v", err)
}
clusterWorkflowTemplates = append(clusterWorkflowTemplates, cwftmpls...)
}

if len(clusterWorkflowTemplates) == 0 {
log.Fatalln("No cluster workflow template found in given files")
}

return clusterWorkflowTemplates
}
29 changes: 2 additions & 27 deletions cmd/argo/commands/cron/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import (
"context"
"fmt"
"log"
"os"

"github.com/argoproj/pkg/errors"
"github.com/argoproj/pkg/json"
"github.com/spf13/cobra"

Expand All @@ -33,15 +31,7 @@ func NewCreateCommand() *cobra.Command {
Use: "create FILE1 FILE2...",
Short: "create a cron workflow",
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
cmd.HelpFunc()(cmd, args)
os.Exit(1)
}

if parametersFile != "" {
err := util.ReadParametersFile(parametersFile, &submitOpts)
errors.CheckError(err)
}
checkArgs(cmd, args, parametersFile, &submitOpts)

CreateCronWorkflows(cmd.Context(), args, &cliCreateOpts, &submitOpts)
},
Expand All @@ -61,24 +51,9 @@ func CreateCronWorkflows(ctx context.Context, filePaths []string, cliOpts *cliCr
log.Fatal(err)
}

fileContents, err := util.ReadManifest(filePaths...)
if err != nil {
log.Fatal(err)
}

var cronWorkflows []wfv1.CronWorkflow
for _, body := range fileContents {
cronWfs := unmarshalCronWorkflows(body, cliOpts.strict)
cronWorkflows = append(cronWorkflows, cronWfs...)
}

if len(cronWorkflows) == 0 {
log.Println("No CronWorkflows found in given files")
os.Exit(1)
}
cronWorkflows := generateCronWorkflows(filePaths, cliOpts.strict)

for _, cronWf := range cronWorkflows {

if cliOpts.schedule != "" {
cronWf.Spec.Schedule = cliOpts.schedule
}
Expand Down
1 change: 1 addition & 0 deletions cmd/argo/commands/cron/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func NewCronWorkflowCommand() *cobra.Command {
command.AddCommand(NewLintCommand())
command.AddCommand(NewSuspendCommand())
command.AddCommand(NewResumeCommand())
command.AddCommand(NewUpdateCommand())

return command
}
87 changes: 87 additions & 0 deletions cmd/argo/commands/cron/update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package cron

import (
"context"
"fmt"
"log"

"github.com/spf13/cobra"

"github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client"
cronworkflowpkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/cronworkflow"
wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
"github.com/argoproj/argo-workflows/v3/workflow/util"
)

type cliUpdateOpts struct {
output string // --output
strict bool // --strict
}

func NewUpdateCommand() *cobra.Command {
var (
cliUpdateOpts cliUpdateOpts
submitOpts wfv1.SubmitOpts
parametersFile string
)
command := &cobra.Command{
Use: "update FILE1 FILE2...",
Short: "update a cron workflow",
Example: `# Update a Cron Workflow Template:
argo cron update FILE1
# Update a Cron Workflow Template and print it as YAML:
argo cron update FILE1 --output yaml
# Update a Cron Workflow Template with relaxed validation:
argo cron update FILE1 --strict false
`,
Run: func(cmd *cobra.Command, args []string) {
checkArgs(cmd, args, parametersFile, &submitOpts)

updateCronWorkflows(cmd.Context(), args, &cliUpdateOpts, &submitOpts)
},
}

util.PopulateSubmitOpts(command, &submitOpts, &parametersFile, false)
command.Flags().StringVarP(&cliUpdateOpts.output, "output", "o", "", "Output format. One of: name|json|yaml|wide")
command.Flags().BoolVar(&cliUpdateOpts.strict, "strict", true, "perform strict workflow validation")
return command
}

func updateCronWorkflows(ctx context.Context, filePaths []string, cliOpts *cliUpdateOpts, submitOpts *wfv1.SubmitOpts) {
ctx, apiClient := client.NewAPIClient(ctx)
serviceClient, err := apiClient.NewCronWorkflowServiceClient()
if err != nil {
log.Fatal(err)
}

cronWorkflows := generateCronWorkflows(filePaths, cliOpts.strict)

for _, cronWf := range cronWorkflows {
newWf := wfv1.Workflow{Spec: cronWf.Spec.WorkflowSpec}
err := util.ApplySubmitOpts(&newWf, submitOpts)
if err != nil {
log.Fatal(err)
}
if cronWf.Namespace == "" {
cronWf.Namespace = client.Namespace()
}
current, err := serviceClient.GetCronWorkflow(ctx, &cronworkflowpkg.GetCronWorkflowRequest{
Name: cronWf.Name,
Namespace: cronWf.Namespace,
})
if err != nil {
log.Fatalf("Failed to get existing cron workflow %q to update: %v", cronWf.Name, err)
}
cronWf.ResourceVersion = current.ResourceVersion
updated, err := serviceClient.UpdateCronWorkflow(ctx, &cronworkflowpkg.UpdateCronWorkflowRequest{
Namespace: cronWf.Namespace,
CronWorkflow: &cronWf,
})
if err != nil {
log.Fatalf("Failed to update workflow template: %v", err)
}
fmt.Print(getCronWorkflowGet(updated))
}
}
38 changes: 38 additions & 0 deletions cmd/argo/commands/cron/util.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package cron

import (
"log"
"os"
"time"

"github.com/argoproj/pkg/errors"
"github.com/spf13/cobra"

"github.com/argoproj/argo-workflows/v3/workflow/util"

"github.com/robfig/cron/v3"

"github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
Expand All @@ -26,3 +33,34 @@ func GetNextRuntime(cwf *v1alpha1.CronWorkflow) (time.Time, error) {

return nextRunTime, nil
}

func generateCronWorkflows(filePaths []string, strict bool) []v1alpha1.CronWorkflow {
fileContents, err := util.ReadManifest(filePaths...)
if err != nil {
log.Fatal(err)
}

var cronWorkflows []v1alpha1.CronWorkflow
for _, body := range fileContents {
cronWfs := unmarshalCronWorkflows(body, strict)
cronWorkflows = append(cronWorkflows, cronWfs...)
}

if len(cronWorkflows) == 0 {
log.Fatalln("No CronWorkflows found in given files")
}

return cronWorkflows
}

func checkArgs(cmd *cobra.Command, args []string, parametersFile string, submitOpts *v1alpha1.SubmitOpts) {
if len(args) == 0 {
cmd.HelpFunc()(cmd, args)
os.Exit(1)
}

if parametersFile != "" {
err := util.ReadParametersFile(parametersFile, submitOpts)
errors.CheckError(err)
}
}
17 changes: 1 addition & 16 deletions cmd/argo/commands/template/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
workflowtemplatepkg "github.com/argoproj/argo-workflows/v3/pkg/apiclient/workflowtemplate"
wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1"
"github.com/argoproj/argo-workflows/v3/workflow/common"
"github.com/argoproj/argo-workflows/v3/workflow/util"
)

type cliCreateOpts struct {
Expand Down Expand Up @@ -49,21 +48,7 @@ func CreateWorkflowTemplates(ctx context.Context, filePaths []string, cliOpts *c
log.Fatal(err)
}

fileContents, err := util.ReadManifest(filePaths...)
if err != nil {
log.Fatal(err)
}

var workflowTemplates []wfv1.WorkflowTemplate
for _, body := range fileContents {
wftmpls := unmarshalWorkflowTemplates(body, cliOpts.strict)
workflowTemplates = append(workflowTemplates, wftmpls...)
}

if len(workflowTemplates) == 0 {
log.Println("No workflow template found in given files")
os.Exit(1)
}
workflowTemplates := generateWorkflowTemplates(filePaths, cliOpts.strict)

for _, wftmpl := range workflowTemplates {
if wftmpl.Namespace == "" {
Expand Down
1 change: 1 addition & 0 deletions cmd/argo/commands/template/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func NewTemplateCommand() *cobra.Command {
command.AddCommand(NewCreateCommand())
command.AddCommand(NewDeleteCommand())
command.AddCommand(NewLintCommand())
command.AddCommand(NewUpdateCommand())

return command
}
Loading

0 comments on commit 2e5fb3b

Please sign in to comment.