Skip to content

Commit

Permalink
Add argo yaml validate command and argoexec artifacts load stub
Browse files Browse the repository at this point in the history
  • Loading branch information
jessesuen committed Oct 23, 2017
1 parent 9125058 commit 1fc079d
Show file tree
Hide file tree
Showing 11 changed files with 229 additions and 30 deletions.
3 changes: 2 additions & 1 deletion api/workflow/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ import (

// CRD constants
const (
CRDKind string = "Workflow"
CRDSingular string = "workflow"
CRDPlural string = "workflows"
CRDShortName string = "wf"
CRDGroup string = "argoproj.io"
CRDVersion string = "v1"
FullCRDName string = CRDPlural + "." + CRDGroup
CRDFullName string = CRDPlural + "." + CRDGroup
)

// Workflow types
Expand Down
110 changes: 110 additions & 0 deletions cmd/argo/commands/yaml.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package commands

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"

wfv1 "github.com/argoproj/argo/api/workflow/v1"
"github.com/argoproj/argo/errors"
cmdutil "github.com/argoproj/argo/util/cmd"
"github.com/ghodss/yaml"
"github.com/spf13/cobra"
)

// CLI options
var (
yamlValidateArgs yamlValidateFlags
)

type yamlValidateFlags struct {
failFast bool
strict bool
}

func init() {
RootCmd.AddCommand(yamlCmd)
yamlCmd.AddCommand(yamlValidateCmd)
yamlValidateCmd.Flags().BoolVar(&yamlValidateArgs.failFast, "failfast", true, "Stop upon first validation error")
yamlValidateCmd.Flags().BoolVar(&yamlValidateArgs.strict, "strict", true, "Do not accept unknown keys during validation")
}

var yamlCmd = &cobra.Command{
Use: "yaml",
Short: "YAML commands",
Run: func(cmd *cobra.Command, args []string) {
cmd.HelpFunc()(cmd, args)
},
}

var yamlValidateCmd = &cobra.Command{
Use: "validate (DIRECTORY | FILE1 FILE2 FILE3...)",
Short: "Validate a directory containing Workflow YAML files, or a list of multiple Workflow YAML files",
Run: validateYAML,
}

func validateYAML(cmd *cobra.Command, args []string) {
if len(args) == 0 {
cmd.HelpFunc()(cmd, args)
os.Exit(1)
}
validateDir := cmdutil.MustIsDir(args[0])
var err error
if validateDir {
if len(args) > 1 {
fmt.Printf("Validation of a single directory supported")
os.Exit(1)
}
fmt.Printf("Verifying all yaml files in directory: %s\n", args[0])
err = validateYAMLDir(args[0])
} else {
yamlFiles := make([]string, 0)
for _, filePath := range args {
if cmdutil.MustIsDir(filePath) {
fmt.Printf("Validate against a list of files or a single directory, not both")
os.Exit(1)
}
yamlFiles = append(yamlFiles, filePath)
}
for _, yamlFile := range yamlFiles {
err = vaildateYAMLFile(yamlFile)
if err != nil {
break
}
}
}
if err != nil {
fmt.Printf("YAML validation failed: %v\n", err)
os.Exit(1)
}
fmt.Printf("YAML validated\n")
os.Exit(0)
}

func validateYAMLDir(dirPath string) error {
walkFunc := func(path string, info os.FileInfo, err error) error {
if info == nil || info.IsDir() {
return nil
}
fileExt := filepath.Ext(info.Name())
if fileExt != ".yaml" && fileExt != ".yml" {
return nil
}
return vaildateYAMLFile(path)
}
return filepath.Walk(dirPath, walkFunc)
}

func vaildateYAMLFile(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)
}
var wf wfv1.Workflow
err = yaml.Unmarshal(body, &wf)
if err != nil {
return errors.Errorf(errors.CodeBadRequest, "Failed to parse %s: %v", filePath, err)
}
return nil
}
28 changes: 28 additions & 0 deletions cmd/argoexec/commands/artifacts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package commands

import (
"github.com/spf13/cobra"
)

func init() {
RootCmd.AddCommand(artifactsCmd)
artifactsCmd.AddCommand(artifactsLoadCmd)
}

var artifactsCmd = &cobra.Command{
Use: "artifacts",
Short: "Artifacts commands",
Run: func(cmd *cobra.Command, args []string) {
cmd.HelpFunc()(cmd, args)
},
}

var artifactsLoadCmd = &cobra.Command{
Use: "load ARTIFACTS_JSON",
Short: "Load artifacts according to a json specification",
Run: loadArtifacts,
}

func loadArtifacts(cmd *cobra.Command, args []string) {

}
24 changes: 24 additions & 0 deletions cmd/argoexec/commands/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package commands

import (
"github.com/argoproj/argo/util/cmd"
"github.com/spf13/cobra"
)

const (
// CLIName is the name of the CLI
CLIName = "argoexec"
)

func init() {
RootCmd.AddCommand(cmd.NewVersionCmd(CLIName))
}

// RootCmd is the argo root level command
var RootCmd = &cobra.Command{
Use: CLIName,
Short: "argoexec is executor sidekick to workflow containers",
Run: func(cmd *cobra.Command, args []string) {
cmd.HelpFunc()(cmd, args)
},
}
23 changes: 2 additions & 21 deletions cmd/argoexec/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,11 @@ import (
"fmt"
"os"

"github.com/argoproj/argo/util/cmd"
"github.com/spf13/cobra"
"github.com/argoproj/argo/cmd/argoexec/commands"
)

