From cd117caa9f8c23e7953ffd66a5d660e7151ee193 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 20:04:45 +0000 Subject: [PATCH 01/31] Update k8s.io/utils digest to b307cd5 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index db763d7..d88ba3a 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( k8s.io/api v0.28.4 k8s.io/apiextensions-apiserver v0.28.4 k8s.io/apimachinery v0.28.4 - k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf + k8s.io/utils v0.0.0-20231127182322-b307cd553661 sigs.k8s.io/controller-tools v0.13.0 ) diff --git a/go.sum b/go.sum index 6c5ccd7..383fce2 100644 --- a/go.sum +++ b/go.sum @@ -667,6 +667,8 @@ k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSn k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf h1:iTzha1p7Fi83476ypNSz8nV9iR9932jIIs26F7gNLsU= k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI= +k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From 0f60986efad8b7aa9bb000261fc19060f844df9e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 1 Dec 2023 13:51:03 +0000 Subject: [PATCH 02/31] fix(deps): update module github.com/crossplane/crossplane-runtime to v1.14.3 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index db763d7..cd84967 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.21.3 require ( github.com/alecthomas/kong v0.8.1 - github.com/crossplane/crossplane-runtime v1.14.2 + github.com/crossplane/crossplane-runtime v1.14.3 github.com/crossplane/function-sdk-go v0.1.0 github.com/google/go-cmp v0.6.0 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index 5c8071d..cd7f3bf 100644 --- a/go.sum +++ b/go.sum @@ -71,6 +71,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/crossplane/crossplane-runtime v1.14.2 h1:pV5JMzyzi/kcbeVBVPCat5MHH8zS94MBUapAyGx/Ry0= github.com/crossplane/crossplane-runtime v1.14.2/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o= +github.com/crossplane/crossplane-runtime v1.14.3 h1:YNGALph/UJTtQO+cJ9KGQ5NfALI5453PeE93Aqy9SWg= +github.com/crossplane/crossplane-runtime v1.14.3/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o= github.com/crossplane/function-sdk-go v0.1.0 h1:WN3CUSaj6wgDqQPZZP1whMVIkTAZtN3HVCS67pTMzd8= github.com/crossplane/function-sdk-go v0.1.0/go.mod h1:oRqHZ6RufpfZJ1N8aT4EfkP+5KpkhOKpWz7SeUDwwcw= github.com/crossplane/upjet v0.11.0-rc.0.0.20231012093706-c4a76d2a7505 h1:eCmYgfRopVn6r8RM1Ra4XQAPwVsjTGfktBj2Dk7yy+Y= From 76b1a8a34a529a99d76904cbf9c25f20762f5e48 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 15:52:40 +0000 Subject: [PATCH 03/31] chore(deps): update actions/setup-go action to v5 --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 569a583..3464e91 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,7 +43,7 @@ jobs: uses: actions/checkout@v4 - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} cache: false # The golangci-lint action does its own caching. @@ -60,7 +60,7 @@ jobs: uses: actions/checkout@v4 - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: ${{ env.GO_VERSION }} From 1d3ff7b5591bc87917436eb3c644ec31023455a8 Mon Sep 17 00:00:00 2001 From: Jared Watts Date: Thu, 7 Dec 2023 09:38:27 -0800 Subject: [PATCH 04/31] add simple guidance for including results from previous functions Signed-off-by: Jared Watts --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 73d1bcf..f23239c 100644 --- a/README.md +++ b/README.md @@ -57,9 +57,14 @@ With this function you can use P&T with other functions. For example you can create a desired resource using the [Go Templating][fn-go-templating] function, then patch the result using this function. +To include results from previous functions, simply provide a `resources` entry +for each and specify a `name` field that matches the name of the resource from +the previous function. Also, do not specify any value for the `base` field of +each resource. + It's not just patches either. You can use P&T to derive composite resource connection details from a resource produced by another function, or use it to -determine whether a resource produced by another function is ready +determine whether a resource produced by another function is ready. ### Decouple P&T development from Crossplane core From 66ffa5778606d8a6f36776e82a8e1fec29f1a6c3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 18:28:09 +0000 Subject: [PATCH 05/31] chore(deps): update actions/download-artifact action to v4 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3464e91..1a7ebe0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -135,7 +135,7 @@ jobs: uses: actions/checkout@v4 - name: Download Single-Platform Packages - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: packages path: . From f0dd5847a8c317c761e9c6964f4d8685014276a7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 18:28:13 +0000 Subject: [PATCH 06/31] chore(deps): update actions/upload-artifact action to v4 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3464e91..4770f6c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -116,7 +116,7 @@ jobs: run: ./crossplane xpkg build --package-file=${{ matrix.arch }}.xpkg --package-root=package/ --embed-runtime-image-tarball=runtime-${{ matrix.arch }}.tar - name: Upload Single-Platform Package - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: packages path: "*.xpkg" From 12938673ee27db35ef43de5fc7aafcce9171f57f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 19:57:14 +0000 Subject: [PATCH 07/31] fix(deps): update kubernetes packages to v0.29.0 --- go.mod | 18 +++++++++--------- go.sum | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index f57c1ec..c6ee1b6 100644 --- a/go.mod +++ b/go.mod @@ -11,9 +11,9 @@ require ( github.com/google/go-cmp v0.6.0 github.com/pkg/errors v0.9.1 google.golang.org/protobuf v1.31.0 - k8s.io/api v0.28.4 - k8s.io/apiextensions-apiserver v0.28.4 - k8s.io/apimachinery v0.28.4 + k8s.io/api v0.29.0 + k8s.io/apiextensions-apiserver v0.29.0 + k8s.io/apimachinery v0.29.0 k8s.io/utils v0.0.0-20231127182322-b307cd553661 sigs.k8s.io/controller-tools v0.13.0 ) @@ -26,7 +26,7 @@ require ( github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/fatih/color v1.15.0 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-json-experiment/json v0.0.0-20231013223334-54c864be5b8d // indirect github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/zapr v1.2.4 // indirect @@ -76,12 +76,12 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/client-go v0.28.4 // indirect - k8s.io/component-base v0.28.4 // indirect - k8s.io/klog/v2 v2.100.1 // indirect - k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect + k8s.io/client-go v0.29.0 // indirect + k8s.io/component-base v0.29.0 // indirect + k8s.io/klog/v2 v2.110.1 // indirect + k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect sigs.k8s.io/controller-runtime v0.16.3 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index b4b52ee..55b41f3 100644 --- a/go.sum +++ b/go.sum @@ -98,6 +98,8 @@ github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -696,18 +698,32 @@ 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.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY= k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= +k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= +k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= k8s.io/apiextensions-apiserver v0.28.4 h1:AZpKY/7wQ8n+ZYDtNHbAJBb+N4AXXJvyZx6ww6yAJvU= k8s.io/apiextensions-apiserver v0.28.4/go.mod h1:pgQIZ1U8eJSMQcENew/0ShUTlePcSGFq6dxSxf2mwPM= +k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= +k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8= k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg= +k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= +k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY= k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4= +k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= +k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= k8s.io/component-base v0.28.4 h1:c/iQLWPdUgI90O+T9TeECg8o7N3YJTiuz2sKxILYcYo= k8s.io/component-base v0.28.4/go.mod h1:m9hR0uvqXDybiGL2nf/3Lf0MerAfQXzkfWhUY58JUbU= +k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s= +k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= +k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= +k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= +k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf h1:iTzha1p7Fi83476ypNSz8nV9iR9932jIIs26F7gNLsU= k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI= @@ -723,5 +739,7 @@ sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMm sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= From f9ee71f6b4f93f4aa198b0d23eb44830c54be00f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 20:04:09 +0000 Subject: [PATCH 08/31] fix(deps): update module google.golang.org/protobuf to v1.32.0 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index c6ee1b6..df9db5f 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/crossplane/function-sdk-go v0.1.0 github.com/google/go-cmp v0.6.0 github.com/pkg/errors v0.9.1 - google.golang.org/protobuf v1.31.0 + google.golang.org/protobuf v1.32.0 k8s.io/api v0.29.0 k8s.io/apiextensions-apiserver v0.29.0 k8s.io/apimachinery v0.29.0 diff --git a/go.sum b/go.sum index 55b41f3..108e21f 100644 --- a/go.sum +++ b/go.sum @@ -673,6 +673,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 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= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= From 80efd2070278d23010ab1dbb8df7cffc8ca90bec Mon Sep 17 00:00:00 2001 From: Nic Cope Date: Tue, 2 Jan 2024 12:48:07 -0800 Subject: [PATCH 09/31] Fix for v4 of the upload and download artifacts actiosn These actions require artifact names to be unique across runs. We achieve this by uploading unique names, then downloading all of them. Signed-off-by: Nic Cope --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cda538f..4cc95a6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -118,7 +118,7 @@ jobs: - name: Upload Single-Platform Package uses: actions/upload-artifact@v4 with: - name: packages + name: package-${{ matrix.arch }} path: "*.xpkg" if-no-files-found: error retention-days: 1 @@ -137,8 +137,8 @@ jobs: - name: Download Single-Platform Packages uses: actions/download-artifact@v4 with: - name: packages path: . + merge-multiple: true - name: Setup the Crossplane CLI run: "curl -sL https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh | sh" From 2b74c2a5f0c457aa22f369d0624e173be0a4e712 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 18:32:56 +0000 Subject: [PATCH 10/31] fix(deps): update k8s.io/utils digest to e7106e6 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index df9db5f..479b320 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( k8s.io/api v0.29.0 k8s.io/apiextensions-apiserver v0.29.0 k8s.io/apimachinery v0.29.0 - k8s.io/utils v0.0.0-20231127182322-b307cd553661 + k8s.io/utils v0.0.0-20240102154912-e7106e64919e sigs.k8s.io/controller-tools v0.13.0 ) diff --git a/go.sum b/go.sum index 108e21f..3328072 100644 --- a/go.sum +++ b/go.sum @@ -730,6 +730,8 @@ k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf h1:iTzha1p7Fi83476ypNSz8nV9iR993 k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI= k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= +k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From fa417410cfb754d1554de21da0962ad649f103ef Mon Sep 17 00:00:00 2001 From: Nic Cope Date: Mon, 8 Jan 2024 17:56:34 -0800 Subject: [PATCH 11/31] Always use p.GetType(), not p.Type GetType returns a default value if p.Type is empty. In upstream c/c CRD defaulting does this for us, but we can't rely on that here since our input is not a 'real' API object. Signed-off-by: Nic Cope --- patches.go | 6 +++--- render.go | 8 ++++---- validate.go | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/patches.go b/patches.go index efe1056..19fb918 100644 --- a/patches.go +++ b/patches.go @@ -246,7 +246,7 @@ func ComposedTemplates(pss []v1beta1.PatchSet, cts []v1beta1.ComposedTemplate) ( pn := make(map[string][]v1beta1.ComposedPatch) for _, s := range pss { for _, p := range s.Patches { - if p.Type == v1beta1.PatchTypePatchSet { + if p.GetType() == v1beta1.PatchTypePatchSet { return nil, errors.New(errPatchSetType) } } @@ -257,12 +257,12 @@ func ComposedTemplates(pss []v1beta1.PatchSet, cts []v1beta1.ComposedTemplate) ( for i, r := range cts { var po []v1beta1.ComposedPatch for _, p := range r.Patches { - if p.Type != v1beta1.PatchTypePatchSet { + if p.GetType() != v1beta1.PatchTypePatchSet { po = append(po, p) continue } if p.PatchSetName == nil { - return nil, errors.Errorf(errFmtRequiredField, "PatchSetName", p.Type) + return nil, errors.Errorf(errFmtRequiredField, "PatchSetName", p.GetType()) } ps, ok := pn[*p.PatchSetName] if !ok { diff --git a/render.go b/render.go index f29cab8..02de0af 100644 --- a/render.go +++ b/render.go @@ -65,14 +65,14 @@ func RenderFromJSON(o resource.Object, data []byte) error { func RenderEnvironmentPatches(env *unstructured.Unstructured, oxr, dxr *composite.Unstructured, ps []v1beta1.EnvironmentPatch) error { for i, p := range ps { p := p - switch p.Type { + switch p.GetType() { case v1beta1.PatchTypeToEnvironmentFieldPath, v1beta1.PatchTypeCombineToEnvironment: if err := ApplyToObjects(&p, env, oxr); err != nil { - return errors.Wrapf(err, errFmtPatch, p.Type, i) + return errors.Wrapf(err, errFmtPatch, p.GetType(), i) } case v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeCombineFromEnvironment: if err := ApplyToObjects(&p, env, dxr); err != nil { - return errors.Wrapf(err, errFmtPatch, p.Type, i) + return errors.Wrapf(err, errFmtPatch, p.GetType(), i) } case v1beta1.PatchTypePatchSet, v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeCombineFromComposite, v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeCombineToComposite: // nothing to do @@ -95,7 +95,7 @@ func RenderComposedPatches( //nolint:gocyclo // just a switch ) (errs []error, store bool) { for i, p := range ps { p := p - switch t := p.Type; t { + switch t := p.GetType(); t { case v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeCombineToComposite: // TODO(negz): Should failures to patch the XR be terminal? It could // indicate a required patch failed. A required patch means roughly diff --git a/validate.go b/validate.go index ff006e9..ef45874 100644 --- a/validate.go +++ b/validate.go @@ -104,7 +104,7 @@ func ValidateEnvironment(e *v1beta1.Environment) *field.Error { v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeToEnvironmentFieldPath: default: - return field.Invalid(field.NewPath("patches").Index(i).Key("type"), p.Type, "invalid environment patch type") + return field.Invalid(field.NewPath("patches").Index(i).Key("type"), p.GetType(), "invalid environment patch type") } if err := ValidatePatch(&p); err != nil { From 06869e54798bca45fe841dd0ba8399f896ee766d Mon Sep 17 00:00:00 2001 From: Maximilian Blatt Date: Wed, 10 Jan 2024 18:01:33 +0100 Subject: [PATCH 12/31] fix(environment): Validate against correct patch types Using the correct patch types requires changing the order in which xr and env are passed to ApplyToObjects to the "correct" order (xr, env) instead of (env, xr). Here env takes over the role of the composed resource just like in `Apply`. Signed-off-by: Maximilian Blatt --- fn_test.go | 22 ++++++++++------------ render.go | 10 +++++----- validate.go | 11 ++++++----- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/fn_test.go b/fn_test.go index 7462518..9ed508e 100644 --- a/fn_test.go +++ b/fn_test.go @@ -658,9 +658,9 @@ func TestRunFunction(t *testing.T) { Environment: &v1beta1.Environment{ Patches: []v1beta1.EnvironmentPatch{ { - Type: v1beta1.PatchTypeFromEnvironmentFieldPath, + Type: v1beta1.PatchTypeToCompositeFieldPath, Patch: v1beta1.Patch{ - FromFieldPath: ptr.To[string]("data.widgets"), + FromFieldPath: ptr.To[string]("widgets"), ToFieldPath: ptr.To[string]("spec.watchers"), Transforms: []v1beta1.Transform{ { @@ -713,10 +713,10 @@ func TestRunFunction(t *testing.T) { Environment: &v1beta1.Environment{ Patches: []v1beta1.EnvironmentPatch{ { - Type: v1beta1.PatchTypeToEnvironmentFieldPath, + Type: v1beta1.PatchTypeFromCompositeFieldPath, Patch: v1beta1.Patch{ FromFieldPath: ptr.To[string]("spec.watchers"), - ToFieldPath: ptr.To[string]("data.widgets"), + ToFieldPath: ptr.To[string]("widgets"), Transforms: []v1beta1.Transform{ { Type: v1beta1.TransformTypeMath, @@ -764,7 +764,7 @@ func TestRunFunction(t *testing.T) { Patches: []v1beta1.ComposedPatch{{ Type: v1beta1.PatchTypeFromEnvironmentFieldPath, Patch: v1beta1.Patch{ - FromFieldPath: ptr.To[string]("data.widgets"), + FromFieldPath: ptr.To[string]("widgets"), ToFieldPath: ptr.To[string]("spec.watchers"), Transforms: []v1beta1.Transform{{ Type: v1beta1.TransformTypeConvert, @@ -816,7 +816,7 @@ func TestRunFunction(t *testing.T) { Patches: []v1beta1.ComposedPatch{{ Type: v1beta1.PatchTypeFromEnvironmentFieldPath, Patch: v1beta1.Patch{ - FromFieldPath: ptr.To[string]("data.widgets"), + FromFieldPath: ptr.To[string]("widgets"), ToFieldPath: ptr.To[string]("spec.watchers"), Transforms: []v1beta1.Transform{{ Type: v1beta1.TransformTypeConvert, @@ -872,7 +872,7 @@ func TestRunFunction(t *testing.T) { Patches: []v1beta1.ComposedPatch{{ Type: v1beta1.PatchTypeFromEnvironmentFieldPath, Patch: v1beta1.Patch{ - FromFieldPath: ptr.To[string]("data.widgets"), + FromFieldPath: ptr.To[string]("widgets"), ToFieldPath: ptr.To[string]("spec.watchers"), Transforms: []v1beta1.Transform{{ Type: v1beta1.TransformTypeConvert, @@ -937,18 +937,16 @@ func TestRunFunction(t *testing.T) { } // Crossplane sends as context a fake resource: -// { "apiVersion": "internal.crossplane.io/v1alpha1", "kind": "Environment", "data": {... the actual environment content ...} } +// { "apiVersion": "internal.crossplane.io/v1alpha1", "kind": "Environment", ... the actual environment content ... } // See: https://github.com/crossplane/crossplane/blob/806f0d20d146f6f4f1735c5ec6a7dc78923814b3/internal/controller/apiextensions/composite/environment_fetcher.go#L85C1-L85C1 // That's because the patching code expects a resource to be able to use // runtime.DefaultUnstructuredConverter.FromUnstructured to convert it back to -// an object. This is also why all patches need to specify the full path from data. +// an object. func contextWithEnvironment(data map[string]interface{}) *structpb.Struct { if data == nil { data = map[string]interface{}{} } - u := unstructured.Unstructured{Object: map[string]interface{}{ - "data": data, - }} + u := unstructured.Unstructured{Object: data} u.SetGroupVersionKind(schema.GroupVersionKind{Group: "internal.crossplane.io", Version: "v1alpha1", Kind: "Environment"}) d, err := structpb.NewStruct(u.UnstructuredContent()) if err != nil { diff --git a/render.go b/render.go index 02de0af..e3e5aec 100644 --- a/render.go +++ b/render.go @@ -66,15 +66,15 @@ func RenderEnvironmentPatches(env *unstructured.Unstructured, oxr, dxr *composit for i, p := range ps { p := p switch p.GetType() { - case v1beta1.PatchTypeToEnvironmentFieldPath, v1beta1.PatchTypeCombineToEnvironment: - if err := ApplyToObjects(&p, env, oxr); err != nil { + case v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeCombineFromComposite: + if err := ApplyToObjects(&p, oxr, env); err != nil { return errors.Wrapf(err, errFmtPatch, p.GetType(), i) } - case v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeCombineFromEnvironment: - if err := ApplyToObjects(&p, env, dxr); err != nil { + case v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeCombineToComposite: + if err := ApplyToObjects(&p, dxr, env); err != nil { return errors.Wrapf(err, errFmtPatch, p.GetType(), i) } - case v1beta1.PatchTypePatchSet, v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeCombineFromComposite, v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeCombineToComposite: + case v1beta1.PatchTypePatchSet, v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeCombineFromEnvironment, v1beta1.PatchTypeToEnvironmentFieldPath, v1beta1.PatchTypeCombineToEnvironment: // nothing to do } } diff --git a/validate.go b/validate.go index ef45874..5d87f07 100644 --- a/validate.go +++ b/validate.go @@ -98,11 +98,12 @@ func ValidateEnvironment(e *v1beta1.Environment) *field.Error { } for i, p := range e.Patches { p := p - switch p.GetType() { //nolint:exhaustive // Intentionally targeting only environment patches. - case v1beta1.PatchTypeCombineToEnvironment, - v1beta1.PatchTypeCombineFromEnvironment, - v1beta1.PatchTypeFromEnvironmentFieldPath, - v1beta1.PatchTypeToEnvironmentFieldPath: + switch p.GetType() { //nolint:exhaustive // Only target valid patches according the API spec + case + v1beta1.PatchTypeFromCompositeFieldPath, + v1beta1.PatchTypeToCompositeFieldPath, + v1beta1.PatchTypeCombineFromComposite, + v1beta1.PatchTypeCombineToComposite: default: return field.Invalid(field.NewPath("patches").Index(i).Key("type"), p.GetType(), "invalid environment patch type") } From bc836a457a9e76c8b595ecc6e75f58b36ed1279e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 19:44:57 +0000 Subject: [PATCH 13/31] fix(deps): update module sigs.k8s.io/controller-tools to v0.14.0 --- go.mod | 20 ++++++++++---------- go.sum | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 479b320..f698189 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( k8s.io/apiextensions-apiserver v0.29.0 k8s.io/apimachinery v0.29.0 k8s.io/utils v0.0.0-20240102154912-e7106e64919e - sigs.k8s.io/controller-tools v0.13.0 + sigs.k8s.io/controller-tools v0.14.0 ) require ( @@ -25,7 +25,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect - github.com/fatih/color v1.15.0 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-json-experiment/json v0.0.0-20231013223334-54c864be5b8d // indirect github.com/go-logr/logr v1.3.0 // indirect @@ -45,7 +45,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -55,20 +55,20 @@ require ( github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect github.com/spf13/afero v1.10.0 // indirect - github.com/spf13/cobra v1.7.0 // indirect + github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/testify v1.8.4 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect - golang.org/x/mod v0.13.0 // indirect - golang.org/x/net v0.17.0 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.19.0 // indirect golang.org/x/oauth2 v0.11.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/term v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/term v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.14.0 // indirect + golang.org/x/tools v0.16.1 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect diff --git a/go.sum b/go.sum index 3328072..8326e4a 100644 --- a/go.sum +++ b/go.sum @@ -68,6 +68,7 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/crossplane/crossplane-runtime v1.14.2 h1:pV5JMzyzi/kcbeVBVPCat5MHH8zS94MBUapAyGx/Ry0= github.com/crossplane/crossplane-runtime v1.14.2/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o= @@ -96,6 +97,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.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= @@ -256,6 +258,7 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= @@ -306,6 +309,7 @@ github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -400,6 +404,7 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -435,6 +440,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= 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= @@ -498,11 +505,16 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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= @@ -513,6 +525,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -570,6 +584,7 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= 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= @@ -739,6 +754,7 @@ sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigw sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= sigs.k8s.io/controller-tools v0.13.0 h1:NfrvuZ4bxyolhDBt/rCZhDnx3M2hzlhgo5n3Iv2RykI= sigs.k8s.io/controller-tools v0.13.0/go.mod h1:5vw3En2NazbejQGCeWKRrE7q4P+CW8/klfVqP8QZkgA= +sigs.k8s.io/controller-tools v0.14.0/go.mod h1:TV7uOtNNnnR72SpzhStvPkoS/U5ir0nMudrkrC4M9Sc= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= From 0d640e065d15c9082b5263e15465e6fa68747eea Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 01:45:35 +0000 Subject: [PATCH 14/31] fix(deps): update kubernetes packages to v0.29.1 --- go.mod | 10 +++++----- go.sum | 10 ++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index f698189..aa136fc 100644 --- a/go.mod +++ b/go.mod @@ -11,9 +11,9 @@ require ( github.com/google/go-cmp v0.6.0 github.com/pkg/errors v0.9.1 google.golang.org/protobuf v1.32.0 - k8s.io/api v0.29.0 - k8s.io/apiextensions-apiserver v0.29.0 - k8s.io/apimachinery v0.29.0 + k8s.io/api v0.29.1 + k8s.io/apiextensions-apiserver v0.29.1 + k8s.io/apimachinery v0.29.1 k8s.io/utils v0.0.0-20240102154912-e7106e64919e sigs.k8s.io/controller-tools v0.14.0 ) @@ -76,8 +76,8 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/client-go v0.29.0 // indirect - k8s.io/component-base v0.29.0 // indirect + k8s.io/client-go v0.29.1 // indirect + k8s.io/component-base v0.29.1 // indirect k8s.io/klog/v2 v2.110.1 // indirect k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect sigs.k8s.io/controller-runtime v0.16.3 // indirect diff --git a/go.sum b/go.sum index 8326e4a..a5332f7 100644 --- a/go.sum +++ b/go.sum @@ -717,22 +717,32 @@ k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY= k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= +k8s.io/api v0.29.1 h1:DAjwWX/9YT7NQD4INu49ROJuZAAAP/Ijki48GUPzxqw= +k8s.io/api v0.29.1/go.mod h1:7Kl10vBRUXhnQQI8YR/R327zXC8eJ7887/+Ybta+RoQ= k8s.io/apiextensions-apiserver v0.28.4 h1:AZpKY/7wQ8n+ZYDtNHbAJBb+N4AXXJvyZx6ww6yAJvU= k8s.io/apiextensions-apiserver v0.28.4/go.mod h1:pgQIZ1U8eJSMQcENew/0ShUTlePcSGFq6dxSxf2mwPM= k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= +k8s.io/apiextensions-apiserver v0.29.1 h1:S9xOtyk9M3Sk1tIpQMu9wXHm5O2MX6Y1kIpPMimZBZw= +k8s.io/apiextensions-apiserver v0.29.1/go.mod h1:zZECpujY5yTW58co8V2EQR4BD6A9pktVgHhvc0uLfeU= k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8= k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg= k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= +k8s.io/apimachinery v0.29.1 h1:KY4/E6km/wLBguvCZv8cKTeOwwOBqFNjwJIdMkMbbRc= +k8s.io/apimachinery v0.29.1/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY= k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4= k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= +k8s.io/client-go v0.29.1 h1:19B/+2NGEwnFLzt0uB5kNJnfTsbV8w6TgQRz9l7ti7A= +k8s.io/client-go v0.29.1/go.mod h1:TDG/psL9hdet0TI9mGyHJSgRkW3H9JZk2dNEUS7bRks= k8s.io/component-base v0.28.4 h1:c/iQLWPdUgI90O+T9TeECg8o7N3YJTiuz2sKxILYcYo= k8s.io/component-base v0.28.4/go.mod h1:m9hR0uvqXDybiGL2nf/3Lf0MerAfQXzkfWhUY58JUbU= k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s= k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M= +k8s.io/component-base v0.29.1 h1:MUimqJPCRnnHsskTTjKD+IC1EHBbRCVyi37IoFBrkYw= +k8s.io/component-base v0.29.1/go.mod h1:fP9GFjxYrLERq1GcWWZAE3bqbNcDKDytn2srWuHTtKc= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= From 27b41e8eb9928d45b13fa4baa104a454a85ea4a8 Mon Sep 17 00:00:00 2001 From: Nic Cope Date: Thu, 18 Jan 2024 17:34:05 -0800 Subject: [PATCH 15/31] Treat all errors encountered while patching as fatal This will stop the reconcile. No further patches, resources, or functions will be processed. This commit breaks required field paths, in that we'll return a fatal result if a required field path is missing. This means a set of patches that could have been eventually consistent now cannot. I intend to address that in a following commit. Signed-off-by: Nic Cope --- fn.go | 14 +++++--------- fn_test.go | 17 ++++------------- render.go | 21 ++++++--------------- 3 files changed, 15 insertions(+), 37 deletions(-) diff --git a/fn.go b/fn.go index 81727e2..ad4e592 100644 --- a/fn.go +++ b/fn.go @@ -192,17 +192,13 @@ func (f *Function) RunFunction(ctx context.Context, req *fnv1beta1.RunFunctionRe "name", ocd.Resource.GetName()) } - errs, store := RenderComposedPatches(ocd.Resource, dcd.Resource, oxr.Resource, dxr.Resource, env, t.Patches) - for _, err := range errs { - response.Warning(rsp, errors.Wrapf(err, "cannot render patches for composed resource %q", t.Name)) - log.Info("Cannot render patches for composed resource", "warning", err) - warnings++ + // TODO(negz): No need for multiple errors? + if err := RenderComposedPatches(ocd.Resource, dcd.Resource, oxr.Resource, dxr.Resource, env, t.Patches); err != nil { + response.Fatal(rsp, errors.Wrapf(err, "cannot render patches for composed resource %q", t.Name)) + return rsp, nil } - if store { - // Add or replace our desired resource. - desired[resource.Name(t.Name)] = dcd - } + desired[resource.Name(t.Name)] = dcd } if err := response.SetDesiredCompositeResource(rsp, dxr); err != nil { diff --git a/fn_test.go b/fn_test.go index 9ed508e..02154d8 100644 --- a/fn_test.go +++ b/fn_test.go @@ -406,18 +406,10 @@ func TestRunFunction(t *testing.T) { }, { // This patch should return an error, - // because the required path does not - // exist. + // because the path is not an array. Type: v1beta1.PatchTypeFromCompositeFieldPath, Patch: v1beta1.Patch{ - FromFieldPath: ptr.To[string]("spec.doesNotExist"), - ToFieldPath: ptr.To[string]("spec.explode"), - Policy: &v1beta1.PatchPolicy{ - FromFieldPath: func() *v1beta1.FromFieldPathPolicy { - r := v1beta1.FromFieldPathPolicyRequired - return &r - }(), - }, + FromFieldPath: ptr.To[string]("spec.widgets[0]"), }, }, }, @@ -458,11 +450,10 @@ func TestRunFunction(t *testing.T) { }, Results: []*fnv1beta1.Result{ { - Severity: fnv1beta1.Severity_SEVERITY_WARNING, - Message: fmt.Sprintf("cannot render patches for composed resource %q: cannot apply the %q patch at index 1: spec.doesNotExist: no such field", "cool-resource", "FromCompositeFieldPath"), + Severity: fnv1beta1.Severity_SEVERITY_FATAL, + Message: fmt.Sprintf("cannot render patches for composed resource %q: cannot apply the %q patch at index 1: spec.widgets: not an array", "cool-resource", "FromCompositeFieldPath"), }, }, - Context: &structpb.Struct{Fields: map[string]*structpb.Value{fncontext.KeyEnvironment: structpb.NewStructValue(nil)}}, }, }, }, diff --git a/render.go b/render.go index e3e5aec..fc2ff67 100644 --- a/render.go +++ b/render.go @@ -85,14 +85,7 @@ func RenderEnvironmentPatches(env *unstructured.Unstructured, oxr, dxr *composit // patches that are to or from the supplied composite resource and environment // in the order they were defined. Properly selecting the right source or // destination between observed and desired resources. -func RenderComposedPatches( //nolint:gocyclo // just a switch - ocd *composed.Unstructured, - dcd *composed.Unstructured, - oxr *composite.Unstructured, - dxr *composite.Unstructured, - env *unstructured.Unstructured, - ps []v1beta1.ComposedPatch, -) (errs []error, store bool) { +func RenderComposedPatches(ocd, dcd *composed.Unstructured, oxr, dxr *composite.Unstructured, env *unstructured.Unstructured, ps []v1beta1.ComposedPatch) error { //nolint:gocyclo // just a switch for i, p := range ps { p := p switch t := p.GetType(); t { @@ -112,7 +105,7 @@ func RenderComposedPatches( //nolint:gocyclo // just a switch continue } if err := ApplyToObjects(&p, dxr, ocd); err != nil { - errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i)) + return errors.Wrapf(err, errFmtPatch, t, i) } case v1beta1.PatchTypeToEnvironmentFieldPath, v1beta1.PatchTypeCombineToEnvironment: // TODO(negz): Same as above, but for the Environment. What does it @@ -125,7 +118,7 @@ func RenderComposedPatches( //nolint:gocyclo // just a switch continue } if err := ApplyToObjects(&p, env, ocd); err != nil { - errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i)) + return errors.Wrapf(err, errFmtPatch, t, i) } // If either of the below renderings return an error, most likely a // required FromComposite or FromEnvironment patch failed. A required @@ -135,17 +128,15 @@ func RenderComposedPatches( //nolint:gocyclo // just a switch // resource to our accumulated desired state. case v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeCombineFromComposite: if err := ApplyToObjects(&p, oxr, dcd); err != nil { - errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i)) - return errs, false + return errors.Wrapf(err, errFmtPatch, t, i) } case v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeCombineFromEnvironment: if err := ApplyToObjects(&p, env, dcd); err != nil { - errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i)) - return errs, false + return errors.Wrapf(err, errFmtPatch, t, i) } case v1beta1.PatchTypePatchSet: // Already resolved - nothing to do. } } - return errs, true + return nil } From 6bae35a1659adc959dca005c73042006e7c336b0 Mon Sep 17 00:00:00 2001 From: Nic Cope Date: Fri, 19 Jan 2024 20:31:20 -0800 Subject: [PATCH 16/31] Don't delete resources when required field paths don't exist If we hit a composition error that is likely due to a misconfigured composition we just return a fatal error. Previously we'd skip the affected composed resource, which could result in it being deleted if it already existed. We'll now only skip rendering a composed resource if a required field path is not present _and_ the composed resource doesn't exist yet. Signed-off-by: Nic Cope --- fn.go | 68 ++- fn_test.go | 4 +- input/v1beta1/resources_patches.go | 4 +- patches.go | 204 +++---- patches_test.go | 837 +++++++---------------------- render.go | 95 +--- validate.go | 27 + validate_test.go | 125 +++++ 8 files changed, 513 insertions(+), 851 deletions(-) diff --git a/fn.go b/fn.go index ad4e592..0be03e2 100644 --- a/fn.go +++ b/fn.go @@ -7,6 +7,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "github.com/crossplane/crossplane-runtime/pkg/errors" + "github.com/crossplane/crossplane-runtime/pkg/fieldpath" "github.com/crossplane/crossplane-runtime/pkg/logging" "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" @@ -114,10 +115,14 @@ func (f *Function) RunFunction(ctx context.Context, req *fnv1beta1.RunFunctionRe } if input.Environment != nil { - // Run all patches that are from the (observed) XR to the environment or from the environment to the (desired) XR. - if err := RenderEnvironmentPatches(env, oxr.Resource, dxr.Resource, input.Environment.Patches); err != nil { - response.Fatal(rsp, errors.Wrapf(err, "cannot render ToEnvironment patches from the composite resource")) - return rsp, nil + // Run all patches that are from the (observed) XR to the environment or + // from the environment to the (desired) XR. + for i := range input.Environment.Patches { + p := &input.Environment.Patches[i] + if err := ApplyEnvironmentPatch(p, env, oxr.Resource, dxr.Resource); err != nil { + response.Fatal(rsp, errors.Wrapf(err, "cannot apply the %q environment patch at index %d", p.GetType(), i)) + return rsp, nil + } } } @@ -155,8 +160,8 @@ func (f *Function) RunFunction(ctx context.Context, req *fnv1beta1.RunFunctionRe } } - ocd, ok := observed[resource.Name(t.Name)] - if ok { + ocd, exists := observed[resource.Name(t.Name)] + if exists { existing++ log.Debug("Resource template corresponds to existing composed resource", "metadata-name", ocd.Resource.GetName()) @@ -192,10 +197,53 @@ func (f *Function) RunFunction(ctx context.Context, req *fnv1beta1.RunFunctionRe "name", ocd.Resource.GetName()) } - // TODO(negz): No need for multiple errors? - if err := RenderComposedPatches(ocd.Resource, dcd.Resource, oxr.Resource, dxr.Resource, env, t.Patches); err != nil { - response.Fatal(rsp, errors.Wrapf(err, "cannot render patches for composed resource %q", t.Name)) - return rsp, nil + // Run all patches that are to a desired composed resource, or from an + // observed composed resource. + skip := false + for i := range t.Patches { + p := &t.Patches[i] + if err := ApplyComposedPatch(p, ocd.Resource, dcd.Resource, oxr.Resource, dxr.Resource, env); err != nil { + if fieldpath.IsNotFound(err) { + // This is a patch from a required field path that does not + // exist. The point of FromFieldPathPolicyRequired is to + // block creation of the new 'to' resource until the 'from' + // field path exists. + // + // The only kind of resource we could be patching to that + // might not exist at this point is a composed resource. So + // if we're patching to a composed resource that doesn't + // exist we want to avoid creating it. Otherwise, we just + // treat the patch from a required field path the same way + // we'd treat a patch from an optional field path and skip + // it. + if p.GetPolicy().GetFromFieldPathPolicy() == v1beta1.FromFieldPathPolicyRequired { + if ToComposedResource(p) && !exists { + response.Warning(rsp, errors.Wrapf(err, "not adding new composed resource %q to desired state because %q patch at index %d has 'policy.fromFieldPath: Required'", t.Name, p.GetType(), i)) + + // There's no point processing further patches. + // They'll either be from an observed composed + // resource that doesn't exist yet, or to a desired + // composed resource that we'll discard. + skip = true + break + } + response.Warning(rsp, errors.Wrapf(err, "cannot render composed resource %q %q patch at index %d: ignoring 'policy.fromFieldPath: Required' because 'to' resource already exists", t.Name, p.GetType(), i)) + } + + // If any optional field path isn't found we just skip this + // patch and move on. The path may be populated by a + // subsequent patch. + continue + } + response.Fatal(rsp, errors.Wrapf(err, "cannot render composed resource %q %q patch at index %d", t.Name, p.GetType(), i)) + return rsp, nil + } + } + + // Skip adding this resource to the desired state because it doesn't + // exist yet, and a required FromFieldPath was not (yet) found. + if skip { + continue } desired[resource.Name(t.Name)] = dcd diff --git a/fn_test.go b/fn_test.go index 02154d8..15e85f8 100644 --- a/fn_test.go +++ b/fn_test.go @@ -385,7 +385,7 @@ func TestRunFunction(t *testing.T) { }, }, "FailedPatchNotSaved": { - reason: "If we fail to patch a desired resource produced by a previous Function in the pipeline we should return a warning result, and leave the original desired resource untouched.", + reason: "If we fail to patch a desired resource produced by a previous Function in the pipeline we should return a fatal result.", args: args{ req: &fnv1beta1.RunFunctionRequest{ Input: resource.MustStructObject(&v1beta1.Resources{ @@ -451,7 +451,7 @@ func TestRunFunction(t *testing.T) { Results: []*fnv1beta1.Result{ { Severity: fnv1beta1.Severity_SEVERITY_FATAL, - Message: fmt.Sprintf("cannot render patches for composed resource %q: cannot apply the %q patch at index 1: spec.widgets: not an array", "cool-resource", "FromCompositeFieldPath"), + Message: fmt.Sprintf("cannot render composed resource %q %q patch at index 1: spec.widgets: not an array", "cool-resource", "FromCompositeFieldPath"), }, }, }, diff --git a/input/v1beta1/resources_patches.go b/input/v1beta1/resources_patches.go index 9478a79..65d338d 100644 --- a/input/v1beta1/resources_patches.go +++ b/input/v1beta1/resources_patches.go @@ -36,8 +36,8 @@ const ( type PatchPolicy struct { // FromFieldPath specifies how to patch from a field path. The default is // 'Optional', which means the patch will be a no-op if the specified - // fromFieldPath does not exist. Use 'Required' if the patch should fail if - // the specified path does not exist. + // fromFieldPath does not exist. Use 'Required' to prevent the creation of a + // new composed resource until the required path exists. // +kubebuilder:validation:Enum=Optional;Required // +optional FromFieldPath *FromFieldPathPolicy `json:"fromFieldPath,omitempty"` diff --git a/patches.go b/patches.go index 19fb918..7cdce55 100644 --- a/patches.go +++ b/patches.go @@ -5,17 +5,19 @@ import ( "strings" "github.com/pkg/errors" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "github.com/crossplane/crossplane-runtime/pkg/fieldpath" - "github.com/crossplane/crossplane-runtime/pkg/resource" + + "github.com/crossplane/function-sdk-go/resource/composed" + "github.com/crossplane/function-sdk-go/resource/composite" "github.com/crossplane-contrib/function-patch-and-transform/input/v1beta1" ) const ( - errPatchSetType = "a patch in a PatchSet cannot be of type PatchSet" - errCombineRequiresVariables = "combine patch types require at least one variable" + errPatchSetType = "a patch in a PatchSet cannot be of type PatchSet" errFmtUndefinedPatchSet = "cannot find PatchSet by name %s" errFmtInvalidPatchType = "patch type %s is unsupported" @@ -41,50 +43,6 @@ type PatchWithPatchSetName interface { GetPatchSetName() string } -// Apply executes a patching operation between the from and to resources. -// Applies all patch types unless an 'only' filter is supplied. -func Apply(p PatchInterface, xr resource.Composite, cd resource.Composed, only ...v1beta1.PatchType) error { - return ApplyToObjects(p, xr, cd, only...) -} - -// ApplyToObjects works like Apply but accepts any kind of runtime.Object. It -// might be vulnerable to conversion panics (see -// https://github.com/crossplane/crossplane/pull/3394 for details). -func ApplyToObjects(p PatchInterface, a, b runtime.Object, only ...v1beta1.PatchType) error { - if filterPatch(p, only...) { - return nil - } - - switch p.GetType() { - case v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeFromEnvironmentFieldPath: - return ApplyFromFieldPathPatch(p, a, b) - case v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeToEnvironmentFieldPath: - return ApplyFromFieldPathPatch(p, b, a) - case v1beta1.PatchTypeCombineFromComposite, v1beta1.PatchTypeCombineFromEnvironment: - return ApplyCombineFromVariablesPatch(p, a, b) - case v1beta1.PatchTypeCombineToComposite, v1beta1.PatchTypeCombineToEnvironment: - return ApplyCombineFromVariablesPatch(p, b, a) - case v1beta1.PatchTypePatchSet: - // Already resolved - nothing to do. - } - return errors.Errorf(errFmtInvalidPatchType, p.GetType()) -} - -// filterPatch returns true if patch should be filtered (not applied) -func filterPatch(p PatchInterface, only ...v1beta1.PatchType) bool { - // filter does not apply if not set - if len(only) == 0 { - return false - } - - for _, patchType := range only { - if patchType == p.GetType() { - return false - } - } - return true -} - // ResolveTransforms applies a list of transforms to a patch value. func ResolveTransforms(ts []v1beta1.Transform, input any) (any, error) { var err error @@ -101,19 +59,12 @@ func ResolveTransforms(ts []v1beta1.Transform, input any) (any, error) { // on the "from" resource. Values may be transformed if any are defined on // the patch. func ApplyFromFieldPathPatch(p PatchInterface, from, to runtime.Object) error { - if p.GetFromFieldPath() == "" { - return errors.Errorf(errFmtRequiredField, "FromFieldPath", p.GetType()) - } - fromMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(from) if err != nil { return err } in, err := fieldpath.Pave(fromMap).GetValue(p.GetFromFieldPath()) - if IsOptionalFieldPathNotFound(err, p.GetPolicy()) { - return nil - } if err != nil { return err } @@ -133,39 +84,23 @@ func ApplyFromFieldPathPatch(p PatchInterface, from, to runtime.Object) error { } // ApplyCombineFromVariablesPatch patches the "to" resource, taking a list of -// input variables and combining them into a single output value. -// The single output value may then be further transformed if they are defined -// on the patch. +// input variables and combining them into a single output value. The single +// output value may then be further transformed if they are defined on the +// patch. func ApplyCombineFromVariablesPatch(p PatchInterface, from, to runtime.Object) error { - // Combine patch requires configuration - if p.GetCombine() == nil { - return errors.Errorf(errFmtRequiredField, "Combine", p.GetType()) - } - // Destination field path is required since we can't default to multiple - // fields. - if p.GetToFieldPath() == "" { - return errors.Errorf(errFmtRequiredField, "ToFieldPath", p.GetType()) - } - - combine := p.GetCombine() - vl := len(combine.Variables) - - if vl < 1 { - return errors.New(errCombineRequiresVariables) - } - fromMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(from) if err != nil { return err } - in := make([]any, vl) + c := p.GetCombine() + in := make([]any, len(c.Variables)) // Get value of each variable // NOTE: This currently assumes all variables define a 'fromFieldPath' // value. If we add new variable types, this may not be the case and // this code may be better served split out into a dedicated function. - for i, sp := range combine.Variables { + for i, sp := range c.Variables { iv, err := fieldpath.Pave(fromMap).GetValue(sp.FromFieldPath) // If any source field is not found, we will not @@ -174,9 +109,6 @@ func ApplyCombineFromVariablesPatch(p PatchInterface, from, to runtime.Object) e // number of inputs (e.g. a string format // expecting 3 fields '%s-%s-%s' but only // receiving 2 values). - if IsOptionalFieldPathNotFound(err, p.GetPolicy()) { - return nil - } if err != nil { return err } @@ -184,7 +116,7 @@ func ApplyCombineFromVariablesPatch(p PatchInterface, from, to runtime.Object) e } // Combine input values - cb, err := Combine(*p.GetCombine(), in) + cb, err := Combine(*c, in) if err != nil { return err } @@ -198,20 +130,108 @@ func ApplyCombineFromVariablesPatch(p PatchInterface, from, to runtime.Object) e return errors.Wrap(patchFieldValueToObject(p.GetToFieldPath(), out, to), "cannot patch to object") } -// IsOptionalFieldPathNotFound returns true if the supplied error indicates a -// field path was not found, and the supplied policy indicates a patch from that -// field path was optional. -func IsOptionalFieldPathNotFound(err error, p *v1beta1.PatchPolicy) bool { - switch { - case p == nil: - fallthrough - case p.FromFieldPath == nil: - fallthrough - case *p.FromFieldPath == v1beta1.FromFieldPathPolicyOptional: - return fieldpath.IsNotFound(err) - default: +// ApplyEnvironmentPatch applies a patch to or from the environment. Patches to +// the environment are always from the observed XR. Patches from the environment +// are always to the desired XR. +func ApplyEnvironmentPatch(p *v1beta1.EnvironmentPatch, env *unstructured.Unstructured, oxr, dxr *composite.Unstructured) error { + switch p.GetType() { + // From observed XR to environment. + case v1beta1.PatchTypeFromCompositeFieldPath: + return ApplyFromFieldPathPatch(p, oxr, env) + case v1beta1.PatchTypeCombineFromComposite: + return ApplyCombineFromVariablesPatch(p, oxr, env) + + // From environment to desired XR. + case v1beta1.PatchTypeToCompositeFieldPath: + return ApplyFromFieldPathPatch(p, env, dxr) + case v1beta1.PatchTypeCombineToComposite: + return ApplyCombineFromVariablesPatch(p, env, dxr) + + // Invalid patch types in this context. + case v1beta1.PatchTypeFromEnvironmentFieldPath, + v1beta1.PatchTypeCombineFromEnvironment, + v1beta1.PatchTypeToEnvironmentFieldPath, + v1beta1.PatchTypeCombineToEnvironment: + // Nothing to do. + + case v1beta1.PatchTypePatchSet: + // Already resolved - nothing to do. + } + return nil +} + +// ApplyComposedPatch applies a patch to or from a composed resource. Patches +// from an observed composed resource can be to the desired XR, or to the +// environment. Patches to a desired composed resource can be from the observed +// XR, or from the environment. +func ApplyComposedPatch(p *v1beta1.ComposedPatch, ocd, dcd *composed.Unstructured, oxr, dxr *composite.Unstructured, env *unstructured.Unstructured) error { //nolint:gocyclo // Just a long switch. + // Don't return an error if we're patching from a composed resource that + // doesn't exist yet. We'll try patch from it once it's been created. + if ocd == nil && !ToComposedResource(p) { + return nil + } + + // We always patch from observed state to desired state. This is because + // folks will often want to patch from status fields, which only appear in + // observed state. Observed state should also eventually be consistent with + // desired state. + switch t := p.GetType(); t { + + // From observed composed resource to desired XR. + case v1beta1.PatchTypeToCompositeFieldPath: + return ApplyFromFieldPathPatch(p, ocd, dxr) + case v1beta1.PatchTypeCombineToComposite: + return ApplyCombineFromVariablesPatch(p, ocd, dxr) + + // From observed composed resource to environment. + case v1beta1.PatchTypeToEnvironmentFieldPath: + return ApplyFromFieldPathPatch(p, ocd, env) + case v1beta1.PatchTypeCombineToEnvironment: + return ApplyCombineFromVariablesPatch(p, ocd, env) + + // From observed XR to desired composed resource. + case v1beta1.PatchTypeFromCompositeFieldPath: + return ApplyFromFieldPathPatch(p, oxr, dcd) + case v1beta1.PatchTypeCombineFromComposite: + return ApplyCombineFromVariablesPatch(p, oxr, dcd) + + // From environment to desired composed resource. + case v1beta1.PatchTypeFromEnvironmentFieldPath: + return ApplyFromFieldPathPatch(p, env, dcd) + case v1beta1.PatchTypeCombineFromEnvironment: + return ApplyCombineFromVariablesPatch(p, env, dcd) + + case v1beta1.PatchTypePatchSet: + // Already resolved - nothing to do. + } + + return nil +} + +// ToComposedResource returns true if the supplied patch is to a composed +// resource, not from it. +func ToComposedResource(p *v1beta1.ComposedPatch) bool { + switch p.GetType() { + + // From observed XR to desired composed resource. + case v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeCombineFromComposite: + return true + // From environment to desired composed resource. + case v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeCombineFromEnvironment: + return true + + // From composed resource to composite. + case v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeCombineToComposite: + return false + // From composed resource to environment. + case v1beta1.PatchTypeToEnvironmentFieldPath, v1beta1.PatchTypeCombineToEnvironment: + return false + // We can ignore patchsets; they're inlined. + case v1beta1.PatchTypePatchSet: return false } + + return false } // Combine calls the appropriate combiner. diff --git a/patches_test.go b/patches_test.go index a98f158..bc26cbe 100644 --- a/patches_test.go +++ b/patches_test.go @@ -8,34 +8,27 @@ import ( "github.com/pkg/errors" extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/utils/ptr" "github.com/crossplane/crossplane-runtime/pkg/fieldpath" - "github.com/crossplane/crossplane-runtime/pkg/resource" - "github.com/crossplane/crossplane-runtime/pkg/resource/unstructured/composed" "github.com/crossplane/crossplane-runtime/pkg/test" + "github.com/crossplane/function-sdk-go/resource/composed" "github.com/crossplane/function-sdk-go/resource/composite" "github.com/crossplane-contrib/function-patch-and-transform/input/v1beta1" ) -func TestPatchApply(t *testing.T) { - errNotFound := func(path string) error { - p := &fieldpath.Paved{} - _, err := p.GetValue(path) - return err - } - +func TestApplyFromFieldPathPatch(t *testing.T) { type args struct { - patch v1beta1.ComposedPatch - xr *composite.Unstructured - cd *composed.Unstructured - only []v1beta1.PatchType + p PatchInterface + from runtime.Object + to runtime.Object } + type want struct { - xr *composite.Unstructured - cd *composed.Unstructured + to runtime.Object err error } @@ -44,559 +37,249 @@ func TestPatchApply(t *testing.T) { args want }{ - "InvalidCompositeFieldPathPatch": { - reason: "Should return error when required fields not passed to applyFromFieldPathPatch", - args: args{ - patch: v1beta1.ComposedPatch{ - Type: v1beta1.PatchTypeFromCompositeFieldPath, - // This is missing fields. - }, - xr: &composite.Unstructured{}, - cd: &composed.Unstructured{}, - }, - want: want{ - err: errors.Errorf(errFmtRequiredField, "FromFieldPath", v1beta1.PatchTypeFromCompositeFieldPath), - }, - }, - "Invalidv1.PatchType": { - reason: "Should return an error if an invalid patch type is specified", + "ValidFromCompositeFieldPath": { + reason: "Should correctly apply a valid FromCompositeFieldPath patch", args: args{ - patch: v1beta1.ComposedPatch{ - Type: "invalid-patchtype", - }, - xr: &composite.Unstructured{}, - cd: &composed.Unstructured{}, - }, - want: want{ - err: errors.Errorf(errFmtInvalidPatchType, "invalid-patchtype"), - }, - }, - "ValidCompositeFieldPathPatch": { - reason: "Should correctly apply a CompositeFieldPathPatch with valid settings", - args: args{ - patch: v1beta1.ComposedPatch{ + p: &v1beta1.ComposedPatch{ Type: v1beta1.PatchTypeFromCompositeFieldPath, Patch: v1beta1.Patch{ FromFieldPath: ptr.To[string]("metadata.labels"), ToFieldPath: ptr.To[string]("metadata.labels"), }, }, - xr: &composite.Unstructured{ + from: &composite.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "XR", - "metadata": { - "labels": { - "test": "blah" + "apiVersion": "test.crossplane.io/v1", + "kind": "XR", + "metadata": { + "labels": { + "test": "blah" + } } - } - }`)}, + }`)}, }, - cd: &composed.Unstructured{ + to: &composed.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed", - "metadata": { - "name": "cd" - } - }`)}, + "apiVersion": "test.crossplane.io/v1", + "kind": "Composed", + "metadata": { + "name": "cd" + } + }`)}, }, }, want: want{ - cd: &composed.Unstructured{ + to: &composed.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed", - "metadata": { - "name": "cd", - "labels": { - "test": "blah" + "apiVersion": "test.crossplane.io/v1", + "kind": "Composed", + "metadata": { + "name": "cd", + "labels": { + "test": "blah" + } } - } - }`)}, + }`)}, }, err: nil, }, }, - "ValidCompositeFieldPathPatchWithWildcards": { + "ValidFromFieldPathWithWildcards": { reason: "When passed a wildcarded path, adds a field to each element of an array", args: args{ - patch: v1beta1.ComposedPatch{ + p: &v1beta1.ComposedPatch{ Type: v1beta1.PatchTypeFromCompositeFieldPath, Patch: v1beta1.Patch{ FromFieldPath: ptr.To[string]("metadata.name"), ToFieldPath: ptr.To[string]("metadata.ownerReferences[*].name"), }, }, - xr: &composite.Unstructured{ + from: &composite.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "XR", - "metadata": { - "name": "test" - } - }`)}, + "apiVersion": "test.crossplane.io/v1", + "kind": "XR", + "metadata": { + "name": "test" + } + }`)}, }, - cd: &composed.Unstructured{ + to: &composed.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed", - "metadata": { - "ownerReferences": [ - { - "name": "" - }, - { - "name": "" - } - ] - } - }`)}, + "apiVersion": "test.crossplane.io/v1", + "kind": "Composed", + "metadata": { + "ownerReferences": [ + { + "name": "" + }, + { + "name": "" + } + ] + } + }`)}, }, }, want: want{ - cd: &composed.Unstructured{ + to: &composed.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed", - "metadata": { - "ownerReferences": [ - { - "name": "test" - }, - { - "name": "test" - } - ] - } - }`)}, + "apiVersion": "test.crossplane.io/v1", + "kind": "Composed", + "metadata": { + "ownerReferences": [ + { + "name": "test" + }, + { + "name": "test" + } + ] + } + }`)}, }, }, }, "InvalidCompositeFieldPathPatchWithWildcards": { reason: "When passed a wildcarded path, throws an error if ToFieldPath cannot be expanded", args: args{ - patch: v1beta1.ComposedPatch{ + p: &v1beta1.ComposedPatch{ Type: v1beta1.PatchTypeFromCompositeFieldPath, Patch: v1beta1.Patch{ FromFieldPath: ptr.To[string]("metadata.name"), ToFieldPath: ptr.To[string]("metadata.ownerReferences[*].badField"), }, }, - xr: &composite.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "XR", - "metadata": { - "name": "test" - } - }`)}, - }, - cd: &composed.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed", - "metadata": { - "ownerReferences": [ - { - "name": "test" - }, - { - "name": "test" - } - ] - } - }`)}, - }, - }, - want: want{ - err: errors.Errorf(errFmtExpandingArrayFieldPaths, "metadata.ownerReferences[*].badField"), - }, - }, - "MissingOptionalFieldPath": { - reason: "A FromFieldPath patch should be a no-op when an optional fromFieldPath doesn't exist", - args: args{ - patch: v1beta1.ComposedPatch{ - Type: v1beta1.PatchTypeFromCompositeFieldPath, - Patch: v1beta1.Patch{ - FromFieldPath: ptr.To[string]("metadata.labels"), - ToFieldPath: ptr.To[string]("metadata.labels"), - }, - }, - xr: &composite.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "XR", - "metadata": { - "name": "test" - } - }`)}, - }, - cd: &composed.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed", - "metadata": { - "name": "test" - } - }`)}, - }, - }, - want: want{ - cd: &composed.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed", - "metadata": { - "name": "test" - } - }`)}, - }, - err: nil, - }, - }, - "MissingRequiredFieldPath": { - reason: "A FromFieldPath patch should return an error when a required fromFieldPath doesn't exist", - args: args{ - patch: v1beta1.ComposedPatch{ - Type: v1beta1.PatchTypeFromCompositeFieldPath, - Patch: v1beta1.Patch{ - FromFieldPath: ptr.To[string]("wat"), - Policy: &v1beta1.PatchPolicy{ - FromFieldPath: func() *v1beta1.FromFieldPathPolicy { - s := v1beta1.FromFieldPathPolicyRequired - return &s - }(), - }, - ToFieldPath: ptr.To[string]("wat"), - }, - }, - xr: &composite.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "XR", - "metadata": { - "name": "test" - } - }`)}, - }, - cd: &composed.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed", - "metadata": { - "name": "test" - } - }`)}, - }, - }, - want: want{ - cd: &composed.Unstructured{ + from: &composite.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed", - "metadata": { - "name": "test" - } - }`)}, - }, - err: errNotFound("wat"), - }, - }, - "FilterExcludeCompositeFieldPathPatch": { - reason: "Should not apply the patch as the v1.PatchType is not present in filter.", - args: args{ - patch: v1beta1.ComposedPatch{ - Type: v1beta1.PatchTypeFromCompositeFieldPath, - Patch: v1beta1.Patch{ - FromFieldPath: ptr.To[string]("metadata.labels"), - ToFieldPath: ptr.To[string]("metadata.labels"), - }, - }, - xr: &composite.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "XR", - "metadata": { - "labels": { - "test": "blah" + "apiVersion": "test.crossplane.io/v1", + "kind": "XR", + "metadata": { + "name": "test" } - } - }`)}, - }, - cd: &composed.Unstructured{}, - only: []v1beta1.PatchType{v1beta1.PatchTypePatchSet}, - }, - want: want{ - cd: &composed.Unstructured{}, - err: nil, - }, - }, - "FilterIncludeCompositeFieldPathPatch": { - reason: "Should apply the patch as the v1.PatchType is present in filter.", - args: args{ - patch: v1beta1.ComposedPatch{ - Type: v1beta1.PatchTypeFromCompositeFieldPath, - Patch: v1beta1.Patch{ - FromFieldPath: ptr.To[string]("metadata.labels"), - ToFieldPath: ptr.To[string]("metadata.labels"), - }, + }`)}, }, - xr: &composite.Unstructured{ + to: &composed.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "XR", - "metadata": { - "labels": { - "test": "blah" + "apiVersion": "test.crossplane.io/v1", + "kind": "Composed", + "metadata": { + "ownerReferences": [ + { + "name": "test" + }, + { + "name": "test" + } + ] } - } - }`)}, - }, - cd: &composed.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed" - }`)}, + }`)}, }, - only: []v1beta1.PatchType{v1beta1.PatchTypeFromCompositeFieldPath}, }, want: want{ - cd: &composed.Unstructured{ + to: &composed.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed", - "metadata": { - "labels": { - "test": "blah" + "apiVersion": "test.crossplane.io/v1", + "kind": "Composed", + "metadata": { + "ownerReferences": [ + { + "name": "test" + }, + { + "name": "test" + } + ] } - } - }`)}, + }`)}, }, - err: nil, + err: errors.Errorf(errFmtExpandingArrayFieldPaths, "metadata.ownerReferences[*].badField"), }, }, "DefaultToFieldCompositeFieldPathPatch": { reason: "Should correctly default the ToFieldPath value if not specified.", args: args{ - patch: v1beta1.ComposedPatch{ + p: &v1beta1.ComposedPatch{ Type: v1beta1.PatchTypeFromCompositeFieldPath, Patch: v1beta1.Patch{ FromFieldPath: ptr.To[string]("metadata.labels"), }, }, - xr: &composite.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "XR", - "metadata": { - "labels": { - "test": "blah" - } - } - }`)}, - }, - cd: &composed.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed" - }`)}, - }, - }, - want: want{ - cd: &composed.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed", - "metadata": { - "labels": { - "test": "blah" - } - } - }`)}, - }, - err: nil, - }, - }, - "ValidToCompositeFieldPathPatch": { - reason: "Should correctly apply a ToCompositeFieldPath patch with valid settings", - args: args{ - patch: v1beta1.ComposedPatch{ - Type: v1beta1.PatchTypeToCompositeFieldPath, - Patch: v1beta1.Patch{ - FromFieldPath: ptr.To[string]("metadata.labels"), - ToFieldPath: ptr.To[string]("metadata.labels"), - }, - }, - xr: &composite.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "XR" - }`)}, - }, - cd: &composed.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed", - "metadata": { - "labels": { - "test": "blah" - } - } - }`)}, - }, - }, - want: want{ - xr: &composite.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "XR", - "metadata": { - "labels": { - "test": "blah" - } - } - }`)}, - }, - err: nil, - }, - }, - "ValidToCompositeFieldPathPatchWithWildcards": { - reason: "When passed a wildcarded path, adds a field to each element of an array", - args: args{ - patch: v1beta1.ComposedPatch{ - Type: v1beta1.PatchTypeToCompositeFieldPath, - Patch: v1beta1.Patch{ - FromFieldPath: ptr.To[string]("metadata.name"), - ToFieldPath: ptr.To[string]("metadata.ownerReferences[*].name"), - }, - }, - xr: &composite.Unstructured{ + from: &composite.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "XR", - "metadata": { - "ownerReferences": [ - { - "name": "" - }, - { - "name": "" + "apiVersion": "test.crossplane.io/v1", + "kind": "XR", + "metadata": { + "labels": { + "test": "blah" } - ] - } - }`)}, + } + }`)}, }, - cd: &composed.Unstructured{ + to: &composed.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed", - "metadata": { - "name": "test" - } - }`)}, + "apiVersion": "test.crossplane.io/v1", + "kind": "Composed" + }`)}, }, }, want: want{ - xr: &composite.Unstructured{ + to: &composed.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "XR", - "metadata": { - "ownerReferences": [ - { - "name": "test" - }, - { - "name": "test" + "apiVersion": "test.crossplane.io/v1", + "kind": "Composed", + "metadata": { + "labels": { + "test": "blah" } - ] - } - }`)}, - }, - }, - }, - "MissingCombineFromCompositeConfig": { - reason: "Should return an error if Combine config is not passed", - args: args{ - patch: v1beta1.ComposedPatch{ - Type: v1beta1.PatchTypeCombineFromComposite, - Patch: v1beta1.Patch{ - ToFieldPath: ptr.To[string]("metadata.labels.destination"), - // Missing a Combine field - Combine: nil, - }, - }, - xr: &composite.Unstructured{}, - cd: &composed.Unstructured{}, - }, - want: want{ - xr: &composite.Unstructured{}, - cd: &composed.Unstructured{}, - err: errors.Errorf(errFmtRequiredField, "Combine", v1beta1.PatchTypeCombineFromComposite), - }, - }, - "MissingCombineStrategyFromCompositeConfig": { - reason: "Should return an error if Combine strategy config is not passed", - args: args{ - patch: v1beta1.ComposedPatch{ - Type: v1beta1.PatchTypeCombineFromComposite, - Patch: v1beta1.Patch{ - Combine: &v1beta1.Combine{ - Variables: []v1beta1.CombineVariable{ - {FromFieldPath: "metadata.labels.source1"}, - {FromFieldPath: "metadata.labels.source2"}, - }, - Strategy: v1beta1.CombineStrategyString, - // Missing a String combine config. - }, - ToFieldPath: ptr.To[string]("metadata.labels.destination"), - }, - }, - xr: &composite.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "XR", - "metadata": { - "labels": { - "source1": "a", - "source2": "b" } - } - }`)}, - }, - }, - want: want{ - err: errors.Errorf(errFmtCombineConfigMissing, v1beta1.CombineStrategyString), - }, - }, - "MissingCombineVariablesFromCompositeConfig": { - reason: "Should return an error if no variables have been passed", - args: args{ - patch: v1beta1.ComposedPatch{ - Type: v1beta1.PatchTypeCombineFromComposite, - Patch: v1beta1.Patch{ - Combine: &v1beta1.Combine{ - // This is empty. - Variables: []v1beta1.CombineVariable{}, - Strategy: v1beta1.CombineStrategyString, - String: &v1beta1.StringCombine{Format: "%s-%s"}, - }, - ToFieldPath: ptr.To[string]("objectMeta.labels.destination"), - }, + }`)}, }, - }, - want: want{ - err: errors.New(errCombineRequiresVariables), + err: nil, }, }, - "NoOpOptionalInputFieldFromCompositeConfig": { - // Note: OptionalFieldPathNotFound is tested below, but we want to - // test that we abort the patch if _any_ of our source fields are - // not available. + } + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + err := ApplyFromFieldPathPatch(tc.args.p, tc.args.from, tc.args.to) + + if diff := cmp.Diff(tc.want.to, tc.args.to); diff != "" { + t.Errorf("\n%s\nApplyFromFieldPathPatch(...): -want, +got:\n%s", tc.reason, diff) + } + + if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" { + t.Errorf("\n%s\nApplyFromFieldPathPatch(): -want error, +got error:\n%s", tc.reason, diff) + } + }) + } +} + +func TestApplyCombineFromVariablesPatch(t *testing.T) { + errNotFound := func(path string) error { + p := &fieldpath.Paved{} + _, err := p.GetValue(path) + return err + } + + type args struct { + p PatchInterface + from runtime.Object + to runtime.Object + } + + type want struct { + to runtime.Object + err error + } + + cases := map[string]struct { + reason string + args + want + }{ + "VariableFromFieldPathNotFound": { reason: "Should return no error and not apply patch if an optional variable is missing", args: args{ - patch: v1beta1.ComposedPatch{ + p: &v1beta1.ComposedPatch{ Type: v1beta1.PatchTypeCombineFromComposite, Patch: v1beta1.Patch{ Combine: &v1beta1.Combine{ @@ -611,27 +294,21 @@ func TestPatchApply(t *testing.T) { ToFieldPath: ptr.To[string]("metadata.labels.destination"), }, }, - xr: &composite.Unstructured{ + from: &composite.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "XR", - "metadata": { - "labels": { - "source1": "foo", - "source3": "baz" - } - } - }`)}, + "apiVersion": "test.crossplane.io/v1", + "kind": "XR" + }`)}, }, }, want: want{ - err: nil, + err: errNotFound("metadata"), }, }, "ValidCombineFromComposite": { reason: "Should correctly apply a CombineFromComposite patch with valid settings", args: args{ - patch: v1beta1.ComposedPatch{ + p: &v1beta1.ComposedPatch{ Type: v1beta1.PatchTypeCombineFromComposite, Patch: v1beta1.Patch{ Combine: &v1beta1.Combine{ @@ -645,92 +322,35 @@ func TestPatchApply(t *testing.T) { ToFieldPath: ptr.To[string]("metadata.labels.destination"), }, }, - xr: &composite.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "XR", - "metadata": { - "labels": { - "source1": "foo", - "source2": "bar" - } - } - }`)}, - }, - cd: &composed.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed", - "metadata": { - "labels": { - "test": "blah" - } - } - }`)}, - }, - }, - want: want{ - cd: &composed.Unstructured{ - Unstructured: unstructured.Unstructured{Object: MustObject(`{ - "apiVersion": "test.crossplane.io/v1", - "kind": "Composed", - "metadata": { - "labels": { - "destination": "foo-bar", - "test": "blah" - } - } - }`)}, - }, - err: nil, - }, - }, - "ValidCombineToComposite": { - reason: "Should correctly apply a CombineToComposite patch with valid settings", - args: args{ - patch: v1beta1.ComposedPatch{ - Type: v1beta1.PatchTypeCombineToComposite, - Patch: v1beta1.Patch{ - Combine: &v1beta1.Combine{ - Variables: []v1beta1.CombineVariable{ - {FromFieldPath: "metadata.labels.source1"}, - {FromFieldPath: "metadata.labels.source2"}, - }, - Strategy: v1beta1.CombineStrategyString, - String: &v1beta1.StringCombine{Format: "%s-%s"}, - }, - ToFieldPath: ptr.To[string]("metadata.labels.destination"), - }, - }, - xr: &composite.Unstructured{ + from: &composite.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ "apiVersion": "test.crossplane.io/v1", "kind": "XR", "metadata": { "labels": { - "test": "blah" + "source1": "foo", + "source2": "bar" } } }`)}, }, - cd: &composed.Unstructured{ + to: &composed.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ "apiVersion": "test.crossplane.io/v1", "kind": "Composed", "metadata": { "labels": { - "source1": "foo", - "source2": "bar" + "test": "blah" } } }`)}, }, }, want: want{ - xr: &composite.Unstructured{ + to: &composed.Unstructured{ Unstructured: unstructured.Unstructured{Object: MustObject(`{ "apiVersion": "test.crossplane.io/v1", - "kind": "XR", + "kind": "Composed", "metadata": { "labels": { "destination": "foo-bar", @@ -745,21 +365,14 @@ func TestPatchApply(t *testing.T) { } for name, tc := range cases { t.Run(name, func(t *testing.T) { - ncp := tc.args.xr.DeepCopyObject().(resource.Composite) - err := Apply(&tc.args.patch, ncp, tc.args.cd, tc.args.only...) + err := ApplyCombineFromVariablesPatch(tc.args.p, tc.args.from, tc.args.to) - if tc.want.xr != nil { - if diff := cmp.Diff(tc.want.xr, ncp); diff != "" { - t.Errorf("\n%s\nApply(cp): -want, +got:\n%s", tc.reason, diff) - } - } - if tc.want.cd != nil { - if diff := cmp.Diff(tc.want.cd, tc.args.cd); diff != "" { - t.Errorf("\n%s\nApply(cd): -want, +got:\n%s", tc.reason, diff) - } + if diff := cmp.Diff(tc.want.to, tc.args.to); diff != "" { + t.Errorf("\n%s\nApplyCombineFromVariablesPatch(...): -want, +got:\n%s", tc.reason, diff) } + if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" { - t.Errorf("\n%s\nApply(err): -want, +got:\n%s", tc.reason, diff) + t.Errorf("\n%s\nApplyCombineFromVariablesPatch(): -want error, +got error:\n%s", tc.reason, diff) } }) } @@ -773,84 +386,6 @@ func MustObject(j string) map[string]any { return out } -func TestOptionalFieldPathNotFound(t *testing.T) { - errBoom := errors.New("boom") - errNotFound := func() error { - p := &fieldpath.Paved{} - _, err := p.GetValue("boom") - return err - } - required := v1beta1.FromFieldPathPolicyRequired - optional := v1beta1.FromFieldPathPolicyOptional - type args struct { - err error - p *v1beta1.PatchPolicy - } - - cases := map[string]struct { - reason string - args - want bool - }{ - "NotAnError": { - reason: "Should perform patch if no error finding field.", - args: args{}, - want: false, - }, - "NotFieldNotFoundError": { - reason: "Should return error if something other than field not found.", - args: args{ - err: errBoom, - }, - want: false, - }, - "DefaultOptionalNoPolicy": { - reason: "Should return no-op if field not found and no patch policy specified.", - args: args{ - err: errNotFound(), - }, - want: true, - }, - "DefaultOptionalNoPathPolicy": { - reason: "Should return no-op if field not found and empty patch policy specified.", - args: args{ - p: &v1beta1.PatchPolicy{}, - err: errNotFound(), - }, - want: true, - }, - "OptionalNotFound": { - reason: "Should return no-op if field not found and optional patch policy explicitly specified.", - args: args{ - p: &v1beta1.PatchPolicy{ - FromFieldPath: &optional, - }, - err: errNotFound(), - }, - want: true, - }, - "RequiredNotFound": { - reason: "Should return error if field not found and required patch policy explicitly specified.", - args: args{ - p: &v1beta1.PatchPolicy{ - FromFieldPath: &required, - }, - err: errNotFound(), - }, - want: false, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - got := IsOptionalFieldPathNotFound(tc.args.err, tc.args.p) - if diff := cmp.Diff(tc.want, got); diff != "" { - t.Errorf("IsOptionalFieldPathNotFound(...): -want, +got:\n%s", diff) - } - }) - } -} - func TestComposedTemplates(t *testing.T) { asJSON := func(val interface{}) extv1.JSON { raw, err := json.Marshal(val) diff --git a/render.go b/render.go index fc2ff67..ec9f640 100644 --- a/render.go +++ b/render.go @@ -1,30 +1,18 @@ package main import ( - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/json" "github.com/crossplane/crossplane-runtime/pkg/errors" "github.com/crossplane/crossplane-runtime/pkg/resource" - - "github.com/crossplane/function-sdk-go/resource/composed" - "github.com/crossplane/function-sdk-go/resource/composite" - - "github.com/crossplane-contrib/function-patch-and-transform/input/v1beta1" ) // Error strings const ( errUnmarshalJSON = "cannot unmarshal JSON data" - errFmtKindChanged = "cannot change the kind of a composed resource from %s to %s (possible composed resource template mismatch)" - errFmtNamePrefixLabel = "cannot find top-level composite resource name label %q in composite resource metadata" - - // TODO(negz): Include more detail such as field paths if they exist. - // Perhaps require each patch type to have a String() method to help - // identify it. - errFmtPatch = "cannot apply the %q patch at index %d" + errFmtKindChanged = "cannot change the kind of a composed resource from %s to %s (possible composed resource template mismatch)" ) // RenderFromJSON renders the supplied resource from JSON bytes. @@ -59,84 +47,3 @@ func RenderFromJSON(o resource.Object, data []byte) error { return nil } - -// RenderEnvironmentPatches renders the supplied environment by applying all -// patches that are to the environment, from the supplied XR. -func RenderEnvironmentPatches(env *unstructured.Unstructured, oxr, dxr *composite.Unstructured, ps []v1beta1.EnvironmentPatch) error { - for i, p := range ps { - p := p - switch p.GetType() { - case v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeCombineFromComposite: - if err := ApplyToObjects(&p, oxr, env); err != nil { - return errors.Wrapf(err, errFmtPatch, p.GetType(), i) - } - case v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeCombineToComposite: - if err := ApplyToObjects(&p, dxr, env); err != nil { - return errors.Wrapf(err, errFmtPatch, p.GetType(), i) - } - case v1beta1.PatchTypePatchSet, v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeCombineFromEnvironment, v1beta1.PatchTypeToEnvironmentFieldPath, v1beta1.PatchTypeCombineToEnvironment: - // nothing to do - } - } - return nil -} - -// RenderComposedPatches renders the supplied composed resource by applying all -// patches that are to or from the supplied composite resource and environment -// in the order they were defined. Properly selecting the right source or -// destination between observed and desired resources. -func RenderComposedPatches(ocd, dcd *composed.Unstructured, oxr, dxr *composite.Unstructured, env *unstructured.Unstructured, ps []v1beta1.ComposedPatch) error { //nolint:gocyclo // just a switch - for i, p := range ps { - p := p - switch t := p.GetType(); t { - case v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeCombineToComposite: - // TODO(negz): Should failures to patch the XR be terminal? It could - // indicate a required patch failed. A required patch means roughly - // "this patch has to succeed before you mutate the resource". This - // is useful to make sure we never create a composed resource in the - // wrong state. It's less clear how useful it is for the XR, given - // we'll only ever be updating it, not creating it. - - // We want to patch the XR from observed composed resources, not - // from desired state. This is because folks will typically be - // patching from a field that is set once the observed resource is - // applied such as its status. - if ocd == nil { - continue - } - if err := ApplyToObjects(&p, dxr, ocd); err != nil { - return errors.Wrapf(err, errFmtPatch, t, i) - } - case v1beta1.PatchTypeToEnvironmentFieldPath, v1beta1.PatchTypeCombineToEnvironment: - // TODO(negz): Same as above, but for the Environment. What does it - // mean for a required patch to the environment to fail? Should it - // be terminal? - - // Run all patches that are from the (observed) composed resource to - // the environment. - if ocd == nil { - continue - } - if err := ApplyToObjects(&p, env, ocd); err != nil { - return errors.Wrapf(err, errFmtPatch, t, i) - } - // If either of the below renderings return an error, most likely a - // required FromComposite or FromEnvironment patch failed. A required - // patch means roughly "this patch has to succeed before you mutate the - // resource." This is useful to make sure we never create a composed - // resource in the wrong state. To that end, we don't want to add this - // resource to our accumulated desired state. - case v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeCombineFromComposite: - if err := ApplyToObjects(&p, oxr, dcd); err != nil { - return errors.Wrapf(err, errFmtPatch, t, i) - } - case v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeCombineFromEnvironment: - if err := ApplyToObjects(&p, env, dcd); err != nil { - return errors.Wrapf(err, errFmtPatch, t, i) - } - case v1beta1.PatchTypePatchSet: - // Already resolved - nothing to do. - } - } - return nil -} diff --git a/validate.go b/validate.go index 5d87f07..05d0140 100644 --- a/validate.go +++ b/validate.go @@ -189,6 +189,7 @@ func ValidatePatch(p PatchInterface) *field.Error { //nolint: gocyclo // This is if p.GetToFieldPath() == "" { return field.Required(field.NewPath("toFieldPath"), fmt.Sprintf("toFieldPath must be set for patch type %s", p.GetType())) } + return WrapFieldError(ValidateCombine(p.GetCombine()), field.NewPath("combine")) default: // Should never happen return field.Invalid(field.NewPath("type"), p.GetType(), "unknown patch type") @@ -202,6 +203,32 @@ func ValidatePatch(p PatchInterface) *field.Error { //nolint: gocyclo // This is return nil } +// ValidateCombine validates a Combine. +func ValidateCombine(c *v1beta1.Combine) *field.Error { + switch c.Strategy { + case v1beta1.CombineStrategyString: + if c.String == nil { + return field.Required(field.NewPath("string"), fmt.Sprintf("string must be set for combine strategy %s", c.Strategy)) + } + case "": + return field.Required(field.NewPath("strategy"), "a combine strategy must be provided") + default: + return field.Invalid(field.NewPath("strategy"), c.Strategy, "unknown strategy type") + } + + if len(c.Variables) == 0 { + return field.Required(field.NewPath("variables"), "at least one variable must be provided") + } + + for i := range c.Variables { + if c.Variables[i].FromFieldPath == "" { + return field.Required(field.NewPath("variables").Index(i).Child("fromFieldPath"), "fromFieldPath must be set for each combine variable") + } + } + + return nil +} + // ValidateTransform validates a Transform. func ValidateTransform(t v1beta1.Transform) *field.Error { //nolint:gocyclo // This is a long but simple/same-y switch. switch t.Type { diff --git a/validate_test.go b/validate_test.go index dde1333..5b46a07 100644 --- a/validate_test.go +++ b/validate_test.go @@ -380,6 +380,131 @@ func TestValidatePatch(t *testing.T) { } } +func TestValidateCombine(t *testing.T) { + type args struct { + combine v1beta1.Combine + } + type want struct { + err *field.Error + } + + cases := map[string]struct { + reason string + args args + want want + }{ + "MissingStrategy": { + reason: "A combine with no strategy is invalid", + args: args{ + combine: v1beta1.Combine{}, + }, + want: want{ + err: &field.Error{ + Type: field.ErrorTypeRequired, + Field: "strategy", + }, + }, + }, + "InvalidStrategy": { + reason: "A combine with an unknown strategy is invalid", + args: args{ + combine: v1beta1.Combine{ + Strategy: "Smoosh", + }, + }, + want: want{ + err: &field.Error{ + Type: field.ErrorTypeInvalid, + Field: "strategy", + }, + }, + }, + "ValidStringCombine": { + reason: "A string combine with variables and a format string should be valid", + args: args{ + combine: v1beta1.Combine{ + Strategy: v1beta1.CombineStrategyString, + Variables: []v1beta1.CombineVariable{ + {FromFieldPath: "a"}, + {FromFieldPath: "b"}, + }, + String: &v1beta1.StringCombine{ + Format: "%s-%s", + }, + }, + }, + want: want{ + err: nil, + }, + }, + "MissingVariables": { + reason: "A combine with no variables is invalid", + args: args{ + combine: v1beta1.Combine{ + Strategy: v1beta1.CombineStrategyString, + String: &v1beta1.StringCombine{ + Format: "%s-%s", + }, + }, + }, + want: want{ + err: &field.Error{ + Type: field.ErrorTypeRequired, + Field: "variables", + }, + }, + }, + "VariableMissingFromFieldPath": { + reason: "A variable with no fromFieldPath is invalid", + args: args{ + combine: v1beta1.Combine{ + Strategy: v1beta1.CombineStrategyString, + Variables: []v1beta1.CombineVariable{ + {FromFieldPath: "a"}, + {FromFieldPath: ""}, // Missing. + }, + String: &v1beta1.StringCombine{ + Format: "%s-%s", + }, + }, + }, + want: want{ + err: &field.Error{ + Type: field.ErrorTypeRequired, + Field: "variables[1].fromFieldPath", + }, + }, + }, + "MissingStringConfig": { + reason: "A string combine with no string config is invalid", + args: args{ + combine: v1beta1.Combine{ + Strategy: v1beta1.CombineStrategyString, + Variables: []v1beta1.CombineVariable{ + {FromFieldPath: "a"}, + {FromFieldPath: "b"}, + }, + }, + }, + want: want{ + err: &field.Error{ + Type: field.ErrorTypeRequired, + Field: "string", + }, + }, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + err := ValidateCombine(&tc.args.combine) + if diff := cmp.Diff(tc.want.err, err, cmpopts.IgnoreFields(field.Error{}, "Detail", "BadValue")); diff != "" { + t.Errorf("%s\nValidateCombine(...): -want, +got:\n%s", tc.reason, diff) + } + }) + } +} + func TestValidateTransform(t *testing.T) { type args struct { transform v1beta1.Transform From 1004f14158ea7db8ef941934f1c240cb833444eb Mon Sep 17 00:00:00 2001 From: Nic Cope Date: Fri, 19 Jan 2024 22:40:21 -0800 Subject: [PATCH 17/31] Regenerate input CRD I think Renovate bumped controller-tools, resulting in most of this diff. Signed-off-by: Nic Cope --- go.mod | 1 - go.sum | 77 +- .../input/pt.fn.crossplane.io_resources.yaml | 684 ++++++++++-------- 3 files changed, 390 insertions(+), 372 deletions(-) diff --git a/go.mod b/go.mod index aa136fc..b1cd623 100644 --- a/go.mod +++ b/go.mod @@ -57,7 +57,6 @@ require ( github.com/spf13/afero v1.10.0 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/testify v1.8.4 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect diff --git a/go.sum b/go.sum index a5332f7..05a32d0 100644 --- a/go.sum +++ b/go.sum @@ -67,11 +67,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/crossplane/crossplane-runtime v1.14.2 h1:pV5JMzyzi/kcbeVBVPCat5MHH8zS94MBUapAyGx/Ry0= -github.com/crossplane/crossplane-runtime v1.14.2/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o= github.com/crossplane/crossplane-runtime v1.14.3 h1:YNGALph/UJTtQO+cJ9KGQ5NfALI5453PeE93Aqy9SWg= github.com/crossplane/crossplane-runtime v1.14.3/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o= github.com/crossplane/function-sdk-go v0.1.0 h1:WN3CUSaj6wgDqQPZZP1whMVIkTAZtN3HVCS67pTMzd8= @@ -95,11 +92,8 @@ github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJ github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= 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.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -107,7 +101,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-json-experiment/json v0.0.0-20231013223334-54c864be5b8d h1:zqfo2jECgX5eYQseB/X+uV4Y5ocGOG/vG/LTztUCyPA= github.com/go-json-experiment/json v0.0.0-20231013223334-54c864be5b8d/go.mod h1:6daplAwHHGbUGib4990V3Il26O0OC4aRyvewaaAihaA= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -256,8 +249,7 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -282,10 +274,10 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= 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.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= -github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= +github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -307,8 +299,7 @@ github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUz github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= @@ -402,8 +393,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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= @@ -438,8 +428,6 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -464,8 +452,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -504,15 +492,10 @@ golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -523,8 +506,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -582,8 +563,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= 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= @@ -686,8 +666,6 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -713,48 +691,20 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY= -k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= -k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= -k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= k8s.io/api v0.29.1 h1:DAjwWX/9YT7NQD4INu49ROJuZAAAP/Ijki48GUPzxqw= k8s.io/api v0.29.1/go.mod h1:7Kl10vBRUXhnQQI8YR/R327zXC8eJ7887/+Ybta+RoQ= -k8s.io/apiextensions-apiserver v0.28.4 h1:AZpKY/7wQ8n+ZYDtNHbAJBb+N4AXXJvyZx6ww6yAJvU= -k8s.io/apiextensions-apiserver v0.28.4/go.mod h1:pgQIZ1U8eJSMQcENew/0ShUTlePcSGFq6dxSxf2mwPM= -k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0= -k8s.io/apiextensions-apiserver v0.29.0/go.mod h1:TKmpy3bTS0mr9pylH0nOt/QzQRrW7/h7yLdRForMZwc= k8s.io/apiextensions-apiserver v0.29.1 h1:S9xOtyk9M3Sk1tIpQMu9wXHm5O2MX6Y1kIpPMimZBZw= k8s.io/apiextensions-apiserver v0.29.1/go.mod h1:zZECpujY5yTW58co8V2EQR4BD6A9pktVgHhvc0uLfeU= -k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8= -k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg= -k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= -k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= k8s.io/apimachinery v0.29.1 h1:KY4/E6km/wLBguvCZv8cKTeOwwOBqFNjwJIdMkMbbRc= k8s.io/apimachinery v0.29.1/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= -k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY= -k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4= -k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= -k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= k8s.io/client-go v0.29.1 h1:19B/+2NGEwnFLzt0uB5kNJnfTsbV8w6TgQRz9l7ti7A= k8s.io/client-go v0.29.1/go.mod h1:TDG/psL9hdet0TI9mGyHJSgRkW3H9JZk2dNEUS7bRks= -k8s.io/component-base v0.28.4 h1:c/iQLWPdUgI90O+T9TeECg8o7N3YJTiuz2sKxILYcYo= -k8s.io/component-base v0.28.4/go.mod h1:m9hR0uvqXDybiGL2nf/3Lf0MerAfQXzkfWhUY58JUbU= -k8s.io/component-base v0.29.0 h1:T7rjd5wvLnPBV1vC4zWd/iWRbV8Mdxs+nGaoaFzGw3s= -k8s.io/component-base v0.29.0/go.mod h1:sADonFTQ9Zc9yFLghpDpmNXEdHyQmFIGbiuZbqAXQ1M= k8s.io/component-base v0.29.1 h1:MUimqJPCRnnHsskTTjKD+IC1EHBbRCVyi37IoFBrkYw= k8s.io/component-base v0.29.1/go.mod h1:fP9GFjxYrLERq1GcWWZAE3bqbNcDKDytn2srWuHTtKc= -k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= -k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= -k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf h1:iTzha1p7Fi83476ypNSz8nV9iR9932jIIs26F7gNLsU= -k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI= -k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= @@ -762,13 +712,10 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= -sigs.k8s.io/controller-tools v0.13.0 h1:NfrvuZ4bxyolhDBt/rCZhDnx3M2hzlhgo5n3Iv2RykI= -sigs.k8s.io/controller-tools v0.13.0/go.mod h1:5vw3En2NazbejQGCeWKRrE7q4P+CW8/klfVqP8QZkgA= +sigs.k8s.io/controller-tools v0.14.0 h1:rnNoCC5wSXlrNoBKKzL70LNJKIQKEzT6lloG6/LF73A= sigs.k8s.io/controller-tools v0.14.0/go.mod h1:TV7uOtNNnnR72SpzhStvPkoS/U5ir0nMudrkrC4M9Sc= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= diff --git a/package/input/pt.fn.crossplane.io_resources.yaml b/package/input/pt.fn.crossplane.io_resources.yaml index 1b68e97..052311b 100644 --- a/package/input/pt.fn.crossplane.io_resources.yaml +++ b/package/input/pt.fn.crossplane.io_resources.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.13.0 + controller-gen.kubebuilder.io/version: v0.14.0 name: resources.pt.fn.crossplane.io spec: group: pt.fn.crossplane.io @@ -22,61 +22,72 @@ spec: description: Resources specifies Patch & Transform resource templates. properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string environment: - description: "Environment represents the Composition environment. \n THIS - IS AN ALPHA FIELD. Do not use it in production. It may be changed or - removed without notice." + description: |- + Environment represents the Composition environment. + + + THIS IS AN ALPHA FIELD. + Do not use it in production. It may be changed or removed without notice. properties: patches: - description: Patches is a list of environment patches that are executed - before a composition's resources are composed. These patches are - between the XR and the Environment. Either from the Environment - to the XR, or vice versa. + description: |- + Patches is a list of environment patches that are executed before a + composition's resources are composed. These patches are between the XR + and the Environment. Either from the Environment to the XR, or vice + versa. items: - description: EnvironmentPatch objects are applied between the composite - resource and the environment. Their behaviour depends on the Type - selected. The default Type, FromCompositeFieldPath, copies a value - from the composite resource to the environment, applying any defined - transformers. + description: |- + EnvironmentPatch objects are applied between the composite resource and + the environment. Their behaviour depends on the Type selected. The default + Type, FromCompositeFieldPath, copies a value from the composite resource + to the environment, applying any defined transformers. properties: combine: - description: Combine is the patch configuration for a CombineFromComposite, + description: |- + Combine is the patch configuration for a CombineFromComposite, CombineToComposite patch. properties: strategy: - description: Strategy defines the strategy to use to combine - the input variable values. Currently only string is supported. + description: |- + Strategy defines the strategy to use to combine the input variable values. + Currently only string is supported. enum: - string type: string string: - description: String declares that input variables should - be combined into a single string, using the relevant settings - for formatting purposes. + description: |- + String declares that input variables should be combined into a single + string, using the relevant settings for formatting purposes. properties: fmt: - description: Format the input using a Go format string. - See https://golang.org/pkg/fmt/ for details. + description: |- + Format the input using a Go format string. See + https://golang.org/pkg/fmt/ for details. type: string required: - fmt type: object variables: - description: Variables are the list of variables whose values - will be retrieved and combined. + description: |- + Variables are the list of variables whose values will be retrieved and + combined. items: - description: A CombineVariable defines the source of a - value that is combined with others to form and patch - an output value. Currently, this only supports retrieving - values from a field path. + description: |- + A CombineVariable defines the source of a value that is combined with + others to form and patch an output value. Currently, this only supports + retrieving values from a field path. properties: fromFieldPath: - description: FromFieldPath is the path of the field - on the source whose value is to be used as input. + description: |- + FromFieldPath is the path of the field on the source whose value is + to be used as input. type: string required: - fromFieldPath @@ -88,49 +99,56 @@ spec: - variables type: object fromFieldPath: - description: FromFieldPath is the path of the field on the resource - whose value is to be used as input. Required when type is - FromCompositeFieldPath or ToCompositeFieldPath. + description: |- + FromFieldPath is the path of the field on the resource whose value is + to be used as input. Required when type is FromCompositeFieldPath or + ToCompositeFieldPath. type: string policy: description: Policy configures the specifics of patching behaviour. properties: fromFieldPath: - description: FromFieldPath specifies how to patch from a - field path. The default is 'Optional', which means the - patch will be a no-op if the specified fromFieldPath does - not exist. Use 'Required' if the patch should fail if - the specified path does not exist. + description: |- + FromFieldPath specifies how to patch from a field path. The default is + 'Optional', which means the patch will be a no-op if the specified + fromFieldPath does not exist. Use 'Required' to prevent the creation of a + new composed resource until the required path exists. enum: - Optional - Required type: string type: object toFieldPath: - description: ToFieldPath is the path of the field on the resource - whose value will be changed with the result of transforms. - Leave empty if you'd like to propagate to the same path as - fromFieldPath. + description: |- + ToFieldPath is the path of the field on the resource whose value will + be changed with the result of transforms. Leave empty if you'd like to + propagate to the same path as fromFieldPath. type: string transforms: - description: Transforms are the list of functions that are used - as a FIFO pipe for the input to be transformed. + description: |- + Transforms are the list of functions that are used as a FIFO pipe for the + input to be transformed. items: - description: Transform is a unit of process whose input is - transformed into an output with the supplied configuration. + description: |- + Transform is a unit of process whose input is transformed into an output with + the supplied configuration. properties: convert: description: Convert is used to cast the input into the given output type. properties: format: - description: "The expected input format. \n * `quantity` - - parses the input as a K8s [`resource.Quantity`](https://pkg.go.dev/k8s.io/apimachinery/pkg/api/resource#Quantity). + description: |- + The expected input format. + + + * `quantity` - parses the input as a K8s [`resource.Quantity`](https://pkg.go.dev/k8s.io/apimachinery/pkg/api/resource#Quantity). Only used during `string -> float64` conversions. - * `json` - parses the input as a JSON string. Only - used during `string -> object` or `string -> list` - conversions. \n If this property is null, the default - conversion is applied." + * `json` - parses the input as a JSON string. + Only used during `string -> object` or `string -> list` conversions. + + + If this property is null, the default conversion is applied. enum: - none - quantity @@ -170,26 +188,29 @@ spec: - Input type: string fallbackValue: - description: The fallback value that should be returned - by the transform if now pattern matches. + description: |- + The fallback value that should be returned by the transform if now pattern + matches. x-kubernetes-preserve-unknown-fields: true patterns: - description: The patterns that should be tested against - the input string. Patterns are tested in order. - The value of the first match is used as result of - this transform. + description: |- + The patterns that should be tested against the input string. + Patterns are tested in order. The value of the first match is used as + result of this transform. items: - description: MatchTransformPattern is a transform - that returns the value that matches a pattern. + description: |- + MatchTransformPattern is a transform that returns the value that matches a + pattern. properties: literal: - description: Literal exactly matches the input - string (case sensitive). Is required if `type` - is `literal`. + description: |- + Literal exactly matches the input string (case sensitive). + Is required if `type` is `literal`. type: string regexp: - description: Regexp to match against the input - string. Is required if `type` is `regexp`. + description: |- + Regexp to match against the input string. + Is required if `type` is `regexp`. type: string result: description: The value that is used as result @@ -197,14 +218,17 @@ spec: x-kubernetes-preserve-unknown-fields: true type: default: literal - description: "Type specifies how the pattern - matches the input. \n * `literal` - the pattern - value has to exactly match (case sensitive) - the input string. This is the default. \n - * `regexp` - the pattern treated as a regular - expression against which the input string - is tested. Crossplane will throw an error - if the key is not a valid regexp." + description: |- + Type specifies how the pattern matches the input. + + + * `literal` - the pattern value has to exactly match (case sensitive) the + input string. This is the default. + + + * `regexp` - the pattern treated as a regular expression against + which the input string is tested. Crossplane will throw an error if the + key is not a valid regexp. enum: - literal - regexp @@ -216,8 +240,9 @@ spec: type: array type: object math: - description: Math is used to transform the input via mathematical - operations such as multiplication. + description: |- + Math is used to transform the input via mathematical operations such as + multiplication. properties: clampMax: description: ClampMax makes sure that the value is @@ -243,18 +268,18 @@ spec: type: string type: object string: - description: String is used to transform the input into - a string or a different kind of string. Note that the - input does not necessarily need to be a string. + description: |- + String is used to transform the input into a string or a different kind + of string. Note that the input does not necessarily need to be a string. properties: convert: - description: Optional conversion method to be specified. - `ToUpper` and `ToLower` change the letter case of - the input string. `ToBase64` and `FromBase64` perform - a base64 conversion based on the input string. `ToJson` - converts any input value into its raw JSON representation. - `ToSha1`, `ToSha256` and `ToSha512` generate a hash - value based on the input converted to JSON. + description: |- + Optional conversion method to be specified. + `ToUpper` and `ToLower` change the letter case of the input string. + `ToBase64` and `FromBase64` perform a base64 conversion based on the input string. + `ToJson` converts any input value into its raw JSON representation. + `ToSha1`, `ToSha256` and `ToSha512` generate a hash value based on the input + converted to JSON. enum: - ToUpper - ToLower @@ -266,8 +291,9 @@ spec: - ToSha512 type: string fmt: - description: Format the input using a Go format string. - See https://golang.org/pkg/fmt/ for details. + description: |- + Format the input using a Go format string. See + https://golang.org/pkg/fmt/ for details. type: string regexp: description: Extract a match from the input using @@ -278,9 +304,9 @@ spec: matches the entire expression. type: integer match: - description: Match string. May optionally include - submatches, aka capture groups. See https://pkg.go.dev/regexp/ - for details. + description: |- + Match string. May optionally include submatches, aka capture groups. + See https://pkg.go.dev/regexp/ for details. type: string required: - match @@ -314,9 +340,9 @@ spec: type: array type: default: FromCompositeFieldPath - description: Type sets the patching behaviour to be used. Each - patch type may require its own fields to be set on the Patch - object. + description: |- + Type sets the patching behaviour to be used. Each patch type may require + its own fields to be set on the Patch object. enum: - FromCompositeFieldPath - ToCompositeFieldPath @@ -327,15 +353,19 @@ spec: type: array type: object kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object patchSets: - description: PatchSets define a named set of patches that may be included - by any resource. PatchSets cannot themselves refer to other PatchSets. + description: |- + PatchSets define a named set of patches that may be included by any + resource. PatchSets cannot themselves refer to other PatchSets. items: description: A PatchSet is a set of patches that can be reused from all resources. @@ -346,44 +376,49 @@ spec: patches: description: Patches will be applied as an overlay to the base resource. items: - description: PatchSetPatch defines a set of Patches that can be - referenced by name by other patches of type PatchSet. + description: |- + PatchSetPatch defines a set of Patches that can be referenced by name by + other patches of type PatchSet. properties: combine: - description: Combine is the patch configuration for a CombineFromComposite, + description: |- + Combine is the patch configuration for a CombineFromComposite, CombineToComposite patch. properties: strategy: - description: Strategy defines the strategy to use to combine - the input variable values. Currently only string is - supported. + description: |- + Strategy defines the strategy to use to combine the input variable values. + Currently only string is supported. enum: - string type: string string: - description: String declares that input variables should - be combined into a single string, using the relevant - settings for formatting purposes. + description: |- + String declares that input variables should be combined into a single + string, using the relevant settings for formatting purposes. properties: fmt: - description: Format the input using a Go format string. - See https://golang.org/pkg/fmt/ for details. + description: |- + Format the input using a Go format string. See + https://golang.org/pkg/fmt/ for details. type: string required: - fmt type: object variables: - description: Variables are the list of variables whose - values will be retrieved and combined. + description: |- + Variables are the list of variables whose values will be retrieved and + combined. items: - description: A CombineVariable defines the source of - a value that is combined with others to form and patch - an output value. Currently, this only supports retrieving - values from a field path. + description: |- + A CombineVariable defines the source of a value that is combined with + others to form and patch an output value. Currently, this only supports + retrieving values from a field path. properties: fromFieldPath: - description: FromFieldPath is the path of the field - on the source whose value is to be used as input. + description: |- + FromFieldPath is the path of the field on the source whose value is + to be used as input. type: string required: - fromFieldPath @@ -395,49 +430,56 @@ spec: - variables type: object fromFieldPath: - description: FromFieldPath is the path of the field on the - resource whose value is to be used as input. Required when - type is FromCompositeFieldPath or ToCompositeFieldPath. + description: |- + FromFieldPath is the path of the field on the resource whose value is + to be used as input. Required when type is FromCompositeFieldPath or + ToCompositeFieldPath. type: string policy: description: Policy configures the specifics of patching behaviour. properties: fromFieldPath: - description: FromFieldPath specifies how to patch from - a field path. The default is 'Optional', which means - the patch will be a no-op if the specified fromFieldPath - does not exist. Use 'Required' if the patch should fail - if the specified path does not exist. + description: |- + FromFieldPath specifies how to patch from a field path. The default is + 'Optional', which means the patch will be a no-op if the specified + fromFieldPath does not exist. Use 'Required' to prevent the creation of a + new composed resource until the required path exists. enum: - Optional - Required type: string type: object toFieldPath: - description: ToFieldPath is the path of the field on the resource - whose value will be changed with the result of transforms. - Leave empty if you'd like to propagate to the same path - as fromFieldPath. + description: |- + ToFieldPath is the path of the field on the resource whose value will + be changed with the result of transforms. Leave empty if you'd like to + propagate to the same path as fromFieldPath. type: string transforms: - description: Transforms are the list of functions that are - used as a FIFO pipe for the input to be transformed. + description: |- + Transforms are the list of functions that are used as a FIFO pipe for the + input to be transformed. items: - description: Transform is a unit of process whose input - is transformed into an output with the supplied configuration. + description: |- + Transform is a unit of process whose input is transformed into an output with + the supplied configuration. properties: convert: description: Convert is used to cast the input into the given output type. properties: format: - description: "The expected input format. \n * `quantity` - - parses the input as a K8s [`resource.Quantity`](https://pkg.go.dev/k8s.io/apimachinery/pkg/api/resource#Quantity). + description: |- + The expected input format. + + + * `quantity` - parses the input as a K8s [`resource.Quantity`](https://pkg.go.dev/k8s.io/apimachinery/pkg/api/resource#Quantity). Only used during `string -> float64` conversions. * `json` - parses the input as a JSON string. - Only used during `string -> object` or `string - -> list` conversions. \n If this property is null, - the default conversion is applied." + Only used during `string -> object` or `string -> list` conversions. + + + If this property is null, the default conversion is applied. enum: - none - quantity @@ -477,26 +519,29 @@ spec: - Input type: string fallbackValue: - description: The fallback value that should be returned - by the transform if now pattern matches. + description: |- + The fallback value that should be returned by the transform if now pattern + matches. x-kubernetes-preserve-unknown-fields: true patterns: - description: The patterns that should be tested - against the input string. Patterns are tested - in order. The value of the first match is used - as result of this transform. + description: |- + The patterns that should be tested against the input string. + Patterns are tested in order. The value of the first match is used as + result of this transform. items: - description: MatchTransformPattern is a transform - that returns the value that matches a pattern. + description: |- + MatchTransformPattern is a transform that returns the value that matches a + pattern. properties: literal: - description: Literal exactly matches the input - string (case sensitive). Is required if - `type` is `literal`. + description: |- + Literal exactly matches the input string (case sensitive). + Is required if `type` is `literal`. type: string regexp: - description: Regexp to match against the input - string. Is required if `type` is `regexp`. + description: |- + Regexp to match against the input string. + Is required if `type` is `regexp`. type: string result: description: The value that is used as result @@ -504,15 +549,17 @@ spec: x-kubernetes-preserve-unknown-fields: true type: default: literal - description: "Type specifies how the pattern - matches the input. \n * `literal` - the - pattern value has to exactly match (case - sensitive) the input string. This is the - default. \n * `regexp` - the pattern treated - as a regular expression against which the - input string is tested. Crossplane will - throw an error if the key is not a valid - regexp." + description: |- + Type specifies how the pattern matches the input. + + + * `literal` - the pattern value has to exactly match (case sensitive) the + input string. This is the default. + + + * `regexp` - the pattern treated as a regular expression against + which the input string is tested. Crossplane will throw an error if the + key is not a valid regexp. enum: - literal - regexp @@ -524,8 +571,9 @@ spec: type: array type: object math: - description: Math is used to transform the input via - mathematical operations such as multiplication. + description: |- + Math is used to transform the input via mathematical operations such as + multiplication. properties: clampMax: description: ClampMax makes sure that the value @@ -551,19 +599,18 @@ spec: type: string type: object string: - description: String is used to transform the input into - a string or a different kind of string. Note that - the input does not necessarily need to be a string. + description: |- + String is used to transform the input into a string or a different kind + of string. Note that the input does not necessarily need to be a string. properties: convert: - description: Optional conversion method to be specified. - `ToUpper` and `ToLower` change the letter case - of the input string. `ToBase64` and `FromBase64` - perform a base64 conversion based on the input - string. `ToJson` converts any input value into - its raw JSON representation. `ToSha1`, `ToSha256` - and `ToSha512` generate a hash value based on - the input converted to JSON. + description: |- + Optional conversion method to be specified. + `ToUpper` and `ToLower` change the letter case of the input string. + `ToBase64` and `FromBase64` perform a base64 conversion based on the input string. + `ToJson` converts any input value into its raw JSON representation. + `ToSha1`, `ToSha256` and `ToSha512` generate a hash value based on the input + converted to JSON. enum: - ToUpper - ToLower @@ -575,8 +622,9 @@ spec: - ToSha512 type: string fmt: - description: Format the input using a Go format - string. See https://golang.org/pkg/fmt/ for details. + description: |- + Format the input using a Go format string. See + https://golang.org/pkg/fmt/ for details. type: string regexp: description: Extract a match from the input using @@ -587,9 +635,9 @@ spec: matches the entire expression. type: integer match: - description: Match string. May optionally include - submatches, aka capture groups. See https://pkg.go.dev/regexp/ - for details. + description: |- + Match string. May optionally include submatches, aka capture groups. + See https://pkg.go.dev/regexp/ for details. type: string required: - match @@ -625,9 +673,9 @@ spec: type: array type: default: FromCompositeFieldPath - description: Type sets the patching behaviour to be used. - Each patch type may require its own fields to be set on - the ComposedPatch object. + description: |- + Type sets the patching behaviour to be used. Each patch type may require + its own fields to be set on the ComposedPatch object. enum: - FromCompositeFieldPath - ToCompositeFieldPath @@ -646,59 +694,64 @@ spec: type: object type: array resources: - description: Resources is a list of resource templates that will be used - when a composite resource is created. + description: |- + Resources is a list of resource templates that will be used when a + composite resource is created. items: - description: ComposedTemplate is used to provide information about how - the composed resource should be processed. + description: |- + ComposedTemplate is used to provide information about how the composed + resource should be processed. properties: base: - description: Base of the composed resource that patches will be - applied to and from. If base is omitted, a previous Function within - the pipeline must have produced the named composed resource. Patches - will be applied to and from that resource. If base is specified, - and a previous Function within the pipeline produced the name - composed resource, it will be overwritten. + description: |- + Base of the composed resource that patches will be applied to and from. + If base is omitted, a previous Function within the pipeline must have + produced the named composed resource. Patches will be applied to and from + that resource. If base is specified, and a previous Function within the + pipeline produced the name composed resource, it will be overwritten. type: object x-kubernetes-embedded-resource: true x-kubernetes-preserve-unknown-fields: true connectionDetails: - description: ConnectionDetails lists the propagation secret keys - from this composed resource to the composition instance connection - secret. + description: |- + ConnectionDetails lists the propagation secret keys from this composed + resource to the composition instance connection secret. items: - description: ConnectionDetail includes the information about the - propagation of the connection information from one secret to - another. + description: |- + ConnectionDetail includes the information about the propagation of the connection + information from one secret to another. properties: fromConnectionSecretKey: - description: FromConnectionSecretKey is the key that will - be used to fetch the value from the composed resource's - connection secret. + description: |- + FromConnectionSecretKey is the key that will be used to fetch the value + from the composed resource's connection secret. type: string fromFieldPath: - description: FromFieldPath is the path of the field on the - composed resource whose value to be used as input. Name - must be specified if the type is FromFieldPath. + description: |- + FromFieldPath is the path of the field on the composed resource whose + value to be used as input. Name must be specified if the type is + FromFieldPath. type: string name: - description: Name of the connection secret key that will be - propagated to the connection secret of the composed resource. + description: |- + Name of the connection secret key that will be propagated to the + connection secret of the composed resource. type: string type: - description: Type sets the connection detail fetching behavior - to be used. Each connection detail type may require its - own fields to be set on the ConnectionDetail object. + description: |- + Type sets the connection detail fetching behavior to be used. Each + connection detail type may require its own fields to be set on the + ConnectionDetail object. enum: - FromConnectionSecretKey - FromFieldPath - FromValue type: string value: - description: Value that will be propagated to the connection - secret of the composite resource. May be set to inject a - fixed, non-sensitive connection secret value, for example - a well-known port. + description: |- + Value that will be propagated to the connection secret of the composite + resource. May be set to inject a fixed, non-sensitive connection secret + value, for example a well-known port. type: string required: - name @@ -712,47 +765,51 @@ spec: patches: description: Patches to and from the composed resource. items: - description: ComposedPatch objects are applied between composite - and composed resources. Their behaviour depends on the Type - selected. The default Type, FromCompositeFieldPath, copies a - value from the composite resource to the composed resource, - applying any defined transformers. + description: |- + ComposedPatch objects are applied between composite and composed resources. + Their behaviour depends on the Type selected. The default Type, + FromCompositeFieldPath, copies a value from the composite resource to the + composed resource, applying any defined transformers. properties: combine: - description: Combine is the patch configuration for a CombineFromComposite, + description: |- + Combine is the patch configuration for a CombineFromComposite, CombineToComposite patch. properties: strategy: - description: Strategy defines the strategy to use to combine - the input variable values. Currently only string is - supported. + description: |- + Strategy defines the strategy to use to combine the input variable values. + Currently only string is supported. enum: - string type: string string: - description: String declares that input variables should - be combined into a single string, using the relevant - settings for formatting purposes. + description: |- + String declares that input variables should be combined into a single + string, using the relevant settings for formatting purposes. properties: fmt: - description: Format the input using a Go format string. - See https://golang.org/pkg/fmt/ for details. + description: |- + Format the input using a Go format string. See + https://golang.org/pkg/fmt/ for details. type: string required: - fmt type: object variables: - description: Variables are the list of variables whose - values will be retrieved and combined. + description: |- + Variables are the list of variables whose values will be retrieved and + combined. items: - description: A CombineVariable defines the source of - a value that is combined with others to form and patch - an output value. Currently, this only supports retrieving - values from a field path. + description: |- + A CombineVariable defines the source of a value that is combined with + others to form and patch an output value. Currently, this only supports + retrieving values from a field path. properties: fromFieldPath: - description: FromFieldPath is the path of the field - on the source whose value is to be used as input. + description: |- + FromFieldPath is the path of the field on the source whose value is + to be used as input. type: string required: - fromFieldPath @@ -764,9 +821,10 @@ spec: - variables type: object fromFieldPath: - description: FromFieldPath is the path of the field on the - resource whose value is to be used as input. Required when - type is FromCompositeFieldPath or ToCompositeFieldPath. + description: |- + FromFieldPath is the path of the field on the resource whose value is + to be used as input. Required when type is FromCompositeFieldPath or + ToCompositeFieldPath. type: string patchSetName: description: PatchSetName to include patches from. Required @@ -776,41 +834,47 @@ spec: description: Policy configures the specifics of patching behaviour. properties: fromFieldPath: - description: FromFieldPath specifies how to patch from - a field path. The default is 'Optional', which means - the patch will be a no-op if the specified fromFieldPath - does not exist. Use 'Required' if the patch should fail - if the specified path does not exist. + description: |- + FromFieldPath specifies how to patch from a field path. The default is + 'Optional', which means the patch will be a no-op if the specified + fromFieldPath does not exist. Use 'Required' to prevent the creation of a + new composed resource until the required path exists. enum: - Optional - Required type: string type: object toFieldPath: - description: ToFieldPath is the path of the field on the resource - whose value will be changed with the result of transforms. - Leave empty if you'd like to propagate to the same path - as fromFieldPath. + description: |- + ToFieldPath is the path of the field on the resource whose value will + be changed with the result of transforms. Leave empty if you'd like to + propagate to the same path as fromFieldPath. type: string transforms: - description: Transforms are the list of functions that are - used as a FIFO pipe for the input to be transformed. + description: |- + Transforms are the list of functions that are used as a FIFO pipe for the + input to be transformed. items: - description: Transform is a unit of process whose input - is transformed into an output with the supplied configuration. + description: |- + Transform is a unit of process whose input is transformed into an output with + the supplied configuration. properties: convert: description: Convert is used to cast the input into the given output type. properties: format: - description: "The expected input format. \n * `quantity` - - parses the input as a K8s [`resource.Quantity`](https://pkg.go.dev/k8s.io/apimachinery/pkg/api/resource#Quantity). + description: |- + The expected input format. + + + * `quantity` - parses the input as a K8s [`resource.Quantity`](https://pkg.go.dev/k8s.io/apimachinery/pkg/api/resource#Quantity). Only used during `string -> float64` conversions. * `json` - parses the input as a JSON string. - Only used during `string -> object` or `string - -> list` conversions. \n If this property is null, - the default conversion is applied." + Only used during `string -> object` or `string -> list` conversions. + + + If this property is null, the default conversion is applied. enum: - none - quantity @@ -850,26 +914,29 @@ spec: - Input type: string fallbackValue: - description: The fallback value that should be returned - by the transform if now pattern matches. + description: |- + The fallback value that should be returned by the transform if now pattern + matches. x-kubernetes-preserve-unknown-fields: true patterns: - description: The patterns that should be tested - against the input string. Patterns are tested - in order. The value of the first match is used - as result of this transform. + description: |- + The patterns that should be tested against the input string. + Patterns are tested in order. The value of the first match is used as + result of this transform. items: - description: MatchTransformPattern is a transform - that returns the value that matches a pattern. + description: |- + MatchTransformPattern is a transform that returns the value that matches a + pattern. properties: literal: - description: Literal exactly matches the input - string (case sensitive). Is required if - `type` is `literal`. + description: |- + Literal exactly matches the input string (case sensitive). + Is required if `type` is `literal`. type: string regexp: - description: Regexp to match against the input - string. Is required if `type` is `regexp`. + description: |- + Regexp to match against the input string. + Is required if `type` is `regexp`. type: string result: description: The value that is used as result @@ -877,15 +944,17 @@ spec: x-kubernetes-preserve-unknown-fields: true type: default: literal - description: "Type specifies how the pattern - matches the input. \n * `literal` - the - pattern value has to exactly match (case - sensitive) the input string. This is the - default. \n * `regexp` - the pattern treated - as a regular expression against which the - input string is tested. Crossplane will - throw an error if the key is not a valid - regexp." + description: |- + Type specifies how the pattern matches the input. + + + * `literal` - the pattern value has to exactly match (case sensitive) the + input string. This is the default. + + + * `regexp` - the pattern treated as a regular expression against + which the input string is tested. Crossplane will throw an error if the + key is not a valid regexp. enum: - literal - regexp @@ -897,8 +966,9 @@ spec: type: array type: object math: - description: Math is used to transform the input via - mathematical operations such as multiplication. + description: |- + Math is used to transform the input via mathematical operations such as + multiplication. properties: clampMax: description: ClampMax makes sure that the value @@ -924,19 +994,18 @@ spec: type: string type: object string: - description: String is used to transform the input into - a string or a different kind of string. Note that - the input does not necessarily need to be a string. + description: |- + String is used to transform the input into a string or a different kind + of string. Note that the input does not necessarily need to be a string. properties: convert: - description: Optional conversion method to be specified. - `ToUpper` and `ToLower` change the letter case - of the input string. `ToBase64` and `FromBase64` - perform a base64 conversion based on the input - string. `ToJson` converts any input value into - its raw JSON representation. `ToSha1`, `ToSha256` - and `ToSha512` generate a hash value based on - the input converted to JSON. + description: |- + Optional conversion method to be specified. + `ToUpper` and `ToLower` change the letter case of the input string. + `ToBase64` and `FromBase64` perform a base64 conversion based on the input string. + `ToJson` converts any input value into its raw JSON representation. + `ToSha1`, `ToSha256` and `ToSha512` generate a hash value based on the input + converted to JSON. enum: - ToUpper - ToLower @@ -948,8 +1017,9 @@ spec: - ToSha512 type: string fmt: - description: Format the input using a Go format - string. See https://golang.org/pkg/fmt/ for details. + description: |- + Format the input using a Go format string. See + https://golang.org/pkg/fmt/ for details. type: string regexp: description: Extract a match from the input using @@ -960,9 +1030,9 @@ spec: matches the entire expression. type: integer match: - description: Match string. May optionally include - submatches, aka capture groups. See https://pkg.go.dev/regexp/ - for details. + description: |- + Match string. May optionally include submatches, aka capture groups. + See https://pkg.go.dev/regexp/ for details. type: string required: - match @@ -998,9 +1068,9 @@ spec: type: array type: default: FromCompositeFieldPath - description: Type sets the patching behaviour to be used. - Each patch type may require its own fields to be set on - the ComposedPatch object. + description: |- + Type sets the patching behaviour to be used. Each patch type may require + its own fields to be set on the ComposedPatch object. enum: - FromCompositeFieldPath - PatchSet @@ -1020,13 +1090,15 @@ spec: status: "True" type: Ready type: MatchCondition - description: ReadinessChecks allows users to define custom readiness - checks. All checks have to return true in order for resource to - be considered ready. The default readiness check is to have the - "Ready" condition to be "True". + description: |- + ReadinessChecks allows users to define custom readiness checks. All + checks have to return true in order for resource to be considered ready. + The default readiness check is to have the "Ready" condition to be + "True". items: - description: ReadinessCheck is used to indicate how to tell whether - a resource is ready for consumption + description: |- + ReadinessCheck is used to indicate how to tell whether a resource is ready + for consumption properties: fieldPath: description: FieldPath shows the path of the field whose value From c8bd5a1ba00ec07a53eef65dd6d4ec4ae1ce0273 Mon Sep 17 00:00:00 2001 From: Nic Cope Date: Tue, 23 Jan 2024 17:14:04 -0800 Subject: [PATCH 18/31] Test handling of FieldPathNotFound errors Signed-off-by: Nic Cope --- fn_test.go | 170 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 156 insertions(+), 14 deletions(-) diff --git a/fn_test.go b/fn_test.go index 15e85f8..85c3af7 100644 --- a/fn_test.go +++ b/fn_test.go @@ -384,17 +384,15 @@ func TestRunFunction(t *testing.T) { }, }, }, - "FailedPatchNotSaved": { - reason: "If we fail to patch a desired resource produced by a previous Function in the pipeline we should return a fatal result.", + "OptionalFieldPathNotFound": { + reason: "If we fail to patch a desired resource because an optional field path was not found we should skip the patch.", args: args{ req: &fnv1beta1.RunFunctionRequest{ Input: resource.MustStructObject(&v1beta1.Resources{ Resources: []v1beta1.ComposedTemplate{ { - // This template base no base, so we try to - // patch the resource named "cool-resource" in - // the desired resources array. Name: "cool-resource", + Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD","spec":{}}`)}, Patches: []v1beta1.ComposedPatch{ { // This patch should work. @@ -405,11 +403,11 @@ func TestRunFunction(t *testing.T) { }, }, { - // This patch should return an error, - // because the path is not an array. + // This patch should be skipped, because + // the path is not found Type: v1beta1.PatchTypeFromCompositeFieldPath, Patch: v1beta1.Patch{ - FromFieldPath: ptr.To[string]("spec.widgets[0]"), + FromFieldPath: ptr.To[string]("spec.doesNotExist"), }, }, }, @@ -421,16 +419,94 @@ func TestRunFunction(t *testing.T) { Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"XR","spec":{"widgets":"10"}}`), }, }, + }, + }, + want: want{ + rsp: &fnv1beta1.RunFunctionResponse{ + Meta: &fnv1beta1.ResponseMeta{Ttl: durationpb.New(response.DefaultTTL)}, Desired: &fnv1beta1.State{ Composite: &fnv1beta1.Resource{ - Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"XR","spec":{"widgets":"10"}}`), + Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"XR"}`), }, Resources: map[string]*fnv1beta1.Resource{ "cool-resource": { - Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","spec":{"watchers":42}}`), + // Watchers becomes "10" because our first patch + // worked. We only skipped the second patch. + Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","spec":{"watchers":"10"}}`), }, }, }, + Context: &structpb.Struct{Fields: map[string]*structpb.Value{fncontext.KeyEnvironment: structpb.NewStructValue(nil)}}, + }, + }, + }, + "RequiredFieldPathNotFound": { + reason: "If we fail to patch a desired resource because a required field path was not found, and the resource doesn't exist, we should not add it to desired state (i.e. create it).", + args: args{ + req: &fnv1beta1.RunFunctionRequest{ + Input: resource.MustStructObject(&v1beta1.Resources{ + Resources: []v1beta1.ComposedTemplate{ + { + Name: "new-resource", + Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD","spec":{}}`)}, + Patches: []v1beta1.ComposedPatch{ + { + // This patch will fail because the path + // is not found. + Type: v1beta1.PatchTypeFromCompositeFieldPath, + Patch: v1beta1.Patch{ + FromFieldPath: ptr.To[string]("spec.doesNotExist"), + Policy: &v1beta1.PatchPolicy{ + FromFieldPath: ptr.To[v1beta1.FromFieldPathPolicy](v1beta1.FromFieldPathPolicyRequired), + }, + }, + }, + }, + }, + { + Name: "existing-resource", + Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD","spec":{}}`)}, + Patches: []v1beta1.ComposedPatch{ + { + // This patch should work. + Type: v1beta1.PatchTypeFromCompositeFieldPath, + Patch: v1beta1.Patch{ + FromFieldPath: ptr.To[string]("spec.widgets"), + ToFieldPath: ptr.To[string]("spec.watchers"), + }, + }, + { + // This patch will fail because the path + // is not found. + Type: v1beta1.PatchTypeFromCompositeFieldPath, + Patch: v1beta1.Patch{ + FromFieldPath: ptr.To[string]("spec.doesNotExist"), + Policy: &v1beta1.PatchPolicy{ + FromFieldPath: ptr.To[v1beta1.FromFieldPathPolicy](v1beta1.FromFieldPathPolicyRequired), + }, + }, + }, + }, + }, + }, + }), + Observed: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"XR","spec":{"widgets":"10"}}`), + }, + Resources: map[string]*fnv1beta1.Resource{ + // "existing-resource" exists. + "existing-resource": {}, + + // Note "new-resource" doesn't appear in the + // observed resources. It doesn't yet exist. + }, + }, + Desired: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"XR","spec":{"widgets":"10"}}`), + }, + }, }, }, want: want{ @@ -441,11 +517,77 @@ func TestRunFunction(t *testing.T) { Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"XR","spec":{"widgets":"10"}}`), }, Resources: map[string]*fnv1beta1.Resource{ - "cool-resource": { - // spec.watchers would be "10" if we didn't - // discard the patch that worked. - Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","spec":{"watchers":42}}`), + // Note that the first patch did work. We only + // skipped the patch from the required field path. + "existing-resource": { + Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","spec":{"watchers":"10"}}`), }, + + // Note "new-resource" doesn't appear here. + }, + }, + Context: &structpb.Struct{Fields: map[string]*structpb.Value{fncontext.KeyEnvironment: structpb.NewStructValue(nil)}}, + Results: []*fnv1beta1.Result{ + { + Severity: fnv1beta1.Severity_SEVERITY_WARNING, + Message: `not adding new composed resource "new-resource" to desired state because "FromCompositeFieldPath" patch at index 0 has 'policy.fromFieldPath: Required': spec.doesNotExist: no such field`, + }, + { + Severity: fnv1beta1.Severity_SEVERITY_WARNING, + Message: `cannot render composed resource "existing-resource" "FromCompositeFieldPath" patch at index 1: ignoring 'policy.fromFieldPath: Required' because 'to' resource already exists: spec.doesNotExist: no such field`, + }, + }, + }, + }, + }, + "PatchErrorIsFatal": { + reason: "If we fail to patch a desired resource we should return a fatal result.", + args: args{ + req: &fnv1beta1.RunFunctionRequest{ + Input: resource.MustStructObject(&v1beta1.Resources{ + Resources: []v1beta1.ComposedTemplate{ + { + Name: "cool-resource", + Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD","spec":{}}`)}, + Patches: []v1beta1.ComposedPatch{ + { + // This patch should work. + Type: v1beta1.PatchTypeFromCompositeFieldPath, + Patch: v1beta1.Patch{ + FromFieldPath: ptr.To[string]("spec.widgets"), + ToFieldPath: ptr.To[string]("spec.watchers"), + }, + }, + { + // This patch should return an error, + // because the path is not an array. + Type: v1beta1.PatchTypeFromCompositeFieldPath, + Patch: v1beta1.Patch{ + FromFieldPath: ptr.To[string]("spec.widgets[0]"), + }, + }, + }, + }, + }, + }), + Observed: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"XR","spec":{"widgets":"10"}}`), + }, + }, + Desired: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"XR","spec":{"widgets":"10"}}`), + }, + }, + }, + }, + want: want{ + rsp: &fnv1beta1.RunFunctionResponse{ + Meta: &fnv1beta1.ResponseMeta{Ttl: durationpb.New(response.DefaultTTL)}, + Desired: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"XR","spec":{"widgets":"10"}}`), }, }, Results: []*fnv1beta1.Result{ From a7c2fe84b62a8dfebdce27cfe1f82458bd1d7458 Mon Sep 17 00:00:00 2001 From: Nic Cope Date: Tue, 23 Jan 2024 17:39:01 -0800 Subject: [PATCH 19/31] Fix broken example This was not actually doing any patching - it was skipping the optional field path patch and relying on the bucket already having a region set in its base. Signed-off-by: Nic Cope --- example/composition.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/example/composition.yaml b/example/composition.yaml index 2c73250..f2b6d4b 100644 --- a/example/composition.yaml +++ b/example/composition.yaml @@ -19,12 +19,9 @@ spec: base: apiVersion: s3.aws.upbound.io/v1beta1 kind: Bucket - spec: - forProvider: - region: us-east-2 patches: - type: FromCompositeFieldPath - fromFieldPath: "location" + fromFieldPath: "spec.location" toFieldPath: "spec.forProvider.region" transforms: - type: map From e8c859d3599d6dc9995bab7e2512312c73425baa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 16:26:03 +0000 Subject: [PATCH 20/31] fix(deps): update module github.com/crossplane/crossplane-runtime to v1.14.4 --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index aa136fc..133e3d7 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.21.3 require ( github.com/alecthomas/kong v0.8.1 - github.com/crossplane/crossplane-runtime v1.14.3 + github.com/crossplane/crossplane-runtime v1.14.4 github.com/crossplane/function-sdk-go v0.1.0 github.com/google/go-cmp v0.6.0 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index a5332f7..916ef00 100644 --- a/go.sum +++ b/go.sum @@ -74,6 +74,8 @@ github.com/crossplane/crossplane-runtime v1.14.2 h1:pV5JMzyzi/kcbeVBVPCat5MHH8zS github.com/crossplane/crossplane-runtime v1.14.2/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o= github.com/crossplane/crossplane-runtime v1.14.3 h1:YNGALph/UJTtQO+cJ9KGQ5NfALI5453PeE93Aqy9SWg= github.com/crossplane/crossplane-runtime v1.14.3/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o= +github.com/crossplane/crossplane-runtime v1.14.4 h1:64zSZ75g1QXIMxR2zSQvz4+TTSq5qCUU5lmpiVovVKE= +github.com/crossplane/crossplane-runtime v1.14.4/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o= github.com/crossplane/function-sdk-go v0.1.0 h1:WN3CUSaj6wgDqQPZZP1whMVIkTAZtN3HVCS67pTMzd8= github.com/crossplane/function-sdk-go v0.1.0/go.mod h1:oRqHZ6RufpfZJ1N8aT4EfkP+5KpkhOKpWz7SeUDwwcw= github.com/crossplane/upjet v0.11.0-rc.0.0.20231012093706-c4a76d2a7505 h1:eCmYgfRopVn6r8RM1Ra4XQAPwVsjTGfktBj2Dk7yy+Y= From e2d77c237304a68a576b5f7b23c9bb733a54937e Mon Sep 17 00:00:00 2001 From: Nic Cope Date: Fri, 9 Feb 2024 04:25:31 -0800 Subject: [PATCH 21/31] Remove RenderJSON function This function was copied from c/c but isn't needed here. RenderJSON tried to preserve metadata of the passed object (e.g. name and namespace), and checked that its GVK didn't change. In practice in this function the passed object will always be new and empty so we can just use json.Marshal directly. Signed-off-by: Nic Cope --- fn.go | 3 +- render.go | 49 --------------------- render_test.go | 117 ------------------------------------------------- 3 files changed, 2 insertions(+), 167 deletions(-) delete mode 100644 render.go delete mode 100644 render_test.go diff --git a/fn.go b/fn.go index 0be03e2..6dc9e4b 100644 --- a/fn.go +++ b/fn.go @@ -5,6 +5,7 @@ import ( "google.golang.org/protobuf/types/known/structpb" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/util/json" "github.com/crossplane/crossplane-runtime/pkg/errors" "github.com/crossplane/crossplane-runtime/pkg/fieldpath" @@ -154,7 +155,7 @@ func (f *Function) RunFunction(ctx context.Context, req *fnv1beta1.RunFunctionRe // We want to return this resource unmutated if rendering fails. dcd.Resource = cd.Resource.DeepCopy() default: - if err := RenderFromJSON(dcd.Resource, t.Base.Raw); err != nil { + if err := json.Unmarshal(t.Base.Raw, dcd.Resource); err != nil { response.Fatal(rsp, errors.Wrapf(err, "cannot parse base template of composed resource %q", t.Name)) return rsp, nil } diff --git a/render.go b/render.go deleted file mode 100644 index ec9f640..0000000 --- a/render.go +++ /dev/null @@ -1,49 +0,0 @@ -package main - -import ( - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/json" - - "github.com/crossplane/crossplane-runtime/pkg/errors" - "github.com/crossplane/crossplane-runtime/pkg/resource" -) - -// Error strings -const ( - errUnmarshalJSON = "cannot unmarshal JSON data" - - errFmtKindChanged = "cannot change the kind of a composed resource from %s to %s (possible composed resource template mismatch)" -) - -// RenderFromJSON renders the supplied resource from JSON bytes. -func RenderFromJSON(o resource.Object, data []byte) error { - gvk := o.GetObjectKind().GroupVersionKind() - name := o.GetName() - namespace := o.GetNamespace() - - if err := json.Unmarshal(data, o); err != nil { - return errors.Wrap(err, errUnmarshalJSON) - } - - // TODO(negz): Should we return an error if the name or namespace change, - // rather than just silently re-setting it? Presumably these _changing_ is a - // sign that something has gone wrong, similar to the GVK changing. What - // about the UID changing? - - // Unmarshalling the template will overwrite any existing fields, so we must - // restore the existing name, if any. - o.SetName(name) - o.SetNamespace(namespace) - - // This resource already had a GVK (probably because it already exists), but - // when we rendered its template it changed. This shouldn't happen. Either - // someone changed the kind in the template or we're trying to use the wrong - // template (e.g. because the order of an array of anonymous templates - // changed). - empty := schema.GroupVersionKind{} - if gvk != empty && o.GetObjectKind().GroupVersionKind() != gvk { - return errors.Errorf(errFmtKindChanged, gvk, o.GetObjectKind().GroupVersionKind()) - } - - return nil -} diff --git a/render_test.go b/render_test.go deleted file mode 100644 index 8de503a..0000000 --- a/render_test.go +++ /dev/null @@ -1,117 +0,0 @@ -package main - -import ( - "encoding/json" - "testing" - - "github.com/google/go-cmp/cmp" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - - "github.com/crossplane/crossplane-runtime/pkg/errors" - "github.com/crossplane/crossplane-runtime/pkg/resource" - "github.com/crossplane/crossplane-runtime/pkg/resource/fake" - "github.com/crossplane/crossplane-runtime/pkg/resource/unstructured/composed" - "github.com/crossplane/crossplane-runtime/pkg/test" -) - -func TestRenderFromJSON(t *testing.T) { - errInvalidChar := json.Unmarshal([]byte("olala"), &fake.Composed{}) - - type args struct { - o resource.Object - data []byte - } - type want struct { - o resource.Object - err error - } - cases := map[string]struct { - reason string - args - want - }{ - "InvalidData": { - reason: "We should return an error if the data can't be unmarshalled", - args: args{ - o: &fake.Composed{}, - data: []byte("olala"), - }, - want: want{ - o: &fake.Composed{}, - err: errors.Wrap(errInvalidChar, errUnmarshalJSON), - }, - }, - "ExistingGVKChanged": { - reason: "We should return an error if unmarshalling the base template changed the composed resource's group, version, or kind", - args: args{ - o: composed.New(composed.FromReference(corev1.ObjectReference{ - APIVersion: "example.org/v1", - Kind: "Potato", - })), - data: []byte(`{"apiVersion": "example.org/v1", "kind": "Different"}`), - }, - want: want{ - o: composed.New(composed.FromReference(corev1.ObjectReference{ - APIVersion: "example.org/v1", - Kind: "Different", - })), - err: errors.Errorf(errFmtKindChanged, "example.org/v1, Kind=Potato", "example.org/v1, Kind=Different"), - }, - }, - "NewComposedResource": { - reason: "A valid base template should apply successfully to a new (empty) composed resource", - args: args{ - o: composed.New(), - data: []byte(`{"apiVersion": "example.org/v1", "kind": "Potato", "spec": {"cool": true}}`), - }, - want: want{ - o: &composed.Unstructured{Unstructured: unstructured.Unstructured{ - Object: map[string]any{ - "apiVersion": "example.org/v1", - "kind": "Potato", - "spec": map[string]any{ - "cool": true, - }, - }, - }}, - }, - }, - "ExistingComposedResource": { - reason: "A valid base template should apply successfully to a new (empty) composed resource", - args: args{ - o: composed.New(composed.FromReference(corev1.ObjectReference{ - APIVersion: "example.org/v1", - Kind: "Potato", - Name: "ola-superrandom", - })), - data: []byte(`{"apiVersion": "example.org/v1", "kind": "Potato", "spec": {"cool": true}}`), - }, - want: want{ - o: &composed.Unstructured{Unstructured: unstructured.Unstructured{ - Object: map[string]any{ - "apiVersion": "example.org/v1", - "kind": "Potato", - "metadata": map[string]any{ - "name": "ola-superrandom", - }, - "spec": map[string]any{ - "cool": true, - }, - }, - }}, - }, - }, - } - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - err := RenderFromJSON(tc.args.o, tc.args.data) - if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" { - t.Errorf("\n%s\nRenderFromJSON(...): -want error, +got error:\n%s", tc.reason, diff) - } - if diff := cmp.Diff(tc.want.o, tc.args.o); diff != "" { - t.Errorf("\n%s\nRenderFromJSON(...): -want, +got:\n%s", tc.reason, diff) - } - }) - } -} From defe62c45a59e1505fec7f1dc0282aa704e2122a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 00:52:42 +0000 Subject: [PATCH 22/31] fix(deps): update kubernetes packages to v0.29.2 --- go.mod | 10 +++++----- go.sum | 10 ++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 00a910c..eb6dbe7 100644 --- a/go.mod +++ b/go.mod @@ -11,9 +11,9 @@ require ( github.com/google/go-cmp v0.6.0 github.com/pkg/errors v0.9.1 google.golang.org/protobuf v1.32.0 - k8s.io/api v0.29.1 - k8s.io/apiextensions-apiserver v0.29.1 - k8s.io/apimachinery v0.29.1 + k8s.io/api v0.29.2 + k8s.io/apiextensions-apiserver v0.29.2 + k8s.io/apimachinery v0.29.2 k8s.io/utils v0.0.0-20240102154912-e7106e64919e sigs.k8s.io/controller-tools v0.14.0 ) @@ -75,8 +75,8 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/client-go v0.29.1 // indirect - k8s.io/component-base v0.29.1 // indirect + k8s.io/client-go v0.29.2 // indirect + k8s.io/component-base v0.29.2 // indirect k8s.io/klog/v2 v2.110.1 // indirect k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect sigs.k8s.io/controller-runtime v0.16.3 // indirect diff --git a/go.sum b/go.sum index 7a106d3..73ab1f0 100644 --- a/go.sum +++ b/go.sum @@ -695,14 +695,24 @@ 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.29.1 h1:DAjwWX/9YT7NQD4INu49ROJuZAAAP/Ijki48GUPzxqw= k8s.io/api v0.29.1/go.mod h1:7Kl10vBRUXhnQQI8YR/R327zXC8eJ7887/+Ybta+RoQ= +k8s.io/api v0.29.2 h1:hBC7B9+MU+ptchxEqTNW2DkUosJpp1P+Wn6YncZ474A= +k8s.io/api v0.29.2/go.mod h1:sdIaaKuU7P44aoyyLlikSLayT6Vb7bvJNCX105xZXY0= k8s.io/apiextensions-apiserver v0.29.1 h1:S9xOtyk9M3Sk1tIpQMu9wXHm5O2MX6Y1kIpPMimZBZw= k8s.io/apiextensions-apiserver v0.29.1/go.mod h1:zZECpujY5yTW58co8V2EQR4BD6A9pktVgHhvc0uLfeU= +k8s.io/apiextensions-apiserver v0.29.2 h1:UK3xB5lOWSnhaCk0RFZ0LUacPZz9RY4wi/yt2Iu+btg= +k8s.io/apiextensions-apiserver v0.29.2/go.mod h1:aLfYjpA5p3OwtqNXQFkhJ56TB+spV8Gc4wfMhUA3/b8= k8s.io/apimachinery v0.29.1 h1:KY4/E6km/wLBguvCZv8cKTeOwwOBqFNjwJIdMkMbbRc= k8s.io/apimachinery v0.29.1/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= +k8s.io/apimachinery v0.29.2 h1:EWGpfJ856oj11C52NRCHuU7rFDwxev48z+6DSlGNsV8= +k8s.io/apimachinery v0.29.2/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= k8s.io/client-go v0.29.1 h1:19B/+2NGEwnFLzt0uB5kNJnfTsbV8w6TgQRz9l7ti7A= k8s.io/client-go v0.29.1/go.mod h1:TDG/psL9hdet0TI9mGyHJSgRkW3H9JZk2dNEUS7bRks= +k8s.io/client-go v0.29.2 h1:FEg85el1TeZp+/vYJM7hkDlSTFZ+c5nnK44DJ4FyoRg= +k8s.io/client-go v0.29.2/go.mod h1:knlvFZE58VpqbQpJNbCbctTVXcd35mMyAAwBdpt4jrA= k8s.io/component-base v0.29.1 h1:MUimqJPCRnnHsskTTjKD+IC1EHBbRCVyi37IoFBrkYw= k8s.io/component-base v0.29.1/go.mod h1:fP9GFjxYrLERq1GcWWZAE3bqbNcDKDytn2srWuHTtKc= +k8s.io/component-base v0.29.2 h1:lpiLyuvPA9yV1aQwGLENYyK7n/8t6l3nn3zAtFTJYe8= +k8s.io/component-base v0.29.2/go.mod h1:BfB3SLrefbZXiBfbM+2H1dlat21Uewg/5qtKOl8degM= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= From 03f2829d3139ba7db49e36a8d2285ac2f1a6abc3 Mon Sep 17 00:00:00 2001 From: Christopher Haar Date: Thu, 15 Feb 2024 09:56:25 +0100 Subject: [PATCH 23/31] feat(upboundcare): switch to upboundcare Signed-off-by: Christopher Haar --- .github/workflows/ci.yml | 10 +++++++--- .golangci.yml | 2 +- README.md | 6 +++--- condition_test.go | 2 +- connection.go | 2 +- connection_test.go | 2 +- examples/conditional-rendering/functions.yaml | 2 +- examples/conditional-resources/functions.yaml | 2 +- fn.go | 2 +- fn_test.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- package/crossplane.yaml | 4 ++-- patches.go | 2 +- patches_test.go | 2 +- ready.go | 2 +- ready_test.go | 2 +- render.go | 2 +- transforms.go | 2 +- transforms_test.go | 2 +- validate.go | 2 +- validate_test.go | 2 +- 22 files changed, 32 insertions(+), 28 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d3ea0a..c185fba 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,7 @@ env: # The package to push, without a version tag. The default matches GitHub. For # example xpkg.upbound.io/crossplane/function-template-go. - XPKG: xpkg.upbound.io/borrelli-org/function-conditional-patch-and-transform + XPKG: xpkg.upbound.io/upboundcare/function-conditional-patch-and-transform # The package version to push. The default is 0.0.0-gitsha. XPKG_VERSION: ${{ inputs.version }} @@ -144,9 +144,13 @@ jobs: run: "curl -sL https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh | sh" - name: Login to Upbound + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3 if: env.XPKG_ACCESS_ID != '' - run: "./crossplane xpkg login -a borrelli-org -t ${{ secrets.XPKG_TOKEN }}" - + with: + registry: xpkg.upbound.io + username: ${{ secrets.XPKG_ACCESS_ID }} + password: ${{ secrets.XPKG_TOKEN }} + # If a version wasn't explicitly passed as a workflow_dispatch input we # default to version v0.0.0--, for example # v0.0.0-20231101115142-1091066df799. This is a simple implementation of diff --git a/.golangci.yml b/.golangci.yml index 5421bc0..33be29b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -38,7 +38,7 @@ linters-settings: - default - prefix(github.com/crossplane/crossplane-runtime) - prefix(github.com/crossplane/function-sdk-go) - - prefix(github.com/stevendborrelli/function-conditional-patch-and-transform) + - prefix(github.com/upboundcare/function-conditional-patch-and-transform) - blank - dot diff --git a/README.md b/README.md index 775cc79..8bc8573 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # function-conditional-patch-and-transform -[![CI](https://github.com/stevendborrelli/function-conditional-patch-and-transform/actions/workflows/ci.yml/badge.svg)](https://github.com/stevendborrelli/function-conditional-patch-and-transform/actions/workflows/ci.yml) ![GitHub release (latest SemVer)](https://img.shields.io/github/release/crossplane-contrib/function-conditional-patch-and-transform) +[![CI](https://github.com/upboundcare/function-conditional-patch-and-transform/actions/workflows/ci.yml/badge.svg)](https://github.com/upboundcare/function-conditional-patch-and-transform/actions/workflows/ci.yml) ![GitHub release (latest SemVer)](https://img.shields.io/github/release/crossplane-contrib/function-conditional-patch-and-transform) This composition function is a fork of the upstream [function-patch-and-transform](https://github.com/crossplane-contrib/function-patch-and-transform) that adds support for Conditional invocation of the function and the rendering @@ -18,7 +18,7 @@ metadata: annotations: render.crossplane.io/runtime: Development spec: - package: xpkg.upbound.io/borrelli-org/function-conditional-patch-and-transform:v0.4.0 + package: xpkg.upbound.io/upboundcare/function-conditional-patch-and-transform:v0.4.0 ``` ## What this function does @@ -240,7 +240,7 @@ $ crossplane xpkg build -f package --embed-runtime-image=runtime [docs-composition]: https://docs.crossplane.io/v1.14/getting-started/provider-aws-part-2/#create-a-deployment-template [docs-functions]: https://docs.crossplane.io/v1.14/concepts/composition-functions/ [docs-pandt]: https://docs.crossplane.io/v1.14/concepts/patch-and-transform/ -[fn-go-templating]: https://github.com/stevendborrelli/function-go-templating +[fn-go-templating]: https://github.com/upboundcare/function-go-templating [#4617]: https://github.com/crossplane/crossplane/issues/4617 [#4746]: https://github.com/crossplane/crossplane/issues/4746 [go]: https://go.dev diff --git a/condition_test.go b/condition_test.go index eefab03..cf13e09 100644 --- a/condition_test.go +++ b/condition_test.go @@ -12,7 +12,7 @@ import ( fnv1beta1 "github.com/crossplane/function-sdk-go/proto/v1beta1" "github.com/crossplane/function-sdk-go/resource" - "github.com/stevendborrelli/function-conditional-patch-and-transform/input/v1beta1" + "github.com/upboundcare/function-conditional-patch-and-transform/input/v1beta1" ) func TestEvaluateCondition(t *testing.T) { diff --git a/connection.go b/connection.go index 2a248b6..fddaf85 100644 --- a/connection.go +++ b/connection.go @@ -9,7 +9,7 @@ import ( "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" "github.com/crossplane/crossplane-runtime/pkg/resource" - "github.com/stevendborrelli/function-conditional-patch-and-transform/input/v1beta1" + "github.com/upboundcare/function-conditional-patch-and-transform/input/v1beta1" ) // ConnectionDetailsExtractor extracts the connection details of a resource. diff --git a/connection_test.go b/connection_test.go index eafa683..4fa2fd6 100644 --- a/connection_test.go +++ b/connection_test.go @@ -14,7 +14,7 @@ import ( "github.com/crossplane/crossplane-runtime/pkg/resource/fake" "github.com/crossplane/crossplane-runtime/pkg/test" - "github.com/stevendborrelli/function-conditional-patch-and-transform/input/v1beta1" + "github.com/upboundcare/function-conditional-patch-and-transform/input/v1beta1" ) func TestExtractConnectionDetails(t *testing.T) { diff --git a/examples/conditional-rendering/functions.yaml b/examples/conditional-rendering/functions.yaml index b197224..121ad68 100644 --- a/examples/conditional-rendering/functions.yaml +++ b/examples/conditional-rendering/functions.yaml @@ -3,5 +3,5 @@ kind: Function metadata: name: function-conditional-patch-and-transform spec: - package: xpkg.upbound.io/borrelli-org/function-conditional-patch-and-transform:v0.4.0 + package: xpkg.upbound.io/upboundcare/function-conditional-patch-and-transform:v0.4.0 packagePullPolicy: Always diff --git a/examples/conditional-resources/functions.yaml b/examples/conditional-resources/functions.yaml index b197224..121ad68 100644 --- a/examples/conditional-resources/functions.yaml +++ b/examples/conditional-resources/functions.yaml @@ -3,5 +3,5 @@ kind: Function metadata: name: function-conditional-patch-and-transform spec: - package: xpkg.upbound.io/borrelli-org/function-conditional-patch-and-transform:v0.4.0 + package: xpkg.upbound.io/upboundcare/function-conditional-patch-and-transform:v0.4.0 packagePullPolicy: Always diff --git a/fn.go b/fn.go index df01b37..8deff9f 100644 --- a/fn.go +++ b/fn.go @@ -17,7 +17,7 @@ import ( "github.com/crossplane/function-sdk-go/resource/composed" "github.com/crossplane/function-sdk-go/response" - "github.com/stevendborrelli/function-conditional-patch-and-transform/input/v1beta1" + "github.com/upboundcare/function-conditional-patch-and-transform/input/v1beta1" ) const conditionError = "Condition error" diff --git a/fn_test.go b/fn_test.go index 6cac9cd..d0dd3c1 100644 --- a/fn_test.go +++ b/fn_test.go @@ -22,7 +22,7 @@ import ( "github.com/crossplane/function-sdk-go/resource" "github.com/crossplane/function-sdk-go/response" - "github.com/stevendborrelli/function-conditional-patch-and-transform/input/v1beta1" + "github.com/upboundcare/function-conditional-patch-and-transform/input/v1beta1" ) func TestRunFunction(t *testing.T) { diff --git a/go.mod b/go.mod index 40102c9..2de471a 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/stevendborrelli/function-conditional-patch-and-transform +module github.com/upboundcare/function-conditional-patch-and-transform go 1.21 diff --git a/go.sum b/go.sum index 1217ae5..2ab1b4f 100644 --- a/go.sum +++ b/go.sum @@ -309,8 +309,8 @@ github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stevendborrelli/function-conditional-patch-and-transform v0.2.1 h1:8CNU6BGXWO+lqQw7t+calDuM9JEjQ61YYVA9fM9yv+8= -github.com/stevendborrelli/function-conditional-patch-and-transform v0.2.1/go.mod h1:B9hSlytx1BSH/zezwsRkLhcnEG1NHDQJE7Q5P4zxJGI= +github.com/upboundcare/function-conditional-patch-and-transform v0.2.1 h1:8CNU6BGXWO+lqQw7t+calDuM9JEjQ61YYVA9fM9yv+8= +github.com/upboundcare/function-conditional-patch-and-transform v0.2.1/go.mod h1:B9hSlytx1BSH/zezwsRkLhcnEG1NHDQJE7Q5P4zxJGI= github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= 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= diff --git a/package/crossplane.yaml b/package/crossplane.yaml index 48215e0..5df4b7a 100644 --- a/package/crossplane.yaml +++ b/package/crossplane.yaml @@ -5,7 +5,7 @@ metadata: name: function-conditional-patch-and-transform annotations: meta.crossplane.io/maintainer: Crossplane Maintainers - meta.crossplane.io/source: github.com/stevendborrelli/function-conditional-patch-and-transform + meta.crossplane.io/source: github.com/upboundcare/function-conditional-patch-and-transform meta.crossplane.io/license: Apache-2.0 meta.crossplane.io/description: A patch & transform composition function that supports conditionals meta.crossplane.io/readme: | @@ -13,6 +13,6 @@ metadata: that adds support for Conditional invocation of the function and the rendering of individual resources. See the - [README](https://github.com/stevendborrelli/function-conditional-patch-and-transform) + [README](https://github.com/upboundcare/function-conditional-patch-and-transform) for examples and documentation. spec: {} diff --git a/patches.go b/patches.go index 57fecdf..5337180 100644 --- a/patches.go +++ b/patches.go @@ -10,7 +10,7 @@ import ( "github.com/crossplane/crossplane-runtime/pkg/fieldpath" "github.com/crossplane/crossplane-runtime/pkg/resource" - "github.com/stevendborrelli/function-conditional-patch-and-transform/input/v1beta1" + "github.com/upboundcare/function-conditional-patch-and-transform/input/v1beta1" ) const ( diff --git a/patches_test.go b/patches_test.go index 335a19c..1ba95b1 100644 --- a/patches_test.go +++ b/patches_test.go @@ -17,7 +17,7 @@ import ( "github.com/crossplane/function-sdk-go/resource/composite" - "github.com/stevendborrelli/function-conditional-patch-and-transform/input/v1beta1" + "github.com/upboundcare/function-conditional-patch-and-transform/input/v1beta1" ) func TestPatchApply(t *testing.T) { diff --git a/ready.go b/ready.go index dd6ddd4..59de7ab 100644 --- a/ready.go +++ b/ready.go @@ -8,7 +8,7 @@ import ( "github.com/crossplane/crossplane-runtime/pkg/fieldpath" "github.com/crossplane/crossplane-runtime/pkg/resource" - "github.com/stevendborrelli/function-conditional-patch-and-transform/input/v1beta1" + "github.com/upboundcare/function-conditional-patch-and-transform/input/v1beta1" ) // Error strings diff --git a/ready_test.go b/ready_test.go index bf0b8c9..a7e366a 100644 --- a/ready_test.go +++ b/ready_test.go @@ -14,7 +14,7 @@ import ( "github.com/crossplane/crossplane-runtime/pkg/resource/unstructured/composed" "github.com/crossplane/crossplane-runtime/pkg/test" - "github.com/stevendborrelli/function-conditional-patch-and-transform/input/v1beta1" + "github.com/upboundcare/function-conditional-patch-and-transform/input/v1beta1" ) var _ ReadinessChecker = ReadinessCheckerFn(IsReady) diff --git a/render.go b/render.go index 20398ea..e6b79ad 100644 --- a/render.go +++ b/render.go @@ -11,7 +11,7 @@ import ( "github.com/crossplane/function-sdk-go/resource/composed" "github.com/crossplane/function-sdk-go/resource/composite" - "github.com/stevendborrelli/function-conditional-patch-and-transform/input/v1beta1" + "github.com/upboundcare/function-conditional-patch-and-transform/input/v1beta1" ) // Error strings diff --git a/transforms.go b/transforms.go index 3d9d139..2a5ec4b 100644 --- a/transforms.go +++ b/transforms.go @@ -19,7 +19,7 @@ import ( "github.com/crossplane/crossplane-runtime/pkg/errors" - "github.com/stevendborrelli/function-conditional-patch-and-transform/input/v1beta1" + "github.com/upboundcare/function-conditional-patch-and-transform/input/v1beta1" ) const ( diff --git a/transforms_test.go b/transforms_test.go index bc42130..0ef111e 100644 --- a/transforms_test.go +++ b/transforms_test.go @@ -14,7 +14,7 @@ import ( "github.com/crossplane/crossplane-runtime/pkg/errors" "github.com/crossplane/crossplane-runtime/pkg/test" - "github.com/stevendborrelli/function-conditional-patch-and-transform/input/v1beta1" + "github.com/upboundcare/function-conditional-patch-and-transform/input/v1beta1" ) func TestMapResolve(t *testing.T) { diff --git a/validate.go b/validate.go index bcaf695..e32dded 100644 --- a/validate.go +++ b/validate.go @@ -6,7 +6,7 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" - "github.com/stevendborrelli/function-conditional-patch-and-transform/input/v1beta1" + "github.com/upboundcare/function-conditional-patch-and-transform/input/v1beta1" ) // WrapFieldError wraps the given field.Error adding the given field.Path as root of the Field. diff --git a/validate_test.go b/validate_test.go index 479aefe..848a554 100644 --- a/validate_test.go +++ b/validate_test.go @@ -9,7 +9,7 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/utils/ptr" - "github.com/stevendborrelli/function-conditional-patch-and-transform/input/v1beta1" + "github.com/upboundcare/function-conditional-patch-and-transform/input/v1beta1" ) func TestValidateReadinessCheck(t *testing.T) { From f030a765ddb6dd7cdb75c67f265975e16064e243 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 12:47:59 +0000 Subject: [PATCH 24/31] fix(deps): update module github.com/crossplane/crossplane-runtime to v1.15.1 --- go.mod | 44 +++++++++++++++++++++++--------------------- go.sum | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 00a910c..920d67c 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.21.3 require ( github.com/alecthomas/kong v0.8.1 - github.com/crossplane/crossplane-runtime v1.14.4 + github.com/crossplane/crossplane-runtime v1.15.1 github.com/crossplane/function-sdk-go v0.1.0 github.com/google/go-cmp v0.6.0 github.com/pkg/errors v0.9.1 @@ -24,12 +24,13 @@ require ( github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch/v5 v5.6.0 // indirect + github.com/evanphx/json-patch v5.6.0+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.8.0 // indirect github.com/fatih/color v1.16.0 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-json-experiment/json v0.0.0-20231013223334-54c864be5b8d // indirect - github.com/go-logr/logr v1.3.0 // indirect - github.com/go-logr/zapr v1.2.4 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/zapr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect @@ -39,7 +40,7 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/uuid v1.3.1 // indirect + github.com/google/uuid v1.4.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -47,31 +48,32 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/prometheus/client_golang v1.16.0 // indirect - github.com/prometheus/client_model v0.4.0 // indirect - github.com/prometheus/common v0.44.0 // indirect - github.com/prometheus/procfs v0.10.1 // indirect - github.com/spf13/afero v1.10.0 // indirect + github.com/prometheus/client_golang v1.18.0 // indirect + github.com/prometheus/client_model v0.5.0 // indirect + github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect + github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect + golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.19.0 // indirect - golang.org/x/oauth2 v0.11.0 // indirect - golang.org/x/sys v0.15.0 // indirect - golang.org/x/term v0.15.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/oauth2 v0.15.0 // indirect + golang.org/x/sys v0.16.0 // indirect + golang.org/x/term v0.16.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.16.1 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.17.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect - google.golang.org/grpc v1.59.0 // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect + google.golang.org/grpc v1.61.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -79,7 +81,7 @@ require ( k8s.io/component-base v0.29.1 // indirect k8s.io/klog/v2 v2.110.1 // indirect k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect - sigs.k8s.io/controller-runtime v0.16.3 // indirect + sigs.k8s.io/controller-runtime v0.17.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/go.sum b/go.sum index 7a106d3..592d3d4 100644 --- a/go.sum +++ b/go.sum @@ -73,6 +73,8 @@ github.com/crossplane/crossplane-runtime v1.14.3 h1:YNGALph/UJTtQO+cJ9KGQ5NfALI5 github.com/crossplane/crossplane-runtime v1.14.3/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o= github.com/crossplane/crossplane-runtime v1.14.4 h1:64zSZ75g1QXIMxR2zSQvz4+TTSq5qCUU5lmpiVovVKE= github.com/crossplane/crossplane-runtime v1.14.4/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o= +github.com/crossplane/crossplane-runtime v1.15.1 h1:g1h75tNYOQT152IUNxs8ZgSsRFQKrZN9z69KefMujXs= +github.com/crossplane/crossplane-runtime v1.15.1/go.mod h1:kRcJjJQmBFrR2n/KhwL8wYS7xNfq3D8eK4JliEScOHI= github.com/crossplane/function-sdk-go v0.1.0 h1:WN3CUSaj6wgDqQPZZP1whMVIkTAZtN3HVCS67pTMzd8= github.com/crossplane/function-sdk-go v0.1.0/go.mod h1:oRqHZ6RufpfZJ1N8aT4EfkP+5KpkhOKpWz7SeUDwwcw= github.com/crossplane/upjet v0.11.0-rc.0.0.20231012093706-c4a76d2a7505 h1:eCmYgfRopVn6r8RM1Ra4XQAPwVsjTGfktBj2Dk7yy+Y= @@ -92,6 +94,8 @@ github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCv github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= +github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= 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.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= @@ -106,8 +110,12 @@ github.com/go-json-experiment/json v0.0.0-20231013223334-54c864be5b8d/go.mod h1: github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= @@ -148,6 +156,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -189,6 +198,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/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.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -255,6 +266,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= +github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= @@ -288,19 +301,29 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= +github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= +github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -358,6 +381,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -371,6 +395,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o= +golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -395,6 +421,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -430,8 +457,11 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= 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= @@ -443,6 +473,8 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU= golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= +golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= +golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -454,6 +486,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -493,13 +526,20 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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= @@ -508,6 +548,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -515,6 +556,8 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -565,8 +608,10 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= 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= @@ -600,6 +645,8 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -638,6 +685,8 @@ google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -656,6 +705,8 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5 google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= +google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -714,6 +765,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= +sigs.k8s.io/controller-runtime v0.17.0 h1:fjJQf8Ukya+VjogLO6/bNX9HE6Y2xpsO5+fyS26ur/s= +sigs.k8s.io/controller-runtime v0.17.0/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= sigs.k8s.io/controller-tools v0.14.0 h1:rnNoCC5wSXlrNoBKKzL70LNJKIQKEzT6lloG6/LF73A= sigs.k8s.io/controller-tools v0.14.0/go.mod h1:TV7uOtNNnnR72SpzhStvPkoS/U5ir0nMudrkrC4M9Sc= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= From cd151b497d0463d3a38c9ddb694f53c7c7585d2e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 22 Feb 2024 04:44:30 +0000 Subject: [PATCH 25/31] fix(deps): update module github.com/crossplane/function-sdk-go to v0.2.0 --- go.mod | 4 ++-- go.sum | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 920d67c..489f58b 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ toolchain go1.21.3 require ( github.com/alecthomas/kong v0.8.1 github.com/crossplane/crossplane-runtime v1.15.1 - github.com/crossplane/function-sdk-go v0.1.0 + github.com/crossplane/function-sdk-go v0.2.0 github.com/google/go-cmp v0.6.0 github.com/pkg/errors v0.9.1 google.golang.org/protobuf v1.32.0 @@ -72,7 +72,7 @@ require ( golang.org/x/tools v0.17.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect google.golang.org/grpc v1.61.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 592d3d4..aaa5bae 100644 --- a/go.sum +++ b/go.sum @@ -77,6 +77,8 @@ github.com/crossplane/crossplane-runtime v1.15.1 h1:g1h75tNYOQT152IUNxs8ZgSsRFQK github.com/crossplane/crossplane-runtime v1.15.1/go.mod h1:kRcJjJQmBFrR2n/KhwL8wYS7xNfq3D8eK4JliEScOHI= github.com/crossplane/function-sdk-go v0.1.0 h1:WN3CUSaj6wgDqQPZZP1whMVIkTAZtN3HVCS67pTMzd8= github.com/crossplane/function-sdk-go v0.1.0/go.mod h1:oRqHZ6RufpfZJ1N8aT4EfkP+5KpkhOKpWz7SeUDwwcw= +github.com/crossplane/function-sdk-go v0.2.0 h1:4r+dXeGgwOC2XehJlHsHlkdkUsGW8PzkiyPPd2cshQs= +github.com/crossplane/function-sdk-go v0.2.0/go.mod h1:AvaWMHeKvzzE0vODLBrU5njOzW6sm61Ou4js9OdBUXM= github.com/crossplane/upjet v0.11.0-rc.0.0.20231012093706-c4a76d2a7505 h1:eCmYgfRopVn6r8RM1Ra4XQAPwVsjTGfktBj2Dk7yy+Y= github.com/crossplane/upjet v0.11.0-rc.0.0.20231012093706-c4a76d2a7505/go.mod h1:Ov+eoYS2n0Zge/E50zm65meOTYbAHnU6jPt27fQrpbc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -687,6 +689,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1: google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac h1:nUQEQmH/csSvFECKYRv6HWEyypysidKl2I6Qpsglq/0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= From 14ea3fddc5d6da5e310b157a319d996ac68b6a74 Mon Sep 17 00:00:00 2001 From: Philippe Scorsolini Date: Tue, 13 Feb 2024 19:50:26 +0000 Subject: [PATCH 26/31] feat: toFieldPath policies, replacing upstream MergeOptions Signed-off-by: Philippe Scorsolini --- README.md | 11 +- fn_test.go | 19 +- go.mod | 1 - go.sum | 529 +----------------- input/v1beta1/resources_patches.go | 27 + input/v1beta1/zz_generated.deepcopy.go | 5 + .../input/pt.fn.crossplane.io_resources.yaml | 36 ++ patches.go | 42 +- validate.go | 18 +- 9 files changed, 174 insertions(+), 514 deletions(-) diff --git a/README.md b/README.md index f23239c..8a41aa7 100644 --- a/README.md +++ b/README.md @@ -128,11 +128,12 @@ These fields are now required. This makes P&T configuration less ambiguous: * `resources[i].patches[i].transforms[i].math.type` Also, the `resources[i].patches[i].policy.mergeOptions` field is no longer -supported. - -Composition functions use Kubernetes server-side apply to intelligently merge -arrays and objects. This requires merge configuration to be specified at the -composed resource schema level (i.e. in CRDs) per [#4617]. +supported. The same capability can be achieved by setting +`resources[i].patches[i].policy.toFieldPath` to: +- `MergeObject` - equivalent to + `resources[i].patches[i].policy.mergeOptions.keepMapValues: true` +- `AppendArray` - equivalent to + `resources[i].patches[i].policy.mergeOptions.appendSlice: false` ## Developing this function diff --git a/fn_test.go b/fn_test.go index 85c3af7..0f828b4 100644 --- a/fn_test.go +++ b/fn_test.go @@ -465,7 +465,7 @@ func TestRunFunction(t *testing.T) { }, { Name: "existing-resource", - Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD","spec":{}}`)}, + Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD","spec":{"targetObject": {"keep": "me"}}}`)}, Patches: []v1beta1.ComposedPatch{ { // This patch should work. @@ -475,6 +475,17 @@ func TestRunFunction(t *testing.T) { ToFieldPath: ptr.To[string]("spec.watchers"), }, }, + { + // This patch should work too and properly handle mergeOptions. + Type: v1beta1.PatchTypeFromCompositeFieldPath, + Patch: v1beta1.Patch{ + FromFieldPath: ptr.To[string]("spec.sourceObject"), + ToFieldPath: ptr.To[string]("spec.targetObject"), + Policy: &v1beta1.PatchPolicy{ + ToFieldPath: ptr.To(v1beta1.ToFieldPathPolicyMergeObject), + }, + }, + }, { // This patch will fail because the path // is not found. @@ -492,7 +503,7 @@ func TestRunFunction(t *testing.T) { }), Observed: &fnv1beta1.State{ Composite: &fnv1beta1.Resource{ - Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"XR","spec":{"widgets":"10"}}`), + Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"XR","spec":{"widgets":"10", "sourceObject": {"me": "too"}}}`), }, Resources: map[string]*fnv1beta1.Resource{ // "existing-resource" exists. @@ -520,7 +531,7 @@ func TestRunFunction(t *testing.T) { // Note that the first patch did work. We only // skipped the patch from the required field path. "existing-resource": { - Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","spec":{"watchers":"10"}}`), + Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","spec":{"watchers":"10", "targetObject": {"me": "too", "keep": "me"}}}`), }, // Note "new-resource" doesn't appear here. @@ -534,7 +545,7 @@ func TestRunFunction(t *testing.T) { }, { Severity: fnv1beta1.Severity_SEVERITY_WARNING, - Message: `cannot render composed resource "existing-resource" "FromCompositeFieldPath" patch at index 1: ignoring 'policy.fromFieldPath: Required' because 'to' resource already exists: spec.doesNotExist: no such field`, + Message: `cannot render composed resource "existing-resource" "FromCompositeFieldPath" patch at index 2: ignoring 'policy.fromFieldPath: Required' because 'to' resource already exists: spec.doesNotExist: no such field`, }, }, }, diff --git a/go.mod b/go.mod index da03fee..928887b 100644 --- a/go.mod +++ b/go.mod @@ -47,7 +47,6 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect diff --git a/go.sum b/go.sum index 855e34c..ce1c171 100644 --- a/go.sum +++ b/go.sum @@ -1,45 +1,5 @@ -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.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -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/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2ojoH/0= @@ -54,48 +14,25 @@ github.com/antchfx/xpath v1.2.0 h1:mbwv7co+x0RwgeGAOHdrKy89GvHaGvxxBtPK0uF9Zr8= github.com/antchfx/xpath v1.2.0/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -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/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/crossplane/crossplane-runtime v1.14.3 h1:YNGALph/UJTtQO+cJ9KGQ5NfALI5453PeE93Aqy9SWg= -github.com/crossplane/crossplane-runtime v1.14.3/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o= -github.com/crossplane/crossplane-runtime v1.14.4 h1:64zSZ75g1QXIMxR2zSQvz4+TTSq5qCUU5lmpiVovVKE= -github.com/crossplane/crossplane-runtime v1.14.4/go.mod h1:aOP+5W2wKpvthVs3pFNbVOe1jwrKYbJho0ThGNCVz9o= github.com/crossplane/crossplane-runtime v1.15.1 h1:g1h75tNYOQT152IUNxs8ZgSsRFQKrZN9z69KefMujXs= github.com/crossplane/crossplane-runtime v1.15.1/go.mod h1:kRcJjJQmBFrR2n/KhwL8wYS7xNfq3D8eK4JliEScOHI= -github.com/crossplane/function-sdk-go v0.1.0 h1:WN3CUSaj6wgDqQPZZP1whMVIkTAZtN3HVCS67pTMzd8= -github.com/crossplane/function-sdk-go v0.1.0/go.mod h1:oRqHZ6RufpfZJ1N8aT4EfkP+5KpkhOKpWz7SeUDwwcw= github.com/crossplane/function-sdk-go v0.2.0 h1:4r+dXeGgwOC2XehJlHsHlkdkUsGW8PzkiyPPd2cshQs= github.com/crossplane/function-sdk-go v0.2.0/go.mod h1:AvaWMHeKvzzE0vODLBrU5njOzW6sm61Ou4js9OdBUXM= -github.com/crossplane/upjet v0.11.0-rc.0.0.20231012093706-c4a76d2a7505 h1:eCmYgfRopVn6r8RM1Ra4XQAPwVsjTGfktBj2Dk7yy+Y= -github.com/crossplane/upjet v0.11.0-rc.0.0.20231012093706-c4a76d2a7505/go.mod h1:Ov+eoYS2n0Zge/E50zm65meOTYbAHnU6jPt27fQrpbc= +github.com/crossplane/upjet v1.1.0-rc.0.0.20231227120826-4cb45f9104ac h1:T1MTxsPAE/Cs0/EAGjeC29H9O/rO81yol2/5qGsf888= +github.com/crossplane/upjet v1.1.0-rc.0.0.20231227120826-4cb45f9104ac/go.mod h1:t9etxIdYaxgyvFPBToikm5zBHi8RIpX8N4mTH77lQFM= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.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= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= -github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/evanphx/json-patch/v5 v5.8.0 h1:lRj6N9Nci7MvzrXuX6HFzU8XjmhPiXPlsKEy1u0KQro= github.com/evanphx/json-patch/v5 v5.8.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= @@ -104,18 +41,11 @@ github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-json-experiment/json v0.0.0-20231013223334-54c864be5b8d h1:zqfo2jECgX5eYQseB/X+uV4Y5ocGOG/vG/LTztUCyPA= github.com/go-json-experiment/json v0.0.0-20231013223334-54c864be5b8d/go.mod h1:6daplAwHHGbUGib4990V3Il26O0OC4aRyvewaaAihaA= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= -github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= @@ -130,50 +60,14 @@ github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -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= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -181,77 +75,48 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98 h1:pUa4ghanp6q4IJHwE9RwLgmVFfReJN+KbQ8ExNEUUoQ= -github.com/google/pprof v0.0.0-20230926050212-f7f687d19a98/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/pprof v0.0.0-20240117000934-35fc243c5815 h1:WzfWbQz/Ze8v6l++GGbGNFZnUShVpP/0xffCPLL+ax8= +github.com/google/pprof v0.0.0-20240117000934-35fc243c5815/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/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.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= -github.com/hashicorp/go-hclog v1.2.1 h1:YQsLlGDJgwhXFpucSPyVbCBviQtjlHv3jLTlp8YmtEw= -github.com/hashicorp/go-hclog v1.2.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.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.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl/v2 v2.14.1 h1:x0BpjfZ+CYdbiz+8yZTQ+gdLO7IXvOut7Da+XJayx34= -github.com/hashicorp/hcl/v2 v2.14.1/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0= +github.com/hashicorp/hcl/v2 v2.17.0 h1:z1XvSUyXd1HP10U4lrLg5e0JMVz6CPaJvAgxM0KNZVY= +github.com/hashicorp/hcl/v2 v2.17.0/go.mod h1:gJyW2PTShkJqQBKpAmPO3yxMxIuoXkOF2TpqXzrQyx4= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/terraform-json v0.14.0 h1:sh9iZ1Y8IFJLx+xQiKHGud6/TSUCM0N8e17dKDpqV7s= -github.com/hashicorp/terraform-json v0.14.0/go.mod h1:5A9HIWPkk4e5aeeXIBbkcOvaZbIYnAIkEyqP2pNSckM= -github.com/hashicorp/terraform-plugin-go v0.14.0 h1:ttnSlS8bz3ZPYbMb84DpcPhY4F5DsQtcAS7cHo8uvP4= -github.com/hashicorp/terraform-plugin-go v0.14.0/go.mod h1:2nNCBeRLaenyQEi78xrGrs9hMbulveqG/zDMQSvVJTE= -github.com/hashicorp/terraform-plugin-log v0.7.0 h1:SDxJUyT8TwN4l5b5/VkiTIaQgY6R+Y2BQ0sRZftGKQs= -github.com/hashicorp/terraform-plugin-log v0.7.0/go.mod h1:p4R1jWBXRTvL4odmEkFfDdhUjHf9zcs/BCoNHAc7IK4= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.0 h1:FtCLTiTcykdsURXPt/ku7fYXm3y19nbzbZcUxHx9RbI= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.0/go.mod h1:80wf5oad1tW+oLnbXS4UTYmDCrl7BuN1Q+IA91X1a4Y= +github.com/hashicorp/terraform-json v0.17.0 h1:EiA1Wp07nknYQAiv+jIt4dX4Cq5crgP+TsTE45MjMmM= +github.com/hashicorp/terraform-json v0.17.0/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o= +github.com/hashicorp/terraform-plugin-go v0.16.0 h1:DSOQ0rz5FUiVO4NUzMs8ln9gsPgHMTsfns7Nk+6gPuE= +github.com/hashicorp/terraform-plugin-go v0.16.0/go.mod h1:4sn8bFuDbt+2+Yztt35IbOrvZc0zyEi87gJzsTgCES8= +github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= +github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1 h1:G9WAfb8LHeCxu7Ae8nc1agZlQOSCUWsb610iAogBhCs= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1/go.mod h1:xcOSYlRVdPLmDUoqPhO9fiO/YCN/l6MGYeTzGt5jgkQ= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -266,8 +131,6 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= @@ -291,39 +154,25 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= 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.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY= +github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw= github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= -github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= -github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= -github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= -github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= -github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= @@ -334,9 +183,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -344,275 +190,82 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tmccombs/hcl2json v0.3.3 h1:+DLNYqpWE0CsOQiEZu+OZm5ZBImake3wtITYxQ8uLFQ= github.com/tmccombs/hcl2json v0.3.3/go.mod h1:Y2chtz2x9bAeRTvSibVRVgbLJhLJXKlUeIvjeVdnm4w= -github.com/upbound/provider-aws v0.43.0 h1:ycb6ybc1Dauy0DKiuXShbcjuh7GmPJRBjNngd5dluz8= -github.com/upbound/provider-aws v0.43.0/go.mod h1:m7hoCp3D469sk1vaRh8u4hC8SmpPBJO70JrZS9p2H/U= +github.com/upbound/provider-aws v0.47.1 h1:Z+eAy9Ut4suVrx79pkzhsYTC6uvxNW2jkwAQCUVbq3g= +github.com/upbound/provider-aws v0.47.1/go.mod h1:kYxEeLtZv1CJKbc+O1IribFA47Oqkuso3hSo5vdwptU= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U= -github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= -github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= -github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zclconf/go-cty v1.11.0 h1:726SxLdi2SDnjY+BStqB9J1hNp4+2WlzyXLuimibIe0= -github.com/zclconf/go-cty v1.11.0/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= -go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +github.com/zclconf/go-cty v1.13.2 h1:4GvrUxe/QUDYuJKAav4EYqdM47/kZa672LwmXFmEKT0= +github.com/zclconf/go-cty v1.13.2/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/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-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o= golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -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-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-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= -golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -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= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.11.0 h1:vPL4xzxBM4niKCW6g9whtaWVXTJf1U5e4aZxxFx/gbU= -golang.org/x/oauth2 v0.11.0/go.mod h1:LdF7O/8bLR/qWK9DrpXmbHLTouvRHK0SgJl0GmDBchk= golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= -golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-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-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/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-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= 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= @@ -620,152 +273,37 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac h1:nUQEQmH/csSvFECKYRv6HWEyypysidKl2I6Qpsglq/0= google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 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.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 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= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= -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-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/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-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.29.1 h1:DAjwWX/9YT7NQD4INu49ROJuZAAAP/Ijki48GUPzxqw= -k8s.io/api v0.29.1/go.mod h1:7Kl10vBRUXhnQQI8YR/R327zXC8eJ7887/+Ybta+RoQ= k8s.io/api v0.29.2 h1:hBC7B9+MU+ptchxEqTNW2DkUosJpp1P+Wn6YncZ474A= k8s.io/api v0.29.2/go.mod h1:sdIaaKuU7P44aoyyLlikSLayT6Vb7bvJNCX105xZXY0= -k8s.io/apiextensions-apiserver v0.29.1 h1:S9xOtyk9M3Sk1tIpQMu9wXHm5O2MX6Y1kIpPMimZBZw= -k8s.io/apiextensions-apiserver v0.29.1/go.mod h1:zZECpujY5yTW58co8V2EQR4BD6A9pktVgHhvc0uLfeU= k8s.io/apiextensions-apiserver v0.29.2 h1:UK3xB5lOWSnhaCk0RFZ0LUacPZz9RY4wi/yt2Iu+btg= k8s.io/apiextensions-apiserver v0.29.2/go.mod h1:aLfYjpA5p3OwtqNXQFkhJ56TB+spV8Gc4wfMhUA3/b8= -k8s.io/apimachinery v0.29.1 h1:KY4/E6km/wLBguvCZv8cKTeOwwOBqFNjwJIdMkMbbRc= -k8s.io/apimachinery v0.29.1/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= k8s.io/apimachinery v0.29.2 h1:EWGpfJ856oj11C52NRCHuU7rFDwxev48z+6DSlGNsV8= k8s.io/apimachinery v0.29.2/go.mod h1:6HVkd1FwxIagpYrHSwJlQqZI3G9LfYWRPAkUvLnXTKU= -k8s.io/client-go v0.29.1 h1:19B/+2NGEwnFLzt0uB5kNJnfTsbV8w6TgQRz9l7ti7A= -k8s.io/client-go v0.29.1/go.mod h1:TDG/psL9hdet0TI9mGyHJSgRkW3H9JZk2dNEUS7bRks= k8s.io/client-go v0.29.2 h1:FEg85el1TeZp+/vYJM7hkDlSTFZ+c5nnK44DJ4FyoRg= k8s.io/client-go v0.29.2/go.mod h1:knlvFZE58VpqbQpJNbCbctTVXcd35mMyAAwBdpt4jrA= -k8s.io/component-base v0.29.1 h1:MUimqJPCRnnHsskTTjKD+IC1EHBbRCVyi37IoFBrkYw= -k8s.io/component-base v0.29.1/go.mod h1:fP9GFjxYrLERq1GcWWZAE3bqbNcDKDytn2srWuHTtKc= k8s.io/component-base v0.29.2 h1:lpiLyuvPA9yV1aQwGLENYyK7n/8t6l3nn3zAtFTJYe8= k8s.io/component-base v0.29.2/go.mod h1:BfB3SLrefbZXiBfbM+2H1dlat21Uewg/5qtKOl8degM= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= @@ -774,11 +312,6 @@ k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/A k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= -sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= sigs.k8s.io/controller-runtime v0.17.0 h1:fjJQf8Ukya+VjogLO6/bNX9HE6Y2xpsO5+fyS26ur/s= sigs.k8s.io/controller-runtime v0.17.0/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s= sigs.k8s.io/controller-tools v0.14.0 h1:rnNoCC5wSXlrNoBKKzL70LNJKIQKEzT6lloG6/LF73A= diff --git a/input/v1beta1/resources_patches.go b/input/v1beta1/resources_patches.go index 65d338d..eefb40d 100644 --- a/input/v1beta1/resources_patches.go +++ b/input/v1beta1/resources_patches.go @@ -32,6 +32,16 @@ const ( FromFieldPathPolicyRequired FromFieldPathPolicy = "Required" ) +// A ToFieldPathPolicy determines how to patch to a field path. +type ToFieldPathPolicy string + +// ToFieldPath patch policies. +const ( + ToFieldPathPolicyReplace ToFieldPathPolicy = "Replace" + ToFieldPathPolicyMergeObject ToFieldPathPolicy = "MergeObject" + ToFieldPathPolicyAppendArray ToFieldPathPolicy = "AppendArray" +) + // A PatchPolicy configures the specifics of patching behaviour. type PatchPolicy struct { // FromFieldPath specifies how to patch from a field path. The default is @@ -41,6 +51,15 @@ type PatchPolicy struct { // +kubebuilder:validation:Enum=Optional;Required // +optional FromFieldPath *FromFieldPathPolicy `json:"fromFieldPath,omitempty"` + + // ToFieldPath specifies how to patch to a field path. The default is + // 'Replace', which means the patch will completely replace the target field, + // or create it if it does not exist. Use 'MergeObject' to merge the patch + // object with the target object, or 'AppendArray' to append the patch array + // to the target array. + // +kubebuilder:validation:Enum=Replace;MergeObject;AppendArray + // +optional + ToFieldPath *ToFieldPathPolicy `json:"toFieldPath,omitempty"` } // GetFromFieldPathPolicy returns the FromFieldPathPolicy for this PatchPolicy, defaulting to FromFieldPathPolicyOptional if not specified. @@ -51,6 +70,14 @@ func (pp *PatchPolicy) GetFromFieldPathPolicy() FromFieldPathPolicy { return *pp.FromFieldPath } +// GetToFieldPathPolicy returns the ToFieldPathPolicy for this PatchPolicy, defaulting to ToFieldPathPolicyReplace if not specified. +func (pp *PatchPolicy) GetToFieldPathPolicy() ToFieldPathPolicy { + if pp == nil || pp.ToFieldPath == nil { + return ToFieldPathPolicyReplace + } + return *pp.ToFieldPath +} + // Environment represents the Composition environment. type Environment struct { // Patches is a list of environment patches that are executed before a diff --git a/input/v1beta1/zz_generated.deepcopy.go b/input/v1beta1/zz_generated.deepcopy.go index 5787099..bd97bd7 100644 --- a/input/v1beta1/zz_generated.deepcopy.go +++ b/input/v1beta1/zz_generated.deepcopy.go @@ -365,6 +365,11 @@ func (in *PatchPolicy) DeepCopyInto(out *PatchPolicy) { *out = new(FromFieldPathPolicy) **out = **in } + if in.ToFieldPath != nil { + in, out := &in.ToFieldPath, &out.ToFieldPath + *out = new(ToFieldPathPolicy) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PatchPolicy. diff --git a/package/input/pt.fn.crossplane.io_resources.yaml b/package/input/pt.fn.crossplane.io_resources.yaml index 052311b..9734fdd 100644 --- a/package/input/pt.fn.crossplane.io_resources.yaml +++ b/package/input/pt.fn.crossplane.io_resources.yaml @@ -117,6 +117,18 @@ spec: - Optional - Required type: string + toFieldPath: + description: |- + ToFieldPath specifies how to patch to a field path. The default is + 'Replace', which means the patch will completely replace the target field, + or create it if it does not exist. Use 'MergeObject' to merge the patch + object with the target object, or 'AppendArray' to append the patch array + to the target array. + enum: + - Replace + - MergeObject + - AppendArray + type: string type: object toFieldPath: description: |- @@ -448,6 +460,18 @@ spec: - Optional - Required type: string + toFieldPath: + description: |- + ToFieldPath specifies how to patch to a field path. The default is + 'Replace', which means the patch will completely replace the target field, + or create it if it does not exist. Use 'MergeObject' to merge the patch + object with the target object, or 'AppendArray' to append the patch array + to the target array. + enum: + - Replace + - MergeObject + - AppendArray + type: string type: object toFieldPath: description: |- @@ -843,6 +867,18 @@ spec: - Optional - Required type: string + toFieldPath: + description: |- + ToFieldPath specifies how to patch to a field path. The default is + 'Replace', which means the patch will completely replace the target field, + or create it if it does not exist. Use 'MergeObject' to merge the patch + object with the target object, or 'AppendArray' to append the patch array + to the target array. + enum: + - Replace + - MergeObject + - AppendArray + type: string type: object toFieldPath: description: |- diff --git a/patches.go b/patches.go index 7cdce55..5e06603 100644 --- a/patches.go +++ b/patches.go @@ -7,7 +7,9 @@ import ( "github.com/pkg/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/utils/ptr" + xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" "github.com/crossplane/crossplane-runtime/pkg/fieldpath" "github.com/crossplane/function-sdk-go/resource/composed" @@ -20,11 +22,11 @@ const ( errPatchSetType = "a patch in a PatchSet cannot be of type PatchSet" errFmtUndefinedPatchSet = "cannot find PatchSet by name %s" - errFmtInvalidPatchType = "patch type %s is unsupported" errFmtCombineStrategyNotSupported = "combine strategy %s is not supported" errFmtCombineConfigMissing = "given combine strategy %s requires configuration" errFmtCombineStrategyFailed = "%s strategy could not combine" errFmtExpandingArrayFieldPaths = "cannot expand ToFieldPath %s" + errFmtInvalidPatchPolicy = "invalid patch policy %s" ) // A PatchInterface is a patch that can be applied between resources. @@ -80,7 +82,35 @@ func ApplyFromFieldPathPatch(p PatchInterface, from, to runtime.Object) error { return patchFieldValueToMultiple(p.GetToFieldPath(), out, to) } - return errors.Wrap(patchFieldValueToObject(p.GetToFieldPath(), out, to), "cannot patch to object") + mo, err := toMergeOption(p) + if err != nil { + return err + } + + return errors.Wrap(patchFieldValueToObject(p.GetToFieldPath(), out, to, mo), "cannot patch to object") +} + +// toMergeOption returns the MergeOptions from the PatchPolicy's ToFieldPathPolicy, if defined. +func toMergeOption(p PatchInterface) (mo *xpv1.MergeOptions, err error) { + if p == nil { + return nil, nil + } + pp := p.GetPolicy() + if pp == nil { + return nil, nil + } + switch pp.GetToFieldPathPolicy() { + case v1beta1.ToFieldPathPolicyReplace: + // nothing to do, this is the default + case v1beta1.ToFieldPathPolicyAppendArray: + mo = &xpv1.MergeOptions{AppendSlice: ptr.To(true)} + case v1beta1.ToFieldPathPolicyMergeObject: + mo = &xpv1.MergeOptions{KeepMapValues: ptr.To(true)} + default: + // should never happen + return nil, errors.Errorf(errFmtInvalidPatchPolicy, pp.GetToFieldPathPolicy()) + } + return mo, nil } // ApplyCombineFromVariablesPatch patches the "to" resource, taking a list of @@ -127,7 +157,7 @@ func ApplyCombineFromVariablesPatch(p PatchInterface, from, to runtime.Object) e return err } - return errors.Wrap(patchFieldValueToObject(p.GetToFieldPath(), out, to), "cannot patch to object") + return errors.Wrap(patchFieldValueToObject(p.GetToFieldPath(), out, to, nil), "cannot patch to object") } // ApplyEnvironmentPatch applies a patch to or from the environment. Patches to @@ -298,13 +328,15 @@ func ComposedTemplates(pss []v1beta1.PatchSet, cts []v1beta1.ComposedTemplate) ( // patchFieldValueToObject applies the value to the "to" object at the given // path, returning any errors as they occur. -func patchFieldValueToObject(fieldPath string, value any, to runtime.Object) error { +// If no merge options is supplied, then destination field is replaced +// with the given value. +func patchFieldValueToObject(fieldPath string, value any, to runtime.Object, mo *xpv1.MergeOptions) error { paved, err := fieldpath.PaveObject(to) if err != nil { return err } - if err := paved.SetValue(fieldPath, value); err != nil { + if err := paved.MergeValue(fieldPath, value, mo); err != nil { return err } diff --git a/validate.go b/validate.go index 05d0140..c815a5c 100644 --- a/validate.go +++ b/validate.go @@ -199,7 +199,23 @@ func ValidatePatch(p PatchInterface) *field.Error { //nolint: gocyclo // This is return WrapFieldError(err, field.NewPath("transforms").Index(i)) } } - + if pp := p.GetPolicy(); pp != nil { + switch pp.GetToFieldPathPolicy() { + case v1beta1.ToFieldPathPolicyReplace, + v1beta1.ToFieldPathPolicyAppendArray, + v1beta1.ToFieldPathPolicyMergeObject: + // ok + default: + return field.Invalid(field.NewPath("policy", "toFieldPathPolicy"), pp.GetToFieldPathPolicy(), "unknown toFieldPathPolicy") + } + switch pp.GetFromFieldPathPolicy() { + case v1beta1.FromFieldPathPolicyRequired, + v1beta1.FromFieldPathPolicyOptional: + // ok + default: + return field.Invalid(field.NewPath("policy", "fromFieldPathPolicy"), pp.GetFromFieldPathPolicy(), "unknown fromFieldPathPolicy") + } + } return nil } From 511de3855c9c3dba3bed4b0dc7c1994f652b8848 Mon Sep 17 00:00:00 2001 From: Steven Borrelli Date: Tue, 30 Jan 2024 14:59:26 -0600 Subject: [PATCH 27/31] add conditional rendering Signed-off-by: Steven Borrelli --- condition.go | 82 ++++ condition_test.go | 363 ++++++++++++++++++ example/conditionals/README.md | 49 +++ example/conditionals/composition.yaml | 70 ++++ example/conditionals/definition.yaml | 33 ++ example/conditionals/functions.yaml | 8 + example/conditionals/manifest.yaml | 8 + example/conditionals/provider.yaml | 6 + example/conditionals/xr.yaml | 10 + fn.go | 31 ++ input/v1beta1/conditions.go | 6 + input/v1beta1/resources.go | 3 + input/v1beta1/resources_common.go | 3 + input/v1beta1/zz_generated.deepcopy.go | 10 + .../input/pt.fn.crossplane.io_resources.yaml | 20 +- 15 files changed, 696 insertions(+), 6 deletions(-) create mode 100644 condition.go create mode 100644 condition_test.go create mode 100644 example/conditionals/README.md create mode 100644 example/conditionals/composition.yaml create mode 100644 example/conditionals/definition.yaml create mode 100644 example/conditionals/functions.yaml create mode 100644 example/conditionals/manifest.yaml create mode 100644 example/conditionals/provider.yaml create mode 100644 example/conditionals/xr.yaml create mode 100644 input/v1beta1/conditions.go diff --git a/condition.go b/condition.go new file mode 100644 index 0000000..941b46e --- /dev/null +++ b/condition.go @@ -0,0 +1,82 @@ +package main + +import ( + "reflect" + + "github.com/google/cel-go/cel" + + "github.com/crossplane/crossplane-runtime/pkg/errors" + + fnv1beta1 "github.com/crossplane/function-sdk-go/proto/v1beta1" +) + +// NewCELEnvironment sets up the CEL Environment +func NewCELEnvironment() (*cel.Env, error) { + return cel.NewEnv( + cel.Types(&fnv1beta1.State{}), + cel.Variable("observed", cel.ObjectType("apiextensions.fn.proto.v1beta1.State")), + cel.Variable("desired", cel.ObjectType("apiextensions.fn.proto.v1beta1.State")), + ) +} + +// ToCELVars formats a RunFunctionRequest for CEL evaluation +func ToCELVars(req *fnv1beta1.RunFunctionRequest) map[string]any { + vars := make(map[string]any) + vars["desired"] = req.GetDesired() + vars["observed"] = req.GetObserved() + return vars +} + +// EvaluateCondition will evaluate a CEL expression +func EvaluateCondition(expression *string, req *fnv1beta1.RunFunctionRequest) (bool, error) { + if expression == nil { + return false, nil + } + + env, err := NewCELEnvironment() + if err != nil { + return false, errors.Wrap(err, "CEL Env error") + } + + ast, iss := env.Parse(*expression) + if iss.Err() != nil { + return false, errors.Wrap(iss.Err(), "CEL Parse error") + } + + // Type-check the expression for correctness. + checked, iss := env.Check(ast) + // Report semantic errors, if present. + if iss.Err() != nil { + return false, errors.Wrap(iss.Err(), "CEL TypeCheck error") + } + + // Ensure the output type is a bool. + if !reflect.DeepEqual(checked.OutputType(), cel.BoolType) { + return false, errors.Errorf( + "CEL Type error: expression '%s' must return a boolean, got %v instead", + *expression, + checked.OutputType()) + } + + // Plan the program. + program, err := env.Program(checked) + if err != nil { + return false, errors.Wrap(err, "CEL program plan") + } + + // Convert our Function Request into map[string]any for CEL evaluation + vars := ToCELVars(req) + + // Evaluate the program without any additional arguments. + result, _, err := program.Eval(vars) + if err != nil { + return false, errors.Wrap(err, "CEL program Evaluation") + } + + ret, ok := result.Value().(bool) + if !ok { + return false, errors.Wrap(err, "CEL program did not return a bool") + } + + return ret, nil +} diff --git a/condition_test.go b/condition_test.go new file mode 100644 index 0000000..7afb307 --- /dev/null +++ b/condition_test.go @@ -0,0 +1,363 @@ +package main + +import ( + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + "k8s.io/apimachinery/pkg/runtime" + + "github.com/crossplane/crossplane-runtime/pkg/errors" + + fnv1beta1 "github.com/crossplane/function-sdk-go/proto/v1beta1" + "github.com/crossplane/function-sdk-go/resource" + + "github.com/crossplane-contrib/function-patch-and-transform/input/v1beta1" +) + +func TestEvaluateCondition(t *testing.T) { + dxr := `{"apiVersion":"nopexample.org/v1alpha1","kind":"XNopResource","metadata":{"name":"test-resource"},"spec":{"env":"dev","render":true}}` + oxr := `{"apiVersion":"nopexample.org/v1alpha1","kind":"XNopResource","metadata":{"name":"test-resource"},"spec":{"env":"dev","render":true},"status":{"id":"123","ready":false} }` + + type args struct { + condition v1beta1.Condition + req *fnv1beta1.RunFunctionRequest + } + type want struct { + ret bool + err error + } + + cases := map[string]struct { + reason string + args args + want want + }{ + "CELParseError": { + args: args{ + condition: strPtr("field = value"), + req: &fnv1beta1.RunFunctionRequest{ + Input: resource.MustStructObject(&v1beta1.Resources{ + Resources: []v1beta1.ComposedTemplate{ + { + Name: "cool-resource", + Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)}, + }, + }, + }), + Observed: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(oxr), + }, + }, + Desired: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(dxr), + }, + }, + }, + }, + want: want{ + ret: false, + err: errors.New("CEL Parse error"), + }, + }, + "CELTypeError": { + args: args{ + condition: strPtr("size(desired.resources)"), + req: &fnv1beta1.RunFunctionRequest{ + Input: resource.MustStructObject(&v1beta1.Resources{ + Resources: []v1beta1.ComposedTemplate{ + { + Name: "cool-resource", + Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)}, + }, + }, + }), + Observed: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(oxr), + }, + }, + Desired: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(dxr), + }, + }, + }, + }, + want: want{ + ret: false, + err: errors.New("CEL Type error: expression 'size(desired.resources)' must return a boolean, got int instead"), + }, + }, + "KeyError": { + args: args{ + condition: strPtr("badkey"), + req: &fnv1beta1.RunFunctionRequest{ + Input: resource.MustStructObject(&v1beta1.Resources{ + Resources: []v1beta1.ComposedTemplate{ + { + Name: "cool-resource", + Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)}, + }, + }, + }), + Observed: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(oxr), + }, + }, + Desired: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(dxr), + }, + }, + }, + }, + want: want{ + ret: false, + err: errors.New("CEL TypeCheck error: ERROR: :1:1: undeclared reference to 'badkey' (in container '')\n | badkey\n | ^"), + }, + }, + "TrueDesired": { + args: args{ + condition: strPtr("desired.composite.resource.spec.env == \"dev\" "), + req: &fnv1beta1.RunFunctionRequest{ + Input: resource.MustStructObject(&v1beta1.Resources{ + Resources: []v1beta1.ComposedTemplate{ + { + Name: "cool-resource", + Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)}, + }, + }, + }), + Observed: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(oxr), + }, + }, + Desired: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(dxr), + }, + }, + }, + }, + want: want{ + ret: true, + err: nil, + }, + }, + "TrueDesiredBool": { + args: args{ + condition: strPtr("desired.composite.resource.spec.render == true"), + req: &fnv1beta1.RunFunctionRequest{ + Input: resource.MustStructObject(&v1beta1.Resources{ + Resources: []v1beta1.ComposedTemplate{ + { + Name: "cool-resource", + Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)}, + }, + }, + }), + Observed: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(oxr), + }, + }, + Desired: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(dxr), + }, + }, + }, + }, + want: want{ + ret: true, + err: nil, + }, + }, + "FalseDesiredBool": { + args: args{ + condition: strPtr("desired.composite.resource.spec.render == false"), + req: &fnv1beta1.RunFunctionRequest{ + Input: resource.MustStructObject(&v1beta1.Resources{ + Resources: []v1beta1.ComposedTemplate{ + { + Name: "cool-resource", + Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)}, + }, + }, + }), + Observed: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(oxr), + }, + }, + Desired: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(dxr), + }, + }, + }, + }, + want: want{ + ret: false, + err: nil, + }, + }, + "FalseObservedBool": { + args: args{ + condition: strPtr("observed.composite.resource.status.ready == true"), + req: &fnv1beta1.RunFunctionRequest{ + Input: resource.MustStructObject(&v1beta1.Resources{ + Resources: []v1beta1.ComposedTemplate{ + { + Name: "cool-resource", + Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)}, + }, + }, + }), + Observed: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(oxr), + }, + }, + Desired: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(dxr), + }, + }, + }, + }, + want: want{ + ret: false, + err: nil, + }, + }, + "FalseLengthResources": { + args: args{ + condition: strPtr("size(desired.resources) == 0"), + req: &fnv1beta1.RunFunctionRequest{ + Input: resource.MustStructObject(&v1beta1.Resources{ + Resources: []v1beta1.ComposedTemplate{ + { + Name: "cool-resource", + Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)}, + }, + }, + }), + Observed: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(oxr), + }, + }, + Desired: &fnv1beta1.State{ + Resources: map[string]*fnv1beta1.Resource{ + "test": { + Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","metadata":{"namespace":"default","name":"cool-42"}}`), + }, + }, + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(dxr), + }, + }, + }, + }, + want: want{ + ret: false, + err: nil, + }, + }, + "TrueResourceMapKeyExists": { + args: args{ + condition: strPtr("\"test-resource\" in desired.resources"), + req: &fnv1beta1.RunFunctionRequest{ + Input: resource.MustStructObject(&v1beta1.Resources{ + Resources: []v1beta1.ComposedTemplate{ + { + Name: "cool-resource", + Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)}, + }, + }, + }), + Observed: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(oxr), + }, + }, + Desired: &fnv1beta1.State{ + Resources: map[string]*fnv1beta1.Resource{ + "test-resource": { + Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","metadata":{"namespace":"default","name":"cool-42"}}`), + }, + }, + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(dxr), + }, + }, + }, + }, + want: want{ + ret: true, + err: nil, + }, + }, + "FalseResourceMapKeyExists": { + args: args{ + condition: strPtr("\"bad-resource\" in desired.resources"), + req: &fnv1beta1.RunFunctionRequest{ + Input: resource.MustStructObject(&v1beta1.Resources{ + Resources: []v1beta1.ComposedTemplate{ + { + Name: "cool-resource", + Base: &runtime.RawExtension{Raw: []byte(`{"apiVersion":"example.org/v1","kind":"CD"}`)}, + }, + }, + }), + Observed: &fnv1beta1.State{ + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(oxr), + }, + }, + Desired: &fnv1beta1.State{ + Resources: map[string]*fnv1beta1.Resource{ + "test-resource": { + Resource: resource.MustStructJSON(`{"apiVersion":"example.org/v1","kind":"CD","metadata":{"namespace":"default","name":"cool-42"}}`), + }, + }, + Composite: &fnv1beta1.Resource{ + Resource: resource.MustStructJSON(dxr), + }, + }, + }, + }, + want: want{ + ret: false, + err: nil, + }, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + ret, err := EvaluateCondition(tc.args.condition, tc.args.req) + + if diff := cmp.Diff(tc.want.ret, ret); diff != "" { + t.Errorf("%s\nEvaluateCondition(...): -want ret, +got ret:\n%s", tc.reason, diff) + } + + if tc.want.err != nil || err != nil { + if !strings.HasPrefix(err.Error(), tc.want.err.Error()) { + t.Errorf("\nEvaluateCondition(...): -want err, +got err:\n-want (error starts with): %s\n-got: %s", tc.want.err.Error(), err) + } + } + + }) + } +} + +func strPtr(str string) *string { + return &str +} diff --git a/example/conditionals/README.md b/example/conditionals/README.md new file mode 100644 index 0000000..a11e471 --- /dev/null +++ b/example/conditionals/README.md @@ -0,0 +1,49 @@ +# Conditional Rendering of Individual Resources + +In this example, we show how each resource in a pipeline step can +be individually rendered based on a condition. We will have a blue and a +green deployment that the user can activate: + +```yaml +apiVersion: nop.example.org/v1alpha1 +kind: XNopConditional +metadata: + name: test-resource +spec: + env: dev + render: true + deployment: + blue: true + green: false +``` + +In our Composition both the `blue-resource` and the `green-resource` have a +`condition` that determines if they will be run. + +```yaml + resources: + - name: blue-resource + condition: observed.composite.resource.spec.deployment.blue == true + base: + apiVersion: nop.crossplane.io/v1alpha1 + kind: NopResource + spec: + forProvider: +``` + +## Running This Example Locally + +This example can be rendered using `crossplane beta render`: + +```shell +crossplane beta render xr.yaml composition.yaml functions.yaml +``` + +## Running this example in a Cluster + +- Install Crossplane version 1.14 or newer. See +- Install the nop provider in `kubectl apply -f provider.yaml` +- Install the XRD & Composition in `kubectl apply -f definition.yaml -f composition.yaml` +- Install the Function `kubectl apply -f functions.yaml` + +Finally install the xr: `kubectl apply -f xr` diff --git a/example/conditionals/composition.yaml b/example/conditionals/composition.yaml new file mode 100644 index 0000000..7fc75ee --- /dev/null +++ b/example/conditionals/composition.yaml @@ -0,0 +1,70 @@ +--- +apiVersion: apiextensions.crossplane.io/v1 +kind: Composition +metadata: + name: xnopconditionals.nop.example.org +spec: + compositeTypeRef: + apiVersion: nop.example.org/v1alpha1 + kind: XNopConditional + mode: Pipeline + pipeline: + - step: conditional-patch-and-transform + functionRef: + name: function-conditional-patch-and-transform + input: + apiVersion: conditional-pt.fn.crossplane.io/v1beta1 + kind: Resources + condition: observed.composite.resource.spec.render == true + resources: + - name: blue-resource + condition: observed.composite.resource.spec.deployment.blue == true + base: + apiVersion: nop.crossplane.io/v1alpha1 + kind: NopResource + spec: + forProvider: + fields: + integerField: 42 + stringField: "blue" + objectField: + stringField: "blueObject" + arrayField: + - stringField: "blueArray" + conditionAfter: + - time: 5s + conditionType: Ready + conditionStatus: "True" + connectionDetails: + - name: username + value: fakeuser + - name: password + value: verysecurepassword + - name: endpoint + value: 127.0.0.1 + - name: green-resource + condition: observed.composite.resource.spec.deployment.green == true + base: + apiVersion: nop.crossplane.io/v1alpha1 + kind: NopResource + spec: + forProvider: + fields: + integerField: 42 + stringField: "green" + objectField: + stringField: "greenObject" + arrayField: + - stringField: "greenArray" + conditionAfter: + - time: 5s + conditionType: Ready + conditionStatus: "True" + connectionDetails: + - name: username + value: fakeuser + - name: password + value: verysecurepassword + - name: endpoint + value: 127.0.0.1 + diff --git a/example/conditionals/definition.yaml b/example/conditionals/definition.yaml new file mode 100644 index 0000000..e88d9a6 --- /dev/null +++ b/example/conditionals/definition.yaml @@ -0,0 +1,33 @@ +apiVersion: apiextensions.crossplane.io/v1 +kind: CompositeResourceDefinition +metadata: + name: xnopconditionals.nop.example.org +spec: + group: nop.example.org + names: + kind: XNopConditional + plural: xnopconditionals + versions: + - name: v1alpha1 + referenceable: true + served: true + schema: + openAPIV3Schema: + type: object + properties: + spec: + type: object + properties: + env: + type: string + render: + type: boolean + deployment: + type: object + properties: + blue: + description: Activate the blue resource + type: boolean + green: + description: Activate the green resource + type: boolean \ No newline at end of file diff --git a/example/conditionals/functions.yaml b/example/conditionals/functions.yaml new file mode 100644 index 0000000..424e867 --- /dev/null +++ b/example/conditionals/functions.yaml @@ -0,0 +1,8 @@ +apiVersion: pkg.crossplane.io/v1beta1 +kind: Function +metadata: + name: function-patch-and-transform + # annotations: + # render.crossplane.io/runtime: Development +spec: + package: xpkg.upbound.io/crossplane-contrib/function-patch-and-transform:v0.2.1 diff --git a/example/conditionals/manifest.yaml b/example/conditionals/manifest.yaml new file mode 100644 index 0000000..6786637 --- /dev/null +++ b/example/conditionals/manifest.yaml @@ -0,0 +1,8 @@ +apiVersion: pkg.crossplane.io/v1beta1 +kind: Function +metadata: + name: function-conditional-patch-and-transform + annotations: + render.crossplane.io/runtime: Development +spec: + package: xpkg.upbound.io/borrelli-org/function-conditional-patch-and-transform:v0.4.0 diff --git a/example/conditionals/provider.yaml b/example/conditionals/provider.yaml new file mode 100644 index 0000000..1e28f83 --- /dev/null +++ b/example/conditionals/provider.yaml @@ -0,0 +1,6 @@ +apiVersion: pkg.crossplane.io/v1 +kind: Provider +metadata: + name: provider-nop +spec: + package: xpkg.upbound.io/crossplane-contrib/provider-nop:v0.2.0 \ No newline at end of file diff --git a/example/conditionals/xr.yaml b/example/conditionals/xr.yaml new file mode 100644 index 0000000..6ce819f --- /dev/null +++ b/example/conditionals/xr.yaml @@ -0,0 +1,10 @@ +apiVersion: nop.example.org/v1alpha1 +kind: XNopConditional +metadata: + name: test-resource +spec: + env: prod + render: false + deployment: + blue: true + green: false diff --git a/fn.go b/fn.go index 6dc9e4b..4229f54 100644 --- a/fn.go +++ b/fn.go @@ -22,6 +22,8 @@ import ( "github.com/crossplane-contrib/function-patch-and-transform/input/v1beta1" ) +const conditionError = "Condition error" + // Function performs patch-and-transform style Composition. type Function struct { fnv1beta1.UnimplementedFunctionRunnerServiceServer @@ -45,6 +47,21 @@ func (f *Function) RunFunction(ctx context.Context, req *fnv1beta1.RunFunctionRe return rsp, nil } + // Evaluate any Conditions using the values from the Observed XR + if input.Condition != nil { + // Evaluate the condition to see if we should run + run, err := EvaluateCondition(input.Condition, req) + if err != nil { + response.Fatal(rsp, errors.Wrap(err, conditionError)) + return rsp, nil + } + if !run { + log.Debug("Condition evaluated to false. Skipping run.") + return rsp, nil + } + log.Debug("Condition evaluated to true.") + } + // Our input is an opaque object nested in a Composition, so unfortunately // it won't handle validation for us. if err := ValidateResources(input); err != nil { @@ -140,6 +157,20 @@ func (f *Function) RunFunction(ctx context.Context, req *fnv1beta1.RunFunctionRe dcd := &resource.DesiredComposed{Resource: composed.New()} + if t.Condition != nil { + // Evaluate the condition to see if we should skip this template. + run, err := EvaluateCondition(t.Condition, req) + if err != nil { + log.Info(err.Error()) + response.Fatal(rsp, errors.Wrap(err, conditionError)) + return rsp, nil + } + if !run { + log.Debug("Condition evaluated to false. Skipping template.") + continue + } + log.Debug("Condition evaluated to true.") + } // If we have a base template, render it into our desired resource. If a // previous Function produced a desired resource with this name we'll // overwrite it. If we don't have a base template we'll try to patch to diff --git a/input/v1beta1/conditions.go b/input/v1beta1/conditions.go new file mode 100644 index 0000000..47038c5 --- /dev/null +++ b/input/v1beta1/conditions.go @@ -0,0 +1,6 @@ +package v1beta1 + +// Condition defines the condition for rendering. +// Conditions are defined using the Common Expression Language +// For more information refer to https://github.com/google/cel-spec +type Condition *string diff --git a/input/v1beta1/resources.go b/input/v1beta1/resources.go index c86f447..528240a 100644 --- a/input/v1beta1/resources.go +++ b/input/v1beta1/resources.go @@ -20,6 +20,9 @@ type Resources struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` + // Condition defines a CEL condition whether this function will render + Condition Condition `json:"condition,omitempty"` + // PatchSets define a named set of patches that may be included by any // resource. PatchSets cannot themselves refer to other PatchSets. // +optional diff --git a/input/v1beta1/resources_common.go b/input/v1beta1/resources_common.go index c1d750b..d5d4b5e 100644 --- a/input/v1beta1/resources_common.go +++ b/input/v1beta1/resources_common.go @@ -59,6 +59,9 @@ type ComposedTemplate struct { // +optional Base *runtime.RawExtension `json:"base,omitempty"` + // Condition defines a CEL condition whether this managed resource will render + Condition Condition `json:"condition,omitempty"` + // Patches to and from the composed resource. // +optional Patches []ComposedPatch `json:"patches,omitempty"` diff --git a/input/v1beta1/zz_generated.deepcopy.go b/input/v1beta1/zz_generated.deepcopy.go index bd97bd7..99aba00 100644 --- a/input/v1beta1/zz_generated.deepcopy.go +++ b/input/v1beta1/zz_generated.deepcopy.go @@ -78,6 +78,11 @@ func (in *ComposedTemplate) DeepCopyInto(out *ComposedTemplate) { *out = new(runtime.RawExtension) (*in).DeepCopyInto(*out) } + if in.Condition != nil { + in, out := &in.Condition, &out.Condition + *out = new(string) + **out = **in + } if in.Patches != nil { in, out := &in.Patches, &out.Patches *out = make([]ComposedPatch, len(*in)) @@ -460,6 +465,11 @@ func (in *Resources) DeepCopyInto(out *Resources) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + if in.Condition != nil { + in, out := &in.Condition, &out.Condition + *out = new(string) + **out = **in + } if in.PatchSets != nil { in, out := &in.PatchSets, &out.PatchSets *out = make([]PatchSet, len(*in)) diff --git a/package/input/pt.fn.crossplane.io_resources.yaml b/package/input/pt.fn.crossplane.io_resources.yaml index 9734fdd..d5f95dd 100644 --- a/package/input/pt.fn.crossplane.io_resources.yaml +++ b/package/input/pt.fn.crossplane.io_resources.yaml @@ -28,6 +28,10 @@ spec: may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string + condition: + description: Condition defines a CEL condition whether this function will + render + type: string environment: description: |- Environment represents the Composition environment. @@ -111,8 +115,8 @@ spec: description: |- FromFieldPath specifies how to patch from a field path. The default is 'Optional', which means the patch will be a no-op if the specified - fromFieldPath does not exist. Use 'Required' to prevent the creation of a - new composed resource until the required path exists. + fromFieldPath does not exist. Use 'Required' if the patch should fail if + the specified path does not exist. enum: - Optional - Required @@ -454,8 +458,8 @@ spec: description: |- FromFieldPath specifies how to patch from a field path. The default is 'Optional', which means the patch will be a no-op if the specified - fromFieldPath does not exist. Use 'Required' to prevent the creation of a - new composed resource until the required path exists. + fromFieldPath does not exist. Use 'Required' if the patch should fail if + the specified path does not exist. enum: - Optional - Required @@ -736,6 +740,10 @@ spec: type: object x-kubernetes-embedded-resource: true x-kubernetes-preserve-unknown-fields: true + condition: + description: Condition defines a CEL condition whether this managed + resource will render + type: string connectionDetails: description: |- ConnectionDetails lists the propagation secret keys from this composed @@ -861,8 +869,8 @@ spec: description: |- FromFieldPath specifies how to patch from a field path. The default is 'Optional', which means the patch will be a no-op if the specified - fromFieldPath does not exist. Use 'Required' to prevent the creation of a - new composed resource until the required path exists. + fromFieldPath does not exist. Use 'Required' if the patch should fail if + the specified path does not exist. enum: - Optional - Required From 49d42979437b247bcd3e1013cf9f9d67711d62b7 Mon Sep 17 00:00:00 2001 From: Steven Borrelli Date: Tue, 30 Jan 2024 15:12:47 -0600 Subject: [PATCH 28/31] update go modules Signed-off-by: Steven Borrelli --- go.mod | 4 ++++ go.sum | 8 ++++++++ package/input/pt.fn.crossplane.io_resources.yaml | 12 ++++++------ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 928887b..74d31a7 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/alecthomas/kong v0.8.1 github.com/crossplane/crossplane-runtime v1.15.1 github.com/crossplane/function-sdk-go v0.2.0 + github.com/google/cel-go v0.19.0 github.com/google/go-cmp v0.6.0 github.com/pkg/errors v0.9.1 google.golang.org/protobuf v1.32.0 @@ -20,6 +21,7 @@ require ( require ( dario.cat/mergo v1.0.0 // indirect + github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -58,6 +60,7 @@ require ( github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stoewer/go-strcase v1.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect @@ -71,6 +74,7 @@ require ( golang.org/x/tools v0.17.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240116215550-a9fa1716bcac // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect google.golang.org/grpc v1.61.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/go.sum b/go.sum index ce1c171..614244e 100644 --- a/go.sum +++ b/go.sum @@ -12,6 +12,8 @@ github.com/antchfx/htmlquery v1.2.4 h1:qLteofCMe/KGovBI6SQgmou2QNyedFUW+pE+BpeZ4 github.com/antchfx/htmlquery v1.2.4/go.mod h1:2xO6iu3EVWs7R2JYqBbp8YzG50gj/ofqs5/0VZoDZLc= github.com/antchfx/xpath v1.2.0 h1:mbwv7co+x0RwgeGAOHdrKy89GvHaGvxxBtPK0uF9Zr8= github.com/antchfx/xpath v1.2.0/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs= +github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= +github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -66,6 +68,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/cel-go v0.19.0 h1:vVgaZoHPBDd1lXCYGQOh5A06L4EtuIfmqQ/qnSXSKiU= +github.com/google/cel-go v0.19.0/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -179,6 +183,8 @@ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= +github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -275,6 +281,8 @@ gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto/googleapis/api v0.0.0-20240116215550-a9fa1716bcac h1:OZkkudMUu9LVQMCoRUbI/1p5VCo9BOrlvkqMvWtqa6s= +google.golang.org/genproto/googleapis/api v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:B5xPO//w8qmBDjGReYLpR6UJPnkldGkCSMoH/2vxJeg= google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac h1:nUQEQmH/csSvFECKYRv6HWEyypysidKl2I6Qpsglq/0= google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA= google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= diff --git a/package/input/pt.fn.crossplane.io_resources.yaml b/package/input/pt.fn.crossplane.io_resources.yaml index d5f95dd..03cfc4f 100644 --- a/package/input/pt.fn.crossplane.io_resources.yaml +++ b/package/input/pt.fn.crossplane.io_resources.yaml @@ -115,8 +115,8 @@ spec: description: |- FromFieldPath specifies how to patch from a field path. The default is 'Optional', which means the patch will be a no-op if the specified - fromFieldPath does not exist. Use 'Required' if the patch should fail if - the specified path does not exist. + fromFieldPath does not exist. Use 'Required' to prevent the creation of a + new composed resource until the required path exists. enum: - Optional - Required @@ -458,8 +458,8 @@ spec: description: |- FromFieldPath specifies how to patch from a field path. The default is 'Optional', which means the patch will be a no-op if the specified - fromFieldPath does not exist. Use 'Required' if the patch should fail if - the specified path does not exist. + fromFieldPath does not exist. Use 'Required' to prevent the creation of a + new composed resource until the required path exists. enum: - Optional - Required @@ -869,8 +869,8 @@ spec: description: |- FromFieldPath specifies how to patch from a field path. The default is 'Optional', which means the patch will be a no-op if the specified - fromFieldPath does not exist. Use 'Required' if the patch should fail if - the specified path does not exist. + fromFieldPath does not exist. Use 'Required' to prevent the creation of a + new composed resource until the required path exists. enum: - Optional - Required From 4b208e6f37a974866c83bf043b5c0ed9561d1c5d Mon Sep 17 00:00:00 2001 From: Steven Borrelli Date: Fri, 23 Feb 2024 18:33:31 -0600 Subject: [PATCH 29/31] remove render.go Signed-off-by: Steven Borrelli --- go.mod | 2 - render.go | 151 ------------------------------------------------------ 2 files changed, 153 deletions(-) delete mode 100644 render.go diff --git a/go.mod b/go.mod index d7de1e2..529a3ef 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,6 @@ require ( github.com/crossplane/crossplane-runtime v1.15.1 github.com/crossplane/function-sdk-go v0.2.0 github.com/google/cel-go v0.19.0 - github.com/google/cel-go v0.16.1 github.com/google/go-cmp v0.6.0 github.com/pkg/errors v0.9.1 google.golang.org/protobuf v1.32.0 @@ -23,7 +22,6 @@ require ( require ( dario.cat/mergo v1.0.0 // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect - github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/render.go b/render.go deleted file mode 100644 index e6b79ad..0000000 --- a/render.go +++ /dev/null @@ -1,151 +0,0 @@ -package main - -import ( - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/util/json" - - "github.com/crossplane/crossplane-runtime/pkg/errors" - "github.com/crossplane/crossplane-runtime/pkg/resource" - - "github.com/crossplane/function-sdk-go/resource/composed" - "github.com/crossplane/function-sdk-go/resource/composite" - - "github.com/upboundcare/function-conditional-patch-and-transform/input/v1beta1" -) - -// Error strings -const ( - errUnmarshalJSON = "cannot unmarshal JSON data" - - errFmtKindChanged = "cannot change the kind of a composed resource from %s to %s (possible composed resource template mismatch)" - errFmtNamePrefixLabel = "cannot find top-level composite resource name label %q in composite resource metadata" - - // TODO(negz): Include more detail such as field paths if they exist. - // Perhaps require each patch type to have a String() method to help - // identify it. - errFmtPatch = "cannot apply the %q patch at index %d" -) - -// RenderFromJSON renders the supplied resource from JSON bytes. -func RenderFromJSON(o resource.Object, data []byte) error { - gvk := o.GetObjectKind().GroupVersionKind() - name := o.GetName() - namespace := o.GetNamespace() - - if err := json.Unmarshal(data, o); err != nil { - return errors.Wrap(err, errUnmarshalJSON) - } - - // TODO(negz): Should we return an error if the name or namespace change, - // rather than just silently re-setting it? Presumably these _changing_ is a - // sign that something has gone wrong, similar to the GVK changing. What - // about the UID changing? - - // Unmarshalling the template will overwrite any existing fields, so we must - // restore the existing name, if any. - o.SetName(name) - o.SetNamespace(namespace) - - // This resource already had a GVK (probably because it already exists), but - // when we rendered its template it changed. This shouldn't happen. Either - // someone changed the kind in the template or we're trying to use the wrong - // template (e.g. because the order of an array of anonymous templates - // changed). - empty := schema.GroupVersionKind{} - if gvk != empty && o.GetObjectKind().GroupVersionKind() != gvk { - return errors.Errorf(errFmtKindChanged, gvk, o.GetObjectKind().GroupVersionKind()) - } - - return nil -} - -// RenderEnvironmentPatches renders the supplied environment by applying all -// patches that are to the environment, from the supplied XR. -func RenderEnvironmentPatches(env *unstructured.Unstructured, oxr, dxr *composite.Unstructured, ps []v1beta1.EnvironmentPatch) error { - for i, p := range ps { - p := p - switch p.Type { - case v1beta1.PatchTypeToEnvironmentFieldPath, v1beta1.PatchTypeCombineToEnvironment: - if err := ApplyToObjects(&p, env, oxr); err != nil { - return errors.Wrapf(err, errFmtPatch, p.Type, i) - } - case v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeCombineFromEnvironment: - if err := ApplyToObjects(&p, env, dxr); err != nil { - return errors.Wrapf(err, errFmtPatch, p.Type, i) - } - case v1beta1.PatchTypePatchSet, v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeCombineFromComposite, v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeCombineToComposite: - // nothing to do - } - } - return nil -} - -// RenderComposedPatches renders the supplied composed resource by applying all -// patches that are to or from the supplied composite resource and environment -// in the order they were defined. Properly selecting the right source or -// destination between observed and desired resources. -func RenderComposedPatches( //nolint:gocyclo // just a switch - ocd *composed.Unstructured, - dcd *composed.Unstructured, - oxr *composite.Unstructured, - dxr *composite.Unstructured, - env *unstructured.Unstructured, - ps []v1beta1.ComposedPatch, -) (errs []error, store bool) { - for i, p := range ps { - p := p - switch t := p.Type; t { - case v1beta1.PatchTypeToCompositeFieldPath, v1beta1.PatchTypeCombineToComposite: - // TODO(negz): Should failures to patch the XR be terminal? It could - // indicate a required patch failed. A required patch means roughly - // "this patch has to succeed before you mutate the resource". This - // is useful to make sure we never create a composed resource in the - // wrong state. It's less clear how useful it is for the XR, given - // we'll only ever be updating it, not creating it. - - // We want to patch the XR from observed composed resources, not - // from desired state. This is because folks will typically be - // patching from a field that is set once the observed resource is - // applied such as its status. - if ocd == nil { - continue - } - if err := ApplyToObjects(&p, dxr, ocd); err != nil { - errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i)) - } - case v1beta1.PatchTypeToEnvironmentFieldPath, v1beta1.PatchTypeCombineToEnvironment: - // TODO(negz): Same as above, but for the Environment. What does it - // mean for a required patch to the environment to fail? Should it - // be terminal? - - // Run all patches that are from the (observed) composed resource to - // the environment. - if ocd == nil { - continue - } - if err := ApplyToObjects(&p, env, ocd); err != nil { - errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i)) - } - // If either of the below renderings return an error, most likely a - // required FromComposite or FromEnvironment patch failed. A required - // patch means roughly "this patch has to succeed before you mutate the - // resource." This is useful to make sure we never create a composed - // resource in the wrong state. To that end, we don't want to add this - // resource to our accumulated desired state. - case v1beta1.PatchTypeFromCompositeFieldPath, v1beta1.PatchTypeCombineFromComposite: - if err := ApplyToObjects(&p, oxr, dcd); err != nil { - errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i)) - return errs, false - } - case v1beta1.PatchTypeFromEnvironmentFieldPath, v1beta1.PatchTypeCombineFromEnvironment: - if err := ApplyToObjects(&p, env, dcd); err != nil { - errs = append(errs, errors.Wrapf(err, errFmtPatch, t, i)) - return errs, false - } - case v1beta1.PatchTypePatchSet: - // Already resolved - nothing to do. - } - } - return errs, true -} From faf331700a090c6b96886c58533317d870553b4e Mon Sep 17 00:00:00 2001 From: Steven Borrelli Date: Fri, 23 Feb 2024 18:36:13 -0600 Subject: [PATCH 30/31] remove old examples Signed-off-by: Steven Borrelli --- example/composition.yaml | 30 ------------ example/conditionals/README.md | 49 ------------------- example/conditionals/composition.yaml | 70 --------------------------- example/conditionals/definition.yaml | 33 ------------- example/conditionals/functions.yaml | 8 --- example/conditionals/manifest.yaml | 8 --- example/conditionals/provider.yaml | 6 --- example/conditionals/xr.yaml | 10 ---- 8 files changed, 214 deletions(-) delete mode 100644 example/composition.yaml delete mode 100644 example/conditionals/README.md delete mode 100644 example/conditionals/composition.yaml delete mode 100644 example/conditionals/definition.yaml delete mode 100644 example/conditionals/functions.yaml delete mode 100644 example/conditionals/manifest.yaml delete mode 100644 example/conditionals/provider.yaml delete mode 100644 example/conditionals/xr.yaml diff --git a/example/composition.yaml b/example/composition.yaml deleted file mode 100644 index f2b6d4b..0000000 --- a/example/composition.yaml +++ /dev/null @@ -1,30 +0,0 @@ -apiVersion: apiextensions.crossplane.io/v1 -kind: Composition -metadata: - name: function-patch-and-transform -spec: - compositeTypeRef: - apiVersion: example.crossplane.io/v1 - kind: XR - mode: Pipeline - pipeline: - - step: patch-and-transform - functionRef: - name: function-patch-and-transform - input: - apiVersion: pt.fn.crossplane.io/v1beta1 - kind: Resources - resources: - - name: bucket - base: - apiVersion: s3.aws.upbound.io/v1beta1 - kind: Bucket - patches: - - type: FromCompositeFieldPath - fromFieldPath: "spec.location" - toFieldPath: "spec.forProvider.region" - transforms: - - type: map - map: - EU: "eu-north-1" - US: "us-east-2" \ No newline at end of file diff --git a/example/conditionals/README.md b/example/conditionals/README.md deleted file mode 100644 index a11e471..0000000 --- a/example/conditionals/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# Conditional Rendering of Individual Resources - -In this example, we show how each resource in a pipeline step can -be individually rendered based on a condition. We will have a blue and a -green deployment that the user can activate: - -```yaml -apiVersion: nop.example.org/v1alpha1 -kind: XNopConditional -metadata: - name: test-resource -spec: - env: dev - render: true - deployment: - blue: true - green: false -``` - -In our Composition both the `blue-resource` and the `green-resource` have a -`condition` that determines if they will be run. - -```yaml - resources: - - name: blue-resource - condition: observed.composite.resource.spec.deployment.blue == true - base: - apiVersion: nop.crossplane.io/v1alpha1 - kind: NopResource - spec: - forProvider: -``` - -## Running This Example Locally - -This example can be rendered using `crossplane beta render`: - -```shell -crossplane beta render xr.yaml composition.yaml functions.yaml -``` - -## Running this example in a Cluster - -- Install Crossplane version 1.14 or newer. See -- Install the nop provider in `kubectl apply -f provider.yaml` -- Install the XRD & Composition in `kubectl apply -f definition.yaml -f composition.yaml` -- Install the Function `kubectl apply -f functions.yaml` - -Finally install the xr: `kubectl apply -f xr` diff --git a/example/conditionals/composition.yaml b/example/conditionals/composition.yaml deleted file mode 100644 index 7fc75ee..0000000 --- a/example/conditionals/composition.yaml +++ /dev/null @@ -1,70 +0,0 @@ ---- -apiVersion: apiextensions.crossplane.io/v1 -kind: Composition -metadata: - name: xnopconditionals.nop.example.org -spec: - compositeTypeRef: - apiVersion: nop.example.org/v1alpha1 - kind: XNopConditional - mode: Pipeline - pipeline: - - step: conditional-patch-and-transform - functionRef: - name: function-conditional-patch-and-transform - input: - apiVersion: conditional-pt.fn.crossplane.io/v1beta1 - kind: Resources - condition: observed.composite.resource.spec.render == true - resources: - - name: blue-resource - condition: observed.composite.resource.spec.deployment.blue == true - base: - apiVersion: nop.crossplane.io/v1alpha1 - kind: NopResource - spec: - forProvider: - fields: - integerField: 42 - stringField: "blue" - objectField: - stringField: "blueObject" - arrayField: - - stringField: "blueArray" - conditionAfter: - - time: 5s - conditionType: Ready - conditionStatus: "True" - connectionDetails: - - name: username - value: fakeuser - - name: password - value: verysecurepassword - - name: endpoint - value: 127.0.0.1 - - name: green-resource - condition: observed.composite.resource.spec.deployment.green == true - base: - apiVersion: nop.crossplane.io/v1alpha1 - kind: NopResource - spec: - forProvider: - fields: - integerField: 42 - stringField: "green" - objectField: - stringField: "greenObject" - arrayField: - - stringField: "greenArray" - conditionAfter: - - time: 5s - conditionType: Ready - conditionStatus: "True" - connectionDetails: - - name: username - value: fakeuser - - name: password - value: verysecurepassword - - name: endpoint - value: 127.0.0.1 - diff --git a/example/conditionals/definition.yaml b/example/conditionals/definition.yaml deleted file mode 100644 index e88d9a6..0000000 --- a/example/conditionals/definition.yaml +++ /dev/null @@ -1,33 +0,0 @@ -apiVersion: apiextensions.crossplane.io/v1 -kind: CompositeResourceDefinition -metadata: - name: xnopconditionals.nop.example.org -spec: - group: nop.example.org - names: - kind: XNopConditional - plural: xnopconditionals - versions: - - name: v1alpha1 - referenceable: true - served: true - schema: - openAPIV3Schema: - type: object - properties: - spec: - type: object - properties: - env: - type: string - render: - type: boolean - deployment: - type: object - properties: - blue: - description: Activate the blue resource - type: boolean - green: - description: Activate the green resource - type: boolean \ No newline at end of file diff --git a/example/conditionals/functions.yaml b/example/conditionals/functions.yaml deleted file mode 100644 index 424e867..0000000 --- a/example/conditionals/functions.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: pkg.crossplane.io/v1beta1 -kind: Function -metadata: - name: function-patch-and-transform - # annotations: - # render.crossplane.io/runtime: Development -spec: - package: xpkg.upbound.io/crossplane-contrib/function-patch-and-transform:v0.2.1 diff --git a/example/conditionals/manifest.yaml b/example/conditionals/manifest.yaml deleted file mode 100644 index 6786637..0000000 --- a/example/conditionals/manifest.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: pkg.crossplane.io/v1beta1 -kind: Function -metadata: - name: function-conditional-patch-and-transform - annotations: - render.crossplane.io/runtime: Development -spec: - package: xpkg.upbound.io/borrelli-org/function-conditional-patch-and-transform:v0.4.0 diff --git a/example/conditionals/provider.yaml b/example/conditionals/provider.yaml deleted file mode 100644 index 1e28f83..0000000 --- a/example/conditionals/provider.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: pkg.crossplane.io/v1 -kind: Provider -metadata: - name: provider-nop -spec: - package: xpkg.upbound.io/crossplane-contrib/provider-nop:v0.2.0 \ No newline at end of file diff --git a/example/conditionals/xr.yaml b/example/conditionals/xr.yaml deleted file mode 100644 index 6ce819f..0000000 --- a/example/conditionals/xr.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: nop.example.org/v1alpha1 -kind: XNopConditional -metadata: - name: test-resource -spec: - env: prod - render: false - deployment: - blue: true - green: false From a98d431ba498480e0a7e2d5694189f86c9d53d59 Mon Sep 17 00:00:00 2001 From: Steven Borrelli Date: Fri, 23 Feb 2024 19:02:31 -0600 Subject: [PATCH 31/31] change push org Signed-off-by: Steven Borrelli --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b85bb3c..d63227a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,7 @@ env: # The package to push, without a version tag. The default matches GitHub. For # example xpkg.upbound.io/crossplane/function-template-go. - XPKG: xpkg.upbound.io/upboundcare/function-conditional-patch-and-transform + XPKG: xpkg.upbound.io/borrelli-org/function-conditional-patch-and-transform # The package version to push. The default is 0.0.0-gitsha. XPKG_VERSION: ${{ inputs.version }}