Compare commits

..

36 Commits

Author SHA1 Message Date
Phillip Wittrock
bf721a3fdd update go.mod for release 2020-04-17 09:51:31 -07:00
Phillip Wittrock
7d968fa80e Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-04-17 09:51:26 -07:00
Phillip Wittrock
fd6207b1c3 update go.mod for release 2020-04-02 11:31:23 -07:00
Phillip Wittrock
cbe85f482d Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-04-02 11:31:14 -07:00
Phillip Wittrock
a1c7330331 update go.mod for release 2020-03-28 08:34:06 -07:00
Phillip Wittrock
08ceab40dd Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-03-28 08:34:01 -07:00
Phillip Wittrock
f8fb00cb13 update go.mod for release 2020-03-23 12:08:52 -07:00
Phillip Wittrock
8a1c841420 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-03-23 12:08:31 -07:00
Phillip Wittrock
730d1f2473 update go.mod for release 2020-03-06 09:29:07 -08:00
Phillip Wittrock
29d1a37858 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-03-06 09:29:02 -08:00
Phillip Wittrock
c467f48bf2 update go.mod for release 2020-02-27 12:21:10 -08:00
Phillip Wittrock
054f56ceaf Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.1 2020-02-27 12:21:05 -08:00
Phillip Wittrock
d5a107074d update go.mod for release 2020-02-21 10:18:34 -08:00
Phillip Wittrock
d8bd6db880 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2020-02-21 10:18:15 -08:00
Phillip Wittrock
d27135e3a3 update go.mod for release 2020-02-19 15:00:57 -08:00
Phillip Wittrock
282b1fa49a Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2020-02-19 15:00:38 -08:00
Phillip Wittrock
584eb236fd update go.mod for release 2020-02-05 17:46:10 -08:00
Phillip Wittrock
31a193f60f Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2020-02-05 17:46:04 -08:00
Phillip Wittrock
bf17b244e5 update go.mod for release 2020-01-16 16:24:55 -08:00
Phillip Wittrock
8338299529 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2020-01-16 16:24:35 -08:00
Phillip Wittrock
7adf7eb271 update go.mod for release 2020-01-15 18:10:02 -08:00
Phillip Wittrock
06b091b175 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2020-01-15 18:09:55 -08:00
Phillip Wittrock
bf03669e94 update go.mod for release 2020-01-13 12:49:07 -08:00
Phillip Wittrock
7f52c814a8 release cmd/config
Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0
2020-01-13 12:47:01 -08:00
Phillip Wittrock
d5aac922d9 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2020-01-10 16:38:39 -08:00
Phillip Wittrock
9a62d866f3 update go.mod for release 2020-01-09 17:02:34 -08:00
Phillip Wittrock
b2812838bf release cmd/config 0.0.6
Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0
2020-01-09 17:02:08 -08:00
Phillip Wittrock
e59e477702 update go.mod for release 2020-01-03 10:01:16 -08:00
Phillip Wittrock
4264ad0ad4 release cmd/config 0.0.5 Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2020-01-03 10:01:06 -08:00
Phillip Wittrock
2554cd00eb update go.mod for release 2020-01-02 09:02:06 -08:00
Phillip Wittrock
383244cd63 Release cmd/config 0.0.4
Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0
2020-01-02 09:01:56 -08:00
Phillip Wittrock
b9da33afd4 update go.mod for release 2019-12-20 09:44:25 -08:00
Phillip Wittrock
23e339b86c Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2019-12-20 09:44:21 -08:00
Phillip Wittrock
9555009df8 update go.mod for release 2019-12-16 14:21:02 -08:00
Phillip Wittrock
91a10c560c Merge remote-tracking branch 'upstream/master' into release-cmd/config-v0.0 2019-12-16 14:20:58 -08:00
Phillip Wittrock
780cb19c4d drop replace 2019-12-13 13:50:17 -08:00
12136 changed files with 23573 additions and 902984 deletions

View File

@@ -1,100 +0,0 @@
name: Go
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
lint:
name: Lint
runs-on: [ubuntu-latest]
steps:
- name: Set up Go 1.x
uses: actions/setup-go@v2
with:
go-version: ^1.13
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Lint
run: ./travis/kyaml-pre-commit.sh
env:
KUSTOMIZE_DOCKER_E2E: false # don't need to do e2e tests for linting
test-linux:
name: Test Linux
runs-on: [ubuntu-latest]
steps:
- name: Set up Go 1.x
uses: actions/setup-go@v2
with:
go-version: ^1.13
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Test kyaml
run: go test -cover ./...
working-directory: ./kyaml
- name: Test cmd/config
run: go test -cover ./...
working-directory: ./cmd/config
env:
KUSTOMIZE_DOCKER_E2E: true
test-macos:
name: Test MacOS
runs-on: [macos-latest]
steps:
- name: Set up Go 1.x
uses: actions/setup-go@v2
with:
go-version: ^1.13
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Test kyaml
run: go test -cover ./...
working-directory: ./kyaml
- name: Test cmd/config
run: go test -cover ./...
working-directory: ./cmd/config
env:
KUSTOMIZE_DOCKER_E2E: false # docker not installed on mac
test-windows:
name: Test Windows
runs-on: [windows-latest]
steps:
- name: Set up Go 1.x
uses: actions/setup-go@v2
with:
go-version: ^1.13
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Test kyaml
run: go test -cover ./...
working-directory: ./kyaml
- name: Test cmd/config
run: go test -cover ./...
working-directory: ./cmd/config
env:
KUSTOMIZE_DOCKER_E2E: false # docker on windows not working well yet

2
.gitignore vendored
View File

@@ -19,5 +19,3 @@
# macOS # macOS
*.DS_store *.DS_store
.bin

View File

