Compare commits

...

64 Commits

Author SHA1 Message Date
Jeff Regan
27b2c7f294 Update formatting of component_test.go 2020-07-17 18:31:54 -07:00
Jeff Regan
03d6229c0b Merge pull request #2732 from monopole/beanPole
Switch prefix transformer to kyaml.
2020-07-17 18:09:19 -07:00
jregan
71b7b00bd8 Switch prefix transformer to kyaml. 2020-07-17 16:08:41 -07:00
Jeff Regan
e9396dca2c Merge pull request #2731 from prachirp/go-plugins
Fix go plugins caveats link
2020-07-17 15:49:36 -07:00
Prachi Pendse
bc581b70bf Fix go plugins caveats link 2020-07-17 12:03:19 -07:00
Jeff Regan
ac1c31c82b Merge pull request #2730 from monopole/addTest
Add a test and temporarily disable some plugin tests.
2020-07-17 10:25:07 -07:00
jregan
c878957d0b Add a test and temporarily disable some plugin tests. 2020-07-17 08:23:11 -07:00
Jeff Regan
0b359d0ef0 Merge pull request #2727 from monopole/addE2eTests
Pre v3.8.1; Add e2e tests pinned at v3.8.0
2020-07-15 17:54:54 -07:00
jregan
22ee7cbd49 Pre v3.8.1; Add e2e tests pinned at v3.8.0 2020-07-15 17:33:43 -07:00
Jeff Regan
7bf9c7002f Merge pull request #2726 from monopole/pinToKustomizeApiV_0_5_1
Pin to kustomize/api v0.5.1
2020-07-15 17:26:12 -07:00
jregan
155411f229 Pin to kustomize/api v0.5.1 2020-07-15 17:00:33 -07:00
Jeff Regan
699cc70a7c Merge pull request #2725 from monopole/pinToKyamlv0_4_1
Pin To Kyaml/v0.4.1
2020-07-15 16:44:17 -07:00
jregan
a63a472024 Pin To Kyaml/v0.4.1 2020-07-15 16:17:12 -07:00
Jeff Regan
55f55a5091 Merge pull request #2718 from Shell32-Natsu/unknown-fields
Uniform unmarshal function
2020-07-15 14:36:06 -07:00
Donny Xia
8401196ef9 fix typo 2020-07-15 11:47:47 -07:00
Donny Xia
14edc3890c Add tests for kustomization.go 2020-07-15 11:42:50 -07:00
Donny Xia
897698fb29 Uniform unmarshal function 2020-07-14 17:01:43 -07:00
Jeff Regan
ec9ae3d7b0 Merge pull request #2713 from Shell32-Natsu/empty-list-in-patch
Keep empty array in output
2020-07-14 13:50:37 -07:00
Donny Xia
3a828941fa Improve tests 2020-07-14 11:38:29 -07:00
Jeff Regan
b63b5ce7cc Merge pull request #2683 from Shell32-Natsu/function-benchmark
KRM Function benchmark
2020-07-14 09:05:31 -07:00
Donny Xia
23bd4390d3 code review 2020-07-13 16:40:34 -07:00
Kubernetes Prow Robot
21a0fd33a2 Merge pull request #2696 from arrikto/feature-site-components-guide
docs: Add guide for components
2020-07-13 14:29:20 -07:00
Donny Xia
c6b6dec91f Add tests for IsEmpty and IsMissingorNull 2020-07-13 14:15:55 -07:00
Kubernetes Prow Robot
9cf4367db7 Merge pull request #2709 from aodinokov/fixmount
Fixed incorrect docker mount arguments generation
2020-07-13 12:35:22 -07:00
Jeff Regan
e9c118fd55 Update readme.md 2020-07-13 12:24:34 -07:00
Kubernetes Prow Robot
bfbb1971d4 Merge pull request #2695 from sunny0826/master
add favicons for doc site
2020-07-13 12:09:20 -07:00
Donny Xia
6fabfe963e code review 2020-07-13 12:05:03 -07:00
Donny Xia
67cdd2e27e Add test for keeping empty array 2020-07-13 11:50:01 -07:00
Jeff Regan
6c6b5f744d Merge pull request #2641 from jijiew/doc
doc for kustomize config delete setter
2020-07-13 11:38:43 -07:00
Jeff Regan
7775666c50 Merge pull request #2702 from kubernetes-sigs/dependabot/npm_and_yarn/api/internal/crawl/ui/npm-registry-fetch-4.0.5
Bump npm-registry-fetch from 4.0.2 to 4.0.5 in /api/internal/crawl/ui
2020-07-13 11:36:55 -07:00
Kubernetes Prow Robot
bdd7ae085e Merge pull request #2708 from monopole/byeByeFlag
Removing YAMLSupport==false code path.
2020-07-13 11:11:20 -07:00
Alexey Odinokov
ba3e09849a Made mountString params more similar to docker params
see [1]
kept support for the previous field names similarly to
docker behavior.

[1]
https://docs.docker.com/storage/bind-mounts/#use-a-read-only-bind-mount
2020-07-13 17:21:37 +00:00
Donny Xia
236ae29e9a Don't consider empty array as "empty" 2020-07-13 10:03:24 -07:00
Kubernetes Prow Robot
5c3bd83252 Merge pull request #2707 from mortent/FixDotInSetterName
Allow setters/substitutions with . in the name
2020-07-13 10:03:20 -07:00
Kubernetes Prow Robot
3674e0a91d Merge pull request #2711 from mortent/SubstitutionWithSameNameSetter
Don't allow creating setter with same name as substitution
2020-07-12 23:02:32 -07:00
Morten Torkildsen
f9631e4bb2 Don't allow creating setter with same name as substitution 2020-07-12 11:28:09 -07:00
Morten Torkildsen
c419c1efc3 Allow setters/substitutions with . in the name 2020-07-11 10:41:27 -07:00
Alexey Odinokov
63f9f79fc0 Fixed incorrect docker mount arguments generation
The previous implementation combined --mount and -v notation
of argument [1] adding :ro to make the read-only mount point.
E.g. the command [2] called docker with the following
params: [3]. As a result instead of the read-only
folder /tmp/source, the read-write folder /tmp/source/:ro/'
is created.

This PR:
1. substitutes ':ro' with correct ',readonly'.
2. changes 'src=' and 'dst=' with 'source=' and 'target=' as
   it is stated in the documentation [1]
3. introduces the ability to EXPLICITLY create a mountpoint
   with read-write access. To do so it's necessary to add
   ',rw=true' to the --mount argument
4. corrects UTs adds some additional coverage for added
   functionality

[1]
https://docs.docker.com/storage/bind-mounts/#use-a-read-only-bind-mount

[2]
kustomize fn run ./d --mount type=bind,src=$(pwd)/test/,dst=/tmp/source/

