Skip to content

Commit 16eef37

Browse files
committed
add some unit tests
1 parent fca67cc commit 16eef37

3 files changed

Lines changed: 170 additions & 0 deletions

File tree

pomerium/ctrl/bootstrap_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/pomerium/pomerium/config"
1414

15+
icsv1 "github.com/pomerium/ingress-controller/apis/ingress/v1"
1516
"github.com/pomerium/ingress-controller/model"
1617
"github.com/pomerium/ingress-controller/util"
1718
)
@@ -67,3 +68,62 @@ func TestSecretsDecodeRules(t *testing.T) {
6768
},
6869
}))
6970
}
71+
72+
const exampleCert = `-----BEGIN CERTIFICATE-----
73+
MIIBXzCCAQagAwIBAgICEAAwCgYIKoZIzj0EAwIwFzEVMBMGA1UEAxMMVGVzdCBS
74+
b290IENBMB4XDTI1MDkxMjE1NTk1M1oXDTM1MDkxMDE1NTk1M1owFzEVMBMGA1UE
75+
AxMMVGVzdCBSb290IENBMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEnomv0HAN
76+
5+BEp3H5LZPl7WE3KWa6VPAxBpCf8BXYpyaJH2PG7VJ1Ateu/I2Y/+AH4f8m6DHV
77+
iHhi3ll2Qu1oLqNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
78+
HQYDVR0OBBYEFEibW9kXYo7F3BR++6c8lMlU5GAYMAoGCCqGSM49BAMCA0cAMEQC
79+
IDopBqx9I9AxBtHFzAESP7uoReoRdwwoqdUDY+I+/kW0AiAY1wV3V3A4fSdjV6x9
80+
fk5EbQ+E27ez9yyDZ6XtQKlJLQ==
81+
-----END CERTIFICATE-----`
82+
83+
func TestApplyAdditional(t *testing.T) {
84+
// ApplyAdditional propagates additional core bootstrap settings from the
85+
// Pomerium CRD spec to the config.Options struct.
86+
idpURL := "https://idp.example.com"
87+
cfg := &model.Config{
88+
Pomerium: icsv1.Pomerium{
89+
Spec: icsv1.PomeriumSpec{
90+
Authenticate: &icsv1.Authenticate{
91+
URL: "https://authenticate.example.com",
92+
},
93+
IdentityProvider: &icsv1.IdentityProvider{
94+
Provider: "oidc",
95+
URL: &idpURL,
96+
Secret: "test/idp-client-secret",
97+
},
98+
},
99+
},
100+
IdpSecret: &v1.Secret{
101+
Data: map[string][]byte{
102+
"client_id": []byte("test-client-id"),
103+
"client_secret": []byte("test-client-secret"),
104+
},
105+
},
106+
Certs: map[types.NamespacedName]*v1.Secret{
107+
{Namespace: "test", Name: "my-cert"}: {
108+
Type: v1.SecretTypeTLS,
109+
Data: map[string][]byte{
110+
"tls.crt": []byte(exampleCert),
111+
"tls.key": []byte("not-a-real-key"),
112+
},
113+
},
114+
},
115+
}
116+
117+
var opts config.Options
118+
err := ApplyAdditional(t.Context(), &opts, cfg)
119+
require.NoError(t, err)
120+
assert.Equal(t, "https://authenticate.example.com", opts.AuthenticateURLString)
121+
assert.Equal(t, "oidc", opts.Provider)
122+
assert.Equal(t, "https://idp.example.com", opts.ProviderURL)
123+
assert.Equal(t, "test-client-id", opts.ClientID)
124+
assert.Equal(t, "test-client-secret", opts.ClientSecret)
125+
if assert.Len(t, opts.CertificateData, 1) {
126+
assert.Equal(t, []byte(exampleCert), opts.CertificateData[0].CertBytes)
127+
assert.Equal(t, []byte("not-a-real-key"), opts.CertificateData[0].KeyBytes)
128+
}
129+
}