@@ -14,8 +14,8 @@ all: verify-kustomize
verify-kustomize: \ verify-kustomize: \
lint-kustomize \ lint-kustomize \
test-unit-kustomize-all \ test-unit-kustomize-all \
test-examples-kustomize-against-HEAD test-examples-kustomize-against-HEAD \
# test-examples-kustomize-against-3.7.0 test-examples-kustomize-against-latest
# The following target referenced by a file in # The following target referenced by a file in
# https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/kustomize # https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/kustomize
@@ -23,10 +23,8 @@ verify-kustomize: \
prow-presubmit-check: \ prow-presubmit-check: \
lint-kustomize \ lint-kustomize \
test-unit-kustomize-all \ test-unit-kustomize-all \
test-examples-kustomize-against-HEAD \
test-unit-cmd-all \ test-unit-cmd-all \
test-go-mod test-go-mod
# test-examples-kustomize-against-3.7.0 \
.PHONY: verify-kustomize-e2e .PHONY: verify-kustomize-e2e
verify-kustomize-e2e: test-examples-e2e-kustomize verify-kustomize-e2e: test-examples-e2e-kustomize
@@ -41,8 +39,10 @@ verify-kustomize-e2e: test-examples-e2e-kustomize
$(MYGOBIN)/golangci-lint-kustomize: $(MYGOBIN)/golangci-lint-kustomize:
( \ ( \
set -e; \ set -e; \
export GOBIN=$$(mktemp -d); \
cd hack; \ cd hack; \
GO111MODULE=on go build -tags=tools -o $(MYGOBIN)/golangci-lint-kustomize github.com/golangci/golangci-lint/cmd/golangci-lint; \ GO111MODULE=on go install github.com/golangci/golangci-lint/cmd/golangci-lint; \
mv $$GOBIN/golangci-lint $(MYGOBIN)/golangci-lint-kustomize \
) )
# Version pinned by api/go.mod # Version pinned by api/go.mod
@@ -116,6 +116,7 @@ _builtinplugins = \
ConfigMapGenerator.go \ ConfigMapGenerator.go \
HashTransformer.go \ HashTransformer.go \
ImageTagTransformer.go \ ImageTagTransformer.go \
InventoryTransformer.go \
LabelTransformer.go \ LabelTransformer.go \
LegacyOrderTransformer.go \ LegacyOrderTransformer.go \
NamespaceTransformer.go \ NamespaceTransformer.go \
@@ -124,8 +125,7 @@ _builtinplugins = \
PatchTransformer.go \ PatchTransformer.go \
PrefixSuffixTransformer.go \ PrefixSuffixTransformer.go \
ReplicaCountTransformer.go \ ReplicaCountTransformer.go \
SecretGenerator.go \ SecretGenerator.go
ValueAddTransformer.go
# Maintaining this explicit list of generated files, and # Maintaining this explicit list of generated files, and
# adding it as a dependency to a few targets, to assure # adding it as a dependency to a few targets, to assure
@@ -141,6 +141,7 @@ $(pGen)/AnnotationsTransformer.go: $(pSrc)/annotationstransformer/AnnotationsTra
$(pGen)/ConfigMapGenerator.go: $(pSrc)/configmapgenerator/ConfigMapGenerator.go $(pGen)/ConfigMapGenerator.go: $(pSrc)/configmapgenerator/ConfigMapGenerator.go
$(pGen)/HashTransformer.go: $(pSrc)/hashtransformer/HashTransformer.go $(pGen)/HashTransformer.go: $(pSrc)/hashtransformer/HashTransformer.go
$(pGen)/ImageTagTransformer.go: $(pSrc)/imagetagtransformer/ImageTagTransformer.go $(pGen)/ImageTagTransformer.go: $(pSrc)/imagetagtransformer/ImageTagTransformer.go
$(pGen)/InventoryTransformer.go: $(pSrc)/inventorytransformer/InventoryTransformer.go
$(pGen)/LabelTransformer.go: $(pSrc)/labeltransformer/LabelTransformer.go $(pGen)/LabelTransformer.go: $(pSrc)/labeltransformer/LabelTransformer.go
$(pGen)/LegacyOrderTransformer.go: $(pSrc)/legacyordertransformer/LegacyOrderTransformer.go $(pGen)/LegacyOrderTransformer.go: $(pSrc)/legacyordertransformer/LegacyOrderTransformer.go
$(pGen)/NamespaceTransformer.go: $(pSrc)/namespacetransformer/NamespaceTransformer.go $(pGen)/NamespaceTransformer.go: $(pSrc)/namespacetransformer/NamespaceTransformer.go
@@ -150,7 +151,6 @@ $(pGen)/PatchTransformer.go: $(pSrc)/patchtransformer/PatchTransformer.go
$(pGen)/PrefixSuffixTransformer.go: $(pSrc)/prefixsuffixtransformer/PrefixSuffixTransformer.go $(pGen)/PrefixSuffixTransformer.go: $(pSrc)/prefixsuffixtransformer/PrefixSuffixTransformer.go
$(pGen)/ReplicaCountTransformer.go: $(pSrc)/replicacounttransformer/ReplicaCountTransformer.go $(pGen)/ReplicaCountTransformer.go: $(pSrc)/replicacounttransformer/ReplicaCountTransformer.go
$(pGen)/SecretGenerator.go: $(pSrc)/secretgenerator/SecretGenerator.go $(pGen)/SecretGenerator.go: $(pSrc)/secretgenerator/SecretGenerator.go
$(pGen)/ValueAddTransformer.go: $(pSrc)/valueaddtransformer/ValueAddTransformer.go
# The (verbose but portable) Makefile way to convert to lowercase. # The (verbose but portable) Makefile way to convert to lowercase.
toLowerCase = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1)))))))))))))))))))))))))) toLowerCase = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
@@ -188,15 +188,9 @@ lint-kustomize: install-tools $(builtinplugins)
cd pluginator; \ cd pluginator; \
$(MYGOBIN)/golangci-lint-kustomize -c ../.golangci-kustomize.yml run ./... $(MYGOBIN)/golangci-lint-kustomize -c ../.golangci-kustomize.yml run ./...
# Used to add non-default compilation flags when experimenting with
# plugin-to-api compatibility checks.
.PHONY: build-kustomize-api
build-kustomize-api: $(builtinplugins)
cd api; go build ./...
.PHONY: test-unit-kustomize-api .PHONY: test-unit-kustomize-api
test-unit-kustomize-api: build-kustomize-api test-unit-kustomize-api: $(builtinplugins)
cd api; go test ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222" cd api; go test ./...
.PHONY: test-unit-kustomize-plugins .PHONY: test-unit-kustomize-plugins
test-unit-kustomize-plugins: test-unit-kustomize-plugins:
@@ -218,6 +212,10 @@ test-unit-cmd-all:
test-go-mod: test-go-mod:
./travis/check-go-mod.sh ./travis/check-go-mod.sh
.PHONY:
test-examples-kustomize-against-HEAD: $(MYGOBIN)/kustomize $(MYGOBIN)/mdrip
./hack/testExamplesAgainstKustomize.sh HEAD
.PHONY: .PHONY:
test-examples-e2e-kustomize: $(MYGOBIN)/mdrip $(MYGOBIN)/kind test-examples-e2e-kustomize: $(MYGOBIN)/mdrip $(MYGOBIN)/kind
( \ ( \
@@ -229,18 +227,13 @@ test-examples-e2e-kustomize: $(MYGOBIN)/mdrip $(MYGOBIN)/kind
) )
.PHONY: .PHONY:
test-examples-kustomize-against-HEAD: $(MYGOBIN)/kustomize $(MYGOBIN)/mdrip test-examples-kustomize-against-latest: $(MYGOBIN)/mdrip
./hack/testExamplesAgainstKustomize.sh HEAD
.PHONY:
test-examples-kustomize-against-3.7.0: $(MYGOBIN)/mdrip
( \ ( \
set -e; \ set -e; \
tag=v3.7.0; \
/bin/rm -f $(MYGOBIN)/kustomize; \ /bin/rm -f $(MYGOBIN)/kustomize; \
echo "Installing kustomize $$tag."; \ echo "Installing kustomize from latest."; \
GO111MODULE=on go get sigs.k8s.io/kustomize/kustomize/v3@$${tag}; \ GO111MODULE=on go install sigs.k8s.io/kustomize/kustomize/v3; \
./hack/testExamplesAgainstKustomize.sh $$tag; \ ./hack/testExamplesAgainstKustomize.sh latest; \
echo "Reinstalling kustomize from HEAD."; \ echo "Reinstalling kustomize from HEAD."; \
cd kustomize; go install .; \ cd kustomize; go install .; \
) )
@@ -262,38 +255,21 @@ $(MYGOBIN)/kubeval:
) )
# linux only. # linux only.
# This is for testing an example plugin that uses helm to inflate a chart # This is for testing an example plugin that
# for subsequent kustomization. # uses helm to inflate a chart for subsequent kustomization.
# Don't want to add a hard dependence in go.mod file to helm. # Don't want to add a hard dependence in go.mod file
# Instead, download the binaries. # to helm.
$(MYGOBIN)/helmV2: # Instead, download the binary.
$(MYGOBIN)/helm:
( \ ( \
set -e; \ set -e; \
d=$(shell mktemp -d); cd $$d; \ d=$(shell mktemp -d); cd $$d; \
tgzFile=helm-v2.13.1-linux-amd64.tar.gz; \ wget https://storage.googleapis.com/kubernetes-helm/helm-v2.13.1-linux-amd64.tar.gz; \
wget https://storage.googleapis.com/kubernetes-helm/$$tgzFile; \ tar -xvzf helm-v2.13.1-linux-amd64.tar.gz; \
tar -xvzf $$tgzFile; \ mv linux-amd64/helm $(MYGOBIN); \
mv linux-amd64/helm $(MYGOBIN)/helmV2; \
rm -rf $$d \ rm -rf $$d \
) )
# Helm V3 differs from helm V2; downloading it to provide coverage for the
# chart inflator plugin under helm v3.
$(MYGOBIN)/helmV3:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
tgzFile=helm-v3.2.0-rc.1-linux-amd64.tar.gz; \
wget https://get.helm.sh/$$tgzFile; \
tar -xvzf $$tgzFile; \
mv linux-amd64/helm $(MYGOBIN)/helmV3; \
rm -rf $$d \
)
# Default version of helm is v2 for the time being.
$(MYGOBIN)/helm: $(MYGOBIN)/helmV2
ln -s $(MYGOBIN)/helmV2 $(MYGOBIN)/helm
$(MYGOBIN)/kind: $(MYGOBIN)/kind:
( \ ( \
set -e; \ set -e; \
@@ -312,7 +288,6 @@ clean: kustomize-external-go-plugin-clean
rm -f $(MYGOBIN)/kustomize rm -f $(MYGOBIN)/kustomize
rm -f $(MYGOBIN)/golangci-lint-kustomize rm -f $(MYGOBIN)/golangci-lint-kustomize
# Nuke the site from orbit. It's the only way to be sure.
.PHONY: nuke .PHONY: nuke
nuke: clean nuke: clean
go clean --modcache sudo rm -rf $(shell go env GOPATH)/pkg/mod/sigs.k8s.io

View File

@@ -10,4 +10,3 @@ aliases:
- monopole - monopole
- pwittrock - pwittrock
- mortent - mortent
- phanimarupaka

View File

@@ -16,9 +16,9 @@ inspired by [DAM].
[![Go Report Card](https://goreportcard.com/badge/github.com/kubernetes-sigs/kustomize)](https://goreportcard.com/report/github.com/kubernetes-sigs/kustomize) [![Go Report Card](https://goreportcard.com/badge/github.com/kubernetes-sigs/kustomize)](https://goreportcard.com/report/github.com/kubernetes-sigs/kustomize)
Download a binary from the [release page], or see Download a binary from the [release page], or see
these [instructions](https://kubernetes-sigs.github.io/kustomize/installation/). these [instructions](docs/INSTALL.md).
Browse the [docs](https://kubernetes-sigs.github.io/kustomize/) or jump right into the Browse the [docs](docs) or jump right into the
tested [examples](examples). tested [examples](examples).
## kubectl integration ## kubectl integration
@@ -132,8 +132,20 @@ The YAML can be directly [applied] to a cluster:
## Community ## Community
- [file a bug](https://kubernetes-sigs.github.io/kustomize/contributing/bugs/) instructions To file bugs please read [this](docs/bugs.md).
- [contribute a feature](https://kubernetes-sigs.github.io/kustomize/contributing/features/) instructions
Before working on an implementation, please
* Read the [eschewed feature list].
* File an issue describing
how the new feature would behave
and label it [kind/feature].
### Other communication channels
- [Slack]
- [Mailing List]
- General kubernetes [community page]
### Code of conduct ### Code of conduct
@@ -142,27 +154,32 @@ is governed by the [Kubernetes Code of Conduct].
[`make`]: https://www.gnu.org/software/make [`make`]: https://www.gnu.org/software/make
[`sed`]: https://www.gnu.org/software/sed [`sed`]: https://www.gnu.org/software/sed
[DAM]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#declarative-application-management [DAM]: docs/glossary.md#declarative-application-management
[KEP]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/0008-kustomize.md [KEP]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/0008-kustomize.md
[Kubernetes Code of Conduct]: code-of-conduct.md [Kubernetes Code of Conduct]: code-of-conduct.md
[applied]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#apply [Mailing List]: https://groups.google.com/forum/#!forum/kubernetes-sig-cli
[base]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#base [Slack]: https://kubernetes.slack.com/messages/sig-cli
[declarative configuration]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#declarative-application-management [applied]: docs/glossary.md#apply
[base]: docs/glossary.md#base
[community page]: http://kubernetes.io/community/
[declarative configuration]: docs/glossary.md#declarative-application-management
[eschewed feature list]: docs/eschewedFeatures.md
[imageBase]: docs/images/base.jpg [imageBase]: docs/images/base.jpg
[imageOverlay]: docs/images/overlay.jpg [imageOverlay]: docs/images/overlay.jpg
[kind/feature]: /../../labels/kind%2Ffeature
[kubectl announcement]: https://kubernetes.io/blog/2019/03/25/kubernetes-1-14-release-announcement [kubectl announcement]: https://kubernetes.io/blog/2019/03/25/kubernetes-1-14-release-announcement
[kubectl book]: https://kubectl.docs.kubernetes.io/pages/app_customization/introduction.html [kubectl book]: https://kubectl.docs.kubernetes.io/pages/app_customization/introduction.html
[kubernetes documentation]: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/ [kubernetes documentation]: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/
[kubernetes style]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#kubernetes-style-object [kubernetes style]: docs/glossary.md#kubernetes-style-object
[kustomization]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#kustomization [kustomization]: docs/glossary.md#kustomization
[overlay]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#overlay [overlay]: docs/glossary.md#overlay
[overlays]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#overlay [overlays]: docs/glossary.md#overlay
[release page]: https://github.com/kubernetes-sigs/kustomize/releases [release page]: /../../releases
[resource]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#resource [resource]: docs/glossary.md#resource
[resources]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#resource [resources]: docs/glossary.md#resource
[sig-cli]: https://github.com/kubernetes/community/blob/master/sig-cli/README.md [sig-cli]: https://github.com/kubernetes/community/blob/master/sig-cli/README.md
[variant]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#variant [variant]: docs/glossary.md#variant
[variants]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#variant [variants]: docs/glossary.md#variant
[v2.0.3]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.0.3 [v2.0.3]: /../../releases/tag/v2.0.3
[v2.1.0]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.1.0 [v2.1.0]: /../../releases/tag/v2.1.0
[workflows]: https://kubernetes-sigs.github.io/kustomize/guides [workflows]: docs/workflows.md

View File

@@ -6,6 +6,7 @@ package builtins
import ( import (
"sigs.k8s.io/kustomize/api/filters/annotations" "sigs.k8s.io/kustomize/api/filters/annotations"
"sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/transform"
"sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filtersutil" "sigs.k8s.io/kustomize/kyaml/filtersutil"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
@@ -15,6 +16,10 @@ import (
type AnnotationsTransformerPlugin struct { type AnnotationsTransformerPlugin struct {
Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"` Annotations map[string]string `json:"annotations,omitempty" yaml:"annotations,omitempty"`
FieldSpecs []types.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"` FieldSpecs []types.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
// YAMLSupport can be set to true to use the kyaml filter instead of the
// kunstruct transformer
YAMLSupport bool `json:"yamlSupport,omitempty" yaml:"yamlSupport,omitempty"`
} }
func (p *AnnotationsTransformerPlugin) Config( func (p *AnnotationsTransformerPlugin) Config(
@@ -25,16 +30,27 @@ func (p *AnnotationsTransformerPlugin) Config(
} }
func (p *AnnotationsTransformerPlugin) Transform(m resmap.ResMap) error { func (p *AnnotationsTransformerPlugin) Transform(m resmap.ResMap) error {
for _, r := range m.Resources() { if p.YAMLSupport {
err := filtersutil.ApplyToJSON(annotations.Filter{ for _, r := range m.Resources() {
Annotations: p.Annotations, err := filtersutil.ApplyToJSON(annotations.Filter{
FsSlice: p.FieldSpecs, Annotations: p.Annotations,
}, r) FsSlice: p.FieldSpecs,
}, r.Kunstructured)
if err != nil {
return err
}
}
return nil
} else {
t, err := transform.NewMapTransformer(
p.FieldSpecs,
p.Annotations,
)
if err != nil { if err != nil {
return err return err
} }
return t.Transform(m)
} }
return nil
} }
func NewAnnotationsTransformerPlugin() resmap.TransformerPlugin { func NewAnnotationsTransformerPlugin() resmap.TransformerPlugin {

View File

@@ -0,0 +1,125 @@
// Code generated by pluginator on InventoryTransformer; DO NOT EDIT.
// pluginator {unknown 1970-01-01T00:00:00Z }
package builtins
import (
"fmt"
"sigs.k8s.io/kustomize/api/hasher"
"sigs.k8s.io/kustomize/api/inventory"
"sigs.k8s.io/kustomize/api/kv"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/yaml"
)
type InventoryTransformerPlugin struct {
h *resmap.PluginHelpers
types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
Policy string `json:"policy,omitempty" yaml:"policy,omitempty"`
}
func (p *InventoryTransformerPlugin) Config(
h *resmap.PluginHelpers, c []byte) (err error) {
p.h = h
err = yaml.Unmarshal(c, p)
if err != nil {
return err
}
if p.Policy == "" {
p.Policy = types.GarbageIgnore.String()
}
if p.Policy != types.GarbageCollect.String() &&
p.Policy != types.GarbageIgnore.String() {
return fmt.Errorf(
"unrecognized garbagePolicy '%s'", p.Policy)
}
return nil
}
// Transform generates an inventory object from the input ResMap.
// This ConfigMap supports the pruning command in
// the client side tool proposed here:
// https://github.com/kubernetes/enhancements/pull/810
//
// The inventory data is written to the ConfigMap's
// annotations, rather than to the key-value pairs in
// the ConfigMap's data field, since
// 1. Keys in a ConfigMap's data field are too
// constrained for this purpose.
// 2. Using annotations allow any object to be used,
// not just a ConfigMap, should some other object
// (e.g. some App object) become more desirable
// for this purpose.
func (p *InventoryTransformerPlugin) Transform(m resmap.ResMap) error {
inv, h, err := makeInventory(m)
if err != nil {
return err
}
args := types.ConfigMapArgs{}
args.Name = p.Name
args.Namespace = p.Namespace
args.Options = &types.GeneratorOptions{
Annotations: map[string]string{inventory.HashAnnotation: h},
}
err = inv.UpdateAnnotations(args.Options.Annotations)
if err != nil {
return err
}
cm, err := p.h.ResmapFactory().RF().MakeConfigMap(
kv.NewLoader(p.h.Loader(), p.h.Validator()), &args)
if err != nil {
return err
}
if p.Policy == types.GarbageCollect.String() {
for _, byeBye := range m.AllIds() {
m.Remove(byeBye)
}
}
return m.Append(cm)
}
func makeInventory(m resmap.ResMap) (
inv *inventory.Inventory, hash string, err error) {
inv = inventory.NewInventory()
var keys []string
for _, r := range m.Resources() {
ns := r.GetNamespace()
item := resid.NewResIdWithNamespace(r.GetGvk(), r.GetName(), ns)
if _, ok := inv.Current[item]; ok {
return nil, "", fmt.Errorf(
"item '%v' already in inventory", item)
}
inv.Current[item], err = computeRefs(r, m)
if err != nil {
return nil, "", err
}
keys = append(keys, item.String())
}
h, err := hasher.SortArrayAndComputeHash(keys)
return inv, h, err
}
func computeRefs(
r *resource.Resource, m resmap.ResMap) (refs []resid.ResId, err error) {
for _, refid := range r.GetRefBy() {
ref, err := m.GetByCurrentId(refid)
if err != nil {
return nil, err
}
refs = append(
refs,
resid.NewResIdWithNamespace(
ref.GetGvk(), ref.GetName(), ref.GetNamespace()))
}
return
}
func NewInventoryTransformerPlugin() resmap.TransformerPlugin {
return &InventoryTransformerPlugin{}
}

View File

@@ -4,10 +4,9 @@
package builtins package builtins
import ( import (
"sigs.k8s.io/kustomize/api/filters/labels"
"sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/transform"
"sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filtersutil"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
) )
@@ -25,16 +24,14 @@ func (p *LabelTransformerPlugin) Config(
} }
func (p *LabelTransformerPlugin) Transform(m resmap.ResMap) error { func (p *LabelTransformerPlugin) Transform(m resmap.ResMap) error {
for _, r := range m.Resources() { t, err := transform.NewMapTransformer(
err := filtersutil.ApplyToJSON(labels.Filter{ p.FieldSpecs,
Labels: p.Labels, p.Labels,
FsSlice: p.FieldSpecs, )
}, r) if err != nil {
if err != nil { return err
return err
}
} }
return nil return t.Transform(m)
} }
func NewLabelTransformerPlugin() resmap.TransformerPlugin { func NewLabelTransformerPlugin() resmap.TransformerPlugin {

View File

@@ -10,6 +10,7 @@ import (
"sigs.k8s.io/kustomize/api/resid" "sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource" "sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/transform"
"sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filtersutil" "sigs.k8s.io/kustomize/kyaml/filtersutil"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
@@ -19,6 +20,11 @@ import (
type NamespaceTransformerPlugin struct { type NamespaceTransformerPlugin struct {
types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
FieldSpecs []types.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"` FieldSpecs []types.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
// YAMLSupport can be set to true to use the kyaml filter instead of the
// kunstruct transformer.
// TODO: change the default to use kyaml when it is stable
YAMLSupport bool `json:"yamlSupport,omitempty" yaml:"yamlSupport,omitempty"`
} }
func (p *NamespaceTransformerPlugin) Config( func (p *NamespaceTransformerPlugin) Config(
@@ -37,22 +43,42 @@ func (p *NamespaceTransformerPlugin) Transform(m resmap.ResMap) error {
// Don't mutate empty objects? // Don't mutate empty objects?
continue continue
} }
err := filtersutil.ApplyToJSON(namespace.Filter{
Namespace: p.Namespace, id := r.OrgId()
FsSlice: p.FieldSpecs,
}, r) if !p.YAMLSupport {
if err != nil { // use the old style transform
return err applicableFs := p.applicableFieldSpecs(id)
for _, fs := range applicableFs {
err := transform.MutateField(
r.Map(), fs.PathSlice(), fs.CreateIfNotPresent,
p.changeNamespace(r))
if err != nil {
return err
}
}
} else {
// use the new style transform
err := filtersutil.ApplyToJSON(namespace.Filter{
Namespace: p.Namespace,
FsSlice: p.FieldSpecs,
}, r.Kunstructured)
if err != nil {
return err
}
} }
matches := m.GetMatchingResourcesByCurrentId(r.CurId().Equals) matches := m.GetMatchingResourcesByCurrentId(r.CurId().Equals)
if len(matches) != 1 { if len(matches) != 1 {
return fmt.Errorf( return fmt.Errorf("namespace transformation produces ID conflict: %+v", matches)
"namespace transformation produces ID conflict: %+v", matches)
} }
} }
return nil return nil
} }
const metaNamespace = "metadata/namespace"
// Special casing metadata.namespace since // Special casing metadata.namespace since
// all objects have it, even "ClusterKind" objects // all objects have it, even "ClusterKind" objects
// that don't exist in a namespace (the Namespace // that don't exist in a namespace (the Namespace
@@ -60,9 +86,7 @@ func (p *NamespaceTransformerPlugin) Transform(m resmap.ResMap) error {
func (p *NamespaceTransformerPlugin) applicableFieldSpecs(id resid.ResId) []types.FieldSpec { func (p *NamespaceTransformerPlugin) applicableFieldSpecs(id resid.ResId) []types.FieldSpec {
var res []types.FieldSpec var res []types.FieldSpec
for _, fs := range p.FieldSpecs { for _, fs := range p.FieldSpecs {
if id.IsSelected(&fs.Gvk) && if id.IsSelected(&fs.Gvk) && (fs.Path != metaNamespace || (fs.Path == metaNamespace && id.IsNamespaceableKind())) {
(fs.Path != types.MetadataNamespacePath ||
(fs.Path == types.MetadataNamespacePath && id.IsNamespaceableKind())) {
res = append(res, fs) res = append(res, fs)
} }
} }

View File

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

View File

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

View File

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

View File

@@ -1,142 +0,0 @@
// Code generated by pluginator on ValueAddTransformer; DO NOT EDIT.
// pluginator {unknown 1970-01-01T00:00:00Z }
package builtins
import (
"fmt"
"path/filepath"
"strings"
"sigs.k8s.io/kustomize/api/filters/namespace"
"sigs.k8s.io/kustomize/api/filters/valueadd"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/filtersutil"
"sigs.k8s.io/yaml"
)
// An 'Add' transformer inspired by the IETF RFC 6902 JSON spec Add operation.
type ValueAddTransformerPlugin struct {
// Value is the value to add.
// Defaults to base name of encompassing kustomization root.
Value string `json:"value,omitempty" yaml:"value,omitempty"`
// Targets is a slice of targets that should have the value added.
Targets []Target `json:"targets,omitempty" yaml:"targets,omitempty"`
// TargetFilePath is a file path. If specified, the file will be parsed into
// a slice of Target, and appended to anything that was specified in the
// Targets field. This is just a means to share common target specifications.
TargetFilePath string `json:"targetFilePath,omitempty" yaml:"targetFilePath,omitempty"`
}
// Target describes where to put the value.
type Target struct {
// Selector selects the resources to modify.
Selector *types.Selector `json:"selector,omitempty" yaml:"selector,omitempty"`
// NotSelector selects the resources to exclude
// from those included by overly broad selectors.
// TODO: implement this?
// NotSelector *types.Selector `json:"notSelector,omitempty" yaml:"notSelector,omitempty"`
// FieldPath is a JSON-style path to the field intended to hold the value.
FieldPath string `json:"fieldPath,omitempty" yaml:"fieldPath,omitempty"`
// FilePathPosition is passed to the filter directly. Look there for doc.
FilePathPosition int `json:"filePathPosition,omitempty" yaml:"filePathPosition,omitempty"`
}
func (p *ValueAddTransformerPlugin) Config(h *resmap.PluginHelpers, c []byte) error {
err := yaml.Unmarshal(c, p)
if err != nil {
return err
}
p.Value = strings.TrimSpace(p.Value)
if p.Value == "" {
p.Value = filepath.Base(h.Loader().Root())
}
if p.TargetFilePath != "" {
bytes, err := h.Loader().Load(p.TargetFilePath)
if err != nil {
return err
}
var targets struct {
Targets []Target `json:"targets,omitempty" yaml:"targets,omitempty"`
}
err = yaml.Unmarshal(bytes, &targets)
if err != nil {
return err
}
p.Targets = append(p.Targets, targets.Targets...)
}
if len(p.Targets) == 0 {
return fmt.Errorf("must specify at least one target")
}
for _, target := range p.Targets {
if err = validateSelector(target.Selector); err != nil {
return err
}
// TODO: call validateSelector(target.NotSelector) if field added.
if err = validateJsonFieldPath(target.FieldPath); err != nil {
return err
}
if target.FilePathPosition < 0 {
return fmt.Errorf(
"value of FilePathPosition (%d) cannot be negative",
target.FilePathPosition)
}
}
return nil
}
// TODO: implement
func validateSelector(_ *types.Selector) error {
return nil
}
// TODO: Enforce RFC 6902?
func validateJsonFieldPath(p string) error {
if len(p) == 0 {
return fmt.Errorf("fieldPath cannot be empty")
}
return nil
}
func (p *ValueAddTransformerPlugin) Transform(m resmap.ResMap) (err error) {
for _, t := range p.Targets {
var resources []*resource.Resource
if t.Selector == nil {
resources = m.Resources()
} else {
resources, err = m.Select(*t.Selector)
if err != nil {
return err
}
}
// TODO: consider t.NotSelector if implemented
for _, res := range resources {
if t.FieldPath == types.MetadataNamespacePath {
err = filtersutil.ApplyToJSON(namespace.Filter{
Namespace: p.Value,
}, res)
} else {
err = filtersutil.ApplyToJSON(valueadd.Filter{
Value: p.Value,
FieldPath: t.FieldPath,
FilePathPosition: t.FilePathPosition,
}, res)
}
if err != nil {
return err
}
}
}
return nil
}
func NewValueAddTransformerPlugin() resmap.TransformerPlugin {
return &ValueAddTransformerPlugin{}
}

View File

@@ -3,11 +3,7 @@
package filesys package filesys
import ( import "path/filepath"
"os"
"path/filepath"
"strings"
)
// RootedPath returns a rooted path, e.g. "/foo/bar" as // RootedPath returns a rooted path, e.g. "/foo/bar" as
// opposed to "foo/bar". // opposed to "foo/bar".
@@ -32,94 +28,3 @@ func StripLeadingSeps(s string) string {
} }
return s[k:] return s[k:]
} }
// PathSplit converts a file path to a slice of string.
// If the path is absolute (if the path has a leading slash),
// then the first entry in the result is an empty string.
// Desired: path == PathJoin(PathSplit(path))
func PathSplit(incoming string) []string {
if incoming == "" {
return []string{}
}
dir, path := filepath.Split(incoming)
if dir == string(os.PathSeparator) {
if path == "" {
return []string{""}
}
return []string{"", path}
}
dir = strings.TrimSuffix(dir, string(os.PathSeparator))
if dir == "" {
return []string{path}
}
return append(PathSplit(dir), path)
}
// PathJoin converts a slice of string to a file path.
// If the first entry is an empty string, then the returned
// path is absolute (it has a leading slash).
// Desired: path == PathJoin(PathSplit(path))
func PathJoin(incoming []string) string {
if len(incoming) == 0 {
return ""
}
if incoming[0] == "" {
return string(os.PathSeparator) + filepath.Join(incoming[1:]...)
}
return filepath.Join(incoming...)
}
// InsertPathPart inserts 'part' at position 'pos' in the given filepath.
// The first position is 0.
//
// E.g. if part == 'PEACH'
//
// OLD : NEW : POS
// --------------------------------------------------------
// {empty} : PEACH : irrelevant
// / : /PEACH : irrelevant
// pie : PEACH/pie : 0 (or negative)
// /pie : /PEACH/pie : 0 (or negative)
// raw : raw/PEACH : 1 (or larger)
// /raw : /raw/PEACH : 1 (or larger)
// a/nice/warm/pie : a/nice/warm/PEACH/pie : 3
// /a/nice/warm/pie : /a/nice/warm/PEACH/pie : 3
//
// * An empty part results in no change.
//
// * Absolute paths get their leading '/' stripped, treated like
// relative paths, and the leading '/' is re-added on output.
// The meaning of pos is intentionally the same in either absolute or
// relative paths; if it weren't, this function could convert absolute
// paths to relative paths, which is not desirable.
//
// * For robustness (liberal input, conservative output) Pos values that
// that are too small (large) to index the split filepath result in a
// prefix (postfix) rather than an error. Use extreme position values
// to assure a prefix or postfix (e.g. 0 will always prefix, and
// 9999 will presumably always postfix).
func InsertPathPart(path string, pos int, part string) string {
if part == "" {
return path
}
parts := PathSplit(path)
if pos < 0 {
pos = 0
} else if pos > len(parts) {
pos = len(parts)
}
if len(parts) > 0 && parts[0] == "" && pos < len(parts) {
// An empty string at 0 indicates an absolute path, and means
// we must increment pos. This change means that a position
// specification has the same meaning in relative and absolute paths.
// E.g. in either the path 'a/b/c' or the path '/a/b/c',
// 'a' is at 0, 'b' is at 1 and 'c' is at 2, and inserting at
// zero means a new first field _without_ changing an absolute
// path to a relative path.
pos++
}
result := make([]string, len(parts)+1)
copy(result, parts[0:pos])
result[pos] = part
return PathJoin(append(result, parts[pos:]...))
}

View File

@@ -1,7 +1,6 @@
package filesys_test package filesys_test
import ( import (
"os"
"path/filepath" "path/filepath"
"testing" "testing"
@@ -94,11 +93,6 @@ func TestFilePathSplit(t *testing.T) {
dir: "", dir: "",
file: "rabbit.jpg", file: "rabbit.jpg",
}, },
{
full: "/",
dir: "/",
file: "",
},
{ {
full: "/beans", full: "/beans",
dir: "/", dir: "/",
@@ -130,169 +124,6 @@ func TestFilePathSplit(t *testing.T) {
} }
} }
func TestPathSplitAndJoin(t *testing.T) {
cases := map[string]struct {
original string
expected []string
}{
"Empty": {
original: "",
expected: []string{},
},
"One": {
original: "hello",
expected: []string{"hello"},
},
"Two": {
original: "hello/there",
expected: []string{"hello", "there"},
},
"Three": {
original: "hello/my/friend",
expected: []string{"hello", "my", "friend"},
},
}
for n, c := range cases {
f := func(t *testing.T, original string, expected []string) {
actual := PathSplit(original)
if len(actual) != len(expected) {
t.Fatalf(
"expected len %d, got len %d",
len(expected), len(actual))
}
for i := range expected {
if expected[i] != actual[i] {
t.Fatalf(
"at i=%d, expected '%s', got '%s'",
i, expected[i], actual[i])
}
}
joined := PathJoin(actual)
if joined != original {
t.Fatalf(
"when rejoining, expected '%s', got '%s'",
original, joined)
}
}
t.Run("relative"+n, func(t *testing.T) {
f(t, c.original, c.expected)
})
t.Run("absolute"+n, func(t *testing.T) {
f(t,
string(os.PathSeparator)+c.original,
append([]string{""}, c.expected...))
})
}
}
func TestInsertPathPart(t *testing.T) {
cases := map[string]struct {
original string
pos int
part string
expected string
}{
"rootOne": {
original: "/",
pos: 0,
part: "___",
expected: "/___",
},
"rootTwo": {
original: "/",
pos: 444,
part: "___",
expected: "/___",
},
"rootedFirst": {
original: "/apple",
pos: 0,
part: "___",
expected: "/___/apple",
},
"rootedSecond": {
original: "/apple",
pos: 444,
part: "___",
expected: "/apple/___",
},
"rootedThird": {
original: "/apple/banana",
pos: 444,
part: "___",
expected: "/apple/banana/___",
},
"emptyLow": {
original: "",
pos: -3,
part: "___",
expected: "___",
},
"emptyHigh": {
original: "",
pos: 444,
part: "___",
expected: "___",
},
"peachPie": {
original: "a/nice/warm/pie",
pos: 3,
part: "PEACH",
expected: "a/nice/warm/PEACH/pie",
},
"rootedPeachPie": {
original: "/a/nice/warm/pie",
pos: 3,
part: "PEACH",
expected: "/a/nice/warm/PEACH/pie",
},
"longStart": {
original: "a/b/c/d/e/f",
pos: 0,
part: "___",
expected: "___/a/b/c/d/e/f",
},
"rootedLongStart": {
original: "/a/b/c/d/e/f",
pos: 0,
part: "___",
expected: "/___/a/b/c/d/e/f",
},
"longMiddle": {
original: "a/b/c/d/e/f",
pos: 3,
part: "___",
expected: "a/b/c/___/d/e/f",
},
"rootedLongMiddle": {
original: "/a/b/c/d/e/f",
pos: 3,
part: "___",
expected: "/a/b/c/___/d/e/f",
},
"longEnd": {
original: "a/b/c/d/e/f",
pos: 444,
part: "___",
expected: "a/b/c/d/e/f/___",
},
"rootedLongEnd": {
original: "/a/b/c/d/e/f",
pos: 444,
part: "___",
expected: "/a/b/c/d/e/f/___",
},
}
for n, c := range cases {
t.Run(n, func(t *testing.T) {
actual := InsertPathPart(c.original, c.pos, c.part)
if actual != c.expected {
t.Fatalf("expected '%s', got '%s'", c.expected, actual)
}
})
}
}
func TestStripTrailingSeps(t *testing.T) { func TestStripTrailingSeps(t *testing.T) {
cases := []struct { cases := []struct {
full string full string

View File

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

View File

@@ -123,93 +123,6 @@ a:
}, },
}, },
}, },
"number": {
input: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
annotations:
hero: batman
fiend: riddler
`,
expectedOutput: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
annotations:
hero: batman
fiend: riddler
2: ford
clown: "1"
`,
filter: Filter{Annotations: annoMap{
"clown": "1",
"2": "ford",
}},
},
// test quoting of values which are not considered strings in yaml 1.1
"yaml_1_1_compatibility": {
input: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
annotations:
hero: batman
fiend: riddler
`,
expectedOutput: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
annotations:
hero: batman
fiend: riddler
a: "y"
b: y1
c: "yes"
d: yes1
e: "true"
f: true1
`,
filter: Filter{Annotations: annoMap{
"a": "y",
"b": "y1",
"c": "yes",
"d": "yes1",
"e": "true",
"f": "true1",
}},
},
// test quoting of values which are not considered strings in yaml 1.1
"null_annotations": {
input: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
annotations: null
`,
expectedOutput: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
annotations:
a: a1
b: b1
`,
filter: Filter{Annotations: annoMap{
"a": "a1",
"b": "b1",
}},
},
} }
for tn, tc := range testCases { for tn, tc := range testCases {

View File

@@ -23,8 +23,6 @@ type fieldSpecFilter struct {
// CreateKind defines the type of node to create if the field is not found // CreateKind defines the type of node to create if the field is not found
CreateKind yaml.Kind CreateKind yaml.Kind
CreateTag string
// path keeps internal state about the current path // path keeps internal state about the current path
path []string path []string
} }
@@ -65,8 +63,6 @@ func (fltr fieldSpecFilter) field(obj *yaml.RNode) error {
// lookup the field matching the next path element // lookup the field matching the next path element
var lookupField yaml.Filter var lookupField yaml.Filter
var kind yaml.Kind
var tag string
switch { switch {
case !fltr.FieldSpec.CreateIfNotPresent || fltr.CreateKind == 0 || isSeq: case !fltr.FieldSpec.CreateIfNotPresent || fltr.CreateKind == 0 || isSeq:
// dont' create the field if we don't find it // dont' create the field if we don't find it
@@ -74,13 +70,9 @@ func (fltr fieldSpecFilter) field(obj *yaml.RNode) error {
case len(fltr.path) <= 1: case len(fltr.path) <= 1:
// create the field if it is missing: use the provided node kind // create the field if it is missing: use the provided node kind
lookupField = yaml.LookupCreate(fltr.CreateKind, fieldName) lookupField = yaml.LookupCreate(fltr.CreateKind, fieldName)
kind = fltr.CreateKind
tag = fltr.CreateTag
default: default:
// create the field if it is missing: must be a mapping node // create the field if it is missing: must be a mapping node
lookupField = yaml.LookupCreate(yaml.MappingNode, fieldName) lookupField = yaml.LookupCreate(yaml.MappingNode, fieldName)
kind = yaml.MappingNode
tag = "!!map"
} }
// locate (or maybe create) the field // locate (or maybe create) the field
@@ -89,13 +81,6 @@ func (fltr fieldSpecFilter) field(obj *yaml.RNode) error {
return errors.WrapPrefixf(err, "fieldName: %s", fieldName) return errors.WrapPrefixf(err, "fieldName: %s", fieldName)
} }
// if the value exists, but is null, then change it to the creation type
// TODO: update yaml.LookupCreate to support this
if field.YNode().Tag == "!!null" {
field.YNode().Kind = kind
field.YNode().Tag = tag
}
// copy the current fltr and change the path on the copy // copy the current fltr and change the path on the copy
var next = fltr var next = fltr
// call filter for the next path element on the matching field // call filter for the next path element on the matching field
@@ -139,7 +124,12 @@ func isMatchGVK(fs types.FieldSpec, obj *yaml.RNode) (bool, error) {
} }
// parse the group and version from the apiVersion field // parse the group and version from the apiVersion field
group, version := parseGV(meta.APIVersion) var group, version string
parts := strings.SplitN(meta.APIVersion, "/", 2)
group = parts[0]
if len(parts) > 1 {
version = parts[1]
}
if fs.Group != "" && fs.Group != group { if fs.Group != "" && fs.Group != group {
// group doesn't match // group doesn't match

View File

@@ -4,6 +4,9 @@
package fsslice package fsslice
import ( import (
"strings"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/yaml" "sigs.k8s.io/kustomize/kyaml/yaml"
) )
@@ -19,22 +22,11 @@ func SetScalar(value string) SetFn {
} }
// SetEntry returns a SetFn to set an entry in a map // SetEntry returns a SetFn to set an entry in a map
func SetEntry(key, value, tag string) SetFn { func SetEntry(key, value string) SetFn {
n := &yaml.Node{
Kind: yaml.ScalarNode,
Value: value,
Tag: tag,
}
if tag == yaml.StringTag && yaml.IsYaml1_1NonString(n) {
n.Style = yaml.DoubleQuotedStyle
}
return func(node *yaml.RNode) error { return func(node *yaml.RNode) error {
return node.PipeE(yaml.FieldSetter{ return node.PipeE(yaml.FieldSetter{
Name: key, Name: key, StringValue: value})
Value: yaml.NewRNode(n),
})
} }
} }
var _ yaml.Filter = Filter{} var _ yaml.Filter = Filter{}
@@ -49,9 +41,6 @@ type Filter struct {
// CreateKind is used to create fields that do not exist // CreateKind is used to create fields that do not exist
CreateKind yaml.Kind CreateKind yaml.Kind
// CreateTag is used to set the tag if encountering a null field
CreateTag string
} }
func (fltr Filter) Filter(obj *yaml.RNode) (*yaml.RNode, error) { func (fltr Filter) Filter(obj *yaml.RNode) (*yaml.RNode, error) {
@@ -63,7 +52,6 @@ func (fltr Filter) Filter(obj *yaml.RNode) (*yaml.RNode, error) {
FieldSpec: fltr.FsSlice[i], FieldSpec: fltr.FsSlice[i],
SetValue: fltr.SetValue, SetValue: fltr.SetValue,
CreateKind: fltr.CreateKind, CreateKind: fltr.CreateKind,
CreateTag: fltr.CreateTag,
}).Filter(obj) }).Filter(obj)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -71,3 +59,20 @@ func (fltr Filter) Filter(obj *yaml.RNode) (*yaml.RNode, error) {
} }
return obj, nil return obj, nil
} }
// GetGVK parses the metadata into a GVK
func GetGVK(meta yaml.ResourceMeta) resid.Gvk {
// parse the group and version from the apiVersion field
var group, version string
parts := strings.SplitN(meta.APIVersion, "/", 2)
group = parts[0]
if len(parts) > 1 {
version = parts[1]
}
return resid.Gvk{
Group: group,
Version: version,
Kind: meta.Kind,
}
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/filters/fsslice" "sigs.k8s.io/kustomize/api/filters/fsslice"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml" "sigs.k8s.io/kustomize/kyaml/yaml"
) )
@@ -280,52 +281,6 @@ kind: Bar
a: a:
b: b:
- c: {d: e} - c: {d: e}
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
{
name: "group v1",
fsSlice: `
- path: a/b
group: v1
create: true
kind: Bar
`,
input: `
apiVersion: v1
kind: Bar
`,
expected: `
apiVersion: v1
kind: Bar
`,
filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"),
CreateKind: yaml.ScalarNode,
},
},
{
name: "version v1",
fsSlice: `
- path: a/b
version: v1
create: true
kind: Bar
`,
input: `
apiVersion: v1
kind: Bar
`,
expected: `
apiVersion: v1
kind: Bar
a:
b: e
`, `,
filter: fsslice.Filter{ filter: fsslice.Filter{
SetValue: fsslice.SetScalar("e"), SetValue: fsslice.SetScalar("e"),
@@ -377,3 +332,23 @@ func TestFilter_Filter(t *testing.T) {
}) })
} }
} }
func TestGetGVK(t *testing.T) {
obj, err := yaml.Parse(`
apiVersion: apps/v1
kind: Deployment
`)
if !assert.NoError(t, err) {
t.FailNow()
}
meta, err := obj.GetMeta()
if !assert.NoError(t, err) {
t.FailNow()
}
gvk := fsslice.GetGVK(meta)
expected := resid.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"}
if !assert.Equal(t, expected, gvk) {
t.FailNow()
}
}

View File

@@ -1,49 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package fsslice
import (
"strings"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// Return true for 'v' followed by a 1 or 2, and don't look at rest.
// I.e. 'v1', 'v1beta1', 'v2', would return true.
func looksLikeACoreApiVersion(s string) bool {
if len(s) < 2 {
return false
}
if s[0:1] != "v" {
return false
}
return s[1:2] == "1" || s[1:2] == "2"
}
// parseGV parses apiVersion field into group and version.
func parseGV(apiVersion string) (group, version string) {
// parse the group and version from the apiVersion field
parts := strings.SplitN(apiVersion, "/", 2)
group = parts[0]
if len(parts) > 1 {
version = parts[1]
}
// Special case the original "apiVersion" of what
// we now call the "core" (empty) group.
if version == "" && looksLikeACoreApiVersion(group) {
version = group
group = ""
}
return
}
// GetGVK parses the metadata into a GVK
func GetGVK(meta yaml.ResourceMeta) resid.Gvk {
group, version := parseGV(meta.APIVersion)
return resid.Gvk{
Group: group,
Version: version,
Kind: meta.Kind,
}
}

View File

@@ -1,156 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package fsslice
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
func TestParseGV(t *testing.T) {
testCases := map[string]struct {
input string
expectedGroup string
expectedVersion string
}{
"empty": {
input: "",
expectedGroup: "",
expectedVersion: "",
},
"certSigning": {
input: "certificates.k8s.io/v1beta1",
expectedGroup: "certificates.k8s.io",
expectedVersion: "v1beta1",
},
"extensions": {
input: "extensions/v1beta1",
expectedGroup: "extensions",
expectedVersion: "v1beta1",
},
"normal": {
input: "apps/v1",
expectedGroup: "apps",
expectedVersion: "v1",
},
"justApps": {
input: "apps",
expectedGroup: "apps",
expectedVersion: "",
},
"coreV1": {
input: "v1",
expectedGroup: "",
expectedVersion: "v1",
},
"coreV2": {
input: "v2",
expectedGroup: "",
expectedVersion: "v2",
},
"coreV2Beta1": {
input: "v2beta1",
expectedGroup: "",
expectedVersion: "v2beta1",
},
}
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
group, version := parseGV(tc.input)
if !assert.Equal(t, tc.expectedGroup, group) {
t.FailNow()
}
if !assert.Equal(t, tc.expectedVersion, version) {
t.FailNow()
}
})
}
}
func TestGetGVK(t *testing.T) {
testCases := map[string]struct {
input string
expected resid.Gvk
parseError string
metaError string
}{
"empty": {
input: `
`,
parseError: "EOF",
},
"junk": {
input: `
congress: effective
`,
metaError: "missing Resource metadata",
},
"normal": {
input: `
apiVersion: apps/v1
kind: Deployment
`,
expected: resid.Gvk{Group: "apps", Version: "v1", Kind: "Deployment"},
},
"apiVersionOnlyWithSlash": {
input: `
apiVersion: apps/v1
`,
expected: resid.Gvk{Group: "apps", Version: "v1", Kind: ""},
},
"apiVersionOnlyNoSlash1": {
input: `
apiVersion: apps
`,
expected: resid.Gvk{Group: "apps", Version: "", Kind: ""},
},
"apiVersionOnlyNoSlash2": {
input: `
apiVersion: v1
`,
expected: resid.Gvk{Group: "", Version: "v1", Kind: ""},
},
}
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
obj, err := yaml.Parse(tc.input)
if len(tc.parseError) != 0 {
if err == nil {
t.Error("expected parse error")
return
}
if !strings.Contains(err.Error(), tc.parseError) {
t.Errorf("expected parse err '%s', got '%v'", tc.parseError, err)
}
return
}
if !assert.NoError(t, err) {
t.FailNow()
}
meta, err := obj.GetMeta()
if len(tc.metaError) != 0 {
if err == nil {
t.Error("expected meta error")
return
}
if !strings.Contains(err.Error(), tc.metaError) {
t.Errorf("expected meta err '%s', got '%v'", tc.metaError, err)
}
return
}
if !assert.NoError(t, err) {
t.FailNow()
}
gvk := GetGVK(meta)
if !assert.Equal(t, tc.expected, gvk) {
t.FailNow()
}
})
}
}

View File

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

View File

@@ -8,16 +8,19 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/api/resid" "sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
filtertest_test "sigs.k8s.io/kustomize/api/testutils/filtertest" filtertest_test "sigs.k8s.io/kustomize/api/testutils/filtertest"
"sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/api/types"
) )
var labelsFs = builtinconfig.MakeDefaultConfig().CommonLabels
func TestLabels_Filter(t *testing.T) { func TestLabels_Filter(t *testing.T) {
testCases := map[string]struct { testCases := map[string]struct {
input string input string
expectedOutput string expectedOutput string
filter Filter filter Filter
fsSlice types.FsSlice
}{ }{
"add": { "add": {
input: ` input: `
@@ -42,20 +45,12 @@ metadata:
clown: emmett kelley clown: emmett kelley
dragon: smaug dragon: smaug
`, `,
filter: Filter{ filter: Filter{Labels: labelMap{
Labels: labelMap{ "clown": "emmett kelley",
"clown": "emmett kelley", "auto": "ford",
"auto": "ford", "dragon": "smaug",
"dragon": "smaug", "bean": "cannellini",
"bean": "cannellini", }},
},
FsSlice: []types.FieldSpec{
{
Path: "metadata/labels",
CreateIfNotPresent: true,
},
},
},
}, },
"update": { "update": {
input: ` input: `
@@ -78,21 +73,13 @@ metadata:
bean: cannellini bean: cannellini
clown: emmett kelley clown: emmett kelley
`, `,
filter: Filter{ filter: Filter{Labels: labelMap{
Labels: labelMap{ "clown": "emmett kelley",
"clown": "emmett kelley", "hero": "superman",
"hero": "superman", "fiend": "luthor",
"fiend": "luthor", "bean": "cannellini",
"bean": "cannellini", }},
}, FsSlice: []types.FieldSpec{
{
Path: "metadata/labels",
CreateIfNotPresent: true,
},
},
},
}, },
"data-fieldspecs": { "data-fieldspecs": {
input: ` input: `
apiVersion: example.com/v1 apiVersion: example.com/v1
@@ -126,276 +113,13 @@ a:
b: b:
sleater: kinney sleater: kinney
`, `,
filter: Filter{ filter: Filter{Labels: labelMap{
Labels: labelMap{ "sleater": "kinney",
"sleater": "kinney", }},
}, fsSlice: []types.FieldSpec{
FsSlice: []types.FieldSpec{ {
{ Path: "a/b",
Path: "metadata/labels", CreateIfNotPresent: true,
CreateIfNotPresent: true,
},
{
Path: "a/b",
CreateIfNotPresent: true,
},
},
},
},
"fieldSpecWithKind": {
input: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
---
apiVersion: example.com/v2
kind: Bar
metadata:
name: instance
`,
expectedOutput: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
labels:
cheese: cheddar
---
apiVersion: example.com/v2
kind: Bar
metadata:
name: instance
labels:
cheese: cheddar
a:
b:
cheese: cheddar
`,
filter: Filter{
Labels: labelMap{
"cheese": "cheddar",
},
FsSlice: []types.FieldSpec{
{
Path: "metadata/labels",
CreateIfNotPresent: true,
},
{
Gvk: resid.Gvk{
Kind: "Bar",
},
Path: "a/b",
CreateIfNotPresent: true,
},
},
},
},
"fieldSpecWithVersion": {
input: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
---
apiVersion: example.com/v2
kind: Bar
metadata:
name: instance
`,
expectedOutput: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
labels:
cheese: cheddar
a:
b:
cheese: cheddar
---
apiVersion: example.com/v2
kind: Bar
metadata:
name: instance
labels:
cheese: cheddar
`,
filter: Filter{
Labels: labelMap{
"cheese": "cheddar",
},
FsSlice: []types.FieldSpec{
{
Path: "metadata/labels",
CreateIfNotPresent: true,
},
{
Gvk: resid.Gvk{
Version: "v1",
},
Path: "a/b",
CreateIfNotPresent: true,
},
},
},
},
"fieldSpecWithVersionInConfigButNoGroupInData": {
input: `
apiVersion: v1
kind: Foo
metadata:
name: instance
---
apiVersion: v2
kind: Bar
metadata:
name: instance
`,
expectedOutput: `
apiVersion: v1
kind: Foo
metadata:
name: instance
labels:
cheese: cheddar
a:
b:
cheese: cheddar
---
apiVersion: v2
kind: Bar
metadata:
name: instance
labels:
cheese: cheddar
`,
filter: Filter{
Labels: labelMap{
"cheese": "cheddar",
},
FsSlice: []types.FieldSpec{
{
Path: "metadata/labels",
CreateIfNotPresent: true,
},
{
Gvk: resid.Gvk{
Version: "v1",
},
Path: "a/b",
CreateIfNotPresent: true,
},
},
},
},
"number": {
input: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
labels:
hero: batman
fiend: riddler
`,
expectedOutput: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
labels:
hero: batman
fiend: riddler
1: emmett kelley
auto: "2"
`,
filter: Filter{
Labels: labelMap{
"1": "emmett kelley",
"auto": "2",
},
FsSlice: []types.FieldSpec{
{
Path: "metadata/labels",
CreateIfNotPresent: true,
},
},
},
},
// test quoting of values which are not considered strings in yaml 1.1
"yaml_1_1_compatibility": {
input: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
labels:
hero: batman
fiend: riddler
`,
expectedOutput: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
labels:
hero: batman
fiend: riddler
a: "y"
b: y1
c: "yes"
d: yes1
e: "true"
f: true1
`,
filter: Filter{
Labels: labelMap{
"a": "y",
"b": "y1",
"c": "yes",
"d": "yes1",
"e": "true",
"f": "true1",
},
FsSlice: []types.FieldSpec{
{
Path: "metadata/labels",
CreateIfNotPresent: true,
},
},
},
},
"null_labels": {
input: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
labels: null
`,
expectedOutput: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
labels:
a: a1
`,
filter: Filter{
Labels: labelMap{
"a": "a1",
},
FsSlice: []types.FieldSpec{
{
Path: "metadata/labels",
CreateIfNotPresent: true,
},
}, },
}, },
}, },
@@ -403,9 +127,11 @@ metadata:
for tn, tc := range testCases { for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) { t.Run(tn, func(t *testing.T) {
filter := tc.filter
filter.FsSlice = append(labelsFs, tc.fsSlice...)
if !assert.Equal(t, if !assert.Equal(t,
strings.TrimSpace(tc.expectedOutput), strings.TrimSpace(tc.expectedOutput),
strings.TrimSpace(filtertest_test.RunFilter(t, tc.input, tc.filter))) { strings.TrimSpace(filtertest_test.RunFilter(t, tc.input, filter))) {
t.FailNow() t.FailNow()
} }
}) })

View File

@@ -44,7 +44,6 @@ func (ns Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
FsSlice: ns.FsSlice, FsSlice: ns.FsSlice,
SetValue: fsslice.SetScalar(ns.Namespace), SetValue: fsslice.SetScalar(ns.Namespace),
CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode
CreateTag: yaml.StringTag,
}) })
return node, err return node, err
} }
@@ -79,7 +78,7 @@ func (ns Filter) metaNamespaceHack(obj *yaml.RNode, meta yaml.ResourceMeta) erro
} }
f := fsslice.Filter{ f := fsslice.Filter{
FsSlice: []types.FieldSpec{ FsSlice: []types.FieldSpec{
{Path: types.MetadataNamespacePath, CreateIfNotPresent: true}, {Path: metaNamespaceField, CreateIfNotPresent: true},
}, },
SetValue: fsslice.SetScalar(ns.Namespace), SetValue: fsslice.SetScalar(ns.Namespace),
CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode
@@ -144,7 +143,7 @@ func (ns Filter) removeFieldSpecsForHacks(fs types.FsSlice) types.FsSlice {
var val types.FsSlice var val types.FsSlice
for i := range fs { for i := range fs {
// implemented by metaNamespaceHack // implemented by metaNamespaceHack
if fs[i].Path == types.MetadataNamespacePath { if fs[i].Path == metaNamespaceField {
continue continue
} }
// implemented by roleBindingHack // implemented by roleBindingHack
@@ -161,6 +160,7 @@ func (ns Filter) removeFieldSpecsForHacks(fs types.FsSlice) types.FsSlice {
} }
const ( const (
metaNamespaceField = "metadata/namespace"
subjectsField = "subjects" subjectsField = "subjects"
roleBindingKind = "RoleBinding" roleBindingKind = "RoleBinding"
clusterRoleBindingKind = "ClusterRoleBinding" clusterRoleBindingKind = "ClusterRoleBinding"

View File

@@ -44,37 +44,6 @@ metadata:
filter: namespace.Filter{Namespace: "foo"}, filter: namespace.Filter{Namespace: "foo"},
}, },
{
name: "null_ns",
input: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
namespace: null
---
apiVersion: example.com/v1
kind: Bar
metadata:
name: instance
namespace: null
`,
expected: `
apiVersion: example.com/v1
kind: Foo
metadata:
name: instance
namespace: foo
---
apiVersion: example.com/v1
kind: Bar
metadata:
name: instance
namespace: foo
`,
filter: namespace.Filter{Namespace: "foo"},
},
{ {
name: "add-recurse", name: "add-recurse",
input: ` input: `

View File

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

View File

@@ -31,86 +31,6 @@ apiVersion: apps/v1
metadata: metadata:
name: yourDeploy name: yourDeploy
kind: Deployment kind: Deployment
`,
},
"container patch": {
input: `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
containers:
- name: foo1
- name: foo2
- name: foo3
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
containers:
- name: foo0
`),
expected: `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
containers:
- name: foo1
- name: foo2
- name: foo3
- name: foo0
`,
},
"volumes patch": {
input: `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
volumes:
- name: foo1
- name: foo2
- name: foo3
`,
patch: yaml.MustParse(`
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
volumes:
- name: foo0
`),
expected: `
apiVersion: apps/v1
metadata:
name: myDeploy
kind: Deployment
spec:
template:
spec:
volumes:
- name: foo1
- name: foo2
- name: foo3
- name: foo0
`, `,
}, },
"nested patch": { "nested patch": {

View File

@@ -33,7 +33,6 @@ func (ns Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
FsSlice: ns.FsSlice, FsSlice: ns.FsSlice,
SetValue: ns.set, SetValue: ns.set,
CreateKind: yaml.ScalarNode, // Name is a ScalarNode CreateKind: yaml.ScalarNode, // Name is a ScalarNode
CreateTag: yaml.StringTag,
}) })
return node, err return node, err
} }

View File

@@ -39,7 +39,6 @@ func (rc Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
FsSlice: rc.FsSlice, FsSlice: rc.FsSlice,
SetValue: rc.set, SetValue: rc.set,
CreateKind: yaml.ScalarNode, // replicas is a ScalarNode CreateKind: yaml.ScalarNode, // replicas is a ScalarNode
CreateTag: yaml.IntTag,
}) })
return node, err return node, err
} }

