diff --git a/cmd/helm/testdata/testcharts/chart-with-schema-negative/values.schema.json b/cmd/helm/testdata/testcharts/chart-with-schema-negative/values.schema.json new file mode 100644 index 000000000..4df89bbe8 --- /dev/null +++ b/cmd/helm/testdata/testcharts/chart-with-schema-negative/values.schema.json @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "addresses": { + "description": "List of addresses", + "items": { + "properties": { + "city": { + "type": "string" + }, + "number": { + "type": "number" + }, + "street": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "age": { + "description": "Age", + "minimum": 0, + "type": "integer" + }, + "employmentInfo": { + "properties": { + "salary": { + "minimum": 0, + "type": "number" + }, + "title": { + "type": "string" + } + }, + "required": [ + "salary" + ], + "type": "object" + }, + "firstname": { + "description": "First name", + "type": "string" + }, + "lastname": { + "type": "string" + }, + "likesCoffee": { + "type": "boolean" + }, + "phoneNumbers": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "firstname", + "lastname", + "addresses", + "employmentInfo" + ], + "title": "Values", + "type": "object" +} diff --git a/cmd/helm/testdata/testcharts/chart-with-schema-negative/values.schema.yaml b/cmd/helm/testdata/testcharts/chart-with-schema-negative/values.schema.yaml deleted file mode 100644 index e33597305..000000000 --- a/cmd/helm/testdata/testcharts/chart-with-schema-negative/values.schema.yaml +++ /dev/null @@ -1,46 +0,0 @@ -$schema: http://json-schema.org/draft-07/schema# -title: Values -type: object -properties: - firstname: - description: First name - type: string - lastname: - type: string - likesCoffee: - type: boolean - age: - description: Age - type: integer - minimum: 0 - employmentInfo: - type: object - properties: - salary: - type: number - minimum: 0 - title: - type: string - required: - - salary - addresses: - description: List of addresses - type: array - items: - type: object - properties: - city: - type: string - street: - type: string - number: - type: number - phoneNumbers: - type: array - items: - type: string -required: - - firstname - - lastname - - addresses - - employmentInfo diff --git a/cmd/helm/testdata/testcharts/chart-with-schema/values.schema.json b/cmd/helm/testdata/testcharts/chart-with-schema/values.schema.json new file mode 100644 index 000000000..4df89bbe8 --- /dev/null +++ b/cmd/helm/testdata/testcharts/chart-with-schema/values.schema.json @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "addresses": { + "description": "List of addresses", + "items": { + "properties": { + "city": { + "type": "string" + }, + "number": { + "type": "number" + }, + "street": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "age": { + "description": "Age", + "minimum": 0, + "type": "integer" + }, + "employmentInfo": { + "properties": { + "salary": { + "minimum": 0, + "type": "number" + }, + "title": { + "type": "string" + } + }, + "required": [ + "salary" + ], + "type": "object" + }, + "firstname": { + "description": "First name", + "type": "string" + }, + "lastname": { + "type": "string" + }, + "likesCoffee": { + "type": "boolean" + }, + "phoneNumbers": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "firstname", + "lastname", + "addresses", + "employmentInfo" + ], + "title": "Values", + "type": "object" +} diff --git a/cmd/helm/testdata/testcharts/chart-with-schema/values.schema.yaml b/cmd/helm/testdata/testcharts/chart-with-schema/values.schema.yaml deleted file mode 100644 index e33597305..000000000 --- a/cmd/helm/testdata/testcharts/chart-with-schema/values.schema.yaml +++ /dev/null @@ -1,46 +0,0 @@ -$schema: http://json-schema.org/draft-07/schema# -title: Values -type: object -properties: - firstname: - description: First name - type: string - lastname: - type: string - likesCoffee: - type: boolean - age: - description: Age - type: integer - minimum: 0 - employmentInfo: - type: object - properties: - salary: - type: number - minimum: 0 - title: - type: string - required: - - salary - addresses: - description: List of addresses - type: array - items: - type: object - properties: - city: - type: string - street: - type: string - number: - type: number - phoneNumbers: - type: array - items: - type: string -required: - - firstname - - lastname - - addresses - - employmentInfo diff --git a/docs/charts.md b/docs/charts.md index c760195b2..b53f78c4a 100644 --- a/docs/charts.md +++ b/docs/charts.md @@ -26,7 +26,7 @@ wordpress/ LICENSE # OPTIONAL: A plain text file containing the license for the chart README.md # OPTIONAL: A human-readable README file values.yaml # The default configuration values for this chart - values.schema.yaml # OPTIONAL: A JSON Schema for imposing a structure on the values.yaml file + values.schema.json # OPTIONAL: A JSON Schema for imposing a structure on the values.yaml file charts/ # A directory containing any charts upon which this chart depends. templates/ # A directory of templates that, when combined with values, # will generate valid Kubernetes manifest files. @@ -767,35 +767,46 @@ Also, global variables of parent charts take precedence over the global variable ### Schema Files Sometimes, a chart maintainer might want to define a structure on their values. -This can be done by defining a schema in the `values.schema.yaml` file. A -schema is the yaml representation of a [JSON Schema](https://json-schema.org/). +This can be done by defining a schema in the `values.schema.json` file. A +schema is represented as a [JSON Schema](https://json-schema.org/). It might look something like this: -```yaml -$schema: http://json-schema.org/draft-07/schema# -title: Values -type: object -properties: - name: - description: Service name - type: string - protocol: - type: string - port: - description: Port - type: integer - minimum: 0 - image: - description: Container Image - type: object - properties: - repo: - type: string - tag: - type: string -required: - - protocol - - port +```json +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "image": { + "description": "Container Image", + "properties": { + "repo": { + "type": "string" + }, + "tag": { + "type": "string" + } + }, + "type": "object" + }, + "name": { + "description": "Service name", + "type": "string" + }, + "port": { + "description": "Port", + "minimum": 0, + "type": "integer" + }, + "protocol": { + "type": "string" + } + }, + "required": [ + "protocol", + "port" + ], + "title": "Values", + "type": "object" +} ``` This schema will be applied to the values to validate it. Validation occurs diff --git a/pkg/chart/loader/load.go b/pkg/chart/loader/load.go index f2c52e530..cd886d8c7 100644 --- a/pkg/chart/loader/load.go +++ b/pkg/chart/loader/load.go @@ -90,7 +90,7 @@ func LoadFiles(files []*BufferedFile) (*chart.Chart, error) { return c, errors.Wrap(err, "cannot load values.yaml") } c.RawValues = f.Data - case f.Name == "values.schema.yaml": + case f.Name == "values.schema.json": c.Schema = f.Data case strings.HasPrefix(f.Name, "templates/"): c.Templates = append(c.Templates, &chart.File{Name: f.Name, Data: f.Data}) diff --git a/pkg/chart/loader/load_test.go b/pkg/chart/loader/load_test.go index 2b5235c7e..c5ee1e5a1 100644 --- a/pkg/chart/loader/load_test.go +++ b/pkg/chart/loader/load_test.go @@ -80,7 +80,7 @@ icon: https://example.com/64x64.png Data: []byte("var: some values"), }, { - Name: "values.schema.yaml", + Name: "values.schema.json", Data: []byte("type: Values"), }, { diff --git a/pkg/chartutil/testdata/test-values.schema.json b/pkg/chartutil/testdata/test-values.schema.json new file mode 100644 index 000000000..4df89bbe8 --- /dev/null +++ b/pkg/chartutil/testdata/test-values.schema.json @@ -0,0 +1,67 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "addresses": { + "description": "List of addresses", + "items": { + "properties": { + "city": { + "type": "string" + }, + "number": { + "type": "number" + }, + "street": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "age": { + "description": "Age", + "minimum": 0, + "type": "integer" + }, + "employmentInfo": { + "properties": { + "salary": { + "minimum": 0, + "type": "number" + }, + "title": { + "type": "string" + } + }, + "required": [ + "salary" + ], + "type": "object" + }, + "firstname": { + "description": "First name", + "type": "string" + }, + "lastname": { + "type": "string" + }, + "likesCoffee": { + "type": "boolean" + }, + "phoneNumbers": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "firstname", + "lastname", + "addresses", + "employmentInfo" + ], + "title": "Values", + "type": "object" +} diff --git a/pkg/chartutil/testdata/test-values.schema.yaml b/pkg/chartutil/testdata/test-values.schema.yaml deleted file mode 100644 index e33597305..000000000 --- a/pkg/chartutil/testdata/test-values.schema.yaml +++ /dev/null @@ -1,46 +0,0 @@ -$schema: http://json-schema.org/draft-07/schema# -title: Values -type: object -properties: - firstname: - description: First name - type: string - lastname: - type: string - likesCoffee: - type: boolean - age: - description: Age - type: integer - minimum: 0 - employmentInfo: - type: object - properties: - salary: - type: number - minimum: 0 - title: - type: string - required: - - salary - addresses: - description: List of addresses - type: array - items: - type: object - properties: - city: - type: string - street: - type: string - number: - type: number - phoneNumbers: - type: array - items: - type: string -required: - - firstname - - lastname - - addresses - - employmentInfo diff --git a/pkg/chartutil/values_test.go b/pkg/chartutil/values_test.go index 4ec1651d2..99289843b 100644 --- a/pkg/chartutil/values_test.go +++ b/pkg/chartutil/values_test.go @@ -166,7 +166,7 @@ func TestValidateAgainstSchema(t *testing.T) { if err != nil { t.Fatalf("Error reading YAML file: %s", err) } - schema, err := ioutil.ReadFile("./testdata/test-values.schema.yaml") + schema, err := ioutil.ReadFile("./testdata/test-values.schema.json") if err != nil { t.Fatalf("Error reading YAML file: %s", err) } @@ -181,7 +181,7 @@ func TestValidateAgainstSchemaNegative(t *testing.T) { if err != nil { t.Fatalf("Error reading YAML file: %s", err) } - schema, err := ioutil.ReadFile("./testdata/test-values.schema.yaml") + schema, err := ioutil.ReadFile("./testdata/test-values.schema.json") if err != nil { t.Fatalf("Error reading YAML file: %s", err) } @@ -480,53 +480,73 @@ chapter: } func TestReadSchema(t *testing.T) { - schemaTest := `# Test YAML parse -$schema: http://json-schema.org/draft-07/schema# -title: Values -type: object -properties: - firstname: - description: First name - type: string - lastname: - type: string - likesCoffee: - type: boolean - age: - description: Age - type: integer - minimum: 0 - employmentInfo: - type: object - properties: - salary: - type: number - minimum: 0 - title: - type: string - required: - - salary - addresses: - description: List of addresses - type: array - items: - type: object - properties: - city: - type: string - street: - type: string - number: - type: number - phoneNumbers: - type: array - items: - type: string -required: - - firstname - - lastname - - addresses - - employmentInfo + schemaTest := `{ + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "addresses": { + "description": "List of addresses", + "items": { + "properties": { + "city": { + "type": "string" + }, + "number": { + "type": "number" + }, + "street": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "age": { + "description": "Age", + "minimum": 0, + "type": "integer" + }, + "employmentInfo": { + "properties": { + "salary": { + "minimum": 0, + "type": "number" + }, + "title": { + "type": "string" + } + }, + "required": [ + "salary" + ], + "type": "object" + }, + "firstname": { + "description": "First name", + "type": "string" + }, + "lastname": { + "type": "string" + }, + "likesCoffee": { + "type": "boolean" + }, + "phoneNumbers": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "firstname", + "lastname", + "addresses", + "employmentInfo" + ], + "title": "Values", + "type": "object" +} ` data, err := ReadValues([]byte(schemaTest)) if err != nil { diff --git a/pkg/lint/rules/values.go b/pkg/lint/rules/values.go index 01de9546d..d8c9f1435 100644 --- a/pkg/lint/rules/values.go +++ b/pkg/lint/rules/values.go @@ -55,7 +55,7 @@ func validateValuesFile(valuesPath string) error { } ext := filepath.Ext(valuesPath) - schemaPath := valuesPath[:len(valuesPath)-len(ext)] + ".schema.yaml" + schemaPath := valuesPath[:len(valuesPath)-len(ext)] + ".schema.json" schema, err := ioutil.ReadFile(schemaPath) if len(schema) == 0 { return nil