Skip to content

Commit 6385db9

Browse files
authored
Merge branch 'master' into bjr-schema-shorthand
2 parents 192b1f1 + f21e689 commit 6385db9

File tree

4 files changed

+91
-17
lines changed

4 files changed

+91
-17
lines changed

docs/index.md

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,23 +87,57 @@ The file fixtures/test_crd.yaml containing a SealedSecret was not validated agai
8787
Helm chart configurations generally have a reference to the source template in a comment
8888
like so:
8989

90-
```
90+
```console
9191
# Source: chart/templates/frontend.yam
9292
```
9393

9494
When kubeval detects these comments it will report the relevant chart template files in
9595
the output.
9696

97-
```
97+
```console
9898
$ kubeval fixtures/multi_valid_source.yaml
9999
The file chart/templates/primary.yaml contains a valid Service
100100
The file chart/templates/primary.yaml contains a valid ReplicationControlle
101101
```
102102

103+
## Configuring Output
103104

104-
## Full usage instructions
105+
The output of `kubeval` can be configured using the `--output` flag (`-o`).
105106

107+
As of today `kubeval` supports the following output types:
108+
109+
- Plaintext `--output=stdout`
110+
- JSON: `--output=json`
111+
112+
### Example Output
113+
114+
#### Plaintext
115+
116+
```console
117+
$ kubeval my-invalid-rc.yaml
118+
The document my-invalid-rc.yaml contains an invalid ReplicationController
119+
--> spec.replicas: Invalid type. Expected: integer, given: string
120+
```
121+
122+
#### JSON
123+
124+
```console
125+
$ kubeval fixtures/invalid.yaml -o json
126+
[
127+
{
128+
"filename": "fixtures/invalid.yaml",
129+
"kind": "ReplicationController",
130+
"status": "invalid",
131+
"errors": [
132+
"spec.replicas: Invalid type. Expected: [integer,null], given: string"
133+
]
134+
}
135+
]
106136
```
137+
138+
## Full usage instructions
139+
140+
```console
107141
$ kubeval --help
108142
Validate a Kubernetes YAML file against the relevant schema
109143

@@ -119,7 +153,8 @@ Flags:
119153
--ignore-missing-schemas Skip validation for resource definitions without a schema
120154
-v, --kubernetes-version string Version of Kubernetes to validate against (default "master")
121155
--openshift Use OpenShift schemas instead of upstream Kubernetes
122-
--schema-location string Base URL used to download schemas. Can also be specified with the environment variable KUBEVAL_SCHEMA_LOCATION (default "https://kubernetesjsonschema.dev")
156+
-o, --output string The format of the output of this script. Options are: [stdout json]
157+
--schema-location string Base URL used to download schemas. Can also be specified with the environment variable KUBEVAL_SCHEMA_LOCATION
123158
--skip-kinds strings Comma-separated list of case-sensitive kinds to skip when validating against schemas
124159
--strict Disallow additional properties not in schema
125160
--version version for kubeval

kubeval/config.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package kubeval
22

3-
import "github.com/spf13/cobra"
3+
import (
4+
"fmt"
5+
6+
"github.com/spf13/cobra"
7+
)
48

59
// DefaultSchemaLocation is the default location to search for schemas
610
const DefaultSchemaLocation = "https://kubernetesjsonschema.dev"
@@ -40,6 +44,10 @@ type Config struct {
4044

4145
// FileName is the name to be displayed when testing manifests read from stdin
4246
FileName string
47+
48+
// OutputFormat is the name of the output formatter which will be used when
49+
// reporting results to the user.
50+
OutputFormat string
4351
}
4452

4553
// NewDefaultConfig creates a Config with default values
@@ -60,5 +68,7 @@ func AddKubevalFlags(cmd *cobra.Command, config *Config) *cobra.Command {
6068
cmd.Flags().StringSliceVar(&config.KindsToSkip, "skip-kinds", []string{}, "Comma-separated list of case-sensitive kinds to skip when validating against schemas")
6169
cmd.Flags().StringVarP(&config.SchemaLocation, "schema-location", "s", "", "Base URL used to download schemas. Can also be specified with the environment variable KUBEVAL_SCHEMA_LOCATION.")
6270
cmd.Flags().StringVarP(&config.KubernetesVersion, "kubernetes-version", "v", "master", "Version of Kubernetes to validate against")
71+
cmd.Flags().StringVarP(&config.OutputFormat, "output", "o", "", fmt.Sprintf("The format of the output of this script. Options are: %v", validOutputs()))
72+
6373
return cmd
6474
}

kubeval/output.go

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,44 @@ import (
1212
// TODO (brendanryan) move these structs to `/log` once we have removed the potential
1313
// circular dependancy between this package and `/log`
1414

15-
// OutputManager controls how results of the `kubeval` evaluation will be recorded
15+
// outputManager controls how results of the `kubeval` evaluation will be recorded
1616
// and reported to the end user.
17-
type OutputManager interface {
17+
// This interface is kept private to ensure all implementations are closed within
18+
// this package.
19+
type outputManager interface {
1820
Put(r ValidationResult) error
1921
Flush() error
2022
}
2123

24+
const (
25+
outputSTD = "stdout"
26+
outputJSON = "json"
27+
)
28+
29+
func validOutputs() []string {
30+
return []string{
31+
outputSTD,
32+
outputJSON,
33+
}
34+
}
35+
36+
func GetOutputManager(outFmt string) outputManager {
37+
switch outFmt {
38+
case outputSTD:
39+
return newSTDOutputManager()
40+
case outputJSON:
41+
return newDefaultJSONOutputManager()
42+
default:
43+
return newSTDOutputManager()
44+
}
45+
}
46+
2247
// STDOutputManager reports `kubeval` results to stdout.
2348
type STDOutputManager struct {
2449
}
2550

26-
// NewSTDOutputManager instantiates a new instance of STDOutputManager.
27-
func NewSTDOutputManager() *STDOutputManager {
51+
// newSTDOutputManager instantiates a new instance of STDOutputManager.
52+
func newSTDOutputManager() *STDOutputManager {
2853
return &STDOutputManager{}
2954
}
3055

@@ -98,7 +123,7 @@ func getStatus(r ValidationResult) status {
98123
return statusValid
99124
}
100125

101-
func (j *jsonOutputManager) put(r ValidationResult) error {
126+
func (j *jsonOutputManager) Put(r ValidationResult) error {
102127
// stringify gojsonschema errors
103128
// use a pre-allocated slice to ensure the json will have an
104129
// empty array in the "zero" case
@@ -117,7 +142,7 @@ func (j *jsonOutputManager) put(r ValidationResult) error {
117142
return nil
118143
}
119144

120-
func (j *jsonOutputManager) flush() error {
145+
func (j *jsonOutputManager) Flush() error {
121146
b, err := json.Marshal(j.data)
122147
if err != nil {
123148
return err

main.go

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ var RootCmd = &cobra.Command{
7272
log.Error(err)
7373
os.Exit(1)
7474
}
75-
success, err = logResults(results, success)
75+
success, err = logResults(config.OutputFormat, results, success)
7676
if err != nil {
7777
log.Error(err)
7878
os.Exit(1)
@@ -105,7 +105,7 @@ var RootCmd = &cobra.Command{
105105
success = false
106106
continue
107107
}
108-
success, err = logResults(results, success)
108+
success, err = logResults(config.OutputFormat, results, success)
109109
if err != nil {
110110
log.Error(err)
111111
os.Exit(1)
@@ -119,10 +119,9 @@ var RootCmd = &cobra.Command{
119119
},
120120
}
121121

122-
func logResults(results []kubeval.ValidationResult, success bool) (bool, error) {
123-
//// fetch output logger based on enviroments params -- for now we only support
124-
//// the stdout logger
125-
out := kubeval.NewSTDOutputManager()
122+
func logResults(outFmt string, results []kubeval.ValidationResult, success bool) (bool, error) {
123+
// fetch output logger based on enviroments params
124+
out := kubeval.GetOutputManager(outFmt)
126125

127126
for _, result := range results {
128127
if len(result.Errors) > 0 {
@@ -134,6 +133,11 @@ func logResults(results []kubeval.ValidationResult, success bool) (bool, error)
134133
}
135134
}
136135

136+
err := out.Flush()
137+
if err != nil {
138+
return false, err
139+
}
140+
137141
return success, nil
138142
}
139143

0 commit comments

Comments
 (0)