548 lines
17 KiB
Go
548 lines
17 KiB
Go
// AI generated tests and not yet reviewed.
|
|
package proxyprovider
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
|
|
v1alpha1 "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/apis/proxyprovider/v1alpha1"
|
|
operatorfake "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/clientset/versioned/fake"
|
|
operatorinformers "gitea.t000-n.de/t.behrendt/authentik-kubernetes-operator/pkg/generated/informers/externalversions"
|
|
authentikapi "goauthentik.io/api/v3"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/client-go/kubernetes/fake"
|
|
"k8s.io/client-go/tools/cache"
|
|
)
|
|
|
|
const testOutpostID = "550e8400-e29b-41d4-a716-446655440000"
|
|
|
|
func TestController_syncHandler_create(t *testing.T) {
|
|
const wantPK = 42
|
|
|
|
var outpostPartialUpdateCalled bool
|
|
server := newAuthentikTestServer(t, authentikTestHandlers{
|
|
proxyCreate: func(w http.ResponseWriter, _ *http.Request) {
|
|
writeJSON(t, w, http.StatusCreated, map[string]any{"pk": wantPK})
|
|
},
|
|
outpostRetrieve: outpostRetrieveHandler(t, nil),
|
|
outpostPartialUpdate: func(w http.ResponseWriter, r *http.Request) {
|
|
outpostPartialUpdateCalled = true
|
|
var body struct {
|
|
Providers []int32 `json:"providers"`
|
|
}
|
|
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
|
t.Fatalf("decode outpost patch body: %v", err)
|
|
}
|
|
if !slices.Contains(body.Providers, wantPK) {
|
|
t.Fatalf("patched providers = %v, want to contain %d", body.Providers, wantPK)
|
|
}
|
|
writeJSON(t, w, http.StatusOK, map[string]any{"pk": testOutpostID, "providers": body.Providers})
|
|
},
|
|
})
|
|
t.Cleanup(server.Close)
|
|
|
|
ctrl, ctx, cancel := newTestController(t, testProxyProvider(), server.URL)
|
|
t.Cleanup(cancel)
|
|
|
|
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: "default", Name: "test-pp"})
|
|
if err != nil {
|
|
t.Fatalf("syncHandler() error = %v", err)
|
|
}
|
|
if !outpostPartialUpdateCalled {
|
|
t.Fatal("expected Authentik outpost partial update call")
|
|
}
|
|
|
|
got := getProxyProvider(t, ctrl, "default", "test-pp")
|
|
if got.Status.PK != "42" {
|
|
t.Fatalf("status.pk = %q, want 42", got.Status.PK)
|
|
}
|
|
}
|
|
|
|
func TestController_syncHandler_create_providerAlreadyInOutpost(t *testing.T) {
|
|
const wantPK = 42
|
|
|
|
var outpostPartialUpdateCalled bool
|
|
server := newAuthentikTestServer(t, authentikTestHandlers{
|
|
proxyCreate: func(w http.ResponseWriter, _ *http.Request) {
|
|
writeJSON(t, w, http.StatusCreated, map[string]any{"pk": wantPK})
|
|
},
|
|
outpostRetrieve: outpostRetrieveHandler(t, []int32{wantPK}),
|
|
outpostPartialUpdate: func(w http.ResponseWriter, _ *http.Request) {
|
|
outpostPartialUpdateCalled = true
|
|
},
|
|
})
|
|
t.Cleanup(server.Close)
|
|
|
|
ctrl, ctx, cancel := newTestController(t, testProxyProvider(), server.URL)
|
|
t.Cleanup(cancel)
|
|
|
|
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: "default", Name: "test-pp"})
|
|
if err != nil {
|
|
t.Fatalf("syncHandler() error = %v", err)
|
|
}
|
|
if outpostPartialUpdateCalled {
|
|
t.Fatal("did not expect Authentik outpost partial update when provider is already present")
|
|
}
|
|
|
|
got := getProxyProvider(t, ctrl, "default", "test-pp")
|
|
if got.Status.PK != "42" {
|
|
t.Fatalf("status.pk = %q, want 42", got.Status.PK)
|
|
}
|
|
}
|
|
|
|
func TestController_syncHandler_ensureFinalizers(t *testing.T) {
|
|
pp := testProxyProvider()
|
|
pp.Status.PK = "42"
|
|
|
|
server := newAuthentikTestServer(t, authentikTestHandlers{})
|
|
t.Cleanup(server.Close)
|
|
|
|
ctrl, ctx, cancel := newTestController(t, pp, server.URL)
|
|
t.Cleanup(cancel)
|
|
|
|
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pp.Namespace, Name: pp.Name})
|
|
if err != nil {
|
|
t.Fatalf("syncHandler() error = %v", err)
|
|
}
|
|
|
|
got := getProxyProvider(t, ctrl, pp.Namespace, pp.Name)
|
|
if !slices.Contains(got.Finalizers, DeleteAuthentikProxyProviderFinalizer) {
|
|
t.Fatalf("finalizers = %v, want %q", got.Finalizers, DeleteAuthentikProxyProviderFinalizer)
|
|
}
|
|
}
|
|
|
|
func TestController_syncHandler_update(t *testing.T) {
|
|
pp := testProxyProvider()
|
|
pp.Status.PK = "42"
|
|
pp.Finalizers = []string{DeleteAuthentikProxyProviderFinalizer}
|
|
|
|
var outpostPartialUpdateCalled bool
|
|
server := newAuthentikTestServer(t, authentikTestHandlers{
|
|
allRetrieve: func(w http.ResponseWriter, _ *http.Request) {
|
|
writeJSON(t, w, http.StatusOK, map[string]any{"pk": 42})
|
|
},
|
|
proxyPartialUpdate: func(w http.ResponseWriter, _ *http.Request) {
|
|
writeJSON(t, w, http.StatusOK, map[string]any{"pk": 42})
|
|
},
|
|
outpostRetrieve: outpostRetrieveHandler(t, nil),
|
|
outpostPartialUpdate: func(w http.ResponseWriter, r *http.Request) {
|
|
outpostPartialUpdateCalled = true
|
|
var body struct {
|
|
Providers []int32 `json:"providers"`
|
|
}
|
|
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
|
t.Fatalf("decode outpost patch body: %v", err)
|
|
}
|
|
if !slices.Contains(body.Providers, 42) {
|
|
t.Fatalf("patched providers = %v, want to contain 42", body.Providers)
|
|
}
|
|
writeJSON(t, w, http.StatusOK, map[string]any{"pk": testOutpostID, "providers": body.Providers})
|
|
},
|
|
})
|
|
t.Cleanup(server.Close)
|
|
|
|
ctrl, ctx, cancel := newTestController(t, pp, server.URL)
|
|
t.Cleanup(cancel)
|
|
|
|
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pp.Namespace, Name: pp.Name})
|
|
if err != nil {
|
|
t.Fatalf("syncHandler() error = %v", err)
|
|
}
|
|
if !outpostPartialUpdateCalled {
|
|
t.Fatal("expected Authentik outpost partial update call")
|
|
}
|
|
|
|
got := getProxyProvider(t, ctrl, pp.Namespace, pp.Name)
|
|
if got.Status.PK != "42" {
|
|
t.Fatalf("status.pk = %q, want 42", got.Status.PK)
|
|
}
|
|
}
|
|
|
|
func TestController_syncHandler_update_providerNotFound(t *testing.T) {
|
|
pp := testProxyProvider()
|
|
pp.Status.PK = "42"
|
|
pp.Finalizers = []string{DeleteAuthentikProxyProviderFinalizer}
|
|
|
|
server := newAuthentikTestServer(t, authentikTestHandlers{
|
|
allRetrieve: func(w http.ResponseWriter, _ *http.Request) {
|
|
http.NotFound(w, nil)
|
|
},
|
|
})
|
|
t.Cleanup(server.Close)
|
|
|
|
ctrl, ctx, cancel := newTestController(t, pp, server.URL)
|
|
t.Cleanup(cancel)
|
|
|
|
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pp.Namespace, Name: pp.Name})
|
|
if err != nil {
|
|
t.Fatalf("syncHandler() error = %v", err)
|
|
}
|
|
|
|
got := getProxyProvider(t, ctrl, pp.Namespace, pp.Name)
|
|
if got.Status.PK != "" {
|
|
t.Fatalf("status.pk = %q, want empty after provider not found", got.Status.PK)
|
|
}
|
|
}
|
|
|
|
func TestController_syncHandler_delete(t *testing.T) {
|
|
const wantPK int32 = 42
|
|
now := metav1.Now()
|
|
pp := testProxyProvider()
|
|
pp.Status.PK = "42"
|
|
pp.DeletionTimestamp = &now
|
|
pp.Finalizers = []string{DeleteAuthentikProxyProviderFinalizer}
|
|
|
|
var outpostPartialUpdateCalled, destroyCalled bool
|
|
server := newAuthentikTestServer(t, authentikTestHandlers{
|
|
outpostRetrieve: outpostRetrieveHandler(t, []int32{wantPK}),
|
|
outpostPartialUpdate: func(w http.ResponseWriter, r *http.Request) {
|
|
outpostPartialUpdateCalled = true
|
|
var body struct {
|
|
Providers []int32 `json:"providers"`
|
|
}
|
|
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
|
t.Fatalf("decode outpost patch body: %v", err)
|
|
}
|
|
if slices.Contains(body.Providers, wantPK) {
|
|
t.Fatalf("patched providers = %v, want provider %d removed", body.Providers, wantPK)
|
|
}
|
|
writeJSON(t, w, http.StatusOK, map[string]any{"pk": testOutpostID, "providers": body.Providers})
|
|
},
|
|
proxyDestroy: func(w http.ResponseWriter, r *http.Request) {
|
|
destroyCalled = true
|
|
if r.Method != http.MethodDelete {
|
|
t.Errorf("destroy method = %s, want DELETE", r.Method)
|
|
}
|
|
w.WriteHeader(http.StatusNoContent)
|
|
},
|
|
})
|
|
t.Cleanup(server.Close)
|
|
|
|
ctrl, ctx, cancel := newTestController(t, pp, server.URL)
|
|
t.Cleanup(cancel)
|
|
|
|
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pp.Namespace, Name: pp.Name})
|
|
if err != nil {
|
|
t.Fatalf("syncHandler() error = %v", err)
|
|
}
|
|
if !outpostPartialUpdateCalled {
|
|
t.Fatal("expected Authentik outpost partial update call")
|
|
}
|
|
if !destroyCalled {
|
|
t.Fatal("expected Authentik destroy call")
|
|
}
|
|
|
|
got := getProxyProvider(t, ctrl, pp.Namespace, pp.Name)
|
|
if slices.Contains(got.Finalizers, DeleteAuthentikProxyProviderFinalizer) {
|
|
t.Fatalf("finalizers = %v, want finalizer removed", got.Finalizers)
|
|
}
|
|
}
|
|
|
|
func TestController_syncHandler_delete_providerNotInOutpost(t *testing.T) {
|
|
now := metav1.Now()
|
|
pp := testProxyProvider()
|
|
pp.Status.PK = "42"
|
|
pp.DeletionTimestamp = &now
|
|
pp.Finalizers = []string{DeleteAuthentikProxyProviderFinalizer}
|
|
|
|
var outpostPartialUpdateCalled, destroyCalled bool
|
|
server := newAuthentikTestServer(t, authentikTestHandlers{
|
|
outpostRetrieve: outpostRetrieveHandler(t, nil),
|
|
outpostPartialUpdate: func(w http.ResponseWriter, _ *http.Request) {
|
|
outpostPartialUpdateCalled = true
|
|
},
|
|
proxyDestroy: func(w http.ResponseWriter, _ *http.Request) {
|
|
destroyCalled = true
|
|
w.WriteHeader(http.StatusNoContent)
|
|
},
|
|
})
|
|
t.Cleanup(server.Close)
|
|
|
|
ctrl, ctx, cancel := newTestController(t, pp, server.URL)
|
|
t.Cleanup(cancel)
|
|
|
|
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pp.Namespace, Name: pp.Name})
|
|
if err != nil {
|
|
t.Fatalf("syncHandler() error = %v", err)
|
|
}
|
|
if outpostPartialUpdateCalled {
|
|
t.Fatal("did not expect Authentik outpost partial update when provider is not in outpost")
|
|
}
|
|
if !destroyCalled {
|
|
t.Fatal("expected Authentik destroy call")
|
|
}
|
|
|
|
got := getProxyProvider(t, ctrl, pp.Namespace, pp.Name)
|
|
if slices.Contains(got.Finalizers, DeleteAuthentikProxyProviderFinalizer) {
|
|
t.Fatalf("finalizers = %v, want finalizer removed", got.Finalizers)
|
|
}
|
|
}
|
|
|
|
func TestController_syncHandler_delete_providerAlreadyGone(t *testing.T) {
|
|
const wantPK int32 = 42
|
|
now := metav1.Now()
|
|
pp := testProxyProvider()
|
|
pp.Status.PK = "42"
|
|
pp.DeletionTimestamp = &now
|
|
pp.Finalizers = []string{DeleteAuthentikProxyProviderFinalizer}
|
|
|
|
server := newAuthentikTestServer(t, authentikTestHandlers{
|
|
outpostRetrieve: outpostRetrieveHandler(t, []int32{wantPK}),
|
|
outpostPartialUpdate: func(w http.ResponseWriter, r *http.Request) {
|
|
var body struct {
|
|
Providers []int32 `json:"providers"`
|
|
}
|
|
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
|
|
t.Fatalf("decode outpost patch body: %v", err)
|
|
}
|
|
writeJSON(t, w, http.StatusOK, map[string]any{"pk": testOutpostID, "providers": body.Providers})
|
|
},
|
|
proxyDestroy: func(w http.ResponseWriter, _ *http.Request) {
|
|
http.NotFound(w, nil)
|
|
},
|
|
})
|
|
t.Cleanup(server.Close)
|
|
|
|
ctrl, ctx, cancel := newTestController(t, pp, server.URL)
|
|
t.Cleanup(cancel)
|
|
|
|
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pp.Namespace, Name: pp.Name})
|
|
if err != nil {
|
|
t.Fatalf("syncHandler() error = %v", err)
|
|
}
|
|
|
|
got := getProxyProvider(t, ctrl, pp.Namespace, pp.Name)
|
|
if slices.Contains(got.Finalizers, DeleteAuthentikProxyProviderFinalizer) {
|
|
t.Fatalf("finalizers = %v, want finalizer removed after 404", got.Finalizers)
|
|
}
|
|
}
|
|
|
|
func TestController_syncHandler_notFound(t *testing.T) {
|
|
server := newAuthentikTestServer(t, authentikTestHandlers{})
|
|
t.Cleanup(server.Close)
|
|
|
|
ctrl, ctx, cancel := newTestController(t, nil, server.URL)
|
|
t.Cleanup(cancel)
|
|
|
|
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: "default", Name: "missing"})
|
|
if err != nil {
|
|
t.Fatalf("syncHandler() error = %v, want nil for missing object", err)
|
|
}
|
|
}
|
|
|
|
func TestController_syncHandler_invalidPK(t *testing.T) {
|
|
pp := testProxyProvider()
|
|
pp.Status.PK = "not-a-number"
|
|
pp.Finalizers = []string{DeleteAuthentikProxyProviderFinalizer}
|
|
|
|
server := newAuthentikTestServer(t, authentikTestHandlers{})
|
|
t.Cleanup(server.Close)
|
|
|
|
ctrl, ctx, cancel := newTestController(t, pp, server.URL)
|
|
t.Cleanup(cancel)
|
|
|
|
err := ctrl.syncHandler(ctx, cache.ObjectName{Namespace: pp.Namespace, Name: pp.Name})
|
|
if err == nil {
|
|
t.Fatal("syncHandler() error = nil, want parse error")
|
|
}
|
|
if !strings.Contains(err.Error(), "error parsing PK") {
|
|
t.Fatalf("syncHandler() error = %v, want PK parse error", err)
|
|
}
|
|
}
|
|
|
|
// --- test helpers ---
|
|
|
|
func testProxyProvider() *v1alpha1.ProxyProvider {
|
|
return &v1alpha1.ProxyProvider{
|
|
TypeMeta: metav1.TypeMeta{
|
|
APIVersion: v1alpha1.SchemeGroupVersion.String(),
|
|
Kind: "ProxyProvider",
|
|
},
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test-pp",
|
|
Namespace: "default",
|
|
},
|
|
Spec: v1alpha1.ProxyProviderSpec{
|
|
Name: "my-app",
|
|
AuthorizationFlow: "flow-auth",
|
|
InvalidationFlow: "flow-invalidate",
|
|
ExternalHost: "https://app.example.com",
|
|
Outpost: testOutpostID,
|
|
},
|
|
}
|
|
}
|
|
|
|
func newTestController(t *testing.T, pp *v1alpha1.ProxyProvider, authentikURL string) (*ProxyProviderController, context.Context, context.CancelFunc) {
|
|
t.Helper()
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
ctrl, _, stop := newTestControllerWithContext(t, ctx, pp, authentikURL)
|
|
return ctrl, ctx, func() {
|
|
cancel()
|
|
stop()
|
|
}
|
|
}
|
|
|
|
func newTestControllerWithContext(t *testing.T, ctx context.Context, pp *v1alpha1.ProxyProvider, authentikURL string) (*ProxyProviderController, context.Context, func()) {
|
|
t.Helper()
|
|
|
|
authentikClient := newAuthentikAPIClientForTest(t, authentikURL)
|
|
|
|
var objects []runtime.Object
|
|
if pp != nil {
|
|
objects = append(objects, pp)
|
|
}
|
|
proxyClient := operatorfake.NewSimpleClientset(objects...)
|
|
|
|
informerFactory := operatorinformers.NewSharedInformerFactory(proxyClient, 0)
|
|
proxyInformer := informerFactory.Proxyprovider().V1alpha1().ProxyProviders()
|
|
|
|
ctrl := NewController(ctx, fake.NewClientset(), proxyClient, authentikClient, proxyInformer)
|
|
|
|
informerFactory.Start(ctx.Done())
|
|
for informerType, synced := range informerFactory.WaitForCacheSync(ctx.Done()) {
|
|
if !synced {
|
|
t.Fatalf("informer %v failed to sync", informerType)
|
|
}
|
|
}
|
|
|
|
return ctrl, ctx, func() {}
|
|
}
|
|
|
|
func newAuthentikAPIClientForTest(t *testing.T, serverURL string) *authentikapi.APIClient {
|
|
t.Helper()
|
|
|
|
u, err := url.Parse(serverURL)
|
|
if err != nil {
|
|
t.Fatalf("parse server URL: %v", err)
|
|
}
|
|
|
|
cfg := authentikapi.NewConfiguration()
|
|
cfg.Scheme = u.Scheme
|
|
cfg.Host = u.Host
|
|
|
|
return authentikapi.NewAPIClient(cfg)
|
|
}
|
|
|
|
type authentikTestHandlers struct {
|
|
proxyCreate http.HandlerFunc
|
|
proxyDestroy http.HandlerFunc
|
|
proxyPartialUpdate http.HandlerFunc
|
|
allRetrieve http.HandlerFunc
|
|
outpostRetrieve http.HandlerFunc
|
|
outpostPartialUpdate http.HandlerFunc
|
|
}
|
|
|
|
func outpostRetrieveHandler(t *testing.T, providers []int32) http.HandlerFunc {
|
|
t.Helper()
|
|
return func(w http.ResponseWriter, _ *http.Request) {
|
|
writeJSON(t, w, http.StatusOK, map[string]any{
|
|
"pk": testOutpostID,
|
|
"providers": providers,
|
|
})
|
|
}
|
|
}
|
|
|
|
func newAuthentikTestServer(t *testing.T, handlers authentikTestHandlers) *httptest.Server {
|
|
t.Helper()
|
|
|
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
path := r.URL.Path
|
|
|
|
switch {
|
|
case path == "/api/v3/providers/proxy/" && r.Method == http.MethodPost:
|
|
if handlers.proxyCreate != nil {
|
|
handlers.proxyCreate(w, r)
|
|
return
|
|
}
|
|
http.NotFound(w, r)
|
|
|
|
case strings.HasPrefix(path, "/api/v3/providers/proxy/") && strings.HasSuffix(path, "/"):
|
|
idPath := strings.TrimPrefix(path, "/api/v3/providers/proxy/")
|
|
if idPath == "" {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
switch r.Method {
|
|
case http.MethodDelete:
|
|
if handlers.proxyDestroy != nil {
|
|
handlers.proxyDestroy(w, r)
|
|
return
|
|
}
|
|
http.NotFound(w, r)
|
|
case http.MethodPatch:
|
|
if handlers.proxyPartialUpdate != nil {
|
|
handlers.proxyPartialUpdate(w, r)
|
|
return
|
|
}
|
|
http.NotFound(w, r)
|
|
default:
|
|
http.Error(w, "unexpected method on proxy instance", http.StatusMethodNotAllowed)
|
|
}
|
|
|
|
case strings.HasPrefix(path, "/api/v3/providers/all/") && strings.HasSuffix(path, "/"):
|
|
if r.Method == http.MethodGet && handlers.allRetrieve != nil {
|
|
handlers.allRetrieve(w, r)
|
|
return
|
|
}
|
|
http.NotFound(w, r)
|
|
|
|
case strings.HasPrefix(path, "/api/v3/outposts/instances/") && strings.HasSuffix(path, "/"):
|
|
idPath := strings.TrimPrefix(path, "/api/v3/outposts/instances/")
|
|
idPath = strings.TrimSuffix(idPath, "/")
|
|
if idPath == "" || strings.Contains(idPath, "/") {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
switch r.Method {
|
|
case http.MethodGet:
|
|
if handlers.outpostRetrieve != nil {
|
|
handlers.outpostRetrieve(w, r)
|
|
return
|
|
}
|
|
http.NotFound(w, r)
|
|
case http.MethodPatch:
|
|
if handlers.outpostPartialUpdate != nil {
|
|
handlers.outpostPartialUpdate(w, r)
|
|
return
|
|
}
|
|
http.NotFound(w, r)
|
|
default:
|
|
http.Error(w, "unexpected method on outpost instance", http.StatusMethodNotAllowed)
|
|
}
|
|
|
|
default:
|
|
http.NotFound(w, r)
|
|
}
|
|
})
|
|
|
|
return httptest.NewServer(handler)
|
|
}
|
|
|
|
func writeJSON(t *testing.T, w http.ResponseWriter, status int, body any) {
|
|
t.Helper()
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(status)
|
|
if err := json.NewEncoder(w).Encode(body); err != nil {
|
|
t.Fatalf("write JSON response: %v", err)
|
|
}
|
|
}
|
|
|
|
func getProxyProvider(t *testing.T, ctrl *ProxyProviderController, namespace, name string) *v1alpha1.ProxyProvider {
|
|
t.Helper()
|
|
|
|
got, err := ctrl.proxyProviderClientset.ProxyproviderV1alpha1().ProxyProviders(namespace).Get(
|
|
context.Background(), name, metav1.GetOptions{},
|
|
)
|
|
if err != nil {
|
|
t.Fatalf("get ProxyProvider: %v", err)
|
|
}
|
|
return got
|
|
}
|