mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-24 07:18:17 +00:00
Compare commits
72 Commits
api/v0.4.1
...
cmd/config
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90ae506183 | ||
|
|
093409d7b6 | ||
|
|
083a266b0b | ||
|
|
d6fdf1c01a | ||
|
|
b679e33d47 | ||
|
|
e63b9ef825 | ||
|
|
4b5b0dfdce | ||
|
|
572260c0f0 | ||
|
|
144471ce78 | ||
|
|
37918ae745 | ||
|
|
dca164e967 | ||
|
|
8ac2365406 | ||
|
|
c1a2bf14da | ||
|
|
a7af7df9cb | ||
|
|
0b94a1405d | ||
|
|
b083187e6a | ||
|
|
4dcf81050e | ||
|
|
c97fa946d5 | ||
|
|
c35f5b0189 | ||
|
|
f7ca4fa106 | ||
|
|
98ba8b7491 | ||
|
|
d8769008ca | ||
|
|
b4456d2c24 | ||
|
|
4f68f47e05 | ||
|
|
722e91a5c4 | ||
|
|
b3f5874978 | ||
|
|
1086764c17 | ||
|
|
d94ef43a85 | ||
|
|
83dfa0b9f1 | ||
|
|
89953ec908 | ||
|
|
e465ee9e9a | ||
|
|
1008933b21 | ||
|
|
4246f79874 | ||
|
|
a28dd97871 | ||
|
|
8de94ba96c | ||
|
|
deb55a9f15 | ||
|
|
bf721a3fdd | ||
|
|
7d968fa80e | ||
|
|
fd6207b1c3 | ||
|
|
cbe85f482d | ||
|
|
a1c7330331 | ||
|
|
08ceab40dd | ||
|
|
f8fb00cb13 | ||
|
|
8a1c841420 | ||
|
|
730d1f2473 | ||
|
|
29d1a37858 | ||
|
|
c467f48bf2 | ||
|
|
054f56ceaf | ||
|
|
d5a107074d | ||
|
|
d8bd6db880 | ||
|
|
d27135e3a3 | ||
|
|
282b1fa49a | ||
|
|
584eb236fd | ||
|
|
31a193f60f | ||
|
|
bf17b244e5 | ||
|
|
8338299529 | ||
|
|
7adf7eb271 | ||
|
|
06b091b175 | ||
|
|
bf03669e94 | ||
|
|
7f52c814a8 | ||
|
|
d5aac922d9 | ||
|
|
9a62d866f3 | ||
|
|
b2812838bf | ||
|
|
e59e477702 | ||
|
|
4264ad0ad4 | ||
|
|
2554cd00eb | ||
|
|
383244cd63 | ||
|
|
b9da33afd4 | ||
|
|
23e339b86c | ||
|
|
9555009df8 | ||
|
|
91a10c560c | ||
|
|
780cb19c4d |
@@ -78,6 +78,7 @@ func secretHash(sec *corev1.Secret) (string, error) {
|
||||
|
||||
// encodeConfigMap encodes a ConfigMap.
|
||||
// Data, Kind, and Name are taken into account.
|
||||
// BinaryData is included if it's not empty to avoid useless key in output.
|
||||
func encodeConfigMap(cm *corev1.ConfigMap) (string, error) {
|
||||
// json.Marshal sorts the keys in a stable order in the encoding
|
||||
m := map[string]interface{}{"kind": "ConfigMap", "name": cm.Name, "data": cm.Data}
|
||||
@@ -93,9 +94,14 @@ func encodeConfigMap(cm *corev1.ConfigMap) (string, error) {
|
||||
|
||||
// encodeSecret encodes a Secret.
|
||||
// Data, Kind, Name, and Type are taken into account.
|
||||
// StringData is included if it's not empty to avoid useless key in output.
|
||||
func encodeSecret(sec *corev1.Secret) (string, error) {
|
||||
// json.Marshal sorts the keys in a stable order in the encoding
|
||||
data, err := json.Marshal(map[string]interface{}{"kind": "Secret", "type": sec.Type, "name": sec.Name, "data": sec.Data})
|
||||
m := map[string]interface{}{"kind": "Secret", "type": sec.Type, "name": sec.Name, "data": sec.Data}
|
||||
if len(sec.StringData) > 0 {
|
||||
m["stringData"] = sec.StringData
|
||||
}
|
||||
data, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -58,6 +58,10 @@ func TestSecretHash(t *testing.T) {
|
||||
{"one key", &corev1.Secret{Type: "my-type", Data: map[string][]byte{"one": []byte("")}}, "74bd68bm66", ""},
|
||||
// three keys (tests sorting order)
|
||||
{"three keys", &corev1.Secret{Type: "my-type", Data: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")}}, "dgcb6h9tmk", ""},
|
||||
// with stringdata
|
||||
{"stringdata", &corev1.Secret{Type: "my-type", Data: map[string][]byte{"one": []byte("")}, StringData: map[string]string{"two": "2"}}, "ckm7f798g2", ""},
|
||||
// empty stringdata
|
||||
{"empty stringdata", &corev1.Secret{Type: "my-type", Data: map[string][]byte{"one": []byte("")}, StringData: map[string]string{}}, "74bd68bm66", ""},
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
@@ -125,6 +129,12 @@ func TestEncodeSecret(t *testing.T) {
|
||||
Data: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")},
|
||||
},
|
||||
`{"data":{"one":"","three":"Mw==","two":"Mg=="},"kind":"Secret","name":"","type":"my-type"}`, ""},
|
||||
// with stringdata
|
||||
{"stringdata", &corev1.Secret{Type: "my-type", Data: map[string][]byte{"one": []byte("")}, StringData: map[string]string{"two": "2"}},
|
||||
`{"data":{"one":""},"kind":"Secret","name":"","stringData":{"two":"2"},"type":"my-type"}`, ""},
|
||||
// empty stringdata
|
||||
{"empty stringdata", &corev1.Secret{Type: "my-type", Data: map[string][]byte{"one": []byte("")}, StringData: map[string]string{}},
|
||||
`{"data":{"one":""},"kind":"Secret","name":"","type":"my-type"}`, ""},
|
||||
}
|
||||
for _, c := range cases {
|
||||
s, err := encodeSecret(c.secret)
|
||||
|
||||
@@ -11,16 +11,5 @@ require (
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.4.0
|
||||
k8s.io/apimachinery v0.17.0
|
||||
sigs.k8s.io/kustomize/kyaml v0.0.0 // Don't change this!
|
||||
sigs.k8s.io/kustomize/kyaml v0.1.13 // Don't change this!
|
||||
)
|
||||
|
||||
// Don't change this!
|
||||
//
|
||||
// This line is managed by the release script -- releasing/releasemodule.sh
|
||||
// Pinning to a released version of kyaml will invalidate the e2e tests used to
|
||||
// test kyaml changes as the e2e tests will run against the pinned version, not
|
||||
// the HEAD.
|
||||
//
|
||||
// releasing/releasemodule.sh will remove this line and set the require version
|
||||
// to the kyaml version specified in releasing/VERSIONS
|
||||
replace sigs.k8s.io/kustomize/kyaml v0.0.0 => ../../kyaml
|
||||
|
||||
@@ -350,5 +350,7 @@ k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8
|
||||
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
|
||||
sigs.k8s.io/kustomize/kyaml v0.1.13 h1:EQ2+kUPmlUvBQ62Icxst3gtD09GLNW4PjtJspxkCmpc=
|
||||
sigs.k8s.io/kustomize/kyaml v0.1.13/go.mod h1:72/rLkSi+L/pHM1oCjwrf3ClU+tH5kZQvvdLSqIHwWU=
|
||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
|
||||
@@ -9,10 +9,10 @@ import (
|
||||
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||
"sigs.k8s.io/kustomize/kyaml/setters"
|
||||
"sigs.k8s.io/kustomize/kyaml/setters2"
|
||||
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
|
||||
)
|
||||
|
||||
@@ -21,13 +21,15 @@ func NewCreateSetterRunner(parent string) *CreateSetterRunner {
|
||||
r := &CreateSetterRunner{}
|
||||
set := &cobra.Command{
|
||||
Use: "create-setter DIR NAME VALUE",
|
||||
Args: cobra.ExactArgs(3),
|
||||
Args: cobra.RangeArgs(2, 3),
|
||||
Short: commands.CreateSetterShort,
|
||||
Long: commands.CreateSetterLong,
|
||||
Example: commands.CreateSetterExamples,
|
||||
PreRunE: r.preRunE,
|
||||
RunE: r.runE,
|
||||
}
|
||||
set.Flags().StringVar(&r.Set.SetPartialField.Setter.Value, "value", "",
|
||||
"optional flag, alternative to specifying the value as an argument. e.g. used to specify values that start with '-'")
|
||||
set.Flags().StringVar(&r.Set.SetPartialField.SetBy, "set-by", "",
|
||||
"record who the field was default by.")
|
||||
set.Flags().StringVar(&r.Set.SetPartialField.Description, "description", "",
|
||||
@@ -73,18 +75,23 @@ func (r *CreateSetterRunner) runE(c *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
func (r *CreateSetterRunner) preRunE(c *cobra.Command, args []string) error {
|
||||
valueSetFromFlag := c.Flag("value").Changed
|
||||
var err error
|
||||
r.Set.SetPartialField.Setter.Name = args[1]
|
||||
r.Set.SetPartialField.Setter.Value = args[2]
|
||||
r.CreateSetter.Name = args[1]
|
||||
r.CreateSetter.FieldValue = args[2]
|
||||
if valueSetFromFlag {
|
||||
r.CreateSetter.FieldValue = r.Set.SetPartialField.Setter.Value
|
||||
} else if len(args) > 2 {
|
||||
r.Set.SetPartialField.Setter.Value = args[2]
|
||||
r.CreateSetter.FieldValue = args[2]
|
||||
}
|
||||
r.CreateSetter.FieldName, err = c.Flags().GetString("field")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if setterVersion == "" {
|
||||
if len(args) < 3 {
|
||||
if len(args) < 2 || !c.Flag("value").Changed && len(args) < 3 {
|
||||
setterVersion = "v1"
|
||||
} else if err := initSetterVersion(c, args); err != nil {
|
||||
return err
|
||||
@@ -102,7 +109,7 @@ func (r *CreateSetterRunner) preRunE(c *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
// check if substitution with same name exists and throw error
|
||||
ref, err := spec.NewRef(setters2.DefinitionsPrefix + setters2.SubstitutionDefinitionPrefix + r.CreateSetter.Name)
|
||||
ref, err := spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SubstitutionDefinitionPrefix + r.CreateSetter.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
replicas: 3 # {"$openapi":"replicas"}
|
||||
`,
|
||||
},
|
||||
{
|
||||
@@ -124,7 +124,7 @@ kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
replicas: 3 # {"$openapi":"replicas"}
|
||||
`,
|
||||
},
|
||||
|
||||
@@ -165,7 +165,44 @@ apiVersion: example.com/v1beta1
|
||||
kind: Example
|
||||
spec:
|
||||
list:
|
||||
- "a" # {"$ref":"#/definitions/io.k8s.cli.setters.list"}
|
||||
- "a" # {"$openapi":"list"}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "add replicas with value set by flag",
|
||||
args: []string{"replicas", "--value", "3", "--description", "hello world", "--set-by", "me"},
|
||||
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:
|
||||
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 # {"$openapi":"replicas"}
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||
"sigs.k8s.io/kustomize/kyaml/setters2"
|
||||
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
|
||||
@@ -71,7 +72,7 @@ func (r *CreateSubstitutionRunner) preRunE(c *cobra.Command, args []string) erro
|
||||
}
|
||||
|
||||
// check if setter with same name exists and throw error
|
||||
ref, err := spec.NewRef(setters2.DefinitionsPrefix + setters2.SetterDefinitionPrefix + r.CreateSubstitution.Name)
|
||||
ref, err := spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SetterDefinitionPrefix + r.CreateSubstitution.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -92,7 +93,7 @@ func (r *CreateSubstitutionRunner) preRunE(c *cobra.Command, args []string) erro
|
||||
}
|
||||
|
||||
for _, marker := range markers {
|
||||
ref := setters2.DefinitionsPrefix + setters2.SetterDefinitionPrefix +
|
||||
ref := fieldmeta.DefinitionsPrefix + fieldmeta.SetterDefinitionPrefix +
|
||||
strings.TrimSuffix(strings.TrimPrefix(string(marker), "${"), "}")
|
||||
r.CreateSubstitution.Values = append(
|
||||
r.CreateSubstitution.Values,
|
||||
|
||||
@@ -99,7 +99,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.7.9 # {"$ref":"#/definitions/io.k8s.cli.substitutions.my-image-subst"}
|
||||
image: nginx:1.7.9 # {"$openapi":"my-image-subst"}
|
||||
- name: sidecar
|
||||
image: sidecar:1.7.9
|
||||
`,
|
||||
@@ -181,7 +181,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: something/nginx::1.7.9/nginxotherthing # {"$ref":"#/definitions/io.k8s.cli.substitutions.my-image-subst"}
|
||||
image: something/nginx::1.7.9/nginxotherthing # {"$openapi":"my-image-subst"}
|
||||
- name: sidecar
|
||||
image: sidecar:1.7.9
|
||||
`,
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
||||
"sigs.k8s.io/kustomize/kyaml/setters"
|
||||
"sigs.k8s.io/kustomize/kyaml/setters2"
|
||||
)
|
||||
@@ -117,7 +118,7 @@ func (r *ListSettersRunner) ListSubstitutions(c *cobra.Command, args []string) e
|
||||
s := r.List.Substitutions[i]
|
||||
setters := ""
|
||||
for _, value := range s.Values {
|
||||
setter := strings.TrimPrefix(value.Ref, setters2.DefinitionsPrefix+setters2.SetterDefinitionPrefix)
|
||||
setter := strings.TrimPrefix(value.Ref, fieldmeta.DefinitionsPrefix+fieldmeta.SetterDefinitionPrefix)
|
||||
setters = setters + "," + setter
|
||||
}
|
||||
setters = fmt.Sprintf("[%s]", strings.TrimPrefix(setters, ","))
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"sigs.k8s.io/kustomize/cmd/config/ext"
|
||||
"sigs.k8s.io/kustomize/cmd/config/internal/generateddocs/commands"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
"sigs.k8s.io/kustomize/kyaml/setters"
|
||||
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
|
||||
@@ -20,8 +21,8 @@ import (
|
||||
func NewSetRunner(parent string) *SetRunner {
|
||||
r := &SetRunner{}
|
||||
c := &cobra.Command{
|
||||
Use: "set DIR NAME [VALUE]",
|
||||
Args: cobra.MinimumNArgs(3),
|
||||
Use: "set DIR NAME --values [VALUE]",
|
||||
Args: cobra.MinimumNArgs(2),
|
||||
Short: commands.SetShort,
|
||||
Long: commands.SetLong,
|
||||
Example: commands.SetExamples,
|
||||
@@ -30,6 +31,8 @@ func NewSetRunner(parent string) *SetRunner {
|
||||
}
|
||||
fixDocs(parent, c)
|
||||
r.Command = c
|
||||
c.Flags().StringArrayVar(&r.Values, "values", []string{},
|
||||
"optional flag, the values of the setter to be set to")
|
||||
c.Flags().StringVar(&r.Perform.SetBy, "set-by", "",
|
||||
"annotate the field with who set it")
|
||||
c.Flags().StringVar(&r.Perform.Description, "description", "",
|
||||
@@ -53,6 +56,7 @@ type SetRunner struct {
|
||||
Perform setters.PerformSetters
|
||||
Set settersutil.FieldSetter
|
||||
OpenAPIFile string
|
||||
Values []string
|
||||
}
|
||||
|
||||
func initSetterVersion(c *cobra.Command, args []string) error {
|
||||
@@ -75,16 +79,25 @@ func initSetterVersion(c *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
func (r *SetRunner) preRunE(c *cobra.Command, args []string) error {
|
||||
valueFlagSet := c.Flag("values").Changed
|
||||
|
||||
if valueFlagSet && len(args) > 2 {
|
||||
return errors.Errorf("value should set either from flag or arg")
|
||||
}
|
||||
|
||||
if len(args) > 1 {
|
||||
r.Perform.Name = args[1]
|
||||
r.Lookup.Name = args[1]
|
||||
}
|
||||
if len(args) > 2 {
|
||||
|
||||
if valueFlagSet {
|
||||
r.Perform.Value = r.Values[0]
|
||||
} else if len(args) > 2 {
|
||||
r.Perform.Value = args[2]
|
||||
}
|
||||
|
||||
if setterVersion == "" {
|
||||
if len(args) < 3 {
|
||||
if len(args) < 2 || len(args) < 3 && !valueFlagSet {
|
||||
setterVersion = "v1"
|
||||
} else if err := initSetterVersion(c, args); err != nil {
|
||||
return err
|
||||
@@ -93,12 +106,19 @@ func (r *SetRunner) preRunE(c *cobra.Command, args []string) error {
|
||||
if setterVersion == "v2" {
|
||||
var err error
|
||||
r.Set.Name = args[1]
|
||||
r.Set.Value = args[2]
|
||||
if valueFlagSet {
|
||||
r.Set.Value = r.Values[0]
|
||||
} else {
|
||||
r.Set.Value = args[2]
|
||||
}
|
||||
|
||||
// set remaining values as list values
|
||||
if len(args) > 3 {
|
||||
if valueFlagSet && len(r.Values) > 1 {
|
||||
r.Set.ListValues = r.Values[1:]
|
||||
} else if !valueFlagSet && len(args) > 3 {
|
||||
r.Set.ListValues = args[3:]
|
||||
}
|
||||
|
||||
r.Set.Description = r.Perform.Description
|
||||
r.Set.SetBy = r.Perform.SetBy
|
||||
r.OpenAPIFile, err = ext.GetOpenAPIFile(args)
|
||||
@@ -116,7 +136,7 @@ func (r *SetRunner) runE(c *cobra.Command, args []string) error {
|
||||
fmt.Fprintf(c.OutOrStdout(), "set %d fields\n", count)
|
||||
return handleError(c, err)
|
||||
}
|
||||
if len(args) == 3 {
|
||||
if len(args) > 2 || c.Flag("values").Changed {
|
||||
return handleError(c, r.perform(c, args))
|
||||
}
|
||||
return handleError(c, lookup(r.Lookup, c, args))
|
||||
|
||||
@@ -50,7 +50,7 @@ kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
replicas: 3 # {"$openapi":"replicas"}
|
||||
`,
|
||||
expectedOpenAPI: `
|
||||
apiVersion: v1alpha1
|
||||
@@ -71,9 +71,57 @@ kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
replicas: 4 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
replicas: 4 # {"$openapi":"replicas"}
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "validate length of argument",
|
||||
args: []string{"--description", "hi there", "--set-by", "pw"},
|
||||
inputOpenAPI: `
|
||||
apiVersion: v1alpha1
|
||||
kind: Example
|
||||
openAPI:
|
||||
definitions:
|
||||
io.k8s.cli.setters.replicas:
|
||||
description: hello world
|
||||
x-k8s-cli:
|
||||
setter:
|
||||
name: replicas
|
||||
value: "3"
|
||||
setBy: me
|
||||
`,
|
||||
input: `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
`,
|
||||
expectedOpenAPI: `
|
||||
apiVersion: v1alpha1
|
||||
kind: Example
|
||||
openAPI:
|
||||
definitions:
|
||||
io.k8s.cli.setters.replicas:
|
||||
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"}
|
||||
`,
|
||||
errMsg: "requires at least 2 arg(s), only received 1",
|
||||
},
|
||||
|
||||
{
|
||||
name: "set replicas no description",
|
||||
args: []string{"replicas", "4"},
|
||||
@@ -121,7 +169,7 @@ spec:
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "set image",
|
||||
name: "set image with value",
|
||||
args: []string{"tag", "1.8.1"},
|
||||
out: "set 1 fields\n",
|
||||
inputOpenAPI: `
|
||||
@@ -129,10 +177,10 @@ apiVersion: v1alpha1
|
||||
kind: Example
|
||||
openAPI:
|
||||
definitions:
|
||||
io.k8s.cli.setters.image:
|
||||
io.k8s.cli.setters.image-setter:
|
||||
x-k8s-cli:
|
||||
setter:
|
||||
name: image
|
||||
name: image-setter
|
||||
value: "nginx"
|
||||
io.k8s.cli.setters.tag:
|
||||
x-k8s-cli:
|
||||
@@ -146,7 +194,7 @@ openAPI:
|
||||
pattern: IMAGE:TAG
|
||||
values:
|
||||
- marker: IMAGE
|
||||
ref: '#/definitions/io.k8s.cli.setters.image'
|
||||
ref: '#/definitions/io.k8s.cli.setters.image-setter'
|
||||
- marker: TAG
|
||||
ref: '#/definitions/io.k8s.cli.setters.tag'
|
||||
`,
|
||||
@@ -161,7 +209,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.7.9 # {"$ref":"#/definitions/io.k8s.cli.substitutions.image"}
|
||||
image: nginx:1.7.9 # {"$openapi":"image"}
|
||||
- name: sidecar
|
||||
image: sidecar:1.7.9
|
||||
`,
|
||||
@@ -170,10 +218,10 @@ apiVersion: v1alpha1
|
||||
kind: Example
|
||||
openAPI:
|
||||
definitions:
|
||||
io.k8s.cli.setters.image:
|
||||
io.k8s.cli.setters.image-setter:
|
||||
x-k8s-cli:
|
||||
setter:
|
||||
name: image
|
||||
name: image-setter
|
||||
value: "nginx"
|
||||
io.k8s.cli.setters.tag:
|
||||
x-k8s-cli:
|
||||
@@ -187,7 +235,7 @@ openAPI:
|
||||
pattern: IMAGE:TAG
|
||||
values:
|
||||
- marker: IMAGE
|
||||
ref: '#/definitions/io.k8s.cli.setters.image'
|
||||
ref: '#/definitions/io.k8s.cli.setters.image-setter'
|
||||
- marker: TAG
|
||||
ref: '#/definitions/io.k8s.cli.setters.tag'
|
||||
|
||||
@@ -203,7 +251,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.8.1 # {"$ref":"#/definitions/io.k8s.cli.substitutions.image"}
|
||||
image: nginx:1.8.1 # {"$openapi":"image"}
|
||||
- name: sidecar
|
||||
image: sidecar:1.7.9
|
||||
`,
|
||||
@@ -453,6 +501,205 @@ spec:
|
||||
`,
|
||||
errMsg: `list in body must be of type integer: "string"
|
||||
list in body must be of type integer: "boolean"
|
||||
list in body should have at most 2 items`,
|
||||
},
|
||||
|
||||
{
|
||||
name: "set replicas with value set by flag",
|
||||
args: []string{"replicas", "--values", "4", "--description", "hi there"},
|
||||
out: "set 1 fields\n",
|
||||
inputOpenAPI: `
|
||||
apiVersion: v1alpha1
|
||||
kind: Example
|
||||
openAPI:
|
||||
definitions:
|
||||
io.k8s.cli.setters.replicas:
|
||||
description: hello world
|
||||
x-k8s-cli:
|
||||
setter:
|
||||
name: replicas
|
||||
value: "3"
|
||||
setBy: me
|
||||
`,
|
||||
input: `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
`,
|
||||
expectedOpenAPI: `
|
||||
apiVersion: v1alpha1
|
||||
kind: Example
|
||||
openAPI:
|
||||
definitions:
|
||||
io.k8s.cli.setters.replicas:
|
||||
description: hi there
|
||||
x-k8s-cli:
|
||||
setter:
|
||||
name: replicas
|
||||
value: "4"
|
||||
`,
|
||||
expectedResources: `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
replicas: 4 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
`,
|
||||
},
|
||||
|
||||
{
|
||||
name: "validate values set from either flag or arg",
|
||||
args: []string{"replicas", "4", "--values", "4", "--description", "hi there"},
|
||||
inputOpenAPI: `
|
||||
apiVersion: v1alpha1
|
||||
kind: Example
|
||||
openAPI:
|
||||
definitions:
|
||||
io.k8s.cli.setters.replicas:
|
||||
description: hello world
|
||||
x-k8s-cli:
|
||||
setter:
|
||||
name: replicas
|
||||
value: "3"
|
||||
setBy: me
|
||||
`,
|
||||
input: `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
`,
|
||||
expectedOpenAPI: `
|
||||
apiVersion: v1alpha1
|
||||
kind: Example
|
||||
openAPI:
|
||||
definitions:
|
||||
io.k8s.cli.setters.replicas:
|
||||
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"}
|
||||
`,
|
||||
errMsg: `value should set either from flag or arg`,
|
||||
},
|
||||
|
||||
{
|
||||
name: "openAPI list values set by flag success",
|
||||
args: []string{"list", "--values", "10", "--values", "11"},
|
||||
out: "set 1 fields\n",
|
||||
inputOpenAPI: `
|
||||
kind: Kptfile
|
||||
openAPI:
|
||||
definitions:
|
||||
io.k8s.cli.setters.list:
|
||||
type: array
|
||||
maxItems: 2
|
||||
items:
|
||||
type: integer
|
||||
x-k8s-cli:
|
||||
setter:
|
||||
name: list
|
||||
listValues:
|
||||
- 0
|
||||
`,
|
||||
input: `
|
||||
apiVersion: example.com/v1beta1
|
||||
kind: Example
|
||||
spec:
|
||||
list: # {"$ref":"#/definitions/io.k8s.cli.setters.list"}
|
||||
- 0
|
||||
`,
|
||||
expectedOpenAPI: `
|
||||
kind: Kptfile
|
||||
openAPI:
|
||||
definitions:
|
||||
io.k8s.cli.setters.list:
|
||||
type: array
|
||||
maxItems: 2
|
||||
items:
|
||||
type: integer
|
||||
x-k8s-cli:
|
||||
setter:
|
||||
name: list
|
||||
listValues:
|
||||
- "10"
|
||||
- "11"
|
||||
`,
|
||||
expectedResources: `
|
||||
apiVersion: example.com/v1beta1
|
||||
kind: Example
|
||||
spec:
|
||||
list: # {"$ref":"#/definitions/io.k8s.cli.setters.list"}
|
||||
- "10"
|
||||
- "11"
|
||||
`,
|
||||
},
|
||||
|
||||
{
|
||||
name: "validate openAPI list values set by flag error",
|
||||
args: []string{"list", "--values", "10", "--values", "hi", "--values", "true"},
|
||||
inputOpenAPI: `
|
||||
kind: Kptfile
|
||||
openAPI:
|
||||
definitions:
|
||||
io.k8s.cli.setters.list:
|
||||
type: array
|
||||
maxItems: 2
|
||||
items:
|
||||
type: integer
|
||||
x-k8s-cli:
|
||||
setter:
|
||||
name: list
|
||||
listValues:
|
||||
- 0
|
||||
`,
|
||||
input: `
|
||||
apiVersion: example.com/v1beta1
|
||||
kind: Example
|
||||
spec:
|
||||
list: # {"$ref":"#/definitions/io.k8s.cli.setters.list"}
|
||||
- 0
|
||||
`,
|
||||
expectedOpenAPI: `
|
||||
kind: Kptfile
|
||||
openAPI:
|
||||
definitions:
|
||||
io.k8s.cli.setters.list:
|
||||
type: array
|
||||
maxItems: 2
|
||||
items:
|
||||
type: integer
|
||||
x-k8s-cli:
|
||||
setter:
|
||||
name: list
|
||||
listValues:
|
||||
- 0
|
||||
`,
|
||||
expectedResources: `
|
||||
apiVersion: example.com/v1beta1
|
||||
kind: Example
|
||||
spec:
|
||||
list: # {"$ref":"#/definitions/io.k8s.cli.setters.list"}
|
||||
- 0
|
||||
`,
|
||||
errMsg: `list in body must be of type integer: "string"
|
||||
list in body must be of type integer: "boolean"
|
||||
list in body should have at most 2 items`,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -71,6 +71,10 @@ test 3 == \
|
||||
The url should follow
|
||||
[hashicorp/go-getter URL format](https://github.com/hashicorp/go-getter#url-format).
|
||||
|
||||
Note that using `//` in the url will only copy the directory specified by the path
|
||||
after `//`, which means some relative paths, like `../xxx`, may not work. Using `/` to copy
|
||||
entire repo. For more details please see [go-getter documentation](https://github.com/hashicorp/go-getter#subdirectories).
|
||||
|
||||
Note that S3 and GCS are NOT supported to avoid introducing massive dependency.
|
||||
|
||||
Here are some example urls
|
||||
|
||||
@@ -12,7 +12,7 @@ require (
|
||||
k8s.io/apimachinery v0.17.0
|
||||
k8s.io/client-go v0.17.0
|
||||
sigs.k8s.io/controller-runtime v0.4.0
|
||||
sigs.k8s.io/kustomize/api v0.4.0
|
||||
sigs.k8s.io/kustomize/api v0.4.1
|
||||
sigs.k8s.io/kustomize/cmd/config v0.1.11
|
||||
sigs.k8s.io/kustomize/cmd/kubectl v0.1.0
|
||||
sigs.k8s.io/kustomize/kstatus v0.0.2
|
||||
|
||||
@@ -786,8 +786,8 @@ sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9
|
||||
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
|
||||
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
|
||||
sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
|
||||
sigs.k8s.io/kustomize/api v0.4.0 h1:EhlPWA4S1S1UUPzNanVR/SfPQ7g66j+jiN8ovtyby3Y=
|
||||
sigs.k8s.io/kustomize/api v0.4.0/go.mod h1:NqxqT+wbYHrD0P19Uu4dXiMsVwI1IwQs+MJHlLhmPqQ=
|
||||
sigs.k8s.io/kustomize/api v0.4.1 h1:Lwco6Rsxd3TcubJzx9wAV2k7roh0M95FjrS29n76TRo=
|
||||
sigs.k8s.io/kustomize/api v0.4.1/go.mod h1:NqxqT+wbYHrD0P19Uu4dXiMsVwI1IwQs+MJHlLhmPqQ=
|
||||
sigs.k8s.io/kustomize/cmd/config v0.1.11 h1:wSVvutGQtgiYWcd4IH5sr8jP4v6zgr9IcUAbA+32ULo=
|
||||
sigs.k8s.io/kustomize/cmd/config v0.1.11/go.mod h1:w6vK8ulANez23sOTtmdej5KpBU9Ykdomu/W70PC8YMs=
|
||||
sigs.k8s.io/kustomize/cmd/kubectl v0.1.0 h1:TAAv9ZhUalC0tqgHp1rr8Vv5fA5ILcQwGYjdAGdCmhg=
|
||||
|
||||
@@ -5,12 +5,14 @@ package fieldmeta
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/spec"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||
)
|
||||
|
||||
@@ -54,14 +56,17 @@ func (fm *FieldMeta) Read(n *yaml.RNode) error {
|
||||
continue
|
||||
}
|
||||
c := strings.TrimLeft(c, "#")
|
||||
// if it doesn't Unmarshal that is fine, it means there is no metadata
|
||||
// other comments are valid, they just don't parse
|
||||
|
||||
// TODO: consider more sophisticated parsing techniques similar to what is used
|
||||
// for go struct tags.
|
||||
if err := fm.Schema.UnmarshalJSON([]byte(c)); err != nil {
|
||||
// note: don't return an error if the comment isn't a fieldmeta struct
|
||||
return nil
|
||||
// check for new short hand notation or fall back to openAPI ref format
|
||||
if !fm.processShortHand(c) {
|
||||
// if it doesn't Unmarshal that is fine, it means there is no metadata
|
||||
// other comments are valid, they just don't parse
|
||||
// TODO: consider more sophisticated parsing techniques similar to what is used
|
||||
// for go struct tags.
|
||||
if err := fm.Schema.UnmarshalJSON([]byte(c)); err != nil {
|
||||
// note: don't return an error if the comment isn't a fieldmeta struct
|
||||
return nil
|
||||
}
|
||||
}
|
||||
fe := fm.Schema.VendorExtensible.Extensions["x-kustomize"]
|
||||
if fe == nil {
|
||||
@@ -76,6 +81,55 @@ func (fm *FieldMeta) Read(n *yaml.RNode) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// processShortHand parses the comment for short hand ref, loads schema to fm
|
||||
// and returns true if successful, returns false for any other cases and not throw
|
||||
// error, as the comment might not be a setter ref
|
||||
func (fm *FieldMeta) processShortHand(comment string) bool {
|
||||
input := map[string]string{}
|
||||
err := json.Unmarshal([]byte(comment), &input)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
name := input[shortHandRef]
|
||||
if name == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
// check if setter with the name exists, else check for a substitution
|
||||
// setter and substitution can't have same name in shorthand
|
||||
|
||||
setterRef, err := spec.NewRef(DefinitionsPrefix + SetterDefinitionPrefix + name)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
setterRefBytes, err := setterRef.MarshalJSON()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if _, err := openapi.Resolve(&setterRef); err == nil {
|
||||
setterErr := fm.Schema.UnmarshalJSON(setterRefBytes)
|
||||
return setterErr == nil
|
||||
}
|
||||
|
||||
substRef, err := spec.NewRef(DefinitionsPrefix + SubstitutionDefinitionPrefix + name)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
substRefBytes, err := substRef.MarshalJSON()
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if _, err := openapi.Resolve(&substRef); err == nil {
|
||||
substErr := fm.Schema.UnmarshalJSON(substRefBytes)
|
||||
return substErr == nil
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isExtensionEmpty(x XKustomize) bool {
|
||||
if x.FieldSetter != nil {
|
||||
return false
|
||||
@@ -96,11 +150,11 @@ func (fm *FieldMeta) Write(n *yaml.RNode) error {
|
||||
} else {
|
||||
delete(fm.Schema.VendorExtensible.Extensions, "x-kustomize")
|
||||
}
|
||||
b, err := json.Marshal(fm.Schema)
|
||||
if err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
n.YNode().LineComment = string(b)
|
||||
|
||||
// Ex: {"$ref":"#/definitions/io.k8s.cli.setters.replicas"} should be converted to
|
||||
// {"openAPI":"replicas"} and added to the line comment
|
||||
arr := strings.Split(fm.Schema.Ref.String(), ".")
|
||||
n.YNode().LineComment = fmt.Sprintf(`{"%s":"%s"}`, shortHandRef, arr[len(arr)-1])
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -166,3 +220,28 @@ func (it FieldValueType) TagForValue(value string) string {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
const (
|
||||
// CLIDefinitionsPrefix is the prefix for cli definition keys.
|
||||
CLIDefinitionsPrefix = "io.k8s.cli."
|
||||
|
||||
// SetterDefinitionPrefix is the prefix for setter definition keys.
|
||||
SetterDefinitionPrefix = CLIDefinitionsPrefix + "setters."
|
||||
|
||||
// SubstitutionDefinitionPrefix is the prefix for substitution definition keys.
|
||||
SubstitutionDefinitionPrefix = CLIDefinitionsPrefix + "substitutions."
|
||||
|
||||
// DefinitionsPrefix is the prefix used to reference definitions in the OpenAPI
|
||||
DefinitionsPrefix = "#/definitions/"
|
||||
)
|
||||
|
||||
// shortHandRef is the shorthand reference to setters and substitutions
|
||||
var shortHandRef = "$openapi"
|
||||
|
||||
func SetShortHandRef(ref string) {
|
||||
shortHandRef = ref
|
||||
}
|
||||
|
||||
func ShortHandRef() string {
|
||||
return shortHandRef
|
||||
}
|
||||
|
||||
@@ -79,20 +79,6 @@ func (a *Add) visitScalar(object *yaml.RNode, p string, _ *openapi.ResourceSchem
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
// CLIDefinitionsPrefix is the prefix for cli definition keys.
|
||||
CLIDefinitionsPrefix = "io.k8s.cli."
|
||||
|
||||
// SetterDefinitionPrefix is the prefix for setter definition keys.
|
||||
SetterDefinitionPrefix = CLIDefinitionsPrefix + "setters."
|
||||
|
||||
// SubstitutionDefinitionPrefix is the prefix for substitution definition keys.
|
||||
SubstitutionDefinitionPrefix = CLIDefinitionsPrefix + "substitutions."
|
||||
|
||||
// DefinitionsPrefix is the prefix used to reference definitions in the OpenAPI
|
||||
DefinitionsPrefix = "#/definitions/"
|
||||
)
|
||||
|
||||
// SetterDefinition may be used to update a files OpenAPI definitions with a new setter.
|
||||
type SetterDefinition struct {
|
||||
// Name is the name of the setter to create or update.
|
||||
@@ -133,7 +119,7 @@ func (sd SetterDefinition) AddToFile(path string) error {
|
||||
}
|
||||
|
||||
func (sd SetterDefinition) Filter(object *yaml.RNode) (*yaml.RNode, error) {
|
||||
key := SetterDefinitionPrefix + sd.Name
|
||||
key := fieldmeta.SetterDefinitionPrefix + sd.Name
|
||||
|
||||
definitions, err := object.Pipe(yaml.LookupCreate(
|
||||
yaml.MappingNode, openapi.SupplementaryOpenAPIFieldName, "definitions"))
|
||||
@@ -235,7 +221,7 @@ func (sd SubstitutionDefinition) Filter(object *yaml.RNode) (*yaml.RNode, error)
|
||||
}
|
||||
|
||||
// lookup or create the definition for the substitution
|
||||
defKey := SubstitutionDefinitionPrefix + sd.Name
|
||||
defKey := fieldmeta.SubstitutionDefinitionPrefix + sd.Name
|
||||
def, err := object.Pipe(yaml.LookupCreate(
|
||||
yaml.MappingNode, openapi.SupplementaryOpenAPIFieldName, "definitions", defKey, "x-k8s-cli"))
|
||||
if err != nil {
|
||||
|
||||
@@ -42,7 +42,7 @@ kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
spec:
|
||||
replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
replicas: 3 # {"$openapi":"replicas"}
|
||||
`,
|
||||
},
|
||||
{
|
||||
@@ -67,9 +67,9 @@ kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
annotations:
|
||||
something: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
something: 3 # {"$openapi":"replicas"}
|
||||
spec:
|
||||
replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
replicas: 3 # {"$openapi":"replicas"}
|
||||
`,
|
||||
},
|
||||
{
|
||||
@@ -97,7 +97,7 @@ metadata:
|
||||
annotations:
|
||||
something: 3
|
||||
spec:
|
||||
replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
replicas: 3 # {"$openapi":"replicas"}
|
||||
`,
|
||||
},
|
||||
{
|
||||
@@ -123,9 +123,9 @@ kind: Deployment
|
||||
metadata:
|
||||
name: nginx-deployment
|
||||
annotations:
|
||||
replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
replicas: 3 # {"$openapi":"replicas"}
|
||||
spec:
|
||||
replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
replicas: 3 # {"$openapi":"replicas"}
|
||||
`,
|
||||
},
|
||||
{
|
||||
@@ -153,7 +153,7 @@ metadata:
|
||||
annotations:
|
||||
replicas: 3
|
||||
spec:
|
||||
replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
replicas: 3 # {"$openapi":"replicas"}
|
||||
`,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -162,7 +162,7 @@ spec:
|
||||
// annotations:
|
||||
// something: 3
|
||||
// spec:
|
||||
// replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
// replicas: 3 # {"$openapi":"replicas"}
|
||||
}
|
||||
|
||||
// ExampleAdd demonstrates adding a setter reference to fields.
|
||||
@@ -196,7 +196,7 @@ spec:
|
||||
// metadata:
|
||||
// name: nginx-deployment
|
||||
// annotations:
|
||||
// something: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
// something: 3 # {"$openapi":"replicas"}
|
||||
// spec:
|
||||
// replicas: 3 # {"$ref":"#/definitions/io.k8s.cli.setters.replicas"}
|
||||
// replicas: 3 # {"$openapi":"replicas"}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||
@@ -63,7 +64,7 @@ func (l *List) listSetters(object *yaml.RNode, resourcePath string) error {
|
||||
// the definition key -- contains the setter name
|
||||
key := node.Key.YNode().Value
|
||||
|
||||
if !strings.HasPrefix(key, SetterDefinitionPrefix) {
|
||||
if !strings.HasPrefix(key, fieldmeta.SetterDefinitionPrefix) {
|
||||
// not a setter -- doesn't have the right prefix
|
||||
return nil
|
||||
}
|
||||
@@ -136,7 +137,7 @@ func (l *List) listSubst(object *yaml.RNode) error {
|
||||
// the definition key -- contains the substitution name
|
||||
key := node.Key.YNode().Value
|
||||
|
||||
if !strings.HasPrefix(key, SubstitutionDefinitionPrefix) {
|
||||
if !strings.HasPrefix(key, fieldmeta.SubstitutionDefinitionPrefix) {
|
||||
// not a substitution -- doesn't have the right prefix
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/validate"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
|
||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||
@@ -268,7 +269,7 @@ func (s SetOpenAPI) UpdateFile(path string) error {
|
||||
}
|
||||
|
||||
func (s SetOpenAPI) Filter(object *yaml.RNode) (*yaml.RNode, error) {
|
||||
key := SetterDefinitionPrefix + s.Name
|
||||
key := fieldmeta.SetterDefinitionPrefix + s.Name
|
||||
oa, err := object.Pipe(yaml.Lookup("openAPI", "definitions", key))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -6,6 +6,7 @@ package settersutil
|
||||
import (
|
||||
"io/ioutil"
|
||||
|
||||
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||
"sigs.k8s.io/kustomize/kyaml/setters2"
|
||||
@@ -65,7 +66,7 @@ func (c SetterCreator) Create(openAPIPath, resourcesPath string) error {
|
||||
&setters2.Add{
|
||||
FieldName: c.FieldName,
|
||||
FieldValue: c.FieldValue,
|
||||
Ref: setters2.DefinitionsPrefix + setters2.SetterDefinitionPrefix + c.Name,
|
||||
Ref: fieldmeta.DefinitionsPrefix + fieldmeta.SetterDefinitionPrefix + c.Name,
|
||||
})},
|
||||
Outputs: []kio.Writer{inout},
|
||||
}.Execute()
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/fieldmeta"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||
"sigs.k8s.io/kustomize/kyaml/setters2"
|
||||
@@ -68,7 +69,7 @@ func (c SubstitutionCreator) Create(openAPIPath, resourcesPath string) error {
|
||||
&setters2.Add{
|
||||
FieldName: c.FieldName,
|
||||
FieldValue: c.FieldValue,
|
||||
Ref: setters2.DefinitionsPrefix + setters2.SubstitutionDefinitionPrefix + c.Name,
|
||||
Ref: fieldmeta.DefinitionsPrefix + fieldmeta.SubstitutionDefinitionPrefix + c.Name,
|
||||
})},
|
||||
Outputs: []kio.Writer{inout},
|
||||
}.Execute()
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# kyaml version
|
||||
export kyaml_major=0
|
||||
export kyaml_minor=1
|
||||
export kyaml_patch=12
|
||||
export kyaml_patch=13
|
||||
|
||||
# kstatus version
|
||||
export kstatus_major=0
|
||||
|
||||
@@ -2,4 +2,7 @@ module sigs.k8s.io/kustomize/releasing
|
||||
|
||||
go 1.13
|
||||
|
||||
require github.com/spf13/cobra v1.0.0
|
||||
require (
|
||||
github.com/spf13/cobra v1.0.0
|
||||
golang.org/x/mod v0.3.0
|
||||
)
|
||||
|
||||
@@ -103,29 +103,40 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
|
||||
@@ -212,6 +212,12 @@ func releaseCmdImpl(args []string) error {
|
||||
mod.Tag(),
|
||||
)
|
||||
|
||||
// Check is there replace statement in go.mod
|
||||
err = mod.CheckModReplace()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Run module tests
|
||||
output, err := mod.RunTest()
|
||||
if err != nil {
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/mod/modfile"
|
||||
)
|
||||
|
||||
type module struct {
|
||||
// Module name
|
||||
name string
|
||||
// Module path. This path is only used for running test.
|
||||
// Module path
|
||||
path string
|
||||
// Module version
|
||||
version moduleVersion
|
||||
@@ -23,6 +29,35 @@ func (m *module) UpdateVersion(tags string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *module) CheckModReplace() error {
|
||||
goModPath := filepath.Join(m.path, m.name, "go.mod")
|
||||
info, err := os.Stat(goModPath)
|
||||
if os.IsNotExist(err) || info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
|
||||
goModContent, err := ioutil.ReadFile(goModPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return checkModReplace(goModPath, goModContent)
|
||||
}
|
||||
|
||||
func checkModReplace(path string, data []byte) error {
|
||||
f, err := modfile.Parse(path, data, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(f.Replace) > 0 {
|
||||
var msg strings.Builder
|
||||
for _, replace := range f.Replace {
|
||||
fmt.Fprintf(&msg, " - Please update go.mod to pin a specific version of %s\n", replace.Old.Path)
|
||||
}
|
||||
return fmt.Errorf("Found replace in %s\n%s", path, msg.String())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *module) Tag() string {
|
||||
return m.name + "/" + m.version.String()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -66,3 +69,95 @@ func TestModuleTags(t *testing.T) {
|
||||
t.Errorf("Tag %s doesn't match expected %s", m.Tag(), expect)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckModReplace1(t *testing.T) {
|
||||
path := "testpath"
|
||||
dataString := `module sigs.k8s.io/kustomize/kustomize/v3
|
||||
|
||||
go 1.13
|
||||
|
||||
replace (
|
||||
sigs.k8s.io/kustomize/cmd/kubectl v0.0.3 => ../cmd/kubectl
|
||||
sigs.k8s.io/kustomize/kstatus v0.0.1 => ../kstatus
|
||||
)`
|
||||
|
||||
expect := `Found replace in testpath
|
||||
- Please update go.mod to pin a specific version of sigs.k8s.io/kustomize/cmd/kubectl
|
||||
- Please update go.mod to pin a specific version of sigs.k8s.io/kustomize/kstatus
|
||||
`
|
||||
|
||||
err := checkModReplace(path, []byte(dataString))
|
||||
if err.Error() != expect {
|
||||
t.Errorf("Error %s doesn't match expected %s", err.Error(), expect)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckModReplace2(t *testing.T) {
|
||||
path := "testpath"
|
||||
dataString := `module sigs.k8s.io/kustomize/kustomize/v3
|
||||
|
||||
go 1.13
|
||||
|
||||
replace sigs.k8s.io/kustomize/cmd/kubectl v0.0.3 => ../cmd/kubectl`
|
||||
|
||||
expect := `Found replace in testpath
|
||||
- Please update go.mod to pin a specific version of sigs.k8s.io/kustomize/cmd/kubectl
|
||||
`
|
||||
|
||||
err := checkModReplace(path, []byte(dataString))
|
||||
if err.Error() != expect {
|
||||
t.Errorf("Error %s doesn't match expected %s", err.Error(), expect)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckModReplace3(t *testing.T) {
|
||||
path := "testpath"
|
||||
dataString := `module sigs.k8s.io/kustomize/kustomize/v3
|
||||
|
||||
go 1.13
|
||||
|
||||
exclude (
|
||||
github.com/russross/blackfriday v2.0.0+incompatible
|
||||
sigs.k8s.io/kustomize/api v0.2.0
|
||||
)`
|
||||
|
||||
err := checkModReplace(path, []byte(dataString))
|
||||
if err != nil {
|
||||
t.Errorf("Error %s is not expected", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckModReplaceWithFile(t *testing.T) {
|
||||
dataString := `module sigs.k8s.io/kustomize/kustomize/v3
|
||||
|
||||
go 1.13
|
||||
|
||||
exclude (
|
||||
github.com/russross/blackfriday v2.0.0+incompatible
|
||||
sigs.k8s.io/kustomize/api v0.2.0
|
||||
)`
|
||||
|
||||
dir, err := ioutil.TempDir("", "kustomize-releases-test")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
modName := "kustomize"
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
err = os.MkdirAll(filepath.Join(dir, modName), os.FileMode(0700))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
ioutil.WriteFile(filepath.Join(dir, modName, "go.mod"), []byte(dataString), os.FileMode(0600))
|
||||
|
||||
m := module{
|
||||
name: modName,
|
||||
path: dir,
|
||||
}
|
||||
|
||||
err = m.CheckModReplace()
|
||||
if err != nil {
|
||||
t.Errorf("Error %s is not expected", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user