View File

@@ -61,41 +61,6 @@ spec:
expected: ` expected: `
apiVersion: custom/v1 apiVersion: custom/v1
kind: Custom kind: Custom
metadata:
name: cus
spec:
template:
other: something
replicas: 42
`,
filter: Filter{
Replica: types.Replica{
Name: "cus",
Count: 42,
},
},
fsslice: types.FsSlice{
{
Path: "spec/template/replicas",
CreateIfNotPresent: true,
},
},
},
"add_field_null": {
input: `
apiVersion: custom/v1
kind: Custom
metadata:
name: cus
spec:
template:
other: something
replicas: null
`,
expected: `
apiVersion: custom/v1
kind: Custom
metadata: metadata:
name: cus name: cus
spec: spec:

View File

@@ -1,124 +0,0 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package valueadd
import (
"strings"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// An 'Add' operation aspiring to IETF RFC 6902 JSON.
//
// The filter tries to add a value to a node at a particular field path.
//
// Kinds of target fields:
//
// - Non-existent target field.
//
// The field will be added and the value inserted.
//
// - Existing field, scalar or map.
//
// E.g. 'spec/template/spec/containers/[name:nginx]/image'
//
// This behaves like an IETF RFC 6902 Replace operation would;
// the existing value is replaced without complaint, even though
// this is an Add operation. In contrast, a Replace operation
// must fail (report an error) if the field doesn't exist.
//
// - Existing field, list (array)
// Not supported yet.
// TODO: Honor fields with RFC-6902-style array indices
// TODO: like 'spec/template/spec/containers/2'
// TODO: Modify kyaml/yaml/PathGetter to allow this.
// The value will be inserted into the array at the given position,
// shifting other contents. To instead replace an array entry, use
// an implementation of an IETF RFC 6902 Replace operation.
//
// For the common case of a filepath in the field value, and a desire
// to add the value to the filepath (rather than replace the filepath),
// use a non-zero value of FilePathPosition (see below).
type Filter struct {
// Value is the value to add.
//
// Empty values are disallowed, i.e. this filter isn't intended
// for use in erasing or removing fields. For that, use a filter
// more aligned with the IETF RFC 6902 JSON Remove operation.
//
// At the time of writing, Value's value should be a simple string,
// not a JSON document. This particular filter focuses on easing
// injection of a single-sourced cloud project and/or cluster name
// into various fields, especially namespace and various filepath
// specifications.
Value string
// FieldPath is a JSON-style path to the field intended to hold the value.
FieldPath string
// FilePathPosition is a filepath field index.
//
// Call the value of this field _i_.
//
// If _i_ is zero, negative or unspecified, this field has no effect.
//
// If _i_ is > 0, then it's assumed that
// - 'Value' is a string that can work as a directory or file name,
// - the field value intended for replacement holds a filepath.
//
// The filepath is split into a string slice, the value is inserted
// at position [i-1], shifting the rest of the path to the right.
// A value of i==1 puts the new value at the start of the path.
// This change never converts an absolute path to a relative path,
// meaning adding a new field at position i==1 will preserve a
// leading slash. E.g. if Value == 'PEACH'
//
// OLD : NEW : FilePathPosition
// --------------------------------------------------------
// {empty} : PEACH : irrelevant
// / : /PEACH : irrelevant
// pie : PEACH/pie : 1 (or less to prefix)
// /pie : /PEACH/pie : 1 (or less to prefix)
// raw : raw/PEACH : 2 (or more to postfix)
// /raw : /raw/PEACH : 2 (or more to postfix)
// a/nice/warm/pie : a/nice/warm/PEACH/pie : 4
// /a/nice/warm/pie : /a/nice/warm/PEACH/pie : 4
//
// For robustness (liberal input, conservative output) FilePathPosition
// values that that are too large to index the split filepath result in a
// postfix rather than an error. So use 1 to prefix, 9999 to postfix.
FilePathPosition int `json:"filePathPosition,omitempty" yaml:"filePathPosition,omitempty"`
}
var _ kio.Filter = Filter{}
func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
_, err := kio.FilterAll(yaml.FilterFunc(
func(node *yaml.RNode) (*yaml.RNode, error) {
fields := strings.Split(f.FieldPath, "/")
// TODO: support SequenceNode.
// Presumably here one could look for array indices (digits) at
// the end of the field path (as described in IETF RFC 6902 JSON),
// and if found, take it as a signal that this should be a
// SequenceNode instead of a ScalarNode, and insert the value
// into the proper slot, shifting every over.
n, err := node.Pipe(yaml.LookupCreate(yaml.ScalarNode, fields...))
if err != nil {
return node, err
}
// TODO: allow more kinds
if err := yaml.ErrorIfInvalid(n, yaml.ScalarNode); err != nil {
return nil, err
}
newValue := f.Value
if f.FilePathPosition > 0 {
newValue = filesys.InsertPathPart(
n.YNode().Value, f.FilePathPosition-1, newValue)
}
return n.Pipe(yaml.FieldSetter{StringValue: newValue})
})).Filter(nodes)
return nodes, err
}

View File

@@ -1,109 +0,0 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package valueadd
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
filtertest_test "sigs.k8s.io/kustomize/api/testutils/filtertest"
)
const someResource = `
kind: SomeKind
spec:
resourceRef:
external: projects/whatever
`
func TestValueAddFilter(t *testing.T) {
testCases := map[string]struct {
input string
expectedOutput string
filter Filter
}{
"simpleAdd": {
input: `
kind: SomeKind
`,
expectedOutput: `
kind: SomeKind
spec:
resourceRef:
external: valueAdded
`,
filter: Filter{
Value: "valueAdded",
FieldPath: "spec/resourceRef/external",
},
},
"replaceExisting": {
input: someResource,
expectedOutput: `
kind: SomeKind
spec:
resourceRef:
external: valueAdded
`,
filter: Filter{
Value: "valueAdded",
FieldPath: "spec/resourceRef/external",
},
},
"prefixExisting": {
input: someResource,
expectedOutput: `
kind: SomeKind
spec:
resourceRef:
external: valueAdded/projects/whatever
`,
filter: Filter{
Value: "valueAdded",
FieldPath: "spec/resourceRef/external",
FilePathPosition: 1,
},
},
"postfixExisting": {
input: someResource,
expectedOutput: `
kind: SomeKind
spec:
resourceRef:
external: projects/whatever/valueAdded
`,
filter: Filter{
Value: "valueAdded",
FieldPath: "spec/resourceRef/external",
FilePathPosition: 99,
},
},
"placeInMiddleOfExisting": {
input: someResource,
expectedOutput: `
kind: SomeKind
spec:
resourceRef:
external: projects/valueAdded/whatever
`,
filter: Filter{
Value: "valueAdded",
FieldPath: "spec/resourceRef/external",
FilePathPosition: 2,
},
},
}
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
filter := tc.filter
if !assert.Equal(t,
strings.TrimSpace(tc.expectedOutput),
strings.TrimSpace(filtertest_test.RunFilter(t, tc.input, filter))) {
t.FailNow()
}
})
}
}

View File

@@ -1,6 +1,6 @@
module sigs.k8s.io/kustomize/api module sigs.k8s.io/kustomize/api
go 1.14 go 1.13
require ( require (
github.com/evanphx/json-patch v4.5.0+incompatible github.com/evanphx/json-patch v4.5.0+incompatible
@@ -11,11 +11,11 @@ require (
github.com/stretchr/testify v1.4.0 github.com/stretchr/testify v1.4.0
github.com/yujunz/go-getter v1.4.1-lite github.com/yujunz/go-getter v1.4.1-lite
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff golang.org/x/tools v0.0.0-20191010075000-0337d82405ff
gopkg.in/yaml.v2 v2.3.0 gopkg.in/yaml.v2 v2.2.7
k8s.io/api v0.17.0 k8s.io/api v0.17.0
k8s.io/apimachinery v0.17.0 k8s.io/apimachinery v0.17.0
k8s.io/client-go v0.17.0 k8s.io/client-go v0.17.0
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a
sigs.k8s.io/kustomize/kyaml v0.4.1 sigs.k8s.io/kustomize/kyaml v0.1.5
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.1.0
) )

View File

@@ -17,21 +17,16 @@ github.com/OpenPeeDeeP/depguard v1.0.1 h1:VlW4R6jmBIv3/u1JNlawEvJMM4J+dPORPaZasQ
github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg= github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
@@ -50,7 +45,6 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -58,8 +52,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/dustmop/soup v1.1.2-0.20190516214245-38228baa104e/go.mod h1:CgNC6SGbT+Xb8wGGvzilttZL1mc5sQ/5KkcxsZttMIk= github.com/dustmop/soup v1.1.2-0.20190516214245-38228baa104e/go.mod h1:CgNC6SGbT+Xb8wGGvzilttZL1mc5sQ/5KkcxsZttMIk=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
@@ -74,8 +66,6 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db h1:GYXWx7Vr3+zv833u+8IoXbNnQY0AdXsxAgI0kX7xcwA= github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db h1:GYXWx7Vr3+zv833u+8IoXbNnQY0AdXsxAgI0kX7xcwA=
github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA= github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
@@ -87,55 +77,20 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w= github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= github.com/go-openapi/jsonreference v0.19.2 h1:o20suLFB4Ri0tuzpWtyHlh7E7HnkqTNLq6aR6WVNS1w=
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk=
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/spec v0.19.5 h1:Xm0Ao53uqnk9QE/LlYV5DEU09UAgpliA85QoT9LzqPw= github.com/go-openapi/spec v0.19.5 h1:Xm0Ao53uqnk9QE/LlYV5DEU09UAgpliA85QoT9LzqPw=
github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY= github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g=
github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=
@@ -166,6 +121,7 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -219,7 +175,6 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k=
@@ -267,7 +222,6 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@@ -276,12 +230,9 @@ github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQ
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e h1:hB2xlXdHp/pmPZq0y3QnmWAArdw9PqbmotexnWx/FU8=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb h1:RHba4YImhrUVQDHUCe2BNSOz4tVy2yGyXhvYDvxGgeE= github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb h1:RHba4YImhrUVQDHUCe2BNSOz4tVy2yGyXhvYDvxGgeE=
github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
@@ -321,7 +272,6 @@ github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGV
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/paulmach/orb v0.1.3/go.mod h1:VFlX/8C+IQ1p6FTRRKzKoOPJnvEtA5G0Veuqwbu//Vk= github.com/paulmach/orb v0.1.3/go.mod h1:VFlX/8C+IQ1p6FTRRKzKoOPJnvEtA5G0Veuqwbu//Vk=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
@@ -340,17 +290,13 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d h1:K6eOUihrFLdZjZnA4XlRp864fmWXv9YTIk7VPLhRacA=
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d/go.mod h1:7DPO4domFU579Ga6E61sB9VFNaniPVwJP5C4bBCu3wA= github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d/go.mod h1:7DPO4domFU579Ga6E61sB9VFNaniPVwJP5C4bBCu3wA=
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/securego/gosec v0.0.0-20191002120514-e680875ea14d h1:BzRvVq1EHuIjxpijCEKpAxzKUUMurOQ4sknehIATRh8= github.com/securego/gosec v0.0.0-20191002120514-e680875ea14d h1:BzRvVq1EHuIjxpijCEKpAxzKUUMurOQ4sknehIATRh8=
github.com/securego/gosec v0.0.0-20191002120514-e680875ea14d/go.mod h1:w5+eXa0mYznDkHaMCXA4XYffjlH+cy1oyKbfzJXa2Do= github.com/securego/gosec v0.0.0-20191002120514-e680875ea14d/go.mod h1:w5+eXa0mYznDkHaMCXA4XYffjlH+cy1oyKbfzJXa2Do=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
@@ -358,7 +304,6 @@ github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e h1:MZM7FHLqUHYI0Y/mQAt
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041 h1:llrF3Fs4018ePo4+G/HV/uQUqEI1HMDjCeOf2V6puPc= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041 h1:llrF3Fs4018ePo4+G/HV/uQUqEI1HMDjCeOf2V6puPc=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@@ -371,9 +316,8 @@ github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
@@ -393,7 +337,6 @@ github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb/go.mod h1:a8OnR
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e h1:RumXZ56IrCj4CL+g1b9OL/oH0QnsF976bC8xQFYUD5Q= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e h1:RumXZ56IrCj4CL+g1b9OL/oH0QnsF976bC8xQFYUD5Q=
github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -411,7 +354,6 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI= github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI=
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
@@ -419,12 +361,8 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:
github.com/yujunz/go-getter v1.4.1-lite h1:FhvNc94AXMZkfqUwfMKhnQEC9phkphSGdPTL7tIdhOM= github.com/yujunz/go-getter v1.4.1-lite h1:FhvNc94AXMZkfqUwfMKhnQEC9phkphSGdPTL7tIdhOM=
github.com/yujunz/go-getter v1.4.1-lite/go.mod h1:sbmqxXjyLunH1PkF3n7zSlnVeMvmYUuIl9ZVs/7NyCc= github.com/yujunz/go-getter v1.4.1-lite/go.mod h1:sbmqxXjyLunH1PkF3n7zSlnVeMvmYUuIl9ZVs/7NyCc=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.starlark.net v0.0.0-20190528202925-30ae18b8564f/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg= go.starlark.net v0.0.0-20190528202925-30ae18b8564f/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
@@ -433,10 +371,7 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -451,22 +386,19 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -485,13 +417,11 @@ golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 h1:rOhMmluY6kLMhdnrivzec6lLgaVbMHMn2ISQXJeJ5EM=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c h1:Vco5b+cuG5NNfORVxZy6bYZQ7rsigisU1WQFkvQ0L5E=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -508,15 +438,12 @@ golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -549,11 +476,10 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2 h1:XZx7nhd5GMaZpmDaEHFVafUZC7ya0fuo7cSJ3UCKYmM= gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2 h1:XZx7nhd5GMaZpmDaEHFVafUZC7ya0fuo7cSJ3UCKYmM=
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -580,11 +506,17 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphD
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4= mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f h1:Cq7MalBHYACRd6EesksG1Q8EoIAKOsiZviGKbOLIej4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw= mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.4.1 h1:NEqA/35upoAjb+I5vh1ODUqxoX4DOrezeQa9BhhG5Co= sigs.k8s.io/kustomize v1.0.11 h1:Yb+6DDt9+aR2AvQApvUaKS/ugteeG4MPyoFeUHiPOjk=
sigs.k8s.io/kustomize/kyaml v0.4.1/go.mod h1:XJL84E6sOFeNrQ7CADiemc1B0EjIxHo3OhW4o1aJYNw= sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
sigs.k8s.io/kustomize/kyaml v0.1.1 h1:nGUNYINljZNmlAS8uoobUv/wx/s3Pg8dNxYo+W7uYh0=
sigs.k8s.io/kustomize/kyaml v0.1.1/go.mod h1:/NdPPfrperSCGjm55cwEro1loBVtbtVIXSb7FguK6uk=
sigs.k8s.io/kustomize/kyaml v0.1.2 h1:l12+QGl+ETUHhP8/bZAi6TknU7H194fXL/9b2gUxZFY=
sigs.k8s.io/kustomize/kyaml v0.1.3 h1:zbeHVTMCQPtWgjIH/YYJZC45mm7coTdw2TblyJ79BrY=
sigs.k8s.io/kustomize/kyaml v0.1.3/go.mod h1:461i94nj0h0ylJ6w83jLkR4SqqVhn1iY6fjD0JSTQeE=
sigs.k8s.io/kustomize/kyaml v0.1.5 h1:NicBWYTwkuOfVyZDbNkfSBSCwSgin4uirkedtyZltIc=
sigs.k8s.io/kustomize/kyaml v0.1.5/go.mod h1:461i94nj0h0ylJ6w83jLkR4SqqVhn1iY6fjD0JSTQeE=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4 h1:JPJh2pk3+X4lXAkZIk2RuE/7/FoK9maXw+TNPJhVS/c= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4 h1:JPJh2pk3+X4lXAkZIk2RuE/7/FoK9maXw+TNPJhVS/c=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=

View File

@@ -41,33 +41,33 @@ type Loader interface {
// Kunstructured allows manipulation of k8s objects // Kunstructured allows manipulation of k8s objects
// that do not have Golang structs. // that do not have Golang structs.
type Kunstructured interface { type Kunstructured interface {
Copy() Kunstructured
GetAnnotations() map[string]string
GetBool(path string) (bool, error)
GetFieldValue(string) (interface{}, error)
GetFloat64(path string) (float64, error)
GetGvk() resid.Gvk
GetInt64(path string) (int64, error)
GetKind() string
GetLabels() map[string]string
GetMap(path string) (map[string]interface{}, error)
GetName() string
GetSlice(path string) ([]interface{}, error)
GetString(string) (string, error)
GetStringMap(path string) (map[string]string, error)
GetStringSlice(string) ([]string, error)
Map() map[string]interface{} Map() map[string]interface{}
MarshalJSON() ([]byte, error)
MatchesAnnotationSelector(selector string) (bool, error)
MatchesLabelSelector(selector string) (bool, error)
Patch(Kunstructured) error
SetAnnotations(map[string]string)
SetGvk(resid.Gvk)
SetLabels(map[string]string)
SetMap(map[string]interface{}) SetMap(map[string]interface{})
Copy() Kunstructured
GetFieldValue(string) (interface{}, error)
GetString(string) (string, error)
GetStringSlice(string) ([]string, error)
GetBool(path string) (bool, error)
GetFloat64(path string) (float64, error)
GetInt64(path string) (int64, error)
GetSlice(path string) ([]interface{}, error)
GetStringMap(path string) (map[string]string, error)
GetMap(path string) (map[string]interface{}, error)
MarshalJSON() ([]byte, error)
UnmarshalJSON([]byte) error
GetGvk() resid.Gvk
SetGvk(resid.Gvk)
GetKind() string
GetName() string
SetName(string) SetName(string)
SetNamespace(string) SetNamespace(string)
UnmarshalJSON([]byte) error GetLabels() map[string]string
SetLabels(map[string]string)
GetAnnotations() map[string]string
SetAnnotations(map[string]string)
MatchesLabelSelector(selector string) (bool, error)
MatchesAnnotationSelector(selector string) (bool, error)
Patch(Kunstructured) error
} }
// KunstructuredFactory makes instances of Kunstructured. // KunstructuredFactory makes instances of Kunstructured.

View File

@@ -40,11 +40,7 @@ func (rv *refVarTransformer) replaceVars(in interface{}) (interface{}, error) {
case []interface{}: case []interface{}:
var xs []interface{} var xs []interface{}
for _, a := range in.([]interface{}) { for _, a := range in.([]interface{}) {
x, ok := a.(string) xs = append(xs, expansion2.Expand(a.(string), rv.mappingFunc))
if !ok {
return nil, fmt.Errorf("expected array of strings, found %v", in)
}
xs = append(xs, expansion2.Expand(x, rv.mappingFunc))
} }
return xs, nil return xs, nil
case map[string]interface{}: case map[string]interface{}:
@@ -53,7 +49,7 @@ func (rv *refVarTransformer) replaceVars(in interface{}) (interface{}, error) {
for k, v := range inMap { for k, v := range inMap {
s, ok := v.(string) s, ok := v.(string)
if !ok { if !ok {
// This field can not contain a $(VAR) since it is not // This field not contain a $(VAR) since it is not
// of string type. For instance .spec.replicas: 3 in // of string type. For instance .spec.replicas: 3 in
// a Deployment object // a Deployment object
xs[k] = v xs[k] = v
@@ -68,7 +64,7 @@ func (rv *refVarTransformer) replaceVars(in interface{}) (interface{}, error) {
case interface{}: case interface{}:
s, ok := in.(string) s, ok := in.(string)
if !ok { if !ok {
// This field can not contain a $(VAR) since it is not of string type. // This field not contain a $(VAR) since it is not of string type.
return in, nil return in, nil
} }
// This field can potentially contain a $(VAR) since it is // This field can potentially contain a $(VAR) since it is

View File

@@ -29,7 +29,6 @@ func TestRefVarTransformer(t *testing.T) {
description string description string
given given given given
expected expected expected expected
errMessage string
}{ }{
{ {
description: "var replacement in map[string]", description: "var replacement in map[string]",
@@ -112,27 +111,6 @@ func TestRefVarTransformer(t *testing.T) {
unused: []string{"BAR"}, unused: []string{"BAR"},
}, },
}, },
{
description: "var replacement panic in map[string]",
given: given{
varMap: map[string]interface{}{},
fs: []types.FieldSpec{
{Gvk: resid.Gvk{Version: "v1", Kind: "ConfigMap"}, Path: "data/slice"},
},
res: resmaptest_test.NewRmBuilder(
t, resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())).
Add(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": "cm1",
},
"data": map[string]interface{}{
"slice": []interface{}{5}, // noticeably *not* a []string
}}).ResMap(),
},
errMessage: "expected array of strings, found [5]",
},
} }
for _, tc := range testCases { for _, tc := range testCases {
@@ -144,23 +122,16 @@ func TestRefVarTransformer(t *testing.T) {
err := tr.Transform(tc.given.res) err := tr.Transform(tc.given.res)
// assert // assert
if tc.errMessage != "" { if err != nil {
if err == nil { t.Errorf("unexpected error: %v", err)
t.Fatalf("missing expected error %v", tc.errMessage)
} else if err.Error() != tc.errMessage {
t.Fatalf("actual error doesn't match expected error: \nACTUAL: %v\nEXPECTED: %v", err.Error(), tc.errMessage)
}
} else {
if err != nil {
t.Errorf("unexpected error: %v", err)
}
a, e := tc.given.res, tc.expected.res
if !reflect.DeepEqual(a, e) {
err = e.ErrorIfNotEqualLists(a)
t.Fatalf("actual doesn't match expected: \nACTUAL:\n%v\nEXPECTED:\n%v\nERR: %v", a, e, err)
}
} }
a, e := tc.given.res, tc.expected.res
if !reflect.DeepEqual(a, e) {
err = e.ErrorIfNotEqualLists(a)
t.Fatalf("actual doesn't match expected: \nACTUAL:\n%v\nEXPECTED:\n%v\nERR: %v", a, e, err)
}
}) })
} }
} }

View File

@@ -1,4 +1,4 @@
FROM golang:1.14 AS build FROM golang:1.11 AS build
ARG GO111MODULE=on ARG GO111MODULE=on

View File

@@ -159,31 +159,40 @@ func main() {
} }
} }
query := []byte(`{ "query":{ "match_all":{} } }`) seedDocs := make(crawler.CrawlSeed, 0)
it := idx.IterateQuery(query, 10000, 60*time.Second)
// get all the documents in the index
getSeedDocsFunc := func() {
query := []byte(`{ "query":{ "match_all":{} } }`)
it := idx.IterateQuery(query, 10000, 60*time.Second)
for it.Next() {
for _, hit := range it.Value().Hits.Hits {
seedDocs = append(seedDocs, hit.Document.Document.Copy())
}
}
if err := it.Err(); err != nil {
log.Fatalf("getSeedDocsFunc Error iterating: %v\n", err)
}
}
switch mode { switch mode {
case CrawlIndexAndGithub: case CrawlIndexAndGithub:
getSeedDocsFunc()
crawlers := []crawler.Crawler{ghCrawlerConstructor("", "")} crawlers := []crawler.Crawler{ghCrawlerConstructor("", "")}
crawler.CrawlFromSeedIterator(ctx, it, crawlers, docConverter, indexFunc, seen) crawler.CrawlFromSeed(ctx, seedDocs, crawlers, docConverter, indexFunc, seen)
crawler.CrawlGithub(ctx, crawlers, docConverter, indexFunc, seen) crawler.CrawlGithub(ctx, crawlers, docConverter, indexFunc, seen)
case CrawlIndex: case CrawlIndex:
getSeedDocsFunc()
crawlers := []crawler.Crawler{ghCrawlerConstructor("", "")} crawlers := []crawler.Crawler{ghCrawlerConstructor("", "")}
crawler.CrawlFromSeedIterator(ctx, it, crawlers, docConverter, indexFunc, seen) crawler.CrawlFromSeed(ctx, seedDocs, crawlers, docConverter, indexFunc, seen)
case CrawlGithub: case CrawlGithub:
crawlers := []crawler.Crawler{ghCrawlerConstructor("", "")} crawlers := []crawler.Crawler{ghCrawlerConstructor("", "")}
// add all the documents in the index into seen. // add all the documents in the index into seen.
// this greatly reduces the time overhead of CrawlGithub. // this greatly reduces the time overhead of CrawlGithub.
for it.Next() { getSeedDocsFunc()
for _, hit := range it.Value().Hits.Hits { for _, d := range seedDocs {
d := hit.Document.Document seen[d.ID()] = d.FileType
seen.Set(d.ID(), d.FileType)
}
} }
if err := it.Err(); err != nil {
log.Fatalf("Error iterating the index: %v\n", err)
}
crawler.CrawlGithub(ctx, crawlers, docConverter, indexFunc, seen) crawler.CrawlGithub(ctx, crawlers, docConverter, indexFunc, seen)
case CrawlUser: case CrawlUser:
if *githubUserPtr == "" { if *githubUserPtr == "" {

View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: elasticsearch
spec:
selector:
custom-resource: v1alpha1.ESCluster
custom-resource-name: esbasic
custom-resource-namespace: default
es/data: "true"
using: escluster.Cluster
ports:
- protocol: "TCP"
port: 9200
type: LoadBalancer
loadBalancerIP: ""

View File

@@ -213,36 +213,21 @@ func doCrawl(ctx context.Context, docsPtr *CrawlSeed, crawlers []Crawler, conv C
logger.Printf("\t%d documents cannot be converted but still were inserted or updated in the index\n", convErrCount) logger.Printf("\t%d documents cannot be converted but still were inserted or updated in the index\n", convErrCount)
} }
// CrawlFromSeedIterator iterates all the documents in the index and call CrawlFromSeed for each document.
func CrawlFromSeedIterator(ctx context.Context, it *index.KustomizeIterator, crawlers []Crawler,
conv Converter, indx IndexFunc, seen utils.SeenMap) {
docCount := 0
for it.Next() {
for _, hit := range it.Value().Hits.Hits {
docCount++
logger.Printf("updating document %d from seed\n", docCount)
singleSeed := CrawlSeed{&(hit.Document.Document)}
CrawlFromSeed(ctx, singleSeed, crawlers, conv, indx, seen)
}
}
if err := it.Err(); err != nil {
log.Fatalf("Error iterating the index: %v\n", err)
}
}
// CrawlFromSeed updates all the documents in seed, and crawls all the new // CrawlFromSeed updates all the documents in seed, and crawls all the new
// documents referred in the seed. // documents referred in the seed.
func CrawlFromSeed(ctx context.Context, seed CrawlSeed, crawlers []Crawler, func CrawlFromSeed(ctx context.Context, seed CrawlSeed, crawlers []Crawler,
conv Converter, indx IndexFunc, seen utils.SeenMap) { conv Converter, indx IndexFunc, seen utils.SeenMap) {
// stack tracks the documents directly referred in the seed. // stack tracks the documents directly referred in other documents.
stack := make(CrawlSeed, 0) stack := make(CrawlSeed, 0)
// Exploit seed to update bulk of corpus.
logger.Printf("updating %d documents from seed\n", len(seed))
// each unique document in seed will be crawled once. // each unique document in seed will be crawled once.
doCrawl(ctx, &seed, crawlers, conv, indx, seen, &stack, true, false) doCrawl(ctx, &seed, crawlers, conv, indx, seen, &stack, true, false)
logger.Printf("crawling %d new documents referred by doc\n", len(stack)) // Traverse any new documents added while updating corpus.
logger.Printf("crawling %d new documents found in the seed\n", len(stack))
// While crawling each document in stack, the documents directly referred in the document // While crawling each document in stack, the documents directly referred in the document
// will be added into stack. // will be added into stack.
// After this statement is done, stack will become empty. // After this statement is done, stack will become empty.
@@ -312,6 +297,8 @@ func CrawlGithubRunner(ctx context.Context, output chan<- CrawledDocument,
// CrawlGithub crawls all the kustomization files on Github. // CrawlGithub crawls all the kustomization files on Github.
func CrawlGithub(ctx context.Context, crawlers []Crawler, conv Converter, func CrawlGithub(ctx context.Context, crawlers []Crawler, conv Converter,
indx IndexFunc, seen utils.SeenMap) { indx IndexFunc, seen utils.SeenMap) {
// stack tracks the documents directly referred in other documents.
stack := make(CrawlSeed, 0)
// ch is channel where all the crawlers sends the crawled documents to. // ch is channel where all the crawlers sends the crawled documents to.
ch := make(chan CrawledDocument, 1<<10) ch := make(chan CrawledDocument, 1<<10)
@@ -337,20 +324,7 @@ func CrawlGithub(ctx context.Context, crawlers []Crawler, conv Converter,
"%v could not match any crawler", cdoc)) "%v could not match any crawler", cdoc))
continue continue
} }
// stack tracks the documents directly referred in the document.
stack := make(CrawlSeed, 0)
addBranches(cdoc, match, indx, seen, &stack) addBranches(cdoc, match, indx, seen, &stack)
if len(stack) > 0 {
// here the documents referred in a kustomization file are crawled separately,
// to avoid accumulating all the referred documents into a single gigantic
// mem-inentive stack.
logger.Printf("crawling the %d new documents referred in doc %d",
len(stack), docCount)
doCrawl(ctx, &stack, crawlers, conv, indx, seen, &stack, false, true)
}
} }
}() }()
@@ -362,4 +336,9 @@ func CrawlGithub(ctx context.Context, crawlers []Crawler, conv Converter,
} }
close(ch) close(ch)
wg.Wait() wg.Wait()
// Handle deps of newly discovered documents.
logger.Printf("crawling the %d new documents referred by other documents",
len(stack))
doCrawl(ctx, &stack, crawlers, conv, indx, seen, &stack, false, true)
} }

