Compare commits

..

1 Commits

Author SHA1 Message Date
Jeff Regan
9f5697b154 Update OWNERS_ALIASES 2021-06-08 16:54:20 -07:00
373 changed files with 3359 additions and 34062 deletions

View File

@@ -45,10 +45,6 @@ jobs:
run: go test -cover ./...
working-directory: ./kyaml
- name: Test api
run: go test -cover ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"
working-directory: ./api
- name: Test cmd/config
run: go test -cover ./...
working-directory: ./cmd/config
@@ -73,10 +69,6 @@ jobs:
run: go test -cover ./...
working-directory: ./kyaml
- name: Test api
run: go test -cover ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"
working-directory: ./api
- name: Test cmd/config
run: go test -cover ./...
working-directory: ./cmd/config
@@ -101,11 +93,6 @@ jobs:
run: go test -cover ./...
working-directory: ./kyaml
# TODO: uncomment once Windows tests are passing.
# - name: Test api
# run: go test -cover ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"
# working-directory: ./api
- name: Test cmd/config
run: go test -cover ./...
working-directory: ./cmd/config

View File

@@ -1,25 +1,6 @@
[SIG-CLI]: https://github.com/kubernetes/community/tree/master/sig-cli
[Slack channel]: https://kubernetes.slack.com/messages/kustomize
[Mailing list]: https://groups.google.com/forum/#!forum/kubernetes-sig-cli
[OWNERS file spec]: https://github.com/kubernetes/community/blob/master/contributors/guide/owners.md
[Kustomize OWNERS_ALIASES]: https://github.com/kubernetes-sigs/kustomize/blob/8049f7b1af52e8a7ec26faf6cf714f560d0043c5/OWNERS_ALIASES
[SIG-CLI Teams]: https://github.com/kubernetes/org/blob/main/config/kubernetes-sigs/sig-cli/teams.yaml
[Github permissions]: https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-permission-levels-for-an-organization#repository-access-for-each-permission-level
[Contributor License Agreement]: https://git.k8s.io/community/CLA.md
[Kubernetes Contributor Guide]: http://git.k8s.io/community/contributors/guide
[Contributor Cheat Sheet]: https://git.k8s.io/community/contributors/guide/contributor-cheatsheet/README.md
[CNCF Code of Conduct]: https://github.com/cncf/foundation/blob/master/code-of-conduct.md
[Kubernetes Community Membership]: https://github.com/kubernetes/community/blob/master/community-membership.md
[Contribution Guide]: https://kubectl.docs.kubernetes.io/contributing/kustomize/
[MacOS Dev Guide]: https://kubectl.docs.kubernetes.io/contributing/kustomize/mac/
[Windows Dev Guide]: https://kubectl.docs.kubernetes.io/contributing/kustomize/windows/
# Contributing Guidelines
Welcome to Kubernetes. We are excited about the prospect of you joining our [community](https://github.com/kubernetes/community)! The Kubernetes community abides by the [CNCF Code of Conduct]. Here is an excerpt:
Welcome to Kubernetes. We are excited about the prospect of you joining our [community](https://github.com/kubernetes/community)! The Kubernetes community abides by the CNCF [code of conduct](code-of-conduct.md). Here is an excerpt:
_As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities._
@@ -27,22 +8,13 @@ _As contributors and maintainers of this project, and in the interest of fosteri
Dev guides:
- [Contribution Guide]
- [MacOS Dev Guide]
- [Windows Dev Guide]
- [Mac](docs/macDevGuide.md)
General resources for contributors:
We have full documentation on how to get started contributing here:
- [Contributor License Agreement] - Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests.
- [Kubernetes Contributor Guide] - Main contributor documentation.
- [Contributor Cheat Sheet] - Common resources for existing developers.
Here are some additional ideas to help you get started with Kustomize:
- Attend a Kustomize Bug Scrub. Check the [SIG-CLI] meetings list to find the next one.
- Help triage issues by confirming validity and applying the appropriate `kind` label (e.g. comment `/kind bug`).
- Pick up an issue to fix. Issues with the `help-wanted` label are a good place to start, but you can also look for any issue with the `triage/accepted` label and no assignee. Remember to `/assign` yourself to let others know you're working on it.
- Help confirm new issues labelled `kind/bug` by reproducing them with the latest release.
- Support Kustomize users by responding to questions on issues labelled `kind/support` or in the [Slack channel].
- [Contributor License Agreement](https://git.k8s.io/community/CLA.md) Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests
- [Kubernetes Contributor Guide](http://git.k8s.io/community/contributors/guide) - Main contributor documentation, or you can just jump directly to the [contributing section](http://git.k8s.io/community/contributors/guide#contributing)
- [Contributor Cheat Sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet/README.md) - Common resources for existing developers
## Mentorship
@@ -50,22 +22,19 @@ Here are some additional ideas to help you get started with Kustomize:
## Contributor Ladder
Kustomize follows the [Kubernetes Community Membership] contributor ladder. Roles are as follows:
Kustomize generally follows the [Kubernetes Community Membership](https://github.com/kubernetes/community/blob/master/community-membership.md) contributor ladder. Roles are as follows:
1. Contributor: Anyone who actively contributes code, issues or reviews to the project. All contributors must sign the [Contributor License Agreement].
1. Reviewer: Contributors with a history of review and authorship on Kustomize. Has LGTM rights on the Kustomize repo (as do all kubernetes-sigs org members). Active contributors are encouraged to join the reviewers list to be automatically pinged on PRs.
1. Approver: Highly experienced active reviewer and contributor to Kustomize. Has both LTGM and approval rights on the Kustomize repo, as well as "maintain" [Github permissions].
1. Owner: Approver who sets technical direction and makes or approves design decisions for the project. Has LGTM and approval rights on the Kustomize repo as well as "admin" [Github permissions].
The kyaml module within the Kustomize repo has additional owners following the same ladder.
1. Contributor: Anyone who actively contributes code, issues or reviews to the project. There are no Kustomize-specific requirements for this status. All contributors must [sign the CLA](https://github.com/kubernetes/community/tree/master/contributors/guide#prerequisites).
1. Member/Reviewer: All Kubernetes-SIGs org members have LGTM rights on the Kustomize repo. There are no Kustomize-specific requirements. Kustomize does not currently have any formal reviewers, but the role will be created if there is interest.
1. Maintainer/Approver: Highly experienced active reviewer and contributor to Kustomize. Has both LTGM and approval rights on the Kustomize repo, as well as [Github "maintain" rights](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-permission-levels-for-an-organization#repository-access-for-each-permission-level).
1. Admin/Owner: Maintainer who sets technical direction and makes or approves design decisions for the project. Has LGTM and approval rights on the Kustomize repo as well as [Github "admin" rights](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-permission-levels-for-an-organization#repository-access-for-each-permission-level).
Administrative notes:
- The [OWNERS file spec] is a useful resources in making changes.
- Maintainers and admins must be added to the appropriate lists in both [Kustomize OWNERS_ALIASES] and [SIG-CLI Teams]. If this isn't done, the individual in question will lack either PR approval rights (Kustomize list) or the appropriate Github repository permissions (community list).
- Maintainers and admins must be added to the appropriate list both [in the Kustomize repo](https://github.com/kubernetes-sigs/kustomize/blob/8049f7b1af52e8a7ec26faf6cf714f560d0043c5/OWNERS_ALIASES) and [in the community repo](https://github.com/kubernetes/org/blob/main/config/kubernetes-sigs/sig-cli/teams.yaml). If this isn't done, the individual in question will lack either PR approval rights (Kustomize list) or the appropriate Github repository permissions (community list).
- The spec for the OWNERS file is [in the community repo](https://github.com/kubernetes/community/blob/master/contributors/guide/owners.md).
## Contact Information
- [Slack channel]
- [Mailing list]
- [Slack channel](https://kubernetes.slack.com/messages/sig-cli)
- [Mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-cli)

View File

@@ -4,15 +4,12 @@
# Makefile for kustomize CLI and API.
SHELL := /usr/bin/env bash
GOOS = $(shell go env GOOS)
GOARCH = $(shell go env GOARCH)
MYGOBIN = $(shell go env GOBIN)
ifeq ($(MYGOBIN),)
MYGOBIN = $(shell go env GOPATH)/bin
endif
export PATH := $(MYGOBIN):$(PATH)
MODULES := '"cmd/config" "api/" "kustomize/" "kyaml/"'
LATEST_V4_RELEASE=v4.3.0
# Provide defaults for REPO_OWNER and REPO_NAME if not present.
# Typically these values would be provided by Prow.
@@ -32,7 +29,7 @@ verify-kustomize: \
lint-kustomize \
test-unit-kustomize-all \
test-examples-kustomize-against-HEAD \
test-examples-kustomize-against-v4-release
test-examples-kustomize-against-4.1
# The following target referenced by a file in
# https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/kustomize
@@ -45,7 +42,7 @@ prow-presubmit-check: \
test-unit-cmd-all \
test-go-mod \
test-examples-kustomize-against-HEAD \
test-examples-kustomize-against-v4-release
test-examples-kustomize-against-4.1
.PHONY: verify-kustomize-e2e
verify-kustomize-e2e: test-examples-e2e-kustomize
@@ -279,8 +276,8 @@ test-examples-kustomize-against-HEAD: $(MYGOBIN)/kustomize $(MYGOBIN)/mdrip
./hack/testExamplesAgainstKustomize.sh HEAD
.PHONY:
test-examples-kustomize-against-v4-release: $(MYGOBIN)/mdrip
./hack/testExamplesAgainstKustomize.sh v4@$(LATEST_V4_RELEASE)
test-examples-kustomize-against-4.1: $(MYGOBIN)/mdrip
./hack/testExamplesAgainstKustomize.sh v4@v4.1.2
# linux only.
# This is for testing an example plugin that
@@ -292,8 +289,8 @@ $(MYGOBIN)/kubeval:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
wget https://github.com/instrumenta/kubeval/releases/latest/download/kubeval-$(GOOS)-$(GOARCH).tar.gz; \
tar xf kubeval-$(GOOS)-$(GOARCH).tar.gz; \
wget https://github.com/instrumenta/kubeval/releases/latest/download/kubeval-linux-amd64.tar.gz; \
tar xf kubeval-linux-amd64.tar.gz; \
mv kubeval $(MYGOBIN); \
rm -rf $$d; \
)
@@ -307,10 +304,10 @@ $(MYGOBIN)/helmV2:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
tgzFile=helm-v2.13.1-$(GOOS)-$(GOARCH).tar.gz; \
tgzFile=helm-v2.13.1-linux-amd64.tar.gz; \
wget https://storage.googleapis.com/kubernetes-helm/$$tgzFile; \
tar -xvzf $$tgzFile; \
mv $(GOOS)-$(GOARCH)/helm $(MYGOBIN)/helmV2; \
mv linux-amd64/helm $(MYGOBIN)/helmV2; \
rm -rf $$d \
)
@@ -320,10 +317,10 @@ $(MYGOBIN)/helmV3:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
tgzFile=helm-v3.6.3-$(GOOS)-$(GOARCH).tar.gz; \
tgzFile=helm-v3.5.3-linux-amd64.tar.gz; \
wget https://get.helm.sh/$$tgzFile; \
tar -xvzf $$tgzFile; \
mv $(GOOS)-$(GOARCH)/helm $(MYGOBIN)/helmV3; \
mv linux-amd64/helm $(MYGOBIN)/helmV3; \
rm -rf $$d \
)
@@ -331,7 +328,7 @@ $(MYGOBIN)/kind:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
wget -O ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.7.0/kind-$(GOOS)-$(GOARCH); \
wget -O ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.7.0/kind-$(shell uname)-amd64; \
chmod +x ./kind; \
mv ./kind $(MYGOBIN); \
rm -rf $$d; \
@@ -342,10 +339,10 @@ $(MYGOBIN)/gh:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
tgzFile=gh_1.0.0_$(GOOS)_$(GOARCH).tar.gz; \
tgzFile=gh_1.0.0_linux_amd64.tar.gz; \
wget https://github.com/cli/cli/releases/download/v1.0.0/$$tgzFile; \
tar -xvzf $$tgzFile; \
mv gh_1.0.0_$(GOOS)_$(GOARCH)/bin/gh $(MYGOBIN)/gh; \
mv gh_1.0.0_linux_amd64/bin/gh $(MYGOBIN)/gh; \
rm -rf $$d \
)

6
OWNERS
View File

@@ -1,6 +1,4 @@
# See https://github.com/kubernetes/community/blob/master/community-membership.md
approvers:
- kustomize-approvers
reviewers:
- kustomize-reviewers
- kustomize-admins
- kustomize-maintainers

View File

@@ -1,30 +1,14 @@
# Keep *-owners and *-approvers lists in sync with *-admins and *-maintainers in
# https://github.com/kubernetes/org/blob/main/config/kubernetes-sigs/sig-cli/teams.yaml
aliases:
kustomize-owners:
kustomize-admins: # Please keep in sync with kustomize-admins in https://github.com/kubernetes/org/blob/main/config/kubernetes-sigs/sig-cli/teams.yaml
- knverey
- monopole
- pwittrock
kustomize-approvers:
kustomize-maintainers: # Please keep in sync with kustomize-maintainers in https://github.com/kubernetes/org/blob/main/config/kubernetes-sigs/sig-cli/teams.yaml
- justinsb
- knverey
- monopole
- natasha41575
- pwittrock
kustomize-reviewers:
- knverey
- monopole
- natasha41575
kyaml-approvers:
- mengqiy
- mortent
- natasha41575
- phanimarupaka
kyaml-reviewers:
- mengqiy
- mortent
- phanimarupaka
emeritus-approvers:
- liujingfang1
- Shell32-Natsu
emeritus-maintainers:
- liujingfang1
- mengqiy

View File

@@ -22,22 +22,15 @@ This tool is sponsored by [sig-cli] ([KEP]).
The kustomize build flow at [v2.0.3] was added
to [kubectl v1.14][kubectl announcement]. The kustomize
flow in kubectl remained frozen at v2.0.3 until kubectl v1.21,
which [updated it to v4.0.5][kust-in-kubectl update]. It will
be updated on a regular basis going forward, and such updates
will be reflected in the Kubernetes release notes.
| Kubectl version | Kustomize version |
| --- | --- |
| < v1.14 | n/a |
| v1.14-v1.20 | v2.0.3 |
| v1.21 | v4.0.5 |
| v1.22 | v4.2.0 |
flow in kubectl has remained frozen at v2.0.3 while work
to extract kubectl from the k/k repo, and work to remove
kustomize's dependence on core k/k code ([#2506]) has proceeded.
The reintegration effort is tracked in [#1500] (and its blocking
issues).
[v2.0.3]: /../../tree/v2.0.3
[#2506]: https://github.com/kubernetes-sigs/kustomize/issues/2506
[#1500]: https://github.com/kubernetes-sigs/kustomize/issues/1500
[kust-in-kubectl update]: https://github.com/kubernetes/kubernetes/blob/4d75a6238a6e330337526e0513e67d02b1940b63/CHANGELOG/CHANGELOG-1.21.md#kustomize-updates-in-kubectl
For examples and guides for using the kubectl integration please
see the [kubectl book] or the [kubernetes documentation].
@@ -152,7 +145,7 @@ is governed by the [Kubernetes Code of Conduct].
[`make`]: https://www.gnu.org/software/make
[`sed`]: https://www.gnu.org/software/sed
[DAM]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#declarative-application-management
[KEP]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/2377-Kustomize/README.md
[KEP]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/0008-kustomize.md
[Kubernetes Code of Conduct]: code-of-conduct.md
[applied]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#apply
[base]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#base

View File

@@ -1,14 +1,14 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// +build !windows
package filesys
package filesys_test
import (
"os"
"path/filepath"
"testing"
. "sigs.k8s.io/kustomize/api/filesys"
)
func TestJoin(t *testing.T) {

View File

@@ -1,61 +0,0 @@
// Copyright 2021 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// Package filesys provides a file system abstraction,
// a subset of that provided by golang.org/pkg/os,
// with an on-disk and in-memory representation.
//
// Deprecated: use sigs.k8s.io/kustomize/kyaml/filesys instead.
package filesys
import "sigs.k8s.io/kustomize/kyaml/filesys"
const (
// Separator is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.Separator.
Separator = filesys.Separator
// SelfDir is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.SelfDir.
SelfDir = filesys.SelfDir
// ParentDir is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.ParentDir.
ParentDir = filesys.ParentDir
)
type (
// FileSystem is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.FileSystem.
FileSystem = filesys.FileSystem
// FileSystemOrOnDisk is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.FileSystemOrOnDisk.
FileSystemOrOnDisk = filesys.FileSystemOrOnDisk
// ConfirmedDir is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.ConfirmedDir.
ConfirmedDir = filesys.ConfirmedDir
)
// MakeEmptyDirInMemory is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.MakeEmptyDirInMemory.
func MakeEmptyDirInMemory() FileSystem { return filesys.MakeEmptyDirInMemory() }
// MakeFsInMemory is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.MakeFsInMemory.
func MakeFsInMemory() FileSystem { return filesys.MakeFsInMemory() }
// MakeFsOnDisk is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.MakeFsOnDisk.
func MakeFsOnDisk() FileSystem { return filesys.MakeFsOnDisk() }
// NewTmpConfirmedDir is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.NewTmpConfirmedDir.
func NewTmpConfirmedDir() (filesys.ConfirmedDir, error) { return filesys.NewTmpConfirmedDir() }
// RootedPath is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.RootedPath.
func RootedPath(elem ...string) string { return filesys.RootedPath(elem...) }
// StripTrailingSeps is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.StripTrailingSeps.
func StripTrailingSeps(s string) string { return filesys.StripTrailingSeps(s) }
// StripLeadingSeps is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.StripLeadingSeps.
func StripLeadingSeps(s string) string { return filesys.StripLeadingSeps(s) }
// PathSplit is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.PathSplit.
func PathSplit(incoming string) []string { return filesys.PathSplit(incoming) }
// PathJoin is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.PathJoin.
func PathJoin(incoming []string) string { return filesys.PathJoin(incoming) }
// InsertPathPart is deprecated, use sigs.k8s.io/kustomize/kyaml/filesys.InsertPathPart.
func InsertPathPart(path string, pos int, part string) string {
return filesys.InsertPathPart(path, pos, part)
}

51
api/filesys/filesystem.go Normal file
View File

@@ -0,0 +1,51 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package filesys
import (
"path/filepath"
)
const (
Separator = string(filepath.Separator)
SelfDir = "."
ParentDir = ".."
)
// FileSystem groups basic os filesystem methods.
// It's supposed be functional subset of https://golang.org/pkg/os
type FileSystem interface {
// Create a file.
Create(path string) (File, error)
// MkDir makes a directory.
Mkdir(path string) error
// MkDirAll makes a directory path, creating intervening directories.
MkdirAll(path string) error
// RemoveAll removes path and any children it contains.
RemoveAll(path string) error
// Open opens the named file for reading.
Open(path string) (File, error)
// IsDir returns true if the path is a directory.
IsDir(path string) bool
// ReadDir returns a list of files and directories within a directory.
ReadDir(path string) ([]string, error)
// CleanedAbs converts the given path into a
// directory and a file name, where the directory
// is represented as a ConfirmedDir and all that implies.
// If the entire path is a directory, the file component
// is an empty string.
CleanedAbs(path string) (ConfirmedDir, string, error)
// Exists is true if the path exists in the file system.
Exists(path string) bool
// Glob returns the list of matching files,
// emulating https://golang.org/pkg/path/filepath/#Glob
Glob(pattern string) ([]string, error)
// ReadFile returns the contents of the file at the given path.
ReadFile(path string) ([]byte, error)
// WriteFile writes the data to a file at the given path,
// overwriting anything that's already there.
WriteFile(path string, data []byte) error
// Walk walks the file system with the given WalkFunc.
Walk(path string, walkFn filepath.WalkFunc) error
}

View File

@@ -123,11 +123,11 @@ func (n *fsNode) addFile(name string, c []byte) (result *fsNode, err error) {
if result.offset != nil {
return nil, fmt.Errorf("cannot add already opened file '%s'", n.Path())
}
result.content = append(result.content[:0], c...)
result.content = c
return result, nil
}
result = &fsNode{
content: append([]byte(nil), c...),
content: c,
parent: parent,
}
parent.dir[fileName] = result
@@ -236,7 +236,7 @@ func (n *fsNode) CleanedAbs(path string) (ConfirmedDir, string, error) {
return "", "", errors.Wrap(err, "unable to clean")
}
if node == nil {
return "", "", notExistError(path)
return "", "", fmt.Errorf("'%s' doesn't exist", path)
}
if node.isNodeADir() {
return ConfirmedDir(node.Path()), "", nil
@@ -309,8 +309,7 @@ func (n *fsNode) RemoveAll(path string) error {
return err
}
if result == nil {
// If the path doesn't exist, no need to remove anything.
return nil
return fmt.Errorf("cannot find '%s' to remove it", path)
}
return result.Remove()
}
@@ -352,9 +351,6 @@ func (n *fsNode) IsDir(path string) bool {
// ReadDir implements FileSystem.
func (n *fsNode) ReadDir(path string) ([]string, error) {
if !n.Exists(path) {
return nil, notExistError(path)
}
if !n.IsDir(path) {
return nil, fmt.Errorf("%s is not a directory", path)
}
@@ -402,7 +398,7 @@ func (n *fsNode) Open(path string) (File, error) {
return nil, err
}
if result == nil {
return nil, notExistError(path)
return nil, fmt.Errorf("cannot find '%s' to open it", path)
}
if result.offset != nil {
return nil, fmt.Errorf("cannot open previously opened file '%s'", path)
@@ -427,7 +423,7 @@ func (n *fsNode) ReadFile(path string) (c []byte, err error) {
return nil, err
}
if result == nil {
return nil, notExistError(path)
return nil, fmt.Errorf("cannot find '%s' to read it", path)
}
if result.isNodeADir() {
return nil, fmt.Errorf("cannot read content from non-file '%s'", n.Path())
@@ -494,7 +490,7 @@ func (n *fsNode) Walk(path string, walkFn filepath.WalkFunc) error {
return err
}
if result == nil {
return notExistError(path)
return fmt.Errorf("cannot find '%s' to walk it", path)
}
return result.WalkMe(walkFn)
}
@@ -633,10 +629,3 @@ func (n *fsNode) Glob(pattern string) ([]string, error) {
sort.Strings(result)
return result, nil
}
// notExistError indicates that a file or directory does not exist.
// Unwrapping returns os.ErrNotExist so errors.Is(err, os.ErrNotExist) works correctly.
type notExistError string
func (err notExistError) Error() string { return fmt.Sprintf("'%s' doesn't exist", string(err)) }
func (err notExistError) Unwrap() error { return os.ErrNotExist }

View File

@@ -1,8 +1,6 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// +build !windows
package filesys
import (
@@ -157,13 +155,9 @@ func runBasicOperations(
if string(stuff) != both {
t.Fatalf("%s; unexpected content '%s', expected '%s'", c.what, stuff, both)
}
content := []byte(shortContent)
if err := fSys.WriteFile(c.path, content); err != nil {
if err := fSys.WriteFile(c.path, []byte(shortContent)); err != nil {
t.Fatalf("%s; unexpected error: %v", c.what, err)
}
// This ensures that modifying the original slice does not change the contents of the file.
content[0] = '@'
stuff, err = fSys.ReadFile(c.path)
if err != nil {
t.Fatalf("%s; unexpected error: %v", c.what, err)

View File

@@ -57,7 +57,7 @@ func (x fsOnDisk) CleanedAbs(
deLinked, err := filepath.EvalSymlinks(absRoot)
if err != nil {
return "", "", fmt.Errorf(
"evalsymlink failure on '%s' : %w", path, err)
"evalsymlink failure on '%s' : %v", path, err)
}
if x.IsDir(deLinked) {
return ConfirmedDir(deLinked), "", nil

View File

@@ -1,9 +1,7 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// +build !windows
package filesys
package filesys_test
import (
"io/ioutil"
@@ -12,6 +10,8 @@ import (
"path/filepath"
"reflect"
"testing"
. "sigs.k8s.io/kustomize/api/filesys"
)
func makeTestDir(t *testing.T) (FileSystem, string) {

View File

@@ -1,14 +1,11 @@
// Copyright 2021 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// +build !windows
package filesys
package filesys_test
import (
"os"
"path/filepath"
"testing"
. "sigs.k8s.io/kustomize/api/filesys"
)
// Confirm behavior of filepath.Match

View File

@@ -4,7 +4,6 @@
package imagetag
import (
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
@@ -75,7 +74,7 @@ func (f findFieldsFilter) walk(node *yaml.RNode) error {
return err
}
key := n.Key.YNode().Value
if utils.StringSliceContains(f.fields, key) {
if contains(f.fields, key) {
return f.fieldCallback(n.Value)
}
return nil
@@ -88,6 +87,15 @@ func (f findFieldsFilter) walk(node *yaml.RNode) error {
return nil
}
func contains(slice []string, str string) bool {
for _, s := range slice {
if s == str {
return true
}
}
return false
}
func checkImageTagsFn(imageTag types.Image) fieldCallback {
return func(node *yaml.RNode) error {
if node.YNode().Kind != yaml.SequenceNode {

View File

@@ -56,7 +56,6 @@ func (f Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
// sanity check.
return nil, err
}
f.NameFieldToUpdate.Gvk = f.Referrer.GetGvk()
if err := node.PipeE(fieldspec.Filter{
FieldSpec: f.NameFieldToUpdate,
SetValue: f.set,

View File

@@ -250,7 +250,6 @@ metadata:
name: dep
annotations:
config.kubernetes.io/index: '0'
internal.config.kubernetes.io/index: '0'
data:
slice:
- false
@@ -277,7 +276,6 @@ metadata:
name: dep
annotations:
config.kubernetes.io/index: '0'
internal.config.kubernetes.io/index: '0'
data:
1: str
: invalid map key: value='1', tag='` + yaml.NodeTagInt + `'`,

View File

@@ -44,17 +44,11 @@ func applyReplacement(nodes []*yaml.RNode, value *yaml.RNode, targets []*types.T
t.FieldPaths = []string{types.DefaultReplacementFieldPath}
}
for _, n := range nodes {
ids, err := utils.MakeResIds(n)
if err != nil {
return nil, err
}
for _, id := range ids {
if id.IsSelectedBy(t.Select.ResId) && !rejectId(t.Reject, &id) {
err := applyToNode(n, value, t)
if err != nil {
return nil, err
}
break
id := makeResId(n)
if id.IsSelectedBy(t.Select.ResId) && !rejectId(t.Reject, id) {
err := applyToNode(n, value, t)
if err != nil {
return nil, err
}
}
}
@@ -131,11 +125,10 @@ func getReplacement(nodes []*yaml.RNode, r *types.Replacement) (*yaml.RNode, err
if err != nil {
return nil, err
}
if rn.IsNilOrEmpty() {
return nil, fmt.Errorf("fieldPath `%s` is missing for replacement source %s", r.Source.FieldPath, r.Source)
if !rn.IsNilOrEmpty() {
return getRefinedValue(r.Source.Options, rn)
}
return getRefinedValue(r.Source.Options, rn)
return rn, nil
}
func getRefinedValue(options *types.FieldOptions, rn *yaml.RNode) (*yaml.RNode, error) {
@@ -159,19 +152,12 @@ func getRefinedValue(options *types.FieldOptions, rn *yaml.RNode) (*yaml.RNode,
func selectSourceNode(nodes []*yaml.RNode, selector *types.SourceSelector) (*yaml.RNode, error) {
var matches []*yaml.RNode
for _, n := range nodes {
ids, err := utils.MakeResIds(n)
if err != nil {
return nil, err
}
for _, id := range ids {
if id.IsSelectedBy(selector.ResId) {
if len(matches) > 0 {
return nil, fmt.Errorf(
"multiple matches for selector %s", selector)
}
matches = append(matches, n)
break
if makeResId(n).IsSelectedBy(selector.ResId) {
if len(matches) > 0 {
return nil, fmt.Errorf(
"multiple matches for selector %s", selector)
}
matches = append(matches, n)
}
}
if len(matches) == 0 {
@@ -179,3 +165,17 @@ func selectSourceNode(nodes []*yaml.RNode, selector *types.SourceSelector) (*yam
}
return matches[0], nil
}
// makeResId makes a ResId from an RNode.
func makeResId(n *yaml.RNode) *resid.ResId {
apiVersion := n.Field(yaml.APIVersionField)
var group, version string
if apiVersion != nil {
group, version = resid.ParseGroupVersion(yaml.GetValue(apiVersion.Value))
}
return &resid.ResId{
Gvk: resid.Gvk{Group: group, Version: version, Kind: n.GetKind()},
Name: n.GetName(),
Namespace: n.GetNamespace(),
}
}

View File

@@ -1338,34 +1338,6 @@ spec:
`,
expectedErr: "delimiter option can only be used with scalar nodes",
},
"mapping value contains '.' character": {
input: `apiVersion: v1
kind: Custom
metadata:
name: custom
annotations:
a.b.c/d-e: source
f.g.h/i-j: target
`,
replacements: `replacements:
- source:
name: custom
fieldPath: metadata.annotations.[a.b.c/d-e]
targets:
- select:
name: custom
fieldPaths:
- metadata.annotations.[f.g.h/i-j]
`,
expected: `apiVersion: v1
kind: Custom
metadata:
name: custom
annotations:
a.b.c/d-e: source
f.g.h/i-j: source
`,
},
"list index contains '.' character": {
input: `apiVersion: v1
kind: ConfigMap
@@ -1508,86 +1480,6 @@ spec:
property: third
`,
},
"using a previous ID": {
input: `apiVersion: v1
kind: Deployment
metadata:
name: pre-deploy
annotations:
internal.config.kubernetes.io/previousNames: deploy,deploy
internal.config.kubernetes.io/previousKinds: CronJob,Deployment
internal.config.kubernetes.io/previousNamespaces: default,default
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: postgres:1.8.0
name: postgresdb
`,
replacements: `replacements:
- source:
kind: CronJob
name: deploy
fieldPath: spec.template.spec.containers.0.image
targets:
- select:
kind: Deployment
name: deploy
fieldPaths:
- spec.template.spec.containers.1.image
`,
expected: `apiVersion: v1
kind: Deployment
metadata:
name: pre-deploy
annotations:
internal.config.kubernetes.io/previousNames: deploy,deploy
internal.config.kubernetes.io/previousKinds: CronJob,Deployment
internal.config.kubernetes.io/previousNamespaces: default,default
spec:
template:
spec:
containers:
- image: nginx:1.7.9
name: nginx-tagged
- image: nginx:1.7.9
name: postgresdb
`,
},
"replacement source.fieldPath does not exist": {
input: `apiVersion: v1
kind: ConfigMap
metadata:
name: ports-from
data:
grpcPort: 8080
---
apiVersion: v1
kind: ConfigMap
metadata:
name: ports-to
data:
grpcPort: 8081
`,
replacements: `replacements:
- source:
kind: ConfigMap
name: ports-from
fieldPath: data.httpPort
targets:
- select:
kind: ConfigMap
name: ports-to
fieldPaths:
- data.grpcPort
options:
create: true
`,
expectedErr: "fieldPath `data.httpPort` is missing for replacement source ~G_~V_ConfigMap|~X|ports-from:data.httpPort",
},
}
for tn, tc := range testCases {

View File

@@ -6,7 +6,7 @@ package valueadd
import (
"strings"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)

View File

@@ -3,7 +3,7 @@ module sigs.k8s.io/kustomize/api
go 1.16
require (
github.com/evanphx/json-patch v4.11.0+incompatible
github.com/evanphx/json-patch v4.5.0+incompatible
github.com/go-errors/errors v1.0.1
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/imdario/mergo v0.3.5
@@ -11,6 +11,10 @@ require (
github.com/stretchr/testify v1.5.1
gopkg.in/yaml.v2 v2.4.0
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e
sigs.k8s.io/kustomize/kyaml v0.12.0
sigs.k8s.io/kustomize/kyaml v0.10.20
sigs.k8s.io/yaml v1.2.0
)
replace gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
replace sigs.k8s.io/kustomize/kyaml => ../kyaml

View File

@@ -30,8 +30,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
@@ -217,14 +217,13 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
sigs.k8s.io/kustomize/kyaml v0.12.0 h1:k08l8SLwnKa/eXXB5GW2/OnEc/4gJF90VDFebsOwqw4=
sigs.k8s.io/kustomize/kyaml v0.12.0/go.mod h1:FTJxEZ86ScK184NpGSAQcfEqee0nul8oLCK30D47m4E=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=

View File

@@ -9,10 +9,10 @@ import (
"github.com/pkg/errors"
"k8s.io/kube-openapi/pkg/validation/spec"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/resid"
"sigs.k8s.io/yaml"
)

View File

@@ -8,11 +8,11 @@ import (
"testing"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/filesys"
. "sigs.k8s.io/kustomize/api/internal/accumulator"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
"sigs.k8s.io/kustomize/api/loader"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/resid"
)

View File

@@ -11,7 +11,6 @@ import (
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/kyaml/resid"
)
type nameReferenceTransformer struct {
@@ -110,18 +109,11 @@ func debug(fMap filterMap) {
// 'spec/scaleTargetRef/name' field. Return a filter that can do that.
func (t *nameReferenceTransformer) determineFilters(
resources []*resource.Resource) (fMap filterMap) {
// We cache the resource OrgId values because they don't change and otherwise are very visible in a memory pprof
resourceOrgIds := make([]resid.ResId, len(resources))
for i, resource := range resources {
resourceOrgIds[i] = resource.OrgId()
}
fMap = make(filterMap)
for _, backReference := range t.backRefs {
for _, referrerSpec := range backReference.Referrers {
for i, res := range resources {
if resourceOrgIds[i].IsSelected(&referrerSpec.Gvk) {
for _, res := range resources {
if res.OrgId().IsSelected(&referrerSpec.Gvk) {
// If this is true, the res might be a referrer, and if
// so, the name reference it holds might need an update.
if resHasField(res, referrerSpec.Path) {

View File

@@ -897,9 +897,7 @@ func TestNameReferenceClusterWide(t *testing.T) {
t.Fatalf("unexpected error: %v", err)
}
expected.RemoveBuildAnnotations()
m.RemoveBuildAnnotations()
if err = expected.ErrorIfNotEqualLists(m); err != nil {
t.Fatalf(notEqualErrFmt, err)
}

View File

@@ -168,23 +168,3 @@ func (ra *ResAccumulator) FixBackReferences() (err error) {
return ra.Transform(
newNameReferenceTransformer(ra.tConfig.NameReference))
}
// Intersection drops the resources which "other" does not have.
func (ra *ResAccumulator) Intersection(other resmap.ResMap) error {
for _, curId := range ra.resMap.AllIds() {
toDelete := true
for _, otherId := range other.AllIds() {
if otherId == curId {
toDelete = false
break
}
}
if toDelete {
err := ra.resMap.Remove(curId)
if err != nil {
return err
}
}
}
return nil
}

View File

@@ -362,10 +362,10 @@ func TestResolveVarsWithNoambiguation(t *testing.T) {
"metadata": map[string]interface{}{
"name": "sub-backendOne",
"annotations": map[string]interface{}{
"internal.config.kubernetes.io/previousKinds": "Service",
"internal.config.kubernetes.io/previousNames": "backendOne",
"internal.config.kubernetes.io/previousNamespaces": "default",
"internal.config.kubernetes.io/prefixes": "sub-",
"config.kubernetes.io/previousKinds": "Service",
"config.kubernetes.io/previousNames": "backendOne",
"config.kubernetes.io/previousNamespaces": "default",
"config.kubernetes.io/prefixes": "sub-",
},
}}).ResMap()

View File

@@ -8,12 +8,12 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filesys"
. "sigs.k8s.io/kustomize/api/internal/generators"
"sigs.k8s.io/kustomize/api/kv"
"sigs.k8s.io/kustomize/api/loader"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
var binaryHello = []byte{

View File

@@ -8,12 +8,12 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filesys"
. "sigs.k8s.io/kustomize/api/internal/generators"
"sigs.k8s.io/kustomize/api/kv"
"sigs.k8s.io/kustomize/api/loader"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func TestMakeSecret(t *testing.T) {

View File

@@ -4,7 +4,7 @@
package git
import (
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/api/filesys"
)
// Cloner is a function that can clone a git repo.

View File

@@ -8,8 +8,8 @@ import (
"time"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// gitRunner runs the external git binary.

View File

@@ -11,7 +11,7 @@ import (
"strings"
"time"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/api/filesys"
)
// Used as a temporary non-empty occupant of the cloneDir
@@ -125,7 +125,7 @@ func parseGitUrl(n string) (
index := strings.Index(n, gitSuffix)
orgRepo = n[0:index]
n = n[index+len(gitSuffix):]
if len(n) > 0 && n[0] == '/' {
if n[0] == '/' {
n = n[1:]
}
path, gitRef, gitTimeout, gitSubmodules = peelQuery(n)

View File

@@ -35,6 +35,7 @@ var hostNamesRawAndNormalized = [][]string{
{"git::https://git.example.com/", "https://git.example.com/"},
{"git@github.com:", "git@github.com:"},
{"git@github.com/", "git@github.com:"},
{"git@gitlab2.sqtools.ru:10022/", "git@gitlab2.sqtools.ru:10022/"},
}
func makeUrl(hostFmt, orgRepo, path, href string) string {
@@ -182,12 +183,6 @@ func TestNewRepoSpecFromUrl_CloneSpecs(t *testing.T) {
absPath: notCloned.String(),
ref: "",
},
"t12": {
input: "https://bitbucket.example.com/scm/project/repository.git",
cloneSpec: "https://bitbucket.example.com/scm/project/repository.git",
absPath: notCloned.String(),
ref: "",
},
}
for tn, tc := range testcases {
t.Run(tn, func(t *testing.T) {

View File

@@ -7,9 +7,9 @@ import (
"reflect"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/loader"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/resid"
)

View File

@@ -7,9 +7,9 @@ import (
"path/filepath"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
. "sigs.k8s.io/kustomize/api/internal/plugins/compiler"
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// Regression coverage over compiler behavior.

View File

@@ -10,6 +10,7 @@ import (
"testing"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/filesys"
. "sigs.k8s.io/kustomize/api/internal/plugins/execplugin"
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
@@ -17,7 +18,6 @@ import (
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func TestExecPluginConfig(t *testing.T) {

View File

@@ -78,8 +78,6 @@ func NewFnPlugin(o *types.FnPluginLoadingOptions) *FnPlugin {
EnableExec: o.EnableExec,
StorageMounts: toStorageMounts(o.Mounts),
Env: o.Env,
AsCurrentUser: o.AsCurrentUser,
WorkingDir: o.WorkingDir,
},
}
}

View File

@@ -13,6 +13,7 @@ import (
"strings"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers"
"sigs.k8s.io/kustomize/api/internal/plugins/execplugin"
@@ -22,7 +23,6 @@ import (
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/resid"
)
@@ -47,11 +47,6 @@ func (l *Loader) Config() *types.PluginConfig {
return l.pc
}
// SetWorkDir sets the working directory for this loader's plugins
func (l *Loader) SetWorkDir(wd string) {
l.pc.FnpLoadingOptions.WorkingDir = wd
}
func (l *Loader) LoadGenerators(
ldr ifc.Loader, v ifc.Validator, rm resmap.ResMap) ([]resmap.Generator, error) {
var result []resmap.Generator

View File

@@ -6,6 +6,7 @@ package loader_test
import (
"testing"
"sigs.k8s.io/kustomize/api/filesys"
. "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/loader"
"sigs.k8s.io/kustomize/api/provider"
@@ -13,7 +14,6 @@ import (
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
const (

View File

@@ -12,11 +12,11 @@ import (
"strconv"
"time"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/yaml"
)
@@ -231,10 +231,10 @@ func UpdateResourceOptions(rm resmap.ResMap) (resmap.ResMap, error) {
if err := r.SetAnnotations(annotations); err != nil {
return nil, err
}
if needsHash {
r.EnableHashSuffix()
}
r.SetBehavior(types.NewGenerationBehavior(behavior))
r.SetOptions(types.NewGenArgs(
&types.GeneratorArgs{
Behavior: behavior,
Options: &types.GeneratorOptions{DisableNameSuffixHash: !needsHash}}))
}
return rm, nil
}

View File

@@ -11,12 +11,12 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func TestDeterminePluginSrcRoot(t *testing.T) {

View File

@@ -10,17 +10,14 @@ import (
"strings"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/builtins"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/accumulator"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers"
"sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/yaml"
@@ -41,13 +38,11 @@ func NewKustTarget(
validator ifc.Validator,
rFactory *resmap.Factory,
pLdr *loader.Loader) *KustTarget {
pLdrCopy := *pLdr
pLdrCopy.SetWorkDir(ldr.Root())
return &KustTarget{
ldr: ldr,
validator: validator,
rFactory: rFactory,
pLdr: &pLdrCopy,
pLdr: pLdr,
}
}
@@ -113,7 +108,7 @@ func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) {
}
func (kt *KustTarget) makeCustomizedResMap() (resmap.ResMap, error) {
ra, err := kt.AccumulateTarget(&resource.Origin{})
ra, err := kt.AccumulateTarget()
if err != nil {
return nil, err
}
@@ -156,29 +151,20 @@ func (kt *KustTarget) addHashesToNames(
// holding customized resources and the data/rules used
// to do so. The name back references and vars are
// not yet fixed.
// The origin parameter is used through the recursive calls
// to annotate each resource with information about where
// the resource came from, e.g. the file and/or the repository
// it originated from.
// As an entrypoint, one can pass an empty resource.Origin object to
// AccumulateTarget. As AccumulateTarget moves recursively
// through kustomization directories, it updates `origin.path`
// accordingly. When a remote base is found, it updates `origin.repo`
// and `origin.ref` accordingly.
func (kt *KustTarget) AccumulateTarget(origin *resource.Origin) (
func (kt *KustTarget) AccumulateTarget() (
ra *accumulator.ResAccumulator, err error) {
return kt.accumulateTarget(accumulator.MakeEmptyAccumulator(), origin)
return kt.accumulateTarget(accumulator.MakeEmptyAccumulator())
}
// ra should be empty when this KustTarget is a Kustomization, or the ra of the parent if this KustTarget is a Component
// (or empty if the Component does not have a parent).
func (kt *KustTarget) accumulateTarget(ra *accumulator.ResAccumulator, origin *resource.Origin) (
func (kt *KustTarget) accumulateTarget(ra *accumulator.ResAccumulator) (
resRa *accumulator.ResAccumulator, err error) {
ra, err = kt.accumulateResources(ra, kt.kustomization.Resources, origin)
ra, err = kt.accumulateResources(ra, kt.kustomization.Resources)
if err != nil {
return nil, errors.Wrap(err, "accumulating resources")
}
ra, err = kt.accumulateComponents(ra, kt.kustomization.Components, origin)
ra, err = kt.accumulateComponents(ra, kt.kustomization.Components)
if err != nil {
return nil, errors.Wrap(err, "accumulating components")
}
@@ -219,26 +205,9 @@ func (kt *KustTarget) accumulateTarget(ra *accumulator.ResAccumulator, origin *r
return nil, errors.Wrapf(
err, "merging vars %v", kt.kustomization.Vars)
}
err = kt.IgnoreLocal(ra)
if err != nil {
return nil, err
}
return ra, nil
}
// IgnoreLocal drops the local resource by checking the annotation "config.kubernetes.io/local-config".
func (kt *KustTarget) IgnoreLocal(ra *accumulator.ResAccumulator) error {
rf := kt.rFactory.RF()
if rf.IncludeLocalConfigs {
return nil
}
remainRes, err := rf.DropLocalNodes(ra.ResMap().ToRNodeSlice())
if err != nil {
return err
}
return ra.Intersection(kt.rFactory.FromResourceSlice(remainRes))
}
func (kt *KustTarget) runGenerators(
ra *accumulator.ResAccumulator) error {
var generators []resmap.Generator
@@ -278,7 +247,7 @@ func (kt *KustTarget) configureExternalGenerators() ([]resmap.Generator, error)
}
ra.AppendAll(rm)
}
ra, err := kt.accumulateResources(ra, generatorPaths, &resource.Origin{})
ra, err := kt.accumulateResources(ra, generatorPaths)
if err != nil {
return nil, err
}
@@ -314,7 +283,8 @@ func (kt *KustTarget) configureExternalTransformers(transformers []string) ([]re
}
ra.AppendAll(rm)
}
ra, err := kt.accumulateResources(ra, transformerPaths, &resource.Origin{})
ra, err := kt.accumulateResources(ra, transformerPaths)
if err != nil {
return nil, err
}
@@ -362,16 +332,16 @@ func (kt *KustTarget) removeValidatedByLabel(rm resmap.ResMap) error {
// accumulateResources fills the given resourceAccumulator
// with resources read from the given list of paths.
func (kt *KustTarget) accumulateResources(
ra *accumulator.ResAccumulator, paths []string, origin *resource.Origin) (*accumulator.ResAccumulator, error) {
ra *accumulator.ResAccumulator, paths []string) (*accumulator.ResAccumulator, error) {
for _, path := range paths {
// try loading resource as file then as base (directory or git repository)
if errF := kt.accumulateFile(ra, path, origin); errF != nil {
if errF := kt.accumulateFile(ra, path); errF != nil {
ldr, err := kt.ldr.New(path)
if err != nil {
return nil, errors.Wrapf(
err, "accumulation err='%s'", errF.Error())
}
ra, err = kt.accumulateDirectory(ra, ldr, origin.Append(path), false)
ra, err = kt.accumulateDirectory(ra, ldr, false)
if err != nil {
return nil, errors.Wrapf(
err, "accumulation err='%s'", errF.Error())
@@ -384,7 +354,7 @@ func (kt *KustTarget) accumulateResources(
// accumulateResources fills the given resourceAccumulator
// with resources read from the given list of paths.
func (kt *KustTarget) accumulateComponents(
ra *accumulator.ResAccumulator, paths []string, origin *resource.Origin) (*accumulator.ResAccumulator, error) {
ra *accumulator.ResAccumulator, paths []string) (*accumulator.ResAccumulator, error) {
for _, path := range paths {
// Components always refer to directories
ldr, errL := kt.ldr.New(path)
@@ -392,8 +362,7 @@ func (kt *KustTarget) accumulateComponents(
return nil, fmt.Errorf("loader.New %q", errL)
}
var errD error
origin.Path = filepath.Join(origin.Path, path)
ra, errD = kt.accumulateDirectory(ra, ldr, origin, true)
ra, errD = kt.accumulateDirectory(ra, ldr, true)
if errD != nil {
return nil, fmt.Errorf("accumulateDirectory: %q", errD)
}
@@ -402,7 +371,7 @@ func (kt *KustTarget) accumulateComponents(
}
func (kt *KustTarget) accumulateDirectory(
ra *accumulator.ResAccumulator, ldr ifc.Loader, origin *resource.Origin, isComponent bool) (*accumulator.ResAccumulator, error) {
ra *accumulator.ResAccumulator, ldr ifc.Loader, isComponent bool) (*accumulator.ResAccumulator, error) {
defer ldr.Cleanup()
subKt := NewKustTarget(ldr, kt.validator, kt.rFactory, kt.pLdr)
err := subKt.Load()
@@ -410,7 +379,6 @@ func (kt *KustTarget) accumulateDirectory(
return nil, errors.Wrapf(
err, "couldn't make target for path '%s'", ldr.Root())
}
subKt.kustomization.BuildMetadata = kt.kustomization.BuildMetadata
var bytes []byte
path := ldr.Root()
if openApiPath, exists := subKt.Kustomization().OpenAPI["path"]; exists {
@@ -434,12 +402,12 @@ func (kt *KustTarget) accumulateDirectory(
var subRa *accumulator.ResAccumulator
if isComponent {
// Components don't create a new accumulator: the kustomization directives are added to the current accumulator
subRa, err = subKt.accumulateTarget(ra, origin)
subRa, err = subKt.accumulateTarget(ra)
ra = accumulator.MakeEmptyAccumulator()
} else {
// Child Kustomizations create a new accumulator which resolves their kustomization directives, which will later
// be merged into the current accumulator.
subRa, err = subKt.AccumulateTarget(origin)
subRa, err = subKt.AccumulateTarget()
}
if err != nil {
return nil, errors.Wrapf(
@@ -454,18 +422,11 @@ func (kt *KustTarget) accumulateDirectory(
}
func (kt *KustTarget) accumulateFile(
ra *accumulator.ResAccumulator, path string, origin *resource.Origin) error {
ra *accumulator.ResAccumulator, path string) error {
resources, err := kt.rFactory.FromFile(kt.ldr, path)
if err != nil {
return errors.Wrapf(err, "accumulating resources from '%s'", path)
}
if utils.StringSliceContains(kt.kustomization.BuildMetadata, "originAnnotations") {
origin = origin.Append(path)
err = resources.AnnotateAll(utils.OriginAnnotation, origin.String())
if err != nil {
return errors.Wrapf(err, "cannot add path annotation for '%s'", path)
}
}
err = ra.AppendAll(resources)
if err != nil {
return errors.Wrapf(err, "merging resources from '%s'", path)

View File

@@ -255,5 +255,5 @@ metadata:
actual.RemoveBuildAnnotations()
actYaml, err := actual.AsYaml()
assert.NoError(t, err)
assert.Equal(t, string(expYaml), string(actYaml))
assert.Equal(t, expYaml, actYaml)
}

View File

@@ -6,6 +6,7 @@ package target_test
import (
"testing"
"sigs.k8s.io/kustomize/api/filesys"
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/internal/target"
fLdr "sigs.k8s.io/kustomize/api/loader"
@@ -13,7 +14,6 @@ import (
"sigs.k8s.io/kustomize/api/resmap"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func makeAndLoadKustTarget(

View File

@@ -8,7 +8,6 @@ import (
"strings"
"testing"
"sigs.k8s.io/kustomize/api/resource"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/resid"
@@ -66,7 +65,7 @@ vars:
apiVersion: v300
`)
ra, err := makeAndLoadKustTarget(
t, th.GetFSys(), "/app").AccumulateTarget(&resource.Origin{})
t, th.GetFSys(), "/app").AccumulateTarget()
if err != nil {
t.Fatalf("Err: %v", err)
}
@@ -121,7 +120,7 @@ resources:
`)
ra, err := makeAndLoadKustTarget(
t, th.GetFSys(), "/app/overlays/o2").AccumulateTarget(&resource.Origin{})
t, th.GetFSys(), "/app/overlays/o2").AccumulateTarget()
if err != nil {
t.Fatalf("Err: %v", err)
}
@@ -178,7 +177,7 @@ resources:
- ../o1
`)
_, err := makeAndLoadKustTarget(
t, th.GetFSys(), "/app/overlays/o2").AccumulateTarget(&resource.Origin{})
t, th.GetFSys(), "/app/overlays/o2").AccumulateTarget()
if err == nil {
t.Fatalf("expected var collision")
}

View File

@@ -1,23 +0,0 @@
package utils
import "sigs.k8s.io/kustomize/api/konfig"
const (
BuildAnnotationPreviousKinds = konfig.ConfigAnnoDomain + "/previousKinds"
BuildAnnotationPreviousNames = konfig.ConfigAnnoDomain + "/previousNames"
BuildAnnotationPrefixes = konfig.ConfigAnnoDomain + "/prefixes"
BuildAnnotationSuffixes = konfig.ConfigAnnoDomain + "/suffixes"
BuildAnnotationPreviousNamespaces = konfig.ConfigAnnoDomain + "/previousNamespaces"
BuildAnnotationsRefBy = konfig.ConfigAnnoDomain + "/refBy"
BuildAnnotationsGenBehavior = konfig.ConfigAnnoDomain + "/generatorBehavior"
BuildAnnotationsGenAddHashSuffix = konfig.ConfigAnnoDomain + "/needsHashSuffix"
// the following are only for patches, to specify whether they can change names
// and kinds of their targets
BuildAnnotationAllowNameChange = konfig.ConfigAnnoDomain + "/allowNameChange"
BuildAnnotationAllowKindChange = konfig.ConfigAnnoDomain + "/allowKindChange"
OriginAnnotation = "config.kubernetes.io/origin"
Enabled = "enabled"
)

View File

@@ -1,64 +0,0 @@
package utils
import (
"fmt"
"strings"
"sigs.k8s.io/kustomize/kyaml/resid"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// MakeResIds returns all of an RNode's current and previous Ids
func MakeResIds(n *yaml.RNode) ([]resid.ResId, error) {
var result []resid.ResId
apiVersion := n.Field(yaml.APIVersionField)
var group, version string
if apiVersion != nil {
group, version = resid.ParseGroupVersion(yaml.GetValue(apiVersion.Value))
}
result = append(result, resid.NewResIdWithNamespace(
resid.Gvk{Group: group, Version: version, Kind: n.GetKind()}, n.GetName(), n.GetNamespace()),
)
prevIds, err := PrevIds(n)
if err != nil {
return nil, err
}
result = append(result, prevIds...)
return result, nil
}
// PrevIds returns all of an RNode's previous Ids
func PrevIds(n *yaml.RNode) ([]resid.ResId, error) {
var ids []resid.ResId
// TODO: merge previous names and namespaces into one list of
// pairs on one annotation so there is no chance of error
annotations := n.GetAnnotations()
if _, ok := annotations[BuildAnnotationPreviousNames]; !ok {
return nil, nil
}
names := strings.Split(annotations[BuildAnnotationPreviousNames], ",")
ns := strings.Split(annotations[BuildAnnotationPreviousNamespaces], ",")
kinds := strings.Split(annotations[BuildAnnotationPreviousKinds], ",")
// This should never happen
if len(names) != len(ns) || len(names) != len(kinds) {
return nil, fmt.Errorf(
"number of previous names, " +
"number of previous namespaces, " +
"number of previous kinds not equal")
}
for i := range names {
meta, err := n.GetMeta()
if err != nil {
return nil, err
}
group, version := resid.ParseGroupVersion(meta.APIVersion)
gvk := resid.Gvk{
Group: group,
Version: version,
Kind: kinds[i],
}
ids = append(ids, resid.NewResIdWithNamespace(
gvk, names[i], ns[i]))
}
return ids, nil
}

View File

@@ -23,17 +23,12 @@ func PathSplitter(path string, delimiter string) []string {
return res
}
// SmarterPathSplitter splits a path, retaining bracketed elements.
// If the element is a list entry identifier (defined by the '='),
// it will retain the brackets.
// E.g. "[name=com.foo.someapp]" survives as one thing after splitting
// SmarterPathSplitter splits a path, retaining bracketed list entry identifiers.
// E.g. [name=com.foo.someapp] survives as one thing after splitting
// "spec.template.spec.containers.[name=com.foo.someapp].image"
// See kyaml/yaml/match.go for use of list entry identifiers.
// If the element is a mapping entry identifier, it will remove the
// brackets.
// E.g. "a.b.c" survives as one thing after splitting
// "metadata.annotations.[a.b.c]
// This function uses `PathSplitter`, so it also respects escaped delimiters.
// This function uses `PathSplitter`, so it respects list entry identifiers
// and escaped delimiters.
func SmarterPathSplitter(path string, delimiter string) []string {
var result []string
split := PathSplitter(path, delimiter)
@@ -50,12 +45,7 @@ func SmarterPathSplitter(path string, delimiter string) []string {
break
}
}
bracketedStr := strings.Join(bracketed, delimiter)
if strings.Contains(bracketedStr, "=") {
result = append(result, bracketedStr)
} else {
result = append(result, strings.Trim(bracketedStr, "[]"))
}
result = append(result, strings.Join(bracketed, delimiter))
} else {
result = append(result, elem)
}

View File

@@ -81,10 +81,6 @@ func TestSmarterPathSplitter(t *testing.T) {
input: "spec.data.[name=f.i.[r.s.t..key",
expected: []string{"spec", "data", "[name=f.i.[r.s.t..key"},
},
"mapping value with .": {
input: "metadata.annotations.[a.b.c/d.e.f-g.]",
expected: []string{"metadata", "annotations", "a.b.c/d.e.f-g."},
},
}
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {

View File

@@ -1,44 +0,0 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package utils
// StringSliceIndex returns the index of the str, else -1.
func StringSliceIndex(slice []string, str string) int {
for i := range slice {
if slice[i] == str {
return i
}
}
return -1
}
// StringSliceContains returns true if the slice has the string.
func StringSliceContains(slice []string, str string) bool {
for _, s := range slice {
if s == str {
return true
}
}
return false
}
// SameEndingSubSlice returns true if the slices end the same way, e.g.
// {"a", "b", "c"}, {"b", "c"} => true
// {"a", "b", "c"}, {"a", "b"} => false
// If one slice is empty and the other is not, return false.
func SameEndingSubSlice(shortest, longest []string) bool {
if len(shortest) > len(longest) {
longest, shortest = shortest, longest
}
diff := len(longest) - len(shortest)
if len(shortest) == 0 {
return diff == 0
}
for i := len(shortest) - 1; i >= 0; i-- {
if longest[i+diff] != shortest[i] {
return false
}
}
return true
}

View File

@@ -1,37 +0,0 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package utils_test
import (
"testing"
"github.com/stretchr/testify/assert"
. "sigs.k8s.io/kustomize/api/internal/utils"
)
func TestStringSliceIndex(t *testing.T) {
assert.Equal(t, 0, StringSliceIndex([]string{"a", "b"}, "a"))
assert.Equal(t, 1, StringSliceIndex([]string{"a", "b"}, "b"))
assert.Equal(t, -1, StringSliceIndex([]string{"a", "b"}, "c"))
assert.Equal(t, -1, StringSliceIndex([]string{}, "c"))
}
func TestStringSliceContains(t *testing.T) {
assert.True(t, StringSliceContains([]string{"a", "b"}, "a"))
assert.True(t, StringSliceContains([]string{"a", "b"}, "b"))
assert.False(t, StringSliceContains([]string{"a", "b"}, "c"))
assert.False(t, StringSliceContains([]string{}, "c"))
}
func TestSameEndingSubarray(t *testing.T) {
assert.True(t, SameEndingSubSlice([]string{"", "a", "b"}, []string{"a", "b"}))
assert.True(t, SameEndingSubSlice([]string{"a", "b", ""}, []string{"b", ""}))
assert.True(t, SameEndingSubSlice([]string{"a", "b"}, []string{"a", "b"}))
assert.True(t, SameEndingSubSlice([]string{"a", "b"}, []string{"b"}))
assert.True(t, SameEndingSubSlice([]string{"b"}, []string{"a", "b"}))
assert.True(t, SameEndingSubSlice([]string{}, []string{}))
assert.False(t, SameEndingSubSlice([]string{"a", "b"}, []string{"b", "a"}))
assert.False(t, SameEndingSubSlice([]string{"a", "b"}, []string{}))
assert.False(t, SameEndingSubSlice([]string{"a", "b"}, []string{""}))
}

View File

@@ -31,12 +31,11 @@ const (
// A program name, for use in help, finding the XDG_CONFIG_DIR, etc.
ProgramName = "kustomize"
// ConfigAnnoDomain is internal configuration-related annotation namespace.
// See https://github.com/kubernetes-sigs/kustomize/blob/master/cmd/config/docs/api-conventions/functions-spec.md.
ConfigAnnoDomain = "internal.config.kubernetes.io"
// ConfigAnnoDomain is configuration-related annotation namespace.
ConfigAnnoDomain = "config.kubernetes.io"
// If a resource has this annotation, kustomize will drop it.
IgnoredByKustomizeAnnotation = "config.kubernetes.io/local-config"
IgnoredByKustomizeAnnotation = ConfigAnnoDomain + "/local-config"
// Label key that indicates the resources are built from Kustomize
ManagedbyLabelKey = "app.kubernetes.io/managed-by"

View File

@@ -8,8 +8,8 @@ import (
"path/filepath"
"runtime"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
const (

View File

@@ -10,8 +10,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func TestDefaultAbsPluginHome_NoKustomizePluginHomeEnv(t *testing.T) {

View File

@@ -1,265 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package krusty_test
import (
"testing"
_ "sigs.k8s.io/kustomize/api/krusty"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func TestAnnoOriginLocalFiles(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("service.yaml", `
apiVersion: v1
kind: Service
metadata:
name: myService
spec:
ports:
- port: 7002
`)
th.WriteK(".", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- service.yaml
buildMetadata: [originAnnotations]
`)
options := th.MakeDefaultOptions()
m := th.Run(".", options)
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Service
metadata:
annotations:
config.kubernetes.io/origin: |
path: service.yaml
name: myService
spec:
ports:
- port: 7002
`)
}
func TestAnnoOriginLocalFilesWithOverlay(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
namePrefix: b-
resources:
- namespace.yaml
- role.yaml
- service.yaml
- deployment.yaml
`)
th.WriteF("base/service.yaml", `
apiVersion: v1
kind: Service
metadata:
name: myService
`)
th.WriteF("base/namespace.yaml", `
apiVersion: v1
kind: Namespace
metadata:
name: myNs
`)
th.WriteF("base/role.yaml", `
apiVersion: v1
kind: Role
metadata:
name: myRole
`)
th.WriteF("base/deployment.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: myDep
`)
th.WriteK("prod", `
namePrefix: p-
resources:
- ../base
- service.yaml
- namespace.yaml
buildMetadata: [originAnnotations]
`)
th.WriteF("prod/service.yaml", `
apiVersion: v1
kind: Service
metadata:
name: myService2
`)
th.WriteF("prod/namespace.yaml", `
apiVersion: v1
kind: Namespace
metadata:
name: myNs2
`)
m := th.Run("prod", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Namespace
metadata:
annotations:
config.kubernetes.io/origin: |
path: ../base/namespace.yaml
name: myNs
---
apiVersion: v1
kind: Role
metadata:
annotations:
config.kubernetes.io/origin: |
path: ../base/role.yaml
name: p-b-myRole
---
apiVersion: v1
kind: Service
metadata:
annotations:
config.kubernetes.io/origin: |
path: ../base/service.yaml
name: p-b-myService
---
apiVersion: v1
kind: Deployment
metadata:
annotations:
config.kubernetes.io/origin: |
path: ../base/deployment.yaml
name: p-b-myDep
---
apiVersion: v1
kind: Service
metadata:
annotations:
config.kubernetes.io/origin: |
path: service.yaml
name: p-myService2
---
apiVersion: v1
kind: Namespace
metadata:
annotations:
config.kubernetes.io/origin: |
path: namespace.yaml
name: myNs2
`)
}
// This is a copy of TestGeneratorBasics in configmaps_test.go,
// except that we've enabled the addAnnoOrigin option
// (which doesn't do anything yet).
// TODO: Generated resources should receive the annotation
// config.kubernetes.io/origin: |
// generated-by: path/to/kustomization.yaml
func TestGeneratorWithAnnoOrigin(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK(".", `
namePrefix: blah-
configMapGenerator:
- name: bob
literals:
- fruit=apple
- vegetable=broccoli
envs:
- foo.env
env: bar.env
files:
- passphrase=phrase.dat
- forces.txt
- name: json
literals:
- 'v2=[{"path": "var/druid/segment-cache"}]'
- >-
druid_segmentCache_locations=[{"path":
"var/druid/segment-cache",
"maxSize": 32000000000,
"freeSpacePercent": 1.0}]
secretGenerator:
- name: bob
literals:
- fruit=apple
- vegetable=broccoli
envs:
- foo.env
files:
- passphrase=phrase.dat
- forces.txt
env: bar.env
`)
th.WriteF("foo.env", `
MOUNTAIN=everest
OCEAN=pacific
`)
th.WriteF("bar.env", `
BIRD=falcon
`)
th.WriteF("phrase.dat", `
Life is short.
But the years are long.
Not while the evil days come not.
`)
th.WriteF("forces.txt", `
gravitational
electromagnetic
strong nuclear
weak nuclear
`)
opts := th.MakeDefaultOptions()
m := th.Run(".", opts)
th.AssertActualEqualsExpected(
m, `
apiVersion: v1
data:
BIRD: falcon
MOUNTAIN: everest
OCEAN: pacific
forces.txt: |2
gravitational
electromagnetic
strong nuclear
weak nuclear
fruit: apple
passphrase: |2
Life is short.
But the years are long.
Not while the evil days come not.
vegetable: broccoli
kind: ConfigMap
metadata:
name: blah-bob-g9df72cd5b
---
apiVersion: v1
data:
druid_segmentCache_locations: '[{"path": "var/druid/segment-cache", "maxSize":
32000000000, "freeSpacePercent": 1.0}]'
v2: '[{"path": "var/druid/segment-cache"}]'
kind: ConfigMap
metadata:
name: blah-json-5298bc8g99
---
apiVersion: v1
data:
BIRD: ZmFsY29u
MOUNTAIN: ZXZlcmVzdA==
OCEAN: cGFjaWZpYw==
forces.txt: |
CmdyYXZpdGF0aW9uYWwKZWxlY3Ryb21hZ25ldGljCnN0cm9uZyBudWNsZWFyCndlYWsgbn
VjbGVhcgo=
fruit: YXBwbGU=
passphrase: |
CkxpZmUgaXMgc2hvcnQuCkJ1dCB0aGUgeWVhcnMgYXJlIGxvbmcuCk5vdCB3aGlsZSB0aG
UgZXZpbCBkYXlzIGNvbWUgbm90Lgo=
vegetable: YnJvY2NvbGk=
kind: Secret
metadata:
name: blah-bob-58g62h555c
type: Opaque
`)
}

View File

@@ -1,52 +1,17 @@
package krusty_test
import (
"os"
"os/exec"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
const generateDeploymentDotSh = `#!/bin/sh
cat <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
annotations:
tshirt-size: small # this injects the resource reservations
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
EOF
`
func TestFnExecGenerator(t *testing.T) {
fSys := filesys.MakeFsOnDisk()
// Function plugins should not need the env setup done by MakeEnhancedHarness
th := kusttest_test.MakeHarness(t)
th := kusttest_test.MakeHarnessWithFs(t, fSys)
o := th.MakeOptionsPluginsEnabled()
o.PluginConfig.FnpLoadingOptions.EnableExec = true
tmpDir, err := filesys.NewTmpConfirmedDir()
assert.NoError(t, err)
th.WriteK(tmpDir.String(), `
th.WriteK(".", `
resources:
- short_secret.yaml
generators:
@@ -54,8 +19,7 @@ generators:
`)
// Create some additional resource just to make sure everything is added
th.WriteF(filepath.Join(tmpDir.String(), "short_secret.yaml"),
`
th.WriteF("short_secret.yaml", `
apiVersion: v1
kind: Secret
metadata:
@@ -68,117 +32,23 @@ stringData:
bootcmd:
- mkdir /mnt/vda
`)
th.WriteF(filepath.Join(tmpDir.String(), "generateDeployment.sh"), generateDeploymentDotSh)
assert.NoError(t, os.Chmod(filepath.Join(tmpDir.String(), "generateDeployment.sh"), 0777))
th.WriteF(filepath.Join(tmpDir.String(), "gener.yaml"), `
th.WriteF("gener.yaml", `
kind: executable
metadata:
name: demo
annotations:
config.kubernetes.io/function: |
exec:
path: ./generateDeployment.sh
path: ./fnplugin_test/fnexectest.sh
spec:
`)
m := th.Run(tmpDir.String(), o)
assert.NoError(t, err)
yml, err := m.AsYaml()
assert.NoError(t, err)
assert.Equal(t, `apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-user-data: "true"
name: node1-bmc-secret
stringData:
userData: |
bootcmd:
- mkdir /mnt/vda
type: Opaque
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
tshirt-size: small
labels:
app: nginx
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
`, string(yml))
assert.NoError(t, fSys.RemoveAll(tmpDir.String()))
}
func TestFnExecGeneratorWithOverlay(t *testing.T) {
fSys := filesys.MakeFsOnDisk()
th := kusttest_test.MakeHarnessWithFs(t, fSys)
o := th.MakeOptionsPluginsEnabled()
o.PluginConfig.FnpLoadingOptions.EnableExec = true
tmpDir, err := filesys.NewTmpConfirmedDir()
assert.NoError(t, err)
base := filepath.Join(tmpDir.String(), "base")
prod := filepath.Join(tmpDir.String(), "prod")
assert.NoError(t, fSys.Mkdir(base))
assert.NoError(t, fSys.Mkdir(prod))
th.WriteK(base, `
resources:
- short_secret.yaml
generators:
- gener.yaml
`)
th.WriteK(prod, `
resources:
- ../base
`)
th.WriteF(filepath.Join(base, "short_secret.yaml"),
`
m := th.Run(".", o)
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-user-data: "true"
name: node1-bmc-secret
type: Opaque
stringData:
userData: |
bootcmd:
- mkdir /mnt/vda
`)
th.WriteF(filepath.Join(base, "generateDeployment.sh"), generateDeploymentDotSh)
assert.NoError(t, os.Chmod(filepath.Join(base, "generateDeployment.sh"), 0777))
th.WriteF(filepath.Join(base, "gener.yaml"), `
kind: executable
metadata:
name: demo
annotations:
config.kubernetes.io/function: |
exec:
path: ./generateDeployment.sh
spec:
`)
m := th.Run(prod, o)
assert.NoError(t, err)
yml, err := m.AsYaml()
assert.NoError(t, err)
assert.Equal(t, `apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-user-data: "true"
@@ -193,6 +63,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
config.kubernetes.io/path: deployment_nginx.yaml
tshirt-size: small
labels:
app: nginx
@@ -209,8 +80,7 @@ spec:
containers:
- image: nginx
name: nginx
`, string(yml))
assert.NoError(t, fSys.RemoveAll(tmpDir.String()))
`)
}
func skipIfNoDocker(t *testing.T) {
@@ -276,6 +146,8 @@ type: Opaque
apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
annotations:
config.kubernetes.io/path: config/demo-budget_poddisruptionbudget.yaml
labels:
app: cockroachdb
name: demo
@@ -290,6 +162,8 @@ spec:
apiVersion: v1
kind: Service
metadata:
annotations:
config.kubernetes.io/path: config/demo-public_service.yaml
labels:
app: cockroachdb
name: demo
@@ -310,6 +184,7 @@ apiVersion: v1
kind: Service
metadata:
annotations:
config.kubernetes.io/path: config/demo_service.yaml
prometheus.io/path: _status/vars
prometheus.io/port: "8080"
prometheus.io/scrape: "true"
@@ -334,6 +209,8 @@ spec:
apiVersion: apps/v1
kind: StatefulSet
metadata:
annotations:
config.kubernetes.io/path: config/demo_statefulset.yaml
labels:
app: cockroachdb
name: demo
@@ -506,6 +383,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
config.kubernetes.io/path: deployment_nginx.yaml
tshirt-size: small
labels:
app: nginx
@@ -572,6 +450,8 @@ data:
apiVersion: v1
kind: Namespace
metadata:
annotations:
config.kubernetes.io/path: namespace_my-namespace.yaml
labels:
my-ns-name: function-test
name: my-namespace
@@ -579,6 +459,8 @@ metadata:
apiVersion: v1
kind: Namespace
metadata:
annotations:
config.kubernetes.io/path: namespace_another-namespace.yaml
labels:
my-ns-name: function-test
name: another-namespace
@@ -626,6 +508,8 @@ data:
value: value
kind: ConfigMap
metadata:
annotations:
config.kubernetes.io/path: configmap_env.yaml
name: env
`)
}

View File

@@ -0,0 +1,24 @@
#!/bin/sh
cat <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
app: nginx
annotations:
tshirt-size: small # this injects the resource reservations
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
EOF

View File

@@ -685,167 +685,3 @@ spec:
name: new-name
`)
}
func TestNameReferenceAfterJsonPatch(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("resources.yaml", `
apiVersion: v1
data:
bar: bar
kind: ConfigMap
metadata:
name: cm
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: foo
spec:
selector:
matchLabels:
foo: foo
template:
metadata:
labels:
foo: foo
spec:
containers:
- name: foo
image: example
volumeMounts:
- mountPath: /path
name: myvol
volumes:
- configMap:
name: cm
name: myvol
`)
th.WriteK(".", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namePrefix: foo-
resources:
- resources.yaml
patches:
- target:
group: apps
version: v1
name: foo
patch: |
- op: replace
path: /kind
value: Deployment
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `apiVersion: v1
data:
bar: bar
kind: ConfigMap
metadata:
name: foo-cm
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: foo-foo
spec:
selector:
matchLabels:
foo: foo
template:
metadata:
labels:
foo: foo
spec:
containers:
- image: example
name: foo
volumeMounts:
- mountPath: /path
name: myvol
volumes:
- configMap:
name: foo-cm
name: myvol
`)
}
func TestNameReferenceAfterJsonPatchConfigMapGenerator(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("statefulset.yaml", `
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: foo
spec:
selector:
matchLabels:
foo: foo
template:
metadata:
labels:
foo: foo
spec:
containers:
- name: foo
image: example
volumeMounts:
- mountPath: /path
name: myvol
volumes:
- configMap:
name: cm
name: myvol
`)
th.WriteK(".", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- statefulset.yaml
patches:
- target:
group: apps
version: v1
name: foo
patch: |
- op: replace
path: /kind
value: Deployment
configMapGenerator:
- name: cm
literals:
- bar=bar
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `apiVersion: apps/v1
kind: Deployment
metadata:
name: foo
spec:
selector:
matchLabels:
foo: foo
template:
metadata:
labels:
foo: foo
spec:
containers:
- image: example
name: foo
volumeMounts:
- mountPath: /path
name: myvol
volumes:
- configMap:
name: cm-8hm8224gfd
name: myvol
---
apiVersion: v1
data:
bar: bar
kind: ConfigMap
metadata:
name: cm-8hm8224gfd
`)
}

View File

@@ -230,92 +230,3 @@ spec:
name: configmap-in-base
`)
}
func TestPathWithCronJobV1(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK(".", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- resources.yaml
patches:
- patch: |
apiVersion: batch/v1
kind: CronJob
metadata:
name: test
spec:
jobTemplate:
spec:
template:
spec:
containers:
- name: test
env:
- name: ENV_NEW
value: val_new
target:
kind: CronJob
name: test
`)
th.WriteF("resources.yaml", `
apiVersion: batch/v1
kind: CronJob
metadata:
name: test
spec:
schedule: "5 10 * * 1"
concurrencyPolicy: Forbid
jobTemplate:
spec:
backoffLimit: 3
template:
spec:
restartPolicy: Never
containers:
- name: test
image: bash
command:
- /bin/sh
- -c
- echo "test"
env:
- name: ENV1
value: val1
- name: ENV2
value: val2
- name: ENV3
value: val3`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: batch/v1
kind: CronJob
metadata:
name: test
spec:
concurrencyPolicy: Forbid
jobTemplate:
spec:
backoffLimit: 3
template:
spec:
containers:
- command:
- /bin/sh
- -c
- echo "test"
env:
- name: ENV_NEW
value: val_new
- name: ENV1
value: val1
- name: ENV2
value: val2
- name: ENV3
value: val3
image: bash
name: test
restartPolicy: Never
schedule: 5 10 * * 1
`)
}

View File

@@ -8,6 +8,7 @@ import (
"path/filepath"
"sigs.k8s.io/kustomize/api/builtins"
"sigs.k8s.io/kustomize/api/filesys"
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/internal/target"
"sigs.k8s.io/kustomize/api/konfig"
@@ -16,7 +17,6 @@ import (
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/openapi"
)
@@ -26,7 +26,7 @@ import (
// used instead of performing an exec to a kustomize CLI subprocess.
// To use, load a filesystem with kustomization files (any
// number of overlays and bases), then make a Kustomizer
// injected with the given filesystem, then call Run.
// injected with the given fileystem, then call Run.
type Kustomizer struct {
options *Options
depProvider *provider.DepProvider

View File

@@ -7,8 +7,8 @@ import (
"strings"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/krusty"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// A simple usage example to shows what happens when

View File

@@ -1,70 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package krusty_test
import (
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
// This test checks that if a resource is annotated as "local-config", this resource won't be ignored until
// all transformations have completed. This makes sure the local resource can be used as a transformation input.
// See https://github.com/kubernetes-sigs/kustomize/issues/4124 for details.
func TestSKipLocalConfigAfterTransform(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK(".", `apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- pod.yaml
- deployment.yaml
transformers:
- replacement.yaml
`)
th.WriteF("pod.yaml", `apiVersion: v1
kind: Pod
metadata:
name: buildup
annotations:
config.kubernetes.io/local-config: "true"
spec:
containers:
- name: app
image: nginx
`)
th.WriteF("deployment.yaml", `apiVersion: apps/v1
kind: Deployment
metadata:
name: buildup
`)
th.WriteF("replacement.yaml", `
apiVersion: builtin
kind: ReplacementTransformer
metadata:
name: buildup
replacements:
- source:
kind: Pod
fieldPath: spec
targets:
- select:
kind: Deployment
fieldPaths:
- spec.template.spec
options:
create: true
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `apiVersion: apps/v1
kind: Deployment
metadata:
name: buildup
spec:
template:
spec:
containers:
- image: nginx
name: app
`)
}

View File

@@ -17,11 +17,6 @@ func writeTestSchema(th kusttest_test.Harness, filepath string) {
th.WriteF(filepath+"mycrd_schema.json", string(bytes))
}
func writeTestSchemaYaml(th kusttest_test.Harness, filepath string) {
bytes, _ := ioutil.ReadFile("testdata/customschema.yaml")
th.WriteF(filepath+"mycrd_schema.yaml", string(bytes))
}
func writeCustomResource(th kusttest_test.Harness, filepath string) {
th.WriteF(filepath, `
apiVersion: example.com/v1alpha1
@@ -42,26 +37,6 @@ spec:
`)
}
func writeOtherCustomResource(th kusttest_test.Harness, filepath string) {
th.WriteF(filepath, `
apiVersion: v1alpha1
kind: MyCRD
metadata:
name: service
spec:
template:
spec:
containers:
- name: server
image: server
command: example
ports:
- name: grpc
protocol: TCP
containerPort: 8080
`)
}
func writeTestComponentWithCustomSchema(th kusttest_test.Harness) {
writeTestSchema(th, "comp/")
openapi.ResetOpenAPI()
@@ -94,32 +69,6 @@ patchesStrategicMerge:
image: nginx
`
const customSchemaPatchMultipleGvks = `
patchesStrategicMerge:
- |-
apiVersion: example.com/v1alpha1
kind: MyCRD
metadata:
name: service
spec:
template:
spec:
containers:
- name: server
image: nginx
- |-
apiVersion: v1alpha1
kind: MyCRD
metadata:
name: service
spec:
template:
spec:
containers:
- name: server
image: nginx
`
const patchedCustomResource = `
apiVersion: example.com/v1alpha1
kind: MyCRD
@@ -154,69 +103,6 @@ openapi:
th.AssertActualEqualsExpected(m, patchedCustomResource)
}
func TestCustomOpenApiFieldWithTwoGvks(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK(".", `
resources:
- mycrd.yaml
- myothercrd.yaml
openapi:
path: mycrd_schema.json
`+customSchemaPatchMultipleGvks)
writeCustomResource(th, "mycrd.yaml")
writeOtherCustomResource(th, "myothercrd.yaml")
writeTestSchema(th, "./")
openapi.ResetOpenAPI()
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `apiVersion: example.com/v1alpha1
kind: MyCRD
metadata:
name: service
spec:
template:
spec:
containers:
- command: example
image: nginx
name: server
ports:
- containerPort: 8080
name: grpc
protocol: TCP
---
apiVersion: v1alpha1
kind: MyCRD
metadata:
name: service
spec:
template:
spec:
containers:
- command: example
image: nginx
name: server
ports:
- containerPort: 8080
name: grpc
protocol: TCP
`)
}
func TestCustomOpenApiFieldYaml(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK(".", `
resources:
- mycrd.yaml
openapi:
path: mycrd_schema.yaml
`+customSchemaPatch)
writeCustomResource(th, "mycrd.yaml")
writeTestSchemaYaml(th, "./")
openapi.ResetOpenAPI()
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, patchedCustomResource)
}
// Error if user tries to specify both builtin version
// and custom schema
func TestCustomOpenApiFieldBothPathAndVersion(t *testing.T) {
@@ -225,7 +111,7 @@ func TestCustomOpenApiFieldBothPathAndVersion(t *testing.T) {
resources:
- mycrd.yaml
openapi:
version: v1.21.2
version: v1.20.4
path: mycrd_schema.json
`+customSchemaPatch)
writeCustomResource(th, "mycrd.yaml")
@@ -311,7 +197,7 @@ openapi:
resources:
- ../base
openapi:
version: v1.21.2
version: v1.20.4
`+customSchemaPatch)
writeCustomResource(th, "base/mycrd.yaml")
writeTestSchema(th, "base/")
@@ -329,7 +215,7 @@ spec:
- image: nginx
name: server
`)
assert.Equal(t, "v1212", openapi.GetSchemaVersion())
assert.Equal(t, "v1204", openapi.GetSchemaVersion())
}
func TestCustomOpenAPIFieldFromComponent(t *testing.T) {

View File

@@ -16,7 +16,7 @@ func TestOpenApiFieldBasicUsage(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK(".", `
openapi:
version: v1.21.2
version: v1.20.4
resources:
- deployment.yaml
`)
@@ -44,8 +44,7 @@ spec:
containers:
- image: whatever
`)
assert.Equal(t, "v1212", openapi.GetSchemaVersion())
openapi.ResetOpenAPI()
assert.Equal(t, "v1204", openapi.GetSchemaVersion())
}
func TestOpenApiFieldNotBuiltin(t *testing.T) {
@@ -72,7 +71,6 @@ spec:
if err == nil {
t.Fatalf("expected an error")
}
openapi.ResetOpenAPI()
}
func TestOpenApiFieldDefaultVersion(t *testing.T) {
@@ -106,5 +104,4 @@ spec:
- image: whatever
`)
assert.Equal(t, kubernetesapi.DefaultOpenAPI, openapi.GetSchemaVersion())
openapi.ResetOpenAPI()
}

View File

@@ -9,9 +9,9 @@ import (
"path/filepath"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/konfig"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// The PrintPluginEnv plugin is a toy plugin that emits

View File

@@ -4,13 +4,12 @@
package krusty_test
import (
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/krusty"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func TestRemoteLoad(t *testing.T) {
@@ -40,124 +39,3 @@ spec:
name: nginx
`, string(yml))
}
func TestRemoteResource(t *testing.T) {
fSys := filesys.MakeFsOnDisk()
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
tmpDir, err := filesys.NewTmpConfirmedDir()
assert.NoError(t, err)
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(`
resources:
- github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6
`)))
m, err := b.Run(
fSys,
tmpDir.String())
if utils.IsErrTimeout(err) {
// Don't fail on timeouts.
t.SkipNow()
}
assert.NoError(t, err)
yml, err := m.AsYaml()
assert.NoError(t, err)
assert.Equal(t, `apiVersion: v1
kind: Pod
metadata:
labels:
app: myapp
name: dev-myapp-pod
spec:
containers:
- image: nginx:1.7.9
name: nginx
`, string(yml))
assert.NoError(t, fSys.RemoveAll(tmpDir.String()))
}
func TestRemoteResourceAnnoOrigin(t *testing.T) {
fSys := filesys.MakeFsOnDisk()
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
tmpDir, err := filesys.NewTmpConfirmedDir()
assert.NoError(t, err)
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(`
resources:
- github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6
buildMetadata: [originAnnotations]
`)))
m, err := b.Run(
fSys,
tmpDir.String())
if utils.IsErrTimeout(err) {
// Don't fail on timeouts.
t.SkipNow()
}
assert.NoError(t, err)
yml, err := m.AsYaml()
assert.NoError(t, err)
assert.Equal(t, `apiVersion: v1
kind: Pod
metadata:
annotations:
config.kubernetes.io/origin: |
path: examples/multibases/base/pod.yaml
repo: https://github.com/kubernetes-sigs/kustomize
ref: v1.0.6
labels:
app: myapp
name: dev-myapp-pod
spec:
containers:
- image: nginx:1.7.9
name: nginx
`, string(yml))
assert.NoError(t, fSys.RemoveAll(tmpDir.String()))
}
func TestRemoteResourceAsBaseWithAnnoOrigin(t *testing.T) {
fSys := filesys.MakeFsOnDisk()
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
tmpDir, err := filesys.NewTmpConfirmedDir()
assert.NoError(t, err)
base := filepath.Join(tmpDir.String(), "base")
prod := filepath.Join(tmpDir.String(), "prod")
assert.NoError(t, fSys.Mkdir(base))
assert.NoError(t, fSys.Mkdir(prod))
assert.NoError(t, fSys.WriteFile(filepath.Join(base, "kustomization.yaml"), []byte(`
resources:
- github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6
`)))
assert.NoError(t, fSys.WriteFile(filepath.Join(prod, "kustomization.yaml"), []byte(`
resources:
- ../base
namePrefix: prefix-
buildMetadata: [originAnnotations]
`)))
m, err := b.Run(
fSys,
prod)
if utils.IsErrTimeout(err) {
// Don't fail on timeouts.
t.SkipNow()
}
assert.NoError(t, err)
yml, err := m.AsYaml()
assert.NoError(t, err)
assert.Equal(t, `apiVersion: v1
kind: Pod
metadata:
annotations:
config.kubernetes.io/origin: |
path: examples/multibases/base/pod.yaml
repo: https://github.com/kubernetes-sigs/kustomize
ref: v1.0.6
labels:
app: myapp
name: prefix-dev-myapp-pod
spec:
containers:
- image: nginx:1.7.9
name: nginx
`, string(yml))
assert.NoError(t, fSys.RemoveAll(tmpDir.String()))
}

View File

@@ -261,224 +261,3 @@ spec:
name: nginx
`)
}
func TestReplacementTransformerWithOriginalName(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteF("base/deployments.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: target
spec:
template:
spec:
containers:
- image: nginx:oldtag
name: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: source
spec:
template:
spec:
containers:
- image: nginx:newtag
name: nginx
`)
th.WriteK("base", `
resources:
- deployments.yaml
`)
th.WriteK("overlay", `
namePrefix: prefix1-
resources:
- ../base
`)
th.WriteK(".", `
namePrefix: prefix2-
resources:
- overlay
replacements:
- path: replacement.yaml
`)
th.WriteF("replacement.yaml", `
source:
name: source
fieldPath: spec.template.spec.containers.0.image
targets:
- select:
name: prefix1-target
fieldPaths:
- spec.template.spec.containers.[name=nginx].image
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: prefix2-prefix1-target
spec:
template:
spec:
containers:
- image: nginx:newtag
name: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: prefix2-prefix1-source
spec:
template:
spec:
containers:
- image: nginx:newtag
name: nginx
`)
}
// TODO: Address namePrefix in overlay not applying to replacement targets
// The property `data.blue-name` should end up being `overlay-blue` instead of `blue`
// https://github.com/kubernetes-sigs/kustomize/issues/4034
func TestReplacementTransformerWithNamePrefixOverlay(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("base", `
generatorOptions:
disableNameSuffixHash: true
configMapGenerator:
- name: blue
- name: red
replacements:
- source:
kind: ConfigMap
name: blue
fieldPath: metadata.name
targets:
- select:
name: red
fieldPaths:
- data.blue-name
options:
create: true
`)
th.WriteK(".", `
namePrefix: overlay-
resources:
- base
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: ConfigMap
metadata:
name: overlay-blue
---
apiVersion: v1
data:
blue-name: blue
kind: ConfigMap
metadata:
name: overlay-red
`)
}
// TODO: Address namespace in overlay not applying to replacement targets
// The property `data.blue-namespace` should end up being `overlay-namespace` instead of `base-namespace`
// https://github.com/kubernetes-sigs/kustomize/issues/4034
func TestReplacementTransformerWithNamespaceOverlay(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("base", `
namespace: base-namespace
generatorOptions:
disableNameSuffixHash: true
configMapGenerator:
- name: blue
- name: red
replacements:
- source:
kind: ConfigMap
name: blue
fieldPath: metadata.namespace
targets:
- select:
name: red
fieldPaths:
- data.blue-namespace
options:
create: true
`)
th.WriteK(".", `
namespace: overlay-namespace
resources:
- base
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: ConfigMap
metadata:
name: blue
namespace: overlay-namespace
---
apiVersion: v1
data:
blue-namespace: base-namespace
kind: ConfigMap
metadata:
name: red
namespace: overlay-namespace
`)
}
// TODO: Address configMapGenerator suffix not applying to replacement targets
// The property `data.blue-name` should end up being `blue-6ct58987ht` instead of `blue`
// https://github.com/kubernetes-sigs/kustomize/issues/4034
func TestReplacementTransformerWithConfigMapGenerator(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK(".", `
configMapGenerator:
- name: blue
- name: red
replacements:
- source:
kind: ConfigMap
name: blue
fieldPath: metadata.name
targets:
- select:
name: red
fieldPaths:
- data.blue-name
options:
create: true
`)
m := th.Run(".", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: ConfigMap
metadata:
name: blue-6ct58987ht
---
apiVersion: v1
data:
blue-name: blue
kind: ConfigMap
metadata:
name: red-dc6gc5btkc
`)
}

View File

@@ -34,11 +34,6 @@
"group": "example.com",
"kind": "MyCRD",
"version": "v1alpha1"
},
{
"group": "",
"kind": "MyCRD",
"version": "v1alpha1"
}
]
},

View File

@@ -1,78 +0,0 @@
definitions:
v1alpha1.MyCRD:
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
spec:
properties:
template:
"$ref": "#/definitions/io.k8s.api.core.v1.PodTemplateSpec"
type: object
status:
properties:
success:
type: boolean
type: object
type: object
x-kubernetes-group-version-kind:
- group: example.com
kind: MyCRD
version: v1alpha1
- group: ""
kind: MyCRD
version: v1alpha1
io.k8s.api.core.v1.PodTemplateSpec:
properties:
metadata:
"$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta"
spec:
"$ref": "#/definitions/io.k8s.api.core.v1.PodSpec"
type: object
io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta:
properties:
name:
type: string
type: object
io.k8s.api.core.v1.PodSpec:
properties:
containers:
items:
"$ref": "#/definitions/io.k8s.api.core.v1.Container"
type: array
x-kubernetes-patch-merge-key: name
x-kubernetes-patch-strategy: merge
type: object
io.k8s.api.core.v1.Container:
properties:
command:
items:
type: string
type: array
image:
type: string
name:
type: string
ports:
items:
"$ref": "#/definitions/io.k8s.api.core.v1.ContainerPort"
type: array
x-kubernetes-list-map-keys:
- containerPort
- protocol
x-kubernetes-list-type: map
x-kubernetes-patch-merge-key: containerPort
x-kubernetes-patch-strategy: merge
type: object
io.k8s.api.core.v1.ContainerPort:
properties:
containerPort:
type: integer
name:
type: string
protocol:
type: string
type: object

View File

@@ -8,10 +8,10 @@ import (
"testing"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/filesys"
ldr "sigs.k8s.io/kustomize/api/loader"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func makeKvLoader(fSys filesys.FileSystem) *loader {

View File

@@ -12,9 +12,9 @@ import (
"path/filepath"
"strings"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/git"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// fileLoader is a kustomization's interface to files.

View File

@@ -14,10 +14,10 @@ import (
"strings"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/git"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
type testData struct {

View File

@@ -5,9 +5,9 @@
package loader
import (
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/git"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// NewLoader returns a Loader pointed at the given target.

View File

@@ -6,7 +6,7 @@ package loader
import (
"fmt"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/api/filesys"
)
type LoadRestrictorFunc func(

View File

@@ -8,7 +8,7 @@ import (
"strings"
"testing"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/api/filesys"
)
func TestRestrictionNone(t *testing.T) {

View File

@@ -8,6 +8,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/kv"
"sigs.k8s.io/kustomize/api/loader"
@@ -15,7 +16,6 @@ import (
resmaptest_test "sigs.k8s.io/kustomize/api/testutils/resmaptest"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
@@ -219,10 +219,8 @@ BAR=baz
}
r, err := rmF.NewResMapFromConfigMapArgs(kvLdr, tc.input)
assert.NoError(t, err, tc.description)
r.RemoveBuildAnnotations()
rYaml, err := r.AsYaml()
assert.NoError(t, err, tc.description)
tc.expected.RemoveBuildAnnotations()
expYaml, err := tc.expected.AsYaml()
assert.NoError(t, err, tc.description)
assert.Equal(t, expYaml, rYaml)
@@ -254,7 +252,6 @@ func TestNewResMapFromSecretArgs(t *testing.T) {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
actual.RemoveBuildAnnotations()
actYaml, err := actual.AsYaml()
assert.NoError(t, err)

View File

@@ -136,10 +136,6 @@ type ResMap interface {
// self, then its behavior _cannot_ be merge or replace.
AbsorbAll(ResMap) error
// AnnotateAll annotates all resources in the ResMap with
// the provided key value pair.
AnnotateAll(key string, value string) error
// AsYaml returns the yaml form of resources.
AsYaml() ([]byte, error)
@@ -214,35 +210,6 @@ type ResMap interface {
// namespaces. Cluster wide objects are never excluded.
SubsetThatCouldBeReferencedByResource(*resource.Resource) ResMap
// DeAnchor replaces YAML aliases with structured data copied from anchors.
// This cannot be undone; if desired, call DeepCopy first.
// Subsequent marshalling to YAML will no longer have anchor
// definitions ('&') or aliases ('*').
//
// Anchors are not expected to work across YAML 'documents'.
// If three resources are loaded from one file containing three YAML docs:
//
// {resourceA}
// ---
// {resourceB}
// ---
// {resourceC}
//
// then anchors defined in A cannot be seen from B and C and vice versa.
// OTOH, cross-resource links (a field in B referencing fields in A) will
// work if the resources are gathered in a ResourceList:
//
// apiVersion: config.kubernetes.io/v1
// kind: ResourceList
// metadata:
// name: someList
// items:
// - {resourceA}
// - {resourceB}
// - {resourceC}
//
DeAnchor() error
// DeepCopy copies the ResMap and underlying resources.
DeepCopy() ResMap

View File

@@ -9,7 +9,6 @@ import (
"reflect"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/filters/annotations"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
@@ -532,19 +531,6 @@ func (m *resWrangler) appendReplaceOrMerge(res *resource.Resource) error {
}
}
// AnnotateAll implements ResMap
func (m *resWrangler) AnnotateAll(key string, value string) error {
return m.ApplyFilter(annotations.Filter{
Annotations: map[string]string{
key: value,
},
FsSlice: []types.FieldSpec{{
Path: "metadata/annotations",
CreateIfNotPresent: true,
}},
})
}
// Select returns a list of resources that
// are selected by a Selector
func (m *resWrangler) Select(s types.Selector) ([]*resource.Resource, error) {
@@ -607,16 +593,6 @@ func (m *resWrangler) ToRNodeSlice() []*kyaml.RNode {
return result
}
// DeAnchor implements ResMap.
func (m *resWrangler) DeAnchor() (err error) {
for i := range m.rList {
if err = m.rList[i].DeAnchor(); err != nil {
return err
}
}
return nil
}
// ApplySmPatch applies the patch, and errors on Id collisions.
func (m *resWrangler) ApplySmPatch(
selectedSet *resource.IdSet, patch *resource.Resource) error {

View File

@@ -343,9 +343,9 @@ func TestGetMatchingResourcesByAnyId(t *testing.T) {
"metadata": map[string]interface{}{
"name": "new-alice",
"annotations": map[string]interface{}{
"internal.config.kubernetes.io/previousKinds": "ConfigMap",
"internal.config.kubernetes.io/previousNames": "alice",
"internal.config.kubernetes.io/previousNamespaces": "default",
"config.kubernetes.io/previousKinds": "ConfigMap",
"config.kubernetes.io/previousNames": "alice",
"config.kubernetes.io/previousNamespaces": "default",
},
},
})
@@ -356,9 +356,9 @@ func TestGetMatchingResourcesByAnyId(t *testing.T) {
"metadata": map[string]interface{}{
"name": "new-bob",
"annotations": map[string]interface{}{
"internal.config.kubernetes.io/previousKinds": "ConfigMap,ConfigMap",
"internal.config.kubernetes.io/previousNames": "bob,bob2",
"internal.config.kubernetes.io/previousNamespaces": "default,default",
"config.kubernetes.io/previousKinds": "ConfigMap,ConfigMap",
"config.kubernetes.io/previousNames": "bob,bob2",
"config.kubernetes.io/previousNamespaces": "default,default",
},
},
})
@@ -370,9 +370,9 @@ func TestGetMatchingResourcesByAnyId(t *testing.T) {
"name": "new-bob",
"namespace": "new-happy",
"annotations": map[string]interface{}{
"internal.config.kubernetes.io/previousKinds": "ConfigMap",
"internal.config.kubernetes.io/previousNames": "bob",
"internal.config.kubernetes.io/previousNamespaces": "happy",
"config.kubernetes.io/previousKinds": "ConfigMap",
"config.kubernetes.io/previousNames": "bob",
"config.kubernetes.io/previousNamespaces": "happy",
},
},
})
@@ -384,9 +384,9 @@ func TestGetMatchingResourcesByAnyId(t *testing.T) {
"name": "charlie",
"namespace": "happy",
"annotations": map[string]interface{}{
"internal.config.kubernetes.io/previousKinds": "ConfigMap",
"internal.config.kubernetes.io/previousNames": "charlie",
"internal.config.kubernetes.io/previousNamespaces": "default",
"config.kubernetes.io/previousKinds": "ConfigMap",
"config.kubernetes.io/previousNames": "charlie",
"config.kubernetes.io/previousNamespaces": "default",
},
},
})
@@ -845,8 +845,6 @@ func TestAbsorbAll(t *testing.T) {
}))
w := makeMap1()
assert.NoError(t, w.AbsorbAll(makeMap2(types.BehaviorMerge)))
expected.RemoveBuildAnnotations()
w.RemoveBuildAnnotations()
assert.NoError(t, expected.ErrorIfNotEqualLists(w))
w = makeMap1()
assert.NoError(t, w.AbsorbAll(nil))
@@ -855,7 +853,6 @@ func TestAbsorbAll(t *testing.T) {
w = makeMap1()
w2 := makeMap2(types.BehaviorReplace)
assert.NoError(t, w.AbsorbAll(w2))
w2.RemoveBuildAnnotations()
assert.NoError(t, w2.ErrorIfNotEqualLists(w))
w = makeMap1()
w2 = makeMap2(types.BehaviorUnspecified)
@@ -902,100 +899,6 @@ rules:
}
}
func TestDeAnchorSingleDoc(t *testing.T) {
input := `apiVersion: v1
kind: ConfigMap
metadata:
name: wildcard
data:
color: &color-used blue
feeling: *color-used
`
rm, err := rmF.NewResMapFromBytes([]byte(input))
assert.NoError(t, err)
assert.NoError(t, rm.DeAnchor())
yaml, err := rm.AsYaml()
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(`
apiVersion: v1
data:
color: blue
feeling: blue
kind: ConfigMap
metadata:
name: wildcard
`), strings.TrimSpace(string(yaml)))
}
// Anchor references don't cross YAML document boundaries.
func TestDeAnchorMultiDoc(t *testing.T) {
input := `apiVersion: v1
kind: ConfigMap
metadata:
name: betty
data:
color: &color-used blue
feeling: *color-used
---
apiVersion: v1
kind: ConfigMap
metadata:
name: bob
data:
color: red
feeling: *color-used
`
_, err := rmF.NewResMapFromBytes([]byte(input))
assert.Error(t, err)
assert.Contains(t, err.Error(), "unknown anchor 'color-used' referenced")
}
// Anchor references cross list elements in a ResourceList.
func TestDeAnchorResourceList(t *testing.T) {
input := `apiVersion: config.kubernetes.io/v1
kind: ResourceList
metadata:
name: aShortList
items:
- apiVersion: v1
kind: ConfigMap
metadata:
name: betty
data:
color: &color-used blue
feeling: *color-used
- apiVersion: v1
kind: ConfigMap
metadata:
name: bob
data:
color: red
feeling: *color-used
`
rm, err := rmF.NewResMapFromBytes([]byte(input))
assert.NoError(t, err)
assert.NoError(t, rm.DeAnchor())
yaml, err := rm.AsYaml()
assert.NoError(t, err)
assert.Equal(t, strings.TrimSpace(`
apiVersion: v1
data:
color: blue
feeling: blue
kind: ConfigMap
metadata:
name: betty
---
apiVersion: v1
data:
color: red
feeling: blue
kind: ConfigMap
metadata:
name: bob
`), strings.TrimSpace(string(yaml)))
}
func TestApplySmPatch_General(t *testing.T) {
const (
myDeployment = "Deployment"

View File

@@ -64,23 +64,18 @@ func (rf *Factory) FromMapAndOption(
// TODO: return err instead of log.
log.Fatal(err)
}
return rf.makeOne(n, args)
return rf.makeOne(n, types.NewGenArgs(args))
}
// makeOne returns a new instance of Resource.
func (rf *Factory) makeOne(rn *yaml.RNode, o *types.GeneratorArgs) *Resource {
func (rf *Factory) makeOne(rn *yaml.RNode, o *types.GenArgs) *Resource {
if rn == nil {
log.Fatal("RNode must not be null")
}
resource := &Resource{RNode: *rn}
if o != nil {
if o.Options == nil || !o.Options.DisableNameSuffixHash {
resource.EnableHashSuffix()
}
resource.SetBehavior(types.NewGenerationBehavior(o.Behavior))
if o == nil {
o = types.NewGenArgs(nil)
}
return resource
return &Resource{RNode: *rn, options: o}
}
// SliceFromPatches returns a slice of resources given a patch path
@@ -124,34 +119,14 @@ func (rf *Factory) SliceFromBytes(in []byte) ([]*Resource, error) {
return rf.resourcesFromRNodes(nodes), nil
}
// DropLocalNodes removes the local nodes by default. Local nodes are detected via the annotation `config.kubernetes.io/local-config: "true"`
func (rf *Factory) DropLocalNodes(nodes []*yaml.RNode) ([]*Resource, error) {
var result []*yaml.RNode
for _, node := range nodes {
if node.IsNilOrEmpty() {
continue
}
md, err := node.GetValidatedMetadata()
if err != nil {
return nil, err
}
if rf.IncludeLocalConfigs {
result = append(result, node)
continue
}
localConfig, exist := md.ObjectMeta.Annotations[konfig.IgnoredByKustomizeAnnotation]
if !exist || localConfig == "false" {
result = append(result, node)
}
}
return rf.resourcesFromRNodes(result), nil
}
// ResourcesFromRNodes converts RNodes to Resources.
func (rf *Factory) ResourcesFromRNodes(
nodes []*yaml.RNode) (result []*Resource, err error) {
return rf.DropLocalNodes(nodes)
nodes, err = rf.dropBadNodes(nodes)
if err != nil {
return nil, err
}
return rf.resourcesFromRNodes(nodes), nil
}
// resourcesFromRNode assumes all nodes are good.
@@ -163,7 +138,7 @@ func (rf *Factory) resourcesFromRNodes(
return
}
func (rf *Factory) RNodesFromBytes(b []byte) ([]*yaml.RNode, error) {
func (rf *Factory) RNodesFromBytes(b []byte) (result []*yaml.RNode, err error) {
nodes, err := kio.FromBytes(b)
if err != nil {
return nil, err
@@ -172,17 +147,9 @@ func (rf *Factory) RNodesFromBytes(b []byte) ([]*yaml.RNode, error) {
if err != nil {
return nil, err
}
return rf.inlineAnyEmbeddedLists(nodes)
}
// inlineAnyEmbeddedLists scans the RNode slice for nodes named FooList.
// Such nodes are expected to be lists of resources, each of type Foo.
// These lists are replaced in the result by their inlined resources.
func (rf *Factory) inlineAnyEmbeddedLists(
nodes []*yaml.RNode) (result []*yaml.RNode, err error) {
var n0 *yaml.RNode
for len(nodes) > 0 {
n0, nodes = nodes[0], nodes[1:]
n0 := nodes[0]
nodes = nodes[1:]
kind := n0.GetKind()
if !strings.HasSuffix(kind, "List") {
result = append(result, n0)
@@ -192,7 +159,7 @@ func (rf *Factory) inlineAnyEmbeddedLists(
var m map[string]interface{}
m, err = n0.Map()
if err != nil {
return nil, fmt.Errorf("trouble expanding list of %s; %w", kind, err)
return nil, err
}
items, ok := m["items"]
if !ok {
@@ -244,20 +211,38 @@ func (rf *Factory) convertObjectSliceToNodeSlice(
func (rf *Factory) dropBadNodes(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
var result []*yaml.RNode
for _, n := range nodes {
if n.IsNilOrEmpty() {
continue
}
if _, err := n.GetValidatedMetadata(); err != nil {
ignore, err := rf.shouldIgnore(n)
if err != nil {
return nil, err
}
if foundNil, path := n.HasNilEntryInList(); foundNil {
return nil, fmt.Errorf("empty item at %v in object %v", path, n)
if !ignore {
result = append(result, n)
}
result = append(result, n)
}
return result, nil
}
// shouldIgnore returns true if there's some reason to ignore the node.
func (rf *Factory) shouldIgnore(n *yaml.RNode) (bool, error) {
if n.IsNilOrEmpty() {
return true, nil
}
if !rf.IncludeLocalConfigs {
md, err := n.GetValidatedMetadata()
if err != nil {
return true, err
}
_, ignore := md.ObjectMeta.Annotations[konfig.IgnoredByKustomizeAnnotation]
if ignore {
return true, nil
}
}
if foundNil, path := n.HasNilEntryInList(); foundNil {
return true, fmt.Errorf("empty item at %v in object %v", path, n)
}
return false, nil
}
// SliceFromBytesWithNames unmarshals bytes into a Resource slice with specified original
// name.
func (rf *Factory) SliceFromBytesWithNames(names []string, in []byte) ([]*Resource, error) {
@@ -280,7 +265,7 @@ func (rf *Factory) MakeConfigMap(kvLdr ifc.KvLoader, args *types.ConfigMapArgs)
if err != nil {
return nil, err
}
return rf.makeOne(rn, &args.GeneratorArgs), nil
return rf.makeOne(rn, types.NewGenArgs(&args.GeneratorArgs)), nil
}
// MakeSecret makes an instance of Resource for Secret
@@ -289,5 +274,5 @@ func (rf *Factory) MakeSecret(kvLdr ifc.KvLoader, args *types.SecretArgs) (*Reso
if err != nil {
return nil, err
}
return rf.makeOne(rn, &args.GeneratorArgs), nil
return rf.makeOne(rn, types.NewGenArgs(&args.GeneratorArgs)), nil
}

View File

@@ -5,18 +5,17 @@ package resource_test
import (
"fmt"
"strings"
"reflect"
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/loader"
. "sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/kio"
)
func TestRNodesFromBytes(t *testing.T) {
func TestSliceFromBytes(t *testing.T) {
type testCase struct {
input string
expected []string
@@ -400,11 +399,60 @@ binaryData:
}
}
func TestMoreRNodesFromBytes(t *testing.T) {
func TestSliceFromBytesMore(t *testing.T) {
testConfigMap :=
map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "winnie",
},
}
testDeploymentSpec := map[string]interface{}{
"template": map[string]interface{}{
"spec": map[string]interface{}{
"hostAliases": []interface{}{
map[string]interface{}{
"hostnames": []interface{}{
"a.example.com",
},
"ip": "8.8.8.8",
},
},
},
},
}
testDeploymentA := map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deployment-a",
},
"spec": testDeploymentSpec,
}
testDeploymentB := map[string]interface{}{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": map[string]interface{}{
"name": "deployment-b",
},
"spec": testDeploymentSpec,
}
testDeploymentList :=
map[string]interface{}{
"apiVersion": "v1",
"kind": "DeploymentList",
"items": []interface{}{
testDeploymentA,
testDeploymentB,
},
}
type expected struct {
out []string
out []map[string]interface{}
isErr bool
}
testCases := map[string]struct {
input []byte
exp expected
@@ -417,16 +465,16 @@ func TestMoreRNodesFromBytes(t *testing.T) {
},
"noBytes": {
input: []byte{},
exp: expected{},
exp: expected{
out: []map[string]interface{}{},
},
},
"goodJson": {
input: []byte(`
{"apiVersion":"v1","kind":"ConfigMap","metadata":{"name":"winnie"}}
`),
exp: expected{
out: []string{
`{"apiVersion": "v1", "kind": "ConfigMap", "metadata": {"name": "winnie"}}`,
},
out: []map[string]interface{}{testConfigMap},
},
},
"goodYaml1": {
@@ -437,12 +485,7 @@ metadata:
name: winnie
`),
exp: expected{
out: []string{`
apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
`},
out: []map[string]interface{}{testConfigMap},
},
},
"goodYaml2": {
@@ -458,17 +501,26 @@ metadata:
name: winnie
`),
exp: expected{
out: []string{`
out: []map[string]interface{}{testConfigMap, testConfigMap},
},
},
"localConfigYaml": {
input: []byte(`
apiVersion: v1
kind: ConfigMap
metadata:
name: winnie-skip
annotations:
# this annotation causes the Resource to be ignored by kustomize
config.kubernetes.io/local-config: ""
---
apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
`, `
apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
`},
`),
exp: expected{
out: []map[string]interface{}{testConfigMap},
},
},
"garbageInOneOfTwoObjects": {
@@ -493,7 +545,7 @@ WOOOOOOOOOOOOOOOOOOOOOOOOT: woot
`),
exp: expected{
out: []string{},
out: []map[string]interface{}{},
},
},
"Missing .metadata.name in object": {
@@ -539,18 +591,9 @@ items:
name: winnie
`),
exp: expected{
out: []string{`
apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
`, `
apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
`,
},
out: []map[string]interface{}{
testConfigMap,
testConfigMap},
},
},
"ConfigMapList": {
@@ -568,9 +611,9 @@ items:
name: winnie
`),
exp: expected{
out: []string{
`{"apiVersion": "v1", "kind": "ConfigMap", "metadata": {"name": "winnie"}}`,
`{"apiVersion": "v1", "kind": "ConfigMap", "metadata": {"name": "winnie"}}`,
out: []map[string]interface{}{
testConfigMap,
testConfigMap,
},
},
},
@@ -583,7 +626,7 @@ items:
kind: Deployment
metadata:
name: deployment-a
spec: &foo
spec: &hostAliases
template:
spec:
hostAliases:
@@ -595,39 +638,23 @@ items:
metadata:
name: deployment-b
spec:
*foo
<<: *hostAliases
`),
exp: expected{
out: []string{
`{"apiVersion": "apps/v1", "kind": "Deployment", "metadata": {"name": "deployment-a"}, ` +
`"spec": {"template": {"spec": {"hostAliases": [{"hostnames": ["a.example.com"], "ip": "8.8.8.8"}]}}}}`,
`{"apiVersion": "apps/v1", "kind": "Deployment", "metadata": {"name": "deployment-b"}, ` +
`"spec": {"template": {"spec": {"hostAliases": [{"hostnames": ["a.example.com"], "ip": "8.8.8.8"}]}}}}`},
},
},
"simpleAnchor": {
input: []byte(`
apiVersion: v1
kind: ConfigMap
metadata:
name: wildcard
data:
color: &color-used blue
feeling: *color-used
`),
exp: expected{
out: []string{`
apiVersion: v1
kind: ConfigMap
metadata:
name: wildcard
data:
color: blue
feeling: blue
`},
// TODO(3271): This should work.
// https://github.com/kubernetes-sigs/kustomize/issues/3271
// json.Marshal(obj) fails on the 2nd list item.
// The value of the 1st list item's first spec field is
// map[string]interface{}
// The value of the 2nd list item's first spec field is
// map[interface{}]interface{}
// which causes a encoding/json.UnsupportedTypeError.
isErr: true,
out: []map[string]interface{}{testDeploymentList},
},
},
}
for n := range testCases {
tc := testCases[n]
t.Run(n, func(t *testing.T) {
@@ -639,100 +666,15 @@ data:
assert.False(t, tc.exp.isErr)
assert.Equal(t, len(tc.exp.out), len(rs))
for i := range rs {
actual, err := rs[i].String()
rsMap, err := rs[i].Map()
assert.NoError(t, err)
assert.Equal(
t, strings.TrimSpace(tc.exp.out[i]), strings.TrimSpace(actual))
}
})
}
}
func TestDropLocalNodes(t *testing.T) {
testCases := map[string]struct {
input []byte
expected []byte
}{
"localConfigUnset": {
input: []byte(`apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
`),
expected: []byte(`apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
`),
},
"localConfigSet": {
input: []byte(`apiVersion: v1
kind: ConfigMap
metadata:
name: winnie-skip
annotations:
# this annotation causes the Resource to be ignored by kustomize
config.kubernetes.io/local-config: ""
`),
expected: nil,
},
"localConfigSetToTrue": {
input: []byte(`apiVersion: v1
kind: ConfigMap
metadata:
name: winnie-skip
annotations:
config.kubernetes.io/local-config: "true"
`),
expected: nil,
},
"localConfigSetToFalse": {
input: []byte(`apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
annotations:
config.kubernetes.io/local-config: "false"
`),
expected: []byte(`apiVersion: v1
kind: ConfigMap
metadata:
annotations:
config.kubernetes.io/local-config: "false"
name: winnie
`),
},
"localConfigMultiInput": {
input: []byte(`apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
---
apiVersion: v1
kind: ConfigMap
metadata:
name: winnie-skip
annotations:
config.kubernetes.io/local-config: "true"
`),
expected: []byte(`apiVersion: v1
kind: ConfigMap
metadata:
name: winnie
`),
},
}
for n := range testCases {
tc := testCases[n]
t.Run(n, func(t *testing.T) {
nin, _ := kio.FromBytes(tc.input)
res, err := factory.DropLocalNodes(nin)
assert.NoError(t, err)
if tc.expected == nil {
assert.Equal(t, 0, len(res))
} else {
actual, _ := res[0].AsYAML()
assert.Equal(t, tc.expected, actual)
t, fmt.Sprintf("%v", tc.exp.out[i]), fmt.Sprintf("%v", rsMap))
m, _ := rs[i].Map()
if !reflect.DeepEqual(tc.exp.out[i], m) {
t.Fatalf("%s:\nexpected: %v\n actual: %v",
n, tc.exp.out[i], m)
}
}
})
}

View File

@@ -1,60 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package resource
import (
"path/filepath"
"strings"
"sigs.k8s.io/kustomize/api/internal/git"
)
// Origin retains information about where resources in the output
// of `kustomize build` originated from
type Origin struct {
// Path is the path to the resource, rooted from the directory upon
// which `kustomize build` was invoked
Path string
// Repo is the remote repository that the resource originated from if it is
// not from a local file
Repo string
// Ref is the ref of the remote repository that the resource originated from
// if it is not from a local file
Ref string
}
// Copy returns a copy of origin
func (origin *Origin) Copy() Origin {
return *origin
}
// Append returns a copy of origin with a path appended to it
func (origin *Origin) Append(path string) *Origin {
originCopy := origin.Copy()
repoSpec, err := git.NewRepoSpecFromUrl(path)
if err == nil {
originCopy.Repo = repoSpec.Host + repoSpec.OrgRepo
absPath := repoSpec.AbsPath()
path = absPath[strings.Index(absPath[1:], "/")+1:][1:]
originCopy.Path = ""
originCopy.Ref = repoSpec.Ref
}
originCopy.Path = filepath.Join(originCopy.Path, path)
return &originCopy
}
// String returns a string version of origin
func (origin *Origin) String() string {
var anno string
anno = anno + "path: " + origin.Path + "\n"
if origin.Repo != "" {
anno = anno + "repo: " + origin.Repo + "\n"
}
if origin.Ref != "" {
anno = anno + "ref: " + origin.Ref + "\n"
}
return anno
}

View File

@@ -1,83 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package resource_test
import (
"testing"
. "sigs.k8s.io/kustomize/api/resource"
)
func TestOriginAppend(t *testing.T) {
tests := []struct {
in *Origin
path string
expected string
}{
{
in: &Origin{
Path: "prod",
},
path: "service.yaml",
expected: `path: prod/service.yaml
`,
},
{
in: &Origin{
Path: "overlay/prod",
},
path: "github.com/kubernetes-sigs/kustomize/examples/multibases/dev/",
expected: `path: examples/multibases/dev
repo: https://github.com/kubernetes-sigs/kustomize
`,
},
}
for _, test := range tests {
actual := test.in.Append(test.path).String()
if actual != test.expected {
t.Fatalf("Expected %v, but got %v\n", test.expected, actual)
}
}
}
func TestOriginString(t *testing.T) {
tests := []struct {
in *Origin
expected string
}{
{
in: &Origin{
Path: "prod/service.yaml",
Repo: "github.com/kubernetes-sigs/kustomize/examples/multibases/dev/",
Ref: "v1.0.6",
},
expected: `path: prod/service.yaml
repo: github.com/kubernetes-sigs/kustomize/examples/multibases/dev/
ref: v1.0.6
`,
},
{
in: &Origin{
Path: "prod/service.yaml",
Repo: "github.com/kubernetes-sigs/kustomize/examples/multibases/dev/",
},
expected: `path: prod/service.yaml
repo: github.com/kubernetes-sigs/kustomize/examples/multibases/dev/
`,
},
{
in: &Origin{
Path: "prod/service.yaml",
},
expected: `path: prod/service.yaml
`,
},
}
for _, test := range tests {
if test.in.String() != test.expected {
t.Fatalf("Expected %v, but got %v\n", test.expected, test.in.String())
}
}
}

View File

@@ -4,16 +4,16 @@
package resource
import (
"errors"
"fmt"
"log"
"strings"
"sigs.k8s.io/kustomize/api/filters/patchstrategicmerge"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
"sigs.k8s.io/kustomize/kyaml/resid"
kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
"sigs.k8s.io/yaml"
@@ -23,27 +23,33 @@ import (
// paired with metadata used by kustomize.
type Resource struct {
kyaml.RNode
options *types.GenArgs
refBy []resid.ResId
refVarNames []string
}
var BuildAnnotations = []string{
utils.BuildAnnotationPreviousKinds,
utils.BuildAnnotationPreviousNames,
utils.BuildAnnotationPrefixes,
utils.BuildAnnotationSuffixes,
utils.BuildAnnotationPreviousNamespaces,
utils.BuildAnnotationAllowNameChange,
utils.BuildAnnotationAllowKindChange,
utils.BuildAnnotationsRefBy,
utils.BuildAnnotationsGenBehavior,
utils.BuildAnnotationsGenAddHashSuffix,
const (
buildAnnotationPreviousKinds = konfig.ConfigAnnoDomain + "/previousKinds"
buildAnnotationPreviousNames = konfig.ConfigAnnoDomain + "/previousNames"
buildAnnotationPrefixes = konfig.ConfigAnnoDomain + "/prefixes"
buildAnnotationSuffixes = konfig.ConfigAnnoDomain + "/suffixes"
buildAnnotationPreviousNamespaces = konfig.ConfigAnnoDomain + "/previousNamespaces"
kioutil.PathAnnotation,
kioutil.IndexAnnotation,
kioutil.SeqIndentAnnotation,
// the following are only for patches, to specify whether they can change names
// and kinds of their targets
buildAnnotationAllowNameChange = konfig.ConfigAnnoDomain + "/allowNameChange"
buildAnnotationAllowKindChange = konfig.ConfigAnnoDomain + "/allowKindChange"
allowed = "allowed"
)
kioutil.LegacyPathAnnotation,
kioutil.LegacyIndexAnnotation,
var buildAnnotations = []string{
buildAnnotationPreviousKinds,
buildAnnotationPreviousNames,
buildAnnotationPrefixes,
buildAnnotationSuffixes,
buildAnnotationPreviousNamespaces,
buildAnnotationAllowNameChange,
buildAnnotationAllowKindChange,
}
func (r *Resource) ResetRNode(incoming *Resource) {
@@ -89,8 +95,6 @@ func (r *Resource) DeepCopy() *Resource {
// CopyMergeMetaDataFieldsFrom copies everything but the non-metadata in
// the resource.
// TODO: move to RNode, use GetMeta to improve performance.
// TODO: make a version of mergeStringMaps that is build-annotation aware
// to avoid repeatedly setting refby and genargs annotations
// Must remove the kustomize bit at the end.
func (r *Resource) CopyMergeMetaDataFieldsFrom(other *Resource) error {
if err := r.SetLabels(
@@ -98,7 +102,7 @@ func (r *Resource) CopyMergeMetaDataFieldsFrom(other *Resource) error {
return fmt.Errorf("copyMerge cannot set labels - %w", err)
}
if err := r.SetAnnotations(
mergeStringMapsWithBuildAnnotations(other.GetAnnotations(), r.GetAnnotations())); err != nil {
mergeStringMaps(other.GetAnnotations(), r.GetAnnotations())); err != nil {
return fmt.Errorf("copyMerge cannot set annotations - %w", err)
}
if err := r.SetName(other.GetName()); err != nil {
@@ -112,6 +116,8 @@ func (r *Resource) CopyMergeMetaDataFieldsFrom(other *Resource) error {
}
func (r *Resource) copyKustomizeSpecificFields(other *Resource) {
r.options = other.options
r.refBy = other.copyRefBy()
r.refVarNames = copyStringSlice(other.refVarNames)
}
@@ -153,10 +159,10 @@ func (r *Resource) ErrIfNotEquals(o *Resource) error {
func (r *Resource) ReferencesEqual(other *Resource) bool {
setSelf := make(map[resid.ResId]bool)
setOther := make(map[resid.ResId]bool)
for _, ref := range other.GetRefBy() {
for _, ref := range other.refBy {
setOther[ref] = true
}
for _, ref := range r.GetRefBy() {
for _, ref := range r.refBy {
if _, ok := setOther[ref]; !ok {
return false
}
@@ -165,6 +171,15 @@ func (r *Resource) ReferencesEqual(other *Resource) bool {
return len(setSelf) == len(setOther)
}
func (r *Resource) copyRefBy() []resid.ResId {
if r.refBy == nil {
return nil
}
s := make([]resid.ResId, len(r.refBy))
copy(s, r.refBy)
return s
}
func copyStringSlice(s []string) []string {
if s == nil {
return nil
@@ -176,12 +191,12 @@ func copyStringSlice(s []string) []string {
// Implements ResCtx AddNamePrefix
func (r *Resource) AddNamePrefix(p string) {
r.appendCsvAnnotation(utils.BuildAnnotationPrefixes, p)
r.appendCsvAnnotation(buildAnnotationPrefixes, p)
}
// Implements ResCtx AddNameSuffix
func (r *Resource) AddNameSuffix(s string) {
r.appendCsvAnnotation(utils.BuildAnnotationSuffixes, s)
r.appendCsvAnnotation(buildAnnotationSuffixes, s)
}
func (r *Resource) appendCsvAnnotation(name, value string) {
@@ -199,14 +214,30 @@ func (r *Resource) appendCsvAnnotation(name, value string) {
}
}
func SameEndingSubarray(shortest, longest []string) bool {
if len(shortest) > len(longest) {
longest, shortest = shortest, longest
}
diff := len(longest) - len(shortest)
if len(shortest) == 0 {
return diff == 0
}
for i := len(shortest) - 1; i >= 0; i-- {
if longest[i+diff] != shortest[i] {
return false
}
}
return true
}
// Implements ResCtx GetNamePrefixes
func (r *Resource) GetNamePrefixes() []string {
return r.getCsvAnnotation(utils.BuildAnnotationPrefixes)
return r.getCsvAnnotation(buildAnnotationPrefixes)
}
// Implements ResCtx GetNameSuffixes
func (r *Resource) GetNameSuffixes() []string {
return r.getCsvAnnotation(utils.BuildAnnotationSuffixes)
return r.getCsvAnnotation(buildAnnotationSuffixes)
}
func (r *Resource) getCsvAnnotation(name string) []string {
@@ -221,8 +252,7 @@ func (r *Resource) getCsvAnnotation(name string) []string {
// as OutermostPrefixSuffix but performs a deeper comparison
// of the suffix and prefix slices.
func (r *Resource) PrefixesSuffixesEquals(o ResCtx) bool {
return utils.SameEndingSubSlice(r.GetNamePrefixes(), o.GetNamePrefixes()) &&
utils.SameEndingSubSlice(r.GetNameSuffixes(), o.GetNameSuffixes())
return SameEndingSubarray(r.GetNamePrefixes(), o.GetNamePrefixes()) && SameEndingSubarray(r.GetNameSuffixes(), o.GetNameSuffixes())
}
// RemoveBuildAnnotations removes annotations created by the build process.
@@ -233,7 +263,7 @@ func (r *Resource) RemoveBuildAnnotations() {
if len(annotations) == 0 {
return
}
for _, a := range BuildAnnotations {
for _, a := range buildAnnotations {
delete(annotations, a)
}
if err := r.SetAnnotations(annotations); err != nil {
@@ -242,53 +272,49 @@ func (r *Resource) RemoveBuildAnnotations() {
}
func (r *Resource) setPreviousId(ns string, n string, k string) *Resource {
r.appendCsvAnnotation(utils.BuildAnnotationPreviousNames, n)
r.appendCsvAnnotation(utils.BuildAnnotationPreviousNamespaces, ns)
r.appendCsvAnnotation(utils.BuildAnnotationPreviousKinds, k)
r.appendCsvAnnotation(buildAnnotationPreviousNames, n)
r.appendCsvAnnotation(buildAnnotationPreviousNamespaces, ns)
r.appendCsvAnnotation(buildAnnotationPreviousKinds, k)
return r
}
// AllowNameChange allows name changes to the resource.
func (r *Resource) AllowNameChange() {
r.enable(utils.BuildAnnotationAllowNameChange)
annotations := r.GetAnnotations()
annotations[buildAnnotationAllowNameChange] = allowed
if err := r.SetAnnotations(annotations); err != nil {
panic(err)
}
}
// NameChangeAllowed checks if a patch resource is allowed to change another resource's name.
func (r *Resource) NameChangeAllowed() bool {
return r.isEnabled(utils.BuildAnnotationAllowNameChange)
annotations := r.GetAnnotations()
v, ok := annotations[buildAnnotationAllowNameChange]
return ok && v == allowed
}
// AllowKindChange allows kind changes to the resource.
func (r *Resource) AllowKindChange() {
r.enable(utils.BuildAnnotationAllowKindChange)
}
// KindChangeAllowed checks if a patch resource is allowed to change another resource's kind.
func (r *Resource) KindChangeAllowed() bool {
return r.isEnabled(utils.BuildAnnotationAllowKindChange)
}
func (r *Resource) isEnabled(annoKey string) bool {
annotations := r.GetAnnotations()
v, ok := annotations[annoKey]
return ok && v == utils.Enabled
}
func (r *Resource) enable(annoKey string) {
annotations := r.GetAnnotations()
annotations[annoKey] = utils.Enabled
annotations[buildAnnotationAllowKindChange] = allowed
if err := r.SetAnnotations(annotations); err != nil {
panic(err)
}
}
func (r *Resource) KindChangeAllowed() bool {
annotations := r.GetAnnotations()
v, ok := annotations[buildAnnotationAllowKindChange]
return ok && v == allowed
}
// String returns resource as JSON.
func (r *Resource) String() string {
bs, err := r.MarshalJSON()
if err != nil {
return "<" + err.Error() + ">"
}
return strings.TrimSpace(string(bs))
return strings.TrimSpace(string(bs)) + r.options.String()
}
// AsYAML returns the resource in Yaml form.
@@ -310,34 +336,20 @@ func (r *Resource) MustYaml() string {
return string(yml)
}
// Behavior returns the behavior for the resource.
func (r *Resource) Behavior() types.GenerationBehavior {
annotations := r.GetAnnotations()
if v, ok := annotations[utils.BuildAnnotationsGenBehavior]; ok {
return types.NewGenerationBehavior(v)
}
return types.NewGenerationBehavior("")
// SetOptions updates the generator options for the resource.
func (r *Resource) SetOptions(o *types.GenArgs) {
r.options = o
}
// SetBehavior sets the behavior for the resource.
func (r *Resource) SetBehavior(behavior types.GenerationBehavior) {
annotations := r.GetAnnotations()
annotations[utils.BuildAnnotationsGenBehavior] = behavior.String()
if err := r.SetAnnotations(annotations); err != nil {
panic(err)
}
// Behavior returns the behavior for the resource.
func (r *Resource) Behavior() types.GenerationBehavior {
return r.options.Behavior()
}
// NeedHashSuffix returns true if a resource content
// hash should be appended to the name of the resource.
func (r *Resource) NeedHashSuffix() bool {
return r.isEnabled(utils.BuildAnnotationsGenAddHashSuffix)
}
// EnableHashSuffix marks the resource as needing a content
// hash to be appended to the name of the resource.
func (r *Resource) EnableHashSuffix() {
r.enable(utils.BuildAnnotationsGenAddHashSuffix)
return r.options != nil && r.options.ShouldAddHashSuffixToName()
}
// OrgId returns the original, immutable ResId for the resource.
@@ -357,12 +369,26 @@ func (r *Resource) OrgId() resid.ResId {
// The returned array does not include the resource's current
// ID. If there are no previous IDs, this will return nil.
func (r *Resource) PrevIds() []resid.ResId {
prevIds, err := utils.PrevIds(&r.RNode)
if err != nil {
// this should never happen
panic(err)
var ids []resid.ResId
// TODO: merge previous names and namespaces into one list of
// pairs on one annotation so there is no chance of error
names := r.getCsvAnnotation(buildAnnotationPreviousNames)
ns := r.getCsvAnnotation(buildAnnotationPreviousNamespaces)
kinds := r.getCsvAnnotation(buildAnnotationPreviousKinds)
if len(names) != len(ns) || len(names) != len(kinds) {
panic(errors.New(
"number of previous names, " +
"number of previous namespaces, " +
"number of previous kinds not equal"))
}
return prevIds
for i := range names {
k := kinds[i]
gvk := r.GetGvk()
gvk.Kind = k
ids = append(ids, resid.NewResIdWithNamespace(
gvk, names[i], ns[i]))
}
return ids
}
// StorePreviousId stores the resource's current ID via build annotations.
@@ -381,18 +407,12 @@ func (r *Resource) CurId() resid.ResId {
// GetRefBy returns the ResIds that referred to current resource
func (r *Resource) GetRefBy() []resid.ResId {
var resIds []resid.ResId
asStrings := r.getCsvAnnotation(utils.BuildAnnotationsRefBy)
for _, s := range asStrings {
resIds = append(resIds, resid.FromString(s))
}
return resIds
return r.refBy
}
// AppendRefBy appends a ResId into the refBy list
// Using any type except fmt.Stringer here results in a compilation error
func (r *Resource) AppendRefBy(id fmt.Stringer) {
r.appendCsvAnnotation(utils.BuildAnnotationsRefBy, id.String())
func (r *Resource) AppendRefBy(id resid.ResId) {
r.refBy = append(r.refBy, id)
}
// GetRefVarNames returns vars that refer to current resource
@@ -448,17 +468,3 @@ func mergeStringMaps(maps ...map[string]string) map[string]string {
}
return result
}
func mergeStringMapsWithBuildAnnotations(maps ...map[string]string) map[string]string {
result := mergeStringMaps(maps...)
for i := range BuildAnnotations {
if len(maps) > 0 {
if v, ok := maps[0][BuildAnnotations[i]]; ok {
result[BuildAnnotations[i]] = v
continue
}
}
delete(result, BuildAnnotations[i])
}
return result
}

View File

@@ -9,7 +9,6 @@ import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/provider"
. "sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
@@ -28,6 +27,8 @@ var testConfigMap = factory.FromMap(
},
})
const genArgOptions = "{nsfx:false,beh:unspecified}"
//nolint:gosec
const configMapAsString = `{"apiVersion":"v1","kind":"ConfigMap","metadata":{"name":"winnie","namespace":"hundred-acre-wood"}}`
@@ -64,15 +65,17 @@ func TestResourceString(t *testing.T) {
}{
{
in: testConfigMap,
s: configMapAsString,
s: configMapAsString + genArgOptions,
},
{
in: testDeployment,
s: deploymentAsString,
s: deploymentAsString + genArgOptions,
},
}
for _, test := range tests {
assert.Equal(t, test.in.String(), test.s)
if test.in.String() != test.s {
t.Fatalf("Expected %s == %s", test.in.String(), test.s)
}
}
}
@@ -280,266 +283,6 @@ spec:
`, string(bytes))
}
func TestApplySmPatchShouldOutputListItemsInCorrectOrder(t *testing.T) {
cases := []struct {
name string
skip bool
patch string
expectedOutput string
}{
{
name: "Order should not change when patch has foo only",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: foo
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: foo
- name: bar
`,
},
{
name: "Order changes when patch has bar only",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: bar
`,
// This test records current behavior, but this behavior might be undesirable.
// If so, feel free to change the test to pass with some improved algorithm.
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: bar
- name: foo
`,
},
{
name: "Order should not change and should include a new item at the beginning when patch has a new list item",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: baz
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: baz
- name: foo
- name: bar
`,
},
{
name: "Order should not change when patch has foo and bar in same order",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: foo
- name: bar
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: foo
- name: bar
`,
},
{
name: "Order should change when patch has foo and bar in different order",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: bar
- name: foo
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: bar
- name: foo
`,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
if tc.skip {
t.Skip()
}
resource, err := factory.FromBytes([]byte(`
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
initContainers:
- name: foo
- name: bar
`))
assert.NoError(t, err)
patch, err := factory.FromBytes([]byte(tc.patch))
assert.NoError(t, err)
assert.NoError(t, resource.ApplySmPatch(patch))
bytes, err := resource.AsYAML()
assert.NoError(t, err)
assert.Equal(t, tc.expectedOutput, string(bytes))
})
}
}
func TestApplySmPatchShouldOutputPrimitiveListItemsInCorrectOrder(t *testing.T) {
cases := []struct {
name string
skip bool
patch string
expectedOutput string
}{
{
name: "Order should not change when patch has foo only",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
finalizers: ["foo"]
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
finalizers:
- foo
- bar
name: test
`,
},
{
name: "Order should not change when patch has bar only",
skip: true, // TODO: This test should pass but fails currently. Fix the problem and unskip this test
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
finalizers: ["bar"]
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
finalizers:
- foo
- bar
name: test
`,
},
{
name: "Order should not change and should include a new item at the beginning when patch has a new list item",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
finalizers: ["baz"]
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
finalizers:
- baz
- foo
- bar
name: test
`,
},
{
name: "Order should not change when patch has foo and bar in same order",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
finalizers: ["foo", "bar"]
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
finalizers:
- foo
- bar
name: test
`,
},
{
name: "Order should change when patch has foo and bar in different order",
patch: `apiVersion: v1
kind: Pod
metadata:
name: test
finalizers: ["bar", "foo"]
`,
expectedOutput: `apiVersion: v1
kind: Pod
metadata:
finalizers:
- bar
- foo
name: test
`,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
if tc.skip {
t.Skip()
}
resource, err := factory.FromBytes([]byte(`
kind: Pod
metadata:
name: test
finalizers: ["foo", "bar"]
`))
assert.NoError(t, err)
patch, err := factory.FromBytes([]byte(tc.patch))
assert.NoError(t, err)
assert.NoError(t, resource.ApplySmPatch(patch))
bytes, err := resource.AsYAML()
assert.NoError(t, err)
assert.Equal(t, tc.expectedOutput, string(bytes))
})
}
}
func TestMergeDataMapFrom(t *testing.T) {
resource, err := factory.FromBytes([]byte(`
apiVersion: v1
@@ -973,9 +716,9 @@ metadata:
kind: Secret
metadata:
annotations:
internal.config.kubernetes.io/previousKinds: Secret
internal.config.kubernetes.io/previousNames: oldName
internal.config.kubernetes.io/previousNamespaces: default
config.kubernetes.io/previousKinds: Secret
config.kubernetes.io/previousNames: oldName
config.kubernetes.io/previousNamespaces: default
name: newName
`,
},
@@ -985,9 +728,9 @@ metadata:
kind: Secret
metadata:
annotations:
internal.config.kubernetes.io/previousKinds: Secret
internal.config.kubernetes.io/previousNames: oldName
internal.config.kubernetes.io/previousNamespaces: default
config.kubernetes.io/previousKinds: Secret
config.kubernetes.io/previousNames: oldName
config.kubernetes.io/previousNamespaces: default
name: oldName2
`,
newName: "newName",
@@ -996,9 +739,9 @@ metadata:
kind: Secret
metadata:
annotations:
internal.config.kubernetes.io/previousKinds: Secret,Secret
internal.config.kubernetes.io/previousNames: oldName,oldName2
internal.config.kubernetes.io/previousNamespaces: default,default
config.kubernetes.io/previousKinds: Secret,Secret
config.kubernetes.io/previousNames: oldName,oldName2
config.kubernetes.io/previousNamespaces: default,default
name: newName
`,
},
@@ -1008,9 +751,9 @@ metadata:
kind: Secret
metadata:
annotations:
internal.config.kubernetes.io/previousKinds: Secret
internal.config.kubernetes.io/previousNames: oldName
internal.config.kubernetes.io/previousNamespaces: default
config.kubernetes.io/previousKinds: Secret
config.kubernetes.io/previousNames: oldName
config.kubernetes.io/previousNamespaces: default
name: oldName2
namespace: oldNamespace
`,
@@ -1020,9 +763,9 @@ metadata:
kind: Secret
metadata:
annotations:
internal.config.kubernetes.io/previousKinds: Secret,Secret
internal.config.kubernetes.io/previousNames: oldName,oldName2
internal.config.kubernetes.io/previousNamespaces: default,oldNamespace
config.kubernetes.io/previousKinds: Secret,Secret
config.kubernetes.io/previousNames: oldName,oldName2
config.kubernetes.io/previousNamespaces: default,oldNamespace
name: newName
namespace: newNamespace
`,
@@ -1070,9 +813,9 @@ metadata:
kind: Secret
metadata:
annotations:
internal.config.kubernetes.io/previousKinds: Secret
internal.config.kubernetes.io/previousNames: oldName
internal.config.kubernetes.io/previousNamespaces: default
config.kubernetes.io/previousKinds: Secret
config.kubernetes.io/previousNames: oldName
config.kubernetes.io/previousNamespaces: default
name: newName
`,
expected: []resid.ResId{
@@ -1089,9 +832,9 @@ metadata:
kind: Secret
metadata:
annotations:
internal.config.kubernetes.io/previousKinds: Secret,Secret
internal.config.kubernetes.io/previousNames: oldName,oldName2
internal.config.kubernetes.io/previousNamespaces: default,oldNamespace
config.kubernetes.io/previousKinds: Secret,Secret
config.kubernetes.io/previousNames: oldName,oldName2
config.kubernetes.io/previousNamespaces: default,oldNamespace
name: newName
namespace: newNamespace
`,
@@ -1334,7 +1077,7 @@ func TestSameEndingSubarray(t *testing.T) {
for n := range testCases {
tc := testCases[n]
t.Run(n, func(t *testing.T) {
assert.Equal(t, tc.expected, utils.SameEndingSubSlice(tc.a, tc.b))
assert.Equal(t, tc.expected, SameEndingSubarray(tc.a, tc.b))
})
}
}
@@ -1389,41 +1132,3 @@ spec:
t.Fatalf("expected '%s', got '%s'", expected, actual)
}
}
func TestRefBy(t *testing.T) {
r, err := factory.FromBytes([]byte(`
apiVersion: v1
kind: Deployment
metadata:
name: clown
spec:
numReplicas: 1
`))
assert.NoError(t, err)
r.AppendRefBy(resid.FromString("gr1_ver1_knd1|ns1|name1"))
assert.Equal(t, r.RNode.MustString(), `apiVersion: v1
kind: Deployment
metadata:
name: clown
annotations:
internal.config.kubernetes.io/refBy: gr1_ver1_knd1|ns1|name1
spec:
numReplicas: 1
`)
assert.Equal(t, r.GetRefBy(), []resid.ResId{resid.FromString("gr1_ver1_knd1|ns1|name1")})
r.AppendRefBy(resid.FromString("gr2_ver2_knd2|ns2|name2"))
assert.Equal(t, r.RNode.MustString(), `apiVersion: v1
kind: Deployment
metadata:
name: clown
annotations:
internal.config.kubernetes.io/refBy: gr1_ver1_knd1|ns1|name1,gr2_ver2_knd2|ns2|name2
spec:
numReplicas: 1
`)
assert.Equal(t, r.GetRefBy(), []resid.ResId{
resid.FromString("gr1_ver1_knd1|ns1|name1"),
resid.FromString("gr2_ver2_knd2|ns2|name2"),
})
}

View File

@@ -7,12 +7,12 @@ import (
"path/filepath"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/konfig/builtinpluginconsts"
"sigs.k8s.io/kustomize/api/krusty"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// Harness manages a test environment.

View File

@@ -11,6 +11,7 @@ import (
"strings"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc"
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
"sigs.k8s.io/kustomize/api/konfig"
@@ -19,7 +20,6 @@ import (
"sigs.k8s.io/kustomize/api/resmap"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// HarnessEnhanced manages a full plugin environment for tests.
@@ -148,13 +148,6 @@ func (th *HarnessEnhanced) ResetLoaderRoot(root string) {
}
func (th *HarnessEnhanced) LoadAndRunGenerator(
config string) resmap.ResMap {
rm := th.LoadAndRunGeneratorWithBuildAnnotations(config)
rm.RemoveBuildAnnotations()
return rm
}
func (th *HarnessEnhanced) LoadAndRunGeneratorWithBuildAnnotations(
config string) resmap.ResMap {
res, err := th.rf.RF().FromBytes([]byte(config))
if err != nil {
@@ -169,6 +162,7 @@ func (th *HarnessEnhanced) LoadAndRunGeneratorWithBuildAnnotations(
if err != nil {
th.t.Fatalf("generate err: %v", err)
}
rm.RemoveBuildAnnotations()
return rm
}

View File

@@ -7,10 +7,10 @@ import (
"os"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/internal/plugins/compiler"
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// pluginTestEnv manages compiling plugins for tests.

46
api/types/genargs.go Normal file
View File

@@ -0,0 +1,46 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package types
import (
"strconv"
"strings"
)
// GenArgs is a facade over GeneratorArgs, exposing a few readonly properties.
type GenArgs struct {
args *GeneratorArgs
}
// NewGenArgs returns a new instance of GenArgs.
func NewGenArgs(args *GeneratorArgs) *GenArgs {
return &GenArgs{args: args}
}
func (g *GenArgs) String() string {
if g == nil {
return "{nilGenArgs}"
}
return "{" +
strings.Join([]string{
"nsfx:" + strconv.FormatBool(g.ShouldAddHashSuffixToName()),
"beh:" + g.Behavior().String()},
",") +
"}"
}
// ShouldAddHashSuffixToName returns true if a resource
// content hash should be appended to the name of the resource.
func (g *GenArgs) ShouldAddHashSuffixToName() bool {
return g.args != nil &&
(g.args.Options == nil || !g.args.Options.DisableNameSuffixHash)
}
// Behavior returns Behavior field of GeneratorArgs
func (g *GenArgs) Behavior() GenerationBehavior {
if g == nil || g.args == nil {
return BehaviorUnspecified
}
return NewGenerationBehavior(g.args.Behavior)
}

39
api/types/genargs_test.go Normal file
View File

@@ -0,0 +1,39 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package types_test
import (
"testing"
. "sigs.k8s.io/kustomize/api/types"
)
func TestGenArgs_String(t *testing.T) {
tests := []struct {
ga *GenArgs
expected string
}{
{
ga: nil,
expected: "{nilGenArgs}",
},
{
ga: &GenArgs{},
expected: "{nsfx:false,beh:unspecified}",
},
{
ga: NewGenArgs(
&GeneratorArgs{
Behavior: "merge",
Options: &GeneratorOptions{DisableNameSuffixHash: false},
}),
expected: "{nsfx:true,beh:merge}",
},
}
for _, test := range tests {
if test.ga.String() != test.expected {
t.Fatalf("Expected '%s', got '%s'", test.expected, test.ga.String())
}
}
}

View File

@@ -161,9 +161,6 @@ type Kustomization struct {
// Inventory appends an object that contains the record
// of all other objects, which can be used in apply, prune and delete
Inventory *Inventory `json:"inventory,omitempty" yaml:"inventory,omitempty"`
// BuildMetadata is a list of strings used to toggle different build options
BuildMetadata []string `json:"buildMetadata,omitempty" yaml:"buildMetadata,omitempty"`
}
// FixKustomizationPostUnmarshalling fixes things

View File

@@ -42,7 +42,7 @@ const (
BploLoadFromFileSys
)
// FnPluginLoadingOptions set way functions-based plugins are restricted
// FnPluginLoadingOptions set way functions-based pluing are restricted
type FnPluginLoadingOptions struct {
// Allow to run executables
EnableExec bool
@@ -55,8 +55,4 @@ type FnPluginLoadingOptions struct {
Mounts []string
// list of env variables to pass to fn
Env []string
// Run as uid and gid of the command executor
AsCurrentUser bool
// Run in this working directory
WorkingDir string
}

View File

@@ -1,6 +0,0 @@
# See https://github.com/kubernetes/community/blob/master/community-membership.md
approvers:
- kyaml-approvers
reviewers:
- kyaml-reviewers

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