Skip to content

Commit

Permalink
Proper workflow manifest validation during argo lint and argo submit
Browse files Browse the repository at this point in the history
  • Loading branch information
jessesuen committed Nov 15, 2017
1 parent 6ab0b61 commit dec9789
Show file tree
Hide file tree
Showing 11 changed files with 478 additions and 21 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ vendor/
dist/
# delve debug binaries
cmd/**/debug
debug.test
12 changes: 6 additions & 6 deletions api/workflow/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ var SchemeGroupVersion = schema.GroupVersion{Group: CRDGroup, Version: CRDVersio

// Workflow is the definition of our CRD Workflow class
type Workflow struct {
metav1.TypeMeta `json:",inline"`
metav1.TypeMeta `json:",inline,squash"`
metav1.ObjectMeta `json:"metadata"`
Spec WorkflowSpec `json:"spec"`
Status WorkflowStatus `json:"status"`
}

type WorkflowList struct {
metav1.TypeMeta `json:",inline"`
metav1.TypeMeta `json:",inline,squash"`
metav1.ListMeta `json:"metadata"`
Items []Workflow `json:"items"`
}
Expand Down Expand Up @@ -109,7 +109,7 @@ type Artifact struct {
// From allows an artifact to reference an artifact from a previous step
From string `json:"from,omitempty"`

ArtifactLocation `json:",inline"`
ArtifactLocation `json:",inline,squash"`
}

// ArtifactLocation describes a location for a single or multiple artifacts.
Expand Down Expand Up @@ -150,9 +150,9 @@ type Arguments struct {

// Sidecar is a container which runs alongside the main container
type Sidecar struct {
apiv1.Container `json:",inline"`
apiv1.Container `json:",inline,squash"`

SidecarOptions `json:",inline"`
SidecarOptions `json:",inline,squash"`
}

// SidecarOptions provide a way to customize the behavior of a sidecar and how it
Expand Down Expand Up @@ -215,7 +215,7 @@ type S3Bucket struct {
}

type S3Artifact struct {
S3Bucket `json:",inline"`
S3Bucket `json:",inline,squash"`
Key string `json:"key"`
}

Expand Down
19 changes: 17 additions & 2 deletions cmd/argo/commands/lint.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
wfv1 "github.com/argoproj/argo/api/workflow/v1"
"github.com/argoproj/argo/errors"
cmdutil "github.com/argoproj/argo/util/cmd"
"github.com/argoproj/argo/workflow/common"
"github.com/ghodss/yaml"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -54,7 +55,7 @@ func lintYAML(cmd *cobra.Command, args []string) {
}
}
if err != nil {
fmt.Printf("YAML validation failed: %v\n", err)
fmt.Printf("%v\n", err)
os.Exit(1)
}
fmt.Printf("YAML validated\n")
Expand All @@ -78,12 +79,26 @@ func lintYAMLDir(dirPath string) error {
func lintYAMLFile(filePath string) error {
body, err := ioutil.ReadFile(filePath)
if err != nil {
return errors.Errorf(errors.CodeBadRequest, "Can't read from file: %s, err: %v\n", filePath, err)
return errors.Errorf(errors.CodeBadRequest, "Can't read from file: %s, err: %v", filePath, err)
}
var wf wfv1.Workflow
err = yaml.Unmarshal(body, &wf)
if wf.Kind != "" && wf.Kind != wfv1.CRDKind {
return nil
}
if err != nil {
return errors.Errorf(errors.CodeBadRequest, "Failed to parse %s: %v", filePath, err)
}
err = common.ValidateWorkflow(&wf)
if err != nil {
argoErr, ok := err.(errors.ArgoError)
var errMsg string
if ok {
errMsg = argoErr.Message()
} else {
errMsg = err.Error()
}
return errors.Errorf(errors.CodeBadRequest, "%s: %s", filePath, errMsg)
}
return nil
}
7 changes: 6 additions & 1 deletion cmd/argo/commands/submit.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"

wfv1 "github.com/argoproj/argo/api/workflow/v1"
"github.com/argoproj/argo/workflow/common"
"github.com/ghodss/yaml"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -45,7 +46,11 @@ func submitWorkflows(cmd *cobra.Command, args []string) {
var wf wfv1.Workflow
err = yaml.Unmarshal([]byte(manifestStr), &wf)
if err != nil {
log.Fatalf("Workflow manifest %s failed validation: %v\n%s", filePath, err, manifestStr)
log.Fatalf("Workflow manifest %s failed to parse: %v\n%s", filePath, err, manifestStr)
}
err = common.ValidateWorkflow(&wf)
if err != nil {
log.Fatalf("Workflow manifest %s failed validation: %v", filePath, err)
}
created, err := wfClient.CreateWorkflow(&wf)
if err != nil {
Expand Down
5 changes: 5 additions & 0 deletions errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const (
type ArgoError interface {
Error() string
Code() string
Message() string
JSON() []byte
StackTrace() errors.StackTrace
Format(s fmt.State, verb rune)
Expand Down Expand Up @@ -112,6 +113,10 @@ func (e argoerr) Code() string {
return e.code
}

func (e argoerr) Message() string {
return e.message
}

func (e argoerr) StackTrace() errors.StackTrace {
return e.stracer.StackTrace()
}
Expand Down
2 changes: 1 addition & 1 deletion examples/input-artifact-git.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ spec:
path: /src
git:
repo: https://github.com/argoproj/argo.git
revision: "2.0"
revision: "master"
container:
image: golang:1.8
command: [sh, -c]
Expand Down
Loading

0 comments on commit dec9789

Please sign in to comment.