From 070819754fa48006e850c794b239fb8f041f0e02 Mon Sep 17 00:00:00 2001 From: Pinny Date: Wed, 1 May 2024 13:01:39 +0000 Subject: [PATCH 01/13] Bump dependencies --- Dockerfile | 4 ++-- go.mod | 14 +++++++------- go.sum | 43 ++++++++++++++++++++++--------------------- hack/Dockerfile_fips | 4 ++-- 4 files changed, 33 insertions(+), 32 deletions(-) diff --git a/Dockerfile b/Dockerfile index d8ea89f3b..3f28010d0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,8 +3,8 @@ # Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 -ARG BUILD_IMAGE=golang:1.22.2@sha256:450e3822c7a135e1463cd83e51c8e2eb03b86a02113c89424e6f0f8344bb4168 -ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:f41b84cda410b05cc690c2e33d1973a31c6165a2721e2b5343aab50fecb63441 +ARG BUILD_IMAGE=golang:1.22.2@sha256:d5302d40dc5fbbf38ec472d1848a9d2391a13f93293a6a5b0b87c99dc0eaa6ae +ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:e9ac71e2b8e279a8372741b7a0293afda17650d926900233ec3a7b2b7c22a246 # Prepare to cross-compile by always running the build stage in the build platform, not the target platform. FROM --platform=$BUILDPLATFORM $BUILD_IMAGE as build-env diff --git a/go.mod b/go.mod index 44da35e4c..f4c94757a 100644 --- a/go.mod +++ b/go.mod @@ -35,7 +35,7 @@ replace github.com/coreos/go-oidc/v3 => github.com/coreos/go-oidc/v3 v3.9.0 require ( github.com/MakeNowJust/heredoc/v2 v2.0.1 - github.com/chromedp/cdproto v0.0.0-20240421230201-ab917191657d + github.com/chromedp/cdproto v0.0.0-20240426225625-909263490071 github.com/chromedp/chromedp v0.9.5 github.com/coreos/go-oidc/v3 v3.10.0 github.com/coreos/go-semver v0.3.1 @@ -63,7 +63,7 @@ require ( github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 - github.com/tdewolff/minify/v2 v2.20.19 + github.com/tdewolff/minify/v2 v2.20.20 go.uber.org/mock v0.4.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.22.0 @@ -81,8 +81,8 @@ require ( k8s.io/gengo v0.0.0-20240404160639-a0386bf69313 k8s.io/klog/v2 v2.120.1 k8s.io/kube-aggregator v0.30.0 - k8s.io/kube-openapi v0.0.0-20240411171206-dc4e619f62f3 - k8s.io/utils v0.0.0-20240310230437-4693a0247e57 + k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f + k8s.io/utils v0.0.0-20240423183400-0849a56e8f22 sigs.k8s.io/yaml v1.4.0 ) @@ -163,7 +163,7 @@ require ( github.com/spf13/viper v1.16.0 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect github.com/subosito/gotenv v1.4.2 // indirect - github.com/tdewolff/parse/v2 v2.7.12 // indirect + github.com/tdewolff/parse/v2 v2.7.13 // indirect go.etcd.io/etcd/api/v3 v3.5.10 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect go.etcd.io/etcd/client/v3 v3.5.10 // indirect @@ -185,10 +185,10 @@ require ( go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect - golang.org/x/mod v0.15.0 // indirect + golang.org/x/mod v0.17.0 // indirect golang.org/x/sys v0.19.0 // indirect golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.18.0 // indirect + golang.org/x/tools v0.20.0 // indirect google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect diff --git a/go.sum b/go.sum index 253810f14..846aa7397 100644 --- a/go.sum +++ b/go.sum @@ -70,8 +70,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL 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/chromedp/cdproto v0.0.0-20240202021202-6d0b6a386732/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= -github.com/chromedp/cdproto v0.0.0-20240421230201-ab917191657d h1:x9d0XwRV3aWw1gAZtv0LrI39U+Efjp0mtyXRyikGb9Y= -github.com/chromedp/cdproto v0.0.0-20240421230201-ab917191657d/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= +github.com/chromedp/cdproto v0.0.0-20240426225625-909263490071 h1:RdCf9hH3xq5vJifrjGB7zQlFkdRB3pAppcX2helDq2U= +github.com/chromedp/cdproto v0.0.0-20240426225625-909263490071/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= github.com/chromedp/chromedp v0.9.5 h1:viASzruPJOiThk7c5bueOUY91jGLJVximoEMGoH93rg= github.com/chromedp/chromedp v0.9.5/go.mod h1:D4I2qONslauw/C7INoCir1BJkSwBYMyZgx8X276z3+Y= github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic= @@ -172,7 +172,8 @@ github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+ github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gobuffalo/attrs v1.0.3/go.mod h1:KvDJCE0avbufqS0Bw3UV7RQynESY0jjod+572ctX4t8= github.com/gobuffalo/envy v1.10.2/go.mod h1:qGAGwdvDsaEtPhfBzb3o0SfDea8ByGn9j8bKmVft9z8= github.com/gobuffalo/fizz v1.14.4/go.mod h1:9/2fGNXNeIFOXEEgTPJwiK63e44RjG+Nc4hfMm1ArGM= @@ -272,8 +273,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf 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-20221010195024-131d412537ea h1:R3VfsTXMMK4JCWZDdxScmnTzu9n9YRsDvguLis0U/b8= -github.com/google/pprof v0.0.0-20221010195024-131d412537ea/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= 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.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -462,10 +463,10 @@ github.com/nyaruka/phonenumbers v1.1.1/go.mod h1:cGaEsOrLjIL0iKGqJR5Rfywy86dSkbA github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM= github.com/oleiade/reflections v1.0.1/go.mod h1:rdFxbxq4QXVZWj0F+e9jqjDkc7dbp97vkRixKo2JR60= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= -github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= -github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= -github.com/onsi/gomega v1.31.0 h1:54UJxxj6cPInHS3a35wm6BK/F9nHYueZ1NVujHDrnXE= -github.com/onsi/gomega v1.31.0/go.mod h1:DW9aCi7U6Yi40wNVAvT6kzFnEVEI5n3DloYBiKiT6zk= +github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= +github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= github.com/openzipkin/zipkin-go v0.4.1 h1:kNd/ST2yLLWhaWrkgchya40TJabe8Hioj9udfPcEO5A= github.com/openzipkin/zipkin-go v0.4.1/go.mod h1:qY0VqDSN1pOBN94dBc6w2GJlWLiovAyg7Qt6/I9HecM= github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw= @@ -565,10 +566,10 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= -github.com/tdewolff/minify/v2 v2.20.19 h1:tX0SR0LUrIqGoLjXnkIzRSIbKJ7PaNnSENLD4CyH6Xo= -github.com/tdewolff/minify/v2 v2.20.19/go.mod h1:ulkFoeAVWMLEyjuDz1ZIWOA31g5aWOawCFRp9R/MudM= -github.com/tdewolff/parse/v2 v2.7.12 h1:tgavkHc2ZDEQVKy1oWxwIyh5bP4F5fEh/JmBwPP/3LQ= -github.com/tdewolff/parse/v2 v2.7.12/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= +github.com/tdewolff/minify/v2 v2.20.20 h1:vhULb+VsW2twkplgsawAoUY957efb+EdiZ7zu5fUhhk= +github.com/tdewolff/minify/v2 v2.20.20/go.mod h1:GYaLXFpIIwsX99apQHXfGdISUdlA98wmaoWxjT9C37k= +github.com/tdewolff/parse/v2 v2.7.13 h1:iSiwOUkCYLNfapHoqdLcqZVgvQ0jrsao8YYKP/UJYTI= +github.com/tdewolff/parse/v2 v2.7.13/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo= github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8= @@ -723,8 +724,8 @@ 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.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.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= @@ -944,8 +945,8 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= +golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1092,10 +1093,10 @@ k8s.io/kms v0.30.0 h1:ZlnD/ei5lpvUlPw6eLfVvH7d8i9qZ6HwUQgydNVks8g= k8s.io/kms v0.30.0/go.mod h1:GrMurD0qk3G4yNgGcsCEmepqf9KyyIrTXYR2lyUOJC4= k8s.io/kube-aggregator v0.30.0 h1:+Opc0lmhRmHbNM4m3mLSsUFmK/ikMapO9rvGirX5CEM= k8s.io/kube-aggregator v0.30.0/go.mod h1:KbZZkSSjYE6vkB2TSuZ9GBjU3ucgL7YxT8yX8wll0iQ= -k8s.io/kube-openapi v0.0.0-20240411171206-dc4e619f62f3 h1:SbdLaI6mM6ffDSJCadEaD4IkuPzepLDGlkd2xV0t1uA= -k8s.io/kube-openapi v0.0.0-20240411171206-dc4e619f62f3/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0gQBEuevE/AaBsHY= -k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f h1:0LQagt0gDpKqvIkAMPaRGcXawNMouPECM1+F9BVxEaM= +k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f/go.mod h1:S9tOR0FxgyusSNR+MboCuiDpVWkAifZvaYI1Q2ubgro= +k8s.io/utils v0.0.0-20240423183400-0849a56e8f22 h1:ao5hUqGhsqdm+bYbjH/pRkCs0unBGe9UyDahzs9zQzQ= +k8s.io/utils v0.0.0-20240423183400-0849a56e8f22/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= diff --git a/hack/Dockerfile_fips b/hack/Dockerfile_fips index 3bad74690..63261bc0b 100644 --- a/hack/Dockerfile_fips +++ b/hack/Dockerfile_fips @@ -16,8 +16,8 @@ # See https://go.googlesource.com/go/+/dev.boringcrypto/README.boringcrypto.md # and https://kupczynski.info/posts/fips-golang/ for details. -ARG BUILD_IMAGE=golang:1.22.2@sha256:450e3822c7a135e1463cd83e51c8e2eb03b86a02113c89424e6f0f8344bb4168 -ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:f41b84cda410b05cc690c2e33d1973a31c6165a2721e2b5343aab50fecb63441 +ARG BUILD_IMAGE=golang:1.22.2@sha256:d5302d40dc5fbbf38ec472d1848a9d2391a13f93293a6a5b0b87c99dc0eaa6ae +ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:e9ac71e2b8e279a8372741b7a0293afda17650d926900233ec3a7b2b7c22a246 # This is not currently using --platform to prepare to cross-compile because we use gcc below to build # platform-specific GCO code. This makes multi-arch builds slow due to target platform emulation. From 0a63dd104db901354f2c4df9a85999fa89d7c504 Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Wed, 1 May 2024 11:01:13 -0700 Subject: [PATCH 02/13] fix test failures caused by dep bump and update replace statements --- go.mod | 11 +++---- go.sum | 20 +++++++++--- .../registry/clientsecretrequest/rest_test.go | 7 +++- .../registry/credentialrequest/rest_test.go | 5 +++ internal/testutil/log_level.go | 32 +++++++++++++++++++ 5 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 internal/testutil/log_level.go diff --git a/go.mod b/go.mod index f4c94757a..007b905be 100644 --- a/go.mod +++ b/go.mod @@ -4,12 +4,12 @@ go 1.22.0 toolchain go1.22.2 -// This version taken from https://github.com/kubernetes/apiserver/blob/v0.29.2/go.mod#L14 to avoid compile failures. -replace github.com/google/cel-go => github.com/google/cel-go v0.17.7 +// This version taken from https://github.com/kubernetes/apiserver/blob/v0.30.0/go.mod#L14 to avoid compile failures. +replace github.com/google/cel-go => github.com/google/cel-go v0.17.8 // ory/fosite depends on ory/x which depends on opentelemetry. kubernetes/apiserver also depends on opentelemetry. // Where they clash and cause "go mod tidy" to fail, use replace directives to make it work. -// Copied from https://github.com/kubernetes/apiserver/blob/v0.29.2/go.mod#L28-L33. +// Copied from https://github.com/kubernetes/apiserver/blob/v0.30.0/go.mod#L29-L34. replace ( go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc => go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp => go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 @@ -19,16 +19,13 @@ replace ( go.opentelemetry.io/otel/trace => go.opentelemetry.io/otel/trace v1.19.0 ) -// https://github.com/kubernetes/apiserver/blob/v0.29.2/go.mod does not include this one, but it is also needed +// https://github.com/kubernetes/apiserver/blob/v0.30.0/go.mod does not include this one, but it is also needed // to resolve the clashes with ory/x, so use the same version that kubernetes/apiserver chooses for opentelemetry. replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp => go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 // This is an indirect dep which has CVE-2023-45142, so replace it with the fixed version. replace go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace => go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.44.0 -// This is an indirect dep which has CVE-2024-24786, so replace it with a fixed version -replace google.golang.org/protobuf => google.golang.org/protobuf v1.33.0 - // https://github.com/coreos/go-oidc/releases/tag/v3.10.0 starts to use https://github.com/go-jose/go-jose/releases/tag/v4.0.0. // Unfortunately this has breaking changes. replace github.com/coreos/go-oidc/v3 => github.com/coreos/go-oidc/v3 v3.9.0 diff --git a/go.sum b/go.sum index 846aa7397..76e3a40b7 100644 --- a/go.sum +++ b/go.sum @@ -228,19 +228,22 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y 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.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= 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/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/cel-go v0.17.7 h1:6ebJFzu1xO2n7TLtN+UBqShGBhlD85bhvglh5DpcfqQ= -github.com/google/cel-go v0.17.7/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= +github.com/google/cel-go v0.17.8 h1:j9m730pMZt1Fc4oKhCLUHfjj6527LuhYcYw0Rl8gqto= +github.com/google/cel-go v0.17.8/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= 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= @@ -252,7 +255,6 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ 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= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -1039,6 +1041,16 @@ 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/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.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/internal/registry/clientsecretrequest/rest_test.go b/internal/registry/clientsecretrequest/rest_test.go index af604c930..0595de17c 100644 --- a/internal/registry/clientsecretrequest/rest_test.go +++ b/internal/registry/clientsecretrequest/rest_test.go @@ -1,4 +1,4 @@ -// Copyright 2022-2023 the Pinniped contributors. All Rights Reserved. +// Copyright 2022-2024 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package clientsecretrequest @@ -33,6 +33,7 @@ import ( supervisorfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake" "go.pinniped.dev/internal/oidcclientsecretstorage" "go.pinniped.dev/internal/plog" + "go.pinniped.dev/internal/testutil" ) func TestNew(t *testing.T) { @@ -1563,8 +1564,12 @@ func TestCreate(t *testing.T) { var log bytes.Buffer logger := plog.TestZapr(t, &log) klog.SetLogger(logger) + originalKLogLevel := testutil.GetGlobalKlogLevel() + // trace.Log() utility will only log at level 2 or above, so set that for this test. + testutil.SetGlobalKlogLevel(t, 2) //nolint:staticcheck // old test of code using trace.Log() t.Cleanup(func() { klog.ClearLogger() + testutil.SetGlobalKlogLevel(t, originalKLogLevel) //nolint:staticcheck // old test of code using trace.Log() }) kubeClient := kubefake.NewSimpleClientset() diff --git a/internal/registry/credentialrequest/rest_test.go b/internal/registry/credentialrequest/rest_test.go index e7a80f17e..dffa0b69b 100644 --- a/internal/registry/credentialrequest/rest_test.go +++ b/internal/registry/credentialrequest/rest_test.go @@ -68,16 +68,21 @@ func TestCreate(t *testing.T) { var r *require.Assertions var ctrl *gomock.Controller var logger *testutil.TranscriptLogger + var originalKLogLevel klog.Level it.Before(func() { r = require.New(t) ctrl = gomock.NewController(t) logger = testutil.NewTranscriptLogger(t) //nolint:staticcheck // old test with lots of log statements klog.SetLogger(logr.New(logger)) // this is unfortunately a global logger, so can't run these tests in parallel :( + originalKLogLevel = testutil.GetGlobalKlogLevel() + // trace.Log() utility will only log at level 2 or above, so set that for this test. + testutil.SetGlobalKlogLevel(t, 2) //nolint:staticcheck // old test of code using trace.Log() }) it.After(func() { klog.ClearLogger() + testutil.SetGlobalKlogLevel(t, originalKLogLevel) //nolint:staticcheck // old test of code using trace.Log() ctrl.Finish() }) diff --git a/internal/testutil/log_level.go b/internal/testutil/log_level.go new file mode 100644 index 000000000..3d34a8a0f --- /dev/null +++ b/internal/testutil/log_level.go @@ -0,0 +1,32 @@ +// Copyright 2024 the Pinniped contributors. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +package testutil + +import ( + "strconv" + "testing" + + "github.com/stretchr/testify/require" + "k8s.io/component-base/logs" + "k8s.io/klog/v2" +) + +// Deprecated: This is meant for old tests only. +func SetGlobalKlogLevel(t *testing.T, l klog.Level) { + t.Helper() + _, err := logs.GlogSetter(strconv.Itoa(int(l))) + require.NoError(t, err) +} + +func GetGlobalKlogLevel() klog.Level { + // hack around klog not exposing a Get method + for i := klog.Level(0); i < 256; i++ { + if klog.V(i).Enabled() { + continue + } + return i - 1 + } + + return -1 +} From 5ec1ee086d3e0823ab72adbf9a7a271371e340f1 Mon Sep 17 00:00:00 2001 From: Joshua Casey Date: Thu, 25 Apr 2024 21:52:59 -0500 Subject: [PATCH 03/13] Remove deprecated deploy options --- deploy/concierge/deployment.yaml | 7 +- deploy/concierge/values.yaml | 11 ---- deploy/supervisor/helpers.lib.yaml | 10 +-- deploy/supervisor/service.yaml | 43 ++---------- deploy/supervisor/values.yaml | 101 +++++------------------------ 5 files changed, 26 insertions(+), 146 deletions(-) diff --git a/deploy/concierge/deployment.yaml b/deploy/concierge/deployment.yaml index f2498cadd..30b893c1f 100644 --- a/deploy/concierge/deployment.yaml +++ b/deploy/concierge/deployment.yaml @@ -1,4 +1,4 @@ -#! Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. +#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved. #! SPDX-License-Identifier: Apache-2.0 #@ load("@ytt:data", "data") @@ -96,14 +96,11 @@ data: imagePullSecrets: - image-pull-secret (@ end @) - (@ if data.values.log_level or data.values.deprecated_log_format: @) + (@ if data.values.log_level: @) log: (@ if data.values.log_level: @) level: (@= getAndValidateLogLevel() @) (@ end @) - (@ if data.values.deprecated_log_format: @) - format: (@= data.values.deprecated_log_format @) - (@ end @) (@ end @) --- #@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": diff --git a/deploy/concierge/values.yaml b/deploy/concierge/values.yaml index 582641b80..0e5708956 100644 --- a/deploy/concierge/values.yaml +++ b/deploy/concierge/values.yaml @@ -124,17 +124,6 @@ api_serving_certificate_renew_before_seconds: 2160000 #@schema/validation one_of=["info", "debug", "trace", "all"] log_level: "" -#@schema/title "Log format" -#@ deprecated_log_format_desc = "Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). \ -#@ By default, when this value is left unset, logs are formatted in json. \ -#@ This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json." -#@schema/desc deprecated_log_format_desc -#@schema/examples ("Set logs to JSON format","json") -#@schema/nullable -#@schema/validation one_of=["json", "text"] -#@schema/deprecated "This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json." -deprecated_log_format: "" - #@schema/title "Run as user" #@schema/desc "The user ID that will own the process." #! See the Dockerfile for the reasoning behind this default value. diff --git a/deploy/supervisor/helpers.lib.yaml b/deploy/supervisor/helpers.lib.yaml index fbb60a2d9..818b673a8 100644 --- a/deploy/supervisor/helpers.lib.yaml +++ b/deploy/supervisor/helpers.lib.yaml @@ -1,4 +1,4 @@ -#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved. #! SPDX-License-Identifier: Apache-2.0 #@ load("@ytt:data", "data") @@ -53,17 +53,11 @@ _: #@ template.replace(data.values.custom_labels) #@ "apiService": defaultResourceNameWithSuffix("api"), #@ }, #@ "labels": labels(), -#@ "insecureAcceptExternalUnencryptedHttpRequests": data.values.deprecated_insecure_accept_external_unencrypted_http_requests #@ } -#@ if data.values.log_level or data.values.deprecated_log_format: -#@ config["log"] = {} -#@ end #@ if data.values.log_level: +#@ config["log"] = {} #@ config["log"]["level"] = getAndValidateLogLevel() #@ end -#@ if data.values.deprecated_log_format: -#@ config["log"]["format"] = data.values.deprecated_log_format -#@ end #@ if data.values.endpoints: #@ config["endpoints"] = data.values.endpoints #@ end diff --git a/deploy/supervisor/service.yaml b/deploy/supervisor/service.yaml index fd6b96232..fe8a0f34d 100644 --- a/deploy/supervisor/service.yaml +++ b/deploy/supervisor/service.yaml @@ -1,24 +1,10 @@ -#! Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +#! Copyright 2020-2024 the Pinniped contributors. All Rights Reserved. #! SPDX-License-Identifier: Apache-2.0 #@ load("@ytt:data", "data") -#@ load("@ytt:assert", "assert") #@ load("helpers.lib.yaml", "labels", "deploymentPodLabel", "namespace", "defaultResourceName", "defaultResourceNameWithSuffix") -#@ if hasattr(data.values, "service_http_nodeport_port"): -#@ assert.fail('value "service_http_nodeport_port" has been renamed to "deprecated_service_http_nodeport_port" and will be removed in a future release') -#@ end -#@ if hasattr(data.values, "service_http_nodeport_nodeport"): -#@ assert.fail('value "service_http_nodeport_nodeport" has been renamed to "deprecated_service_http_nodeport_nodeport" and will be removed in a future release') -#@ end -#@ if hasattr(data.values, "service_http_loadbalancer_port"): -#@ assert.fail('value "service_http_loadbalancer_port" has been renamed to "deprecated_service_http_loadbalancer_port" and will be removed in a future release') -#@ end -#@ if hasattr(data.values, "service_http_clusterip_port"): -#@ assert.fail('value "service_http_clusterip_port" has been renamed to "deprecated_service_http_clusterip_port" and will be removed in a future release') -#@ end - -#@ if data.values.deprecated_service_http_nodeport_port or data.values.service_https_nodeport_port: +#@ if data.values.service_https_nodeport_port: --- apiVersion: v1 kind: Service @@ -33,15 +19,6 @@ spec: type: NodePort selector: #@ deploymentPodLabel() ports: - #@ if data.values.deprecated_service_http_nodeport_port: - - name: http - protocol: TCP - port: #@ data.values.deprecated_service_http_nodeport_port - targetPort: 8080 - #@ if data.values.deprecated_service_http_nodeport_nodeport: - nodePort: #@ data.values.deprecated_service_http_nodeport_nodeport - #@ end - #@ end #@ if data.values.service_https_nodeport_port: - name: https protocol: TCP @@ -53,7 +30,7 @@ spec: #@ end #@ end -#@ if data.values.deprecated_service_http_clusterip_port or data.values.service_https_clusterip_port: +#@ if data.values.service_https_clusterip_port: --- apiVersion: v1 kind: Service @@ -68,12 +45,6 @@ spec: type: ClusterIP selector: #@ deploymentPodLabel() ports: - #@ if data.values.deprecated_service_http_clusterip_port: - - name: http - protocol: TCP - port: #@ data.values.deprecated_service_http_clusterip_port - targetPort: 8080 - #@ end #@ if data.values.service_https_clusterip_port: - name: https protocol: TCP @@ -82,7 +53,7 @@ spec: #@ end #@ end -#@ if data.values.deprecated_service_http_loadbalancer_port or data.values.service_https_loadbalancer_port: +#@ if data.values.service_https_loadbalancer_port: --- apiVersion: v1 kind: Service @@ -100,12 +71,6 @@ spec: loadBalancerIP: #@ data.values.service_loadbalancer_ip #@ end ports: - #@ if data.values.deprecated_service_http_loadbalancer_port: - - name: http - protocol: TCP - port: #@ data.values.deprecated_service_http_loadbalancer_port - targetPort: 8080 - #@ end #@ if data.values.service_https_loadbalancer_port: - name: https protocol: TCP diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index e3c31a5b3..2ae58e421 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -79,34 +79,6 @@ image_tag: latest #@schema/validation min_len=1 image_pull_dockerconfigjson: "" -#@schema/title "Deprecated service HTTP nodeport port" -#@schema/desc "When specified, creates a NodePort Service with this `port` value, with port 8080 as its `targetPort`" -#@schema/examples ("Specify port",31234) -#@schema/nullable -#@schema/deprecated "This data value will be removed in a future release" -deprecated_service_http_nodeport_port: 0 - -#@schema/title "Deprecated service http nodeport nodeport" -#@schema/desc "The `nodePort` value of the NodePort Service, optional when `deprecated_service_http_nodeport_port` is specified" -#@schema/examples ("Specify port",31234) -#@schema/nullable -#@schema/deprecated "This data value will be removed in a future release" -deprecated_service_http_nodeport_nodeport: 0 - -#@schema/title "Deprecated service http loadbalancer port" -#@schema/desc "When specified, creates a LoadBalancer Service with this `port` value, with port 8080 as its `targetPort`" -#@schema/examples ("Specify port",8443) -#@schema/nullable -#@schema/deprecated "This data value will be removed in a future release" -deprecated_service_http_loadbalancer_port: 0 - -#@schema/title "Deprecated service http clusterip port" -#@schema/desc "Creates a ClusterIP Service with this `port` value, with port 8080 as its `targetPort`" -#@schema/examples ("Specify port",8443) -#@schema/nullable -#@schema/deprecated "This data value will be removed in a future release" -deprecated_service_http_clusterip_port: 0 - #@schema/title "Service https nodeport port" #@schema/desc "When specified, creates a NodePort Service with this `port` value, with port 8443 as its `targetPort`" #@schema/examples ("Specify port",31243) @@ -147,17 +119,6 @@ service_loadbalancer_ip: "" #@schema/validation one_of=["info", "debug", "trace", "all"] log_level: "" -#@schema/title "Log format" -#@ deprecated_log_format_desc = "Specify the format of logging: json (for machine parsable logs) and text (for legacy klog formatted logs). \ -#@ By default, when this value is left unset, logs are formatted in json. \ -#@ This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json." -#@schema/desc deprecated_log_format_desc -#@schema/examples ("Set logs to JSON format","json") -#@schema/nullable -#@schema/validation one_of=["json", "text"] -#@schema/deprecated "This configuration is deprecated and will be removed in a future release at which point logs will always be formatted as json." -deprecated_log_format: "" - #@schema/title "Run as user" #@schema/desc "The user ID that will own the process." #! See the Dockerfile for the reasoning behind this default value. @@ -195,39 +156,28 @@ https_proxy: "" no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #@schema/title "Endpoints" -#@ endpoints_desc = "Control the HTTP and HTTPS listeners of the Supervisor. The current defaults are: \ -#@ {\"https\":{\"network\":\"tcp\",\"address\":\":8443\"},\"http\":\"disabled\"}. \ -#@ These defaults mean: 1.) for HTTPS listening, bind to all interfaces using TCP on port 8443 and \ -#@ 2.) disable HTTP listening by default. \ +#@ endpoints_desc = "Control the HTTPS listener of the Supervisor. The current defaults are: \ +#@ {\"https\":{\"network\":\"tcp\",\"address\":\":8443\"}}. \ +#@ These defaults mean: Tor HTTPS listening, bind to all interfaces using TCP on port 8443. \ #@ The schema of this config is as follows: \ -#@ {\"https\":{\"network\":\"tcp | unix | disabled\",\"address\":\"host:port when network=tcp or /pinniped_socket/socketfile.sock when network=unix\"},\"http\":{\"network\":\"tcp | unix | disabled\",\"address\":\"same as https, except that when network=tcp then the address is only allowed to bind to loopback interfaces\"}} \ -#@ The HTTP listener can only be bound to loopback interfaces. This allows the listener to accept \ -#@ traffic from within the pod, e.g. from a service mesh sidecar. The HTTP listener should not be \ -#@ used to accept traffic from outside the pod, since that would mean that the network traffic could be \ -#@ transmitted unencrypted. The HTTPS listener should be used instead to accept traffic from outside the pod. \ -#@ Ingresses and load balancers that terminate TLS connections should re-encrypt the data and route traffic \ -#@ to the HTTPS listener. Unix domain sockets may also be used for integrations with service meshes. \ +#@ {\"https\":{\"network\":\"tcp\",\"address\":\"{host}:{port}\"}} \ +#@ The HTTPS listener must be used to accept all traffic from outside the pod. \ +#@ Ingresses and load balancers that terminate TLS connections must re-encrypt the data and route traffic \ +#@ to the HTTPS listener, or provide TLS passthrough. \ #@ Changing the HTTPS port number must be accompanied by matching changes to the service and deployment \ #@ manifests. Changes to the HTTPS listener must be coordinated with the deployment health checks." #@schema/desc endpoints_desc -#@schema/examples ("Example matching default settings", '{"https":{"network":"tcp","address":":8443"},"http":"disabled"}') +#@schema/examples ("Example matching default settings", '{"https":{"network":"tcp","address":":8443"}}') #@schema/type any=True #@ def validate_endpoint(endpoint): -#@ if(type(endpoint) not in ["yamlfragment", "string"]): +#@ if (type(endpoint) != "yamlfragment"): #@ return False #@ end -#@ if(type(endpoint) in ["string"]): -#@ if (endpoint != "disabled"): -#@ return False -#@ end +#@ if (endpoint["network"] != "tcp"): +#@ return False #@ end -#@ if(type(endpoint) in ["yamlfragment"]): -#@ if (endpoint["network"] not in ["tcp", "unix", "disabled"]): -#@ return False -#@ end -#@ if (type(endpoint["address"]) not in ["string"]): -#@ return False -#@ end +#@ if (type(endpoint["address"]) != "string"): +#@ return False #@ end #@ return True #@ end @@ -235,26 +185,11 @@ no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,. #@ """ #@ Returns True if endpoints fulfill the expected structure #@ """ -#@ http_val = endpoints["http"] -#@ https_val = endpoints["https"] -#@ return validate_endpoint(http_val) and validate_endpoint(https_val) +#@ if (type(endpoints) != "yamlfragment"): +#@ return False +#@ end +#@ return validate_endpoint(endpoints["https"]) #@ end #@schema/nullable -#@schema/validation ("a map with keys 'http' and 'https', whose values are either the string 'disabled' or a map having keys 'network' and 'address', and the value of 'network' must be one of the allowed values", validate_endpoints) +#@schema/validation ("a map with key 'https', whose values are either the string 'disabled' or a map having keys 'network' and 'address', and the value of 'network' must be one of the allowed values", validate_endpoints) endpoints: { } - -#@ deprecated_insecure_accept_external_unencrypted_http_requests_desc = "Optionally override the validation on the endpoints.http \ -#@ value which checks that only loopback interfaces are used. \ -#@ When deprecated_insecure_accept_external_unencrypted_http_requests is true, the HTTP listener is allowed to bind to any \ -#@ interface, including interfaces that are listening for traffic from outside the pod. This value is being introduced \ -#@ to ease the transition to the new loopback interface validation for the HTTP port for any users who need more time \ -#@ to change their ingress strategy to avoid using plain HTTP into the Supervisor pods. \ -#@ This value is immediately deprecated upon its introduction. It will be removed in some future release, at which time \ -#@ traffic from outside the pod will need to be sent to the HTTPS listener instead, with no simple workaround available. \ -#@ Allowed values are true (boolean), 'true' (string), false (boolean), and 'false' (string). The default is false." -#@schema/desc deprecated_insecure_accept_external_unencrypted_http_requests_desc -#@schema/type any=True -#@schema/validation ("a boolean or string version of boolean", lambda v: type(v) in ["string", "boolean"]) -#@schema/validation one_of=["true", "false", True, False] -#@schema/deprecated "This data value will be removed in a future release" -deprecated_insecure_accept_external_unencrypted_http_requests: false From d67238d46f160010a4e48221166c20d246964c7a Mon Sep 17 00:00:00 2001 From: Joshua Casey Date: Fri, 26 Apr 2024 11:50:00 -0500 Subject: [PATCH 04/13] Remove code related to deprecated config params logLevel and HTTP networking --- internal/config/concierge/config.go | 3 +- internal/config/concierge/config_test.go | 10 +- internal/config/concierge/types.go | 6 +- internal/config/supervisor/config.go | 48 +--- internal/config/supervisor/config_test.go | 261 +--------------------- internal/config/supervisor/types.go | 34 +-- internal/plog/config.go | 9 +- internal/plog/config_test.go | 4 +- internal/supervisor/server/server.go | 107 ++++----- 9 files changed, 69 insertions(+), 413 deletions(-) diff --git a/internal/config/concierge/config.go b/internal/config/concierge/config.go index ee4c97e1d..a95619565 100644 --- a/internal/config/concierge/config.go +++ b/internal/config/concierge/config.go @@ -1,4 +1,4 @@ -// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 // Package concierge contains functionality to load/store Config's from/to @@ -79,7 +79,6 @@ func FromPath(ctx context.Context, path string) (*Config, error) { return nil, fmt.Errorf("validate names: %w", err) } - plog.MaybeSetDeprecatedLogLevel(config.LogLevel, &config.Log) if err := plog.ValidateAndSetLogLevelAndFormatGlobally(ctx, config.Log); err != nil { return nil, fmt.Errorf("validate log level: %w", err) } diff --git a/internal/config/concierge/config_test.go b/internal/config/concierge/config_test.go index 61b145166..7f51cde33 100644 --- a/internal/config/concierge/config_test.go +++ b/internal/config/concierge/config_test.go @@ -1,4 +1,4 @@ -// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package concierge @@ -57,7 +57,8 @@ func TestFromPath(t *testing.T) { namePrefix: kube-cert-agent-name-prefix- image: kube-cert-agent-image imagePullSecrets: [kube-cert-agent-image-pull-secret] - logLevel: debug + log: + level: debug `), wantConfig: &Config{ DiscoveryInfo: DiscoveryInfoSpec{ @@ -94,7 +95,6 @@ func TestFromPath(t *testing.T) { Image: ptr.To("kube-cert-agent-image"), ImagePullSecrets: []string{"kube-cert-agent-image-pull-secret"}, }, - LogLevel: func(level plog.LogLevel) *plog.LogLevel { return &level }(plog.LevelDebug), Log: plog.LogSpec{ Level: plog.LevelDebug, }, @@ -215,7 +215,6 @@ func TestFromPath(t *testing.T) { namePrefix: kube-cert-agent-name-prefix- image: kube-cert-agent-image imagePullSecrets: [kube-cert-agent-image-pull-secret] - logLevel: debug log: level: all format: json @@ -255,9 +254,8 @@ func TestFromPath(t *testing.T) { Image: ptr.To("kube-cert-agent-image"), ImagePullSecrets: []string{"kube-cert-agent-image-pull-secret"}, }, - LogLevel: func(level plog.LogLevel) *plog.LogLevel { return &level }(plog.LevelDebug), Log: plog.LogSpec{ - Level: plog.LevelDebug, + Level: plog.LevelAll, Format: plog.FormatJSON, }, }, diff --git a/internal/config/concierge/types.go b/internal/config/concierge/types.go index 967a38787..ffcaac5b0 100644 --- a/internal/config/concierge/types.go +++ b/internal/config/concierge/types.go @@ -1,4 +1,4 @@ -// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package concierge @@ -15,9 +15,7 @@ type Config struct { NamesConfig NamesConfigSpec `json:"names"` KubeCertAgentConfig KubeCertAgentSpec `json:"kubeCertAgent"` Labels map[string]string `json:"labels"` - // Deprecated: use log.level instead - LogLevel *plog.LogLevel `json:"logLevel"` - Log plog.LogSpec `json:"log"` + Log plog.LogSpec `json:"log"` } // DiscoveryInfoSpec contains configuration knobs specific to diff --git a/internal/config/supervisor/config.go b/internal/config/supervisor/config.go index 36be3fb51..4ae0d6083 100644 --- a/internal/config/supervisor/config.go +++ b/internal/config/supervisor/config.go @@ -1,4 +1,4 @@ -// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 // Package supervisor contains functionality to load/store Config's from/to @@ -66,7 +66,6 @@ func FromPath(ctx context.Context, path string) (*Config, error) { return nil, fmt.Errorf("validate names: %w", err) } - plog.MaybeSetDeprecatedLogLevel(config.LogLevel, &config.Log) if err := plog.ValidateAndSetLogLevelAndFormatGlobally(ctx, config.Log); err != nil { return nil, fmt.Errorf("validate log level: %w", err) } @@ -80,23 +79,10 @@ func FromPath(ctx context.Context, path string) (*Config, error) { Network: NetworkTCP, Address: ":8443", }) - maybeSetEndpointDefault(&config.Endpoints.HTTP, Endpoint{ - Network: NetworkDisabled, - }) if err := validateEndpoint(*config.Endpoints.HTTPS); err != nil { return nil, fmt.Errorf("validate https endpoint: %w", err) } - if err := validateEndpoint(*config.Endpoints.HTTP); err != nil { - return nil, fmt.Errorf("validate http endpoint: %w", err) - } - if err := validateAdditionalHTTPEndpointRequirements(*config.Endpoints.HTTP, config.AllowExternalHTTP); err != nil { - return nil, fmt.Errorf("validate http endpoint: %w", err) - } - if err := validateAtLeastOneEnabledEndpoint(*config.Endpoints.HTTPS, *config.Endpoints.HTTP); err != nil { - return nil, fmt.Errorf("validate endpoints: %w", err) - } - return &config, nil } @@ -142,42 +128,12 @@ func validateEndpoint(endpoint Endpoint) error { } return nil case NetworkDisabled: - if len(endpoint.Address) != 0 { - return fmt.Errorf("address set to %q when disabled, should be empty", endpoint.Address) - } - return nil + return fmt.Errorf("must not be disabled") default: return fmt.Errorf("unknown network %q", n) } } -func validateAdditionalHTTPEndpointRequirements(endpoint Endpoint, allowExternalHTTP stringOrBoolAsBool) error { - if endpoint.Network == NetworkTCP && !addrIsOnlyOnLoopback(endpoint.Address) { - if allowExternalHTTP { - // Log that the validation should have been triggered. - plog.Warning("Listening on non-loopback interfaces for the HTTP port is deprecated and will be removed " + - "in a future release. Your current configuration would not be allowed in that future release. " + - "Please see comments in deploy/supervisor/values.yaml and review your settings.") - // Skip enforcement of the validation. - return nil - } - return fmt.Errorf( - "http listener address %q for %q network may only bind to loopback interfaces", - endpoint.Address, - endpoint.Network) - } - return nil -} - -func validateAtLeastOneEnabledEndpoint(endpoints ...Endpoint) error { - for _, endpoint := range endpoints { - if endpoint.Network != NetworkDisabled { - return nil - } - } - return constable.Error("all endpoints are disabled") -} - // For tcp networks, the address can be in several formats: host:port, host:, and :port. // See address description in https://pkg.go.dev/net#Listen and https://pkg.go.dev/net#Dial. // The host may be a literal IP address, or a host name that can be resolved to IP addresses, diff --git a/internal/config/supervisor/config_test.go b/internal/config/supervisor/config_test.go index a90f662db..4752a3020 100644 --- a/internal/config/supervisor/config_test.go +++ b/internal/config/supervisor/config_test.go @@ -1,4 +1,4 @@ -// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package supervisor @@ -24,7 +24,7 @@ func TestFromPath(t *testing.T) { wantError string }{ { - name: "Happy", + name: "Happy (with new log field)", yaml: here.Doc(` --- apiGroupSuffix: some.suffix.com @@ -37,58 +37,6 @@ func TestFromPath(t *testing.T) { https: network: unix address: :1234 - http: - network: tcp - address: 127.0.0.1:1234 - insecureAcceptExternalUnencryptedHttpRequests: false - logLevel: trace - aggregatedAPIServerPort: 12345 - `), - wantConfig: &Config{ - APIGroupSuffix: ptr.To("some.suffix.com"), - Labels: map[string]string{ - "myLabelKey1": "myLabelValue1", - "myLabelKey2": "myLabelValue2", - }, - NamesConfig: NamesConfigSpec{ - DefaultTLSCertificateSecret: "my-secret-name", - }, - Endpoints: &Endpoints{ - HTTPS: &Endpoint{ - Network: "unix", - Address: ":1234", - }, - HTTP: &Endpoint{ - Network: "tcp", - Address: "127.0.0.1:1234", - }, - }, - AllowExternalHTTP: false, - LogLevel: func(level plog.LogLevel) *plog.LogLevel { return &level }(plog.LevelTrace), - Log: plog.LogSpec{ - Level: plog.LevelTrace, - }, - AggregatedAPIServerPort: ptr.To[int64](12345), - }, - }, - { - name: "Happy with new log field", - yaml: here.Doc(` - --- - apiGroupSuffix: some.suffix.com - labels: - myLabelKey1: myLabelValue1 - myLabelKey2: myLabelValue2 - names: - defaultTLSCertificateSecret: my-secret-name - endpoints: - https: - network: unix - address: :1234 - http: - network: tcp - address: 127.0.0.1:1234 - insecureAcceptExternalUnencryptedHttpRequests: false log: level: info format: text @@ -108,12 +56,7 @@ func TestFromPath(t *testing.T) { Network: "unix", Address: ":1234", }, - HTTP: &Endpoint{ - Network: "tcp", - Address: "127.0.0.1:1234", - }, }, - AllowExternalHTTP: false, Log: plog.LogSpec{ Level: plog.LevelInfo, Format: plog.FormatText, @@ -121,57 +64,6 @@ func TestFromPath(t *testing.T) { AggregatedAPIServerPort: ptr.To[int64](12345), }, }, - { - name: "Happy with old and new log field", - yaml: here.Doc(` - --- - apiGroupSuffix: some.suffix.com - labels: - myLabelKey1: myLabelValue1 - myLabelKey2: myLabelValue2 - names: - defaultTLSCertificateSecret: my-secret-name - endpoints: - https: - network: unix - address: :1234 - http: - network: tcp - address: 127.0.0.1:1234 - insecureAcceptExternalUnencryptedHttpRequests: false - logLevel: trace - log: - level: info - format: text - `), - wantConfig: &Config{ - APIGroupSuffix: ptr.To("some.suffix.com"), - Labels: map[string]string{ - "myLabelKey1": "myLabelValue1", - "myLabelKey2": "myLabelValue2", - }, - NamesConfig: NamesConfigSpec{ - DefaultTLSCertificateSecret: "my-secret-name", - }, - Endpoints: &Endpoints{ - HTTPS: &Endpoint{ - Network: "unix", - Address: ":1234", - }, - HTTP: &Endpoint{ - Network: "tcp", - Address: "127.0.0.1:1234", - }, - }, - AllowExternalHTTP: false, - LogLevel: func(level plog.LogLevel) *plog.LogLevel { return &level }(plog.LevelTrace), - Log: plog.LogSpec{ - Level: plog.LevelTrace, - Format: plog.FormatText, - }, - AggregatedAPIServerPort: ptr.To[int64](10250), - }, - }, { name: "bad log format", yaml: here.Doc(` @@ -202,11 +94,7 @@ func TestFromPath(t *testing.T) { Network: "tcp", Address: ":8443", }, - HTTP: &Endpoint{ - Network: "disabled", - }, }, - AllowExternalHTTP: false, AggregatedAPIServerPort: ptr.To[int64](10250), }, }, @@ -219,10 +107,8 @@ func TestFromPath(t *testing.T) { endpoints: https: network: disabled - http: - network: disabled `), - wantError: "validate endpoints: all endpoints are disabled", + wantError: "validate https endpoint: must not be disabled", }, { name: "invalid https endpoint", @@ -238,141 +124,6 @@ func TestFromPath(t *testing.T) { `), wantError: `validate https endpoint: unknown network "foo"`, }, - { - name: "invalid http endpoint", - yaml: here.Doc(` - --- - names: - defaultTLSCertificateSecret: my-secret-name - endpoints: - https: - network: disabled - http: - network: bar - `), - wantError: `validate http endpoint: unknown network "bar"`, - }, - { - name: "http endpoint uses tcp but binds to more than only loopback interfaces with insecureAcceptExternalUnencryptedHttpRequests missing", - yaml: here.Doc(` - --- - names: - defaultTLSCertificateSecret: my-secret-name - endpoints: - https: - network: disabled - http: - network: tcp - address: :8080 - `), - wantError: `validate http endpoint: http listener address ":8080" for "tcp" network may only bind to loopback interfaces`, - }, - { - name: "http endpoint uses tcp but binds to more than only loopback interfaces with insecureAcceptExternalUnencryptedHttpRequests set to boolean false", - yaml: here.Doc(` - --- - names: - defaultTLSCertificateSecret: my-secret-name - endpoints: - https: - network: disabled - http: - network: tcp - address: :8080 - insecureAcceptExternalUnencryptedHttpRequests: false - `), - wantError: `validate http endpoint: http listener address ":8080" for "tcp" network may only bind to loopback interfaces`, - }, - { - name: "http endpoint uses tcp but binds to more than only loopback interfaces with insecureAcceptExternalUnencryptedHttpRequests set to unsupported value", - yaml: here.Doc(` - --- - names: - defaultTLSCertificateSecret: my-secret-name - insecureAcceptExternalUnencryptedHttpRequests: "garbage" # this will be treated as the default, which is false - `), - wantError: `decode yaml: error unmarshaling JSON: while decoding JSON: invalid value for boolean`, - }, - { - name: "http endpoint uses tcp but binds to more than only loopback interfaces with insecureAcceptExternalUnencryptedHttpRequests set to string false", - yaml: here.Doc(` - --- - names: - defaultTLSCertificateSecret: my-secret-name - endpoints: - https: - network: disabled - http: - network: tcp - address: :8080 - insecureAcceptExternalUnencryptedHttpRequests: "false" - `), - wantError: `validate http endpoint: http listener address ":8080" for "tcp" network may only bind to loopback interfaces`, - }, - { - name: "http endpoint uses tcp but binds to more than only loopback interfaces with insecureAcceptExternalUnencryptedHttpRequests set to boolean true", - yaml: here.Doc(` - --- - names: - defaultTLSCertificateSecret: my-secret-name - endpoints: - http: - network: tcp - address: :1234 - insecureAcceptExternalUnencryptedHttpRequests: true - `), - wantConfig: &Config{ - APIGroupSuffix: ptr.To("pinniped.dev"), - Labels: map[string]string{}, - NamesConfig: NamesConfigSpec{ - DefaultTLSCertificateSecret: "my-secret-name", - }, - Endpoints: &Endpoints{ - HTTPS: &Endpoint{ - Network: "tcp", - Address: ":8443", - }, - HTTP: &Endpoint{ - Network: "tcp", - Address: ":1234", - }, - }, - AllowExternalHTTP: true, - AggregatedAPIServerPort: ptr.To[int64](10250), - }, - }, - { - name: "http endpoint uses tcp but binds to more than only loopback interfaces with insecureAcceptExternalUnencryptedHttpRequests set to string true", - yaml: here.Doc(` - --- - names: - defaultTLSCertificateSecret: my-secret-name - endpoints: - http: - network: tcp - address: :1234 - insecureAcceptExternalUnencryptedHttpRequests: "true" - `), - wantConfig: &Config{ - APIGroupSuffix: ptr.To("pinniped.dev"), - Labels: map[string]string{}, - NamesConfig: NamesConfigSpec{ - DefaultTLSCertificateSecret: "my-secret-name", - }, - Endpoints: &Endpoints{ - HTTPS: &Endpoint{ - Network: "tcp", - Address: ":8443", - }, - HTTP: &Endpoint{ - Network: "tcp", - Address: ":1234", - }, - }, - AllowExternalHTTP: true, - AggregatedAPIServerPort: ptr.To[int64](10250), - }, - }, { name: "endpoint disabled with non-empty address", yaml: here.Doc(` @@ -384,7 +135,7 @@ func TestFromPath(t *testing.T) { network: disabled address: wee `), - wantError: `validate https endpoint: address set to "wee" when disabled, should be empty`, + wantError: `validate https endpoint: must not be disabled`, }, { name: "endpoint tcp with empty address", @@ -393,10 +144,10 @@ func TestFromPath(t *testing.T) { names: defaultTLSCertificateSecret: my-secret-name endpoints: - http: + https: network: tcp `), - wantError: `validate http endpoint: address must be set with "tcp" network`, + wantError: `validate https endpoint: address must be set with "tcp" network`, }, { name: "endpoint unix with empty address", diff --git a/internal/config/supervisor/types.go b/internal/config/supervisor/types.go index bd89e2c7a..7ef9294e0 100644 --- a/internal/config/supervisor/types.go +++ b/internal/config/supervisor/types.go @@ -1,25 +1,20 @@ -// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package supervisor import ( - "errors" - "go.pinniped.dev/internal/plog" ) // Config contains knobs to setup an instance of the Pinniped Supervisor. type Config struct { - APIGroupSuffix *string `json:"apiGroupSuffix,omitempty"` - Labels map[string]string `json:"labels"` - NamesConfig NamesConfigSpec `json:"names"` - // Deprecated: use log.level instead - LogLevel *plog.LogLevel `json:"logLevel"` - Log plog.LogSpec `json:"log"` - Endpoints *Endpoints `json:"endpoints"` - AllowExternalHTTP stringOrBoolAsBool `json:"insecureAcceptExternalUnencryptedHttpRequests"` - AggregatedAPIServerPort *int64 `json:"aggregatedAPIServerPort"` + APIGroupSuffix *string `json:"apiGroupSuffix,omitempty"` + Labels map[string]string `json:"labels"` + NamesConfig NamesConfigSpec `json:"names"` + Log plog.LogSpec `json:"log"` + Endpoints *Endpoints `json:"endpoints"` + AggregatedAPIServerPort *int64 `json:"aggregatedAPIServerPort"` } // NamesConfigSpec configures the names of some Kubernetes resources for the Supervisor. @@ -30,24 +25,9 @@ type NamesConfigSpec struct { type Endpoints struct { HTTPS *Endpoint `json:"https,omitempty"` - HTTP *Endpoint `json:"http,omitempty"` } type Endpoint struct { Network string `json:"network"` Address string `json:"address"` } - -type stringOrBoolAsBool bool - -func (sb *stringOrBoolAsBool) UnmarshalJSON(b []byte) error { - switch string(b) { - case "true", `"true"`: - *sb = true - case "false", `"false"`: - *sb = false - default: - return errors.New("invalid value for boolean") - } - return nil -} diff --git a/internal/plog/config.go b/internal/plog/config.go index b5e7ad3ce..1a28cfe0c 100644 --- a/internal/plog/config.go +++ b/internal/plog/config.go @@ -1,4 +1,4 @@ -// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package plog @@ -50,13 +50,6 @@ type LogSpec struct { Format LogFormat `json:"format,omitempty"` } -func MaybeSetDeprecatedLogLevel(level *LogLevel, log *LogSpec) { - if level != nil { - Warning("logLevel is deprecated, set log.level instead") - log.Level = *level - } -} - func ValidateAndSetLogLevelAndFormatGlobally(ctx context.Context, spec LogSpec) error { klogLevel := klogLevelForPlogLevel(spec.Level) if klogLevel < 0 { diff --git a/internal/plog/config_test.go b/internal/plog/config_test.go index 1c7888631..0b77d2557 100644 --- a/internal/plog/config_test.go +++ b/internal/plog/config_test.go @@ -1,4 +1,4 @@ -// Copyright 2020-2023 the Pinniped contributors. All Rights Reserved. +// Copyright 2020-2024 the Pinniped contributors. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 package plog @@ -166,7 +166,7 @@ testing.tRunner // check for the deprecation warning require.True(t, scanner.Scan()) require.NoError(t, scanner.Err()) - require.Equal(t, fmt.Sprintf(`I1121 23:37:26.953313%8d config.go:96] "setting log.format to 'text' is deprecated - this option will be removed in a future release" warning=true`, + require.Equal(t, fmt.Sprintf(`I1121 23:37:26.953313%8d config.go:89] "setting log.format to 'text' is deprecated - this option will be removed in a future release" warning=true`, pid), scanner.Text()) Debug("what is happening", "does klog", "work?") diff --git a/internal/supervisor/server/server.go b/internal/supervisor/server/server.go index 99709d57d..ba254ec96 100644 --- a/internal/supervisor/server/server.go +++ b/internal/supervisor/server/server.go @@ -508,80 +508,61 @@ func runSupervisor(ctx context.Context, podInfo *downward.PodInfo, cfg *supervis return fmt.Errorf("could not create aggregated API server: %w", err) } - if e := cfg.Endpoints.HTTP; e.Network != supervisor.NetworkDisabled { - finishSetupPerms := maybeSetupUnixPerms(e, supervisorPod) + finishSetupPerms := maybeSetupUnixPerms(cfg.Endpoints.HTTPS, supervisorPod) - httpListener, err := net.Listen(e.Network, e.Address) - if err != nil { - return fmt.Errorf("cannot create http listener with network %q and address %q: %w", e.Network, e.Address, err) - } - - if err := finishSetupPerms(); err != nil { - return fmt.Errorf("cannot setup http listener permissions for network %q and address %q: %w", e.Network, e.Address, err) - } - - defer func() { _ = httpListener.Close() }() - startServer(ctx, shutdown, httpListener, oidProvidersManager) - plog.Debug("supervisor http listener started", "address", httpListener.Addr().String()) + bootstrapCert, err := getBootstrapCert() // generate this in-memory once per process startup + if err != nil { + return fmt.Errorf("https listener bootstrap error: %w", err) } - if e := cfg.Endpoints.HTTPS; e.Network != supervisor.NetworkDisabled { //nolint:nestif - finishSetupPerms := maybeSetupUnixPerms(e, supervisorPod) + c := ptls.Default(nil) + c.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + cert := dynamicTLSCertProvider.GetTLSCert(strings.ToLower(info.ServerName)) + foundServerNameCert := cert != nil - bootstrapCert, err := getBootstrapCert() // generate this in-memory once per process startup - if err != nil { - return fmt.Errorf("https listener bootstrap error: %w", err) + defaultCert := dynamicTLSCertProvider.GetDefaultTLSCert() + + if !foundServerNameCert { + cert = defaultCert } - c := ptls.Default(nil) - c.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { - cert := dynamicTLSCertProvider.GetTLSCert(strings.ToLower(info.ServerName)) - foundServerNameCert := cert != nil - - defaultCert := dynamicTLSCertProvider.GetDefaultTLSCert() - - if !foundServerNameCert { - cert = defaultCert - } - - // If we still don't have a cert for the request at this point, then using the bootstrapping cert, - // but in that case also set the request to fail unless it is a health check request. - usingBootstrapCert := false - if cert == nil { - usingBootstrapCert = true - setIsBootstrapConn(info.Context()) // make this connection only work for bootstrap requests - cert = bootstrapCert - } - - // Emit logs visible at a higher level of logging than the default. Using Info level so the user - // can safely configure a production Supervisor to show this message if they choose. - plog.Info("choosing TLS cert for incoming request", - "requestSNIServerName", info.ServerName, - "foundCertForSNIServerNameFromFederationDomain", foundServerNameCert, - "foundDefaultCertFromSecret", defaultCert != nil, - "defaultCertSecretName", cfg.NamesConfig.DefaultTLSCertificateSecret, - "servingBootstrapHealthzCert", usingBootstrapCert, - "requestLocalAddr", info.Conn.LocalAddr().String(), - "requestRemoteAddr", info.Conn.RemoteAddr().String(), - ) - - return cert, nil + // If we still don't have a cert for the request at this point, then using the bootstrapping cert, + // but in that case also set the request to fail unless it is a health check request. + usingBootstrapCert := false + if cert == nil { + usingBootstrapCert = true + setIsBootstrapConn(info.Context()) // make this connection only work for bootstrap requests + cert = bootstrapCert } - httpsListener, err := tls.Listen(e.Network, e.Address, c) - if err != nil { - return fmt.Errorf("cannot create https listener with network %q and address %q: %w", e.Network, e.Address, err) - } + // Emit logs visible at a higher level of logging than the default. Using Info level so the user + // can safely configure a production Supervisor to show this message if they choose. + plog.Info("choosing TLS cert for incoming request", + "requestSNIServerName", info.ServerName, + "foundCertForSNIServerNameFromFederationDomain", foundServerNameCert, + "foundDefaultCertFromSecret", defaultCert != nil, + "defaultCertSecretName", cfg.NamesConfig.DefaultTLSCertificateSecret, + "servingBootstrapHealthzCert", usingBootstrapCert, + "requestLocalAddr", info.Conn.LocalAddr().String(), + "requestRemoteAddr", info.Conn.RemoteAddr().String(), + ) - if err := finishSetupPerms(); err != nil { - return fmt.Errorf("cannot setup https listener permissions for network %q and address %q: %w", e.Network, e.Address, err) - } - - defer func() { _ = httpsListener.Close() }() - startServer(ctx, shutdown, httpsListener, oidProvidersManager) - plog.Debug("supervisor https listener started", "address", httpsListener.Addr().String()) + return cert, nil } + httpsListener, err := tls.Listen(cfg.Endpoints.HTTPS.Network, cfg.Endpoints.HTTPS.Address, c) + if err != nil { + return fmt.Errorf("cannot create https listener with network %q and address %q: %w", cfg.Endpoints.HTTPS.Network, cfg.Endpoints.HTTPS.Address, err) + } + + if err := finishSetupPerms(); err != nil { + return fmt.Errorf("cannot setup https listener permissions for network %q and address %q: %w", cfg.Endpoints.HTTPS.Network, cfg.Endpoints.HTTPS.Address, err) + } + + defer func() { _ = httpsListener.Close() }() + startServer(ctx, shutdown, httpsListener, oidProvidersManager) + plog.Debug("supervisor https listener started", "address", httpsListener.Addr().String()) + plog.Debug("supervisor started") defer plog.Debug("supervisor exiting") From 460fbbacc7200f8f93da28ef1b6a37acc84e2f34 Mon Sep 17 00:00:00 2001 From: Joshua Casey Date: Mon, 29 Apr 2024 09:15:23 -0500 Subject: [PATCH 05/13] Update documentation to remove reference to legacy HTTP ports --- .../howto/supervisor/configure-supervisor.md | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/site/content/docs/howto/supervisor/configure-supervisor.md b/site/content/docs/howto/supervisor/configure-supervisor.md index ef7d77830..daf984238 100644 --- a/site/content/docs/howto/supervisor/configure-supervisor.md +++ b/site/content/docs/howto/supervisor/configure-supervisor.md @@ -54,24 +54,15 @@ ingress and TLS configuration. In that case, please refer to the documentation f ## Exposing the Supervisor app's endpoints outside the cluster -The Supervisor app's endpoints should be exposed as HTTPS endpoints with proper TLS certificates signed by a +The Supervisor app's endpoints must be exposed as HTTPS endpoints with proper TLS certificates signed by a certificate authority (CA) which is trusted by your end user's web browsers. -It is recommended that the traffic to these endpoints should be encrypted via TLS all the way into the +Furthermore, all traffic to Supervisor endpoints must be encrypted via TLS all the way into the Supervisor pods, even when crossing boundaries that are entirely inside the Kubernetes cluster. The credentials and tokens that are handled by these endpoints are too sensitive to transmit without encryption. -In previous versions of the Supervisor app, there were both HTTP and HTTPS ports available for use by default. -These ports each host all the Supervisor's endpoints. Unfortunately, this has caused some confusion in the community -and some blog posts have been written which demonstrate using the HTTP port in such a way that a portion of the traffic's -path is unencrypted. Newer versions of the Supervisor disable the HTTP port by default to make it more clear that -the Supervisor app is not intended to receive non-TLS HTTP traffic from outside the Pod. Furthermore, in these newer versions, -when the HTTP listener is configured to be enabled it may only listen on loopback interfaces for traffic from within its own pod. -To aid in transition for impacted users, the old behavior of allowing the HTTP listener to receive traffic from -outside the pod may be re-enabled using the -`deprecated_insecure_accept_external_unencrypted_http_requests` value in -[values.yaml](https://github.com/vmware-tanzu/pinniped/blob/main/deploy/supervisor/values.yaml), -until that setting is removed in a future release. +Previous versions of the Supervisor app supported both HTTP and HTTPS ports. Starting with Pinniped v0.30.0, +HTTP ports are no longer allowed. Because there are many ways to expose TLS services from a Kubernetes cluster, the Supervisor app leaves this up to the user. Some common approaches are: From ad7df9f7d1a0bff326c2e8d8d1d62c451523f530 Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Wed, 1 May 2024 12:27:26 -0700 Subject: [PATCH 06/13] don't remove user's ability to configure http port to listen on loopback --- deploy/concierge/deployment.yaml | 2 - deploy/supervisor/values.yaml | 46 +++++--- internal/config/concierge/config_test.go | 105 ++++------------- internal/config/supervisor/config.go | 37 +++++- internal/config/supervisor/config_test.go | 75 ++++++++++-- internal/config/supervisor/types.go | 1 + internal/plog/config.go | 13 +-- internal/plog/config_test.go | 72 +----------- internal/supervisor/server/server.go | 109 ++++++++++-------- .../howto/supervisor/configure-supervisor.md | 8 +- 10 files changed, 226 insertions(+), 242 deletions(-) diff --git a/deploy/concierge/deployment.yaml b/deploy/concierge/deployment.yaml index 30b893c1f..26b892524 100644 --- a/deploy/concierge/deployment.yaml +++ b/deploy/concierge/deployment.yaml @@ -98,9 +98,7 @@ data: (@ end @) (@ if data.values.log_level: @) log: - (@ if data.values.log_level: @) level: (@= getAndValidateLogLevel() @) - (@ end @) (@ end @) --- #@ if data.values.image_pull_dockerconfigjson and data.values.image_pull_dockerconfigjson != "": diff --git a/deploy/supervisor/values.yaml b/deploy/supervisor/values.yaml index 2ae58e421..750a5e075 100644 --- a/deploy/supervisor/values.yaml +++ b/deploy/supervisor/values.yaml @@ -156,28 +156,39 @@ https_proxy: "" no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,.cluster.local" #@schema/title "Endpoints" -#@ endpoints_desc = "Control the HTTPS listener of the Supervisor. The current defaults are: \ -#@ {\"https\":{\"network\":\"tcp\",\"address\":\":8443\"}}. \ -#@ These defaults mean: Tor HTTPS listening, bind to all interfaces using TCP on port 8443. \ +#@ endpoints_desc = "Control the HTTP and HTTPS listeners of the Supervisor. The current defaults are: \ +#@ {\"https\":{\"network\":\"tcp\",\"address\":\":8443\"},\"http\":\"disabled\"}. \ +#@ These defaults mean: 1.) for HTTPS listening, bind to all interfaces using TCP on port 8443 and \ +#@ 2.) disable HTTP listening by default. \ #@ The schema of this config is as follows: \ -#@ {\"https\":{\"network\":\"tcp\",\"address\":\"{host}:{port}\"}} \ -#@ The HTTPS listener must be used to accept all traffic from outside the pod. \ -#@ Ingresses and load balancers that terminate TLS connections must re-encrypt the data and route traffic \ -#@ to the HTTPS listener, or provide TLS passthrough. \ +#@ {\"https\":{\"network\":\"tcp | unix | disabled\",\"address\":\"host:port when network=tcp or /pinniped_socket/socketfile.sock when network=unix\"},\"http\":{\"network\":\"tcp | unix | disabled\",\"address\":\"same as https, except that when network=tcp then the address is only allowed to bind to loopback interfaces\"}} \ +#@ The HTTP listener can only be bound to loopback interfaces. This allows the listener to accept \ +#@ traffic from within the pod, e.g. from a service mesh sidecar. The HTTP listener should not be \ +#@ used to accept traffic from outside the pod, since that would mean that the network traffic could be \ +#@ transmitted unencrypted. The HTTPS listener should be used instead to accept traffic from outside the pod. \ +#@ Ingresses and load balancers that terminate TLS connections should re-encrypt the data and route traffic \ +#@ to the HTTPS listener. Unix domain sockets may also be used for integrations with service meshes. \ #@ Changing the HTTPS port number must be accompanied by matching changes to the service and deployment \ #@ manifests. Changes to the HTTPS listener must be coordinated with the deployment health checks." #@schema/desc endpoints_desc -#@schema/examples ("Example matching default settings", '{"https":{"network":"tcp","address":":8443"}}') +#@schema/examples ("Example matching default settings", '{"https":{"network":"tcp","address":":8443"},"http":"disabled"}') #@schema/type any=True #@ def validate_endpoint(endpoint): -#@ if (type(endpoint) != "yamlfragment"): +#@ if(type(endpoint) not in ["yamlfragment", "string"]): #@ return False #@ end -#@ if (endpoint["network"] != "tcp"): -#@ return False +#@ if(type(endpoint) in ["string"]): +#@ if (endpoint != "disabled"): +#@ return False +#@ end #@ end -#@ if (type(endpoint["address"]) != "string"): -#@ return False +#@ if(type(endpoint) in ["yamlfragment"]): +#@ if (endpoint["network"] not in ["tcp", "unix", "disabled"]): +#@ return False +#@ end +#@ if (type(endpoint["address"]) not in ["string"]): +#@ return False +#@ end #@ end #@ return True #@ end @@ -185,11 +196,10 @@ no_proxy: "$(KUBERNETES_SERVICE_HOST),169.254.169.254,127.0.0.1,localhost,.svc,. #@ """ #@ Returns True if endpoints fulfill the expected structure #@ """ -#@ if (type(endpoints) != "yamlfragment"): -#@ return False -#@ end -#@ return validate_endpoint(endpoints["https"]) +#@ http_val = endpoints["http"] +#@ https_val = endpoints["https"] +#@ return validate_endpoint(http_val) and validate_endpoint(https_val) #@ end #@schema/nullable -#@schema/validation ("a map with key 'https', whose values are either the string 'disabled' or a map having keys 'network' and 'address', and the value of 'network' must be one of the allowed values", validate_endpoints) +#@schema/validation ("a map with keys 'http' and 'https', whose values are either the string 'disabled' or a map having keys 'network' and 'address', and the value of 'network' must be one of the allowed values", validate_endpoints) endpoints: { } diff --git a/internal/config/concierge/config_test.go b/internal/config/concierge/config_test.go index 7f51cde33..ec7573941 100644 --- a/internal/config/concierge/config_test.go +++ b/internal/config/concierge/config_test.go @@ -101,87 +101,7 @@ func TestFromPath(t *testing.T) { }, }, { - name: "Fully filled out new log struct", - yaml: here.Doc(` - --- - discovery: - url: https://some.discovery/url - api: - servingCertificate: - durationSeconds: 3600 - renewBeforeSeconds: 2400 - apiGroupSuffix: some.suffix.com - aggregatedAPIServerPort: 12345 - impersonationProxyServerPort: 4242 - names: - servingCertificateSecret: pinniped-concierge-api-tls-serving-certificate - credentialIssuer: pinniped-config - apiService: pinniped-api - kubeCertAgentPrefix: kube-cert-agent-prefix - impersonationLoadBalancerService: impersonationLoadBalancerService-value - impersonationClusterIPService: impersonationClusterIPService-value - impersonationTLSCertificateSecret: impersonationTLSCertificateSecret-value - impersonationCACertificateSecret: impersonationCACertificateSecret-value - impersonationSignerSecret: impersonationSignerSecret-value - impersonationSignerSecret: impersonationSignerSecret-value - agentServiceAccount: agentServiceAccount-value - impersonationProxyServiceAccount: impersonationProxyServiceAccount-value - impersonationProxyLegacySecret: impersonationProxyLegacySecret-value - extraName: extraName-value - labels: - myLabelKey1: myLabelValue1 - myLabelKey2: myLabelValue2 - kubeCertAgent: - namePrefix: kube-cert-agent-name-prefix- - image: kube-cert-agent-image - imagePullSecrets: [kube-cert-agent-image-pull-secret] - log: - level: all - format: json - `), - wantConfig: &Config{ - DiscoveryInfo: DiscoveryInfoSpec{ - URL: ptr.To("https://some.discovery/url"), - }, - APIConfig: APIConfigSpec{ - ServingCertificateConfig: ServingCertificateConfigSpec{ - DurationSeconds: ptr.To[int64](3600), - RenewBeforeSeconds: ptr.To[int64](2400), - }, - }, - APIGroupSuffix: ptr.To("some.suffix.com"), - AggregatedAPIServerPort: ptr.To[int64](12345), - ImpersonationProxyServerPort: ptr.To[int64](4242), - NamesConfig: NamesConfigSpec{ - ServingCertificateSecret: "pinniped-concierge-api-tls-serving-certificate", - CredentialIssuer: "pinniped-config", - APIService: "pinniped-api", - ImpersonationLoadBalancerService: "impersonationLoadBalancerService-value", - ImpersonationClusterIPService: "impersonationClusterIPService-value", - ImpersonationTLSCertificateSecret: "impersonationTLSCertificateSecret-value", - ImpersonationCACertificateSecret: "impersonationCACertificateSecret-value", - ImpersonationSignerSecret: "impersonationSignerSecret-value", - AgentServiceAccount: "agentServiceAccount-value", - ImpersonationProxyServiceAccount: "impersonationProxyServiceAccount-value", - ImpersonationProxyLegacySecret: "impersonationProxyLegacySecret-value", - }, - Labels: map[string]string{ - "myLabelKey1": "myLabelValue1", - "myLabelKey2": "myLabelValue2", - }, - KubeCertAgentConfig: KubeCertAgentSpec{ - NamePrefix: ptr.To("kube-cert-agent-name-prefix-"), - Image: ptr.To("kube-cert-agent-image"), - ImagePullSecrets: []string{"kube-cert-agent-image-pull-secret"}, - }, - Log: plog.LogSpec{ - Level: plog.LevelAll, - Format: plog.FormatJSON, - }, - }, - }, - { - name: "Fully filled out old log and new log struct", + name: "fully filled out including log format", yaml: here.Doc(` --- discovery: @@ -279,7 +199,28 @@ func TestFromPath(t *testing.T) { level: all format: snorlax `), - wantError: "decode yaml: error unmarshaling JSON: while decoding JSON: invalid log format, valid choices are the empty string, json and text", + wantError: "decode yaml: error unmarshaling JSON: while decoding JSON: invalid log format, valid choices are the empty string or 'json'", + }, + { + name: "cli is a bad log format when configured by the user", + yaml: here.Doc(` + --- + names: + servingCertificateSecret: pinniped-concierge-api-tls-serving-certificate + credentialIssuer: pinniped-config + apiService: pinniped-api + impersonationLoadBalancerService: impersonationLoadBalancerService-value + impersonationClusterIPService: impersonationClusterIPService-value + impersonationTLSCertificateSecret: impersonationTLSCertificateSecret-value + impersonationCACertificateSecret: impersonationCACertificateSecret-value + impersonationSignerSecret: impersonationSignerSecret-value + agentServiceAccount: agentServiceAccount-value + impersonationProxyServiceAccount: impersonationProxyServiceAccount-value + log: + level: all + format: cli + `), + wantError: "decode yaml: error unmarshaling JSON: while decoding JSON: invalid log format, valid choices are the empty string or 'json'", }, { name: "When only the required fields are present, causes other fields to be defaulted", diff --git a/internal/config/supervisor/config.go b/internal/config/supervisor/config.go index 4ae0d6083..1e7c60d1b 100644 --- a/internal/config/supervisor/config.go +++ b/internal/config/supervisor/config.go @@ -79,10 +79,23 @@ func FromPath(ctx context.Context, path string) (*Config, error) { Network: NetworkTCP, Address: ":8443", }) + maybeSetEndpointDefault(&config.Endpoints.HTTP, Endpoint{ + Network: NetworkDisabled, + }) if err := validateEndpoint(*config.Endpoints.HTTPS); err != nil { return nil, fmt.Errorf("validate https endpoint: %w", err) } + if err := validateEndpoint(*config.Endpoints.HTTP); err != nil { + return nil, fmt.Errorf("validate http endpoint: %w", err) + } + if err := validateAdditionalHTTPEndpointRequirements(*config.Endpoints.HTTP); err != nil { + return nil, fmt.Errorf("validate http endpoint: %w", err) + } + if err := validateAtLeastOneEnabledEndpoint(*config.Endpoints.HTTPS, *config.Endpoints.HTTP); err != nil { + return nil, fmt.Errorf("validate endpoints: %w", err) + } + return &config, nil } @@ -128,12 +141,34 @@ func validateEndpoint(endpoint Endpoint) error { } return nil case NetworkDisabled: - return fmt.Errorf("must not be disabled") + if len(endpoint.Address) != 0 { + return fmt.Errorf("address set to %q when disabled, should be empty", endpoint.Address) + } + return nil default: return fmt.Errorf("unknown network %q", n) } } +func validateAdditionalHTTPEndpointRequirements(endpoint Endpoint) error { + if endpoint.Network == NetworkTCP && !addrIsOnlyOnLoopback(endpoint.Address) { + return fmt.Errorf( + "http listener address %q for %q network may only bind to loopback interfaces", + endpoint.Address, + endpoint.Network) + } + return nil +} + +func validateAtLeastOneEnabledEndpoint(endpoints ...Endpoint) error { + for _, endpoint := range endpoints { + if endpoint.Network != NetworkDisabled { + return nil + } + } + return constable.Error("all endpoints are disabled") +} + // For tcp networks, the address can be in several formats: host:port, host:, and :port. // See address description in https://pkg.go.dev/net#Listen and https://pkg.go.dev/net#Dial. // The host may be a literal IP address, or a host name that can be resolved to IP addresses, diff --git a/internal/config/supervisor/config_test.go b/internal/config/supervisor/config_test.go index 4752a3020..61834a0eb 100644 --- a/internal/config/supervisor/config_test.go +++ b/internal/config/supervisor/config_test.go @@ -24,7 +24,7 @@ func TestFromPath(t *testing.T) { wantError string }{ { - name: "Happy (with new log field)", + name: "Happy", yaml: here.Doc(` --- apiGroupSuffix: some.suffix.com @@ -37,9 +37,13 @@ func TestFromPath(t *testing.T) { https: network: unix address: :1234 + http: + network: tcp + address: 127.0.0.1:1234 + insecureAcceptExternalUnencryptedHttpRequests: false log: level: info - format: text + format: json aggregatedAPIServerPort: 12345 `), wantConfig: &Config{ @@ -56,16 +60,20 @@ func TestFromPath(t *testing.T) { Network: "unix", Address: ":1234", }, + HTTP: &Endpoint{ + Network: "tcp", + Address: "127.0.0.1:1234", + }, }, Log: plog.LogSpec{ Level: plog.LevelInfo, - Format: plog.FormatText, + Format: plog.FormatJSON, }, AggregatedAPIServerPort: ptr.To[int64](12345), }, }, { - name: "bad log format", + name: "cli is a bad log format when configured by the user", yaml: here.Doc(` --- names: @@ -74,7 +82,7 @@ func TestFromPath(t *testing.T) { level: info format: cli `), - wantError: "decode yaml: error unmarshaling JSON: while decoding JSON: invalid log format, valid choices are the empty string, json and text", + wantError: "decode yaml: error unmarshaling JSON: while decoding JSON: invalid log format, valid choices are the empty string or 'json'", }, { name: "When only the required fields are present, causes other fields to be defaulted", @@ -94,6 +102,9 @@ func TestFromPath(t *testing.T) { Network: "tcp", Address: ":8443", }, + HTTP: &Endpoint{ + Network: "disabled", + }, }, AggregatedAPIServerPort: ptr.To[int64](10250), }, @@ -107,8 +118,10 @@ func TestFromPath(t *testing.T) { endpoints: https: network: disabled + http: + network: disabled `), - wantError: "validate https endpoint: must not be disabled", + wantError: "validate endpoints: all endpoints are disabled", }, { name: "invalid https endpoint", @@ -124,6 +137,50 @@ func TestFromPath(t *testing.T) { `), wantError: `validate https endpoint: unknown network "foo"`, }, + { + name: "invalid http endpoint", + yaml: here.Doc(` + --- + names: + defaultTLSCertificateSecret: my-secret-name + endpoints: + https: + network: disabled + http: + network: bar + `), + wantError: `validate http endpoint: unknown network "bar"`, + }, + { + name: "http endpoint uses tcp but binds to more than only loopback interfaces with insecureAcceptExternalUnencryptedHttpRequests missing", + yaml: here.Doc(` + --- + names: + defaultTLSCertificateSecret: my-secret-name + endpoints: + https: + network: disabled + http: + network: tcp + address: :8080 + `), + wantError: `validate http endpoint: http listener address ":8080" for "tcp" network may only bind to loopback interfaces`, + }, + { + name: "http endpoint uses tcp but binds to more than only loopback interfaces", + yaml: here.Doc(` + --- + names: + defaultTLSCertificateSecret: my-secret-name + endpoints: + https: + network: disabled + http: + network: tcp + address: :8080 + `), + wantError: `validate http endpoint: http listener address ":8080" for "tcp" network may only bind to loopback interfaces`, + }, { name: "endpoint disabled with non-empty address", yaml: here.Doc(` @@ -135,7 +192,7 @@ func TestFromPath(t *testing.T) { network: disabled address: wee `), - wantError: `validate https endpoint: must not be disabled`, + wantError: `validate https endpoint: address set to "wee" when disabled, should be empty`, }, { name: "endpoint tcp with empty address", @@ -144,10 +201,10 @@ func TestFromPath(t *testing.T) { names: defaultTLSCertificateSecret: my-secret-name endpoints: - https: + http: network: tcp `), - wantError: `validate https endpoint: address must be set with "tcp" network`, + wantError: `validate http endpoint: address must be set with "tcp" network`, }, { name: "endpoint unix with empty address", diff --git a/internal/config/supervisor/types.go b/internal/config/supervisor/types.go index 7ef9294e0..918375f67 100644 --- a/internal/config/supervisor/types.go +++ b/internal/config/supervisor/types.go @@ -25,6 +25,7 @@ type NamesConfigSpec struct { type Endpoints struct { HTTPS *Endpoint `json:"https,omitempty"` + HTTP *Endpoint `json:"http,omitempty"` } type Endpoint struct { diff --git a/internal/plog/config.go b/internal/plog/config.go index 1a28cfe0c..b2c60416f 100644 --- a/internal/plog/config.go +++ b/internal/plog/config.go @@ -22,8 +22,6 @@ func (l *LogFormat) UnmarshalJSON(b []byte) error { switch string(b) { case `""`, `"json"`: *l = FormatJSON - case `"text"`: - *l = FormatText // there is no "cli" case because it is not a supported option via our config default: return errInvalidLogFormat @@ -33,11 +31,10 @@ func (l *LogFormat) UnmarshalJSON(b []byte) error { const ( FormatJSON LogFormat = "json" - FormatText LogFormat = "text" FormatCLI LogFormat = "cli" // only used by the pinniped CLI and not the server components errInvalidLogLevel = constable.Error("invalid log level, valid choices are the empty string, info, debug, trace and all") - errInvalidLogFormat = constable.Error("invalid log format, valid choices are the empty string, json and text") + errInvalidLogFormat = constable.Error("invalid log format, valid choices are the empty string or 'json'") ) var _ json.Unmarshaler = func() *LogFormat { @@ -68,8 +65,6 @@ func ValidateAndSetLogLevelAndFormatGlobally(ctx context.Context, spec LogSpec) encoding = "json" case FormatCLI: encoding = "console" - case FormatText: - encoding = "text" default: return errInvalidLogFormat } @@ -81,12 +76,8 @@ func ValidateAndSetLogLevelAndFormatGlobally(ctx context.Context, spec LogSpec) setGlobalLoggers(log, flush) - //nolint:exhaustive // the switch above is exhaustive for format already - switch spec.Format { - case FormatCLI: + if spec.Format == FormatCLI { return nil // do not spawn go routines on the CLI to allow the CLI to call this more than once - case FormatText: - Warning("setting log.format to 'text' is deprecated - this option will be removed in a future release") } // do spawn go routines on the server diff --git a/internal/plog/config_test.go b/internal/plog/config_test.go index 0b77d2557..c5e750377 100644 --- a/internal/plog/config_test.go +++ b/internal/plog/config_test.go @@ -101,7 +101,7 @@ func TestFormat(t *testing.T) { "timestamp": "2022-11-21T23:37:26.953313Z", "caller": "%s/config_test.go:%d$plog.TestFormat.func1", "message": "something happened", - "error": "invalid log format, valid choices are the empty string, json and text", + "error": "invalid log format, valid choices are the empty string or 'json'", "an": "item" }`, wd, getLineNumberOfCaller()-11), scanner.Text()) @@ -148,7 +148,7 @@ testing.tRunner DebugErr("something happened", errInvalidLogFormat, "an", "item") require.True(t, scanner.Scan()) require.NoError(t, scanner.Err()) - require.Equal(t, fmt.Sprintf(nowStr+` plog/config_test.go:%d something happened {"error": "invalid log format, valid choices are the empty string, json and text", "an": "item"}`, + require.Equal(t, fmt.Sprintf(nowStr+` plog/config_test.go:%d something happened {"error": "invalid log format, valid choices are the empty string or 'json'", "an": "item"}`, getLineNumberOfCaller()-4), scanner.Text()) Logr().WithName("burrito").Error(errInvalidLogLevel, "wee", "a", "b", "slightly less than a year", 363*24*time.Hour, "slightly more than 2 years", 2*367*24*time.Hour) @@ -157,74 +157,6 @@ testing.tRunner require.Equal(t, fmt.Sprintf(nowStr+` burrito plog/config_test.go:%d wee {"a": "b", "slightly less than a year": "363d", "slightly more than 2 years": "2y4d", "error": "invalid log level, valid choices are the empty string, info, debug, trace and all"}`, getLineNumberOfCaller()-4), scanner.Text()) - old := New().WithName("created before mode change").WithValues("is", "old") - - err = ValidateAndSetLogLevelAndFormatGlobally(ctx, LogSpec{Level: LevelDebug, Format: FormatText}) - require.NoError(t, err) - pid := os.Getpid() - - // check for the deprecation warning - require.True(t, scanner.Scan()) - require.NoError(t, scanner.Err()) - require.Equal(t, fmt.Sprintf(`I1121 23:37:26.953313%8d config.go:89] "setting log.format to 'text' is deprecated - this option will be removed in a future release" warning=true`, - pid), scanner.Text()) - - Debug("what is happening", "does klog", "work?") - require.True(t, scanner.Scan()) - require.NoError(t, scanner.Err()) - require.Equal(t, fmt.Sprintf(`I1121 23:37:26.953313%8d config_test.go:%d] "what is happening" does klog="work?"`, - pid, getLineNumberOfCaller()-4), scanner.Text()) - - Logr().WithName("panda").V(KlogLevelDebug).Info("are the best", "yes?", "yes.") - require.True(t, scanner.Scan()) - require.NoError(t, scanner.Err()) - require.Equal(t, fmt.Sprintf(`I1121 23:37:26.953313%8d config_test.go:%d] "are the best" logger="panda" yes?="yes."`, - pid, getLineNumberOfCaller()-4), scanner.Text()) - - New().WithName("hi").WithName("there").WithValues("a", 1, "b", 2).Always("do it") - require.True(t, scanner.Scan()) - require.NoError(t, scanner.Err()) - require.Equal(t, fmt.Sprintf(`I1121 23:37:26.953313%8d config_test.go:%d] "do it" logger="hi.there" a=1 b=2`, - pid, getLineNumberOfCaller()-4), scanner.Text()) - - l := WithValues("x", 33, "z", 22) - l.Debug("what to do") - l.Debug("and why") - require.True(t, scanner.Scan()) - require.NoError(t, scanner.Err()) - require.Equal(t, fmt.Sprintf(`I1121 23:37:26.953313%8d config_test.go:%d] "what to do" x=33 z=22`, - pid, getLineNumberOfCaller()-5), scanner.Text()) - require.True(t, scanner.Scan()) - require.NoError(t, scanner.Err()) - require.Equal(t, fmt.Sprintf(`I1121 23:37:26.953313%8d config_test.go:%d] "and why" x=33 z=22`, - pid, getLineNumberOfCaller()-8), scanner.Text()) - - old.Always("should be klog text format", "for", "sure") - require.True(t, scanner.Scan()) - require.NoError(t, scanner.Err()) - require.Equal(t, fmt.Sprintf(`I1121 23:37:26.953313%8d config_test.go:%d] "should be klog text format" logger="created before mode change" is="old" for="sure"`, - pid, getLineNumberOfCaller()-4), scanner.Text()) - - // make sure child loggers do not share state - old1 := old.WithValues("i am", "old1") - old2 := old.WithName("old2") - old1.Warning("warn") - old2.Info("info") - require.True(t, scanner.Scan()) - require.NoError(t, scanner.Err()) - require.Equal(t, fmt.Sprintf(`I1121 23:37:26.953313%8d config_test.go:%d] "warn" logger="created before mode change" is="old" i am="old1" warning=true`, - pid, getLineNumberOfCaller()-5), scanner.Text()) - require.True(t, scanner.Scan()) - require.NoError(t, scanner.Err()) - require.Equal(t, fmt.Sprintf(`I1121 23:37:26.953313%8d config_test.go:%d] "info" logger="created before mode change.old2" is="old"`, - pid, getLineNumberOfCaller()-8), scanner.Text()) - - Trace("should not be logged", "for", "sure") - require.Empty(t, buf.String()) - - Logr().V(klogLevelAll).Info("also should not be logged", "open", "close") - require.Empty(t, buf.String()) - require.False(t, scanner.Scan()) require.NoError(t, scanner.Err()) require.Empty(t, scanner.Text()) diff --git a/internal/supervisor/server/server.go b/internal/supervisor/server/server.go index ba254ec96..99709d57d 100644 --- a/internal/supervisor/server/server.go +++ b/internal/supervisor/server/server.go @@ -508,60 +508,79 @@ func runSupervisor(ctx context.Context, podInfo *downward.PodInfo, cfg *supervis return fmt.Errorf("could not create aggregated API server: %w", err) } - finishSetupPerms := maybeSetupUnixPerms(cfg.Endpoints.HTTPS, supervisorPod) + if e := cfg.Endpoints.HTTP; e.Network != supervisor.NetworkDisabled { + finishSetupPerms := maybeSetupUnixPerms(e, supervisorPod) - bootstrapCert, err := getBootstrapCert() // generate this in-memory once per process startup - if err != nil { - return fmt.Errorf("https listener bootstrap error: %w", err) - } - - c := ptls.Default(nil) - c.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { - cert := dynamicTLSCertProvider.GetTLSCert(strings.ToLower(info.ServerName)) - foundServerNameCert := cert != nil - - defaultCert := dynamicTLSCertProvider.GetDefaultTLSCert() - - if !foundServerNameCert { - cert = defaultCert + httpListener, err := net.Listen(e.Network, e.Address) + if err != nil { + return fmt.Errorf("cannot create http listener with network %q and address %q: %w", e.Network, e.Address, err) } - // If we still don't have a cert for the request at this point, then using the bootstrapping cert, - // but in that case also set the request to fail unless it is a health check request. - usingBootstrapCert := false - if cert == nil { - usingBootstrapCert = true - setIsBootstrapConn(info.Context()) // make this connection only work for bootstrap requests - cert = bootstrapCert + if err := finishSetupPerms(); err != nil { + return fmt.Errorf("cannot setup http listener permissions for network %q and address %q: %w", e.Network, e.Address, err) } - // Emit logs visible at a higher level of logging than the default. Using Info level so the user - // can safely configure a production Supervisor to show this message if they choose. - plog.Info("choosing TLS cert for incoming request", - "requestSNIServerName", info.ServerName, - "foundCertForSNIServerNameFromFederationDomain", foundServerNameCert, - "foundDefaultCertFromSecret", defaultCert != nil, - "defaultCertSecretName", cfg.NamesConfig.DefaultTLSCertificateSecret, - "servingBootstrapHealthzCert", usingBootstrapCert, - "requestLocalAddr", info.Conn.LocalAddr().String(), - "requestRemoteAddr", info.Conn.RemoteAddr().String(), - ) - - return cert, nil + defer func() { _ = httpListener.Close() }() + startServer(ctx, shutdown, httpListener, oidProvidersManager) + plog.Debug("supervisor http listener started", "address", httpListener.Addr().String()) } - httpsListener, err := tls.Listen(cfg.Endpoints.HTTPS.Network, cfg.Endpoints.HTTPS.Address, c) - if err != nil { - return fmt.Errorf("cannot create https listener with network %q and address %q: %w", cfg.Endpoints.HTTPS.Network, cfg.Endpoints.HTTPS.Address, err) - } + if e := cfg.Endpoints.HTTPS; e.Network != supervisor.NetworkDisabled { //nolint:nestif + finishSetupPerms := maybeSetupUnixPerms(e, supervisorPod) - if err := finishSetupPerms(); err != nil { - return fmt.Errorf("cannot setup https listener permissions for network %q and address %q: %w", cfg.Endpoints.HTTPS.Network, cfg.Endpoints.HTTPS.Address, err) - } + bootstrapCert, err := getBootstrapCert() // generate this in-memory once per process startup + if err != nil { + return fmt.Errorf("https listener bootstrap error: %w", err) + } - defer func() { _ = httpsListener.Close() }() - startServer(ctx, shutdown, httpsListener, oidProvidersManager) - plog.Debug("supervisor https listener started", "address", httpsListener.Addr().String()) + c := ptls.Default(nil) + c.GetCertificate = func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + cert := dynamicTLSCertProvider.GetTLSCert(strings.ToLower(info.ServerName)) + foundServerNameCert := cert != nil + + defaultCert := dynamicTLSCertProvider.GetDefaultTLSCert() + + if !foundServerNameCert { + cert = defaultCert + } + + // If we still don't have a cert for the request at this point, then using the bootstrapping cert, + // but in that case also set the request to fail unless it is a health check request. + usingBootstrapCert := false + if cert == nil { + usingBootstrapCert = true + setIsBootstrapConn(info.Context()) // make this connection only work for bootstrap requests + cert = bootstrapCert + } + + // Emit logs visible at a higher level of logging than the default. Using Info level so the user + // can safely configure a production Supervisor to show this message if they choose. + plog.Info("choosing TLS cert for incoming request", + "requestSNIServerName", info.ServerName, + "foundCertForSNIServerNameFromFederationDomain", foundServerNameCert, + "foundDefaultCertFromSecret", defaultCert != nil, + "defaultCertSecretName", cfg.NamesConfig.DefaultTLSCertificateSecret, + "servingBootstrapHealthzCert", usingBootstrapCert, + "requestLocalAddr", info.Conn.LocalAddr().String(), + "requestRemoteAddr", info.Conn.RemoteAddr().String(), + ) + + return cert, nil + } + + httpsListener, err := tls.Listen(e.Network, e.Address, c) + if err != nil { + return fmt.Errorf("cannot create https listener with network %q and address %q: %w", e.Network, e.Address, err) + } + + if err := finishSetupPerms(); err != nil { + return fmt.Errorf("cannot setup https listener permissions for network %q and address %q: %w", e.Network, e.Address, err) + } + + defer func() { _ = httpsListener.Close() }() + startServer(ctx, shutdown, httpsListener, oidProvidersManager) + plog.Debug("supervisor https listener started", "address", httpsListener.Addr().String()) + } plog.Debug("supervisor started") defer plog.Debug("supervisor exiting") diff --git a/site/content/docs/howto/supervisor/configure-supervisor.md b/site/content/docs/howto/supervisor/configure-supervisor.md index daf984238..15adbfe3c 100644 --- a/site/content/docs/howto/supervisor/configure-supervisor.md +++ b/site/content/docs/howto/supervisor/configure-supervisor.md @@ -54,15 +54,15 @@ ingress and TLS configuration. In that case, please refer to the documentation f ## Exposing the Supervisor app's endpoints outside the cluster -The Supervisor app's endpoints must be exposed as HTTPS endpoints with proper TLS certificates signed by a +The Supervisor app's endpoints should be exposed as HTTPS endpoints with proper TLS certificates signed by a certificate authority (CA) which is trusted by your end user's web browsers. -Furthermore, all traffic to Supervisor endpoints must be encrypted via TLS all the way into the +It is recommended that the traffic to these endpoints should be encrypted via TLS all the way into the Supervisor pods, even when crossing boundaries that are entirely inside the Kubernetes cluster. The credentials and tokens that are handled by these endpoints are too sensitive to transmit without encryption. -Previous versions of the Supervisor app supported both HTTP and HTTPS ports. Starting with Pinniped v0.30.0, -HTTP ports are no longer allowed. +The Supervisor only listens on an HTTPS port by default. Incoming traffic must use TLS. The only exception is for +an advanced configuration style using a service mesh to deliver traffic into the Supervisor (discussed below). Because there are many ways to expose TLS services from a Kubernetes cluster, the Supervisor app leaves this up to the user. Some common approaches are: From 0baae514250648763ee3631abb8c334fda5a4462 Mon Sep 17 00:00:00 2001 From: Pinny Date: Thu, 2 May 2024 13:01:17 +0000 Subject: [PATCH 07/13] Bump dependencies --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 007b905be..0e4263e05 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ replace github.com/coreos/go-oidc/v3 => github.com/coreos/go-oidc/v3 v3.9.0 require ( github.com/MakeNowJust/heredoc/v2 v2.0.1 - github.com/chromedp/cdproto v0.0.0-20240426225625-909263490071 + github.com/chromedp/cdproto v0.0.0-20240501202034-ef67d660e9fd github.com/chromedp/chromedp v0.9.5 github.com/coreos/go-oidc/v3 v3.10.0 github.com/coreos/go-semver v0.3.1 diff --git a/go.sum b/go.sum index 76e3a40b7..c06d576c7 100644 --- a/go.sum +++ b/go.sum @@ -70,8 +70,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL 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/chromedp/cdproto v0.0.0-20240202021202-6d0b6a386732/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= -github.com/chromedp/cdproto v0.0.0-20240426225625-909263490071 h1:RdCf9hH3xq5vJifrjGB7zQlFkdRB3pAppcX2helDq2U= -github.com/chromedp/cdproto v0.0.0-20240426225625-909263490071/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= +github.com/chromedp/cdproto v0.0.0-20240501202034-ef67d660e9fd h1:5/HXKq8EaAWVmnl6Hnyl4SVq7FF5990DBW6AuTrWtVw= +github.com/chromedp/cdproto v0.0.0-20240501202034-ef67d660e9fd/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs= github.com/chromedp/chromedp v0.9.5 h1:viASzruPJOiThk7c5bueOUY91jGLJVximoEMGoH93rg= github.com/chromedp/chromedp v0.9.5/go.mod h1:D4I2qONslauw/C7INoCir1BJkSwBYMyZgx8X276z3+Y= github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic= From fbc3334e8caf449d1ceced6711ecb658df846f49 Mon Sep 17 00:00:00 2001 From: "Benjamin A. Petersen" Date: Thu, 2 May 2024 11:33:53 -0400 Subject: [PATCH 08/13] Improve TestFuzzAndJSONNewValidEmptyAuthorizeCodeSession message --- .../authorizationcode/authorizationcode_test.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/fositestorage/authorizationcode/authorizationcode_test.go b/internal/fositestorage/authorizationcode/authorizationcode_test.go index 568393f32..a95d0e970 100644 --- a/internal/fositestorage/authorizationcode/authorizationcode_test.go +++ b/internal/fositestorage/authorizationcode/authorizationcode_test.go @@ -428,7 +428,13 @@ func TestFuzzAndJSONNewValidEmptyAuthorizeCodeSession(t *testing.T) { // cause those old session Secrets to be discarded upon read after an upgrade. // Note that when you change the storage version, you will also need to change it in the JSON content of the // expected value for this assertion. - require.JSONEq(t, ExpectedAuthorizeCodeSessionJSONFromFuzzing, authorizeCodeSessionJSONFromFuzzing, "actual:\n%s", authorizeCodeSessionJSONFromFuzzing) + require.JSONEq(t, + ExpectedAuthorizeCodeSessionJSONFromFuzzing, + authorizeCodeSessionJSONFromFuzzing, + "actual:\n%s\n\n(NOTICE: This test may fail when storage structure is updated. "+ + "Be sure to update relevant version variables (authorizeCodeStorageVersion, oidcStorageVersion, pkceStorageVersion, "+ + "refreshTokenStorageVersion, accessTokenStorageVersion) to a new value and leave a comment documenting the change. "+ + "Updating the version ensures new secret generation, therefore smooth upgrades of Pinniped.)", authorizeCodeSessionJSONFromFuzzing) } func TestReadFromSecret(t *testing.T) { From 3e148b629dcd2e2fb0c5e2879880ac603d5c257c Mon Sep 17 00:00:00 2001 From: Pinny Date: Fri, 3 May 2024 13:02:36 +0000 Subject: [PATCH 09/13] Bump dependencies --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0e4263e05..734cba5fe 100644 --- a/go.mod +++ b/go.mod @@ -79,7 +79,7 @@ require ( k8s.io/klog/v2 v2.120.1 k8s.io/kube-aggregator v0.30.0 k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f - k8s.io/utils v0.0.0-20240423183400-0849a56e8f22 + k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 sigs.k8s.io/yaml v1.4.0 ) diff --git a/go.sum b/go.sum index c06d576c7..6292ef58e 100644 --- a/go.sum +++ b/go.sum @@ -1107,8 +1107,8 @@ k8s.io/kube-aggregator v0.30.0 h1:+Opc0lmhRmHbNM4m3mLSsUFmK/ikMapO9rvGirX5CEM= k8s.io/kube-aggregator v0.30.0/go.mod h1:KbZZkSSjYE6vkB2TSuZ9GBjU3ucgL7YxT8yX8wll0iQ= k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f h1:0LQagt0gDpKqvIkAMPaRGcXawNMouPECM1+F9BVxEaM= k8s.io/kube-openapi v0.0.0-20240430033511-f0e62f92d13f/go.mod h1:S9tOR0FxgyusSNR+MboCuiDpVWkAifZvaYI1Q2ubgro= -k8s.io/utils v0.0.0-20240423183400-0849a56e8f22 h1:ao5hUqGhsqdm+bYbjH/pRkCs0unBGe9UyDahzs9zQzQ= -k8s.io/utils v0.0.0-20240423183400-0849a56e8f22/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/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 85e5970d6e44a3d0001e3820036b574320e6b923 Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Fri, 3 May 2024 12:35:49 -0700 Subject: [PATCH 10/13] only auto-detect version v1 of ValidatingAdmissionPlugin during startup --- .../admissionpluginconfg.go | 8 +++----- .../admissionpluginconfg_test.go | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/internal/admissionpluginconfig/admissionpluginconfg.go b/internal/admissionpluginconfig/admissionpluginconfg.go index d0ea9766d..e118bc1a8 100644 --- a/internal/admissionpluginconfig/admissionpluginconfg.go +++ b/internal/admissionpluginconfig/admissionpluginconfg.go @@ -5,7 +5,6 @@ package admissionpluginconfig import ( "fmt" - "strings" "github.com/pkg/errors" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" @@ -82,17 +81,16 @@ func k8sAPIServerHasValidatingAdmissionPolicyResource(discoveryClient discovery. return false, fmt.Errorf("failed to perform k8s API discovery: %w", err) } - // Now look at all discovered groups until we find admissionregistration.k8s.io. - wantedGroupWithSlash := fmt.Sprintf("%s/", admissionregistrationv1.GroupName) + // Now look at all discovered groups until we find version v1 of group admissionregistration.k8s.io. for _, resourcesPerGV := range resources { - if strings.HasPrefix(resourcesPerGV.GroupVersion, wantedGroupWithSlash) { + if resourcesPerGV.GroupVersion == admissionregistrationv1.SchemeGroupVersion.String() { // Found the group, so now look to see if it includes ValidatingAdmissionPolicy as a resource, // which went GA in Kubernetes 1.30, and could be enabled by a feature flag in previous versions. for _, resource := range resourcesPerGV.APIResources { if resource.Kind == "ValidatingAdmissionPolicy" { // Found it! plog.Info("found ValidatingAdmissionPolicy resource on this Kubernetes cluster", - "group", resource.Group, "version", resource.Version, "kind", resource.Kind) + "groupVersion", resourcesPerGV.GroupVersion, "kind", resource.Kind) return true, nil } } diff --git a/internal/admissionpluginconfig/admissionpluginconfg_test.go b/internal/admissionpluginconfig/admissionpluginconfg_test.go index cd05ca0b3..52b0a2bb0 100644 --- a/internal/admissionpluginconfig/admissionpluginconfg_test.go +++ b/internal/admissionpluginconfig/admissionpluginconfg_test.go @@ -57,6 +57,14 @@ func TestConfigureAdmissionPlugins(t *testing.T) { }, } + newStyleAdmissionResourcesWithValidatingAdmissionPoliciesAtOlderAPIVersion := &metav1.APIResourceList{ + GroupVersion: admissionregistrationv1.SchemeGroupVersion.Group + "/v1beta1", + APIResources: []metav1.APIResource{ + {Name: "validatingwebhookconfigurations", Kind: "ValidatingWebhookConfiguration"}, + {Name: "validatingadmissionpolicies", Kind: "ValidatingAdmissionPolicy"}, + }, + } + oldStyleAdmissionResourcesWithoutValidatingAdmissionPolicies := &metav1.APIResourceList{ GroupVersion: admissionregistrationv1.SchemeGroupVersion.String(), APIResources: []metav1.APIResource{ @@ -92,6 +100,16 @@ func TestConfigureAdmissionPlugins(t *testing.T) { wantRegisteredPlugins: customOldStylePluginsRegistered, wantRecommendedPluginOrder: customOldStyleRecommendedPluginOrder, }, + { + name: "when there is only an older version of ValidatingAdmissionPolicy resource, as there would be in an old Kubernetes cluster with the feature flag enabled, then we change the plugin configuration to be more like it was for old versions of Kubernetes (because the admission code wants to watch v1)", + availableAPIResources: []*metav1.APIResourceList{ + coreResources, + newStyleAdmissionResourcesWithValidatingAdmissionPoliciesAtOlderAPIVersion, + appsResources, + }, + wantRegisteredPlugins: customOldStylePluginsRegistered, + wantRecommendedPluginOrder: customOldStyleRecommendedPluginOrder, + }, { name: "when there is a total error returned by discovery", discoveryErr: errors.New("total error from API discovery client"), From e4d6a7208755b5131986158ebfca36ecf21c41f8 Mon Sep 17 00:00:00 2001 From: Pinny Date: Mon, 6 May 2024 13:02:10 +0000 Subject: [PATCH 11/13] Bump dependencies --- go.mod | 8 ++++---- go.sum | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index 734cba5fe..39bdaa2fa 100644 --- a/go.mod +++ b/go.mod @@ -65,10 +65,10 @@ require ( go.uber.org/zap v1.27.0 golang.org/x/crypto v0.22.0 golang.org/x/net v0.24.0 - golang.org/x/oauth2 v0.19.0 + golang.org/x/oauth2 v0.20.0 golang.org/x/sync v0.7.0 - golang.org/x/term v0.19.0 - golang.org/x/text v0.14.0 + golang.org/x/term v0.20.0 + golang.org/x/text v0.15.0 k8s.io/api v0.30.0 k8s.io/apiextensions-apiserver v0.30.0 k8s.io/apimachinery v0.30.0 @@ -183,7 +183,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20230515195305-f3d0a9c9a5cc // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/sys v0.19.0 // indirect + golang.org/x/sys v0.20.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.20.0 // indirect google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect diff --git a/go.sum b/go.sum index 6292ef58e..ecac51b82 100644 --- a/go.sum +++ b/go.sum @@ -25,9 +25,8 @@ cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUM 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/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= -cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= 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= @@ -782,8 +781,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ 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.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= -golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= +golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= +golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= 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= @@ -858,8 +857,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 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= @@ -869,8 +868,8 @@ golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= 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= @@ -881,8 +880,9 @@ 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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -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/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.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= From 73e7aeca6e73290acf0742bcf69b98418f11e13f Mon Sep 17 00:00:00 2001 From: Ryan Richard Date: Mon, 6 May 2024 11:50:39 -0700 Subject: [PATCH 12/13] add doc for how to use GoLand to run integration tests --- CONTRIBUTING.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a16637758..429fb265c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -152,6 +152,29 @@ go build -o pinniped ./cmd/pinniped To destroy the local Kubernetes cluster, run `./hack/kind-down.sh`. +#### Using GoLand to Run an Integration Test + +It can sometimes be convenient to use GoLand to run an integration test. For example, this allows using the +GoLand debugger to debug the test itself (not the server, since that it running in-cluster). + +Note that the output of `hack/prepare-for-integration-tests.sh` says: + +```bash +# Using GoLand? Paste the result of this command into GoLand's run configuration "Environment". +# hack/integration-test-env-goland.sh | pbcopy +``` + +After using `hack/prepare-for-integration-tests.sh`, run `hack/integration-test-env-goland.sh | pbcopy` as instructed. Then: + +1. Select and run an integration test within GoLand. It will fail complaining about missing env vars. +1. Pull down the menu that shows the name of the test which you just ran in the previous step, and choose "Edit Configurations...". +1. In the "Environment" text box for the run configuration of the integration test that you just ran, + paste the results of `hack/integration-test-env-goland.sh | pbcopy`. +1. Apply, and then run the integration test again. This time the test will use the environment variables provided. + +Note that if you run `hack/prepare-for-integration-tests.sh` again, then you may need to repeat these steps. +Each run of `hack/prepare-for-integration-tests.sh` can result in different values for some of the env vars. + ### Observing Tests on the Continuous Integration Environment [CI](https://ci.pinniped.dev/teams/main/pipelines/pull-requests) From f94b1e70fc1a68bbeac9ade0b0e4d9e46de52f92 Mon Sep 17 00:00:00 2001 From: Pinny Date: Tue, 7 May 2024 13:02:55 +0000 Subject: [PATCH 13/13] Bump dependencies --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 39bdaa2fa..bb505a52c 100644 --- a/go.mod +++ b/go.mod @@ -63,8 +63,8 @@ require ( github.com/tdewolff/minify/v2 v2.20.20 go.uber.org/mock v0.4.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.22.0 - golang.org/x/net v0.24.0 + golang.org/x/crypto v0.23.0 + golang.org/x/net v0.25.0 golang.org/x/oauth2 v0.20.0 golang.org/x/sync v0.7.0 golang.org/x/term v0.20.0 diff --git a/go.sum b/go.sum index ecac51b82..20982c19a 100644 --- a/go.sum +++ b/go.sum @@ -684,8 +684,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= 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= @@ -770,8 +770,8 @@ golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= 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=