Add schema-path flag to input openAPI for setters

This commit is contained in:
Phani Teja Marupaka
2020-05-16 18:36:05 -07:00
parent 2eabe24896
commit 50cba50a8d
5 changed files with 169 additions and 1 deletions

View File

@@ -48,6 +48,9 @@ func NewCreateSetterRunner(parent string) *CreateSetterRunner {
set.Flags().MarkHidden("partial")
set.Flags().StringVar(&setterVersion, "version", "",
"use this version of the setter format")
set.Flags().StringVar(&r.CreateSetter.SchemaPath, "schema-path", "",
`openAPI schema file path for setter constraints -- file content `+
`e.g. {"type": "string", "maxLength": 15, "enum": ["allowedValue1", "allowedValue2"]}`)
set.Flags().MarkHidden("version")
fixDocs(parent, set)
r.Command = set

View File

@@ -21,6 +21,7 @@ func TestCreateSetterCommand(t *testing.T) {
name string
input string
args []string
schema string
out string
inputOpenAPI string
expectedOpenAPI string
@@ -85,6 +86,88 @@ openAPI:
`,
err: "substitution with name my-image already exists, substitution and setter can't have same name",
},
{
name: "add replicas with schema",
args: []string{"replicas", "3", "--description", "hello world", "--set-by", "me"},
schema: `{"maximum": 10, "type": "integer"}`,
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
`,
inputOpenAPI: `
apiVersion: v1alpha1
kind: Example
`,
expectedOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.replicas:
maximum: 10
type: integer
description: hello world
x-k8s-cli:
setter:
name: replicas
value: "3"
setBy: me
`,
expectedResources: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
`,
},
{
name: "add replicas with schema list values",
args: []string{"list", "a", "--description", "hello world", "--set-by", "me", "--type", "array"},
schema: `{"maxItems": 2, "type": "array", "items": {"type": "string"}}`,
input: `
apiVersion: example.com/v1beta1
kind: Example
spec:
list:
- "a"
`,
inputOpenAPI: `
apiVersion: v1alpha1
kind: Example
`,
expectedOpenAPI: `
apiVersion: v1alpha1
kind: Example
openAPI:
definitions:
io.k8s.cli.setters.list:
items:
type: string
maxItems: 2
type: array
description: hello world
x-k8s-cli:
setter:
name: list
value: a
setBy: me
`,
expectedResources: `
apiVersion: example.com/v1beta1
kind: Example
spec:
list:
- "a" # {"$ref":"#/definitions/io.k8s.cli.setters.list"}
`,
},
}
for i := range tests {
test := tests[i]
@@ -98,10 +181,27 @@ openAPI:
t.FailNow()
}
defer os.Remove(f.Name())
err = ioutil.WriteFile(f.Name(), []byte(test.inputOpenAPI), 0600)
if !assert.NoError(t, err) {
t.FailNow()
}
if test.schema != "" {
sch, err := ioutil.TempFile("", "schema.json")
if !assert.NoError(t, err) {
t.FailNow()
}
defer os.Remove(sch.Name())
err = ioutil.WriteFile(sch.Name(), []byte(test.schema), 0600)
if !assert.NoError(t, err) {
t.FailNow()
}
test.args = append(test.args, "--schema-path", sch.Name())
}
old := ext.GetOpenAPIFile
defer func() { ext.GetOpenAPIFile = old }()
ext.GetOpenAPIFile = func(args []string) (s string, err error) {

View File

@@ -4,6 +4,7 @@
package setters2
import (
"encoding/json"
"strings"
"github.com/go-openapi/spec"
@@ -116,6 +117,9 @@ type SetterDefinition struct {
// Type is the type of the setter value.
Type string `yaml:"type,omitempty"`
// Schema is the openAPI schema for setter constraints.
Schema string `yaml:"schema,omitempty"`
// EnumValues is a map of possible setter values to actual field values.
// If EnumValues is specified, then the value set the by user 1) MUST
// be present in the enumValues map as a key, and 2) the map entry value
@@ -137,6 +141,26 @@ func (sd SetterDefinition) Filter(object *yaml.RNode) (*yaml.RNode, error) {
if err != nil {
return nil, err
}
definitions, err := object.Pipe(yaml.Lookup(openapi.SupplementaryOpenAPIFieldName, "definitions"))
if err != nil {
return nil, err
}
if sd.Schema != "" {
schNode, err := ConvertJSONToYamlNode(sd.Schema)
if err != nil {
return nil, err
}
err = definitions.PipeE(yaml.SetField(key, schNode))
if err != nil {
return nil, err
}
// don't write the schema to the extension
sd.Schema = ""
}
if sd.Description != "" {
err = def.PipeE(yaml.FieldSetter{Name: "description", StringValue: sd.Description})
if err != nil {
@@ -176,6 +200,24 @@ func (sd SetterDefinition) Filter(object *yaml.RNode) (*yaml.RNode, error) {
return object, nil
}
// ConvertJSONToYamlNode parses input json string and returns equivalent yaml node
func ConvertJSONToYamlNode(jsonStr string) (*yaml.RNode, error) {
var body map[string]interface{}
err := json.Unmarshal([]byte(jsonStr), &body)
if err != nil {
return nil, err
}
yml, err := yaml.Marshal(body)
if err != nil {
return nil, err
}
ymlStr, err := yaml.Parse(string(yml))
if err != nil {
return nil, err
}
return ymlStr, nil
}
// SetterDefinition may be used to update a files OpenAPI definitions with a new substitution.
type SubstitutionDefinition struct {
// Name is the name of the substitution to create or update

View File

@@ -4,6 +4,8 @@
package settersutil
import (
"io/ioutil"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/setters2"
@@ -21,6 +23,8 @@ type SetterCreator struct {
Type string
SchemaPath string
// FieldName if set will add the OpenAPI reference to fields with this name or path
// FieldName may be the full name of the field, full path to the field, or the path suffix.
// e.g. all of the following would match spec.template.spec.containers.image --
@@ -35,10 +39,14 @@ type SetterCreator struct {
}
func (c SetterCreator) Create(openAPIPath, resourcesPath string) error {
schema, err := schemaFromFile(c.SchemaPath)
if err != nil {
return err
}
// Update the OpenAPI definitions to hace the setter
sd := setters2.SetterDefinition{
Name: c.Name, Value: c.FieldValue, Description: c.Description, SetBy: c.SetBy,
Type: c.Type,
Type: c.Type, Schema: schema,
}
if err := sd.AddToFile(openAPIPath); err != nil {
return err
@@ -62,3 +70,15 @@ func (c SetterCreator) Create(openAPIPath, resourcesPath string) error {
Outputs: []kio.Writer{inout},
}.Execute()
}
// schemaFromFile reads the contents from schemaPath and returns schema
func schemaFromFile(schemaPath string) (string, error) {
if schemaPath == "" {
return "", nil
}
sch, err := ioutil.ReadFile(schemaPath)
if err != nil {
return "", err
}
return string(sch), nil
}

View File

@@ -1,3 +1,6 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package testutil_test
import (