diff --git a/go.mod b/go.mod index b102bd619a..e232473921 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,8 @@ module github.com/GoogleContainerTools/kpt go 1.17 require ( - github.com/GoogleContainerTools/kpt/porch/api v0.0.0-20220707151439-cb4c4e496c92 + github.com/GoogleContainerTools/kpt-functions-sdk/go/fn v0.0.0-20220802210946-984d8349f565 + // github.com/GoogleContainerTools/kpt/porch/api v0.0.0-20220707151439-cb4c4e496c92 github.com/cpuguy83/go-md2man/v2 v2.0.1 github.com/go-errors/errors v1.4.2 github.com/google/go-cmp v0.5.7 @@ -12,26 +13,28 @@ require ( github.com/otiai10/copy v1.7.0 github.com/philopon/go-toposort v0.0.0-20170620085441-9be86dbd762f github.com/spf13/cobra v1.4.0 - github.com/stretchr/testify v1.7.1 + github.com/stretchr/testify v1.8.0 github.com/xlab/treeprint v1.1.0 golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 golang.org/x/text v0.3.7 - gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b + gopkg.in/yaml.v3 v3.0.1 gotest.tools v2.2.0+incompatible - k8s.io/api v0.24.0 + k8s.io/api v0.24.3 k8s.io/apiextensions-apiserver v0.24.0 - k8s.io/apimachinery v0.24.0 + k8s.io/apimachinery v0.24.3 k8s.io/cli-runtime v0.24.0 k8s.io/client-go v0.24.0 k8s.io/component-base v0.24.0 - k8s.io/klog/v2 v2.60.1 + k8s.io/klog/v2 v2.70.1 k8s.io/kubectl v0.24.0 sigs.k8s.io/cli-utils v0.32.0 sigs.k8s.io/controller-runtime v0.11.0 sigs.k8s.io/kustomize/api v0.11.5 - sigs.k8s.io/kustomize/kyaml v0.13.7 + sigs.k8s.io/kustomize/kyaml v0.13.8 ) +require github.com/GoogleContainerTools/kpt/porch/api v0.0.0-20220802174803-aa37aa6ebdfb + require ( cloud.google.com/go/compute v1.3.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect @@ -41,26 +44,25 @@ require ( github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect + github.com/GoogleContainerTools/kpt-functions-sdk/go/api v0.0.0-20220723081830-33aee7fe8a2e // indirect github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect - github.com/PuerkitoBio/purell v1.1.1 // indirect - github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful v2.9.5+incompatible // indirect + github.com/emicklei/go-restful/v3 v3.8.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/fatih/camelcase v1.0.0 // indirect github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect github.com/fvbommel/sortorder v1.0.1 // indirect - github.com/go-logr/logr v1.2.0 // indirect + github.com/go-logr/logr v1.2.3 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/swag v0.21.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/btree v1.0.1 // indirect - github.com/google/gnostic v0.5.7-v3refs // indirect + github.com/google/gnostic v0.6.9 // indirect github.com/google/gofuzz v1.1.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect @@ -80,7 +82,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/onsi/gomega v1.17.0 // indirect + github.com/onsi/gomega v1.19.0 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -91,19 +93,21 @@ require ( github.com/spyzhov/ajson v0.4.2 // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect golang.org/x/crypto v0.0.0-20220214200702-86341886e292 // indirect - golang.org/x/net v0.0.0-20220412020605-290c469a71a5 // indirect + golang.org/x/net v0.0.0-20220728211354-c7608f3a8462 // indirect golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect - golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect + golang.org/x/sys v0.0.0-20220731174439-a90be440212d // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/protobuf v1.28.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/kube-openapi v0.0.0-20220401212409-b28bf2818661 // indirect + k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 // indirect k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) + +replace github.com/GoogleContainerTools/kpt-functions-sdk/go/fn => ../kpt-functions-sdk/go/fn diff --git a/go.sum b/go.sum index cf9a05cee7..a09b1509cd 100644 --- a/go.sum +++ b/go.sum @@ -69,16 +69,17 @@ github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUM github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/GoogleContainerTools/kpt/porch/api v0.0.0-20220707151439-cb4c4e496c92 h1:0h6lonywmlgUWEc62Nvjt3IqkzudXDbplILJc7wlayI= -github.com/GoogleContainerTools/kpt/porch/api v0.0.0-20220707151439-cb4c4e496c92/go.mod h1:51Vk7QZ+XUzHCvQBi7t9tiWqTXvy6T13cv/inUXJJ0s= +github.com/GoogleContainerTools/kpt-functions-sdk/go/api v0.0.0-20220720212527-133180134b93/go.mod h1:gkK43tTaPXFNASpbIbQImzhmt1hdcdin++kvzTblykc= +github.com/GoogleContainerTools/kpt-functions-sdk/go/api v0.0.0-20220723081830-33aee7fe8a2e h1:qMte0VxQ9+kDTBIyYFK77AN5ZCi7+SFCv5Tu46sUXaY= +github.com/GoogleContainerTools/kpt-functions-sdk/go/api v0.0.0-20220723081830-33aee7fe8a2e/go.mod h1:gkK43tTaPXFNASpbIbQImzhmt1hdcdin++kvzTblykc= +github.com/GoogleContainerTools/kpt/porch/api v0.0.0-20220802174803-aa37aa6ebdfb h1:kcrlXOf3gQTbIhrZKcwbAwT/UmsNkJ1zWCX3TlZPdtI= +github.com/GoogleContainerTools/kpt/porch/api v0.0.0-20220802174803-aa37aa6ebdfb/go.mod h1:51Vk7QZ+XUzHCvQBi7t9tiWqTXvy6T13cv/inUXJJ0s= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -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/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/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -105,6 +106,7 @@ github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJm github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= @@ -157,6 +159,8 @@ github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkg github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw= +github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -176,6 +180,7 @@ github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8 github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= @@ -202,8 +207,9 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/zapr v1.2.0 h1:n4JnPI1T3Qq1SFEi/F8rwLrZERp2bso19PJZDB9dayk= github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= @@ -211,8 +217,9 @@ github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUe github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= -github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU= @@ -268,8 +275,9 @@ github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9 github.com/google/cel-go v0.9.0/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w= github.com/google/cel-go v0.10.1/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w= github.com/google/cel-spec v0.6.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA= -github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= +github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -457,11 +465,14 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0 h1:9Luw4uT5HTjHTN8+aNcSThgH1vdXnmdJ8xIfZ4wyTRE= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= @@ -561,19 +572,24 @@ github.com/spyzhov/ajson v0.4.2/go.mod h1:63V+CGM6f1Bu/p4nLIN8885ojBdt88TbLoSFzy github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= 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-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= 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/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk= @@ -737,8 +753,9 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5 h1:bRb386wvrE+oBNdF1d/Xh9mQrfQ4ecYhW5qJ5GvTGT4= golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220728211354-c7608f3a8462 h1:UreQrH7DbFXSi9ZFox6FNT3WBooWmdANpU+IfkT1T4I= +golang.org/x/net v0.0.0-20220728211354-c7608f3a8462/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= 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-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -848,8 +865,10 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220731174439-a90be440212d h1:Sv5ogFZatcgIMMtBSTTAgMYsicp25MXBubjXNDKwm80= +golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= @@ -935,6 +954,7 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM= golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1091,8 +1111,9 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1123,8 +1144,9 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= @@ -1139,15 +1161,17 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.23.0/go.mod h1:8wmDdLBHBNxtOIytwLstXt5E9PddnZb0GaMcqsvDBpg= k8s.io/api v0.23.5/go.mod h1:Na4XuKng8PXJ2JsploYYrivXrINeTaycCGcYgF91Xm8= -k8s.io/api v0.24.0 h1:J0hann2hfxWr1hinZIDefw7Q96wmCBx6SSB8IY0MdDg= k8s.io/api v0.24.0/go.mod h1:5Jl90IUrJHUJYEMANRURMiVvJ0g7Ax7r3R1bqO8zx8I= +k8s.io/api v0.24.3 h1:tt55QEmKd6L2k5DP6G/ZzdMQKvG5ro4H4teClqm0sTY= +k8s.io/api v0.24.3/go.mod h1:elGR/XSZrS7z7cSZPzVWaycpJuGIw57j9b95/1PdJNI= k8s.io/apiextensions-apiserver v0.23.0/go.mod h1:xIFAEEDlAZgpVBl/1VSjGDmLoXAWRG40+GsWhKhAxY4= k8s.io/apiextensions-apiserver v0.24.0 h1:JfgFqbA8gKJ/uDT++feAqk9jBIwNnL9YGdQvaI9DLtY= k8s.io/apiextensions-apiserver v0.24.0/go.mod h1:iuVe4aEpe6827lvO6yWQVxiPSpPoSKVjkq+MIdg84cM= k8s.io/apimachinery v0.23.0/go.mod h1:fFCTTBKvKcwTPFzjlcxp91uPFZr+JA0FubU4fLzzFYc= k8s.io/apimachinery v0.23.5/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= -k8s.io/apimachinery v0.24.0 h1:ydFCyC/DjCvFCHK5OPMKBlxayQytB8pxy8YQInd5UyQ= k8s.io/apimachinery v0.24.0/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM= +k8s.io/apimachinery v0.24.3 h1:hrFiNSA2cBZqllakVYyH/VyEh4B581bQRmqATJSeQTg= +k8s.io/apimachinery v0.24.3/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM= k8s.io/apiserver v0.23.0/go.mod h1:Cec35u/9zAepDPPFyT+UMrgqOCjgJ5qtfVJDxjZYmt4= k8s.io/apiserver v0.24.0/go.mod h1:WFx2yiOMawnogNToVvUYT9nn1jaIkMKj41ZYCVycsBA= k8s.io/cli-runtime v0.24.0 h1:ot3Qf49T852uEyNApABO1UHHpFIckKK/NqpheZYN2gM= @@ -1170,13 +1194,15 @@ k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.40.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.60.1 h1:VW25q3bZx9uE3vvdL6M8ezOX79vA2Aq1nEWLqNQclHc= k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ= +k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk= -k8s.io/kube-openapi v0.0.0-20220401212409-b28bf2818661 h1:nqYOUleKLC/0P1zbU29F5q6aoezM6MOAVz+iyfQbZ5M= k8s.io/kube-openapi v0.0.0-20220401212409-b28bf2818661/go.mod h1:daOouuuwd9JXpv1L7Y34iV3yf6nxzipkKMWWlqlvK9M= +k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 h1:yEQKdMCjzAOvGeiTwG4hO/hNVNtDOuUFvMUZ0OlaIzs= +k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8/go.mod h1:mbJ+NSUoAhuR14N0S63bPkh8MGVSo3VYSGZtH/mfMe0= k8s.io/kubectl v0.24.0 h1:nA+WtMLVdXUs4wLogGd1mPTAesnLdBpCVgCmz3I7dXo= k8s.io/kubectl v0.24.0/go.mod h1:pdXkmCyHiRTqjYfyUJiXtbVNURhv0/Q1TyRhy2d5ic0= k8s.io/metrics v0.24.0/go.mod h1:jrLlFGdKl3X+szubOXPG0Lf2aVxuV3QJcbsgVRAM6fI= @@ -1204,8 +1230,10 @@ sigs.k8s.io/kustomize/api v0.11.5/go.mod h1:2UDpxS6AonWXow2ZbySd4AjUxmdXLeTlvGBC sigs.k8s.io/kustomize/cmd/config v0.10.6/go.mod h1:/S4A4nUANUa4bZJ/Edt7ZQTyKOY9WCER0uBS1SW2Rco= sigs.k8s.io/kustomize/kustomize/v4 v4.5.4/go.mod h1:Zo/Xc5FKD6sHl0lilbrieeGeZHVYCA4BzxeAaLI05Bg= sigs.k8s.io/kustomize/kyaml v0.13.6/go.mod h1:yHP031rn1QX1lr/Xd934Ri/xdVNG8BE2ECa78Ht/kEg= -sigs.k8s.io/kustomize/kyaml v0.13.7 h1:/EZ/nPaLUzeJKF/BuJ4QCuMVJWiEVoI8iftOHY3g3tk= +sigs.k8s.io/kustomize/kyaml v0.13.7-0.20220418212550-9d5491c2e20c/go.mod h1:6K+IUOuir3Y7nucPRAjw9yth04KSWBnP5pqUTGwj/qU= sigs.k8s.io/kustomize/kyaml v0.13.7/go.mod h1:6K+IUOuir3Y7nucPRAjw9yth04KSWBnP5pqUTGwj/qU= +sigs.k8s.io/kustomize/kyaml v0.13.8 h1:L4dSaDb6dL5mzv0UWSrUw8bskcEW+EnNtIObT5BoRsU= +sigs.k8s.io/kustomize/kyaml v0.13.8/go.mod h1:QsRbD0/KcU+wdk0/L0fIp2KLnohkVzs6fQ85/nOXac4= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= sigs.k8s.io/structured-merge-diff/v4 v4.2.0/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= diff --git a/internal/cmdget/cmdget.go b/internal/cmdget/cmdget.go index 7ec1393997..19ab12b134 100644 --- a/internal/cmdget/cmdget.go +++ b/internal/cmdget/cmdget.go @@ -23,6 +23,7 @@ import ( docs "github.com/GoogleContainerTools/kpt/internal/docs/generated/pkgdocs" "github.com/GoogleContainerTools/kpt/internal/errors" "github.com/GoogleContainerTools/kpt/internal/pkg" + "github.com/GoogleContainerTools/kpt/internal/pkgautorun" "github.com/GoogleContainerTools/kpt/internal/types" "github.com/GoogleContainerTools/kpt/internal/util/argutil" "github.com/GoogleContainerTools/kpt/internal/util/cmdutil" @@ -54,6 +55,7 @@ func NewRunner(ctx context.Context, parent string) *Runner { c.Flags().StringVar(&r.strategy, "strategy", string(kptfilev1.ResourceMerge), "update strategy that should be used when updating this package -- must be one of: "+ strings.Join(kptfilev1.UpdateStrategiesAsStrings(), ",")) + c.Flags().BoolVar(&r.ReserveBuiltin, "debug", false, "") c.Flags().BoolVar(&r.isDeploymentInstance, "for-deployment", false, "(Experimental) indicates if this package will be deployed to a cluster.") _ = c.RegisterFlagCompletionFunc("strategy", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { @@ -73,6 +75,7 @@ type Runner struct { Command *cobra.Command strategy string isDeploymentInstance bool + ReserveBuiltin bool } func (r *Runner) preRunE(_ *cobra.Command, args []string) error { @@ -105,7 +108,6 @@ func (r *Runner) preRunE(_ *cobra.Command, args []string) error { return errors.E(op, types.UniquePath(t.Destination), err) } r.Get.Destination = string(p.UniquePath) - strategy, err := kptfilev1.ToUpdateStrategy(r.strategy) if err != nil { return err @@ -120,6 +122,10 @@ func (r *Runner) runE(c *cobra.Command, _ []string) error { if err := r.Get.Run(r.ctx); err != nil { return errors.E(op, types.UniquePath(r.Get.Destination), err) } - - return nil + autoRunner := pkgautorun.AutoRunner{ + Ctx: r.ctx, + Destination: r.Get.Destination, + ReserveBuiltin: r.ReserveBuiltin, + } + return autoRunner.RunPkgAutoPipeline() } diff --git a/internal/cmdrender/cmdrender.go b/internal/cmdrender/cmdrender.go index 50a7fde388..61eb9caabb 100644 --- a/internal/cmdrender/cmdrender.go +++ b/internal/cmdrender/cmdrender.go @@ -44,6 +44,8 @@ func NewRunner(ctx context.Context, parent string) *Runner { RunE: r.runE, PreRunE: r.preRunE, } + c.Flags().BoolVar(&r.enablePkgAutorun, "enable-pkg-autorun", false, + "run pkg-auto-run pipeline before render") c.Flags().StringVar(&r.resultsDirPath, "results-dir", "", "path to a directory to save function results") c.Flags().StringVarP(&r.dest, "output", "o", "", @@ -63,13 +65,14 @@ func NewCommand(ctx context.Context, parent string) *cobra.Command { // Runner contains the run function pipeline run command type Runner struct { - pkgPath string - resultsDirPath string - imagePullPolicy string - allowExec bool - dest string - Command *cobra.Command - ctx context.Context + pkgPath string + resultsDirPath string + imagePullPolicy string + enablePkgAutorun bool + allowExec bool + dest string + Command *cobra.Command + ctx context.Context } func (r *Runner) preRunE(c *cobra.Command, args []string) error { @@ -116,12 +119,13 @@ func (r *Runner) runE(c *cobra.Command, _ []string) error { return err } executor := render.Renderer{ - PkgPath: absPkgPath, - ResultsDirPath: r.resultsDirPath, - Output: output, - ImagePullPolicy: cmdutil.StringToImagePullPolicy(r.imagePullPolicy), - AllowExec: r.allowExec, - FileSystem: filesys.FileSystemOrOnDisk{}, + PkgPath: absPkgPath, + ResultsDirPath: r.resultsDirPath, + Output: output, + ImagePullPolicy: cmdutil.StringToImagePullPolicy(r.imagePullPolicy), + AllowExec: r.allowExec, + FileSystem: filesys.FileSystemOrOnDisk{}, + EnablePkgAutorun: r.enablePkgAutorun, } if err := executor.Execute(r.ctx); err != nil { return err diff --git a/internal/cmdupdate/cmdupdate.go b/internal/cmdupdate/cmdupdate.go index 938e578661..55b65480b6 100644 --- a/internal/cmdupdate/cmdupdate.go +++ b/internal/cmdupdate/cmdupdate.go @@ -25,6 +25,7 @@ import ( docs "github.com/GoogleContainerTools/kpt/internal/docs/generated/pkgdocs" "github.com/GoogleContainerTools/kpt/internal/errors" "github.com/GoogleContainerTools/kpt/internal/pkg" + "github.com/GoogleContainerTools/kpt/internal/pkgautorun" "github.com/GoogleContainerTools/kpt/internal/types" "github.com/GoogleContainerTools/kpt/internal/util/argutil" "github.com/GoogleContainerTools/kpt/internal/util/cmdutil" @@ -55,6 +56,7 @@ func NewRunner(ctx context.Context, parent string) *Runner { "the update strategy that will be used when updating the package. This will change "+ "the default strategy for the package -- must be one of: "+ strings.Join(kptfilev1.UpdateStrategiesAsStrings(), ",")) + c.Flags().BoolVar(&r.ReserveBuiltin, "debug", false, "") _ = c.RegisterFlagCompletionFunc("strategy", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { return kptfilev1.UpdateStrategiesAsStrings(), cobra.ShellCompDirectiveDefault }) @@ -70,10 +72,12 @@ func NewCommand(ctx context.Context, parent string) *cobra.Command { // Runner contains the run function. // TODO, support listing versions type Runner struct { - ctx context.Context - strategy string - Update update.Command - Command *cobra.Command + ctx context.Context + strategy string + Update update.Command + Command *cobra.Command + autoRunner *pkgautorun.AutoRunner + ReserveBuiltin bool } func (r *Runner) preRunE(_ *cobra.Command, args []string) error { @@ -120,7 +124,16 @@ func (r *Runner) preRunE(_ *cobra.Command, args []string) error { if len(parts) > 1 { r.Update.Ref = parts[1] } - return nil + r.autoRunner = &pkgautorun.AutoRunner{ + Ctx: r.ctx, + Destination: string(p.UniquePath), + ReserveBuiltin: true, + } + if err := r.autoRunner.RunPkgAutoPipeline(); err != nil { + return err + } + return r.autoRunner.DeleteNativeConfig() + } func (r *Runner) runE(c *cobra.Command, _ []string) error { @@ -128,8 +141,8 @@ func (r *Runner) runE(c *cobra.Command, _ []string) error { if err := r.Update.Run(r.ctx); err != nil { return errors.E(op, r.Update.Pkg.UniquePath, err) } - - return nil + r.autoRunner.ReserveBuiltin = r.ReserveBuiltin + return r.autoRunner.RunPkgAutoPipelineWithMerge() } func resolveRelPath(path types.UniquePath) (string, error) { diff --git a/internal/fnruntime/container.go b/internal/fnruntime/container.go index cec22b9965..29e127cf01 100644 --- a/internal/fnruntime/container.go +++ b/internal/fnruntime/container.go @@ -28,7 +28,6 @@ import ( "sync" "time" - "github.com/GoogleContainerTools/kpt/internal/printer" "github.com/GoogleContainerTools/kpt/internal/types" "github.com/GoogleContainerTools/kpt/internal/util/porch" fnresult "github.com/GoogleContainerTools/kpt/pkg/api/fnresult/v1" @@ -156,7 +155,7 @@ func (f *ContainerFn) runCLI(reader io.Reader, writer io.Writer, bin string, fil OriginalErr: exitErr, ExitCode: exitErr.ExitCode(), Stderr: filterCLIOutputFn(&errSink), - TruncateOutput: printer.TruncateOutput, + TruncateOutput: true, } } return fmt.Errorf("unexpected function error: %w", err) diff --git a/internal/fnruntime/exec.go b/internal/fnruntime/exec.go index 514429fd51..72ce8f1b75 100644 --- a/internal/fnruntime/exec.go +++ b/internal/fnruntime/exec.go @@ -23,7 +23,6 @@ import ( "os/exec" "time" - "github.com/GoogleContainerTools/kpt/internal/printer" fnresult "github.com/GoogleContainerTools/kpt/pkg/api/fnresult/v1" ) @@ -66,7 +65,7 @@ func (f *ExecFn) Run(r io.Reader, w io.Writer) error { OriginalErr: exitErr, ExitCode: exitErr.ExitCode(), Stderr: errSink.String(), - TruncateOutput: printer.TruncateOutput, + TruncateOutput: true, } } return fmt.Errorf("unexpected function error: %w", err) diff --git a/internal/fnruntime/fnerrors.go b/internal/fnruntime/fnerrors.go index 988c6d36a7..88b766eb56 100644 --- a/internal/fnruntime/fnerrors.go +++ b/internal/fnruntime/fnerrors.go @@ -49,7 +49,7 @@ func (fe *ExecError) String() string { Title: "Stderr", Lines: strings.Split(fe.Stderr, "\n"), UseQuote: true, - TruncateOutput: fe.TruncateOutput, + TruncateOutput: true, } b.WriteString(errLines.String()) b.WriteString(fmt.Sprintf(" Exit Code: %d\n", fe.ExitCode)) diff --git a/internal/fnruntime/runner.go b/internal/fnruntime/runner.go index 30f6c825bf..6da8ee725d 100644 --- a/internal/fnruntime/runner.go +++ b/internal/fnruntime/runner.go @@ -378,7 +378,7 @@ func printFnResult(ctx context.Context, fnResult *fnresult.Result, opt *printer. ri := &multiLineFormatter{ Title: "Results", Lines: lines, - TruncateOutput: printer.TruncateOutput, + TruncateOutput: true, } pr.OptPrintf(opt, "%s", ri.String()) } @@ -400,7 +400,7 @@ func printFnStderr(ctx context.Context, stdErr string) { Title: "Stderr", Lines: strings.Split(stdErr, "\n"), UseQuote: true, - TruncateOutput: printer.TruncateOutput, + TruncateOutput: true, } pr.Printf("%s", errLines.String()) } @@ -473,15 +473,17 @@ func (ri *multiLineFormatter) String() string { b.WriteString(fmt.Sprintf(" %s:\n", ri.Title)) lineIndent := strings.Repeat(" ", FnExecErrorIndentation+2) - if !ri.TruncateOutput { - // stderr string should have indentations - for _, s := range ri.Lines { - // suppress newlines to avoid poor formatting - s = strings.ReplaceAll(s, "\n", " ") - b.WriteString(fmt.Sprintf(lineIndent+strInterpolator+"\n", s)) + /* + if !ri.TruncateOutput { + // stderr string should have indentations + for _, s := range ri.Lines { + // suppress newlines to avoid poor formatting + s = strings.ReplaceAll(s, "\n", " ") + b.WriteString(fmt.Sprintf(lineIndent+strInterpolator+"\n", s)) + } + return b.String() } - return b.String() - } + */ printedLines := 0 for i, s := range ri.Lines { if i >= ri.MaxLines { diff --git a/internal/pkg/pkg.go b/internal/pkg/pkg.go index e4c55fa7b8..aef1166d1b 100644 --- a/internal/pkg/pkg.go +++ b/internal/pkg/pkg.go @@ -212,13 +212,13 @@ func New(fs filesys.FileSystem, path string) (*Pkg, error) { // Kptfile returns the Kptfile meta resource by lazy loading it from the filesytem. // A nil value represents an implicit package. func (p *Pkg) Kptfile() (*kptfilev1.KptFile, error) { - if p.kptfile == nil { - kf, err := ReadKptfile(p.fsys, p.UniquePath.String()) - if err != nil { - return nil, err - } - p.kptfile = kf + // if p.kptfile == nil { + kf, err := ReadKptfile(p.fsys, p.UniquePath.String()) + if err != nil { + return nil, err } + p.kptfile = kf + //} return p.kptfile, nil } @@ -257,7 +257,6 @@ func DecodeKptfile(in io.Reader) (*kptfilev1.KptFile, error) { if err := CheckKptfileVersion(c); err != nil { return kf, err } - d := yaml.NewDecoder(bytes.NewBuffer(c)) d.KnownFields(true) if err := d.Decode(kf); err != nil { @@ -332,6 +331,18 @@ func (p *Pkg) Pipeline() (*kptfilev1.Pipeline, error) { return pl, nil } +func (p *Pkg) PkgAutoRunPipeline() (*kptfilev1.PkgAutoRun, error) { + kf, err := p.Kptfile() + if err != nil { + return nil, err + } + autoRunPipeline := kf.PkgAutoRun + if autoRunPipeline == nil { + return &kptfilev1.PkgAutoRun{}, nil + } + return autoRunPipeline, nil +} + // String returns the slash-separated relative path to the package. func (p *Pkg) String() string { return string(p.DisplayPath) diff --git a/internal/pkgautorun/autorun.go b/internal/pkgautorun/autorun.go new file mode 100644 index 0000000000..7767f72a7e --- /dev/null +++ b/internal/pkgautorun/autorun.go @@ -0,0 +1,566 @@ +package pkgautorun + +import ( + "bytes" + "context" + "fmt" + "io/ioutil" + "os" + "path/filepath" + + "github.com/GoogleContainerTools/kpt-functions-sdk/go/fn" + "github.com/GoogleContainerTools/kpt/internal/fnruntime" + "github.com/GoogleContainerTools/kpt/internal/pkg" + "github.com/GoogleContainerTools/kpt/internal/printer" + kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" + "github.com/GoogleContainerTools/kpt/thirdparty/cmdconfig/commands/runner" + "github.com/GoogleContainerTools/kpt/thirdparty/kyaml/runfn" + "github.com/google/shlex" + "sigs.k8s.io/kustomize/kyaml/filesys" + "sigs.k8s.io/kustomize/kyaml/fn/runtime/runtimeutil" + "sigs.k8s.io/kustomize/kyaml/kio" + "sigs.k8s.io/kustomize/kyaml/kio/kioutil" + "sigs.k8s.io/kustomize/kyaml/yaml" + "sigs.k8s.io/kustomize/kyaml/yaml/merge3" +) + +const GeneratedDir = "generated" +const builtinMergedAnnotation = "internal.kpt.dev/generated-builtin-merged" +const ( + NativeConfigOpBackToNative = "writeBackToNativeConfig" + NativeConfigAdaptorImage = "gcr.io/kpt-fn-demo/configmap-generator:yuwen-v0.1" + ConfigMapTmpFnPath = "generated/config-map-fn-config.yaml" +) + +func (r *AutoRunner) NewConfigMapGenerator(generator *fn.KubeObject, kf *kptfilev1.KptFile) (*kptfilev1.Function, error) { + source := generator.GetMap("spec").GetSlice("source")[0] + source.SetNestedString(NativeConfigOpBackToNative, "operation") + + for _, inclNonKrmFile := range kf.PkgAutoRun.InclNonKrmFiles { + if inclNonKrmFile.Name == source.GetString("localFileRef") { + source.SetNestedString(inclNonKrmFile.Path, "localFile") + } + } + var fileErr error + var f *os.File + defer f.Close() + os.Mkdir(GeneratedDir, os.ModePerm) + if _, err := os.Stat(ConfigMapTmpFnPath); os.IsNotExist(err) { + f, fileErr = os.Create(ConfigMapTmpFnPath) + } else { + f, fileErr = os.OpenFile(ConfigMapTmpFnPath, os.O_CREATE|os.O_WRONLY, 0660) + } + if fileErr != nil { + return nil, fileErr + } + if _, writeErr := f.WriteString(generator.String()); writeErr != nil { + return nil, writeErr + } + return &kptfilev1.Function{ + Image: NativeConfigAdaptorImage, + ConfigPath: ConfigMapTmpFnPath, + }, nil +} + +type AutoRunner struct { + Ctx context.Context + Destination string + ReserveBuiltin bool + trackNativeConfigs fn.KubeObjects + originGenerated fn.KubeObjects +} + +func (r *AutoRunner) RunPkgAutoPipelineWithMerge() error { + return r.runPkgAutoPipeline(true) +} + +func (r *AutoRunner) RunPkgAutoPipeline() error { + return r.runPkgAutoPipeline(false) +} + +func (r *AutoRunner) runPkgAutoPipeline(enableMerge bool) error { + p, err := pkg.New(filesys.FileSystemOrOnDisk{}, r.Destination) + if err != nil { + return err + } + kf, err := p.Kptfile() + if err != nil { + return err + } + var nonKrmObjects fn.KubeObjects + if kf.PkgAutoRun.InclNonKrmFiles != nil { + nonKrmObjects, err = r.GenerateNonKrmResources(kf.PkgAutoRun.InclNonKrmFiles) + if err != nil { + return err + } + } + var writer kio.ReaderWriter + out := &bytes.Buffer{} + writer = &kio.ByteReadWriter{ + Writer: out, + KeepReaderAnnotations: true, + WrappingKind: kio.ResourceListKind, + WrappingAPIVersion: kio.ResourceListAPIVersion, + } + var rl *fn.ResourceList + var rawResourceList, output []byte + + for _, kptFunction := range kf.PkgAutoRun.BuiltInFunctions { + configs, _ := kio.LocalPackageReader{PackagePath: filepath.Join(p.UniquePath.String(), kptFunction.ConfigPath), PreserveSeqIndent: true, WrapBareSeqNode: true}.Read() + if len(configs) != 1 { + return fmt.Errorf("expected exactly 1 functionConfig, found %d", len(configs)) + } + functionConfig := configs[0] + rawResourceList, err = r.ReadResourceListFromFnSource(p.UniquePath.String(), functionConfig) + + if err != nil { + return err + } + rl, err = fn.ParseResourceList(rawResourceList) + if err != nil { + return err + } + r.trackNativeConfigs = nonKrmObjects + RefreshNonKrmObjects(rl, nonKrmObjects) + var oldGenerated, newGenerated fn.KubeObjects + if enableMerge { + rl.Items, oldGenerated = separateGenerated(rl.Items) + if err = r.RunFunction(writer, functionConfig, rl, kptFunction); err != nil { + return err + } + if rl, err = fn.ParseResourceList(out.Bytes()); err != nil { + return err + } + rl.Items, newGenerated = separateGenerated(rl.Items) + var mergedObjects fn.KubeObjects + mergedObjects, err = mergeGenerated(oldGenerated, r.originGenerated, newGenerated) + if err != nil { + return err + } + rl.Items = append(rl.Items, mergedObjects...) + output, err = rl.ToYAML() + if err != nil { + return err + } + output, err = r.UpdateNonKrmAfterMerge(string(output)) + if err != nil { + return err + } + output, err = r.CleanupBuiltInObjects(string(output)) + if err != nil { + return err + } + return writeResourceListToLocalPackage(output, string(p.UniquePath)) + } else { + if err = r.RunFunction(writer, functionConfig, rl, kptFunction); err != nil { + return err + } + output, err = r.CleanupBuiltInObjects(out.String()) + if err != nil { + return err + } + if err = r.CacheOriginFromGeneratedDir(p.UniquePath.String()); err != nil { + return err + } + return writeResourceListToLocalPackage(output, string(p.UniquePath)) + } + } + return nil +} + +func (r *AutoRunner) CacheOriginFromGeneratedDir(resolvedPath string) error { + var buf bytes.Buffer + p := kio.Pipeline{ + ContinueOnEmptyResult: true, + Inputs: []kio.Reader{ + kio.LocalPackageReader{ + PackagePath: resolvedPath, + MatchFilesGlob: pkg.MatchAllKRM, + PreserveSeqIndent: true, + WrapBareSeqNode: true, + }, + }, + Outputs: []kio.Writer{ + kio.ByteWriter{ + Writer: &buf, + KeepReaderAnnotations: true, + WrappingKind: kio.ResourceListKind, + WrappingAPIVersion: kio.ResourceListAPIVersion, + Sort: true, + }, + }, + } + if err := p.Execute(); err != nil { + panic(err) + } + rl, err := fn.ParseResourceList(buf.Bytes()) + if err != nil { + return err + } + r.originGenerated = rl.Items.Where(func(o *fn.KubeObject) bool { return o.GetAnnotation(fn.GeneratorBuiltinIdentifier) != "" }) + return nil +} + +func RefreshNonKrmObjects(rl *fn.ResourceList, nonKrmObjects fn.KubeObjects) { + rl.Items = rl.Items.WhereNot(func(o *fn.KubeObject) bool { return o.GetKind() == fn.NonKrmKind }) + rl.Items = append(rl.Items, nonKrmObjects...) +} + +func writeResourceListToLocalPackage(input []byte, uniquePath string) error { + if err := os.RemoveAll(GeneratedDir); err != nil { + return err + } + pkgWriter := &kio.LocalPackageReadWriter{ + PackagePath: uniquePath, + MatchFilesGlob: pkg.MatchAllKRM, + PreserveSeqIndent: true, + PackageFileName: kptfilev1.KptFileName, + IncludeSubpackages: true, + WrapBareSeqNode: true, + } + return kio.Pipeline{ + Inputs: []kio.Reader{&kio.ByteReader{Reader: bytes.NewBuffer(input)}}, + Outputs: []kio.Writer{pkgWriter}, + }.Execute() +} + +// TODO: get Origin from the UpstreamLock +func mergeGenerated(oldObjects, originObjects, upsertedObjects fn.KubeObjects) (fn.KubeObjects, error) { + var mergedObjects fn.KubeObjects + for _, upserted := range upsertedObjects { + + old := oldObjects.Where(func(o *fn.KubeObject) bool { + return o.GetAnnotation(fn.GeneratorBuiltinIdentifier) == upserted.GetAnnotation(fn.GeneratorBuiltinIdentifier) && o.GetKind() == upserted.GetKind() + })[0] + localRnode := old.ToRNode() + updatedRnode := upserted.ToRNode() + origins := originObjects.Where(func(o *fn.KubeObject) bool { + return o.GetAnnotation(fn.GeneratorBuiltinIdentifier) == upserted.GetAnnotation(fn.GeneratorBuiltinIdentifier) && o.GetKind() == upserted.GetKind() + }) + var originRnode *yaml.RNode + if len(origins) > 0 { + originRnode = origins[0].ToRNode() + } else { + originRnode = updatedRnode + } + merged, err := merge3.Merge(localRnode, originRnode, updatedRnode) + if err != nil { + return nil, fmt.Errorf(err.Error() + "1") + } + + mergedKubeObject := fn.RnodeToKubeObject(merged) + if err != nil { + return nil, fmt.Errorf(err.Error() + "2") + } + mergedKubeObject.SetAnnotation(builtinMergedAnnotation, "true") + mergedObjects = append(mergedObjects, mergedKubeObject) + } + + return mergedObjects, nil +} + +func separateGenerated(items fn.KubeObjects) (fn.KubeObjects, fn.KubeObjects) { + var nonGeneratedObjects fn.KubeObjects + var generatedObjects fn.KubeObjects + for _, object := range items { + switch true { + case object.GetAnnotation(fn.GeneratorBuiltinIdentifier) != "": + generatedObjects = append(generatedObjects, object) + default: + nonGeneratedObjects = append(nonGeneratedObjects, object) + } + } + return nonGeneratedObjects, generatedObjects +} + +func getFunctionSpec(image, exec string) (*runtimeutil.FunctionSpec, error) { + fn := &runtimeutil.FunctionSpec{} + if image != "" { + fn.Container.Image = image + } else if exec != "" { + s, err := shlex.Split(exec) + if err != nil { + return nil, fmt.Errorf("exec command %q must be valid: %w", exec, err) + } + if len(s) > 0 { + fn.Exec.Path = s[0] + } + } + return fn, nil +} + +func (r *AutoRunner) RunFunction(writer kio.Writer, functionConfig *yaml.RNode, inputResourceList *fn.ResourceList, function kptfilev1.Function) error { + p, err := pkg.New(filesys.FileSystemOrOnDisk{}, r.Destination) + output := &bytes.Buffer{} + content, _ := inputResourceList.ToYAML() + input := bytes.NewReader(content) + fnSpec, err := getFunctionSpec(function.Image, function.Exec) + if err != nil { + return err + } + run := runfn.RunFns{ + Ctx: r.Ctx, + Input: input, + Output: output, + ImagePullPolicy: fnruntime.IfNotPresentPull, + AsCurrentUser: false, + ContinueOnEmptyResult: true, + Function: fnSpec, + OriginalExec: function.Exec, + Path: p.UniquePath.String(), + FnConfig: functionConfig, + } + if err = runner.HandleError(r.Ctx, run.Execute()); err != nil { + return err + } + rl, _ := fn.ParseResourceList(output.Bytes()) + for _, o := range rl.Items { + if o.GetAnnotation(fn.GeneratorBuiltinIdentifier) != "" || o.GetAnnotation(fn.GeneratorIdentifier) != "" || o.GetKind() == fn.NonKrmKind { + curFilePath := o.GetAnnotation(fn.PathAnnotation) + newFilePath := filepath.Join(GeneratedDir, filepath.Base(curFilePath)) + o.SetAnnotation(fn.PathAnnotation, newFilePath) + o.SetAnnotation(kioutil.LegacyPathAnnotation, newFilePath) + o.SetAnnotation(kioutil.LegacyIndexAnnotation, o.GetAnnotation(fn.IndexAnnotation)) + } + } + + newOutput, err := rl.ToYAML() + if err != nil { + return err + } + return kio.Pipeline{ + Inputs: []kio.Reader{&kio.ByteReader{ + Reader: bytes.NewBuffer(newOutput), + PreserveSeqIndent: true, + WrapBareSeqNode: true, + WrappingKind: kio.ResourceListKind, + WrappingAPIVersion: kio.ResourceListAPIVersion, + }}, + Outputs: []kio.Writer{writer}, + }.Execute() +} + +func IsInternalGenerator(o *fn.KubeObject) bool { + if o.GetKind() != "ConfigMapGenerator" { + return false + } + sources := o.GetMap("spec").GetSlice("source") + for _, source := range sources { + + val, _, _ := source.NestedString("operation") + if val == NativeConfigOpBackToNative { + return true + } + } + return false +} +func (r *AutoRunner) CleanupBuiltInObjects(data string) ([]byte, error) { + p, _ := pkg.New(filesys.FileSystemOrOnDisk{}, r.Destination) + os.Remove(filepath.Join(p.UniquePath.String(), ConfigMapTmpFnPath)) + rl, err := fn.ParseResourceList([]byte(data)) + if err != nil { + return nil, err + } + var newItems fn.KubeObjects + for _, item := range rl.Items { + if item.GetKind() == fn.NonKrmKind { + continue + } + if !r.ReserveBuiltin && item.GetAnnotation(fn.GeneratorBuiltinIdentifier) != "" { + continue + } + + if item.GetAnnotation(fn.GeneratorBuiltinIdentifier) != "" || item.GetAnnotation(fn.GeneratorIdentifier) != "" { + curFilePath := item.GetAnnotation(fn.PathAnnotation) + newFilePath := filepath.Join(GeneratedDir, filepath.Base(curFilePath)) + item.SetAnnotation(fn.PathAnnotation, newFilePath) + item.SetAnnotation(kioutil.LegacyPathAnnotation, newFilePath) + item.SetAnnotation(kioutil.LegacyIndexAnnotation, item.GetAnnotation(fn.IndexAnnotation)) + } + newItems = append(newItems, item) + } + rl.Items = newItems + return rl.ToYAML() +} + +func (r *AutoRunner) UpdateNonKrmAfterMerge(data string) ([]byte, error) { + rl, err := fn.ParseResourceList([]byte(data)) + if err != nil { + return nil, err + } + // should have single builtin merge anno + sourceOfTruthCanonicalFn := func(o *fn.KubeObject) bool { + return o.GetAnnotation(builtinMergedAnnotation) != "" + } + sotCanonicalObjects := rl.Items.Where(sourceOfTruthCanonicalFn) + if len(sotCanonicalObjects) == 0 { + sotCanonicalObjects = rl.Items.Where(func(o *fn.KubeObject) bool { + return o.GetAnnotation(fn.GeneratorBuiltinIdentifier) != "" + }) + } + if len(sotCanonicalObjects) > 1 { + sotCanonicalObjects = []*fn.KubeObject{sotCanonicalObjects[len(sotCanonicalObjects)-1]} + } + for _, obj := range sotCanonicalObjects { + // Get the matching Generator from annotation + generatorFnConfigResourceID := obj.GetAnnotation(fn.GeneratorBuiltinIdentifier) + if generatorFnConfigResourceID == "" { + return nil, fmt.Errorf("missing generator builtin annotation %v", obj.String()) + } + generatorFnConfigs := rl.Items.Where(func(o *fn.KubeObject) bool { + return o.GetKind() == "ConfigMapGenerator" + }) + if len(generatorFnConfigs) == 0 { + return nil, fmt.Errorf("missing generator function config") + } + // WriteToNonKrmFromCanonical removes old nonKRM object, so WriteNonKrmToNativeFile can just write all native config. + if err = r.WriteToNonKrmFromCanonical(generatorFnConfigs[0], rl); err != nil { + return nil, err + } + if err = r.WriteNonKrmToNativeFile(rl); err != nil { + return nil, err // should have single builtin merge + } + } + return rl.ToYAML() +} + +// WriteNonKrmToNativeFile write non KRM object back to the native file and remove the non KRM object from the resourcelist. +func (r *AutoRunner) WriteNonKrmToNativeFile(rl *fn.ResourceList) error { + rawConfigMaps := rl.Items.Where(func(o *fn.KubeObject) bool { + return o.GetKind() == "ConfigMap" && o.GetAnnotation(fn.GeneratorIdentifier) != "" + }) + if len(rawConfigMaps) != 1 { + return fmt.Errorf("expect a single raw ConfigMap. got " + rawConfigMaps.String()) + } + rawFileAndContent, found, err := rawConfigMaps[0].NestedStringMap("data") + if !found || err != nil { + return fmt.Errorf("no data from SOT canonical ConfigMap") + } + var f *os.File + defer f.Close() + for file, content := range rawFileAndContent { + var fileErr error + if _, err := os.Stat(file); os.IsNotExist(err) { + f, fileErr = os.Create(file) + } else { + f, fileErr = os.OpenFile(file, os.O_CREATE|os.O_WRONLY, 0660) + } + if fileErr != nil { + return fileErr + } + if _, writeErr := f.WriteString(content); writeErr != nil { + return writeErr + } + pr := printer.FromContextOrDie(r.Ctx) + pr.Printf("Successfully update " + file + "\n") + } + return nil +} + +func (r *AutoRunner) WriteToNonKrmFromCanonical(fnConfig *fn.KubeObject, rl *fn.ResourceList) error { + out := &bytes.Buffer{} + writer := kio.ByteWriter{ + Writer: out, + KeepReaderAnnotations: true, + WrappingKind: kio.ResourceListKind, + WrappingAPIVersion: kio.ResourceListAPIVersion, + Sort: true, + } + // Get filename from Kptfile pkgAutoRun + p, err := pkg.New(filesys.FileSystemOrOnDisk{}, r.Destination) + if err != nil { + return err + } + kf, err := p.Kptfile() + if err != nil { + return err + } + pr := printer.FromContextOrDie(r.Ctx) + // fnConfig should be ConfigMapGenerator + function, err := r.NewConfigMapGenerator(fnConfig, kf) + if err != nil { + return err + } + + rl.Items = rl.Items.WhereNot(fn.IsNonKrmObject) + configs, _ := kio.LocalPackageReader{PackagePath: filepath.Join(p.UniquePath.String(), ConfigMapTmpFnPath), PreserveSeqIndent: true, WrapBareSeqNode: true}.Read() + if len(configs) == 0 { + return fmt.Errorf("unable to write configMapGenerator fn-config to " + ConfigMapTmpFnPath) + } + if err := r.RunFunction(writer, configs[0], rl, *function); err != nil { + pr.Printf("fail run function " + rl.Items.String() + "\n\n") + + return err + } + newrl, err := fn.ParseResourceList(out.Bytes()) + if err != nil { + return err + } + rl.Items = newrl.Items + for _, o := range rl.Items { + if o.GetId().String() == fnConfig.GetId().String() { + sources := o.GetMap("spec").GetSlice("source") + for _, source := range sources { + source.RemoveNestedField("operation") + source.RemoveNestedField("localFile") + } + } + } + rl.Results = newrl.Results + return nil +} + +func (r *AutoRunner) GenerateNonKrmResources(includeNonKrmFiels []kptfilev1.LocalFile) (fn.KubeObjects, error) { + var nonKrmObjects []*fn.KubeObject + for _, localNonKrmFile := range includeNonKrmFiels { + content, err := ioutil.ReadFile(filepath.Join(r.Destination, localNonKrmFile.Path)) + if err != nil { + return nil, err + } + newNonKrmFile := fn.NewNonKrmResource() + obj, err := fn.NewFromTypedObject(newNonKrmFile) + if err != nil { + return nil, err + } + obj.SetName(localNonKrmFile.Name) + obj.SetNestedString(string(content), "spec", "content") + obj.SetNestedString(filepath.Base(localNonKrmFile.Path), "spec", "filename") + nonKrmObjects = append(nonKrmObjects, obj) + } + return nonKrmObjects, nil +} + +func (r *AutoRunner) ReadResourceListFromFnSource(resolvedPath string, fnConfig *yaml.RNode) ([]byte, error) { + var inputs []kio.Reader + inputs = append(inputs, kio.LocalPackageReader{ + PackagePath: resolvedPath, + MatchFilesGlob: pkg.MatchAllKRM, + PreserveSeqIndent: true, + PackageFileName: kptfilev1.KptFileName, + IncludeSubpackages: true, + WrapBareSeqNode: true, + }) + var outputs []kio.Writer + actual := &bytes.Buffer{} + outputs = append(outputs, kio.ByteWriter{ + Writer: actual, + FunctionConfig: fnConfig, + WrappingKind: kio.ResourceListKind, + WrappingAPIVersion: kio.ResourceListAPIVersion, + }) + err := kio.Pipeline{Inputs: inputs, Outputs: outputs}.Execute() + if err != nil { + return nil, err + } + return actual.Bytes(), err +} + +func (r *AutoRunner) DeleteNativeConfig() error { + for _, o := range r.trackNativeConfigs { + fpath := filepath.Join(r.Destination, o.GetMap("spec").GetString("filename")) + if err := os.Remove(fpath); err != nil { + return err + } + } + return nil +} diff --git a/internal/util/render/executor.go b/internal/util/render/executor.go index 9284050e9e..9e2c7287b8 100644 --- a/internal/util/render/executor.go +++ b/internal/util/render/executor.go @@ -22,9 +22,11 @@ import ( "path/filepath" "strings" + krmfn "github.com/GoogleContainerTools/kpt-functions-sdk/go/fn" "github.com/GoogleContainerTools/kpt/internal/errors" "github.com/GoogleContainerTools/kpt/internal/fnruntime" "github.com/GoogleContainerTools/kpt/internal/pkg" + "github.com/GoogleContainerTools/kpt/internal/pkgautorun" "github.com/GoogleContainerTools/kpt/internal/printer" "github.com/GoogleContainerTools/kpt/internal/types" "github.com/GoogleContainerTools/kpt/internal/util/attribution" @@ -67,6 +69,8 @@ type Renderer struct { // FileSystem is the input filesystem to operate on FileSystem filesys.FileSystem + + EnablePkgAutorun bool } // Execute runs a pipeline. @@ -91,14 +95,13 @@ func (e *Renderer) Execute(ctx context.Context) error { runtime: e.Runtime, } - if _, err = hydrate(ctx, root, hctx); err != nil { + if _, err = hydrate(ctx, root, hctx, e.EnablePkgAutorun); err != nil { // Note(droot): ignore the error in function result saving // to avoid masking the hydration error. // don't disable the CLI output in case of error _ = e.saveFnResults(ctx, hctx.fnResults) return errors.E(op, root.pkg.UniquePath, err) } - // adjust the relative paths of the resources. err = adjustRelPath(hctx) if err != nil { @@ -265,7 +268,7 @@ func (s hydrationState) String() string { } // hydrate hydrates given pkg and returns wet resources. -func hydrate(ctx context.Context, pn *pkgNode, hctx *hydrationContext) (output []*yaml.RNode, err error) { +func hydrate(ctx context.Context, pn *pkgNode, hctx *hydrationContext, enablePkgAutorun bool) (output []*yaml.RNode, err error) { const op errors.Op = "pkg.render" curr, found := hctx.pkgs[pn.pkg.UniquePath] @@ -310,7 +313,7 @@ func hydrate(ctx context.Context, pn *pkgNode, hctx *hydrationContext) (output [ return output, errors.E(op, subpkg.UniquePath, err) } - transitiveResources, err = hydrate(ctx, subPkgNode, hctx) + transitiveResources, err = hydrate(ctx, subPkgNode, hctx, enablePkgAutorun) if err != nil { return output, errors.E(op, subpkg.UniquePath, err) } @@ -331,12 +334,28 @@ func hydrate(ctx context.Context, pn *pkgNode, hctx *hydrationContext) (output [ // include current package's resources in the input resource list input = append(input, currPkgResources...) - + // Initialize a AutoRunner + autoRunner := &pkgautorun.AutoRunner{ + Ctx: ctx, + ReserveBuiltin: true, + Destination: string(pn.pkg.UniquePath), + } + if enablePkgAutorun { + input, err = curr.RunPkgPipeline(ctx, autoRunner, hctx, input) + if err != nil { + return output, errors.E(op, curr.pkg.UniquePath, err) + } + } output, err = curr.runPipeline(ctx, hctx, input) if err != nil { return output, errors.E(op, curr.pkg.UniquePath, err) } - + if enablePkgAutorun { + output, err = curr.ClosePkgAutopipeline(ctx, autoRunner, output) + if err != nil { + return output, errors.E(op, curr.pkg.UniquePath, err) + } + } // pkg is hydrated, mark the pkg as wet and update the resources curr.state = Wet curr.resources = output @@ -344,6 +363,164 @@ func hydrate(ctx context.Context, pn *pkgNode, hctx *hydrationContext) (output [ return output, err } +func (pn *pkgNode) recreateResourceList(autoRunner *pkgautorun.AutoRunner, input []*yaml.RNode) (*krmfn.ResourceList, error) { + kf, _ := pn.pkg.Kptfile() + kptFunction := kf.PkgAutoRun.BuiltInFunctions[0] + configs, _ := kio.LocalPackageReader{PackagePath: filepath.Join(pn.pkg.UniquePath.String(), kptFunction.ConfigPath), PreserveSeqIndent: true, WrapBareSeqNode: true}.Read() + if len(configs) != 1 { + return nil, fmt.Errorf("expected exactly 1 functionConfig, found %d", len(configs)) + } + functionConfig := configs[0] + rawResourceList, err := autoRunner.ReadResourceListFromFnSource(pn.pkg.UniquePath.String(), functionConfig) + if err != nil { + return nil, err + } + rl, err := krmfn.ParseResourceList(rawResourceList) + if err != nil { + return nil, err + } + var kubeObjects krmfn.KubeObjects + for _, node := range input { + ko := krmfn.RnodeToKubeObject(node) + kubeObjects = append(kubeObjects, ko) + } + rl.Items = kubeObjects + return rl, nil +} + +func (pn *pkgNode) ClosePkgAutopipeline(ctx context.Context, autoRunner *pkgautorun.AutoRunner, input []*yaml.RNode) ([]*yaml.RNode, error) { + pkgPipeline, err := pn.pkg.PkgAutoRunPipeline() + if err != nil { + return nil, err + } + if pkgPipeline.IsEmpty() { + if err := kptfilev1.AreKRM(input); err != nil { + return nil, fmt.Errorf("input resource list must contain only KRM resources: %s", err.Error()) + } + return input, nil + } + // Simplify the code to a single function. + rl, err := pn.recreateResourceList(autoRunner, input) + inputBytes, err := rl.ToYAML() + if err != nil { + return nil, err + } + output, err := autoRunner.UpdateNonKrmAfterMerge(string(inputBytes)) + output, err = autoRunner.CleanupBuiltInObjects(string(output)) + + if err != nil { + return nil, err + } + rl, err = krmfn.ParseResourceList(output) + var newRnodeList []*yaml.RNode + for _, ko := range rl.Items { + if ko.GetAnnotation(krmfn.GeneratorBuiltinIdentifier) != "" { + continue + } + rnode := ko.ToRNode() + err := pkg.SetPkgPathAnnotation(rnode, pn.pkg.UniquePath) + if err != nil { + return nil, err + } + newRnodeList = append(newRnodeList, rnode) + } + return newRnodeList, nil +} + +func (pn *pkgNode) RunPkgPipeline(ctx context.Context, autorunner *pkgautorun.AutoRunner, hctx *hydrationContext, input []*yaml.RNode) ([]*yaml.RNode, error) { + const op errors.Op = "pipeline.pkgPipelineRun" + pr := printer.FromContextOrDie(ctx) + pr.OptPrintf(printer.NewOpt().PkgDisplay(pn.pkg.DisplayPath), "\n") + + // Validate PkgAutoRun + pkgPipeline, err := pn.pkg.PkgAutoRunPipeline() + if err != nil { + return nil, err + } + if pkgPipeline.IsEmpty() { + if err := kptfilev1.AreKRM(input); err != nil { + return nil, fmt.Errorf("input resource list must contain only KRM resources: %s", err.Error()) + } + return input, nil + } + // Filter out generated resources + var tmpInput []*yaml.RNode + for _, node := range input { + if v, ok := node.GetAnnotations()[krmfn.GeneratorBuiltinIdentifier]; ok && v != "" { + continue + } + if v, ok := node.GetAnnotations()[krmfn.GeneratorIdentifier]; ok && v != "" { + continue + } + if node.GetKind() == krmfn.NonKrmKind { + continue + } + tmpInput = append(tmpInput, node) + } + input = tmpInput + // Read native files as a BuiltinNonKRM KRM objects + nonKrmKubeObjects, err := autorunner.GenerateNonKrmResources(pkgPipeline.InclNonKrmFiles) + if err != nil { + return nil, err + } + var nonKrmRNodes []*yaml.RNode + for _, ko := range nonKrmKubeObjects { + nonKrmRNodes = append(nonKrmRNodes, ko.ToRNode()) + } + input = append(input, nonKrmRNodes...) + // Run PkgAutoRun pipeline. + resources, err := pn.pkgRun(pkgPipeline.BuiltInFunctions, ctx, hctx, input) + if err != nil { + return nil, errors.E(op, pn.pkg.UniquePath, err) + } + return resources, nil +} + +// Only run a single function here. +func (pn *pkgNode) pkgRun(functions []kptfilev1.Function, ctx context.Context, hctx *hydrationContext, input []*yaml.RNode) ([]*yaml.RNode, error) { + pkgGenerators, err := fnChain(ctx, hctx, pn.pkg.UniquePath, functions) + if err != nil { + return nil, err + } + + for i, generator := range pkgGenerators { + if functions[i].ConfigPath != "" { + for _, r := range input { + pkgPath, err := pkg.GetPkgPathAnnotation(r) + if err != nil { + return nil, err + } + currPath, _, err := kioutil.GetFileAnnotations(r) + if err != nil { + return nil, err + } + if pkgPath == pn.pkg.UniquePath.String() && // resource belong to current package + currPath == functions[i].ConfigPath { // configPath matches + generator.SetFnConfig(r) + continue + } + } + } + output := &kio.PackageBuffer{} + // create a kio pipeline from kyaml library to execute the function chains + singleGenerator := kio.Pipeline{ + Inputs: []kio.Reader{ + &kio.PackageBuffer{Nodes: input}, + }, + Filters: []kio.Filter{generator}, + Outputs: []kio.Writer{output}, + } + err = singleGenerator.Execute() + if err != nil { + return nil, err + } + hctx.executedFunctionCnt++ + + input = output.Nodes + } + return input, nil +} + // runPipeline runs the pipeline defined at current pkgNode on given input resources. func (pn *pkgNode) runPipeline(ctx context.Context, hctx *hydrationContext, input []*yaml.RNode) ([]*yaml.RNode, error) { const op errors.Op = "pipeline.run" @@ -379,7 +556,6 @@ func (pn *pkgNode) runPipeline(ctx context.Context, hctx *hydrationContext, inpu return nil, errors.E(op, pn.pkg.UniquePath, err) } // print a new line after a pipeline running - pr.Printf("\n") return mutatedResources, nil } diff --git a/pkg/api/kptfile/v1/types.go b/pkg/api/kptfile/v1/types.go index c5bd88837f..a284bdbfad 100644 --- a/pkg/api/kptfile/v1/types.go +++ b/pkg/api/kptfile/v1/types.go @@ -56,7 +56,18 @@ type KptFile struct { Pipeline *Pipeline `yaml:"pipeline,omitempty" json:"pipeline,omitempty"` // Inventory contains parameters for the inventory object used in apply. - Inventory *Inventory `yaml:"inventory,omitempty" json:"inventory,omitempty"` + Inventory *Inventory `yaml:"inventory,omitempty" json:"inventory,omitempty"` + PkgAutoRun *PkgAutoRun `yaml:"pkgAutoRun,omitempty" json:"pkgAutoRun,omitempty"` +} + +type PkgAutoRun struct { + InclNonKrmFiles []LocalFile `yaml:"inclNonKrmFiles,omitempty" json:"inclNonKrmFiles,omitempty"` + BuiltInFunctions []Function `yaml:"pipeline,omitempty" json:"pipeline,omitempty"` +} + +type LocalFile struct { + Name string `yaml:"name,omitempty" json:"name,omitempty"` + Path string `yaml:"path,omitempty" json:"path,omitempty"` } // OriginType defines the type of origin for a package. @@ -253,6 +264,13 @@ func (p *Pipeline) IsEmpty() bool { return false } +func (p *PkgAutoRun) IsEmpty() bool { + if p == nil { + return true + } + return len(p.BuiltInFunctions) == 0 +} + // Function specifies a KRM function. type Function struct { // `Image` specifies the function container image. diff --git a/pkg/kptfile/kptfileutil/util.go b/pkg/kptfile/kptfileutil/util.go index 6858f8608f..a369f11639 100644 --- a/pkg/kptfile/kptfileutil/util.go +++ b/pkg/kptfile/kptfileutil/util.go @@ -272,6 +272,7 @@ func merge(localKf, updatedKf, originalKf *kptfilev1.KptFile) error { localKf.Info = mergedKf.Info localKf.Pipeline = mergedKf.Pipeline localKf.Inventory = mergedKf.Inventory + localKf.PkgAutoRun = mergedKf.PkgAutoRun return nil }