[3]
--mount type=bind,src=/home/ubuntu/kpt-functions-catalog/functions/ts/test/,dst=/tmp/source/:ro
2020-07-11 17:03:44 +00:00
jregan
33e68c0f97 Removing YAMLSupport==false code path.
This continues work on the master and v3.8.* branches
to eliminate apimachinery dependence.
2020-07-10 19:06:26 -07:00
Kubernetes Prow Robot
556eb48651 Merge pull request #2706 from mortent/FixCmdConfigGoMod
Fix go.mod file in cmd/config
2020-07-10 18:53:22 -07:00
Morten Torkildsen
5b26c3b4cc Fix go.mod file in cmd/config 2020-07-10 17:14:49 -07:00
Donny Xia
42e19d610a Improve cleanup 2020-07-08 11:08:19 -07:00
dependabot[bot]
950b1c895f Bump npm-registry-fetch from 4.0.2 to 4.0.5 in /api/internal/crawl/ui
Bumps [npm-registry-fetch](https://github.com/npm/registry-fetch) from 4.0.2 to 4.0.5.
- [Release notes](https://github.com/npm/registry-fetch/releases)
- [Changelog](https://github.com/npm/npm-registry-fetch/blob/latest/CHANGELOG.md)
- [Commits](https://github.com/npm/registry-fetch/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2020-07-08 00:49:07 +00:00
Kubernetes Prow Robot
ca5feb7751 Merge pull request #2700 from jijiew/win-seperator
modify the byteioreader to handler windows line ending.
2020-07-07 10:13:58 -07:00
Jijie Wei
488a88ec6e modify the bytereader to handler windows line ending. 2020-07-07 09:49:17 -07:00
Morten Torkildsen
fd3a4a88be Merge pull request #2699 from mortent/ReturnCmdConfigRedirects
Return go.mod replace directives
2020-07-06 21:28:37 -07:00
Morten Torkildsen
e6147347a8 Return go.mod replace directives 2020-07-06 21:12:32 -07:00
Morten Torkildsen
0b756877e1 Merge pull request #2698 from mortent/PrepCmdConfigForRelease
Prep cmd/config for release
2020-07-06 21:03:40 -07:00
Morten Torkildsen
0f4b5e6787 Prep cmd/config for release 2020-07-06 20:50:18 -07:00
Ioannis Androulidakis
1b531c6ac7 docs: Add guide for components
Extend the list of Kustomize guides available in the official website
with one about components, so that users can familiarize with this use
case and feature.

Signed-off-by: Ioannis Androulidakis <ioannis@arrikto.com>
2020-07-06 23:15:49 +03:00
Donny Xia
f6cac7e7e8 Add newline to the end of file 2020-07-06 09:38:31 -07:00
guoxudong
fe0577a15f add favicons 2020-07-06 09:42:23 +08:00
guoxudong
f68740be66 add favicons 2020-07-06 09:42:09 +08:00
Kubernetes Prow Robot
855ce1a8db Merge pull request #2693 from t0rr3sp3dr0/master
Update function annotation on docs
2020-07-05 18:06:50 -07:00
Jeff Regan
6a50372dd5 Merge pull request #2694 from monopole/switchToApiV0_5_0
Switch to kustomize/api v0.5.0
2020-07-04 21:22:19 -07:00
jregan
5a0228629f Switch kustomize to api/v0.5.0 2020-07-04 19:45:45 -07:00
Jeff Regan
def00220ce Merge pull request #2668 from monopole/doesItWork
Switch namespace and patch transformers to kyaml.
2020-07-04 17:11:56 -07:00
jregan
d3a7335bbc Switch namespace and patch transformers to kyaml. 2020-07-04 16:21:01 -07:00
Pedro Tôrres
94095a63ff Update function annotation on docs
Signed-off-by: Pedro Tôrres <t0rr3sp3dr0@gmail.com>
2020-07-04 18:19:28 -03:00
Donny Xia
c2ccfd72ad Update readme 2020-07-01 12:55:38 -07:00
Donny Xia
6d324d70c4 Add benchmark for containerized KRM function in kustomize 2020-07-01 12:47:16 -07:00
Jijie Wei
e32aa8ddb2 revert generated doc change 2020-06-23 14:22:09 -07:00
Jijie Wei
b92de5cb80 revert change in generated doc 2020-06-23 14:17:39 -07:00
Jijie Wei
ecfa732a04 doc for kustomize config delete setter 2020-06-23 13:47:19 -07:00
300 changed files with 10975 additions and 1368 deletions

View File

@@ -15,7 +15,7 @@ verify-kustomize: \
lint-kustomize \
test-unit-kustomize-all \
test-examples-kustomize-against-HEAD \
test-examples-kustomize-against-3.6.1
test-examples-kustomize-against-3.8.0
# The following target referenced by a file in
# https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/kustomize
@@ -23,10 +23,10 @@ verify-kustomize: \
prow-presubmit-check: \
lint-kustomize \
test-unit-kustomize-all \
test-examples-kustomize-against-HEAD \
test-examples-kustomize-against-3.6.1 \
test-unit-cmd-all \
test-go-mod
test-go-mod \
test-examples-kustomize-against-HEAD \
test-examples-kustomize-against-3.8.0
.PHONY: verify-kustomize-e2e
verify-kustomize-e2e: test-examples-e2e-kustomize
@@ -233,10 +233,10 @@ test-examples-kustomize-against-HEAD: $(MYGOBIN)/kustomize $(MYGOBIN)/mdrip
./hack/testExamplesAgainstKustomize.sh HEAD
.PHONY:
test-examples-kustomize-against-3.6.1: $(MYGOBIN)/mdrip
test-examples-kustomize-against-3.8.0: $(MYGOBIN)/mdrip
( \
set -e; \
tag=v3.6.1; \
tag=v3.8.0; \
/bin/rm -f $(MYGOBIN)/kustomize; \
echo "Installing kustomize $$tag."; \
GO111MODULE=on go get sigs.k8s.io/kustomize/kustomize/v3@$${tag}; \

View File

@@ -10,7 +10,6 @@ import (
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/transform"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filtersutil"
"sigs.k8s.io/yaml"
@@ -20,11 +19,6 @@ import (
type NamespaceTransformerPlugin struct {
types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
FieldSpecs []types.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
// YAMLSupport can be set to true to use the kyaml filter instead of the
// kunstruct transformer.
// TODO: change the default to use kyaml when it is stable
YAMLSupport bool `json:"yamlSupport,omitempty" yaml:"yamlSupport,omitempty"`
}
func (p *NamespaceTransformerPlugin) Config(
@@ -43,31 +37,13 @@ func (p *NamespaceTransformerPlugin) Transform(m resmap.ResMap) error {
// Don't mutate empty objects?
continue
}
id := r.OrgId()
if p.YAMLSupport {
// use the new style transform
err := filtersutil.ApplyToJSON(namespace.Filter{
Namespace: p.Namespace,
FsSlice: p.FieldSpecs,
}, r)
if err != nil {
return err
}
} else {
// use the old style transform
applicableFs := p.applicableFieldSpecs(id)
for _, fs := range applicableFs {
err := transform.MutateField(
r.Map(), fs.PathSlice(), fs.CreateIfNotPresent,
p.changeNamespace(r))
if err != nil {
return err
}
}
err := filtersutil.ApplyToJSON(namespace.Filter{
Namespace: p.Namespace,
FsSlice: p.FieldSpecs,
}, r)
if err != nil {
return err
}
matches := m.GetMatchingResourcesByCurrentId(r.CurId().Equals)
if len(matches) != 1 {
return fmt.Errorf(

View File

@@ -23,8 +23,6 @@ type PatchJson6902TransformerPlugin struct {
Target types.PatchTarget `json:"target,omitempty" yaml:"target,omitempty"`
Path string `json:"path,omitempty" yaml:"path,omitempty"`
JsonOp string `json:"jsonOp,omitempty" yaml:"jsonOp,omitempty"`
YAMLSupport bool `json:"yamlSupport,omitempty" yaml:"yamlSupport,omitempty"`
}
func (p *PatchJson6902TransformerPlugin) Config(
@@ -87,22 +85,9 @@ func (p *PatchJson6902TransformerPlugin) Transform(m resmap.ResMap) error {
if err != nil {
return err
}
if !p.YAMLSupport {
rawObj, err := obj.MarshalJSON()
if err != nil {
return err
}
modifiedObj, err := p.decodedPatch.Apply(rawObj)
if err != nil {
return errors.Wrapf(
err, "failed to apply json patch '%s'", p.JsonOp)
}
return obj.UnmarshalJSON(modifiedObj)
} else {
return filtersutil.ApplyToJSON(patchjson6902.Filter{
Patch: p.JsonOp,
}, obj)
}
return filtersutil.ApplyToJSON(patchjson6902.Filter{
Patch: p.JsonOp,
}, obj)
}
func NewPatchJson6902TransformerPlugin() resmap.TransformerPlugin {

View File

@@ -5,7 +5,9 @@ package builtins
import (
"fmt"
"strings"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/filters/patchstrategicmerge"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
@@ -19,8 +21,6 @@ type PatchStrategicMergeTransformerPlugin struct {
loadedPatches []*resource.Resource
Paths []types.PatchStrategicMerge `json:"paths,omitempty" yaml:"paths,omitempty"`
Patches string `json:"patches,omitempty" yaml:"patches,omitempty"`
YAMLSupport bool `json:"yamlSupport,omitempty" yaml:"yamlSupport,omitempty"`
}
func (p *PatchStrategicMergeTransformerPlugin) Config(
@@ -73,31 +73,43 @@ func (p *PatchStrategicMergeTransformerPlugin) Transform(m resmap.ResMap) error
if err != nil {
return err
}
if !p.YAMLSupport {
err = target.Patch(patch.Copy())
patchCopy := patch.DeepCopy()
patchCopy.SetName(target.GetName())
patchCopy.SetNamespace(target.GetNamespace())
patchCopy.SetGvk(target.GetGvk())
node, err := filtersutil.GetRNode(patchCopy)
if err != nil {
return err
}
err = filtersutil.ApplyToJSON(patchstrategicmerge.Filter{
Patch: node,
}, target)
if err != nil {
// Check for an error string from UnmarshalJSON that's indicative
// of an object that's missing basic KRM fields, and thus may have been
// entirely deleted (an acceptable outcome). This error handling should
// be deleted along with use of ResMap and apimachinery functions like
// UnmarshalJSON.
if !strings.Contains(err.Error(), "Object 'Kind' is missing") {
// Some unknown error, let it through.
return err
}
if len(target.Map()) != 0 {
return errors.Wrapf(
err, "with unexpectedly non-empty object map of size %d",
len(target.Map()))
}
// Fall through to handle deleted object.
}
if len(target.Map()) == 0 {
// This means all fields have been removed from the object.
// This can happen if a patch required deletion of the
// entire resource (not just a part of it). This means
// the overall resmap must shrink by one.
err = m.Remove(target.CurId())
if err != nil {
return err
}
// remove the resource from resmap
// when the patch is to $patch: delete that target
if len(target.Map()) == 0 {
err = m.Remove(target.CurId())
if err != nil {
return err
}
}
} else {
patchCopy := patch.DeepCopy()
patchCopy.SetName(target.GetName())
patchCopy.SetNamespace(target.GetNamespace())
patchCopy.SetGvk(target.GetGvk())
node, err := filtersutil.GetRNode(patchCopy)
if err != nil {
return err
}
err = filtersutil.ApplyToJSON(patchstrategicmerge.Filter{
Patch: node,
}, target)
}
}
return nil

View File

@@ -8,7 +8,6 @@ import (
"strings"
jsonpatch "github.com/evanphx/json-patch"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/filters/patchjson6902"
"sigs.k8s.io/kustomize/api/filters/patchstrategicmerge"
"sigs.k8s.io/kustomize/api/resmap"
@@ -24,8 +23,6 @@ type PatchTransformerPlugin struct {
Path string `json:"path,omitempty" yaml:"path,omitempty"`
Patch string `json:"patch,omitempty" yaml:"patch,omitempty"`
Target *types.Selector `json:"target,omitempty" yaml:"target,omitempty"`
YAMLSupport bool `json:"yamlSupport,omitempty" yaml:"yamlSupport,omitempty"`
}
func (p *PatchTransformerPlugin) Config(
@@ -73,11 +70,11 @@ func (p *PatchTransformerPlugin) Config(
}
func (p *PatchTransformerPlugin) Transform(m resmap.ResMap) error {
if p.loadedPatch != nil {
if p.loadedPatch == nil {
return p.transformJson6902(m, p.decodedPatch)
} else {
// The patch was a strategic merge patch
return p.transformStrategicMerge(m, p.loadedPatch)
} else {
return p.transformJson6902(m, p.decodedPatch)
}
}
@@ -111,20 +108,15 @@ func (p *PatchTransformerPlugin) transformStrategicMerge(m resmap.ResMap, patch
}
// applySMPatch applies the provided strategic merge patch to the
// given resource. Depending on the value of YAMLSupport, it will either
// use the legacy implementation or the kyaml-based solution.
// given resource.
func (p *PatchTransformerPlugin) applySMPatch(resource, patch *resource.Resource) error {
if !p.YAMLSupport {
return resource.Patch(patch.Copy())
} else {
node, err := filtersutil.GetRNode(patch)
if err != nil {
return err
}
return filtersutil.ApplyToJSON(patchstrategicmerge.Filter{
Patch: node,
}, resource)
node, err := filtersutil.GetRNode(patch)
if err != nil {
return err
}
return filtersutil.ApplyToJSON(patchstrategicmerge.Filter{
Patch: node,
}, resource)
}
// transformJson6902 applies the provided json6902 patch
@@ -133,13 +125,14 @@ func (p *PatchTransformerPlugin) transformJson6902(m resmap.ResMap, patch jsonpa
if p.Target == nil {
return fmt.Errorf("must specify a target for patch %s", p.Patch)
}
resources, err := m.Select(*p.Target)
if err != nil {
return err
}
for _, res := range resources {
err = p.applyJson6902Patch(res, patch)
err = filtersutil.ApplyToJSON(patchjson6902.Filter{
Patch: p.Patch,
}, res)
if err != nil {
return err
}
@@ -147,28 +140,6 @@ func (p *PatchTransformerPlugin) transformJson6902(m resmap.ResMap, patch jsonpa
return nil
}
// applyJson6902Patch applies the provided patch to the given resource.
// Depending on the value of YAMLSupport, it will either
// use the legacy implementation or the kyaml-based solution.
func (p *PatchTransformerPlugin) applyJson6902Patch(resource *resource.Resource, patch jsonpatch.Patch) error {
if !p.YAMLSupport {
rawObj, err := resource.MarshalJSON()
if err != nil {
return err
}
modifiedObj, err := patch.Apply(rawObj)
if err != nil {
return errors.Wrapf(
err, "failed to apply json patch '%s'", p.Patch)
}
return resource.UnmarshalJSON(modifiedObj)
} else {
return filtersutil.ApplyToJSON(patchjson6902.Filter{
Patch: p.Patch,
}, resource)
}
}
// jsonPatchFromBytes loads a Json 6902 patch from
// a bytes input
func jsonPatchFromBytes(

View File

@@ -5,31 +5,27 @@ package builtins
import (
"errors"
"fmt"
"sigs.k8s.io/kustomize/api/transform"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/api/filters/prefixsuffix"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filtersutil"
"sigs.k8s.io/yaml"
)
// Add the given prefix and suffix to the field.
type PrefixSuffixTransformerPlugin struct {
Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"`
Suffix string `json:"suffix,omitempty" yaml:"suffix,omitempty"`
FieldSpecs []types.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"`
Suffix string `json:"suffix,omitempty" yaml:"suffix,omitempty"`
FieldSpecs types.FsSlice `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
}
// Not placed in a file yet due to lack of demand.
var prefixSuffixFieldSpecsToSkip = []types.FieldSpec{
{
Gvk: resid.Gvk{Kind: "CustomResourceDefinition"},
},
{
Gvk: resid.Gvk{Group: "apiregistration.k8s.io", Kind: "APIService"},
},
// A Gvk skip list for prefix/suffix modification.
// hard coded for now - eventually should be part of config.
var prefixSuffixFieldSpecsToSkip = types.FsSlice{
{Gvk: resid.Gvk{Kind: "CustomResourceDefinition"}},
{Gvk: resid.Gvk{Group: "apiregistration.k8s.io", Kind: "APIService"}},
}
func (p *PrefixSuffixTransformerPlugin) Config(
@@ -48,29 +44,24 @@ func (p *PrefixSuffixTransformerPlugin) Config(
}
func (p *PrefixSuffixTransformerPlugin) Transform(m resmap.ResMap) error {
// Even if both the Prefix and Suffix are empty we want
// to proceed with the transformation. This allows to add contextual
// information to the resources (AddNamePrefix and AddNameSuffix).
for _, r := range m.Resources() {
// TODO: move this test into the filter (i.e. make a better filter)
if p.shouldSkip(r.OrgId()) {
// Don't change the actual definition
// of a CRD.
continue
}
id := r.OrgId()
// current default configuration contains
// only one entry: "metadata/name" with no GVK
for _, path := range p.FieldSpecs {
if !id.IsSelected(&path.Gvk) {
// With the currrent default configuration,
// because no Gvk is specified, so a wild
// card
for _, fs := range p.FieldSpecs {
// TODO: this is redundant to filter (but needed for now)
if !id.IsSelected(&fs.Gvk) {
continue
}
if smellsLikeANameChange(&path) {
// TODO: move this test into the filter.
if smellsLikeANameChange(&fs) {
// "metadata/name" is the only field.
// this will add a prefix and a suffix
// to the resource even if those are
@@ -78,15 +69,11 @@ func (p *PrefixSuffixTransformerPlugin) Transform(m resmap.ResMap) error {
r.AddNamePrefix(p.Prefix)
r.AddNameSuffix(p.Suffix)
}
// the addPrefixSuffix method will not
// change the name if both the prefix and suffix
// are empty.
err := transform.MutateField(
r.Map(),
path.PathSlice(),
path.CreateIfNotPresent,
p.addPrefixSuffix)
err := filtersutil.ApplyToJSON(prefixsuffix.Filter{
Prefix: p.Prefix,
Suffix: p.Suffix,
FieldSpec: fs,
}, r)
if err != nil {
return err
}
@@ -99,8 +86,7 @@ func smellsLikeANameChange(fs *types.FieldSpec) bool {
return fs.Path == "metadata/name"
}
func (p *PrefixSuffixTransformerPlugin) shouldSkip(
id resid.ResId) bool {
func (p *PrefixSuffixTransformerPlugin) shouldSkip(id resid.ResId) bool {
for _, path := range prefixSuffixFieldSpecsToSkip {
if id.IsSelected(&path.Gvk) {
return true
@@ -109,15 +95,6 @@ func (p *PrefixSuffixTransformerPlugin) shouldSkip(
return false
}
func (p *PrefixSuffixTransformerPlugin) addPrefixSuffix(
in interface{}) (interface{}, error) {
s, ok := in.(string)
if !ok {
return nil, fmt.Errorf("%#v is expected to be %T", in, s)
}
return fmt.Sprintf("%s%s%s", p.Prefix, s, p.Suffix), nil
}
func NewPrefixSuffixTransformerPlugin() resmap.TransformerPlugin {
return &PrefixSuffixTransformerPlugin{}
}

View File

@@ -30,7 +30,7 @@ func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
for _, k := range keys {
if err := node.PipeE(fsslice.Filter{
FsSlice: f.FsSlice,
SetValue: fsslice.SetEntry(k, f.Annotations[k], yaml.StringTag),
SetValue: filtersutil.SetEntry(k, f.Annotations[k], yaml.StringTag),
CreateKind: yaml.MappingNode, // Annotations are MappingNodes.
CreateTag: "!!map",
}); err != nil {

View File

@@ -0,0 +1,6 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// Package fieldspec contains a yaml.Filter to modify a resource
// that matches the FieldSpec.
package fieldspec

View File

@@ -0,0 +1,61 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package fieldspec_test
import (
"bytes"
"log"
"os"
. "sigs.k8s.io/kustomize/api/filters/fieldspec"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
func ExampleFilter() {
in := &kio.ByteReader{
Reader: bytes.NewBufferString(`
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
---
apiVersion: example.com/v1
kind: Bar
metadata:
name: instance
`),
}
fltr := Filter{
CreateKind: yaml.ScalarNode,
SetValue: filtersutil.SetScalar("green"),
FieldSpec: types.FieldSpec{Path: "a/b", CreateIfNotPresent: true},
}
err := kio.Pipeline{
Inputs: []kio.Reader{in},
Filters: []kio.Filter{kio.FilterAll(fltr)},
Outputs: []kio.Writer{kio.ByteWriter{Writer: os.Stdout}},
}.Execute()
if err != nil {
log.Fatal(err)
}
// Output:
// apiVersion: example.com/v1
// kind: Foo
// metadata:
// name: instance
// a:
// b: green
// ---
// apiVersion: example.com/v1
// kind: Bar
// metadata:
// name: instance
// a:
// b: green
}

View File

@@ -1,24 +1,27 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package fsslice
package fieldspec
import (
"strings"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// fieldSpecFilter applies a single fieldSpec to a single object
// fieldSpecFilter stores internal state and should not be reused
type fieldSpecFilter struct {
var _ yaml.Filter = Filter{}
// Filter applies a single fieldSpec to a single object
// Filter stores internal state and should not be reused
type Filter struct {
// FieldSpec contains the path to the value to set.
FieldSpec types.FieldSpec `yaml:"fieldSpec"`
// Set the field using this function
SetValue SetFn
SetValue filtersutil.SetFn
// CreateKind defines the type of node to create if the field is not found
CreateKind yaml.Kind
@@ -29,7 +32,7 @@ type fieldSpecFilter struct {
path []string
}
func (fltr fieldSpecFilter) Filter(obj *yaml.RNode) (*yaml.RNode, error) {
func (fltr Filter) Filter(obj *yaml.RNode) (*yaml.RNode, error) {
// check if the FieldSpec applies to the object
if match, err := isMatchGVK(fltr.FieldSpec, obj); !match || err != nil {
return obj, errors.Wrap(err)
@@ -43,7 +46,7 @@ func (fltr fieldSpecFilter) Filter(obj *yaml.RNode) (*yaml.RNode, error) {
return obj, nil
}
func (fltr fieldSpecFilter) filter(obj *yaml.RNode) error {
func (fltr Filter) filter(obj *yaml.RNode) error {
if len(fltr.path) == 0 {
// found the field -- set its value
return fltr.SetValue(obj)
@@ -60,7 +63,7 @@ func (fltr fieldSpecFilter) filter(obj *yaml.RNode) error {
}
// field calls filter on the field matching the next path element
func (fltr fieldSpecFilter) field(obj *yaml.RNode) error {
func (fltr Filter) field(obj *yaml.RNode) error {
fieldName, isSeq := isSequenceField(fltr.path[0])
// lookup the field matching the next path element
@@ -104,9 +107,9 @@ func (fltr fieldSpecFilter) field(obj *yaml.RNode) error {
}
// seq calls filter on all sequence elements
func (fltr fieldSpecFilter) seq(obj *yaml.RNode) error {
func (fltr Filter) seq(obj *yaml.RNode) error {
if err := obj.VisitElements(func(node *yaml.RNode) error {
// recurse on each element -- re-allocating a fieldSpecFilter is
// recurse on each element -- re-allocating a Filter is
// not strictly required, but is more consistent with field
// and less likely to have side effects
// keep the entire path -- it does not contain parts for sequences

View File

@@ -0,0 +1,380 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package fieldspec_test
import (
"bytes"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filters/fieldspec"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
type TestCase struct {
name string
input string
expected string
filter fieldspec.Filter
fieldSpec string
error string
}
var tests = []TestCase{
{
name: "update",
fieldSpec: `
path: a/b
group: foo
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a:
b: c
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a:
b: e
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
},
{
name: "update-kind-not-match",
fieldSpec: `
path: a/b
group: foo
kind: Bar1
`,
input: `
apiVersion: foo/v1beta1
kind: Bar2
a:
b: c
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar2
a:
b: c
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
},
{
name: "update-group-not-match",
fieldSpec: `
path: a/b
group: foo1
kind: Bar
`,
input: `
apiVersion: foo2/v1beta1
kind: Bar
a:
b: c
`,
expected: `
apiVersion: foo2/v1beta1
kind: Bar
a:
b: c
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
},
{
name: "update-version-not-match",
fieldSpec: `
path: a/b
group: foo
version: v1beta1
kind: Bar
`,
input: `
apiVersion: foo/v1beta2
kind: Bar
a:
b: c
`,
expected: `
apiVersion: foo/v1beta2
kind: Bar
a:
b: c
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
},
{
name: "bad-version",
fieldSpec: `
path: a/b
group: foo
version: v1beta1
kind: Bar
`,
input: `
apiVersion: foo/v1beta2/something
kind: Bar
a:
b: c
`,
expected: `
apiVersion: foo/v1beta2/something
kind: Bar
a:
b: c
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
},
{
name: "bad-meta",
fieldSpec: `
path: a/b
group: foo
version: v1beta1
kind: Bar
`,
input: `
a:
b: c
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
error: "missing Resource metadata",
},
{
name: "miss-match-type",
fieldSpec: `
path: a/b/c
kind: Bar
`,
input: `
kind: Bar
a:
b: a
`,
error: "obj kind: Bar\na:\n b: a\n at path a/b/c: unsupported yaml node",
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
},
{
name: "add",
fieldSpec: `
path: a/b/c/d
group: foo
create: true
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a: {}
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a: {b: {c: {d: e}}}
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
{
name: "update-in-sequence",
fieldSpec: `
path: a/b[]/c/d
group: foo
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c:
d: a
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c:
d: e
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
},
},
// Don't create a sequence
{
name: "empty-sequence-no-create",
fieldSpec: `
path: a/b[]/c/d
group: foo
create: true
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a: {}
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a: {}
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
// Create a new field for an element in a sequence
{
name: "empty-sequence-create",
fieldSpec: `
path: a/b[]/c/d
group: foo
create: true
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c: {}
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c: {d: e}
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
{
name: "group v1",
fieldSpec: `
path: a/b
group: v1
create: true
kind: Bar
`,
input: `
apiVersion: v1
kind: Bar
`,
expected: `
apiVersion: v1
kind: Bar
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
{
name: "version v1",
fieldSpec: `
path: a/b
version: v1
create: true
kind: Bar
`,
input: `
apiVersion: v1
kind: Bar
`,
expected: `
apiVersion: v1
kind: Bar
a:
b: e
`,
filter: fieldspec.Filter{
SetValue: filtersutil.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
}
func TestFilter_Filter(t *testing.T) {
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
err := yaml.Unmarshal([]byte(test.fieldSpec), &test.filter.FieldSpec)
if !assert.NoError(t, err) {
t.FailNow()
}
out := &bytes.Buffer{}
rw := &kio.ByteReadWriter{
Reader: bytes.NewBufferString(test.input),
Writer: out,
OmitReaderAnnotations: true,
}
// run the filter
err = kio.Pipeline{
Inputs: []kio.Reader{rw},
Filters: []kio.Filter{kio.FilterAll(test.filter)},
Outputs: []kio.Writer{rw},
}.Execute()
if test.error != "" {
if !assert.EqualError(t, err, test.error) {
t.FailNow()
}
// stop rest of test
return
}
if !assert.NoError(t, err) {
t.FailNow()
}
// check results
if !assert.Equal(t,
strings.TrimSpace(test.expected),
strings.TrimSpace(out.String())) {
t.FailNow()
}
})
}
}

View File

@@ -1,6 +1,6 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package fsslice
package fieldspec
import (
"strings"

View File

@@ -1,6 +1,6 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package fsslice
package fieldspec
import (
"strings"

View File

@@ -0,0 +1,33 @@
package filtersutil
import (
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// SetFn is a function that accepts an RNode to possibly modify.
type SetFn func(*yaml.RNode) error
// SetScalar returns a SetFn to set a scalar value
func SetScalar(value string) SetFn {
return func(node *yaml.RNode) error {
return node.PipeE(yaml.FieldSetter{StringValue: value})
}
}
// SetEntry returns a SetFn to set an entry in a map
func SetEntry(key, value, tag string) SetFn {
n := &yaml.Node{
Kind: yaml.ScalarNode,
Value: value,
Tag: tag,
}
if tag == yaml.StringTag && yaml.IsYaml1_1NonString(n) {
n.Style = yaml.DoubleQuotedStyle
}
return func(node *yaml.RNode) error {
return node.PipeE(yaml.FieldSetter{
Name: key,
Value: yaml.NewRNode(n),
})
}
}

View File

@@ -1,6 +1,6 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// Package fsslice contains a yaml.Filter to modify a resource using an
// FsSlice to identify fields to be updated within the resource.
// Package fsslice contains a yaml.Filter to modify a resource if
// it matches one or more FieldSpec entries.
package fsslice

View File

@@ -8,6 +8,7 @@ import (
"log"
"os"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/filters/fsslice"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
@@ -30,7 +31,7 @@ metadata:
}
fltr := fsslice.Filter{
CreateKind: yaml.ScalarNode,
SetValue: fsslice.SetScalar("green"),
SetValue: filtersutil.SetScalar("green"),
FsSlice: []types.FieldSpec{
{Path: "a/b", CreateIfNotPresent: true},
},

View File

@@ -4,48 +4,22 @@
package fsslice
import (
"sigs.k8s.io/kustomize/api/filters/fieldspec"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// SetFn sets a value
type SetFn func(*yaml.RNode) error
// SetScalar returns a SetFn to set a scalar value
func SetScalar(value string) SetFn {
return func(node *yaml.RNode) error {
return node.PipeE(yaml.FieldSetter{StringValue: value})
}
}
// SetEntry returns a SetFn to set an entry in a map
func SetEntry(key, value, tag string) SetFn {
n := &yaml.Node{
Kind: yaml.ScalarNode,
Value: value,
Tag: tag,
}
if tag == yaml.StringTag && yaml.IsYaml1_1NonString(n) {
n.Style = yaml.DoubleQuotedStyle
}
return func(node *yaml.RNode) error {
return node.PipeE(yaml.FieldSetter{
Name: key,
Value: yaml.NewRNode(n),
})
}
}
var _ yaml.Filter = Filter{}
// Filter uses an FsSlice to modify fields on a single object
// Filter ranges over an FsSlice to modify fields on a single object.
// An FsSlice is a range of FieldSpecs. A FieldSpec is a GVK plus a path.
type Filter struct {
// FieldSpecList list of FieldSpecs to set
FsSlice types.FsSlice `yaml:"fsSlice"`
// SetValue is called on each field that matches one of the FieldSpecs
SetValue SetFn
SetValue filtersutil.SetFn
// CreateKind is used to create fields that do not exist
CreateKind yaml.Kind
@@ -59,7 +33,7 @@ func (fltr Filter) Filter(obj *yaml.RNode) (*yaml.RNode, error) {
// apply this FieldSpec
// create a new filter for each iteration because they
// store internal state about the field paths
_, err := (&fieldSpecFilter{
_, err := (&fieldspec.Filter{
FieldSpec: fltr.FsSlice[i],
SetValue: fltr.SetValue,
CreateKind: fltr.CreateKind,

View File

@@ -9,335 +9,77 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filters/fsslice"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
. "sigs.k8s.io/kustomize/api/filters/fsslice"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
type TestCase struct {
name string
input string
expected string
filter fsslice.Filter
filter Filter
fsSlice string
error string
}
var tests = []TestCase{
{
name: "update",
var tests = map[string]TestCase{
"empty": {
fsSlice: `
- path: a/b
group: foo
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
apiVersion: foo/v1
kind: Bar
a:
b: c
`,
expected: `
apiVersion: foo/v1beta1
apiVersion: foo/v1
kind: Bar
a:
b: e
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
},
},
{
name: "update-kind-not-match",
fsSlice: `
- path: a/b
group: foo
kind: Bar1
`,
input: `
apiVersion: foo/v1beta1
kind: Bar2
a:
b: c
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar2
a:
b: c
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
},
},
{
name: "update-group-not-match",
fsSlice: `
- path: a/b
group: foo1
kind: Bar
`,
input: `
apiVersion: foo2/v1beta1
kind: Bar
a:
b: c
`,
expected: `
apiVersion: foo2/v1beta1
kind: Bar
a:
b: c
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
},
},
{
name: "update-version-not-match",
fsSlice: `
- path: a/b
group: foo
version: v1beta1
kind: Bar
`,
input: `
apiVersion: foo/v1beta2
kind: Bar
a:
b: c
`,
expected: `
apiVersion: foo/v1beta2
kind: Bar
a:
b: c
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
},
},
{
name: "bad-version",
fsSlice: `
- path: a/b
group: foo
version: v1beta1
kind: Bar
`,
input: `
apiVersion: foo/v1beta2/something
kind: Bar
a:
b: c
`,
expected: `
apiVersion: foo/v1beta2/something
kind: Bar
a:
b: c
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
},
},
{
name: "bad-meta",
fsSlice: `
- path: a/b
group: foo
version: v1beta1
kind: Bar
`,
input: `
a:
b: c
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
},
error: "missing Resource metadata",
},
{
name: "miss-match-type",
fsSlice: `
- path: a/b/c
kind: Bar
`,
input: `
kind: Bar
a:
b: a
`,
error: "obj kind: Bar\na:\n b: a\n at path a/b/c: unsupported yaml node",
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
},
},
{
name: "add",
fsSlice: `
- path: a/b/c/d
group: foo
create: true
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a: {}
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a: {b: {c: {d: e}}}
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
filter: Filter{
SetValue: filtersutil.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
{
name: "update-in-sequence",
fsSlice: `
- path: a/b[]/c/d
group: foo
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c:
d: a
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c:
d: e
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
},
},
// Don't create a sequence
{
name: "empty-sequence-no-create",
fsSlice: `
- path: a/b[]/c/d
group: foo
create: true
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a: {}
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a: {}
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
// Create a new field for an element in a sequence
{
name: "empty-sequence-create",
fsSlice: `
- path: a/b[]/c/d
group: foo
create: true
kind: Bar
`,
input: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c: {}
`,
expected: `
apiVersion: foo/v1beta1
kind: Bar
a:
b:
- c: {d: e}
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
{
name: "group v1",
"two": {
fsSlice: `
- path: a/b
group: v1
group: foo
version: v1
create: true
kind: Bar
`,
input: `
apiVersion: v1
kind: Bar
`,
expected: `
apiVersion: v1
kind: Bar
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
{
name: "version v1",
fsSlice: `
- path: a/b
- path: q/r[]/s/t
group: foo
version: v1
create: true
kind: Bar
`,
input: `
apiVersion: v1
apiVersion: foo/v1
kind: Bar
q:
r:
- s: {}
`,
expected: `
apiVersion: v1
apiVersion: foo/v1
kind: Bar
q:
r:
- s: {t: e}
a:
b: e
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
filter: Filter{
SetValue: filtersutil.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
}
func TestFilter_Filter(t *testing.T) {
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
func TestFilter(t *testing.T) {
for name := range tests {
test := tests[name]
t.Run(name, func(t *testing.T) {
err := yaml.Unmarshal([]byte(test.fsSlice), &test.filter.FsSlice)
if !assert.NoError(t, err) {
t.FailNow()

View File

@@ -4,6 +4,7 @@
package imagetag
import (
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/filters/fsslice"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
@@ -35,7 +36,7 @@ func (f Filter) filter(node *yaml.RNode) (*yaml.RNode, error) {
return node, nil
}
func updateImageTagFn(imageTag types.Image) fsslice.SetFn {
func updateImageTagFn(imageTag types.Image) filtersutil.SetFn {
return func(node *yaml.RNode) error {
return node.PipeE(imageTagUpdater{
ImageTag: imageTag,

View File

@@ -31,7 +31,7 @@ func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
for _, k := range keys {
if err := node.PipeE(fsslice.Filter{
FsSlice: f.FsSlice,
SetValue: fsslice.SetEntry(k, f.Labels[k], yaml.StringTag),
SetValue: filtersutil.SetEntry(k, f.Labels[k], yaml.StringTag),
CreateKind: yaml.MappingNode, // Labels are MappingNodes.
CreateTag: "!!map",
}); err != nil {

View File

@@ -4,6 +4,8 @@
package namespace
import (
"sigs.k8s.io/kustomize/api/filters/fieldspec"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/filters/fsslice"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
@@ -42,7 +44,7 @@ func (ns Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
// transformations based on data -- :)
err := node.PipeE(fsslice.Filter{
FsSlice: ns.FsSlice,
SetValue: fsslice.SetScalar(ns.Namespace),
SetValue: filtersutil.SetScalar(ns.Namespace),
CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode
CreateTag: yaml.StringTag,
})
@@ -73,7 +75,7 @@ func (ns Filter) hacks(obj *yaml.RNode) error {
// if they are cluster scoped through either an annotation on the resources,
// or through inlined OpenAPI on the resource as a YAML comment.
func (ns Filter) metaNamespaceHack(obj *yaml.RNode, meta yaml.ResourceMeta) error {
gvk := fsslice.GetGVK(meta)
gvk := fieldspec.GetGVK(meta)
if !gvk.IsNamespaceableKind() {
return nil
}
@@ -81,7 +83,7 @@ func (ns Filter) metaNamespaceHack(obj *yaml.RNode, meta yaml.ResourceMeta) erro
FsSlice: []types.FieldSpec{
{Path: types.MetadataNamespacePath, CreateIfNotPresent: true},
},
SetValue: fsslice.SetScalar(ns.Namespace),
SetValue: filtersutil.SetScalar(ns.Namespace),
CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode
}
_, err := f.Filter(obj)

View File

@@ -1,3 +1,6 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package patchstrategicmerge
import (
@@ -13,9 +16,13 @@ type Filter struct {
var _ kio.Filter = Filter{}
func (pf Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
return kio.FilterAll(yaml.FilterFunc(pf.run)).Filter(nodes)
}
func (pf Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
return merge2.Merge(pf.Patch, node)
var result []*yaml.RNode
for i := range nodes {
r, err := merge2.Merge(pf.Patch, nodes[i])
if err != nil {
return nil, err
}
result = append(result, r)
}
return result, nil
}

View File

@@ -9,12 +9,11 @@ import (
"os"
"sigs.k8s.io/kustomize/api/filters/prefixsuffix"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
)
func ExampleFilter() {
fss := builtinconfig.MakeDefaultConfig().NamePrefix
err := kio.Pipeline{
Inputs: []kio.Reader{&kio.ByteReader{Reader: bytes.NewBufferString(`
apiVersion: example.com/v1
@@ -27,7 +26,8 @@ kind: Bar
metadata:
name: instance
`)}},
Filters: []kio.Filter{prefixsuffix.Filter{Prefix: "baz-", FsSlice: fss}},
Filters: []kio.Filter{prefixsuffix.Filter{
Prefix: "baz-", FieldSpec: types.FieldSpec{Path: "metadata/name"}}},
Outputs: []kio.Writer{kio.ByteWriter{Writer: os.Stdout}},
}.Execute()
if err != nil {

View File

@@ -6,7 +6,8 @@ package prefixsuffix
import (
"fmt"
"sigs.k8s.io/kustomize/api/filters/fsslice"
"sigs.k8s.io/kustomize/api/filters/fieldspec"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
@@ -17,28 +18,26 @@ type Filter struct {
Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"`
Suffix string `json:"suffix,omitempty" yaml:"suffix,omitempty"`
FsSlice types.FsSlice `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
FieldSpec types.FieldSpec `json:"fieldSpec,omitempty" yaml:"fieldSpec,omitempty"`
}
var _ kio.Filter = Filter{}
func (ns Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
return kio.FilterAll(yaml.FilterFunc(ns.run)).Filter(nodes)
func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
return kio.FilterAll(yaml.FilterFunc(f.run)).Filter(nodes)
}
// Run runs the filter on a single node rather than a slice
func (ns Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
// transformations based on data -- :)
err := node.PipeE(fsslice.Filter{
FsSlice: ns.FsSlice,
SetValue: ns.set,
func (f Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
err := node.PipeE(fieldspec.Filter{
FieldSpec: f.FieldSpec,
SetValue: f.evaluateField,
CreateKind: yaml.ScalarNode, // Name is a ScalarNode
CreateTag: yaml.StringTag,
})
return node, err
}
func (ns Filter) set(node *yaml.RNode) error {
return fsslice.SetScalar(fmt.Sprintf(
"%s%s%s", ns.Prefix, node.YNode().Value, ns.Suffix))(node)
func (f Filter) evaluateField(node *yaml.RNode) error {
return filtersutil.SetScalar(fmt.Sprintf(
"%s%s%s", f.Prefix, node.YNode().Value, f.Suffix))(node)
}

View File

@@ -9,14 +9,12 @@ import (
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filters/prefixsuffix"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
filtertest_test "sigs.k8s.io/kustomize/api/testutils/filtertest"
"sigs.k8s.io/kustomize/api/types"
)
var tests = []TestCase{
{
name: "prefix",
var tests = map[string]TestCase{
"prefix": {
input: `
apiVersion: example.com/v1
kind: Foo
@@ -40,10 +38,10 @@ metadata:
name: foo-instance
`,
filter: prefixsuffix.Filter{Prefix: "foo-"},
fs: types.FieldSpec{Path: "metadata/name"},
},
{
name: "suffix",
"suffix": {
input: `
apiVersion: example.com/v1
kind: Foo
@@ -67,10 +65,10 @@ metadata:
name: instance-foo
`,
filter: prefixsuffix.Filter{Suffix: "-foo"},
fs: types.FieldSpec{Path: "metadata/name"},
},
{
name: "prefix-suffix",
"prefix-suffix": {
input: `
apiVersion: example.com/v1
kind: Foo
@@ -94,10 +92,10 @@ metadata:
name: bar-instance-foo
`,
filter: prefixsuffix.Filter{Prefix: "bar-", Suffix: "-foo"},
fs: types.FieldSpec{Path: "metadata/name"},
},
{
name: "data-fieldspecs",
"data-fieldspecs": {
input: `
apiVersion: example.com/v1
kind: Foo
@@ -119,7 +117,7 @@ a:
apiVersion: example.com/v1
kind: Foo
metadata:
name: foo-instance
name: instance
a:
b:
c: foo-d
@@ -127,35 +125,28 @@ a:
apiVersion: example.com/v1
kind: Bar
metadata:
name: foo-instance
name: instance
a:
b:
c: foo-d
`,
filter: prefixsuffix.Filter{Prefix: "foo-"},
fsslice: []types.FieldSpec{
{
Path: "a/b/c",
},
},
fs: types.FieldSpec{Path: "a/b/c"},
},
}
type TestCase struct {
name string
input string
expected string
filter prefixsuffix.Filter
fsslice types.FsSlice
fs types.FieldSpec
}
var config = builtinconfig.MakeDefaultConfig()
func TestFilter(t *testing.T) {
for i := range tests {
test := tests[i]
t.Run(test.name, func(t *testing.T) {
test.filter.FsSlice = append(config.NamePrefix, test.fsslice...)
for name := range tests {
test := tests[name]
t.Run(name, func(t *testing.T) {
test.filter.FieldSpec = test.fs
if !assert.Equal(t,
strings.TrimSpace(test.expected),
strings.TrimSpace(

View File

@@ -3,6 +3,7 @@ package replicacount
import (
"strconv"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/filters/fsslice"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
@@ -45,5 +46,5 @@ func (rc Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
}
func (rc Filter) set(node *yaml.RNode) error {
return fsslice.SetScalar(strconv.FormatInt(rc.Replica.Count, 10))(node)
return filtersutil.SetScalar(strconv.FormatInt(rc.Replica.Count, 10))(node)
}

View File

@@ -16,6 +16,8 @@ require (
k8s.io/apimachinery v0.17.0
k8s.io/client-go v0.17.0
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a
sigs.k8s.io/kustomize/kyaml v0.3.4
sigs.k8s.io/kustomize/kyaml v0.4.1
sigs.k8s.io/yaml v1.2.0
)
replace sigs.k8s.io/kustomize/kyaml v0.4.1 => ../kyaml

View File

@@ -580,8 +580,6 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphD
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.3.4 h1:RhxnabYltv4mdD5+I7pIaJtae+eaTn4TiZqPT7K+C7A=
sigs.k8s.io/kustomize/kyaml v0.3.4/go.mod h1:XJL84E6sOFeNrQ7CADiemc1B0EjIxHo3OhW4o1aJYNw=
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=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=

View File

@@ -515,7 +515,7 @@ k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.3.4/go.mod h1:XJL84E6sOFeNrQ7CADiemc1B0EjIxHo3OhW4o1aJYNw=
sigs.k8s.io/kustomize/kyaml v0.4.1/go.mod h1:XJL84E6sOFeNrQ7CADiemc1B0EjIxHo3OhW4o1aJYNw=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,6 @@
package target
import (
"bytes"
"encoding/json"
"fmt"
"strings"
@@ -60,7 +59,7 @@ func (kt *KustTarget) Load() error {
return err
}
var k types.Kustomization
err = unmarshal(content, &k)
err = k.Unmarshal(content)
if err != nil {
return err
}
@@ -104,18 +103,8 @@ func loadKustFile(ldr ifc.Loader) ([]byte, error) {
}
}
func unmarshal(y []byte, o interface{}) error {
j, err := yaml.YAMLToJSON(y)
if err != nil {
return err
}
dec := json.NewDecoder(bytes.NewReader(j))
dec.DisallowUnknownFields()
return dec.Decode(o)
}
// MakeCustomizedResMap creates a fully customized ResMap
// per the instructions contained in its kustomiztion instance.
// per the instructions contained in its kustomization instance.
func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) {
return kt.makeCustomizedResMap()
}

View File

@@ -225,13 +225,13 @@ spec:
spec:
containers:
- env:
- name: foo
value: bar
- name: FOO
valueFrom:
configMapKeyRef:
key: somekey
name: test-infra-app-env-ffmd9b969m
- name: foo
value: bar
image: nginx:1.8.0
name: nginx
ports:

View File

@@ -39,8 +39,8 @@ resources:
configMapGenerator:
- name: my-configmap
literals:
- testValue=1
- otherValue=10
- testValue=1
- otherValue=10
`)
th.WriteF("/app/base/deploy.yaml", `
apiVersion: v1
@@ -59,13 +59,13 @@ replicas:
- name: storefront
count: 3
resources:
- stub.yaml
- stub.yaml
configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- testValue=2
- compValue=5
- testValue=2
- compValue=5
`)
th.WriteF("/app/comp/stub.yaml", `
apiVersion: v1
@@ -156,7 +156,7 @@ configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- otherValue=9
- otherValue=9
`),
writeK("/app/prod", `
resources:
@@ -211,8 +211,8 @@ components:
configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- otherValue=9
literals:
- otherValue=9
`),
writeK("/app/prod", `
resources:
@@ -327,8 +327,8 @@ configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- compValue=5
- testValue=2
- compValue=5
- testValue=2
`),
},
runPath: "/app/direct-component",
@@ -360,7 +360,7 @@ configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- otherValue=9
- otherValue=9
`),
},
runPath: "/app/prod",
@@ -574,7 +574,7 @@ configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- otherValue=9
- otherValue=9
`),
},
runPath: "/app/prod",

View File

@@ -59,6 +59,7 @@ spec:
location: SW
`)
th.WriteF("/app/base/animalPark.yaml", `
apiVersion: foo
kind: AnimalPark
metadata:
name: sandiego
@@ -93,6 +94,7 @@ varReference:
`)
m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: foo
kind: AnimalPark
metadata:
labels:
@@ -161,6 +163,7 @@ varReference:
`)
m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: foo
kind: AnimalPark
metadata:
labels:
@@ -212,14 +215,17 @@ func TestFixedBug605_BaseCustomizationAvailableInOverlay(t *testing.T) {
nameReference:
- kind: Gorilla
fieldSpecs:
- kind: AnimalPark
- apiVersion: foo
kind: AnimalPark
path: spec/gorillaRef/name
- kind: Giraffe
fieldSpecs:
- kind: AnimalPark
- apiVersion: foo
kind: AnimalPark
path: spec/giraffeRef/name
varReference:
- path: spec/food
apiVersion: foo
kind: AnimalPark
`)
th.WriteK("/app/overlay", `
@@ -242,6 +248,7 @@ spec:
`)
// The following replaces the gorillaRef in the AnimalPark.
th.WriteF("/app/overlay/animalPark.yaml", `
apiVersion: foo
kind: AnimalPark
metadata:
name: sandiego
@@ -251,6 +258,7 @@ spec:
`)
m := th.Run("/app/overlay", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: foo
kind: AnimalPark
metadata:
labels:

View File

@@ -156,8 +156,7 @@ spec:
- mountPath: /tmp/ps
name: busybox-persistent-storage
volumes:
- emptyDir: {}
name: busybox-persistent-storage
- name: busybox-persistent-storage
- configMap:
name: configmap-in-base
name: configmap-in-base
@@ -233,8 +232,7 @@ spec:
- mountPath: /tmp/ps
name: nginx-persistent-storage
volumes:
- emptyDir: {}
name: nginx-persistent-storage
- name: nginx-persistent-storage
- configMap:
name: configmap-in-base
name: configmap-in-base
@@ -260,8 +258,7 @@ spec:
- mountPath: /tmp/ps
name: busybox-persistent-storage
volumes:
- emptyDir: {}
name: busybox-persistent-storage
- name: busybox-persistent-storage
- configMap:
name: configmap-in-base
name: configmap-in-base
@@ -335,8 +332,7 @@ spec:
- mountPath: /tmp/ps
name: nginx-persistent-storage
volumes:
- emptyDir: {}
name: nginx-persistent-storage
- name: nginx-persistent-storage
- configMap:
name: configmap-in-base
name: configmap-in-base
@@ -463,8 +459,7 @@ spec:
- mountPath: /tmp/ps
name: busybox-persistent-storage
volumes:
- emptyDir: {}
name: busybox-persistent-storage
- name: busybox-persistent-storage
- configMap:
name: configmap-in-base
name: configmap-in-base
@@ -564,8 +559,7 @@ spec:
- mountPath: /tmp/ps
name: busybox-persistent-storage
volumes:
- emptyDir: {}
name: busybox-persistent-storage
- name: busybox-persistent-storage
- configMap:
name: configmap-in-base
name: configmap-in-base
@@ -667,8 +661,7 @@ spec:
- mountPath: /tmp/ps
name: busybox-persistent-storage
volumes:
- emptyDir: {}
name: busybox-persistent-storage
- name: busybox-persistent-storage
- configMap:
name: configmap-in-base
name: configmap-in-base
@@ -769,8 +762,7 @@ spec:
- mountPath: /tmp/ps
name: busybox-persistent-storage
volumes:
- emptyDir: {}
name: busybox-persistent-storage
- name: busybox-persistent-storage
- configMap:
name: configmap-in-base
name: configmap-in-base
@@ -965,8 +957,7 @@ spec:
- mountPath: /tmp/ps
name: busybox-persistent-storage
volumes:
- emptyDir: {}
name: busybox-persistent-storage
- name: busybox-persistent-storage
- configMap:
name: configmap-in-base
name: configmap-in-base
@@ -1180,8 +1171,7 @@ spec:
- mountPath: /tmp/ps
name: busybox-persistent-storage
volumes:
- emptyDir: {}
name: busybox-persistent-storage
- name: busybox-persistent-storage
- configMap:
name: configmap-in-base
name: configmap-in-base

View File

@@ -150,8 +150,6 @@ spec:
func makeBaseWithGenerators(th kusttest_test.Harness) {
th.WriteK("/app", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namePrefix: team-foo-
commonLabels:
app: mynginx
@@ -325,8 +323,6 @@ spec:
name: configmap-in-overlay
`)
th.WriteK("/overlay", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namePrefix: staging-
commonLabels:
env: staging
@@ -389,12 +385,12 @@ spec:
- gcePersistentDisk:
pdName: nginx-persistent-storage
name: nginx-persistent-storage
- configMap:
name: staging-configmap-in-overlay-k7cbc75tg8
name: configmap-in-overlay
- configMap:
name: staging-team-foo-configmap-in-base-gh9d7t85gb
name: configmap-in-base
- configMap:
name: staging-configmap-in-overlay-k7cbc75tg8
name: configmap-in-overlay
---
apiVersion: v1
kind: Service

View File

@@ -79,8 +79,7 @@ spec:
- mountPath: /tmp/ps
name: nginx-persistent-storage
volumes:
- emptyDir: {}
name: nginx-persistent-storage
- name: nginx-persistent-storage
- configMap:
name: configmap-in-base
name: configmap-in-base
@@ -223,8 +222,7 @@ spec:
- mountPath: /tmp/ps
name: nginx-persistent-storage
volumes:
- emptyDir: {}
name: nginx-persistent-storage
- name: nginx-persistent-storage
- configMap:
name: configmap-in-base
name: configmap-in-base

View File

@@ -0,0 +1,48 @@
package krusty_test
import (
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func TestKeepEmptyArray(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("/app/resources.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: testing123
spec:
replicas: 1
selector: null
template:
spec:
containers:
- name: event
image: testing123
imagePullPolicy: IfNotPresent
imagePullSecrets: []`)
th.WriteK("/app", `
resources:
- resources.yaml`)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: testing123
spec:
replicas: 1
selector: null
template:
spec:
containers:
- image: testing123
imagePullPolicy: IfNotPresent
name: event
imagePullSecrets: []
`)
}

View File

@@ -146,12 +146,12 @@ spec:
- gcePersistentDisk:
pdName: nginx-persistent-storage
name: nginx-persistent-storage
- configMap:
name: a-configmap-in-overlay-ffm9hf78mc
name: configmap-in-overlay
- configMap:
name: a-b-configmap-in-base-fm96mhk4dt
name: configmap-in-base
- configMap:
name: a-configmap-in-overlay-ffm9hf78mc
name: configmap-in-overlay
---
apiVersion: v1
kind: Service
@@ -190,8 +190,6 @@ metadata:
func makeCommonFileForMultiplePatchTest(th kusttest_test.Harness) {
th.WriteK("/app/base", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namePrefix: team-foo-
commonLabels:
app: mynginx
@@ -249,8 +247,6 @@ spec:
app: nginx
`)
th.WriteK("/app/overlay/staging", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namePrefix: staging-
commonLabels:
env: staging
@@ -355,12 +351,12 @@ spec:
- gcePersistentDisk:
pdName: nginx-persistent-storage
name: nginx-persistent-storage
- configMap:
name: staging-configmap-in-overlay-k7cbc75tg8
name: configmap-in-overlay
- configMap:
name: staging-team-foo-configmap-in-base-g7k6gt2889
name: configmap-in-base
- configMap:
name: staging-configmap-in-overlay-k7cbc75tg8
name: configmap-in-overlay
---
apiVersion: v1
kind: Service
@@ -544,8 +540,7 @@ spec:
- mountPath: /tmp/ps
name: nginx-persistent-storage
volumes:
- emptyDir: {}
name: nginx-persistent-storage
- name: nginx-persistent-storage
- configMap:
name: staging-team-foo-configmap-in-base-g7k6gt2889
name: configmap-in-base

View File

@@ -10,24 +10,6 @@ import (
"sigs.k8s.io/kustomize/api/types"
)
func writeDeployment(th *kusttest_test.HarnessEnhanced, path string) {
th.WriteF(path, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeployment
spec:
template:
metadata:
labels:
backend: awesome
spec:
containers:
- name: whatever
image: whatever
`)
}
func writeStringPrefixer(th *kusttest_test.HarnessEnhanced, path, name string) {
th.WriteF(path, `
apiVersion: someteam.example.com/v1
@@ -37,53 +19,6 @@ metadata:
`)
}
func writeDatePrefixer(th *kusttest_test.HarnessEnhanced, path, name string) {
th.WriteF(path, `
apiVersion: someteam.example.com/v1
kind: DatePrefixer
metadata:
name: `+name+`
`)
}
func TestOrderedTransformers(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
BuildGoPlugin("someteam.example.com", "v1", "StringPrefixer").
BuildGoPlugin("someteam.example.com", "v1", "DatePrefixer")
defer th.Reset()
th.WriteK("/app", `
resources:
- deployment.yaml
transformers:
- peachPrefixer.yaml
- date1Prefixer.yaml
- applePrefixer.yaml
- date2Prefixer.yaml
`)
writeDeployment(th, "/app/deployment.yaml")
writeStringPrefixer(th, "/app/applePrefixer.yaml", "apple")
writeStringPrefixer(th, "/app/peachPrefixer.yaml", "peach")
writeDatePrefixer(th, "/app/date1Prefixer.yaml", "date1")
writeDatePrefixer(th, "/app/date2Prefixer.yaml", "date2")
m := th.Run("/app", th.MakeOptionsPluginsEnabled())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: 2018-05-11-apple-2018-05-11-peach-myDeployment
spec:
template:
metadata:
labels:
backend: awesome
spec:
containers:
- image: whatever
name: whatever
`)
}
func TestPluginsNotEnabled(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
BuildGoPlugin("someteam.example.com", "v1", "StringPrefixer")
@@ -165,6 +100,78 @@ metadata:
`)
}
/*
The tests below are disabled until the StringPrefixer and DatePrefixer
can be rewritten using kyaml, instead of depending on the
PrefixSuffixTransformerPlugin. That dependency is causing
failures in the test loader.
func writeDeployment(th *kusttest_test.HarnessEnhanced, path string) {
th.WriteF(path, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeployment
spec:
template:
metadata:
labels:
backend: awesome
spec:
containers:
- name: whatever
image: whatever
`)
}
func writeDatePrefixer(th *kusttest_test.HarnessEnhanced, path, name string) {
th.WriteF(path, `
apiVersion: someteam.example.com/v1
kind: DatePrefixer
metadata:
name: `+name+`
`)
}
func TestOrderedTransformers(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
BuildGoPlugin("someteam.example.com", "v1", "StringPrefixer").
BuildGoPlugin("someteam.example.com", "v1", "DatePrefixer")
defer th.Reset()
th.WriteK("/app", `
resources:
- deployment.yaml
transformers:
- peachPrefixer.yaml
- date1Prefixer.yaml
- applePrefixer.yaml
- date2Prefixer.yaml
`)
writeDeployment(th, "/app/deployment.yaml")
writeStringPrefixer(th, "/app/applePrefixer.yaml", "apple")
writeStringPrefixer(th, "/app/peachPrefixer.yaml", "peach")
writeDatePrefixer(th, "/app/date1Prefixer.yaml", "date1")
writeDatePrefixer(th, "/app/date2Prefixer.yaml", "date2")
m := th.Run("/app", th.MakeOptionsPluginsEnabled())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: 2018-05-11-apple-2018-05-11-peach-myDeployment
spec:
template:
metadata:
labels:
backend: awesome
spec:
containers:
- image: whatever
name: whatever
`)
}
func TestTransformedTransformers(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t).
BuildGoPlugin("someteam.example.com", "v1", "StringPrefixer").
@@ -205,3 +212,4 @@ spec:
name: whatever
`)
}
*/

View File

@@ -13,6 +13,178 @@ import (
"sigs.k8s.io/kustomize/api/types"
)
func TestSliceFromBytes(t *testing.T) {
type testCase struct {
input string
expected []string
}
testCases := map[string]testCase{
"empty1": {
input: "",
expected: []string{},
},
"empty2": {
input: `
---
---
`,
expected: []string{},
},
"deployment1": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: pooh
---
`,
expected: []string{
`apiVersion: apps/v1
kind: Deployment
metadata:
name: pooh
`,
},
},
"deployment2": {
input: `
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
baseAnno: This is a base annotation
labels:
app: mungebot
foo: bar
name: baseprefix-mungebot
spec:
replicas: 1
selector:
matchLabels:
foo: bar
template:
metadata:
annotations:
baseAnno: This is a base annotation
labels:
app: mungebot
foo: bar
spec:
containers:
- env:
- name: foo
value: bar
image: nginx
name: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
annotations:
baseAnno: This is a base annotation
labels:
app: mungebot
foo: bar
name: baseprefix-mungebot-service
spec:
ports:
- port: 7002
selector:
app: mungebot
foo: bar
`,
expected: []string{
`apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
baseAnno: This is a base annotation
labels:
app: mungebot
foo: bar
name: baseprefix-mungebot
spec:
replicas: 1
selector:
matchLabels:
foo: bar
template:
metadata:
annotations:
baseAnno: This is a base annotation
labels:
app: mungebot
foo: bar
spec:
containers:
- env:
- name: foo
value: bar
image: nginx
name: nginx
ports:
- containerPort: 80
`,
`apiVersion: v1
kind: Service
metadata:
annotations:
baseAnno: This is a base annotation
labels:
app: mungebot
foo: bar
name: baseprefix-mungebot-service
spec:
ports:
- port: 7002
selector:
app: mungebot
foo: bar
`,
},
},
}
for name := range testCases {
tc := testCases[name]
t.Run(name, func(t *testing.T) {
result, err := factory.SliceFromBytes([]byte(tc.input))
if err != nil {
t.Fatalf("%v: fails with err: %v", name, err)
}
if len(result) != len(tc.expected) {
for i := range result {
bytes, err := result[i].AsYAML()
if err != nil {
t.Fatalf("%v: result to YAML fails with err: %v", name, err)
}
tmp := string(bytes)
t.Logf("--- %d:\n%s", i, tmp)
}
t.Fatalf(
"%v: actual len %d != expected len %d",
name, len(result), len(tc.expected))
}
for i := range tc.expected {
bytes, err := result[i].AsYAML()
if err != nil {
t.Fatalf("%v: result to YAML fails with err: %v", name, err)
}
tmp := string(bytes)
if tmp != tc.expected[i] {
t.Fatalf(
"%v: string mismatch in item %d\n"+
"actual:\n-----\n%s\n-----\n"+
"expected:\n-----\n%s\n-----\n",
name, i, tmp, tc.expected[i])
}
}
})
}
}
func TestSliceFromPatches(t *testing.T) {
patchGood1 := types.PatchStrategicMerge("patch1.yaml")
patch1 := `

View File

@@ -4,9 +4,6 @@
package kusttest_test
import (
"bytes"
"fmt"
"strconv"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
@@ -20,8 +17,6 @@ import (
"sigs.k8s.io/kustomize/api/resource"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// HarnessEnhanced manages a full plugin environment for tests.
@@ -130,42 +125,8 @@ func (th *HarnessEnhanced) LoadAndRunTransformer(
func (th *HarnessEnhanced) RunTransformerAndCheckResult(
config, input, expected string) {
for _, b := range []bool{true, false} {
th.t.Run(fmt.Sprintf("yaml-%v", b), func(t *testing.T) {
c, err := toggleYamlSupportField(config, b)
if err != nil {
th.t.Fatalf("Err: %v", err)
}
resMap, err := th.RunTransformer(c, input)
if err != nil {
th.t.Fatalf("Err: %v", err)
}
th.AssertActualEqualsExpected(resMap, expected)
})
}
}
func toggleYamlSupportField(config string, yamlSupport bool) (string, error) {
var out bytes.Buffer
rw := kio.ByteReadWriter{
Reader: bytes.NewBufferString(config),
Writer: &out,
}
err := kio.Pipeline{
Inputs: []kio.Reader{&rw},
Filters: []kio.Filter{
kio.FilterAll(yaml.FilterFunc(
func(node *yaml.RNode) (*yaml.RNode, error) {
return node.Pipe(yaml.FieldSetter{
Name: "yamlSupport",
StringValue: strconv.FormatBool(yamlSupport),
})
}),
),
},
Outputs: []kio.Writer{&rw},
}.Execute()
return out.String(), err
resMap := th.LoadAndRunTransformer(config, input)
th.AssertActualEqualsExpected(resMap, expected)
}
func (th *HarnessEnhanced) ErrorFromLoadAndRunTransformer(
@@ -178,16 +139,8 @@ type AssertFunc func(t *testing.T, err error)
func (th *HarnessEnhanced) RunTransformerAndCheckError(
config, input string, assertFn AssertFunc) {
for _, b := range []bool{true, false} {
th.t.Run(fmt.Sprintf("yaml-%v", b), func(t *testing.T) {
c, err := toggleYamlSupportField(config, b)
if err != nil {
th.t.Fatalf("Err: %v", err)
}
_, err = th.RunTransformer(c, input)
assertFn(t, err)
})
}
_, err := th.RunTransformer(config, input)
assertFn(th.t, err)
}
func (th *HarnessEnhanced) RunTransformer(
@@ -203,6 +156,7 @@ func (th *HarnessEnhanced) RunTransformerFromResMap(
config string, resMap resmap.ResMap) (resmap.ResMap, error) {
transConfig, err := th.rf.RF().FromBytes([]byte(config))
if err != nil {
th.t.Logf("config: '%s'", config)
th.t.Fatalf("Err: %v", err)
}
g, err := th.pl.LoadTransformer(

View File

@@ -3,6 +3,13 @@
package types
import (
"bytes"
"encoding/json"
"sigs.k8s.io/yaml"
)
const (
KustomizationVersion = "kustomize.config.k8s.io/v1beta1"
KustomizationKind = "Kustomization"
@@ -165,3 +172,20 @@ func (k *Kustomization) EnforceFields() []string {
}
return errs
}
// Unmarshal replace k with the content in YAML input y
func (k *Kustomization) Unmarshal(y []byte) error {
j, err := yaml.YAMLToJSON(y)
if err != nil {
return err
}
dec := json.NewDecoder(bytes.NewReader(j))
dec.DisallowUnknownFields()
var nk Kustomization
err = dec.Decode(&nk)
if err != nil {
return err
}
*k = nk
return nil
}

View File

@@ -0,0 +1,184 @@
package types
import (
"testing"
)
func fixKustomizationPostUnmarshallingCheck(k, e *Kustomization) bool {
return (k.Kind == e.Kind && k.APIVersion == e.APIVersion &&
len(k.Resources) == len(e.Resources) && k.Resources[0] == e.Resources[0] &&
k.Bases == nil)
}
func TestFixKustomizationPostUnmarshalling(t *testing.T) {
var k Kustomization
k.Bases = append(k.Bases, "foo")
k.FixKustomizationPostUnmarshalling()
expected := Kustomization{
TypeMeta: TypeMeta{
Kind: KustomizationKind,
APIVersion: KustomizationVersion,
},
Resources: []string{"foo"},
}
if !fixKustomizationPostUnmarshallingCheck(&k, &expected) {
t.Fatalf("unexpected output: %v", k)
}
}
func TestFixKustomizationPostUnmarshalling_2(t *testing.T) {
k := Kustomization{
TypeMeta: TypeMeta{
Kind: ComponentKind,
},
}
k.Bases = append(k.Bases, "foo")
k.FixKustomizationPostUnmarshalling()
expected := Kustomization{
TypeMeta: TypeMeta{
Kind: ComponentKind,
APIVersion: ComponentVersion,
},
Resources: []string{"foo"},
}
if !fixKustomizationPostUnmarshallingCheck(&k, &expected) {
t.Fatalf("unexpected output: %v", k)
}
}
func TestEnforceFields_InvalidKindAndVersion(t *testing.T) {
k := Kustomization{
TypeMeta: TypeMeta{
Kind: "foo",
APIVersion: "bar",
},
}
errs := k.EnforceFields()
if len(errs) != 2 {
t.Fatalf("number of errors should be 2 but got: %v", errs)
}
}
func TestEnforceFields_InvalidKind(t *testing.T) {
k := Kustomization{
TypeMeta: TypeMeta{
Kind: "foo",
APIVersion: KustomizationVersion,
},
}
errs := k.EnforceFields()
if len(errs) != 1 {
t.Fatalf("number of errors should be 1 but got: %v", errs)
}
expected := "kind should be " + KustomizationKind + " or " + ComponentKind
if errs[0] != expected {
t.Fatalf("error should be %v but got: %v", expected, errs[0])
}
}
func TestEnforceFields_InvalidVersion(t *testing.T) {
k := Kustomization{
TypeMeta: TypeMeta{
Kind: KustomizationKind,
APIVersion: "bar",
},
}
errs := k.EnforceFields()
if len(errs) != 1 {
t.Fatalf("number of errors should be 1 but got: %v", errs)
}
expected := "apiVersion for " + k.Kind + " should be " + KustomizationVersion
if errs[0] != expected {
t.Fatalf("error should be %v but got: %v", expected, errs[0])
}
}
func TestEnforceFields_ComponentKind(t *testing.T) {
k := Kustomization{
TypeMeta: TypeMeta{
Kind: ComponentKind,
APIVersion: "bar",
},
}
errs := k.EnforceFields()
if len(errs) != 1 {
t.Fatalf("number of errors should be 1 but got: %v", errs)
}
expected := "apiVersion for " + k.Kind + " should be " + ComponentVersion
if errs[0] != expected {
t.Fatalf("error should be %v but got: %v", expected, errs[0])
}
}
func TestEnforceFields(t *testing.T) {
k := Kustomization{
TypeMeta: TypeMeta{
Kind: KustomizationKind,
APIVersion: KustomizationVersion,
},
}
errs := k.EnforceFields()
if len(errs) != 0 {
t.Fatalf("number of errors should be 0 but got: %v", errs)
}
}
func TestUnmarshal(t *testing.T) {
y := []byte(`
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- foo
- bar
nameSuffix: dog
namePrefix: cat`)
var k Kustomization
err := k.Unmarshal(y)
if err != nil {
t.Fatal(err)
}
if k.Kind != KustomizationKind || k.APIVersion != KustomizationVersion ||
len(k.Resources) != 2 || k.NamePrefix != "cat" || k.NameSuffix != "dog" {
t.Fatalf("wrong unmarshal result: %v", k)
}
}
func TestUnmarshal_UnkownField(t *testing.T) {
y := []byte(`
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
unknown: foo`)
var k Kustomization
err := k.Unmarshal(y)
if err == nil {
t.Fatalf("expect an error")
}
expect := "json: unknown field \"unknown\""
if err.Error() != expect {
t.Fatalf("expect %v but got: %v", expect, err.Error())
}
}
func TestUnmarshal_InvalidYaml(t *testing.T) {
y := []byte(`
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
unknown`)
var k Kustomization
err := k.Unmarshal(y)
if err == nil {
t.Fatalf("expect an error")
}
}

View File

@@ -116,14 +116,14 @@ metadata:
name: my-instance
annotations:
config.kubernetes.io/local-config: "true"
config.k8s.io/function: |
config.kubernetes.io/function: |
container:
image: gcr.io/example-functions/nginx-template:v1.0.0
spec:
replicas: 5
```
- `annotations[config.k8s.io/function].container.image`: the image to use for this API
- `annotations[config.kubernetes.io/function].container.image`: the image to use for this API
- `annotations[config.kubernetes.io/local-config]`: mark this as not a Resource that should
be applied

View File

@@ -114,7 +114,7 @@ functionConfig:
name: staging
metadata:
annotations:
config.k8s.io/function: |
config.kubernetes.io/function: |
container:
image: gcr.io/example/foo:v1.0.0
spec:

View File

@@ -0,0 +1,65 @@
## delete-setter
[Alpha] Delete a custom setter for a Resource field
### Synopsis
Delete a custom setter for a Resource field.
DIR
A directory containing Resource configuration.
NAME
The name of the setter to create.
### Deleting a Custom Setter
**Given the YAML:**
# resource.yaml
apiVersion: v1
kind: Service
metadata:
...
spec:
...
ports:
...
- name: http
port: 8080 # {"type":"integer","x-kustomize":{"partialFieldSetters":[{"name":"http-port","value":"8080"}]}}
...
**Delete setter:**
# delete a setter for ports
$ kustomize cfg set create DIR/ http-port
comment will be removed for this field is not settable any more.
**Newly modified YAML:**
# resource.yaml
apiVersion: v1
kind: Service
metadata:
...
spec:
...
ports:
...
- name: http
port: 8080
...
### Deleting a setter used in substitution
If the setter is also used in substitution, it will ask you to delete the substitution first.
### Examples
# delete a setter for port
kustomize cfg create-setter DIR/ port

View File

@@ -14,23 +14,8 @@ require (
k8s.io/cli-runtime v0.17.3
k8s.io/client-go v0.17.3
k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd
sigs.k8s.io/cli-utils v0.12.0
// TODO: Fix this -- this should depend on v0.0.0 and be replaced (below),
// however the cli-runtime dependency causes `go mod` to set this as the
// dependency.
sigs.k8s.io/kustomize/kyaml v0.1.13 // Don't change this!
sigs.k8s.io/cli-utils v0.16.0
sigs.k8s.io/kustomize/kyaml v0.4.1
)
// TODO: Fix this -- we sould only depend on v0.0.0 and replace that one.
//
// 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
sigs.k8s.io/kustomize/kyaml v0.1.13 => ../../kyaml
)
replace sigs.k8s.io/kustomize/kyaml => ../../kyaml

View File

@@ -550,7 +550,6 @@ gopkg.in/yaml.v2 v2.0.0/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
@@ -617,14 +616,12 @@ modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I=
sigs.k8s.io/cli-utils v0.12.0 h1:+CvYwQAEtKvcx/NaUVF9rDKvY91VwJj+i7D2lWBMYc0=
sigs.k8s.io/cli-utils v0.12.0/go.mod h1:H35YA5iJIM7EVNgqDTjX2dgt4wE23zmnXOTSTlyD+PE=
sigs.k8s.io/cli-utils v0.16.0 h1:Wr32m1oxjIqc9G9l+igr13PeIM9LCyq8jQ8KjXKelvg=
sigs.k8s.io/cli-utils v0.16.0/go.mod h1:9Jqm9K2W6ShhCxsEuaz6HSRKKOXigPUx3ZfypGgxBLY=
sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9NPsg=
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/kyaml v0.1.4 h1:cDG2u7v6CTAZmWKzCjk0hKG7AIN+2mCHx2ifwPbvKrs=
sigs.k8s.io/kustomize/kyaml v0.1.4/go.mod h1:461i94nj0h0ylJ6w83jLkR4SqqVhn1iY6fjD0JSTQeE=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU=
@@ -633,4 +630,6 @@ sigs.k8s.io/testing_frameworks v0.1.2 h1:vK0+tvjF0BZ/RYFeZ1E6BYBwHJJXhjuZ3TdsEKH
sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=

View File

@@ -372,6 +372,41 @@ metadata:
name: nginx-deployment
spec:
replicas: 3 # {"$openapi":"replicas"}
`,
},
{
name: "add setter with . in the name",
args: []string{"foo.bar", "3"},
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.foo.bar:
x-k8s-cli:
setter:
name: foo.bar
value: "3"
`,
expectedResources: `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3 # {"$openapi":"foo.bar"}
`,
},
}

View File

@@ -86,14 +86,17 @@ func (r *CreateSubstitutionRunner) preRunE(c *cobra.Command, args []string) erro
// extract setter name tokens from pattern enclosed in ${}
re := regexp.MustCompile(`\$\{([^}]*)\}`)
markers := re.FindAll([]byte(r.CreateSubstitution.Pattern), -1)
markers := re.FindAllString(r.CreateSubstitution.Pattern, -1)
if len(markers) == 0 {
return errors.Errorf("unable to find setter or substitution names in pattern, " +
"setter names must be enclosed in ${}")
}
for _, marker := range markers {
name := strings.TrimSuffix(strings.TrimPrefix(string(marker), "${"), "}")
name := strings.TrimSuffix(strings.TrimPrefix(marker, "${"), "}")
if name == r.CreateSubstitution.Name {
return fmt.Errorf("setters must have different name than the substitution: %s", name)
}
ref, err := spec.NewRef(fieldmeta.DefinitionsPrefix + fieldmeta.SubstitutionDefinitionPrefix + name)
if err != nil {
@@ -112,7 +115,7 @@ func (r *CreateSubstitutionRunner) preRunE(c *cobra.Command, args []string) erro
r.CreateSubstitution.Values = append(
r.CreateSubstitution.Values,
setters2.Value{Marker: string(marker), Ref: markerRef},
setters2.Value{Marker: marker, Ref: markerRef},
)
}

View File

@@ -408,6 +408,39 @@ spec:
`,
err: "cyclic substitution detected with name my-nested-subst",
},
{
name: "substitution with non-existing setter with same name",
args: []string{
"foo", "--field-value", "prefix-1234", "--pattern", "prefix-${foo}"},
input: `
apiVersion: test/v1
kind: Foo
metadata:
name: foo
spec:
setterVal: 1234
substVal: prefix-1234
`,
inputOpenAPI: `
apiVersion: v1alpha1
kind: Example
`,
expectedOpenAPI: `
apiVersion: v1alpha1
kind: Example
`,
expectedResources: `
apiVersion: test/v1
kind: Foo
metadata:
name: foo
spec:
setterVal: 1234
substVal: prefix-1234
`,
err: "setters must have different name than the substitution: foo",
},
}
for i := range tests {
test := tests[i]

View File

@@ -6,6 +6,7 @@ package commands
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/openapi"
"sigs.k8s.io/kustomize/kyaml/setters2/settersutil"
)
@@ -16,9 +17,9 @@ func NewDeleteSetterRunner(parent string) *DeleteSetterRunner {
c := &cobra.Command{
Use: "delete-setter DIR NAME",
Args: cobra.MinimumNArgs(2),
Short: "delete values on Resources fields.",
Long: "",
Example: "",
Short: commands.DeleteSetterShort,
Long: commands.DeleteSetterLong,
Example: commands.DeleteSetterExamples,
PreRunE: r.preRunE,
RunE: r.runE,
}

View File

@@ -175,13 +175,13 @@ are passed to the Function through the ` + "`" + `ResourceList.functionConfig` +
name: my-instance
annotations:
config.kubernetes.io/local-config: "true"
config.k8s.io/function: |
config.kubernetes.io/function: |
container:
image: gcr.io/example-functions/nginx-template:v1.0.0
spec:
replicas: 5
- ` + "`" + `annotations[config.k8s.io/function].container.image` + "`" + `: the image to use for this API
- ` + "`" + `annotations[config.kubernetes.io/function].container.image` + "`" + `: the image to use for this API
- ` + "`" + `annotations[config.kubernetes.io/local-config]` + "`" + `: mark this as not a Resource that should
be applied
@@ -343,7 +343,7 @@ An example using ` + "`" + `config.kubernetes.io/v1beta1/ResourceList` + "`" + `
name: staging
metadata:
annotations:
config.k8s.io/function: |
config.kubernetes.io/function: |
container:
image: gcr.io/example/foo:v1.0.0
spec:

View File

@@ -89,6 +89,22 @@ var CreateSetterExamples = `
kustomize cfg create-setter DIR/ image-tag v1.0.1 --type "string" \
--field image --description "current stable release"`
var DeleteSetterShort = `[Alpha] Delete a custom setter for a Resource field`
var DeleteSetterLong = `
Delete a custom setter for a Resource field.
DIR
A directory containing Resource configuration.
NAME
The name of the setter to create.
`
var DeleteSetterExamples = `
# delete a setter for port
kustomize cfg create-setter DIR/ port`
var FmtShort = `[Alpha] Format yaml configuration files.`
var FmtLong = `
[Alpha] Format yaml configuration files.

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
@@ -911,8 +911,8 @@ absolute path, or by relative path.</p>
<li><strong>B</strong> may not <em>depend on</em> <strong>A</strong>, even transitively.</li>
</ul>
<p><strong>A</strong> may contain <strong>B</strong>, but in this case it might be
simplest to have <strong>A</strong> directly depend on <strong>B</strong>&rsquo;s
resources and eliminate <strong>B</strong>&rsquo;s kustomization.yaml file
simplest to have <strong>A</strong> directly depend on <strong>B</strong>&lsquo;s
resources and eliminate <strong>B</strong>&lsquo;s kustomization.yaml file
(i.e. absorb <strong>B</strong> into <strong>A</strong>).</p>
<p>Conventionally, <strong>B</strong> is in a directory that&rsquo;s sibling
to <strong>A</strong>, or <strong>B</strong> is off in a completely independent

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
@@ -873,7 +873,7 @@ configmap is created is <code>whatever.ini</code>.</p>
<div class="text-muted mt-5 pt-3 border-top">Last modified June 7, 2020: <a href="https://github.com/kubernetes-sigs/kustomize/commit/42497c664f619a36cc86156e366b53099bd633cb">Convert docs to docsy (42497c66)</a>
<div class="text-muted mt-5 pt-3 border-top">Last modified June 30, 2020: <a href="https://github.com/kubernetes-sigs/kustomize/commit/69adcf9aaf7ab032f4a387ad70048255f5294a98">configMapGenerator docs content addition (69adcf9a)</a>
</div>
</div>

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -782,7 +782,7 @@ resources.&lt;/p&gt;
supported. No ints, bools, arrays etc. It&amp;rsquo;s not
possible to, say, extract the name of the image in
container number 2 of some pod template.&lt;/p&gt;
&lt;p&gt;A variable reference, i.e. the string &amp;lsquo;$(FOO)&amp;rsquo;,
&lt;p&gt;A variable reference, i.e. the string &amp;lsquo;$(FOO)&#39;,
can only be placed in particular fields of
particular objects as specified by kustomize&amp;rsquo;s
configuration data.&lt;/p&gt;

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
@@ -506,10 +506,10 @@
<ul class="td-sidebar-nav__section pr-md-3">
<li class="td-sidebar-nav__section-title">
<a href="/kustomize/api-reference/kustomization/patchesjson6902/" class="align-left pl-0 pr-2 collapsed td-sidebar-link td-sidebar-link__section">patchesJson6902</a>
<a href="/kustomize/api-reference/kustomization/patchesjson6902/" class="align-left pl-0 pr-2 td-sidebar-link td-sidebar-link__section">patchesJson6902</a>
</li>
<ul>
<li class="collapse " id="kustomizeapi-referencekustomizationpatchesjson6902">
<li class="collapse show" id="kustomizeapi-referencekustomizationpatchesjson6902">
@@ -529,10 +529,10 @@
<ul class="td-sidebar-nav__section pr-md-3">
<li class="td-sidebar-nav__section-title">
<a href="/kustomize/api-reference/kustomization/patchesstrategicmerge/" class="align-left pl-0 pr-2 collapsed td-sidebar-link td-sidebar-link__section">patchesStrategicMerge</a>
<a href="/kustomize/api-reference/kustomization/patchesstrategicmerge/" class="align-left pl-0 pr-2 td-sidebar-link td-sidebar-link__section">patchesStrategicMerge</a>
</li>
<ul>
<li class="collapse " id="kustomizeapi-referencekustomizationpatchesstrategicmerge">
<li class="collapse show" id="kustomizeapi-referencekustomizationpatchesstrategicmerge">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
@@ -483,10 +483,10 @@
<ul class="td-sidebar-nav__section pr-md-3">
<li class="td-sidebar-nav__section-title">
<a href="/kustomize/api-reference/kustomization/patches/" class="align-left pl-0 pr-2 collapsed td-sidebar-link td-sidebar-link__section">patches</a>
<a href="/kustomize/api-reference/kustomization/patches/" class="align-left pl-0 pr-2 td-sidebar-link td-sidebar-link__section">patches</a>
</li>
<ul>
<li class="collapse " id="kustomizeapi-referencekustomizationpatches">
<li class="collapse show" id="kustomizeapi-referencekustomizationpatches">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
@@ -483,10 +483,10 @@
<ul class="td-sidebar-nav__section pr-md-3">
<li class="td-sidebar-nav__section-title">
<a href="/kustomize/api-reference/kustomization/patches/" class="align-left pl-0 pr-2 collapsed td-sidebar-link td-sidebar-link__section">patches</a>
<a href="/kustomize/api-reference/kustomization/patches/" class="align-left pl-0 pr-2 td-sidebar-link td-sidebar-link__section">patches</a>
</li>
<ul>
<li class="collapse " id="kustomizeapi-referencekustomizationpatches">
<li class="collapse show" id="kustomizeapi-referencekustomizationpatches">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
@@ -794,7 +794,7 @@ resources.</p>
supported. No ints, bools, arrays etc. It&rsquo;s not
possible to, say, extract the name of the image in
container number 2 of some pod template.</p>
<p>A variable reference, i.e. the string &lsquo;$(FOO)&rsquo;,
<p>A variable reference, i.e. the string &lsquo;$(FOO)',
can only be placed in particular fields of
particular objects as specified by kustomize&rsquo;s
configuration data.</p>

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -274,7 +274,7 @@
<url>
<loc>https://kubernetes-sigs.github.io/kustomize/guides/plugins/</loc>
<lastmod>2020-06-15T14:22:31-07:00</lastmod>
<lastmod>2020-06-26T17:02:00+01:00</lastmod>
<xhtml:link
rel="alternate"
hreflang="zh"
@@ -559,7 +559,7 @@
<url>
<loc>https://kubernetes-sigs.github.io/kustomize/api-reference/kustomization/configmapgenerator/</loc>
<lastmod>2020-06-07T21:07:46-07:00</lastmod>
<lastmod>2020-06-30T00:44:14+05:30</lastmod>
<xhtml:link
rel="alternate"
hreflang="zh"

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="generator" content="Hugo 0.73.0" />
<meta name="generator" content="Hugo 0.68.3" />
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Some files were not shown because too many files have changed in this diff Show More