diff --git a/cmd/config/internal/commands/source.go b/cmd/config/internal/commands/source.go index 27382bb2f..555e2d660 100644 --- a/cmd/config/internal/commands/source.go +++ b/cmd/config/internal/commands/source.go @@ -71,7 +71,7 @@ func (r *SourceRunner) runE(c *cobra.Command, args []string) error { var inputs []kio.Reader for _, a := range args { - inputs = append(inputs, kio.LocalPackageReader{PackagePath: a}) + inputs = append(inputs, kio.LocalPackageReader{PackagePath: a, IncludeJSON: true}) } if len(inputs) == 0 { inputs = []kio.Reader{&kio.ByteReader{Reader: c.InOrStdin()}} diff --git a/cmd/config/internal/commands/source_test.go b/cmd/config/internal/commands/source_test.go index 141541143..b7f77d2ca 100644 --- a/cmd/config/internal/commands/source_test.go +++ b/cmd/config/internal/commands/source_test.go @@ -21,25 +21,37 @@ func TestSourceCommand(t *testing.T) { } defer os.RemoveAll(d) - err = ioutil.WriteFile(filepath.Join(d, "f1.yaml"), []byte(` -kind: Deployment -metadata: - labels: - app: nginx2 - name: foo - annotations: - app: nginx2 -spec: - replicas: 1 + err = ioutil.WriteFile(filepath.Join(d, "f1.json"), []byte(` +{ + "kind": "Deployment", + "metadata": { + "labels": { + "app": "nginx2" + }, + "name": "foo", + "annotations": { + "app": "nginx2" + } + }, + "spec": { + "replicas": 1 + } +} --- -kind: Service -metadata: - name: foo - annotations: - app: nginx -spec: - selector: - app: nginx +{ + "kind": "Service", + "metadata": { + "name": "foo", + "annotations": { + "app": "nginx" + } + }, + "spec": { + "selector": { + "app": "nginx" + } + } +} `), 0600) if !assert.NoError(t, err) { return @@ -86,22 +98,22 @@ kind: ResourceList items: - kind: Deployment metadata: - labels: - app: nginx2 - name: foo annotations: app: nginx2 config.kubernetes.io/index: '0' - config.kubernetes.io/path: 'f1.yaml' + config.kubernetes.io/path: 'f1.json' + labels: + app: nginx2 + name: foo spec: replicas: 1 - kind: Service metadata: - name: foo annotations: app: nginx config.kubernetes.io/index: '1' - config.kubernetes.io/path: 'f1.yaml' + config.kubernetes.io/path: 'f1.json' + name: foo spec: selector: app: nginx diff --git a/kyaml/kio/byteio_reader.go b/kyaml/kio/byteio_reader.go index 670fb96f5..662f04437 100644 --- a/kyaml/kio/byteio_reader.go +++ b/kyaml/kio/byteio_reader.go @@ -101,6 +101,9 @@ type ByteReader struct { // WrappingKind is set by Read(), and is the kind of the object that // the read objects were originally wrapped in. WrappingKind string + + // JSON indicates if the input file source is json + JSON bool } var _ Reader = &ByteReader{} @@ -119,7 +122,14 @@ func (r *ByteReader) Read() ([]*yaml.RNode, error) { index := 0 for i := range values { - decoder := yaml.NewDecoder(bytes.NewBufferString(values[i])) + value := values[i] + if r.JSON { + value, err = yaml.ConvertJSONToYamlString(value) + if err != nil { + return nil, err + } + } + decoder := yaml.NewDecoder(bytes.NewBufferString(value)) node, err := r.decode(index, decoder) if err == io.EOF { continue diff --git a/kyaml/kio/pkgio_reader.go b/kyaml/kio/pkgio_reader.go index 854c8d392..0392949d6 100644 --- a/kyaml/kio/pkgio_reader.go +++ b/kyaml/kio/pkgio_reader.go @@ -7,6 +7,7 @@ import ( "fmt" "os" "path/filepath" + "strings" "sigs.k8s.io/kustomize/kyaml/errors" "sigs.k8s.io/kustomize/kyaml/kio/kioutil" @@ -162,10 +163,18 @@ type LocalPackageReader struct { // SetAnnotations are annotations to set on the Resources as they are read. SetAnnotations map[string]string `yaml:"setAnnotations,omitempty"` + + // IncludeJSON indicates if the json resources files must be included during read + IncludeJSON bool } var _ Reader = LocalPackageReader{} +const ( + JSONFilePattern = "*.json" + JSONSuffix = ".json" +) + var DefaultMatch = []string{"*.yaml", "*.yml"} // Read reads the Resources. @@ -178,6 +187,9 @@ func (r LocalPackageReader) Read() ([]*yaml.RNode, error) { r.PackagePath = filepath.ToSlash(r.PackagePath) if len(r.MatchFilesGlob) == 0 { r.MatchFilesGlob = DefaultMatch + if r.IncludeJSON { + r.MatchFilesGlob = append(r.MatchFilesGlob, JSONFilePattern) + } } var operand ResourceNodeSlice @@ -243,6 +255,7 @@ func (r *LocalPackageReader) readFile(path string, _ os.FileInfo) ([]*yaml.RNode Reader: f, OmitReaderAnnotations: r.OmitReaderAnnotations, SetAnnotations: r.SetAnnotations, + JSON: strings.HasSuffix(path, JSONSuffix), } return rr.Read() } diff --git a/kyaml/yaml/types.go b/kyaml/yaml/types.go index d74cb8471..bf2e9cacc 100644 --- a/kyaml/yaml/types.go +++ b/kyaml/yaml/types.go @@ -724,22 +724,31 @@ func (rn *RNode) UnmarshalJSON(b []byte) error { // ConvertJSONToYamlNode parses input json string and returns equivalent yaml node func ConvertJSONToYamlNode(jsonStr string) (*RNode, error) { - var body map[string]interface{} - err := json.Unmarshal([]byte(jsonStr), &body) + yml, err := ConvertJSONToYamlString(jsonStr) if err != nil { return nil, err } - yml, err := yaml.Marshal(body) - if err != nil { - return nil, err - } - node, err := Parse(string(yml)) + node, err := Parse(yml) if err != nil { return nil, err } return node, nil } +// ConvertJSONToYamlNode parses input json string and returns equivalent yaml string +func ConvertJSONToYamlString(jsonStr string) (string, error) { + var body map[string]interface{} + err := json.Unmarshal([]byte(jsonStr), &body) + if err != nil { + return "", err + } + yml, err := yaml.Marshal(body) + if err != nil { + return "", err + } + return string(yml), nil +} + // checkKey returns true if all elems have the key func checkKey(key string, elems []*Node) bool { count := 0 diff --git a/kyaml/yaml/types_test.go b/kyaml/yaml/types_test.go index b963d5b28..52c1eb5ea 100644 --- a/kyaml/yaml/types_test.go +++ b/kyaml/yaml/types_test.go @@ -166,3 +166,19 @@ type: string } assert.Equal(t, expected, actual) } + +func TestConvertJSONToYamlString(t *testing.T) { + inputJSON := `{"type": "string", "maxLength": 15, "enum": ["allowedValue1", "allowedValue2"]}` + expected := `enum: + - allowedValue1 + - allowedValue2 +maxLength: 15 +type: string +` + + actual, err := ConvertJSONToYamlString(inputJSON) + if !assert.NoError(t, err) { + t.FailNow() + } + assert.Equal(t, expected, actual) +}