View File

@@ -82,15 +82,14 @@ func (gc githubCrawler) Crawl(ctx context.Context,
ranges := []RangeWithin{ ranges := []RangeWithin{
RangeWithin{ RangeWithin{
start: uint64(0), start: uint64(0),
end: githubMaxFileSize, end: githubMaxFileSize,
}, },
} }
errs := make(multiError, 0) errs := make(multiError, 0)
for len(ranges) > 0 { for len(ranges) > 0 {
logger.Printf("Current ranges: %v (len: %d)\n", ranges, len(ranges)) tailRange := ranges[len(ranges) - 1]
tailRange := ranges[len(ranges)-1]
ranges = ranges[:(len(ranges) - 1)] ranges = ranges[:(len(ranges) - 1)]
reProcessQueryRanges, err := gc.CrawlSingleRange(ctx, output, seen, tailRange.start, tailRange.end) reProcessQueryRanges, err := gc.CrawlSingleRange(ctx, output, seen, tailRange.start, tailRange.end)
if err != nil { if err != nil {
@@ -152,15 +151,7 @@ func (gc githubCrawler) CrawlSingleRange(ctx context.Context,
} }
queryResult.Add(rangeResult) queryResult.Add(rangeResult)
if reProcessQuery { if reProcessQuery {
// if the size of a range is 0, such as [245, 245], and reProcessQuery is true, reProcessQueryRanges = append(reProcessQueryRanges, RangeSizes(query))
// it means that there are more than 1000 results for the query range.
// Reprocessing the query range will not help because the GitHub Search API
// only provides up to 1,000 results for each search.
if RangeSizes(query).Size() == 0 {
logger.Printf("range size is 0 includes more than 1000 results: %s", query)
} else {
reProcessQueryRanges = append(reProcessQueryRanges, RangeSizes(query))
}
} }
} }

View File

@@ -225,7 +225,3 @@ type RangeWithin struct {
func (r RangeWithin) RangeString() string { func (r RangeWithin) RangeString() string {
return fmt.Sprintf("%d..%d", r.start, r.end) return fmt.Sprintf("%d..%d", r.start, r.end)
} }
func (r RangeWithin) Size() uint64 {
return r.end - r.start
}

View File

@@ -1,6 +1,6 @@
module sigs.k8s.io/kustomize/api/internal/crawl module sigs.k8s.io/kustomize/api/internal/crawl
go 1.14 go 1.12
require ( require (
github.com/elastic/go-elasticsearch/v6 v6.8.5 github.com/elastic/go-elasticsearch/v6 v6.8.5
@@ -8,8 +8,6 @@ require (
github.com/gorilla/mux v1.7.3 github.com/gorilla/mux v1.7.3
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79
github.com/rs/cors v1.7.0 github.com/rs/cors v1.7.0
sigs.k8s.io/kustomize/api v0.0.0 sigs.k8s.io/kustomize/api v0.3.1
sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml v1.1.0
) )
replace sigs.k8s.io/kustomize/api v0.0.0 => ../../../api

View File

@@ -1,7 +1,6 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
github.com/360EntSecGroup-Skylar/excelize v1.4.1/go.mod h1:vnax29X2usfl7HHkBrX5EvSCJcmH3dT9luvxzu8iGAE=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
@@ -13,30 +12,18 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM= github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
github.com/bombsimon/wsl v1.2.5/go.mod h1:43lEF/i0kpXbLCeDXL9LMT8c92HyBywXb0AsgMHYngM= github.com/bombsimon/wsl v1.2.5/go.mod h1:43lEF/i0kpXbLCeDXL9LMT8c92HyBywXb0AsgMHYngM=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@@ -45,7 +32,6 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -53,10 +39,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/dustmop/soup v1.1.2-0.20190516214245-38228baa104e/go.mod h1:CgNC6SGbT+Xb8wGGvzilttZL1mc5sQ/5KkcxsZttMIk=
github.com/elastic/go-elasticsearch/v6 v6.8.5 h1:U2HtkBseC1FNBmDr0TR2tKltL6FxoY+niDAlj5M8TK8= github.com/elastic/go-elasticsearch/v6 v6.8.5 h1:U2HtkBseC1FNBmDr0TR2tKltL6FxoY+niDAlj5M8TK8=
github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI= github.com/elastic/go-elasticsearch/v6 v6.8.5/go.mod h1:UwaDJsD3rWLM5rKNFzv9hgox93HoX8utj1kxD9aFUcI=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
@@ -69,61 +52,23 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA= github.com/go-critic/go-critic v0.3.5-0.20190904082202-d79a9f0c64db/go.mod h1:+sE8vrLDS2M0pZkBk0wy6+nLdKexVDrl/jBqQOTDThA=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM= github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTDqfpXvXAN0sXM=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik=
github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk=
github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU=
github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0=
github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94=
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU=
github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs=
github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk=
github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA=
github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64=
github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4=
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/spec v0.19.5/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk=
github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU=
github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY=
github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU=
github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk=
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4=
github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
github.com/go-openapi/validate v0.19.8/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=
github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ=
@@ -183,7 +128,6 @@ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXi
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k=
@@ -199,12 +143,6 @@ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:Fecb
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0=
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
@@ -238,22 +176,15 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/matoous/godox v0.0.0-20190911065817-5d6d842e92eb/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk= github.com/mitchellh/go-ps v0.0.0-20190716172923-621e5597135b/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
@@ -262,7 +193,6 @@ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lN
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk= github.com/mozilla/tls-observatory v0.0.0-20190404164649-a3c1b6cfecfd/go.mod h1:SrKMQvPiws7F7iqYp8/TX+IhxCYhzr6N/1yb8cwHsGk=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@@ -276,8 +206,6 @@ github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME= github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/paulmach/orb v0.1.3/go.mod h1:VFlX/8C+IQ1p6FTRRKzKoOPJnvEtA5G0Veuqwbu//Vk=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -295,22 +223,17 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d/go.mod h1:7DPO4domFU579Ga6E61sB9VFNaniPVwJP5C4bBCu3wA=
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI= github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/securego/gosec v0.0.0-20191002120514-e680875ea14d/go.mod h1:w5+eXa0mYznDkHaMCXA4XYffjlH+cy1oyKbfzJXa2Do= github.com/securego/gosec v0.0.0-20191002120514-e680875ea14d/go.mod h1:w5+eXa0mYznDkHaMCXA4XYffjlH+cy1oyKbfzJXa2Do=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc= github.com/shirou/gopsutil v0.0.0-20190901111213-e4ec7b275ada/go.mod h1:WWnYX4lzhCH5h/3YBfyVA3VbLYjlMZZAQcW9ojMexNc=
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc= github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@@ -320,7 +243,6 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
@@ -333,17 +255,13 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.3-0.20181224173747-660f15d67dbb/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok=
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=
github.com/uudashr/gocognit v0.0.0-20190926065955-1655d0de0517/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM= github.com/uudashr/gocognit v0.0.0-20190926065955-1655d0de0517/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM=
@@ -351,19 +269,10 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s= github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4= github.com/valyala/quicktemplate v1.2.0/go.mod h1:EH+4AkTd43SvgIbQHYu59/cJyxDoOVRUAfrukLPuGJ4=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yujunz/go-getter v1.4.1-lite h1:FhvNc94AXMZkfqUwfMKhnQEC9phkphSGdPTL7tIdhOM=
github.com/yujunz/go-getter v1.4.1-lite/go.mod h1:sbmqxXjyLunH1PkF3n7zSlnVeMvmYUuIl9ZVs/7NyCc=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.starlark.net v0.0.0-20190528202925-30ae18b8564f/go.mod h1:c1/X6cHgvdXj6pUlmWKMkuqRnW4K8x2vwt6JAaaircg=
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
@@ -371,10 +280,8 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -384,18 +291,15 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -404,8 +308,6 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -424,15 +326,12 @@ golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 h1:rOhMmluY6kLMhdnrivzec6lLgaVbMHMn2ISQXJeJ5EM= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69 h1:rOhMmluY6kLMhdnrivzec6lLgaVbMHMn2ISQXJeJ5EM=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c h1:Vco5b+cuG5NNfORVxZy6bYZQ7rsigisU1WQFkvQ0L5E=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -448,7 +347,6 @@ golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181117154741-2ddaf7f79a09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@@ -456,7 +354,6 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190521203540-521d6ed310dd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190719005602-e377ae9d6386/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -490,11 +387,6 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
@@ -515,10 +407,9 @@ k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw= mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw=
sigs.k8s.io/kustomize/kyaml v0.4.1/go.mod h1:XJL84E6sOFeNrQ7CADiemc1B0EjIxHo3OhW4o1aJYNw= sigs.k8s.io/kustomize/api v0.3.1 h1:oqMIXvS6tFEUVuKIRUKDa05eC4Hh+cb9JYg8Zhp2d24=
sigs.k8s.io/kustomize/api v0.3.1/go.mod h1:A+ATnlHqzictQfQC1q3KB/T6MSr0UWQsrrLxMWkge2E=
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0= sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=

File diff suppressed because it is too large Load Diff

View File

@@ -1,37 +1,21 @@
package utils package utils
import "sync" type SeenMap map[string]string
type SeenMap struct {
data map[string]string
lock sync.RWMutex
}
// TODO: add lock to avoid race condition
func (seen SeenMap) Seen(item string) bool { func (seen SeenMap) Seen(item string) bool {
seen.lock.RLock() _, ok := seen[item]
_, ok := seen.data[item]
seen.lock.RUnlock()
return ok return ok
} }
func (seen SeenMap) Set(k, v string) { func (seen SeenMap) Set(k, v string) {
seen.lock.Lock() seen[k] = v
seen.data[k] = v
seen.lock.Unlock()
} }
// The caller should make sure that key is in the map. // The caller should make sure that key is in the map.
func (seen SeenMap) Value(k string) string { func (seen SeenMap) Value(k string) string {
seen.lock.RLock() return seen[k]
v := seen.data[k]
seen.lock.RUnlock()
return v
} }
func NewSeenMap() SeenMap { func NewSeenMap() SeenMap {
return SeenMap{ return make(map[string]string)
data: make(map[string]string),
lock: sync.RWMutex{},
}
} }

View File

@@ -4,6 +4,7 @@
package git package git
import ( import (
"bytes"
"log" "log"
"os/exec" "os/exec"
@@ -35,50 +36,32 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error {
"clone", "clone",
"--depth=1", "--depth=1",
repoSpec.CloneSpec(), repoSpec.CloneSpec(),
"-b",
repoSpec.Ref,
repoSpec.Dir.String()) repoSpec.Dir.String())
out, err := cmd.CombinedOutput() var out bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &out
err = cmd.Run()
if err != nil { if err != nil {
log.Printf("Error cloning git repo: %s", out) log.Printf("Error cloning git repo: %s", out.String())
return errors.Wrapf( return errors.Wrapf(
err, err,
"trouble cloning git repo %v in %s", "trouble cloning git repo %v in %s",
repoSpec.CloneSpec(), repoSpec.Dir.String()) repoSpec.CloneSpec(), repoSpec.Dir.String())
} }
cmd = exec.Command(
gitProgram,
"fetch",
"--depth=1",
"origin",
repoSpec.Ref)
cmd.Dir = repoSpec.Dir.String()
out, err = cmd.CombinedOutput()
if err != nil {
log.Printf("Error fetching ref: %s", out)
return errors.Wrapf(err, "trouble fetching %s", repoSpec.Ref)
}
cmd = exec.Command(
gitProgram,
"checkout",
"FETCH_HEAD")
cmd.Dir = repoSpec.Dir.String()
out, err = cmd.CombinedOutput()
if err != nil {
log.Printf("Error checking out ref: %s", out)
return errors.Wrapf(err, "trouble checking out %s", repoSpec.Ref)
}
cmd = exec.Command( cmd = exec.Command(
gitProgram, gitProgram,
"submodule", "submodule",
"update", "update",
"--init", "--init",
"--recursive") "--recursive")
cmd.Stdout = &out
cmd.Stderr = &out
cmd.Dir = repoSpec.Dir.String() cmd.Dir = repoSpec.Dir.String()
out, err = cmd.CombinedOutput() err = cmd.Run()
if err != nil { if err != nil {
log.Printf("Error fetching submodules: %s", out)
return errors.Wrapf(err, "trouble fetching submodules for %s", repoSpec.CloneSpec()) return errors.Wrapf(err, "trouble fetching submodules for %s", repoSpec.CloneSpec())
} }

View File

@@ -13,21 +13,21 @@ func _() {
_ = x[ConfigMapGenerator-2] _ = x[ConfigMapGenerator-2]
_ = x[HashTransformer-3] _ = x[HashTransformer-3]
_ = x[ImageTagTransformer-4] _ = x[ImageTagTransformer-4]
_ = x[LabelTransformer-5] _ = x[InventoryTransformer-5]
_ = x[LegacyOrderTransformer-6] _ = x[LabelTransformer-6]
_ = x[NamespaceTransformer-7] _ = x[LegacyOrderTransformer-7]
_ = x[PatchJson6902Transformer-8] _ = x[NamespaceTransformer-8]
_ = x[PatchStrategicMergeTransformer-9] _ = x[PatchJson6902Transformer-9]
_ = x[PatchTransformer-10] _ = x[PatchStrategicMergeTransformer-10]
_ = x[PrefixSuffixTransformer-11] _ = x[PatchTransformer-11]
_ = x[ReplicaCountTransformer-12] _ = x[PrefixSuffixTransformer-12]
_ = x[SecretGenerator-13] _ = x[ReplicaCountTransformer-13]
_ = x[ValueAddTransformer-14] _ = x[SecretGenerator-14]
} }
const _BuiltinPluginType_name = "UnknownAnnotationsTransformerConfigMapGeneratorHashTransformerImageTagTransformerLabelTransformerLegacyOrderTransformerNamespaceTransformerPatchJson6902TransformerPatchStrategicMergeTransformerPatchTransformerPrefixSuffixTransformerReplicaCountTransformerSecretGeneratorValueAddTransformer" const _BuiltinPluginType_name = "UnknownAnnotationsTransformerConfigMapGeneratorHashTransformerImageTagTransformerInventoryTransformerLabelTransformerLegacyOrderTransformerNamespaceTransformerPatchJson6902TransformerPatchStrategicMergeTransformerPatchTransformerPrefixSuffixTransformerReplicaCountTransformerSecretGenerator"
var _BuiltinPluginType_index = [...]uint16{0, 7, 29, 47, 62, 81, 97, 119, 139, 163, 193, 209, 232, 255, 270, 289} var _BuiltinPluginType_index = [...]uint16{0, 7, 29, 47, 62, 81, 101, 117, 139, 159, 183, 213, 229, 252, 275, 290}
func (i BuiltinPluginType) String() string { func (i BuiltinPluginType) String() string {
if i < 0 || i >= BuiltinPluginType(len(_BuiltinPluginType_index)-1) { if i < 0 || i >= BuiltinPluginType(len(_BuiltinPluginType_index)-1) {

View File

@@ -17,6 +17,7 @@ const (
ConfigMapGenerator ConfigMapGenerator
HashTransformer HashTransformer
ImageTagTransformer ImageTagTransformer
InventoryTransformer
LabelTransformer LabelTransformer
LegacyOrderTransformer LegacyOrderTransformer
NamespaceTransformer NamespaceTransformer
@@ -26,7 +27,6 @@ const (
PrefixSuffixTransformer PrefixSuffixTransformer
ReplicaCountTransformer ReplicaCountTransformer
SecretGenerator SecretGenerator
ValueAddTransformer
) )
var stringToBuiltinPluginTypeMap map[string]BuiltinPluginType var stringToBuiltinPluginTypeMap map[string]BuiltinPluginType
@@ -63,6 +63,7 @@ var TransformerFactories = map[BuiltinPluginType]func() resmap.TransformerPlugin
AnnotationsTransformer: builtins.NewAnnotationsTransformerPlugin, AnnotationsTransformer: builtins.NewAnnotationsTransformerPlugin,
HashTransformer: builtins.NewHashTransformerPlugin, HashTransformer: builtins.NewHashTransformerPlugin,
ImageTagTransformer: builtins.NewImageTagTransformerPlugin, ImageTagTransformer: builtins.NewImageTagTransformerPlugin,
InventoryTransformer: builtins.NewInventoryTransformerPlugin,
LabelTransformer: builtins.NewLabelTransformerPlugin, LabelTransformer: builtins.NewLabelTransformerPlugin,
LegacyOrderTransformer: builtins.NewLegacyOrderTransformerPlugin, LegacyOrderTransformer: builtins.NewLegacyOrderTransformerPlugin,
NamespaceTransformer: builtins.NewNamespaceTransformerPlugin, NamespaceTransformer: builtins.NewNamespaceTransformerPlugin,
@@ -71,5 +72,4 @@ var TransformerFactories = map[BuiltinPluginType]func() resmap.TransformerPlugin
PatchTransformer: builtins.NewPatchTransformerPlugin, PatchTransformer: builtins.NewPatchTransformerPlugin,
PrefixSuffixTransformer: builtins.NewPrefixSuffixTransformerPlugin, PrefixSuffixTransformer: builtins.NewPrefixSuffixTransformerPlugin,
ReplicaCountTransformer: builtins.NewReplicaCountTransformerPlugin, ReplicaCountTransformer: builtins.NewReplicaCountTransformerPlugin,
ValueAddTransformer: builtins.NewValueAddTransformerPlugin,
} }

View File

@@ -6,103 +6,178 @@ package compiler
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"log"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"runtime"
"strings" "strings"
"time"
"github.com/pkg/errors" "github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/internal/plugins/utils" "sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/konfig"
) )
// Compiler creates Go plugin object files. // Compiler creates Go plugin object files.
//
// Source code is read from
// ${srcRoot}/${g}/${v}/${k}.go
//
// Object code is written to
// ${objRoot}/${g}/${v}/${k}.so
type Compiler struct { type Compiler struct {
// pluginRoot is where the user srcRoot string
// has her ${g}/${v}/$lower(${k})/${k}.go files. objRoot string
pluginRoot string }
// Where compilation happens.
workDir string // DeterminePluginSrcRoot guesses where the user
// Used as the root file name for src and object. // has her ${g}/${v}/$lower(${k})/${k}.go files.
rawKind string func DeterminePluginSrcRoot(fSys filesys.FileSystem) (string, error) {
// Capture compiler output. return konfig.FirstDirThatExistsElseError(
stderr bytes.Buffer "source directory", fSys, []konfig.NotedFunc{
// Capture compiler output. {
stdout bytes.Buffer Note: "relative to unit test",
F: func() string {
return filepath.Clean(
filepath.Join(
os.Getenv("PWD"),
"..", "..",
konfig.RelPluginHome))
},
},
{
Note: "relative to unit test (internal pkg)",
F: func() string {
return filepath.Clean(
filepath.Join(
os.Getenv("PWD"),
"..", "..", "..", "..",
konfig.RelPluginHome))
},
},
{
Note: "relative to api package",
F: func() string {
return filepath.Clean(
filepath.Join(
os.Getenv("PWD"),
"..", "..", "..",
konfig.RelPluginHome))
},
},
{
Note: "old style $GOPATH",
F: func() string {
return filepath.Join(
os.Getenv("GOPATH"),
"src", konfig.DomainName,
konfig.ProgramName, konfig.RelPluginHome)
},
},
{
Note: "HOME with literal 'gopath'",
F: func() string {
return filepath.Join(
konfig.HomeDir(), "gopath",
"src", konfig.DomainName,
konfig.ProgramName, konfig.RelPluginHome)
},
},
{
Note: "home directory",
F: func() string {
return filepath.Join(
konfig.HomeDir(), konfig.DomainName,
konfig.ProgramName, konfig.RelPluginHome)
},
},
})
} }
// NewCompiler returns a new compiler instance. // NewCompiler returns a new compiler instance.
func NewCompiler(root string) *Compiler { func NewCompiler(srcRoot, objRoot string) *Compiler {
return &Compiler{pluginRoot: root} return &Compiler{srcRoot: srcRoot, objRoot: objRoot}
} }
// Set GVK converts g,v,k tuples to file path components. // ObjRoot is root of compilation target tree.
func (b *Compiler) SetGVK(g, v, k string) { func (b *Compiler) ObjRoot() string {
b.rawKind = k return b.objRoot
b.workDir = filepath.Join(b.pluginRoot, g, v, strings.ToLower(k))
} }
func (b *Compiler) srcPath() string { // SrcRoot is where to find src.
return filepath.Join(b.workDir, b.rawKind+".go") func (b *Compiler) SrcRoot() string {
return b.srcRoot
} }
func (b *Compiler) objFile() string { func goBin() string {
return b.rawKind + ".so" return filepath.Join(runtime.GOROOT(), "bin", "go")
} }
// Absolute path to the compiler output (the .so file). // Compile reads ${srcRoot}/${g}/${v}/${k}.go
func (b *Compiler) ObjPath() string { // and writes ${objRoot}/${g}/${v}/${k}.so
return filepath.Join(b.workDir, b.objFile()) func (b *Compiler) Compile(g, v, k string) error {
} lowK := strings.ToLower(k)
objDir := filepath.Join(b.objRoot, g, v, lowK)
// Compile changes its working directory to objFile := filepath.Join(objDir, k) + ".so"
// ${pluginRoot}/${g}/${v}/$lower(${k} and places if RecentFileExists(objFile) {
// object code next to source code. // Skip rebuilding it.
func (b *Compiler) Compile() error { return nil
if !utils.FileExists(b.srcPath()) { }
return fmt.Errorf("cannot find source at '%s'", b.srcPath()) err := os.MkdirAll(objDir, os.ModePerm)
if err != nil {
return err
}
srcFile := filepath.Join(b.srcRoot, g, v, lowK, k) + ".go"
if !FileExists(srcFile) {
// Handy for tests of lone plugins.
s := k + ".go"
if !FileExists(s) {
return fmt.Errorf(
"cannot find source at '%s' or '%s'", srcFile, s)
}
srcFile = s
} }
// If you use an IDE, make sure it's go build and test flags
// match those used below. Same goes for Makefile targets.
commands := []string{ commands := []string{
"build", "build",
// "-trimpath", This flag used to make it better, now it makes it worse,
// see https://github.com/golang/go/issues/31354
"-buildmode", "-buildmode",
"plugin", "plugin",
"-o", b.objFile(), "-o", objFile, srcFile,
} }
goBin := utils.GoBin() goBin := goBin()
if !utils.FileExists(goBin) { if !FileExists(goBin) {
return fmt.Errorf( return fmt.Errorf(
"cannot find go compiler %s", goBin) "cannot find go compiler %s", goBin)
} }
cmd := exec.Command(goBin, commands...) cmd := exec.Command(goBin, commands...)
b.stderr.Reset() var stderr bytes.Buffer
cmd.Stderr = &b.stderr cmd.Stderr = &stderr
b.stdout.Reset()
cmd.Stdout = &b.stdout
cmd.Env = os.Environ() cmd.Env = os.Environ()
cmd.Dir = b.workDir
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
b.report()
return errors.Wrapf( return errors.Wrapf(
err, "cannot compile %s:\nSTDERR\n%s\n", err, "cannot compile %s:\nSTDERR\n%s\n", srcFile, stderr.String())
b.srcPath(), b.stderr.String())
} }
result := filepath.Join(b.workDir, b.objFile()) return nil
if utils.FileExists(result) {
log.Printf("compiler created: %s", result)
return nil
}
return fmt.Errorf("post compile, cannot find '%s'", result)
} }
func (b *Compiler) report() { // True if file less than 3 minutes old, i.e. not
log.Println("stdout: -------") // accidentally left over from some earlier build.
log.Println(b.stdout.String()) func RecentFileExists(path string) bool {
log.Println("----------------") fi, err := os.Stat(path)
log.Println("stderr: -------") if err != nil {
log.Println(b.stderr.String()) if os.IsNotExist(err) {
log.Println("----------------") return false
}
}
age := time.Since(fi.ModTime())
return age.Minutes() < 3
}
func FileExists(name string) bool {
if _, err := os.Stat(name); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
} }

View File

@@ -4,48 +4,64 @@
package compiler_test package compiler_test
import ( import (
"io/ioutil"
"os"
"path/filepath" "path/filepath"
"testing" "testing"
"sigs.k8s.io/kustomize/api/filesys" "sigs.k8s.io/kustomize/api/filesys"
. "sigs.k8s.io/kustomize/api/internal/plugins/compiler" . "sigs.k8s.io/kustomize/api/internal/plugins/compiler"
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
) )
// Regression coverage over compiler behavior. // Regression coverage over compiler behavior.
func TestCompiler(t *testing.T) { func TestCompiler(t *testing.T) {
srcRoot, err := utils.DeterminePluginSrcRoot(filesys.MakeFsOnDisk()) configRoot, err := ioutil.TempDir("", "kustomize-compiler-test")
if err != nil {
t.Errorf("failed to make temp dir: %v", err)
}
srcRoot, err := DeterminePluginSrcRoot(filesys.MakeFsOnDisk())
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
c := NewCompiler(srcRoot) c := NewCompiler(srcRoot, configRoot)
if configRoot != c.ObjRoot() {
t.Errorf("unexpected objRoot %s", c.ObjRoot())
}
c.SetGVK("someteam.example.com", "v1", "DatePrefixer")
expectObj := filepath.Join( expectObj := filepath.Join(
srcRoot, "someteam.example.com", "v1", "dateprefixer", "DatePrefixer.so") c.ObjRoot(),
if expectObj != c.ObjPath() { "someteam.example.com", "v1", "dateprefixer", "DatePrefixer.so")
t.Errorf("Expected '%s', got '%s'", expectObj, c.ObjPath()) if FileExists(expectObj) {
t.Errorf("obj file should not exist yet: %s", expectObj)
} }
err = c.Compile() err = c.Compile("someteam.example.com", "v1", "DatePrefixer")
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
if !utils.FileExists(expectObj) { if !RecentFileExists(expectObj) {
t.Errorf("didn't find expected obj file %s", expectObj) t.Errorf("didn't find expected obj file %s", expectObj)
} }
c.SetGVK("builtin", "", "SecretGenerator")
expectObj = filepath.Join( expectObj = filepath.Join(
srcRoot, c.ObjRoot(),
"builtin", "", "secretgenerator", "SecretGenerator.so") "builtin", "", "secretgenerator", "SecretGenerator.so")
if expectObj != c.ObjPath() { if FileExists(expectObj) {
t.Errorf("Expected '%s', got '%s'", expectObj, c.ObjPath()) t.Errorf("obj file should not exist yet: %s", expectObj)
} }
err = c.Compile() err = c.Compile("builtin", "", "SecretGenerator")
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
if !utils.FileExists(expectObj) { if !RecentFileExists(expectObj) {
t.Errorf("didn't find expected obj file %s", expectObj) t.Errorf("didn't find expected obj file %s", expectObj)
} }
err = os.RemoveAll(c.ObjRoot())
if err != nil {
t.Errorf(
"removing temp dir: %s %v", c.ObjRoot(), err)
}
if FileExists(expectObj) {
t.Errorf("cleanup failed; still see: %s", expectObj)
}
} }

