mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-01-03 11:45:45 +00:00
Allow multiple Pinnipeds to work on same cluster
Yes, this is a huge commit.
The middleware allows you to customize the API groups of all of the
*.pinniped.dev API groups.
Some notes about other small things in this commit:
- We removed the internal/client package in favor of pkg/conciergeclient. The
two packages do basically the same thing. I don't think we use the former
anymore.
- We re-enabled cluster-scoped owner assertions in the integration tests.
This code was added in internal/ownerref. See a0546942 for when this
assertion was removed.
- Note: the middlware code is in charge of restoring the GV of a request object,
so we should never need to write mutations that do that.
- We updated the supervisor secret generation to no longer manually set an owner
reference to the deployment since the middleware code now does this. I think we
still need some way to make an initial event for the secret generator
controller, which involves knowing the namespace and the name of the generated
secret, so I still wired the deployment through. We could use a namespace/name
tuple here, but I was lazy.
Signed-off-by: Andrew Keesler <akeesler@vmware.com>
Co-authored-by: Ryan Richard <richardry@vmware.com>
This commit is contained in:
231
internal/kubeclient/path_test.go
Normal file
231
internal/kubeclient/path_test.go
Normal file
@@ -0,0 +1,231 @@
|
||||
// Copyright 2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package kubeclient
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
|
||||
loginv1alpha1 "go.pinniped.dev/generated/1.20/apis/concierge/login/v1alpha1"
|
||||
configv1alpha1 "go.pinniped.dev/generated/1.20/apis/supervisor/config/v1alpha1"
|
||||
)
|
||||
|
||||
func Test_updatePathNewGVK(t *testing.T) {
|
||||
type args struct {
|
||||
reqURL *url.URL
|
||||
result *mutationResult
|
||||
apiPathPrefix string
|
||||
reqInfo *genericapirequest.RequestInfo
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *url.URL
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "no gvk change",
|
||||
args: args{
|
||||
reqURL: mustParse(t, "https://walrus.tld/api/v1/pods"),
|
||||
result: &mutationResult{},
|
||||
},
|
||||
want: mustParse(t, "https://walrus.tld/api/v1/pods"),
|
||||
},
|
||||
{
|
||||
name: "no original gvk group",
|
||||
args: args{
|
||||
result: &mutationResult{
|
||||
origGVK: schema.GroupVersionKind{
|
||||
Group: "",
|
||||
},
|
||||
gvkChanged: true,
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "cluster-scoped list path",
|
||||
args: args{
|
||||
reqURL: mustParse(t, "https://walrus.tld/apis/"+loginv1alpha1.SchemeGroupVersion.String()+"/tokencredentialrequests"),
|
||||
result: &mutationResult{
|
||||
origGVK: loginv1alpha1.SchemeGroupVersion.WithKind("TokenCredentialRequest"),
|
||||
newGVK: schema.GroupVersionKind{
|
||||
Group: "login.concierge.tuna.io",
|
||||
Version: loginv1alpha1.SchemeGroupVersion.Version,
|
||||
Kind: "TokenCredentialRequest",
|
||||
},
|
||||
gvkChanged: true,
|
||||
},
|
||||
apiPathPrefix: "/apis",
|
||||
reqInfo: &genericapirequest.RequestInfo{},
|
||||
},
|
||||
want: mustParse(t, "https://walrus.tld/apis/login.concierge.tuna.io/v1alpha1/tokencredentialrequests"),
|
||||
},
|
||||
{
|
||||
name: "cluster-scoped get path",
|
||||
args: args{
|
||||
reqURL: mustParse(t, "https://walrus.tld/apis/"+loginv1alpha1.SchemeGroupVersion.String()+"/tokencredentialrequests/some-name"),
|
||||
result: &mutationResult{
|
||||
origGVK: loginv1alpha1.SchemeGroupVersion.WithKind("TokenCredentialRequest"),
|
||||
newGVK: schema.GroupVersionKind{
|
||||
Group: "login.concierge.tuna.io",
|
||||
Version: loginv1alpha1.SchemeGroupVersion.Version,
|
||||
Kind: "TokenCredentialRequest",
|
||||
},
|
||||
gvkChanged: true,
|
||||
},
|
||||
apiPathPrefix: "/apis",
|
||||
reqInfo: &genericapirequest.RequestInfo{},
|
||||
},
|
||||
want: mustParse(t, "https://walrus.tld/apis/login.concierge.tuna.io/v1alpha1/tokencredentialrequests/some-name"),
|
||||
},
|
||||
{
|
||||
name: "namespace-scoped list path",
|
||||
args: args{
|
||||
reqURL: mustParse(t, "https://walrus.tld/apis/"+configv1alpha1.SchemeGroupVersion.String()+"/namespaces/default/federationdomains"),
|
||||
result: &mutationResult{
|
||||
origGVK: configv1alpha1.SchemeGroupVersion.WithKind("FederationDomain"),
|
||||
newGVK: schema.GroupVersionKind{
|
||||
Group: "config.supervisor.tuna.io",
|
||||
Version: configv1alpha1.SchemeGroupVersion.Version,
|
||||
Kind: "FederationDomain",
|
||||
},
|
||||
gvkChanged: true,
|
||||
},
|
||||
apiPathPrefix: "/apis",
|
||||
reqInfo: &genericapirequest.RequestInfo{},
|
||||
},
|
||||
want: mustParse(t, "https://walrus.tld/apis/config.supervisor.tuna.io/v1alpha1/namespaces/default/federationdomains"),
|
||||
},
|
||||
{
|
||||
name: "namespace-scoped get path",
|
||||
args: args{
|
||||
reqURL: mustParse(t, "https://walrus.tld/apis/"+configv1alpha1.SchemeGroupVersion.String()+"/namespaces/default/federationdomains/some-name"),
|
||||
result: &mutationResult{
|
||||
origGVK: configv1alpha1.SchemeGroupVersion.WithKind("FederationDomain"),
|
||||
newGVK: schema.GroupVersionKind{
|
||||
Group: "config.supervisor.tuna.io",
|
||||
Version: configv1alpha1.SchemeGroupVersion.Version,
|
||||
Kind: "FederationDomain",
|
||||
},
|
||||
gvkChanged: true,
|
||||
},
|
||||
apiPathPrefix: "/apis",
|
||||
reqInfo: &genericapirequest.RequestInfo{},
|
||||
},
|
||||
want: mustParse(t, "https://walrus.tld/apis/config.supervisor.tuna.io/v1alpha1/namespaces/default/federationdomains/some-name"),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := updatePathNewGVK(tt.args.reqURL, tt.args.result, tt.args.apiPathPrefix, tt.args.reqInfo)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("updatePathNewGVK() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("updatePathNewGVK() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_reqWithoutPrefix(t *testing.T) {
|
||||
body := ioutil.NopCloser(bytes.NewBuffer([]byte("some body")))
|
||||
newReq := func(rawurl string) *http.Request {
|
||||
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, rawurl, body)
|
||||
require.NoError(t, err)
|
||||
return req
|
||||
}
|
||||
|
||||
type args struct {
|
||||
req *http.Request
|
||||
hostURL string
|
||||
apiPathPrefix string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *http.Request
|
||||
}{
|
||||
{
|
||||
name: "happy path",
|
||||
args: args{
|
||||
req: newReq("https://walrus.tld/apis/some/path"),
|
||||
hostURL: "https://walrus.tld",
|
||||
apiPathPrefix: "/apis",
|
||||
},
|
||||
want: newReq("https://walrus.tld/some/path"),
|
||||
},
|
||||
{
|
||||
name: "host url already has slash suffix",
|
||||
args: args{
|
||||
req: newReq("https://walrus.tld/apis/some/path"),
|
||||
hostURL: "https://walrus.tld/",
|
||||
apiPathPrefix: "/apis",
|
||||
},
|
||||
want: newReq("https://walrus.tld/some/path"),
|
||||
},
|
||||
{
|
||||
name: "api prefix already has slash prefix",
|
||||
args: args{
|
||||
req: newReq("https://walrus.tld/apis/some/path"),
|
||||
hostURL: "https://walrus.tld",
|
||||
apiPathPrefix: "apis",
|
||||
},
|
||||
want: newReq("https://walrus.tld/some/path"),
|
||||
},
|
||||
{
|
||||
name: "api prefix already has slash suffix",
|
||||
args: args{
|
||||
req: newReq("https://walrus.tld/apis/some/path"),
|
||||
hostURL: "https://walrus.tld",
|
||||
apiPathPrefix: "/apis/",
|
||||
},
|
||||
want: newReq("https://walrus.tld/some/path"),
|
||||
},
|
||||
{
|
||||
name: "no api path prefix",
|
||||
args: args{
|
||||
req: newReq("https://walrus.tld"),
|
||||
},
|
||||
want: newReq("https://walrus.tld"),
|
||||
},
|
||||
{
|
||||
name: "hostURL and req URL mismatch",
|
||||
args: args{
|
||||
req: newReq("https://walrus.tld.some-other-url/some/path"),
|
||||
hostURL: "https://walrus.tld",
|
||||
apiPathPrefix: "/apis",
|
||||
},
|
||||
want: newReq("https://walrus.tld.some-other-url/some/path"),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
req := *tt.args.req
|
||||
if got := reqWithoutPrefix(&req, tt.args.hostURL, tt.args.apiPathPrefix); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("reqWithoutPrefix() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func mustParse(t *testing.T, rawurl string) *url.URL {
|
||||
t.Helper()
|
||||
url, err := url.Parse(rawurl)
|
||||
require.NoError(t, err)
|
||||
return url
|
||||
}
|
||||
Reference in New Issue
Block a user