mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-09-09 01:26:09 +00:00
update code for compatibility with Go 1.27
Fix some test expectations and also fix the production code in impersonator.go to make them compatible with both Go 1.27 and also with older versions, e.g. Go 1.26. With these changes, all unit tests pass when run with either Go 1.26 or Go 1.27. Signed-off-by: Ryan Richard <richardry@vmware.com>
This commit is contained in:
@@ -906,9 +906,54 @@ func getTransportForProtocol(restConfig *rest.Config, protocol string) (http.Rou
|
||||
return nil, fmt.Errorf("could not extract TLS config: %w", err)
|
||||
}
|
||||
cfg.NextProtos = []string{protocol}
|
||||
|
||||
// Overriding NextProtos above is not sufficient on its own. Starting with Go 1.27,
|
||||
// http2.ConfigureTransports no longer sets NextProtos itself, and instead enables http2 by
|
||||
// setting http.Transport.Protocols to allow both http/1.1 and h2. On the first round trip,
|
||||
// net/http lazily recomputes NextProtos from Protocols, which would undo the override above.
|
||||
// Restricting Protocols to only the desired protocol makes the override stick.
|
||||
if err := restrictTransportToProtocol(rt, protocol); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := kubeclient.AssertSecureTransport(rt); err != nil {
|
||||
return nil, err // make sure we only use a secure TLS config
|
||||
}
|
||||
|
||||
return rt, nil
|
||||
}
|
||||
|
||||
// restrictTransportToProtocol configures the underlying http.Transport to speak only the given
|
||||
// protocol, which must be either "h2" or "http/1.1".
|
||||
func restrictTransportToProtocol(rt http.RoundTripper, protocol string) error {
|
||||
t, err := unwrapHTTPTransport(rt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var protocols http.Protocols
|
||||
switch protocol {
|
||||
case "h2":
|
||||
protocols.SetHTTP2(true)
|
||||
case "http/1.1":
|
||||
protocols.SetHTTP1(true)
|
||||
default:
|
||||
return fmt.Errorf("unsupported protocol %q", protocol)
|
||||
}
|
||||
t.Protocols = &protocols
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// unwrapHTTPTransport digs through any round tripper wrappers to find the underlying
|
||||
// http.Transport. This mirrors how utilnet.TLSClientConfig unwraps round trippers.
|
||||
func unwrapHTTPTransport(rt http.RoundTripper) (*http.Transport, error) {
|
||||
switch t := rt.(type) {
|
||||
case *http.Transport:
|
||||
return t, nil
|
||||
case utilnet.RoundTripperWrapper:
|
||||
return unwrapHTTPTransport(t.WrappedRoundTripper())
|
||||
default:
|
||||
return nil, fmt.Errorf("could not find underlying http.Transport, found type: %T", rt)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2025 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package supervisor
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
|
||||
"go.pinniped.dev/internal/here"
|
||||
"go.pinniped.dev/internal/plog"
|
||||
"go.pinniped.dev/internal/testutil"
|
||||
)
|
||||
|
||||
func TestFromPath(t *testing.T) {
|
||||
@@ -424,7 +425,11 @@ func TestFromPath(t *testing.T) {
|
||||
oidc:
|
||||
ignoreUserInfoEndpoint: "should be a struct, but is a string"
|
||||
`),
|
||||
wantError: "decode yaml: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go struct field OIDCSpec.oidc.ignoreUserInfoEndpoint of type supervisor.IgnoreUserInfoEndpointSpec",
|
||||
wantError: testutil.StringBasedOnGoVersion(testutil.GoVersionDependentString{
|
||||
GoVersion: "go1.27",
|
||||
BeforeVersion: "decode yaml: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go struct field OIDCSpec.oidc.ignoreUserInfoEndpoint of type supervisor.IgnoreUserInfoEndpointSpec",
|
||||
SinceVersion: "decode yaml: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go struct field .oidc.ignoreUserInfoEndpoint of type supervisor.IgnoreUserInfoEndpointSpec",
|
||||
}),
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
|
||||
@@ -615,8 +615,11 @@ func TestPlog(t *testing.T) {
|
||||
case runtimeVersionSemver.Major == 1 && runtimeVersionSemver.Minor == 21:
|
||||
// Format of string for Go 1.21
|
||||
return "func13.TestPlog.func13.1.func2"
|
||||
case runtimeVersionSemver.Major == 1 && runtimeVersionSemver.Minor >= 27:
|
||||
// Format of string for Go 1.27+
|
||||
return "func13.1.1"
|
||||
case runtimeVersionSemver.Major == 1 && runtimeVersionSemver.Minor >= 22:
|
||||
// Format of string for Go 1.22+
|
||||
// Format of string for Go 1.22 - 1.26
|
||||
return "func13.TestPlog.func13.1.2"
|
||||
default:
|
||||
// Format of string for Go 1.20 and below.
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright 2026 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"go/version"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// GoVersionDependentString describes a string whose value depends on which version of Go is
|
||||
// running the test. GoVersion should be a Go language version, e.g. "go1.27". BeforeVersion is
|
||||
// the value to use on older versions of Go, and SinceVersion is the value to use on GoVersion
|
||||
// and on newer versions of Go.
|
||||
type GoVersionDependentString struct {
|
||||
GoVersion string
|
||||
BeforeVersion string
|
||||
SinceVersion string
|
||||
}
|
||||
|
||||
// StringBasedOnGoVersion returns the value of the given GoVersionDependentString for the version
|
||||
// of Go which is running the test.
|
||||
func StringBasedOnGoVersion(s GoVersionDependentString) string {
|
||||
lang := version.Lang(runtime.Version())
|
||||
if lang == "" {
|
||||
// Not a released version of Go, e.g. a development build, so assume that it is the newest behavior.
|
||||
return s.SinceVersion
|
||||
}
|
||||
if version.Compare(lang, version.Lang(s.GoVersion)) >= 0 {
|
||||
return s.SinceVersion
|
||||
}
|
||||
return s.BeforeVersion
|
||||
}
|
||||
@@ -3664,7 +3664,11 @@ func TestMaybePerformPinnipedSupervisorIDPDiscovery(t *testing.T) {
|
||||
{
|
||||
name: "when the Supervisor returns invalid discovery information, returns an error",
|
||||
pinnipedDiscovery: `"not-valid-discovery-claim"`,
|
||||
wantErr: `could not decode the Pinniped IDP discovery document URL in OIDC discovery from "FAKE-ISSUER": json: cannot unmarshal string into Go struct field OIDCDiscoveryResponse.discovery.supervisor.pinniped.dev/v1alpha1 of type v1alpha1.OIDCDiscoveryResponseIDPEndpoint`,
|
||||
wantErr: testutil.StringBasedOnGoVersion(testutil.GoVersionDependentString{
|
||||
GoVersion: "go1.27",
|
||||
BeforeVersion: `could not decode the Pinniped IDP discovery document URL in OIDC discovery from "FAKE-ISSUER": json: cannot unmarshal string into Go struct field OIDCDiscoveryResponse.discovery.supervisor.pinniped.dev/v1alpha1 of type v1alpha1.OIDCDiscoveryResponseIDPEndpoint`,
|
||||
SinceVersion: `could not decode the Pinniped IDP discovery document URL in OIDC discovery from "FAKE-ISSUER": json: cannot unmarshal string into Go struct field OIDCDiscoveryResponse.discovery.supervisor.pinniped.dev~1v1alpha1 of type v1alpha1.OIDCDiscoveryResponseIDPEndpoint`,
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "when the Supervisor has invalid pinniped_identity_providers_endpoint, returns an error",
|
||||
|
||||
Reference in New Issue
Block a user