View File

@@ -94,7 +94,7 @@ TO GENERATE CODE
cd $repo/plugin/builtin cd $repo/plugin/builtin
go generate ./... go generate ./...
See travis/kyaml-pre-commit.sh for canonical way See travis/pre-commit.sh for canonical way
to execute the above. to execute the above.
This creates This creates

View File

@@ -9,17 +9,22 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"os/exec" "os/exec"
"strconv"
"strings" "strings"
"github.com/google/shlex" "github.com/google/shlex"
"github.com/pkg/errors" "github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/internal/plugins/utils" "sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
) )
const ( const (
idAnnotation = "kustomize.config.k8s.io/id"
HashAnnotation = "kustomize.config.k8s.io/needs-hash"
BehaviorAnnotation = "kustomize.config.k8s.io/behavior"
tmpConfigFilePrefix = "kust-plugin-config-" tmpConfigFilePrefix = "kust-plugin-config-"
) )
@@ -109,12 +114,12 @@ func (p *ExecPlugin) Generate() (resmap.ResMap, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return utils.UpdateResourceOptions(rm) return p.UpdateResourceOptions(rm)
} }
func (p *ExecPlugin) Transform(rm resmap.ResMap) error { func (p *ExecPlugin) Transform(rm resmap.ResMap) error {
// add ResIds as annotations to all objects so that we can add them back // add ResIds as annotations to all objects so that we can add them back
inputRM, err := utils.GetResMapWithIDAnnotation(rm) inputRM, err := p.getResMapWithIdAnnotation(rm)
if err != nil { if err != nil {
return err return err
} }
@@ -132,7 +137,7 @@ func (p *ExecPlugin) Transform(rm resmap.ResMap) error {
} }
// update the original ResMap based on the output // update the original ResMap based on the output
return utils.UpdateResMapValues(p.path, p.h, output, rm) return p.updateResMapValues(output, rm)
} }
// invokePlugin writes plugin config to a temp file, then // invokePlugin writes plugin config to a temp file, then
@@ -179,3 +184,91 @@ func (p *ExecPlugin) getEnv() []string {
"KUSTOMIZE_PLUGIN_CONFIG_ROOT="+p.h.Loader().Root()) "KUSTOMIZE_PLUGIN_CONFIG_ROOT="+p.h.Loader().Root())
return env return env
} }
// Returns a new copy of the given ResMap with the ResIds annotated in each Resource
func (p *ExecPlugin) getResMapWithIdAnnotation(rm resmap.ResMap) (resmap.ResMap, error) {
inputRM := rm.DeepCopy()
for _, r := range inputRM.Resources() {
idString, err := yaml.Marshal(r.CurId())
if err != nil {
return nil, err
}
annotations := r.GetAnnotations()
if annotations == nil {
annotations = make(map[string]string)
}
annotations[idAnnotation] = string(idString)
r.SetAnnotations(annotations)
}
return inputRM, nil
}
// updateResMapValues updates the Resource value in the given ResMap
// with the emitted Resource values in output.
func (p *ExecPlugin) updateResMapValues(output []byte, rm resmap.ResMap) error {
outputRM, err := p.h.ResmapFactory().NewResMapFromBytes(output)
if err != nil {
return err
}
for _, r := range outputRM.Resources() {
// for each emitted Resource, find the matching Resource in the original ResMap
// using its id
annotations := r.GetAnnotations()
idString, ok := annotations[idAnnotation]
if !ok {
return fmt.Errorf("the transformer %s should not remove annotation %s",
p.path, idAnnotation)
}
id := resid.ResId{}
err := yaml.Unmarshal([]byte(idString), &id)
if err != nil {
return err
}
res, err := rm.GetByCurrentId(id)
if err != nil {
return fmt.Errorf("unable to find unique match to %s", id.String())
}
// remove the annotation set by Kustomize to track the resource
delete(annotations, idAnnotation)
if len(annotations) == 0 {
annotations = nil
}
r.SetAnnotations(annotations)
// update the ResMap resource value with the transformed object
res.Kunstructured = r.Kunstructured
}
return nil
}
// updateResourceOptions updates the generator options for each resource in the
// given ResMap based on plugin provided annotations.
func (p *ExecPlugin) UpdateResourceOptions(rm resmap.ResMap) (resmap.ResMap, error) {
for _, r := range rm.Resources() {
// Disable name hashing by default and require plugin to explicitly
// request it for each resource.
annotations := r.GetAnnotations()
behavior := annotations[BehaviorAnnotation]
var needsHash bool
if val, ok := annotations[HashAnnotation]; ok {
b, err := strconv.ParseBool(val)
if err != nil {
return nil, fmt.Errorf(
"the annotation %q contains an invalid value (%q)",
HashAnnotation, val)
}
needsHash = b
}
delete(annotations, HashAnnotation)
delete(annotations, BehaviorAnnotation)
if len(annotations) == 0 {
annotations = nil
}
r.SetAnnotations(annotations)
r.SetOptions(types.NewGenArgs(
&types.GeneratorArgs{
Behavior: behavior,
Options: &types.GeneratorOptions{DisableNameSuffixHash: !needsHash}}))
}
return rm, nil
}

View File

@@ -4,6 +4,7 @@
package execplugin_test package execplugin_test
import ( import (
"fmt"
"strings" "strings"
"testing" "testing"
@@ -16,6 +17,7 @@ import (
"sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource" "sigs.k8s.io/kustomize/api/resource"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest" valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
) )
func TestExecPluginConfig(t *testing.T) { func TestExecPluginConfig(t *testing.T) {
@@ -89,3 +91,107 @@ metadata:
t.Fatalf("unexpected arg array: %#v", p.Args()) t.Fatalf("unexpected arg array: %#v", p.Args())
} }
} }
func makeConfigMap(rf *resource.Factory, name, behavior string, hashValue *string) *resource.Resource {
r := rf.FromMap(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{"name": name},
})
annotations := map[string]string{}
if behavior != "" {
annotations[BehaviorAnnotation] = behavior
}
if hashValue != nil {
annotations[HashAnnotation] = *hashValue
}
if len(annotations) > 0 {
r.SetAnnotations(annotations)
}
return r
}
func makeConfigMapOptions(rf *resource.Factory, name, behavior string, disableHash bool) *resource.Resource {
return rf.FromMapAndOption(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{"name": name},
}, &types.GeneratorArgs{
Behavior: behavior,
Options: &types.GeneratorOptions{DisableNameSuffixHash: disableHash}})
}
func strptr(s string) *string {
return &s
}
func TestUpdateResourceOptions(t *testing.T) {
p := NewExecPlugin("")
if err := p.ErrIfNotExecutable(); err == nil {
t.Fatalf("expected unexecutable error")
}
rf := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
in := resmap.New()
expected := resmap.New()
cases := []struct {
behavior string
needsHash bool
hashValue *string
}{
{hashValue: strptr("false")},
{hashValue: strptr("true"), needsHash: true},
{behavior: "replace"},
{behavior: "merge"},
{behavior: "create"},
{behavior: "nonsense"},
{behavior: "merge", hashValue: strptr("false")},
{behavior: "merge", hashValue: strptr("true"), needsHash: true},
}
for i, c := range cases {
name := fmt.Sprintf("test%d", i)
in.Append(makeConfigMap(rf, name, c.behavior, c.hashValue))
expected.Append(makeConfigMapOptions(rf, name, c.behavior, !c.needsHash))
}
actual, err := p.UpdateResourceOptions(in)
if err != nil {
t.Fatalf("unexpected error: %v", err.Error())
}
for i, a := range expected.Resources() {
b := actual.GetByIndex(i)
if b == nil {
t.Fatalf("resource %d missing from processed map", i)
}
if !a.Equals(b) {
t.Errorf("expected %v got %v", a, b)
}
if a.NeedHashSuffix() != b.NeedHashSuffix() {
t.Errorf("")
}
if a.Behavior() != b.Behavior() {
t.Errorf("expected %v got %v", a.Behavior(), b.Behavior())
}
}
}
func TestUpdateResourceOptionsWithInvalidHashAnnotationValues(t *testing.T) {
p := NewExecPlugin("")
if err := p.ErrIfNotExecutable(); err == nil {
t.Fatalf("expected unexecutable error")
}
rf := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
cases := []string{
"",
"FaLsE",
"TrUe",
"potato",
}
for i, c := range cases {
name := fmt.Sprintf("test%d", i)
in := resmap.New()
in.Append(makeConfigMap(rf, name, "", &c))
_, err := p.UpdateResourceOptions(in)
if err == nil {
t.Errorf("expected error from value %q", c)
}
}
}

View File

@@ -1,197 +0,0 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package fnplugin
import (
"bytes"
"fmt"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil"
"sigs.k8s.io/kustomize/kyaml/runfn"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// FnPlugin is the struct to hold function information
type FnPlugin struct {
// Function runner
runFns runfn.RunFns
// Plugin configuration data.
cfg []byte
// Plugin name cache for error output
pluginName string
// PluginHelpers
h *resmap.PluginHelpers
}
func bytesToRNode(yml []byte) (*yaml.RNode, error) {
rnode, err := yaml.Parse(string(yml))
if err != nil {
return nil, err
}
return rnode, nil
}
func resourceToRNode(res *resource.Resource) (*yaml.RNode, error) {
yml, err := res.AsYAML()
if err != nil {
return nil, err
}
return bytesToRNode(yml)
}
// GetFunctionSpec return function spec is there is. Otherwise return nil
func GetFunctionSpec(res *resource.Resource) *runtimeutil.FunctionSpec {
rnode, err := resourceToRNode(res)
if err != nil {
return nil
}
return runtimeutil.GetFunctionSpec(rnode)
}
func toStorageMounts(mounts []string) []runtimeutil.StorageMount {
var sms []runtimeutil.StorageMount
for _, mount := range mounts {
sms = append(sms, runtimeutil.StringToStorageMount(mount))
}
return sms
}
// NewFnPlugin creates a FnPlugin struct
func NewFnPlugin(o *types.FnPluginLoadingOptions) *FnPlugin {
return &FnPlugin{
runFns: runfn.RunFns{
Functions: []*yaml.RNode{},
Network: o.Network,
NetworkName: o.NetworkName,
EnableStarlark: o.EnableStar,
EnableExec: o.EnableExec,
StorageMounts: toStorageMounts(o.Mounts),
},
}
}
// Cfg returns function config
func (p *FnPlugin) Cfg() []byte {
return p.cfg
}
// Config is called by kustomize to pass-in config information
func (p *FnPlugin) Config(h *resmap.PluginHelpers, config []byte) error {
p.h = h
p.cfg = config
fn, err := bytesToRNode(p.cfg)
if err != nil {
return err
}
meta, err := fn.GetMeta()
if err != nil {
return err
}
p.pluginName = fmt.Sprintf("api: %s, kind: %s, name: %s",
meta.APIVersion, meta.Kind, meta.Name)
return nil
}
// Generate is called when run as generator
func (p *FnPlugin) Generate() (resmap.ResMap, error) {
output, err := p.invokePlugin(nil)
if err != nil {
return nil, err
}
rm, err := p.h.ResmapFactory().NewResMapFromBytes(output)
if err != nil {
return nil, err
}
return utils.UpdateResourceOptions(rm)
}
// Transform is called when run as transformer
func (p *FnPlugin) Transform(rm resmap.ResMap) error {
// add ResIds as annotations to all objects so that we can add them back
inputRM, err := utils.GetResMapWithIDAnnotation(rm)
if err != nil {
return err
}
// encode the ResMap so it can be fed to the plugin
resources, err := inputRM.AsYaml()
if err != nil {
return err
}
// invoke the plugin with resources as the input
output, err := p.invokePlugin(resources)
if err != nil {
return fmt.Errorf("%v %s", err, string(output))
}
// update the original ResMap based on the output
return utils.UpdateResMapValues(p.pluginName, p.h, output, rm)
}
func injectAnnotation(input *yaml.RNode, k, v string) error {
err := input.PipeE(yaml.SetAnnotation(k, v))
if err != nil {
return err
}
return nil
}
// invokePlugin uses Function runner to run function as plugin
func (p *FnPlugin) invokePlugin(input []byte) ([]byte, error) {
// get function config rnode
functionConfig, err := bytesToRNode(p.cfg)
if err != nil {
return nil, err
}
// This annotation will let kustomize ingnore this item in output
err = injectAnnotation(functionConfig, "config.kubernetes.io/local-config", "true")
if err != nil {
return nil, err
}
// we need to add config as input for generators. Some of them don't work with FunctionConfig
// and in addition kio.Pipeline won't create anything if there are no objects
// see https://github.com/kubernetes-sigs/kustomize/blob/master/kyaml/kio/kio.go#L93
// Since we added `local-config` annotation so it will be ignored in generator output
// TODO(donnyxia): This is actually not used by generator and only used to bypass a kio limitation.
// Need better solution.
if input == nil {
yaml, err := functionConfig.String()
if err != nil {
return nil, err
}
input = []byte(yaml)
}
// Configure and Execute Fn. We don't need to convert resources to ResourceList here
// because function runtime will do that. See kyaml/fn/runtime/runtimeutil/runtimeutil.go
var ouputBuffer bytes.Buffer
p.runFns.Input = bytes.NewReader(input)
p.runFns.Functions = append(p.runFns.Functions, functionConfig)
p.runFns.Output = &ouputBuffer
err = p.runFns.Execute()
if err != nil {
return nil, errors.Wrap(
err, "couldn't execute function")
}
return ouputBuffer.Bytes(), nil
}

View File

@@ -5,7 +5,6 @@ package loader
import ( import (
"fmt" "fmt"
"log"
"os" "os"
"path/filepath" "path/filepath"
"plugin" "plugin"
@@ -16,8 +15,6 @@ import (
"sigs.k8s.io/kustomize/api/ifc" "sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers" "sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers"
"sigs.k8s.io/kustomize/api/internal/plugins/execplugin" "sigs.k8s.io/kustomize/api/internal/plugins/execplugin"
"sigs.k8s.io/kustomize/api/internal/plugins/fnplugin"
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
"sigs.k8s.io/kustomize/api/konfig" "sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/resid" "sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/resmap"
@@ -25,7 +22,6 @@ import (
"sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/api/types"
) )
// Loader loads plugins using a file loader (a different loader).
type Loader struct { type Loader struct {
pc *types.PluginConfig pc *types.PluginConfig
rf *resmap.Factory rf *resmap.Factory
@@ -111,35 +107,17 @@ func isBuiltinPlugin(res *resource.Resource) bool {
} }
func (l *Loader) loadAndConfigurePlugin( func (l *Loader) loadAndConfigurePlugin(
ldr ifc.Loader, ldr ifc.Loader, v ifc.Validator, res *resource.Resource) (c resmap.Configurable, err error) {
v ifc.Validator,
res *resource.Resource) (c resmap.Configurable, err error) {
if isBuiltinPlugin(res) { if isBuiltinPlugin(res) {
switch l.pc.BpLoadingOptions { // Instead of looking for and loading a .so file, just
case types.BploLoadFromFileSys: // instantiate the plugin from a generated factory
c, err = l.loadPlugin(res) // function (see "pluginator"). Being able to do this
case types.BploUseStaticallyLinked: // is what makes a plugin "builtin".
// Instead of looking for and loading a .so file, c, err = l.makeBuiltinPlugin(res.GetGvk())
// instantiate the plugin from a generated factory } else if l.pc.PluginRestrictions == types.PluginRestrictionsNone {
// function (see "pluginator"). Being able to do this c, err = l.loadPlugin(res.OrgId())
// is what makes a plugin "builtin".
c, err = l.makeBuiltinPlugin(res.GetGvk())
default:
err = fmt.Errorf(
"unknown plugin loader behavior specified: %v",
l.pc.BpLoadingOptions)
}
} else { } else {
switch l.pc.PluginRestrictions { err = types.NewErrOnlyBuiltinPluginsAllowed(res.OrgId().Kind)
case types.PluginRestrictionsNone:
c, err = l.loadPlugin(res)
case types.PluginRestrictionsBuiltinsOnly:
err = types.NewErrOnlyBuiltinPluginsAllowed(res.OrgId().Kind)
default:
err = fmt.Errorf(
"unknown plugin restriction specified: %v",
l.pc.PluginRestrictions)
}
} }
if err != nil { if err != nil {
return nil, err return nil, err
@@ -167,15 +145,7 @@ func (l *Loader) makeBuiltinPlugin(r resid.Gvk) (resmap.Configurable, error) {
return nil, errors.Errorf("unable to load builtin %s", r) return nil, errors.Errorf("unable to load builtin %s", r)
} }
func (l *Loader) loadPlugin(res *resource.Resource) (resmap.Configurable, error) { func (l *Loader) loadPlugin(resId resid.ResId) (resmap.Configurable, error) {
spec := fnplugin.GetFunctionSpec(res)
if spec != nil {
return fnplugin.NewFnPlugin(&l.pc.FnpLoadingOptions), nil
}
return l.loadExecOrGoPlugin(res.OrgId())
}
func (l *Loader) loadExecOrGoPlugin(resId resid.ResId) (resmap.Configurable, error) {
// First try to load the plugin as an executable. // First try to load the plugin as an executable.
p := execplugin.NewExecPlugin(l.absolutePluginPath(resId)) p := execplugin.NewExecPlugin(l.absolutePluginPath(resId))
err := p.ErrIfNotExecutable() err := p.ErrIfNotExecutable()
@@ -213,13 +183,8 @@ func (l *Loader) loadGoPlugin(id resid.ResId) (resmap.Configurable, error) {
if c, ok := registry[regId]; ok { if c, ok := registry[regId]; ok {
return copyPlugin(c), nil return copyPlugin(c), nil
} }
absPath := l.absolutePluginPath(id) + ".so" absPath := l.absolutePluginPath(id)
if !utils.FileExists(absPath) { p, err := plugin.Open(absPath + ".so")
return nil, fmt.Errorf(
"expected file with Go object code at: %s", absPath)
}
log.Printf("Attempting plugin load from '%s'", absPath)
p, err := plugin.Open(absPath)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "plugin %s fails to load", absPath) return nil, errors.Wrapf(err, "plugin %s fails to load", absPath)
} }

View File

@@ -15,7 +15,6 @@ import (
"sigs.k8s.io/kustomize/api/resource" "sigs.k8s.io/kustomize/api/resource"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest" kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest" valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
"sigs.k8s.io/kustomize/api/types"
) )
const ( const (
@@ -59,26 +58,22 @@ func TestLoader(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
generatorConfigs, err := rmF.NewResMapFromBytes([]byte( c, err := konfig.EnabledPluginConfig()
if err != nil {
t.Fatal(err)
}
pLdr := NewLoader(c, rmF)
if pLdr == nil {
t.Fatal("expect non-nil loader")
}
m, err := rmF.NewResMapFromBytes([]byte(
someServiceGenerator + "---\n" + secretGenerator)) someServiceGenerator + "---\n" + secretGenerator))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
for _, behavior := range []types.BuiltinPluginLoadingOptions{ _, err = pLdr.LoadGenerators(
types.BploUseStaticallyLinked, fLdr, valtest_test.MakeFakeValidator(), m)
types.BploLoadFromFileSys} { if err != nil {
c, err := konfig.EnabledPluginConfig(behavior) t.Fatal(err)
if err != nil {
t.Fatal(err)
}
pLdr := NewLoader(c, rmF)
if pLdr == nil {
t.Fatal("expect non-nil loader")
}
_, err = pLdr.LoadGenerators(
fLdr, valtest_test.MakeFakeValidator(), generatorConfigs)
if err != nil {
t.Fatal(err)
}
} }
} }

View File

@@ -1,215 +0,0 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package utils
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strconv"
"time"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/resid"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/yaml"
)
const (
idAnnotation = "kustomize.config.k8s.io/id"
HashAnnotation = "kustomize.config.k8s.io/needs-hash"
BehaviorAnnotation = "kustomize.config.k8s.io/behavior"
)
func GoBin() string {
return filepath.Join(runtime.GOROOT(), "bin", "go")
}
// DeterminePluginSrcRoot guesses where the user
// has her ${g}/${v}/$lower(${k})/${k}.go files.
func DeterminePluginSrcRoot(fSys filesys.FileSystem) (string, error) {
return konfig.FirstDirThatExistsElseError(
"source directory", fSys, []konfig.NotedFunc{
{
Note: "relative to unit test",
F: func() string {
return filepath.Clean(
filepath.Join(
os.Getenv("PWD"),
"..", "..",
konfig.RelPluginHome))
},
},
{
Note: "relative to unit test (internal pkg)",
F: func() string {
return filepath.Clean(
filepath.Join(
os.Getenv("PWD"),
"..", "..", "..", "..",
konfig.RelPluginHome))
},
},
{
Note: "relative to api package",
F: func() string {
return filepath.Clean(
filepath.Join(
os.Getenv("PWD"),
"..", "..", "..",
konfig.RelPluginHome))
},
},
{
Note: "old style $GOPATH",
F: func() string {
return filepath.Join(
os.Getenv("GOPATH"),
"src", konfig.DomainName,
konfig.ProgramName, konfig.RelPluginHome)
},
},
{
Note: "HOME with literal 'gopath'",
F: func() string {
return filepath.Join(
konfig.HomeDir(), "gopath",
"src", konfig.DomainName,
konfig.ProgramName, konfig.RelPluginHome)
},
},
{
Note: "home directory",
F: func() string {
return filepath.Join(
konfig.HomeDir(), konfig.DomainName,
konfig.ProgramName, konfig.RelPluginHome)
},
},
})
}
// FileYoungerThan returns true if the file both exists and has an
// age is <= the Duration argument.
func FileYoungerThan(path string, d time.Duration) bool {
fi, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) {
return false
}
}
return time.Since(fi.ModTime()) <= d
}
// FileModifiedAfter returns true if the file both exists and was
// modified after the given time..
func FileModifiedAfter(path string, t time.Time) bool {
fi, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) {
return false
}
}
return fi.ModTime().After(t)
}
func FileExists(path string) bool {
if _, err := os.Stat(path); err != nil {
if os.IsNotExist(err) {
return false
}
}
return true
}
// GetResMapWithIDAnnotation returns a new copy of the given ResMap with the ResIds annotated in each Resource
func GetResMapWithIDAnnotation(rm resmap.ResMap) (resmap.ResMap, error) {
inputRM := rm.DeepCopy()
for _, r := range inputRM.Resources() {
idString, err := yaml.Marshal(r.CurId())
if err != nil {
return nil, err
}
annotations := r.GetAnnotations()
if annotations == nil {
annotations = make(map[string]string)
}
annotations[idAnnotation] = string(idString)
r.SetAnnotations(annotations)
}
return inputRM, nil
}
// UpdateResMapValues updates the Resource value in the given ResMap
// with the emitted Resource values in output.
func UpdateResMapValues(pluginName string, h *resmap.PluginHelpers, output []byte, rm resmap.ResMap) error {
outputRM, err := h.ResmapFactory().NewResMapFromBytes(output)
if err != nil {
return err
}
for _, r := range outputRM.Resources() {
// for each emitted Resource, find the matching Resource in the original ResMap
// using its id
annotations := r.GetAnnotations()
idString, ok := annotations[idAnnotation]
if !ok {
return fmt.Errorf("the transformer %s should not remove annotation %s",
pluginName, idAnnotation)
}
id := resid.ResId{}
err := yaml.Unmarshal([]byte(idString), &id)
if err != nil {
return err
}
res, err := rm.GetByCurrentId(id)
if err != nil {
return fmt.Errorf("unable to find unique match to %s", id.String())
}
// remove the annotation set by Kustomize to track the resource
delete(annotations, idAnnotation)
if len(annotations) == 0 {
annotations = nil
}
r.SetAnnotations(annotations)
// update the resource value with the transformed object
res.ResetPrimaryData(r)
}
return nil
}
// UpdateResourceOptions updates the generator options for each resource in the
// given ResMap based on plugin provided annotations.
func UpdateResourceOptions(rm resmap.ResMap) (resmap.ResMap, error) {
for _, r := range rm.Resources() {
// Disable name hashing by default and require plugin to explicitly
// request it for each resource.
annotations := r.GetAnnotations()
behavior := annotations[BehaviorAnnotation]
var needsHash bool
if val, ok := annotations[HashAnnotation]; ok {
b, err := strconv.ParseBool(val)
if err != nil {
return nil, fmt.Errorf(
"the annotation %q contains an invalid value (%q)",
HashAnnotation, val)
}
needsHash = b
}
delete(annotations, HashAnnotation)
delete(annotations, BehaviorAnnotation)
if len(annotations) == 0 {
annotations = nil
}
r.SetAnnotations(annotations)
r.SetOptions(types.NewGenArgs(
&types.GeneratorArgs{
Behavior: behavior,
Options: &types.GeneratorOptions{DisableNameSuffixHash: !needsHash}}))
}
return rm, nil
}

View File

@@ -1,127 +0,0 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package utils
import (
"fmt"
"path/filepath"
"strings"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
)
func TestDeterminePluginSrcRoot(t *testing.T) {
actual, err := DeterminePluginSrcRoot(filesys.MakeFsOnDisk())
if err != nil {
t.Error(err)
}
if !filepath.IsAbs(actual) {
t.Errorf("expected absolute path, but got '%s'", actual)
}
if !strings.HasSuffix(actual, konfig.RelPluginHome) {
t.Errorf("expected suffix '%s' in '%s'", konfig.RelPluginHome, actual)
}
}
func makeConfigMap(rf *resource.Factory, name, behavior string, hashValue *string) *resource.Resource {
r := rf.FromMap(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{"name": name},
})
annotations := map[string]string{}
if behavior != "" {
annotations[BehaviorAnnotation] = behavior
}
if hashValue != nil {
annotations[HashAnnotation] = *hashValue
}
if len(annotations) > 0 {
r.SetAnnotations(annotations)
}
return r
}
func makeConfigMapOptions(rf *resource.Factory, name, behavior string, disableHash bool) *resource.Resource {
return rf.FromMapAndOption(map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{"name": name},
}, &types.GeneratorArgs{
Behavior: behavior,
Options: &types.GeneratorOptions{DisableNameSuffixHash: disableHash}})
}
func strptr(s string) *string {
return &s
}
func TestUpdateResourceOptions(t *testing.T) {
rf := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
in := resmap.New()
expected := resmap.New()
cases := []struct {
behavior string
needsHash bool
hashValue *string
}{
{hashValue: strptr("false")},
{hashValue: strptr("true"), needsHash: true},
{behavior: "replace"},
{behavior: "merge"},
{behavior: "create"},
{behavior: "nonsense"},
{behavior: "merge", hashValue: strptr("false")},
{behavior: "merge", hashValue: strptr("true"), needsHash: true},
}
for i, c := range cases {
name := fmt.Sprintf("test%d", i)
in.Append(makeConfigMap(rf, name, c.behavior, c.hashValue))
expected.Append(makeConfigMapOptions(rf, name, c.behavior, !c.needsHash))
}
actual, err := UpdateResourceOptions(in)
if err != nil {
t.Fatalf("unexpected error: %v", err.Error())
}
for i, a := range expected.Resources() {
b := actual.GetByIndex(i)
if b == nil {
t.Fatalf("resource %d missing from processed map", i)
}
if !a.Equals(b) {
t.Errorf("expected %v got %v", a, b)
}
if a.NeedHashSuffix() != b.NeedHashSuffix() {
t.Errorf("")
}
if a.Behavior() != b.Behavior() {
t.Errorf("expected %v got %v", a.Behavior(), b.Behavior())
}
}
}
func TestUpdateResourceOptionsWithInvalidHashAnnotationValues(t *testing.T) {
rf := resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())
cases := []string{
"",
"FaLsE",
"TrUe",
"potato",
}
for i, c := range cases {
name := fmt.Sprintf("test%d", i)
in := resmap.New()
in.Append(makeConfigMap(rf, name, "", &c))
_, err := UpdateResourceOptions(in)
if err == nil {
t.Errorf("expected error from value %q", c)
}
}
}

View File