const (
// CLIName is the name of the CLI
CLIName = "argoexec"
)

// RootCmd is the root level command
var RootCmd = &cobra.Command{
Use: CLIName,
Short: "Argo Executor",
Run: func(cmd *cobra.Command, args []string) {
cmd.HelpFunc()(cmd, args)
},
}

func init() {
RootCmd.AddCommand(cmd.NewVersionCmd(CLIName))
}

func main() {
if err := RootCmd.Execute(); err != nil {
if err := commands.RootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
Expand Down
12 changes: 12 additions & 0 deletions examples/hello-world.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: argoproj.io/v1
kind: Workflow
metadata:
generateName: argo-wf-
spec:
entrypoint: hello-world
templates:
- name: hello-world
type: container
image: alpine:latest
command: [sh, -c]
args: ["echo 'hello world'"]
32 changes: 32 additions & 0 deletions examples/workflow-artifacts.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
apiVersion: argoproj.io/v1
kind: Workflow
metadata:
generateName: argo-wf-
spec:
entrypoint: artifact-example
templates:
- name: artifact-example
type: workflow
steps:
- COWSAY:
template: cowsay
- PRINT:
template: print-message
- name: cowsay
type: container
image: docker/whalesay:latest
command: [sh, -c]
args: ["cowsay hello world | tee /tmp/hello_world.txt"]
outputs:
artifacts:
MESSAGE:
path: /tmp/hello_world.txt
- name: print-message
type: container
inputs:
artifacts:
MESSAGE:
path: /tmp/message
image: alpine:latest
command: [cat]
args: [/tmp/message]
11 changes: 11 additions & 0 deletions util/cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package cmd

import (
"fmt"
"os"

"github.com/argoproj/argo"
"github.com/spf13/cobra"
Expand All @@ -19,3 +20,13 @@ func NewVersionCmd(cliName string) *cobra.Command {
},
}
}

// MustIsDir returns whether or not the given filePath is a directory. Exits if path does not exist
func MustIsDir(filePath string) bool {
fileInfo, err := os.Stat(filePath)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
return fileInfo.IsDir()
}
3 changes: 2 additions & 1 deletion version.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var (
Branch = "unknown"
Tag = ""
BuildDate = "unknown"
FullVersion = fmt.Sprintf("%s-%s", Version, Revision)
ShortRevision = Revision[0:7]
FullVersion = fmt.Sprintf("%s-%s", Version, ShortRevision)
DisplayVersion = fmt.Sprintf("%s (Build Date: %s)", FullVersion, BuildDate)
)
9 changes: 4 additions & 5 deletions workflow/client/cr.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package client

import (
"fmt"
"reflect"
"time"

wfv1 "github.com/argoproj/argo/api/workflow/v1"
Expand All @@ -19,15 +18,15 @@ func CreateCustomResourceDefinition(clientset apiextensionsclient.Interface) (*a
fmt.Printf("Creating Workflow CRD\n")
crd := &apiextensionsv1beta1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{
Name: wfv1.FullCRDName,
Name: wfv1.CRDFullName,
},
Spec: apiextensionsv1beta1.CustomResourceDefinitionSpec{
Group: wfv1.CRDGroup,
Version: wfv1.SchemeGroupVersion.Version,
Scope: apiextensionsv1beta1.NamespaceScoped,
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
Plural: wfv1.CRDPlural,
Kind: reflect.TypeOf(wfv1.Workflow{}).Name(),
Kind: wfv1.CRDKind,
ShortNames: []string{wfv1.CRDShortName},
},
},
Expand All @@ -40,7 +39,7 @@ func CreateCustomResourceDefinition(clientset apiextensionsclient.Interface) (*a

// wait for CRD being established
err = wait.Poll(500*time.Millisecond, 60*time.Second, func() (bool, error) {
crd, err = clientset.Apiextensions().CustomResourceDefinitions().Get(wfv1.FullCRDName, metav1.GetOptions{})
crd, err = clientset.Apiextensions().CustomResourceDefinitions().Get(wfv1.CRDFullName, metav1.GetOptions{})
if err != nil {
return false, err
}
Expand All @@ -59,7 +58,7 @@ func CreateCustomResourceDefinition(clientset apiextensionsclient.Interface) (*a
return false, err
})
if err != nil {
deleteErr := clientset.ApiextensionsV1beta1().CustomResourceDefinitions().Delete(wfv1.FullCRDName, nil)
deleteErr := clientset.ApiextensionsV1beta1().CustomResourceDefinitions().Delete(wfv1.CRDFullName, nil)
if deleteErr != nil {
return nil, errors.NewAggregate([]error{err, deleteErr})
}
Expand Down
4 changes: 2 additions & 2 deletions workflow/controller/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ func (wfc *WorkflowController) createWorkflowContainer(wf *wfv1.Workflow, nodeNa
},
OwnerReferences: []metav1.OwnerReference{
metav1.OwnerReference{
APIVersion: "argoproj.io/v1",
Kind: "Workflow",
APIVersion: wfv1.CRDFullName,
Kind: wfv1.CRDKind,
Name: wf.ObjectMeta.Name,
UID: wf.ObjectMeta.UID,
BlockOwnerDeletion: &t,
Expand Down

0 comments on commit 1fc079d

Please sign in to comment.