pomerium/routes_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import (
44
"context"
55
"fmt"
66
"math/rand"
7+
"net/url"
78
"sort"
89
"testing"
910

1011
"github.com/google/go-cmp/cmp"
1112
"github.com/stretchr/testify/assert"
1213
"github.com/stretchr/testify/require"
14+
"github.com/volatiletech/null/v9"
1315
"google.golang.org/protobuf/encoding/protojson"
1416
"google.golang.org/protobuf/proto"
1517
"google.golang.org/protobuf/testing/protocmp"
@@ -19,7 +21,9 @@ import (
1921
"k8s.io/apimachinery/pkg/types"
2022
"k8s.io/apimachinery/pkg/util/intstr"
2123

24+
"github.com/pomerium/pomerium/config"
2225
pb "github.com/pomerium/pomerium/pkg/grpc/config"
26+
"github.com/pomerium/pomerium/pkg/identity"
2327

2428
_ "github.com/pomerium/ingress-controller/internal"
2529
"github.com/pomerium/ingress-controller/model"
@@ -82,6 +86,59 @@ func TestHttp01Solver(t *testing.T) {
8286
require.True(t, routes[0].PreserveHostHeader)
8387
}
8488

89+
func TestIngressToRoutes(t *testing.T) {
90+
typePrefix := networkingv1.PathTypePrefix
91+
ic := &model.IngressConfig{
92+
Ingress: &networkingv1.Ingress{
93+
ObjectMeta: metav1.ObjectMeta{Name: "my-ingress", Namespace: "test"},
94+
Spec: networkingv1.IngressSpec{
95+
Rules: []networkingv1.IngressRule{{
96+
Host: "a.localhost.pomerium.io",
97+
IngressRuleValue: networkingv1.IngressRuleValue{
98+
HTTP: &networkingv1.HTTPIngressRuleValue{
99+
Paths: []networkingv1.HTTPIngressPath{{
100+
Path: "/",
101+
PathType: &typePrefix,
102+
Backend: networkingv1.IngressBackend{
103+
Service: &networkingv1.IngressServiceBackend{
104+
Name: "example-svc",
105+
Port: networkingv1.ServiceBackendPort{Number: 8080},
106+
},
107+
},
108+
}},
109+
},
110+
},
111+
}},
112+
},
113+
},
114+
Services: map[types.NamespacedName]*corev1.Service{
115+
{Name: "example-svc", Namespace: "test"}: {},
116+
},
117+
}
118+
119+
routes, err := IngressToRoutes(context.Background(), ic)
120+
require.NoError(t, err)
121+
assert.Equal(t, []config.Policy{{
122+
ID: `{"n":"my-ingress","ns":"test","h":"a.localhost.pomerium.io","p":"/"}`,
123+
Name: "test-my-ingress-a-localhost-pomerium-io",
124+
From: "https://a.localhost.pomerium.io",
125+
To: config.WeightedURLs{{
126+
URL: url.URL{
127+
Scheme: "http",
128+
Host: "example-svc.test.svc.cluster.local:8080",
129+
},
130+
LbWeight: 0,
131+
}},
132+
Prefix: "/",
133+
StatName: null.StringFrom("test-my-ingress-a-localhost-pomerium-io"),
134+
AllowedIDPClaims: identity.FlattenedClaims{},
135+
SubPolicies: []config.SubPolicy{{
136+
AllowedIDPClaims: identity.FlattenedClaims{},
137+
}},
138+
HealthyPanicThreshold: null.NewInt32(0, false),
139+
}}, routes)
140+
}
141+
85142
func TestUpsertIngress(t *testing.T) {
86143
typePrefix := networkingv1.PathTypePrefix
87144
ic := &model.IngressConfig{

pomerium/sync_api_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,51 @@ func TestAPIReconciler_upsertOneIngress(t *testing.T) {
617617
assert.Equal(t, "missing-route-id", ic.Annotations["api.pomerium.io/route-id-0"])
618618
})
619619

620+
t.Run("failed precondition", func(t *testing.T) {
621+
// Pomerium Enterprise returns FailedPrecondition when route 'From' overlaps
622+
// with an existing route.
623+
ingress := ingressTemplate.DeepCopy()
624+
ic := &model.IngressConfig{
625+
AnnotationPrefix: "a", Ingress: ingress,
626+
Services: map[types.NamespacedName]*corev1.Service{
627+
{Name: "example-svc", Namespace: "test"}: {},
628+
},
629+
}
630+
631+
apiClient, k8sClient, r := setupReconciler(t)
632+
ctx := t.Context()
633+
634+
apiClient.EXPECT().CreateRoute(ctx, RequestEq(&configpb.CreateRouteRequest{
635+
Route: &configpb.Route{
636+
OriginatorId: new("ingress-controller"),
637+
Name: new("test-my-ingress-a-localhost-pomerium-io"),
638+
From: "https://a.localhost.pomerium.io",
639+
To: []string{"http://example-svc.test.svc.cluster.local:8080"},
640+
Prefix: "/",
641+
},
642+
})).Return(nil, connect.NewError(connect.CodeFailedPrecondition, fmt.Errorf("route overlap")))
643+
644+
apiClient.EXPECT().ListRoutes(ctx, RequestEq(&configpb.ListRoutesRequest{
645+
Filter: filterByName(t, "test-my-ingress-a-localhost-pomerium-io"),
646+
})).Return(connect.NewResponse(&configpb.ListRoutesResponse{
647+
Routes: []*configpb.Route{{
648+
Id: new("overlapping-route-id"),
649+
OriginatorId: new("ingress-controller"),
650+
Name: new("test-my-ingress-a-localhost-pomerium-io"),
651+
From: "https://a.localhost.pomerium.io",
652+
To: []string{"http://example-svc.test.svc.cluster.local:8080"},
653+
Prefix: "/",
654+
}},
655+
}), nil)
656+
657+
k8sClient.EXPECT().Patch(ctx, ingress, gomock.Any()).Return(nil)
658+
659+
changed, err := r.upsertOneIngress(ctx, ic)
660+
assert.True(t, changed)
661+
assert.NoError(t, err)
662+
assert.Equal(t, "overlapping-route-id", ic.Annotations["api.pomerium.io/route-id-0"])
663+
})
664+
620665
t.Run("patch error", func(t *testing.T) {
621666
ingress := ingressTemplate.DeepCopy()
622667
ic := &model.IngressConfig{
@@ -1647,6 +1692,14 @@ func TestAPIReconciler_deletePolicy(t *testing.T) {
16471692
})
16481693
}
16491694

1695+
func TestNewAPIReconciler_InvalidURL(t *testing.T) {
1696+
// NewAPIReconciler should return an error if the API URL is invalid
1697+
// when a dial address override is specified.
1698+
_, err := NewAPIReconciler("://invalid", "token", config.NewDefaultOptions(), "localhost:8443")
1699+
assert.Error(t, err)
1700+
assert.Contains(t, err.Error(), "invalid API URL")
1701+
}
1702+
16501703
func createKeyPairResponseWithID(id string) *connect.Response[configpb.CreateKeyPairResponse] {
16511704
return &connect.Response[configpb.CreateKeyPairResponse]{
16521705
Msg: &configpb.CreateKeyPairResponse{

0 commit comments

Comments
 (0)