@@ -4,6 +4,7 @@
package target package target
import ( import (
"bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"strings" "strings"
@@ -54,12 +55,9 @@ func (kt *KustTarget) Load() error {
if err != nil { if err != nil {
return err return err
} }
content, err = types.FixKustomizationPreUnmarshalling(content) content = types.FixKustomizationPreUnmarshalling(content)
if err != nil {
return err
}
var k types.Kustomization var k types.Kustomization
err = k.Unmarshal(content) err = unmarshal(content, &k)
if err != nil { if err != nil {
return err return err
} }
@@ -74,14 +72,6 @@ func (kt *KustTarget) Load() error {
return nil return nil
} }
// Kustomization returns a copy of the immutable, internal kustomization object.
func (kt *KustTarget) Kustomization() types.Kustomization {
var result types.Kustomization
b, _ := json.Marshal(*kt.kustomization)
json.Unmarshal(b, &result)
return result
}
func loadKustFile(ldr ifc.Loader) ([]byte, error) { func loadKustFile(ldr ifc.Loader) ([]byte, error) {
var content []byte var content []byte
match := 0 match := 0
@@ -103,13 +93,28 @@ func loadKustFile(ldr ifc.Loader) ([]byte, error) {
} }
} }
func unmarshal(y []byte, o interface{}) error {
j, err := yaml.YAMLToJSON(y)
if err != nil {
return err
}
dec := json.NewDecoder(bytes.NewReader(j))
dec.DisallowUnknownFields()
return dec.Decode(o)
}
// MakeCustomizedResMap creates a fully customized ResMap // MakeCustomizedResMap creates a fully customized ResMap
// per the instructions contained in its kustomiztion instance. // per the instructions contained in its kustomiztion instance.
func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) { func (kt *KustTarget) MakeCustomizedResMap() (resmap.ResMap, error) {
return kt.makeCustomizedResMap() return kt.makeCustomizedResMap(types.GarbageIgnore)
} }
func (kt *KustTarget) makeCustomizedResMap() (resmap.ResMap, error) { func (kt *KustTarget) MakePruneConfigMap() (resmap.ResMap, error) {
return kt.makeCustomizedResMap(types.GarbageCollect)
}
func (kt *KustTarget) makeCustomizedResMap(
garbagePolicy types.GarbagePolicy) (resmap.ResMap, error) {
ra, err := kt.AccumulateTarget() ra, err := kt.AccumulateTarget()
if err != nil { if err != nil {
return nil, err return nil, err
@@ -136,6 +141,11 @@ func (kt *KustTarget) makeCustomizedResMap() (resmap.ResMap, error) {
return nil, err return nil, err
} }
err = kt.computeInventory(ra, garbagePolicy)
if err != nil {
return nil, err
}
return ra.ResMap(), nil return ra.ResMap(), nil
} }
@@ -149,27 +159,46 @@ func (kt *KustTarget) addHashesToNames(
return ra.Transform(p) return ra.Transform(p)
} }
func (kt *KustTarget) computeInventory(
ra *accumulator.ResAccumulator, garbagePolicy types.GarbagePolicy) error {
inv := kt.kustomization.Inventory
if inv == nil {
return nil
}
if inv.Type != "ConfigMap" {
return fmt.Errorf("don't know how to do that")
}
if inv.ConfigMap.Namespace != kt.kustomization.Namespace {
return fmt.Errorf("namespace mismatch")
}
var c struct {
Policy string
types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty"`
}
c.Name = inv.ConfigMap.Name
c.Namespace = inv.ConfigMap.Namespace
c.Policy = garbagePolicy.String()
p := builtins.NewInventoryTransformerPlugin()
err := kt.configureBuiltinPlugin(p, c, builtinhelpers.InventoryTransformer)
if err != nil {
return err
}
return ra.Transform(p)
}
// AccumulateTarget returns a new ResAccumulator, // AccumulateTarget returns a new ResAccumulator,
// holding customized resources and the data/rules used // holding customized resources and the data/rules used
// to do so. The name back references and vars are // to do so. The name back references and vars are
// not yet fixed. // not yet fixed.
func (kt *KustTarget) AccumulateTarget() ( func (kt *KustTarget) AccumulateTarget() (
ra *accumulator.ResAccumulator, err error) { ra *accumulator.ResAccumulator, err error) {
return kt.accumulateTarget(accumulator.MakeEmptyAccumulator()) ra = accumulator.MakeEmptyAccumulator()
} err = kt.accumulateResources(ra, kt.kustomization.Resources)
// 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) (
resRa *accumulator.ResAccumulator, err error) {
ra, err = kt.accumulateResources(ra, kt.kustomization.Resources)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "accumulating resources") return nil, errors.Wrap(err, "accumulating resources")
} }
ra, err = kt.accumulateComponents(ra, kt.kustomization.Components)
if err != nil {
return nil, errors.Wrap(err, "accumulating components")
}
tConfig, err := builtinconfig.MakeTransformerConfig( tConfig, err := builtinconfig.MakeTransformerConfig(
kt.ldr, kt.kustomization.Configurations) kt.ldr, kt.kustomization.Configurations)
if err != nil { if err != nil {
@@ -198,10 +227,6 @@ func (kt *KustTarget) accumulateTarget(ra *accumulator.ResAccumulator) (
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = kt.runValidators(ra)
if err != nil {
return nil, err
}
err = ra.MergeVars(kt.kustomization.Vars) err = ra.MergeVars(kt.kustomization.Vars)
if err != nil { if err != nil {
return nil, errors.Wrapf( return nil, errors.Wrapf(
@@ -238,7 +263,7 @@ func (kt *KustTarget) runGenerators(
func (kt *KustTarget) configureExternalGenerators() ([]resmap.Generator, error) { func (kt *KustTarget) configureExternalGenerators() ([]resmap.Generator, error) {
ra := accumulator.MakeEmptyAccumulator() ra := accumulator.MakeEmptyAccumulator()
ra, err := kt.accumulateResources(ra, kt.kustomization.Generators) err := kt.accumulateResources(ra, kt.kustomization.Generators)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -253,7 +278,7 @@ func (kt *KustTarget) runTransformers(ra *accumulator.ResAccumulator) error {
return err return err
} }
r = append(r, lts...) r = append(r, lts...)
lts, err = kt.configureExternalTransformers(kt.kustomization.Transformers) lts, err = kt.configureExternalTransformers()
if err != nil { if err != nil {
return err return err
} }
@@ -262,132 +287,56 @@ func (kt *KustTarget) runTransformers(ra *accumulator.ResAccumulator) error {
return ra.Transform(t) return ra.Transform(t)
} }
func (kt *KustTarget) configureExternalTransformers(transformers []string) ([]resmap.Transformer, error) { func (kt *KustTarget) configureExternalTransformers() ([]resmap.Transformer, error) {
ra := accumulator.MakeEmptyAccumulator() ra := accumulator.MakeEmptyAccumulator()
ra, err := kt.accumulateResources(ra, transformers) err := kt.accumulateResources(ra, kt.kustomization.Transformers)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return kt.pLdr.LoadTransformers(kt.ldr, kt.validator, ra.ResMap()) return kt.pLdr.LoadTransformers(kt.ldr, kt.validator, ra.ResMap())
} }
func (kt *KustTarget) runValidators(ra *accumulator.ResAccumulator) error {
validators, err := kt.configureExternalTransformers(kt.kustomization.Validators)
if err != nil {
return err
}
for _, v := range validators {
// Validators shouldn't modify the resource map
orignal := ra.ResMap().DeepCopy()
err = v.Transform(ra.ResMap())
if err != nil {
return err
}
new := ra.ResMap().DeepCopy()
kt.removeValidatedByLabel(new)
if err = orignal.ErrorIfNotEqualSets(new); err != nil {
return fmt.Errorf("validator shouldn't modify the resource map: %v", err)
}
}
return nil
}
func (kt *KustTarget) removeValidatedByLabel(rm resmap.ResMap) {
resources := rm.Resources()
for _, r := range resources {
labels := r.GetLabels()
if _, found := labels[konfig.ValidatedByLabelKey]; !found {
continue
}
delete(labels, konfig.ValidatedByLabelKey)
if len(labels) == 0 {
r.SetLabels(nil)
} else {
r.SetLabels(labels)
}
}
}
// accumulateResources fills the given resourceAccumulator // accumulateResources fills the given resourceAccumulator
// with resources read from the given list of paths. // with resources read from the given list of paths.
func (kt *KustTarget) accumulateResources( func (kt *KustTarget) accumulateResources(
ra *accumulator.ResAccumulator, paths []string) (*accumulator.ResAccumulator, error) { ra *accumulator.ResAccumulator, paths []string) error {
for _, path := range paths { for _, path := range paths {
// try loading resource as file then as base (directory or git repository) // try loading resource as file then as base (directory or git repository)
if errF := kt.accumulateFile(ra, path); errF != nil { if errF := kt.accumulateFile(ra, path); errF != nil {
ldr, errL := kt.ldr.New(path) ldr, errL := kt.ldr.New(path)
if errL != nil { if errL != nil {
return nil, fmt.Errorf("accumulateFile %q, loader.New %q", errF, errL) return fmt.Errorf("accumulateFile %q, loader.New %q", errF, errL)
} }
var errD error errD := kt.accumulateDirectory(ra, ldr)
ra, errD = kt.accumulateDirectory(ra, ldr, false)
if errD != nil { if errD != nil {
return nil, fmt.Errorf("accumulateFile %q, accumulateDirector: %q", errF, errD) return fmt.Errorf("accumulateFile %q, accumulateDirector: %q", errF, errD)
} }
} }
} }
return ra, nil return nil
}
// accumulateResources fills the given resourceAccumulator
// with resources read from the given list of paths.
func (kt *KustTarget) accumulateComponents(
ra *accumulator.ResAccumulator, paths []string) (*accumulator.ResAccumulator, error) {
for _, path := range paths {
// Components always refer to directories
ldr, errL := kt.ldr.New(path)
if errL != nil {
return nil, fmt.Errorf("loader.New %q", errL)
}
var errD error
ra, errD = kt.accumulateDirectory(ra, ldr, true)
if errD != nil {
return nil, fmt.Errorf("accumulateDirectory: %q", errD)
}
}
return ra, nil
} }
func (kt *KustTarget) accumulateDirectory( func (kt *KustTarget) accumulateDirectory(
ra *accumulator.ResAccumulator, ldr ifc.Loader, isComponent bool) (*accumulator.ResAccumulator, error) { ra *accumulator.ResAccumulator, ldr ifc.Loader) error {
defer ldr.Cleanup() defer ldr.Cleanup()
subKt := NewKustTarget( subKt := NewKustTarget(
ldr, kt.validator, kt.rFactory, kt.tFactory, kt.pLdr) ldr, kt.validator, kt.rFactory, kt.tFactory, kt.pLdr)
err := subKt.Load() err := subKt.Load()
if err != nil { if err != nil {
return nil, errors.Wrapf( return errors.Wrapf(
err, "couldn't make target for path '%s'", ldr.Root()) err, "couldn't make target for path '%s'", ldr.Root())
} }
if isComponent && subKt.kustomization.Kind != types.ComponentKind { subRa, err := subKt.AccumulateTarget()
return nil, fmt.Errorf(
"expected kind '%s' for path '%s' but got '%s'", types.ComponentKind, ldr.Root(), subKt.kustomization.Kind)
} else if !isComponent && subKt.kustomization.Kind == types.ComponentKind {
return nil, fmt.Errorf(
"expected kind != '%s' for path '%s'", types.ComponentKind, ldr.Root())
}
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)
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()
}
if err != nil { if err != nil {
return nil, errors.Wrapf( return errors.Wrapf(
err, "recursed accumulation of path '%s'", ldr.Root()) err, "recursed accumulation of path '%s'", ldr.Root())
} }
err = ra.MergeAccumulator(subRa) err = ra.MergeAccumulator(subRa)
if err != nil { if err != nil {
return nil, errors.Wrapf( return errors.Wrapf(
err, "recursed merging from path '%s'", ldr.Root()) err, "recursed merging from path '%s'", ldr.Root())
} }
return ra, nil return nil
} }
func (kt *KustTarget) accumulateFile( func (kt *KustTarget) accumulateFile(
@@ -415,8 +364,7 @@ func (kt *KustTarget) configureBuiltinPlugin(
} }
err = p.Config(resmap.NewPluginHelpers(kt.ldr, kt.validator, kt.rFactory), y) err = p.Config(resmap.NewPluginHelpers(kt.ldr, kt.validator, kt.rFactory), y)
if err != nil { if err != nil {
return errors.Wrapf( return errors.Wrapf(err, "builtin %s config: %v", bpt, y)
err, "trouble configuring builtin %s with config: `\n%s`", bpt, string(y))
} }
return nil return nil
} }

View File

@@ -4,8 +4,6 @@
package target package target
import ( import (
"fmt"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig" "sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers" "sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers"
"sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/resmap"
@@ -292,10 +290,4 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func(
} }
return return
}, },
// No kustomization file keyword for this yet.
builtinhelpers.ValueAddTransformer: func(
kt *KustTarget, bpt builtinhelpers.BuiltinPluginType, f tFactory, tc *builtinconfig.TransformerConfig) (
result []resmap.Transformer, err error) {
return nil, fmt.Errorf("valueadd keyword not yet defined")
},
} }

View File

@@ -5,99 +5,22 @@ package target_test
import ( import (
"encoding/base64" "encoding/base64"
"reflect"
"testing" "testing"
"github.com/stretchr/testify/require" "sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/ifc" "sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct" "sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource" "sigs.k8s.io/kustomize/api/resource"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest" kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
"sigs.k8s.io/kustomize/api/types"
) )
// KustTarget is primarily tested in the krusty package with // KustTarget is primarily tested in the krusty package with
// high level tests. // high level tests.
func TestLoad(t *testing.T) {
th := kusttest_test.MakeHarness(t)
expectedTypeMeta := types.TypeMeta{
APIVersion: "kustomize.config.k8s.io/v1beta1",
Kind: "Kustomization",
}
testCases := map[string]struct {
errContains string
content string
k types.Kustomization
}{
"empty": {
// no content
k: types.Kustomization{
TypeMeta: expectedTypeMeta,
},
},
"nonsenseLatin": {
errContains: "error converting YAML to JSON",
content: `
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
`,
},
"simple": {
content: `
commonLabels:
app: nginx
`,
k: types.Kustomization{
TypeMeta: expectedTypeMeta,
CommonLabels: map[string]string{"app": "nginx"},
},
},
"commented": {
content: `
# Licensed to the Blah Blah Software Foundation
# ...
# yada yada yada.
commonLabels:
app: nginx
`,
k: types.Kustomization{
TypeMeta: expectedTypeMeta,
CommonLabels: map[string]string{"app": "nginx"},
},
},
}
kt := makeKustTargetWithRf(
t, th.GetFSys(), "/",
resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl()))
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
th.WriteK("/", tc.content)
err := kt.Load()
if tc.errContains != "" {
require.NotNilf(t, err, "expected error containing: `%s`", tc.errContains)
require.Contains(t, err.Error(), tc.errContains)
} else {
require.Nilf(t, err, "got error: %v", err)
k := kt.Kustomization()
require.Condition(t, func() bool {
return reflect.DeepEqual(tc.k, k)
}, "expected %v, got %v", tc.k, k)
}
})
}
}
func TestMakeCustomizedResMap(t *testing.T) { func TestMakeCustomizedResMap(t *testing.T) {
th := kusttest_test.MakeHarness(t) fSys := filesys.MakeFsInMemory()
th := kusttest_test.MakeHarnessWithFs(t, fSys)
th.WriteK("/whatever", ` th.WriteK("/whatever", `
apiVersion: kustomize.config.k8s.io/v1beta1 apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization kind: Kustomization
@@ -244,13 +167,8 @@ metadata:
} }
} }
kt := makeKustTargetWithRf( actual, err := makeKustTargetWithRf(
t, th.GetFSys(), "/whatever", resFactory) t, fSys, "/whatever", resFactory).MakeCustomizedResMap()
err := kt.Load()
if err != nil {
t.Fatalf("unexpected Resources error %v", err)
}
actual, err := kt.MakeCustomizedResMap()
if err != nil { if err != nil {
t.Fatalf("unexpected Resources error %v", err) t.Fatalf("unexpected Resources error %v", err)
} }

View File

