forked from argoproj/argo-workflows
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lint.go
127 lines (120 loc) · 4.16 KB
/
lint.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package validate
import (
"io/ioutil"
"os"
"path/filepath"
"github.com/argoproj/pkg/json"
"github.com/argoproj/argo/errors"
"github.com/argoproj/argo/pkg/apis/workflow"
wfv1 "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1"
"github.com/argoproj/argo/workflow/common"
"github.com/argoproj/argo/workflow/templateresolution"
)
// LintWorkflowDir validates all workflow manifests in a directory. Ignores non-workflow manifests
func LintWorkflowDir(wftmplGetter templateresolution.WorkflowTemplateNamespacedGetter, dirPath string, strict bool) error {
walkFunc := func(path string, info os.FileInfo, err error) error {
if info == nil || info.IsDir() {
return nil
}
fileExt := filepath.Ext(info.Name())
switch fileExt {
case ".yaml", ".yml", ".json":
default:
return nil
}
return LintWorkflowFile(wftmplGetter, path, strict)
}
return filepath.Walk(dirPath, walkFunc)
}
// LintWorkflowFile lints a json file, or multiple workflow manifest in a single yaml file. Ignores
// non-workflow manifests
func LintWorkflowFile(wftmplGetter templateresolution.WorkflowTemplateNamespacedGetter, filePath string, strict bool) error {
body, err := ioutil.ReadFile(filePath)
if err != nil {
return errors.Errorf(errors.CodeBadRequest, "Can't read from file: %s, err: %v", filePath, err)
}
var workflows []wfv1.Workflow
if json.IsJSON(body) {
var wf wfv1.Workflow
if strict {
err = json.UnmarshalStrict(body, &wf)
} else {
err = json.Unmarshal(body, &wf)
}
if err == nil {
workflows = []wfv1.Workflow{wf}
} else {
if wf.Kind != "" && wf.Kind != workflow.WorkflowKind {
// If we get here, it was a k8s manifest which was not of type 'Workflow'
// We ignore these since we only care about validating Workflow manifests.
return nil
}
}
} else {
workflows, err = common.SplitWorkflowYAMLFile(body, strict)
}
if err != nil {
return errors.Errorf(errors.CodeBadRequest, "%s failed to parse: %v", filePath, err)
}
for _, wf := range workflows {
err = ValidateWorkflow(wftmplGetter, &wf, ValidateOpts{Lint: true})
if err != nil {
return errors.Errorf(errors.CodeBadRequest, "%s: %s", filePath, err.Error())
}
}
return nil
}
// LintWorkflowTemplateDir validates all workflow manifests in a directory. Ignores non-workflow template manifests
func LintWorkflowTemplateDir(wftmplGetter templateresolution.WorkflowTemplateNamespacedGetter, namespace, dirPath string, strict bool) error {
walkFunc := func(path string, info os.FileInfo, err error) error {
if info == nil || info.IsDir() {
return nil
}
fileExt := filepath.Ext(info.Name())
switch fileExt {
case ".yaml", ".yml", ".json":
default:
return nil
}
return LintWorkflowTemplateFile(wftmplGetter, namespace, path, strict)
}
return filepath.Walk(dirPath, walkFunc)
}
// LintWorkflowTemplateFile lints a json file, or multiple workflow template manifest in a single yaml file. Ignores
// non-workflow template manifests
func LintWorkflowTemplateFile(wftmplGetter templateresolution.WorkflowTemplateNamespacedGetter, namespace, filePath string, strict bool) error {
body, err := ioutil.ReadFile(filePath)
if err != nil {
return errors.Errorf(errors.CodeBadRequest, "Can't read from file: %s, err: %v", filePath, err)
}
var workflowTemplates []wfv1.WorkflowTemplate
if json.IsJSON(body) {
var wftmpl wfv1.WorkflowTemplate
if strict {
err = json.UnmarshalStrict(body, &wftmpl)
} else {
err = json.Unmarshal(body, &wftmpl)
}
if err == nil {
workflowTemplates = []wfv1.WorkflowTemplate{wftmpl}
} else {
if wftmpl.Kind != "" && wftmpl.Kind != workflow.WorkflowTemplateKind {
// If we get here, it was a k8s manifest which was not of type 'Workflow'
// We ignore these since we only care about validating Workflow manifests.
return nil
}
}
} else {
workflowTemplates, err = common.SplitWorkflowTemplateYAMLFile(body, strict)
}
if err != nil {
return errors.Errorf(errors.CodeBadRequest, "%s failed to parse: %v", filePath, err)
}
for _, wftmpl := range workflowTemplates {
err = ValidateWorkflowTemplate(wftmplGetter, &wftmpl)
if err != nil {
return errors.Errorf(errors.CodeBadRequest, "%s: %s", filePath, err.Error())
}
}
return nil
}