@@ -18,17 +18,13 @@ import (
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest" valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
) )
func makeAndLoadKustTarget( func makeKustTarget(
t *testing.T, t *testing.T,
fSys filesys.FileSystem, fSys filesys.FileSystem,
root string) *target.KustTarget { root string) *target.KustTarget {
kt := makeKustTargetWithRf( return makeKustTargetWithRf(
t, fSys, root, t, fSys, root,
resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl())) resource.NewFactory(kunstruct.NewKunstructuredFactoryImpl()))
if err := kt.Load(); err != nil {
t.Fatalf("Unexpected load error %v", err)
}
return kt
} }
func makeKustTargetWithRf( func makeKustTargetWithRf(
@@ -42,10 +38,14 @@ func makeKustTargetWithRf(
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
return target.NewKustTarget( kt := target.NewKustTarget(
ldr, ldr,
valtest_test.MakeFakeValidator(), valtest_test.MakeFakeValidator(),
rf, rf,
transformer.NewFactoryImpl(), transformer.NewFactoryImpl(),
pLdr.NewLoader(pc, rf)) pLdr.NewLoader(pc, rf))
if err = kt.Load(); err != nil {
t.Fatalf("Unexpected construction error %v", err)
}
return kt
} }

View File

@@ -64,7 +64,7 @@ vars:
name: heron name: heron
apiVersion: v300 apiVersion: v300
`) `)
ra, err := makeAndLoadKustTarget( ra, err := makeKustTarget(
t, th.GetFSys(), "/app").AccumulateTarget() t, th.GetFSys(), "/app").AccumulateTarget()
if err != nil { if err != nil {
t.Fatalf("Err: %v", err) t.Fatalf("Err: %v", err)
@@ -119,7 +119,7 @@ resources:
- ../o1 - ../o1
`) `)
ra, err := makeAndLoadKustTarget( ra, err := makeKustTarget(
t, th.GetFSys(), "/app/overlays/o2").AccumulateTarget() t, th.GetFSys(), "/app/overlays/o2").AccumulateTarget()
if err != nil { if err != nil {
t.Fatalf("Err: %v", err) t.Fatalf("Err: %v", err)
@@ -176,7 +176,7 @@ vars:
resources: resources:
- ../o1 - ../o1
`) `)
_, err := makeAndLoadKustTarget( _, err := makeKustTarget(
t, th.GetFSys(), "/app/overlays/o2").AccumulateTarget() t, th.GetFSys(), "/app/overlays/o2").AccumulateTarget()
if err == nil { if err == nil {
t.Fatalf("expected var collision") t.Fatalf("expected var collision")

View File

@@ -0,0 +1,12 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package inventory
const (
// Annotation that contains the inventory content.
ContentAnnotation = "kustomize.config.k8s.io/Inventory"
// Annotation for inventory content hash.
HashAnnotation = "kustomize.config.k8s.io/InventoryHash"
)

235
api/inventory/inventory.go Normal file
View File

@@ -0,0 +1,235 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package inventory
import (
"encoding/json"
"sigs.k8s.io/kustomize/api/resid"
)
//Refs is a reference map. Each key is the id
//of a k8s resource, and each value is a list of
//object ids that refer back to the object in the
//key.
//For example, the key could correspond to a
//ConfigMap, and the list of values might include
//several different Deployments that get data from
//that ConfigMap (and thus refer to it).
//References are important in inventory management
//because one may not delete an object before all
//objects referencing it have been removed.
type Refs map[resid.ResId][]resid.ResId
func NewRefs() Refs {
return Refs{}
}
// Merge merges a Refs into an existing Refs
func (rf Refs) Merge(b Refs) Refs {
for key, value := range b {
_, ok := rf[key]
if ok {
rf[key] = append(rf[key], value...)
} else {
rf[key] = value
}
}
return rf
}
// removeIfContains removes the reference relationship
// a --> b
// from the Refs if it exists
func (rf Refs) RemoveIfContains(a, b resid.ResId) {
refs, ok := rf[a]
if !ok {
return
}
for i, ref := range refs {
if ref.Equals(b) {
rf[a] = append(refs[:i], refs[i+1:]...)
break
}
}
}
//Inventory is a an object intended for
//serialization into the annotations of a so-called
//apply-root object (a ConfigMap, an Application,
//etc.) living in the cluster. This apply-root
//object is written as part of an apply operation as
//a means to record overall cluster state changes.
//At the end of a successful apply, the "current"
//field in Inventory will be a map whose keys all
//correspond to an object in the cluster, and
//"previous" will be the previous such set (an empty
//set on the first apply).
//An Inventory allows the Prune method to work.
type Inventory struct {
Current Refs `json:"current,omitempty"`
Previous Refs `json:"previous,omitempty"`
}
// NewInventory returns an Inventory object
func NewInventory() *Inventory {
return &Inventory{
Current: NewRefs(),
Previous: NewRefs(),
}
}
// UpdateCurrent updates the Inventory given a
// new current Refs
// The existing Current refs is merged into
// the Previous refs
func (a *Inventory) UpdateCurrent(curref Refs) *Inventory {
if len(a.Previous) > 0 {
a.Previous.Merge(a.Current)
} else {
a.Previous = a.Current
}
a.Current = curref
return a
}
func (a *Inventory) removeNewlyOrphanedItemsFromPrevious() []resid.ResId {
var results []resid.ResId
for item, refs := range a.Previous {
if _, ok := a.Current[item]; ok {
delete(a.Previous, item)
continue
}
var newRefs []resid.ResId
toDelete := true
for _, ref := range refs {
if _, ok := a.Current[ref]; ok {
toDelete = false
newRefs = append(newRefs, ref)
}
}
if toDelete {
results = append(results, item)
delete(a.Previous, item)
} else {
a.Previous[item] = newRefs
}
}
return results
}
func (a *Inventory) removeOrphanedItemsFromPreviousThatAreNotInCurrent() []resid.ResId {
var results []resid.ResId
for item, refs := range a.Previous {
if _, ok := a.Current[item]; ok {
continue
}
if len(refs) == 0 {
results = append(results, item)
delete(a.Previous, item)
}
}
return results
}
func (a *Inventory) removeOrphanedItemsFromPreviousThatAreInCurrent() {
//Remove references from Previous that are already in Current refs
for item, refs := range a.Current {
for _, ref := range refs {
a.Previous.RemoveIfContains(item, ref)
}
}
//Remove items from Previous that are already in Current refs
for item, refs := range a.Previous {
if len(refs) == 0 {
if _, ok := a.Current[item]; ok {
delete(a.Previous, item)
}
}
}
}
// Prune computes the diff of Current refs and Previous refs
// and returns a list of Items that can be pruned.
// An item that can be pruned shows up only in Previous refs.
// Prune also updates the Previous refs with those items removed
func (a *Inventory) Prune() []resid.ResId {
a.removeOrphanedItemsFromPreviousThatAreInCurrent()
// These are candidates for deletion from the cluster.
removable1 := a.removeOrphanedItemsFromPreviousThatAreNotInCurrent()
removable2 := a.removeNewlyOrphanedItemsFromPrevious()
return append(removable1, removable2...)
}
// inventory is the internal type used for serialization
type inventory struct {
Current map[string][]resid.ResId `json:"current,omitempty"`
Previous map[string][]resid.ResId `json:"previous,omitempty"`
}
func (a *Inventory) toInternalType() inventory {
prev := map[string][]resid.ResId{}
curr := map[string][]resid.ResId{}
for id, refs := range a.Current {
curr[id.String()] = refs
}
for id, refs := range a.Previous {
prev[id.String()] = refs
}
return inventory{
Current: curr,
Previous: prev,
}
}
func (a *Inventory) fromInternalType(i *inventory) {
for s, refs := range i.Previous {
a.Previous[resid.FromString(s)] = refs
}
for s, refs := range i.Current {
a.Current[resid.FromString(s)] = refs
}
}
func (a *Inventory) marshal() ([]byte, error) {
return json.Marshal(a.toInternalType())
}
func (a *Inventory) unMarshal(data []byte) error {
inv := &inventory{
Current: map[string][]resid.ResId{},
Previous: map[string][]resid.ResId{},
}
err := json.Unmarshal(data, inv)
if err != nil {
return err
}
a.fromInternalType(inv)
return nil
}
// UpdateAnnotations update the annotation map
func (a *Inventory) UpdateAnnotations(annot map[string]string) error {
data, err := a.marshal()
if err != nil {
return err
}
annot[ContentAnnotation] = string(data)
return nil
}
// LoadFromAnnotation loads the Inventory date from the annotation map
func (a *Inventory) LoadFromAnnotation(annot map[string]string) error {
value, ok := annot[ContentAnnotation]
if ok {
return a.unMarshal([]byte(value))
}
return nil
}

View File

@@ -0,0 +1,60 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package inventory_test
import (
"testing"
. "sigs.k8s.io/kustomize/api/inventory"
"sigs.k8s.io/kustomize/api/resid"
)
func makeRefs() (Refs, Refs) {
a := resid.FromString("G1_V1_K1|ns1|nm1")
b := resid.FromString("G2_V2_K2|ns2|nm2")
c := resid.FromString("G3_V3_K3|ns3|nm3")
current := NewRefs()
current[a] = []resid.ResId{b, c}
current[b] = []resid.ResId{}
current[c] = []resid.ResId{}
newRefs := NewRefs()
newRefs[a] = []resid.ResId{b}
newRefs[b] = []resid.ResId{}
return current, newRefs
}
func TestInventory(t *testing.T) {
inventory := NewInventory()
curref, _ := makeRefs()
inventory.UpdateCurrent(curref)
if len(inventory.Current) != 3 {
t.Fatalf("not getting the correct inventory %v", inventory)
}
curref, newref := makeRefs()
inventory.UpdateCurrent(curref)
if len(inventory.Current) != 3 {
t.Fatalf("not getting the corrent inventory %v", inventory)
}
if len(inventory.Previous) != 3 {
t.Fatalf("not getting the corrent inventory %v", inventory)
}
items := inventory.Prune()
if len(items) != 0 {
t.Fatalf("not getting the corrent items %v", items)
}
if len(inventory.Previous) != 0 {
t.Fatalf("not getting the corrent inventory %v", inventory)
}
inventory.UpdateCurrent(newref)
items = inventory.Prune()
if len(items) != 1 {
t.Fatalf("not getting the corrent items %v", items)
}
if len(inventory.Previous) != 0 {
t.Fatalf("not getting the corrent inventory %v", inventory.Previous)
}
}

View File

@@ -78,7 +78,6 @@ func secretHash(sec *corev1.Secret) (string, error) {
// encodeConfigMap encodes a ConfigMap. // encodeConfigMap encodes a ConfigMap.
// Data, Kind, and Name are taken into account. // Data, Kind, and Name are taken into account.
// BinaryData is included if it's not empty to avoid useless key in output.
func encodeConfigMap(cm *corev1.ConfigMap) (string, error) { func encodeConfigMap(cm *corev1.ConfigMap) (string, error) {
// json.Marshal sorts the keys in a stable order in the encoding // json.Marshal sorts the keys in a stable order in the encoding
m := map[string]interface{}{"kind": "ConfigMap", "name": cm.Name, "data": cm.Data} m := map[string]interface{}{"kind": "ConfigMap", "name": cm.Name, "data": cm.Data}
@@ -94,14 +93,9 @@ func encodeConfigMap(cm *corev1.ConfigMap) (string, error) {
// encodeSecret encodes a Secret. // encodeSecret encodes a Secret.
// Data, Kind, Name, and Type are taken into account. // Data, Kind, Name, and Type are taken into account.
// StringData is included if it's not empty to avoid useless key in output.
func encodeSecret(sec *corev1.Secret) (string, error) { func encodeSecret(sec *corev1.Secret) (string, error) {
// json.Marshal sorts the keys in a stable order in the encoding // json.Marshal sorts the keys in a stable order in the encoding
m := map[string]interface{}{"kind": "Secret", "type": sec.Type, "name": sec.Name, "data": sec.Data} data, err := json.Marshal(map[string]interface{}{"kind": "Secret", "type": sec.Type, "name": sec.Name, "data": sec.Data})
if len(sec.StringData) > 0 {
m["stringData"] = sec.StringData
}
data, err := json.Marshal(m)
if err != nil { if err != nil {
return "", err return "", err
} }

View File

@@ -58,10 +58,6 @@ func TestSecretHash(t *testing.T) {
{"one key", &corev1.Secret{Type: "my-type", Data: map[string][]byte{"one": []byte("")}}, "74bd68bm66", ""}, {"one key", &corev1.Secret{Type: "my-type", Data: map[string][]byte{"one": []byte("")}}, "74bd68bm66", ""},
// three keys (tests sorting order) // three keys (tests sorting order)
{"three keys", &corev1.Secret{Type: "my-type", Data: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")}}, "dgcb6h9tmk", ""}, {"three keys", &corev1.Secret{Type: "my-type", Data: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")}}, "dgcb6h9tmk", ""},
// with stringdata
{"stringdata", &corev1.Secret{Type: "my-type", Data: map[string][]byte{"one": []byte("")}, StringData: map[string]string{"two": "2"}}, "ckm7f798g2", ""},
// empty stringdata
{"empty stringdata", &corev1.Secret{Type: "my-type", Data: map[string][]byte{"one": []byte("")}, StringData: map[string]string{}}, "74bd68bm66", ""},
} }
for _, c := range cases { for _, c := range cases {
@@ -129,12 +125,6 @@ func TestEncodeSecret(t *testing.T) {
Data: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")}, Data: map[string][]byte{"two": []byte("2"), "one": []byte(""), "three": []byte("3")},
}, },
`{"data":{"one":"","three":"Mw==","two":"Mg=="},"kind":"Secret","name":"","type":"my-type"}`, ""}, `{"data":{"one":"","three":"Mw==","two":"Mg=="},"kind":"Secret","name":"","type":"my-type"}`, ""},
// with stringdata
{"stringdata", &corev1.Secret{Type: "my-type", Data: map[string][]byte{"one": []byte("")}, StringData: map[string]string{"two": "2"}},
`{"data":{"one":""},"kind":"Secret","name":"","stringData":{"two":"2"},"type":"my-type"}`, ""},
// empty stringdata
{"empty stringdata", &corev1.Secret{Type: "my-type", Data: map[string][]byte{"one": []byte("")}, StringData: map[string]string{}},
`{"data":{"one":""},"kind":"Secret","name":"","type":"my-type"}`, ""},
} }
for _, c := range cases { for _, c := range cases {
s, err := encodeSecret(c.secret) s, err := encodeSecret(c.secret)

View File

@@ -21,11 +21,6 @@ nameReference:
- path: spec/scaleTargetRef/name - path: spec/scaleTargetRef/name
kind: HorizontalPodAutoscaler kind: HorizontalPodAutoscaler
- kind: StatefulSet
fieldSpecs:
- path: spec/scaleTargetRef/name
kind: HorizontalPodAutoscaler
- kind: ConfigMap - kind: ConfigMap
version: v1 version: v1
fieldSpecs: fieldSpecs:
@@ -252,10 +247,6 @@ nameReference:
kind: Role kind: Role
- path: rules/resourceNames - path: rules/resourceNames
kind: ClusterRole kind: ClusterRole
- path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name
kind: Service
group: serving.knative.dev
version: v1
- kind: Service - kind: Service
version: v1 version: v1

View File

@@ -30,13 +30,4 @@ const (
// A program name, for use in help, finding the XDG_CONFIG_DIR, etc. // A program name, for use in help, finding the XDG_CONFIG_DIR, etc.
ProgramName = "kustomize" ProgramName = "kustomize"
// Label key that indicates the resources are built from Kustomize
ManagedbyLabelKey = "app.kubernetes.io/managed-by"
// An environment variable to turn on/off adding the ManagedByLabelKey
EnableManagedbyLabelEnv = "KUSTOMIZE_ENABLE_MANAGEDBY_LABEL"
// Label key that indicates the resources are validated by a validator
ValidatedByLabelKey = "validated-by"
) )

View File

@@ -35,46 +35,37 @@ const (
// Domain from which kustomize code is imported, for locating // Domain from which kustomize code is imported, for locating
// plugin source code under $GOPATH when GOPATH is defined. // plugin source code under $GOPATH when GOPATH is defined.
DomainName = "sigs.k8s.io" DomainName = "sigs.k8s.io"
// Injected into plugin paths when plugins are disabled.
// Provides a clue in flows that shouldn't happen.
NoPluginHomeSentinal = "/No/non-builtin/plugins!"
) )
func EnabledPluginConfig(b types.BuiltinPluginLoadingOptions) (*types.PluginConfig, error) { func EnabledPluginConfig() (*types.PluginConfig, error) {
dir, err := DefaultAbsPluginHome(filesys.MakeFsOnDisk()) dir, err := DefaultAbsPluginHome(filesys.MakeFsOnDisk())
if err != nil { if err != nil {
return nil, err return nil, err
} }
return MakePluginConfig(types.PluginRestrictionsNone, b, dir), nil return MakePluginConfig(types.PluginRestrictionsNone, dir), nil
} }
func DisabledPluginConfig() *types.PluginConfig { func DisabledPluginConfig() *types.PluginConfig {
return MakePluginConfig( return MakePluginConfig(
types.PluginRestrictionsBuiltinsOnly, types.PluginRestrictionsBuiltinsOnly, NoPluginHomeSentinal)
types.BploUseStaticallyLinked,
NoPluginHomeSentinal)
} }
func MakePluginConfig( func MakePluginConfig(
pr types.PluginRestrictions, pr types.PluginRestrictions, home string) *types.PluginConfig {
b types.BuiltinPluginLoadingOptions,
home string) *types.PluginConfig {
return &types.PluginConfig{ return &types.PluginConfig{
PluginRestrictions: pr, PluginRestrictions: pr,
AbsPluginHome: home, AbsPluginHome: home,
BpLoadingOptions: b,
} }
} }
// Use an obviously erroneous path, in case it's accidentally used.
const NoPluginHomeSentinal = "/no/non-builtin/plugins!"
type NotedFunc struct { type NotedFunc struct {
Note string Note string
F func() string F func() string
} }
// DefaultAbsPluginHome returns the absolute path in the given file
// system to first directory that looks like a good candidate for
// the home of kustomize plugins.
func DefaultAbsPluginHome(fSys filesys.FileSystem) (string, error) { func DefaultAbsPluginHome(fSys filesys.FileSystem) (string, error) {
return FirstDirThatExistsElseError( return FirstDirThatExistsElseError(
"plugin home directory", fSys, []NotedFunc{ "plugin home directory", fSys, []NotedFunc{

View File

@@ -154,8 +154,9 @@ LEGUME=chickpea
`) `)
th.WriteF("/app/overlay/configmap/dummy.txt", th.WriteF("/app/overlay/configmap/dummy.txt",
`Lorem ipsum dolor sit amet, consectetur `Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
`) `)
th.WriteF("/app/overlay/deployment/deployment.yaml", ` th.WriteF("/app/overlay/deployment/deployment.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1
@@ -225,13 +226,13 @@ spec:
spec: spec:
containers: containers:
- env: - env:
- name: foo
value: bar
- name: FOO - name: FOO
valueFrom: valueFrom:
configMapKeyRef: configMapKeyRef:
key: somekey key: somekey
name: test-infra-app-env-ffmd9b969m name: test-infra-app-env-ffmd9b969m
- name: foo
value: bar
image: nginx:1.8.0 image: nginx:1.8.0
name: nginx name: nginx
ports: ports:
@@ -292,7 +293,11 @@ metadata:
--- ---
apiVersion: v1 apiVersion: v1
data: data:
nonsense: "Lorem ipsum dolor sit amet, consectetur\nadipiscing elit, sed do eiusmod tempor\nincididunt ut labore et dolore magna aliqua. \n" nonsense: |
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
kind: ConfigMap kind: ConfigMap
metadata: metadata:
annotations: annotations:
@@ -301,6 +306,6 @@ metadata:
app: mungebot app: mungebot
org: kubernetes org: kubernetes
repo: test-infra repo: test-infra
name: test-infra-app-config-f462h769f9 name: test-infra-app-config-hh272bg5d4
`) `)
} }

View File

@@ -132,54 +132,6 @@ spec:
`) `)
} }
func TestTinyOverlay(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
namePrefix: a-
resources:
- deployment.yaml
`)
th.WriteF("base/deployment.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeployment
spec:
template:
spec:
containers:
- image: whatever
`)
th.WriteK("overlay", `
namePrefix: b-
resources:
- ../base
patchesStrategicMerge:
- depPatch.yaml
`)
th.WriteF("overlay/depPatch.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: myDeployment
spec:
replicas: 999
`)
m := th.Run("overlay", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: b-a-myDeployment
spec:
replicas: 999
template:
spec:
containers:
- image: whatever
`)
}
func writeSmallBase(th kusttest_test.Harness) { func writeSmallBase(th kusttest_test.Harness) {
th.WriteK("/app/base", ` th.WriteK("/app/base", `
namePrefix: a- namePrefix: a-
@@ -264,8 +216,6 @@ func TestSmallOverlay(t *testing.T) {
namePrefix: b- namePrefix: b-
commonLabels: commonLabels:
env: prod env: prod
quotedFruit: "peach"
quotedBoolean: "true"
resources: resources:
- ../base - ../base
patchesStrategicMerge: patchesStrategicMerge:
@@ -299,8 +249,6 @@ metadata:
labels: labels:
app: myApp app: myApp
env: prod env: prod
quotedBoolean: "true"
quotedFruit: peach
name: b-a-myDeployment name: b-a-myDeployment
spec: spec:
replicas: 1000 replicas: 1000
@@ -308,16 +256,12 @@ spec:
matchLabels: matchLabels:
app: myApp app: myApp
env: prod env: prod
quotedBoolean: "true"
quotedFruit: peach
template: template:
metadata: metadata:
labels: labels:
app: myApp app: myApp
backend: awesome backend: awesome
env: prod env: prod
quotedBoolean: "true"
quotedFruit: peach
spec: spec:
containers: containers:
- image: whatever:1.8.0 - image: whatever:1.8.0
@@ -329,8 +273,6 @@ metadata:
labels: labels:
app: myApp app: myApp
env: prod env: prod
quotedBoolean: "true"
quotedFruit: peach
name: b-a-myService name: b-a-myService
spec: spec:
ports: ports:
@@ -339,8 +281,6 @@ spec:
app: myApp app: myApp
backend: bungie backend: bungie
env: prod env: prod
quotedBoolean: "true"
quotedFruit: peach
`) `)
} }

View File

@@ -1,670 +0,0 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package krusty_test
import (
"fmt"
"strings"
"testing"
"sigs.k8s.io/kustomize/api/konfig"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
type FileGen func(kusttest_test.Harness)
func writeC(path string, content string) FileGen {
return func(th kusttest_test.Harness) {
th.WriteC(path, content)
}
}
func writeF(path string, content string) FileGen {
return func(th kusttest_test.Harness) {
th.WriteF(path, content)
}
}
func writeK(path string, content string) FileGen {
return func(th kusttest_test.Harness) {
th.WriteK(path, content)
}
}
func writeTestBase(th kusttest_test.Harness) {
th.WriteK("/app/base", `
resources:
- deploy.yaml
configMapGenerator:
- name: my-configmap
literals:
- testValue=1
- otherValue=10
`)
th.WriteF("/app/base/deploy.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: storefront
spec:
replicas: 1
`)
}
func writeTestComponent(th kusttest_test.Harness) {
th.WriteC("/app/comp", `
namePrefix: comp-
replicas:
- name: storefront
count: 3
resources:
- stub.yaml
configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- testValue=2
- compValue=5
`)
th.WriteF("/app/comp/stub.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: stub
spec:
replicas: 1
`)
}
func writeOverlayProd(th kusttest_test.Harness) {
th.WriteK("/app/prod", `
resources:
- ../base
- db
components:
- ../comp
`)
writeDB(th)
}
func writeDB(th kusttest_test.Harness) {
deployment("db", "/app/prod/db")(th)
}
func deployment(name string, path string) FileGen {
return writeF(path, fmt.Sprintf(`
apiVersion: v1
kind: Deployment
metadata:
name: %s
spec:
type: Logical
`, name))
}
func TestComponent(t *testing.T) {
testCases := map[string]struct {
input []FileGen
runPath string
expectedOutput string
}{
// Components are inserted into the resource hierarchy as the parent of those
// resources that come before it in the resources list of the parent Kustomization.
"basic-component": {
input: []FileGen{writeTestBase, writeTestComponent, writeOverlayProd},
runPath: "/app/prod",
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: comp-storefront
spec:
replicas: 3
---
apiVersion: v1
data:
compValue: "5"
otherValue: "10"
testValue: "2"
kind: ConfigMap
metadata:
annotations: {}
labels: {}
name: comp-my-configmap-ct5bgtbccd
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-db
spec:
type: Logical
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-stub
spec:
replicas: 1
`,
},
"multiple-components": {
input: []FileGen{writeTestBase, writeTestComponent, writeDB,
writeC("/app/additionalcomp", `
configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- otherValue=9
`),
writeK("/app/prod", `
resources:
- ../base
- db
components:
- ../comp
- ../additionalcomp
`),
},
runPath: "/app/prod",
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: comp-storefront
spec:
replicas: 3
---
apiVersion: v1
data:
compValue: "5"
otherValue: "9"
testValue: "2"
kind: ConfigMap
metadata:
annotations: {}
labels: {}
name: comp-my-configmap-dgf97tmg6h
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-db
spec:
type: Logical
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-stub
spec:
replicas: 1
`,
},
"nested-components": {
input: []FileGen{writeTestBase, writeTestComponent, writeDB,
writeC("/app/additionalcomp", `
components:
- ../comp
configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- otherValue=9
`),
writeK("/app/prod", `
resources:
- ../base
- db
components:
- ../additionalcomp
`),
},
runPath: "/app/prod",
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: comp-storefront
spec:
replicas: 3
---
apiVersion: v1
data:
compValue: "5"
otherValue: "9"
testValue: "2"
kind: ConfigMap
metadata:
annotations: {}
labels: {}
name: comp-my-configmap-dgf97tmg6h
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-db
spec:
type: Logical
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-stub
spec:
replicas: 1
`,
},
// If a component sets a name prefix on a base, then that base can also be separately included
// without being affected by the component in another branch of the resource tree
"basic-component-with-repeated-base": {
input: []FileGen{writeTestBase, writeTestComponent, writeOverlayProd,
writeK("/app/repeated", `
resources:
- ../base
- ../prod
`),
},
runPath: "/app/repeated",
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: storefront
spec:
replicas: 1
---
apiVersion: v1
data:
otherValue: "10"
testValue: "1"
kind: ConfigMap
metadata:
name: my-configmap-7k9t4h74f8
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-storefront
spec:
replicas: 3
---
apiVersion: v1
data:
compValue: "5"
otherValue: "10"
testValue: "2"
kind: ConfigMap
metadata:
annotations: {}
labels: {}
name: comp-my-configmap-ct5bgtbccd
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-db
spec:
type: Logical
---
apiVersion: v1
kind: Deployment
metadata:
name: comp-stub
spec:
replicas: 1
`,
},
"applying-component-directly-should-be-same-as-kustomization": {
input: []FileGen{writeTestBase, writeTestComponent,
writeC("/app/direct-component", `
resources:
- ../base
configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- compValue=5
- testValue=2
`),
},
runPath: "/app/direct-component",
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: storefront
spec:
replicas: 1
---
apiVersion: v1
data:
compValue: "5"
otherValue: "10"
testValue: "2"
kind: ConfigMap
metadata:
annotations: {}
labels: {}
name: my-configmap-96dt22k28h
`,
},
"missing-optional-component-api-version": {
input: []FileGen{writeTestBase, writeOverlayProd,
writeF("/app/comp/"+konfig.DefaultKustomizationFileName(), `
kind: Component
configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- otherValue=9
`),
},
runPath: "/app/prod",
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: storefront
spec:
replicas: 1
---
apiVersion: v1
data:
otherValue: "9"
testValue: "1"
kind: ConfigMap
metadata:
annotations: {}
labels: {}
name: my-configmap-72cfg2mg5d
---
apiVersion: v1
kind: Deployment
metadata:
name: db
spec:
type: Logical
`,
},
// See how nameSuffix "-b" is also added to the resources included by "comp-a" because they are in the
// accumulator when "comp-b" is accumulated. In practice we could use simple Kustomizations for this example.
"components-can-add-the-same-base-if-the-first-renames-resources": {
input: []FileGen{writeTestBase,
deployment("proxy", "/app/comp-a/proxy.yaml"),
writeC("/app/comp-a", `
resources:
- ../base
nameSuffix: "-a"
`),
writeC("/app/comp-b", `
resources:
- ../base
nameSuffix: "-b"
`),
writeK("/app/prod", `
components:
- ../comp-a
- ../comp-b`),
},
runPath: "/app/prod",
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: storefront-a-b
spec:
replicas: 1
---
apiVersion: v1
data:
otherValue: "10"
testValue: "1"
kind: ConfigMap
metadata:
name: my-configmap-a-b-tfb7c5t69m
---
apiVersion: v1
kind: Deployment
metadata:
name: storefront-b
spec:
replicas: 1
---
apiVersion: v1
data:
otherValue: "10"
testValue: "1"
kind: ConfigMap
metadata:
name: my-configmap-b-8h7b8862bb
`,
},
"multiple-bases-can-add-the-same-component-if-it-doesn-not-define-named-entities": {
input: []FileGen{
writeC("/app/comp", `
namespace: prod
`),
writeK("/app/base-a", `
resources:
- proxy.yaml
components:
- ../comp
`),
deployment("proxy-a", "/app/base-a/proxy.yaml"),
writeK("/app/base-b", `
resources:
- proxy.yaml
components:
- ../comp
`),
deployment("proxy-b", "/app/base-b/proxy.yaml"),
writeK("/app/prod", `
resources:
- proxy.yaml
- ../base-a
- ../base-b
`),
deployment("proxy-prod", "/app/prod/proxy.yaml"),
},
runPath: "/app/prod",
// Note that the namepsace has not been applied to proxy-prod because it was not in scope when the
// component was applied
expectedOutput: `
apiVersion: v1
kind: Deployment
metadata:
name: proxy-prod
spec:
type: Logical
---
apiVersion: v1
kind: Deployment
metadata:
name: proxy-a
namespace: prod
spec:
type: Logical
---
apiVersion: v1
kind: Deployment
metadata:
name: proxy-b
namespace: prod
spec:
type: Logical
`,
},
}
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
th := kusttest_test.MakeHarness(t)
for _, f := range tc.input {
f(th)
}
m := th.Run(tc.runPath, th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, tc.expectedOutput)
})
}
}
func TestComponentErrors(t *testing.T) {
testCases := map[string]struct {
input []FileGen
runPath string
expectedError string
}{
"components-cannot-be-added-to-resources": {
input: []FileGen{writeTestBase, writeTestComponent,
writeK("/app/compinres", `
resources:
- ../base
- ../comp
`),
},
runPath: "app/compinres",
expectedError: "expected kind != 'Component' for path '/app/comp'",
},
"kustomizations-cannot-be-added-to-components": {
input: []FileGen{writeTestBase, writeTestComponent,
writeK("/app/kustincomponents", `
components:
- ../base
- ../comp
`),
},
runPath: "/app/kustincomponents",
expectedError: "accumulating components: accumulateDirectory: \"expected kind 'Component' for path " +
"'/app/base' but got 'Kustomization'",
},
"files-cannot-be-added-to-components-list": {
input: []FileGen{writeTestBase,
writeF("/app/filesincomponents/stub.yaml", `
apiVersion: v1
kind: Deployment
metadata:
name: stub
spec:
replicas: 1
`),
writeK("/app/filesincomponents", `
components:
- stub.yaml
- ../comp
`),
},
runPath: "/app/filesincomponents",
expectedError: "'/app/filesincomponents/stub.yaml' must be a directory to be a root",
},
"invalid-component-api-version": {
input: []FileGen{writeTestBase, writeOverlayProd,
writeF("/app/comp/"+konfig.DefaultKustomizationFileName(), `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Component
configMapGenerator:
- name: my-configmap
behavior: merge
literals:
- otherValue=9
`),
},
runPath: "/app/prod",
expectedError: "apiVersion for Component should be kustomize.config.k8s.io/v1alpha1",
},
"components-cannot-add-the-same-resource": {
input: []FileGen{writeTestBase,
writeC("/app/comp-a", `
resources:
- proxy.yaml
`),
deployment("proxy", "/app/comp-a/proxy.yaml"),
writeC("/app/comp-b", `
resources:
- proxy.yaml
`),
deployment("proxy", "/app/comp-b/proxy.yaml"),
writeK("/app/prod", `
resources:
- ../base
components:
- ../comp-a
- ../comp-b`),
},
runPath: "/app/prod",
expectedError: "may not add resource with an already registered id: ~G_v1_Deployment|~X|proxy",
},
"components-cannot-add-the-same-base": {
input: []FileGen{writeTestBase,
deployment("proxy", "/app/comp-a/proxy.yaml"),
writeC("/app/comp-a", `
resources:
- ../base
`),
writeC("/app/comp-b", `
resources:
- ../base
`),
writeK("/app/prod", `
components:
- ../comp-a
- ../comp-b`),
},
runPath: "/app/prod",
expectedError: "may not add resource with an already registered id: ~G_v1_Deployment|~X|storefront",
},
"components-cannot-add-bases-containing-the-same-resource": {
input: []FileGen{writeTestBase,
writeC("/app/comp-a", `
resources:
- ../base-a
`),
writeK("/app/base-a", `
resources:
- proxy.yaml
`),
deployment("proxy", "/app/base-a/proxy.yaml"),
writeC("/app/comp-b", `
resources:
- ../base-b
`),
writeK("/app/base-b", `
resources:
- proxy.yaml
`),
deployment("proxy", "/app/base-b/proxy.yaml"),
writeK("/app/prod", `
resources:
- ../base
components:
- ../comp-a
- ../comp-b`),
},
runPath: "/app/prod",
expectedError: "may not add resource with an already registered id: ~G_v1_Deployment|~X|proxy",
},
}
for tn, tc := range testCases {
t.Run(tn, func(t *testing.T) {
th := kusttest_test.MakeHarness(t)
for _, f := range tc.input {
f(th)
}
err := th.RunWithErr(tc.runPath, th.MakeDefaultOptions())
if err == nil || !strings.Contains(err.Error(), tc.expectedError) {
t.Fatalf("unexpected error: %s", err)
}
})
}
}

View File

@@ -85,7 +85,8 @@ metadata:
--- ---
apiVersion: v1 apiVersion: v1
data: data:
druid_segmentCache_locations: '[{"path": "var/druid/segment-cache", "maxSize": 32000000000, "freeSpacePercent": 1.0}]' druid_segmentCache_locations: '[{"path": "var/druid/segment-cache", "maxSize":
32000000000, "freeSpacePercent": 1.0}]'
v2: '[{"path": "var/druid/segment-cache"}]' v2: '[{"path": "var/druid/segment-cache"}]'
kind: ConfigMap kind: ConfigMap
metadata: metadata:

View File

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

View File

@@ -11,7 +11,7 @@ import (
func makeCommonFileForExtendedPatchTest(th kusttest_test.Harness) { func makeCommonFileForExtendedPatchTest(th kusttest_test.Harness) {
th.WriteF("/app/base/deployment.yaml", ` th.WriteF("/app/base/deployment.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: nginx name: nginx
@@ -36,7 +36,7 @@ spec:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
--- ---
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: busybox name: busybox
@@ -101,7 +101,7 @@ patches:
name: busybox name: busybox
`) `)
th.WriteF("/app/base/patch.yaml", ` th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: busybox name: busybox
@@ -110,7 +110,7 @@ metadata:
`) `)
m := th.Run("/app/base", th.MakeDefaultOptions()) m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
labels: labels:
@@ -135,7 +135,7 @@ spec:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
--- ---
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
annotations: annotations:
@@ -156,7 +156,8 @@ spec:
- mountPath: /tmp/ps - mountPath: /tmp/ps
name: busybox-persistent-storage name: busybox-persistent-storage
volumes: volumes:
- name: busybox-persistent-storage - emptyDir: {}
name: busybox-persistent-storage
- configMap: - configMap:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
@@ -202,7 +203,7 @@ patches:
kind: Deployment kind: Deployment
`) `)
th.WriteF("/app/base/patch.yaml", ` th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: busybox name: busybox
@@ -211,7 +212,7 @@ metadata:
`) `)
m := th.Run("/app/base", th.MakeDefaultOptions()) m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
annotations: annotations:
@@ -232,12 +233,13 @@ spec:
- mountPath: /tmp/ps - mountPath: /tmp/ps
name: nginx-persistent-storage name: nginx-persistent-storage
volumes: volumes:
- name: nginx-persistent-storage - emptyDir: {}
name: nginx-persistent-storage
- configMap: - configMap:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
--- ---
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
annotations: annotations:
@@ -258,7 +260,8 @@ spec:
- mountPath: /tmp/ps - mountPath: /tmp/ps
name: busybox-persistent-storage name: busybox-persistent-storage
volumes: volumes:
- name: busybox-persistent-storage - emptyDir: {}
name: busybox-persistent-storage
- configMap: - configMap:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
@@ -302,7 +305,7 @@ patches:
labelSelector: app=nginx labelSelector: app=nginx
`) `)
th.WriteF("/app/base/patch.yaml", ` th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: nginx name: nginx
@@ -311,7 +314,7 @@ metadata:
`) `)
m := th.Run("/app/base", th.MakeDefaultOptions()) m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
annotations: annotations:
@@ -332,12 +335,13 @@ spec:
- mountPath: /tmp/ps - mountPath: /tmp/ps
name: nginx-persistent-storage name: nginx-persistent-storage
volumes: volumes:
- name: nginx-persistent-storage - emptyDir: {}
name: nginx-persistent-storage
- configMap: - configMap:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
--- ---
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
labels: labels:
@@ -404,7 +408,7 @@ patches:
kind: Deployment kind: Deployment
`) `)
th.WriteF("/app/base/patch.yaml", ` th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: busybox name: busybox
@@ -413,7 +417,7 @@ metadata:
`) `)
m := th.Run("/app/base", th.MakeDefaultOptions()) m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
labels: labels:
@@ -438,7 +442,7 @@ spec:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
--- ---
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
annotations: annotations:
@@ -459,7 +463,8 @@ spec:
- mountPath: /tmp/ps - mountPath: /tmp/ps
name: busybox-persistent-storage name: busybox-persistent-storage
volumes: volumes:
- name: busybox-persistent-storage - emptyDir: {}
name: busybox-persistent-storage
- configMap: - configMap:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
@@ -504,7 +509,7 @@ patches:
labelSelector: app=busybox labelSelector: app=busybox
`) `)
th.WriteF("/app/base/patch.yaml", ` th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: busybox name: busybox
@@ -513,7 +518,7 @@ metadata:
`) `)
m := th.Run("/app/base", th.MakeDefaultOptions()) m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
labels: labels:
@@ -538,7 +543,7 @@ spec:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
--- ---
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
annotations: annotations:
@@ -559,7 +564,8 @@ spec:
- mountPath: /tmp/ps - mountPath: /tmp/ps
name: busybox-persistent-storage name: busybox-persistent-storage
volumes: volumes:
- name: busybox-persistent-storage - emptyDir: {}
name: busybox-persistent-storage
- configMap: - configMap:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
@@ -606,7 +612,7 @@ patches:
labelSelector: app=busybox labelSelector: app=busybox
`) `)
th.WriteF("/app/base/patch.yaml", ` th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: busybox name: busybox
@@ -615,7 +621,7 @@ metadata:
`) `)
m := th.Run("/app/base", th.MakeDefaultOptions()) m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
labels: labels:
@@ -640,7 +646,7 @@ spec:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
--- ---
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
annotations: annotations:
@@ -661,7 +667,8 @@ spec:
- mountPath: /tmp/ps - mountPath: /tmp/ps
name: busybox-persistent-storage name: busybox-persistent-storage
volumes: volumes:
- name: busybox-persistent-storage - emptyDir: {}
name: busybox-persistent-storage
- configMap: - configMap:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
@@ -707,7 +714,7 @@ patches:
labelSelector: app=busybox labelSelector: app=busybox
`) `)
th.WriteF("/app/base/patch.yaml", ` th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: busybox name: busybox
@@ -716,7 +723,7 @@ metadata:
`) `)
m := th.Run("/app/base", th.MakeDefaultOptions()) m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
labels: labels:
@@ -741,7 +748,7 @@ spec:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
--- ---
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
annotations: annotations:
@@ -762,7 +769,8 @@ spec:
- mountPath: /tmp/ps - mountPath: /tmp/ps
name: busybox-persistent-storage name: busybox-persistent-storage
volumes: volumes:
- name: busybox-persistent-storage - emptyDir: {}
name: busybox-persistent-storage
- configMap: - configMap:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
@@ -806,7 +814,7 @@ patches:
name: no-match name: no-match
`) `)
th.WriteF("/app/base/patch.yaml", ` th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: busybox name: busybox
@@ -815,7 +823,7 @@ metadata:
`) `)
m := th.Run("/app/base", th.MakeDefaultOptions()) m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
labels: labels:
@@ -840,7 +848,7 @@ spec:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
--- ---
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
labels: labels:
@@ -902,7 +910,7 @@ patches:
- path: patch.yaml - path: patch.yaml
`) `)
th.WriteF("/app/base/patch.yaml", ` th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: busybox name: busybox
@@ -911,7 +919,7 @@ metadata:
`) `)
m := th.Run("/app/base", th.MakeDefaultOptions()) m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
labels: labels:
@@ -936,7 +944,7 @@ spec:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
--- ---
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
annotations: annotations:
@@ -957,7 +965,8 @@ spec:
- mountPath: /tmp/ps - mountPath: /tmp/ps
name: busybox-persistent-storage name: busybox-persistent-storage
volumes: volumes:
- name: busybox-persistent-storage - emptyDir: {}
name: busybox-persistent-storage
- configMap: - configMap:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
@@ -1005,7 +1014,7 @@ patches:
kind: Job kind: Job
`) `)
th.WriteF("/app/base/patch.yaml", ` th.WriteF("/app/base/patch.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: busybox name: busybox
@@ -1014,7 +1023,7 @@ metadata:
`) `)
m := th.Run("/app/base", th.MakeDefaultOptions()) m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
labels: labels:
@@ -1039,7 +1048,7 @@ spec:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
--- ---
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
labels: labels:
@@ -1107,7 +1116,7 @@ patches:
kind: Deployment kind: Deployment
`) `)
th.WriteF("/app/base/patch1.yaml", ` th.WriteF("/app/base/patch1.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: busybox name: busybox
@@ -1115,7 +1124,7 @@ metadata:
new-key-from-patch1: new-value new-key-from-patch1: new-value
`) `)
th.WriteF("/app/base/patch2.yaml", ` th.WriteF("/app/base/patch2.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: busybox name: busybox
@@ -1124,7 +1133,7 @@ metadata:
`) `)
m := th.Run("/app/base", th.MakeDefaultOptions()) m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
labels: labels:
@@ -1149,7 +1158,7 @@ spec:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base
--- ---
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
annotations: annotations:
@@ -1171,7 +1180,8 @@ spec:
- mountPath: /tmp/ps - mountPath: /tmp/ps
name: busybox-persistent-storage name: busybox-persistent-storage
volumes: volumes:
- name: busybox-persistent-storage - emptyDir: {}
name: busybox-persistent-storage
- configMap: - configMap:
name: configmap-in-base name: configmap-in-base
name: configmap-in-base name: configmap-in-base

View File

@@ -1,466 +0,0 @@
package krusty_test
import (
"os/exec"
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func TestFnExecGenerator(t *testing.T) {
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("/app", `
resources:
- short_secret.yaml
generators:
- gener.yaml
`)
// Create some additional resource just to make sure everything is added
th.WriteF("/app/short_secret.yaml", `
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("/app/gener.yaml", `
kind: executable
metadata:
name: demo
annotations:
config.kubernetes.io/function: |
exec:
path: ./fnplugin_test/fnexectest.sh
spec:
`)
o := th.MakeOptionsPluginsEnabled()
o.PluginConfig.FnpLoadingOptions.EnableExec = true
m := th.Run("/app", o)
th.AssertActualEqualsExpected(m, `
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:
config.kubernetes.io/path: deployment_nginx.yaml
tshirt-size: small
labels:
app: nginx
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
`)
}
func skipIfNoDocker(t *testing.T) {
if _, err := exec.LookPath("docker"); err != nil {
t.Skip("skipping because docker binary wasn't found in PATH")
}
}
func TestFnContainerGenerator(t *testing.T) {
skipIfNoDocker(t)
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("/app", `
resources:
- short_secret.yaml
generators:
- gener.yaml
`)
// Create generator config
th.WriteF("/app/gener.yaml", `
apiVersion: examples.config.kubernetes.io/v1beta1
kind: CockroachDB
metadata:
name: demo
annotations:
config.kubernetes.io/function: |
container:
image: gcr.io/kustomize-functions/example-cockroachdb:v0.1.0
spec:
replicas: 3
`)
// Create some additional resource just to make sure everything is added
th.WriteF("/app/short_secret.yaml", `
apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-user-data: "true"
name: node1-bmc-secret
type: Opaque
stringData:
userData: |
bootcmd:
- mkdir /mnt/vda
`)
m := th.Run("/app", th.MakeOptionsPluginsEnabled())
th.AssertActualEqualsExpected(m, `
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: policy/v1beta1
kind: PodDisruptionBudget
metadata:
annotations:
config.kubernetes.io/path: config/demo-budget_poddisruptionbudget.yaml
labels:
app: cockroachdb
name: demo
name: demo-budget
spec:
minAvailable: 67%
selector:
matchLabels:
app: cockroachdb
name: demo
---
apiVersion: v1
kind: Service
metadata:
annotations:
config.kubernetes.io/path: config/demo-public_service.yaml
labels:
app: cockroachdb
name: demo
name: demo-public
spec:
ports:
- name: grpc
port: 26257
targetPort: 26257
- name: http
port: 8080
targetPort: 8080
selector:
app: cockroachdb
name: demo
---
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"
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
labels:
app: cockroachdb
name: demo
name: demo
spec:
clusterIP: None
ports:
- name: grpc
port: 26257
targetPort: 26257
- name: http
port: 8080
targetPort: 8080
selector:
app: cockroachdb
name: demo
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
annotations:
config.kubernetes.io/path: config/demo_statefulset.yaml
labels:
app: cockroachdb
name: demo
name: demo
spec:
replicas: 3
selector:
matchLabels:
app: cockroachdb
name: demo
serviceName: demo
template:
metadata:
labels:
app: cockroachdb
name: demo
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- cockroachdb
topologyKey: kubernetes.io/hostname
weight: 100
containers:
- command:
- /bin/bash
- -ecx
- |
# The use of qualified `+"`hostname -f`"+` is crucial:
# Other nodes aren't able to look up the unqualified hostname.
CRARGS=("start" "--logtostderr" "--insecure" "--host" "$(hostname -f)" "--http-host" "0.0.0.0")
# We only want to initialize a new cluster (by omitting the join flag)
# if we're sure that we're the first node (i.e. index 0) and that
# there aren't any other nodes running as part of the cluster that
# this is supposed to be a part of (which indicates that a cluster
# already exists and we should make sure not to create a new one).
# It's fine to run without --join on a restart if there aren't any
# other nodes.
if [ ! "$(hostname)" == "cockroachdb-0" ] || [ -e "/cockroach/cockroach-data/cluster_exists_marker" ]
then
# We don't join cockroachdb in order to avoid a node attempting
# to join itself, which currently doesn't work
# (https://github.com/cockroachdb/cockroach/issues/9625).
CRARGS+=("--join" "cockroachdb-public")
fi
exec /cockroach/cockroach ${CRARGS[*]}
image: cockroachdb/cockroach:v1.1.0
imagePullPolicy: IfNotPresent
name: demo
ports:
- containerPort: 26257
name: grpc
- containerPort: 8080
name: http
volumeMounts:
- mountPath: /cockroach/cockroach-data
name: datadir
initContainers:
- args:
- -on-start=/on-start.sh
- -service=cockroachdb
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
image: cockroachdb/cockroach-k8s-init:0.1
imagePullPolicy: IfNotPresent
name: bootstrap
volumeMounts:
- mountPath: /cockroach/cockroach-data
name: datadir
terminationGracePeriodSeconds: 60
volumes:
- name: datadir
persistentVolumeClaim:
claimName: datadir
volumeClaimTemplates:
- metadata:
name: datadir
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
`)
}
func TestFnContainerTransformer(t *testing.T) {
skipIfNoDocker(t)
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("/app", `
resources:
- data.yaml
transformers:
- transf1.yaml
- transf2.yaml
`)
th.WriteF("/app/data.yaml", `
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
`)
// This transformer should add resource reservations based on annotation in data.yaml
// See https://github.com/kubernetes-sigs/kustomize/tree/master/functions/examples/injection-tshirt-sizes
th.WriteF("/app/transf1.yaml", `
apiVersion: examples.config.kubernetes.io/v1beta1
kind: Validator
metadata:
name: valid
annotations:
config.kubernetes.io/function: |-
container:
image: gcr.io/kustomize-functions/example-tshirt:v0.2.0
`)
// This transformer will check resources without and won't do any changes
// See https://github.com/kubernetes-sigs/kustomize/tree/master/functions/examples/validator-kubeval
th.WriteF("/app/transf2.yaml", `
apiVersion: examples.config.kubernetes.io/v1beta1
kind: Kubeval
metadata:
name: validate
annotations:
config.kubernetes.io/function: |
container:
image: gcr.io/kustomize-functions/example-validator-kubeval:v0.1.0
spec:
strict: true
ignoreMissingSchemas: true
# TODO: Update this to use network/volumes features.
# Relevant issues:
# - https://github.com/kubernetes-sigs/kustomize/issues/1901
# - https://github.com/kubernetes-sigs/kustomize/issues/1902
kubernetesVersion: "1.16.0"
schemaLocation: "file:///schemas"
`)
m := th.Run("/app", th.MakeOptionsPluginsEnabled())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
config.kubernetes.io/path: deployment_nginx.yaml
tshirt-size: small
labels:
app: nginx
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
resources:
requests:
cpu: 200m
memory: 50M
`)
}
func TestFnContainerTransformerWithConfig(t *testing.T) {
skipIfNoDocker(t)
th := kusttest_test.MakeEnhancedHarness(t)
defer th.Reset()
th.WriteK("/app", `
resources:
- data1.yaml
- data2.yaml
transformers:
- label_namespace.yaml
`)
th.WriteF("/app/data1.yaml", `apiVersion: v1
kind: Namespace
metadata:
name: my-namespace
`)
th.WriteF("/app/data2.yaml", `apiVersion: v1
kind: Namespace
metadata:
name: another-namespace
`)
th.WriteF("/app/label_namespace.yaml", `apiVersion: v1
kind: ConfigMap
metadata:
name: label_namespace
annotations:
config.kubernetes.io/function: |-
container:
image: gcr.io/kpt-functions/label-namespace@sha256:4f030738d6d25a207641ca517916431517578bd0eb8d98a8bde04e3bb9315dcd
data:
label_name: my-ns-name
label_value: function-test
`)
m := th.Run("/app", th.MakeOptionsPluginsEnabled())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Namespace
metadata:
annotations:
config.kubernetes.io/path: namespace_my-namespace.yaml
labels:
my-ns-name: function-test
name: my-namespace
---
apiVersion: v1
kind: Namespace
metadata:
annotations:
config.kubernetes.io/path: namespace_another-namespace.yaml
labels:
my-ns-name: function-test
name: another-namespace
`)
}

View File

@@ -1,24 +0,0 @@
#!/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

@@ -56,7 +56,7 @@ spec:
app: nginx app: nginx
`) `)
th.WriteF("/app/base/deployment.yaml", ` th.WriteF("/app/base/deployment.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: nginx name: nginx
@@ -92,7 +92,7 @@ spec:
org: example.com org: example.com
team: foo team: foo
--- ---
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
annotations: annotations:
@@ -150,6 +150,8 @@ spec:
func makeBaseWithGenerators(th kusttest_test.Harness) { func makeBaseWithGenerators(th kusttest_test.Harness) {
th.WriteK("/app", ` th.WriteK("/app", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namePrefix: team-foo- namePrefix: team-foo-
commonLabels: commonLabels:
app: mynginx app: mynginx
@@ -171,7 +173,7 @@ secretGenerator:
- password=somepw - password=somepw
`) `)
th.WriteF("/app/deployment.yaml", ` th.WriteF("/app/deployment.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: nginx name: nginx
@@ -216,7 +218,7 @@ func TestBaseWithGeneratorsAlone(t *testing.T) {
makeBaseWithGenerators(th) makeBaseWithGenerators(th)
m := th.Run("/app", th.MakeDefaultOptions()) m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
annotations: annotations:
@@ -306,7 +308,7 @@ func TestMergeAndReplaceGenerators(t *testing.T) {
th := kusttest_test.MakeHarness(t) th := kusttest_test.MakeHarness(t)
makeBaseWithGenerators(th) makeBaseWithGenerators(th)
th.WriteF("/overlay/deployment.yaml", ` th.WriteF("/overlay/deployment.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: nginx name: nginx
@@ -323,6 +325,8 @@ spec:
name: configmap-in-overlay name: configmap-in-overlay
`) `)
th.WriteK("/overlay", ` th.WriteK("/overlay", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namePrefix: staging- namePrefix: staging-
commonLabels: commonLabels:
env: staging env: staging
@@ -347,7 +351,7 @@ secretGenerator:
`) `)
m := th.Run("/overlay", th.MakeDefaultOptions()) m := th.Run("/overlay", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
annotations: annotations:
@@ -385,12 +389,12 @@ spec:
- gcePersistentDisk: - gcePersistentDisk:
pdName: nginx-persistent-storage pdName: nginx-persistent-storage
name: nginx-persistent-storage name: nginx-persistent-storage
- configMap:
name: staging-team-foo-configmap-in-base-gh9d7t85gb
name: configmap-in-base
- configMap: - configMap:
name: staging-configmap-in-overlay-k7cbc75tg8 name: staging-configmap-in-overlay-k7cbc75tg8
name: configmap-in-overlay name: configmap-in-overlay
- configMap:
name: staging-team-foo-configmap-in-base-gh9d7t85gb
name: configmap-in-base
--- ---
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
@@ -537,7 +541,7 @@ configMapGenerator:
if err == nil { if err == nil {
t.Fatalf("expected error") t.Fatalf("expected error")
} }
if !strings.Contains(err.Error(), "behavior must be merge or replace") { if !strings.Contains(err.Error(), "must merge or replace") {
t.Fatalf("unexpected error %v", err) t.Fatalf("unexpected error %v", err)
} }
} }
@@ -562,7 +566,7 @@ secretGenerator:
if err == nil { if err == nil {
t.Fatalf("expected error") t.Fatalf("expected error")
} }
if !strings.Contains(err.Error(), "behavior must be merge or replace") { if !strings.Contains(err.Error(), "must merge or replace") {
t.Fatalf("unexpected error %v", err) t.Fatalf("unexpected error %v", err)
} }
} }

View File

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

View File

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

View File

@@ -4,8 +4,6 @@
package krusty package krusty
import ( import (
"fmt"
"sigs.k8s.io/kustomize/api/builtins" "sigs.k8s.io/kustomize/api/builtins"
"sigs.k8s.io/kustomize/api/filesys" "sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/internal/k8sdeps/transformer" "sigs.k8s.io/kustomize/api/internal/k8sdeps/transformer"
@@ -13,9 +11,7 @@ import (
"sigs.k8s.io/kustomize/api/internal/target" "sigs.k8s.io/kustomize/api/internal/target"
"sigs.k8s.io/kustomize/api/k8sdeps/kunstruct" "sigs.k8s.io/kustomize/api/k8sdeps/kunstruct"
"sigs.k8s.io/kustomize/api/k8sdeps/validator" "sigs.k8s.io/kustomize/api/k8sdeps/validator"
"sigs.k8s.io/kustomize/api/konfig"
fLdr "sigs.k8s.io/kustomize/api/loader" fLdr "sigs.k8s.io/kustomize/api/loader"
"sigs.k8s.io/kustomize/api/provenance"
"sigs.k8s.io/kustomize/api/resmap" "sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource" "sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/api/types"
@@ -75,22 +71,16 @@ func (b *Kustomizer) Run(path string) (resmap.ResMap, error) {
return nil, err return nil, err
} }
var m resmap.ResMap var m resmap.ResMap
m, err = kt.MakeCustomizedResMap() if b.options.DoPrune {
m, err = kt.MakePruneConfigMap()
} else {
m, err = kt.MakeCustomizedResMap()
}
if err != nil { if err != nil {
return nil, err return nil, err
} }
if b.options.DoLegacyResourceSort { if b.options.DoLegacyResourceSort {
builtins.NewLegacyOrderTransformerPlugin().Transform(m) builtins.NewLegacyOrderTransformerPlugin().Transform(m)
} }
if b.options.AddManagedbyLabel {
t := builtins.LabelTransformerPlugin{
Labels: map[string]string{konfig.ManagedbyLabelKey: fmt.Sprintf("kustomize-%s", provenance.GetProvenance().Version)},
FieldSpecs: []types.FieldSpec{{
Path: "metadata/labels",
CreateIfNotPresent: true,
}},
}
t.Transform(m)
}
return m, nil return m, nil
} }

View File

@@ -1,43 +0,0 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package krusty_test
import (
"testing"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
)
func TestAddManagedbyLabel(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteF("/app/service.yaml", `
apiVersion: v1
kind: Service
metadata:
name: myService
spec:
ports:
- port: 7002
`)
th.WriteK("/app", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- service.yaml
`)
options := th.MakeDefaultOptions()
options.AddManagedbyLabel = true
m := th.Run("/app", options)
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/managed-by: kustomize-v444.333.222
name: myService
spec:
ports:
- port: 7002
`)
}

View File

@@ -1,110 +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"
)
func makeCommonFileForMergeEnvFromTest(th kusttest_test.Harness) {
th.WriteF("/app/deployment.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- name: nginx
image: image1
envFrom:
- configMapRef:
name: some-config
- configMapRef:
name: more-config
`)
}
// When patching, `envFrom` should merge the list instead of replacing it.
func TestMergeEnvFrom(t *testing.T) {
th := kusttest_test.MakeHarness(t)
makeCommonFileForMergeEnvFromTest(th)
th.WriteK("/app", `
resources:
- deployment.yaml
patchesStrategicMerge:
- |-
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- name: nginx
envFrom:
- configMapRef:
name: another-config
`)
m := th.Run("/app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- envFrom:
- configMapRef:
name: another-config
image: image1
name: nginx
`)
}
func TestMergeEnvFromViaJsonInline(t *testing.T) {
th := kusttest_test.MakeHarness(t)
makeCommonFileForMergeEnvFromTest(th)
th.WriteK("app", `
resources:
- deployment.yaml
patches:
- target:
kind: Deployment
name: nginx
patch: |-
- op: add
path: /spec/template/spec/containers/0/envFrom/-
value:
configMapRef:
name: another-config
`)
m := th.Run("app", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- envFrom:
- configMapRef:
name: some-config
- configMapRef:
name: more-config
- configMapRef:
name: another-config
image: image1
name: nginx
`)
}

View File

@@ -10,186 +10,10 @@ import (
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest" kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
) )
func TestSimpleMultiplePatches(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("base", `
namePrefix: b-
commonLabels:
team: foo
resources:
- deployment.yaml
- service.yaml
configMapGenerator:
- name: configmap-in-base
literals:
- foo=bar
`)
th.WriteF("base/deployment.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: nginx-persistent-storage
mountPath: /tmp/ps
- name: sidecar
image: sidecar:latest
volumes:
- name: nginx-persistent-storage
emptyDir: {}
- configMap:
name: configmap-in-base
name: configmap-in-base
`)
th.WriteF("base/service.yaml", `
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- port: 80
`)
th.WriteK("overlay", `
namePrefix: a-
commonLabels:
env: staging
patchesStrategicMerge:
- deployment-patch1.yaml
- deployment-patch2.yaml
resources:
- ../base
configMapGenerator:
- name: configmap-in-overlay
literals:
- hello=world
`)
th.WriteF("overlay/deployment-patch1.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- name: nginx
image: nginx:latest
env:
- name: ENVKEY
value: ENVVALUE
volumes:
- name: nginx-persistent-storage
emptyDir: null
gcePersistentDisk:
pdName: nginx-persistent-storage
- configMap:
name: configmap-in-overlay
name: configmap-in-overlay
`)
th.WriteF("overlay/deployment-patch2.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
template:
spec:
containers:
- name: nginx
env:
- name: ANOTHERENV
value: FOO
volumes:
- name: nginx-persistent-storage
`)
m := th.Run("overlay", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
env: staging
team: foo
name: a-b-nginx
spec:
selector:
matchLabels:
env: staging
team: foo
template:
metadata:
labels:
env: staging
team: foo
spec:
containers:
- env:
- name: ANOTHERENV
value: FOO
- name: ENVKEY
value: ENVVALUE
image: nginx:latest
name: nginx
volumeMounts:
- mountPath: /tmp/ps
name: nginx-persistent-storage
- image: sidecar:latest
name: sidecar
volumes:
- gcePersistentDisk:
pdName: nginx-persistent-storage
name: nginx-persistent-storage
- configMap:
name: a-b-configmap-in-base-fm96mhk4dt
name: configmap-in-base
- configMap:
name: a-configmap-in-overlay-ffm9hf78mc
name: configmap-in-overlay
---
apiVersion: v1
kind: Service
metadata:
labels:
env: staging
team: foo
name: a-b-nginx
spec:
ports:
- port: 80
selector:
env: staging
team: foo
---
apiVersion: v1
data:
foo: bar
kind: ConfigMap
metadata:
labels:
env: staging
team: foo
name: a-b-configmap-in-base-fm96mhk4dt
---
apiVersion: v1
data:
hello: world
kind: ConfigMap
metadata:
labels:
env: staging
name: a-configmap-in-overlay-ffm9hf78mc
`)
}
func makeCommonFileForMultiplePatchTest(th kusttest_test.Harness) { func makeCommonFileForMultiplePatchTest(th kusttest_test.Harness) {
th.WriteK("/app/base", ` th.WriteK("/app/base", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namePrefix: team-foo- namePrefix: team-foo-
commonLabels: commonLabels:
app: mynginx app: mynginx
@@ -206,7 +30,7 @@ configMapGenerator:
- foo=bar - foo=bar
`) `)
th.WriteF("/app/base/deployment.yaml", ` th.WriteF("/app/base/deployment.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: nginx name: nginx
@@ -247,6 +71,8 @@ spec:
app: nginx app: nginx
`) `)
th.WriteK("/app/overlay/staging", ` th.WriteK("/app/overlay/staging", `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namePrefix: staging- namePrefix: staging-
commonLabels: commonLabels:
env: staging env: staging
@@ -266,7 +92,7 @@ func TestMultiplePatchesNoConflict(t *testing.T) {
th := kusttest_test.MakeHarness(t) th := kusttest_test.MakeHarness(t)
makeCommonFileForMultiplePatchTest(th) makeCommonFileForMultiplePatchTest(th)
th.WriteF("/app/overlay/staging/deployment-patch1.yaml", ` th.WriteF("/app/overlay/staging/deployment-patch1.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: nginx name: nginx
@@ -289,7 +115,7 @@ spec:
name: configmap-in-overlay name: configmap-in-overlay
`) `)
th.WriteF("/app/overlay/staging/deployment-patch2.yaml", ` th.WriteF("/app/overlay/staging/deployment-patch2.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: nginx name: nginx
@@ -306,7 +132,7 @@ spec:
`) `)
m := th.Run("/app/overlay/staging", th.MakeDefaultOptions()) m := th.Run("/app/overlay/staging", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, ` th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
annotations: annotations:
@@ -351,12 +177,12 @@ spec:
- gcePersistentDisk: - gcePersistentDisk:
pdName: nginx-persistent-storage pdName: nginx-persistent-storage
name: nginx-persistent-storage name: nginx-persistent-storage
- configMap:
name: staging-team-foo-configmap-in-base-g7k6gt2889
name: configmap-in-base
- configMap: - configMap:
name: staging-configmap-in-overlay-k7cbc75tg8 name: staging-configmap-in-overlay-k7cbc75tg8
name: configmap-in-overlay name: configmap-in-overlay
- configMap:
name: staging-team-foo-configmap-in-base-g7k6gt2889
name: configmap-in-base
--- ---
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
@@ -407,7 +233,7 @@ func TestMultiplePatchesWithConflict(t *testing.T) {
th := kusttest_test.MakeHarness(t) th := kusttest_test.MakeHarness(t)
makeCommonFileForMultiplePatchTest(th) makeCommonFileForMultiplePatchTest(th)
th.WriteF("/app/overlay/staging/deployment-patch1.yaml", ` th.WriteF("/app/overlay/staging/deployment-patch1.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: nginx name: nginx
@@ -429,7 +255,7 @@ spec:
name: configmap-in-overlay name: configmap-in-overlay
`) `)
th.WriteF("/app/overlay/staging/deployment-patch2.yaml", ` th.WriteF("/app/overlay/staging/deployment-patch2.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: nginx name: nginx
@@ -453,7 +279,7 @@ spec:
} }
func TestMultiplePatchesWithOnePatchDeleteDirective(t *testing.T) { func TestMultiplePatchesWithOnePatchDeleteDirective(t *testing.T) {
additivePatch := `apiVersion: apps/v1 additivePatch := `apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: nginx name: nginx
@@ -466,7 +292,7 @@ spec:
- name: SOME_NAME - name: SOME_NAME
value: somevalue value: somevalue
` `
deletePatch := `apiVersion: apps/v1 deletePatch := `apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: nginx name: nginx
@@ -502,7 +328,7 @@ spec:
th.WriteF("/app/overlay/staging/deployment-patch1.yaml", c.patch1) th.WriteF("/app/overlay/staging/deployment-patch1.yaml", c.patch1)
th.WriteF("/app/overlay/staging/deployment-patch2.yaml", c.patch2) th.WriteF("/app/overlay/staging/deployment-patch2.yaml", c.patch2)
m := th.Run("/app/overlay/staging", th.MakeDefaultOptions()) m := th.Run("/app/overlay/staging", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `apiVersion: apps/v1 th.AssertActualEqualsExpected(m, `apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
annotations: annotations:
@@ -540,7 +366,8 @@ spec:
- mountPath: /tmp/ps - mountPath: /tmp/ps
name: nginx-persistent-storage name: nginx-persistent-storage
volumes: volumes:
- name: nginx-persistent-storage - emptyDir: {}
name: nginx-persistent-storage
- configMap: - configMap:
name: staging-team-foo-configmap-in-base-g7k6gt2889 name: staging-team-foo-configmap-in-base-g7k6gt2889
name: configmap-in-base name: configmap-in-base
@@ -596,7 +423,7 @@ func TestMultiplePatchesBothWithPatchDeleteDirective(t *testing.T) {
th := kusttest_test.MakeHarness(t) th := kusttest_test.MakeHarness(t)
makeCommonFileForMultiplePatchTest(th) makeCommonFileForMultiplePatchTest(th)
th.WriteF("/app/overlay/staging/deployment-patch1.yaml", ` th.WriteF("/app/overlay/staging/deployment-patch1.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: nginx name: nginx
@@ -608,7 +435,7 @@ spec:
name: sidecar name: sidecar
`) `)
th.WriteF("/app/overlay/staging/deployment-patch2.yaml", ` th.WriteF("/app/overlay/staging/deployment-patch2.yaml", `
apiVersion: apps/v1 apiVersion: apps/v1beta2
kind: Deployment kind: Deployment
metadata: metadata:
name: nginx name: nginx

View File

@@ -1,51 +0,0 @@
// Copyright 2020 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 shows numeric-looking strings correctly handled as strings
func TestNumericCommonLabels(t *testing.T) {
th := kusttest_test.MakeHarness(t)
// A basic deployment just used to put labels into
th.WriteF("/app/default/deployment.yaml", `
apiVersion: apps/v1
kind: Deployment
metadata:
name: the-deployment
`)
// Combine these custom transformers in one kustomization file.
// This kustomization file has a string-valued commonLabel that
// should always be quoted to remain a string
th.WriteK("/app/default", `
commonLabels:
version: "1"
resources:
- deployment.yaml
`)
m := th.Run("/app/default", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
version: "1"
name: the-deployment
spec:
selector:
matchLabels:
version: "1"
template:
metadata:
labels:
version: "1"
`)
}

View File

@@ -18,11 +18,6 @@ type Options struct {
// order as specified by the kustomization file(s). // order as specified by the kustomization file(s).
DoLegacyResourceSort bool DoLegacyResourceSort bool
// When true, a label
// app.kubernetes.io/managed-by: kustomize-<version>
// is added to all the resources in the build out.
AddManagedbyLabel bool
// Restrictions on what can be loaded from the file system. // Restrictions on what can be loaded from the file system.
// See type definition. // See type definition.
LoadRestrictions types.LoadRestrictions LoadRestrictions types.LoadRestrictions

View File

@@ -0,0 +1,163 @@
// 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"
)
func TestPruneConfigMap(t *testing.T) {
th := kusttest_test.MakeHarness(t)
th.WriteK("/app/base", `
resources:
- deployment.yaml
- service.yaml
- secret.yaml
inventory:
type: ConfigMap
configMap:
name: haha
namespace: default
namePrefix: my-
namespace: default
`)
th.WriteF("/app/base/deployment.yaml", `
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: mysql
labels:
app: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: pass
key: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
emptyDir: {}
`)
th.WriteF("/app/base/service.yaml", `
apiVersion: v1
kind: Service
metadata:
name: mmmysql
labels:
app: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
`)
th.WriteF("/app/base/secret.yaml", `
apiVersion: v1
kind: Secret
metadata:
name: pass
type: Opaque
data:
# Default password is "admin".
password: YWRtaW4=
username: jingfang
`)
m := th.Run("/app/base", th.MakeDefaultOptions())
//nolint
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
app: mysql
name: my-mysql
namespace: default
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: my-pass
image: mysql:5.6
name: mysql
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- mountPath: /var/lib/mysql
name: mysql-persistent-storage
volumes:
- emptyDir: {}
name: mysql-persistent-storage
---
apiVersion: v1
kind: Service
metadata:
labels:
app: mysql
name: my-mmmysql
namespace: default
spec:
ports:
- port: 3306
selector:
app: mysql
---
apiVersion: v1
data:
password: YWRtaW4=
username: jingfang
kind: Secret
metadata:
name: my-pass
namespace: default
type: Opaque
---
apiVersion: v1
kind: ConfigMap
metadata:
annotations:
kustomize.config.k8s.io/Inventory: '{"current":{"apps_v1beta2_Deployment|default|my-mysql":null,"~G_v1_Secret|default|my-pass":[{"group":"apps","version":"v1beta2","kind":"Deployment","name":"my-mysql","namespace":"default"}],"~G_v1_Service|default|my-mmmysql":null}}'
kustomize.config.k8s.io/InventoryHash: kd67f7ht8t
name: haha
namespace: default
`)
}

View File

@@ -844,7 +844,8 @@ spec:
- -namespace=${POD_NAMESPACE} - -namespace=${POD_NAMESPACE}
- -certs-dir=/cockroach-certs - -certs-dir=/cockroach-certs
- -type=node - -type=node
- -addresses=localhost,127.0.0.1,${POD_IP},$(hostname -f),$(hostname -f|cut -f 1-2 -d '.'),dev-base-cockroachdb-public - -addresses=localhost,127.0.0.1,${POD_IP},$(hostname -f),$(hostname -f|cut
-f 1-2 -d '.'),dev-base-cockroachdb-public
- -symlink-ca-from=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt - -symlink-ca-from=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
env: env:
- name: POD_IP - name: POD_IP

View File

@@ -9,6 +9,7 @@ import (
"fmt" "fmt"
"os" "os"
"path" "path"
"regexp"
"strings" "strings"
"unicode" "unicode"
"unicode/utf8" "unicode/utf8"
@@ -85,11 +86,17 @@ func (kvl *loader) keyValuesFromFileSources(sources []string) ([]types.Pair, err
if err != nil { if err != nil {
return nil, err return nil, err
} }
kvs = append(kvs, types.Pair{Key: k, Value: string(content)}) kvs = append(kvs, types.Pair{Key: k, Value: trimTrailingSpacesInLines(string(content))})
} }
return kvs, nil return kvs, nil
} }
// trimTrailingSpacesInLines takes string with multiple lines and trims the trailing white spaces and tabs from each line.
func trimTrailingSpacesInLines(str string) string {
re := regexp.MustCompile(`[ \t]*\n`)
return re.ReplaceAllString(str, "\n")
}
func (kvl *loader) keyValuesFromEnvFiles(paths []string) ([]types.Pair, error) { func (kvl *loader) keyValuesFromEnvFiles(paths []string) ([]types.Pair, error) {
var kvs []types.Pair var kvs []types.Pair
for _, p := range paths { for _, p := range paths {

View File

@@ -95,3 +95,12 @@ func TestKeyValuesFromFileSources(t *testing.T) {
} }
} }
} }
func TestTrimTrailingSpacesInLines(t *testing.T) {
input := "\"fooKey\": \"fooValue\" \t\n \t\t \n\t\"barKey\": \"barValue\""
expected := "\"fooKey\": \"fooValue\"\n\n\t\"barKey\": \"barValue\""
res := trimTrailingSpacesInLines(input)
if !reflect.DeepEqual(res, expected) {
t.Errorf("Trim trailing spaces in lines should succeed, got: %s exptected: %s", res, expected)
}
}

View File

@@ -60,8 +60,6 @@ func getRemoteTarget(rs *remoteTargetSpec) error {
return err return err
} }
rs.Dir = filesys.ConfirmedDir(rs.Dir.Join("repo"))
// Get the pwd // Get the pwd
pwd, err := os.Getwd() pwd, err := os.Getwd()
if err != nil { if err != nil {

View File

@@ -84,6 +84,7 @@ var orderFirst = []string{
"ResourceQuota", "ResourceQuota",
"StorageClass", "StorageClass",
"CustomResourceDefinition", "CustomResourceDefinition",
"MutatingWebhookConfiguration",
"ServiceAccount", "ServiceAccount",
"PodSecurityPolicy", "PodSecurityPolicy",
"Role", "Role",
@@ -101,7 +102,6 @@ var orderFirst = []string{
"PodDisruptionBudget", "PodDisruptionBudget",
} }
var orderLast = []string{ var orderLast = []string{
"MutatingWebhookConfiguration",
"ValidatingWebhookConfiguration", "ValidatingWebhookConfiguration",
} }
var typeOrders = func() map[string]int { var typeOrders = func() map[string]int {
@@ -167,7 +167,6 @@ var notNamespaceableKinds = []string{
"CSIDriver", "CSIDriver",
"CSINode", "CSINode",
"CertificateSigningRequest", "CertificateSigningRequest",
"Cluster",
"ClusterRole", "ClusterRole",
"ClusterRoleBinding", "ClusterRoleBinding",
"ComponentStatus", "ComponentStatus",

View File

@@ -68,10 +68,6 @@ var lessThanTests = []struct {
Gvk{Group: "a", Version: "b", Kind: orderLast[0]}}, Gvk{Group: "a", Version: "b", Kind: orderLast[0]}},
{Gvk{Group: "a", Version: "b", Kind: "CustomKindA"}, {Gvk{Group: "a", Version: "b", Kind: "CustomKindA"},
Gvk{Group: "a", Version: "b", Kind: "CustomKindB"}}, Gvk{Group: "a", Version: "b", Kind: "CustomKindB"}},
{Gvk{Group: "a", Version: "b", Kind: "CustomKindX"},
Gvk{Group: "a", Version: "b", Kind: "MutatingWebhookConfiguration"}},
{Gvk{Group: "a", Version: "b", Kind: "MutatingWebhookConfiguration"},
Gvk{Group: "a", Version: "b", Kind: "ValidatingWebhookConfiguration"}},
{Gvk{Group: "a", Version: "b", Kind: "CustomKindX"}, {Gvk{Group: "a", Version: "b", Kind: "CustomKindX"},
Gvk{Group: "a", Version: "b", Kind: "ValidatingWebhookConfiguration"}}, Gvk{Group: "a", Version: "b", Kind: "ValidatingWebhookConfiguration"}},
{Gvk{Group: "a", Version: "b", Kind: "APIService"}, {Gvk{Group: "a", Version: "b", Kind: "APIService"},

View File

@@ -532,7 +532,7 @@ func (m *resWrangler) ErrorIfNotEqualSets(other ResMap) error {
for _, r1 := range m.rList { for _, r1 := range m.rList {
id := r1.CurId() id := r1.CurId()
others := m2.GetMatchingResourcesByCurrentId(id.Equals) others := m2.GetMatchingResourcesByCurrentId(id.Equals)
if len(others) == 0 { if len(others) < 0 {
return fmt.Errorf( return fmt.Errorf(
"id in self missing from other; id: %s", id) "id in self missing from other; id: %s", id)
} }
@@ -691,7 +691,7 @@ func (m *resWrangler) appendReplaceOrMerge(
res.Merge(old) res.Merge(old)
default: default:
return fmt.Errorf( return fmt.Errorf(
"id %#v exists; behavior must be merge or replace", id) "id %#v exists; must merge or replace", id)
} }
i, err := m.Replace(res) i, err := m.Replace(res)
if err != nil { if err != nil {

View File

@@ -669,12 +669,7 @@ func TestErrorIfNotEqualSets(t *testing.T) {
t.Fatalf("%v should not equal %v %v", m1, m2, err) t.Fatalf("%v should not equal %v %v", m1, m2, err)
} }
m3 := resmaptest_test.NewRmBuilder(t, rf).AddR(r2).ResMap() m3 := resmaptest_test.NewRmBuilder(t, rf).Add(
if err := m2.ErrorIfNotEqualSets(m3); err == nil {
t.Fatalf("%v should not equal %v %v", m2, m3, err)
}
m3 = resmaptest_test.NewRmBuilder(t, rf).Add(
map[string]interface{}{ map[string]interface{}{
"apiVersion": "v1", "apiVersion": "v1",
"kind": "ConfigMap", "kind": "ConfigMap",

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