Skip to content

Commit

Permalink
Fix Gateway trigger for when secret is modified (#2261)
Browse files Browse the repository at this point in the history
* Fix Gateway trigger for when secret is modified

* Add some simple unit tests

* up some testing timeouts for acceptance tests
  • Loading branch information
Andrew Stucki authored and absolutelightning committed Aug 4, 2023
1 parent 543f3c5 commit 2684338
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 7 deletions.
12 changes: 6 additions & 6 deletions acceptance/tests/api-gateway/api_gateway_tenancy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func TestAPIGateway_Tenancy(t *testing.T) {
checkConsulNotExists(t, consulClient, api.APIGateway, "gateway", namespaceForConsul(c.namespaceMirroring, gatewayNamespace))

// route failure
retryCheck(t, 10, func(r *retry.R) {
retryCheck(t, 30, func(r *retry.R) {
var httproute gwv1beta1.HTTPRoute
err := k8sClient.Get(context.Background(), types.NamespacedName{Name: "route", Namespace: routeNamespace}, &httproute)
require.NoError(r, err)
Expand All @@ -178,7 +178,7 @@ func TestAPIGateway_Tenancy(t *testing.T) {
createReferenceGrant(t, k8sClient, "route-service", routeNamespace, serviceNamespace)

// gateway updated with references allowed
retryCheck(t, 10, func(r *retry.R) {
retryCheck(t, 30, func(r *retry.R) {
var gateway gwv1beta1.Gateway
err := k8sClient.Get(context.Background(), types.NamespacedName{Name: "gateway", Namespace: gatewayNamespace}, &gateway)
require.NoError(r, err)
Expand All @@ -195,7 +195,7 @@ func TestAPIGateway_Tenancy(t *testing.T) {
})

// check the Consul gateway is updated, with the listener.
retryCheck(t, 10, func(r *retry.R) {
retryCheck(t, 30, func(r *retry.R) {
entry, _, err := consulClient.ConfigEntries().Get(api.APIGateway, "gateway", &api.QueryOptions{
Namespace: namespaceForConsul(c.namespaceMirroring, gatewayNamespace),
})
Expand All @@ -210,7 +210,7 @@ func TestAPIGateway_Tenancy(t *testing.T) {
})

// route updated with gateway and services allowed
retryCheck(t, 10, func(r *retry.R) {
retryCheck(t, 30, func(r *retry.R) {
var httproute gwv1beta1.HTTPRoute
err := k8sClient.Get(context.Background(), types.NamespacedName{Name: "route", Namespace: routeNamespace}, &httproute)
require.NoError(r, err)
Expand All @@ -225,7 +225,7 @@ func TestAPIGateway_Tenancy(t *testing.T) {
})

// now check to make sure that the route is updated and valid
retryCheck(t, 10, func(r *retry.R) {
retryCheck(t, 30, func(r *retry.R) {
// since we're not bound, check to make sure that the route doesn't target the gateway in Consul.
entry, _, err := consulClient.ConfigEntries().Get(api.HTTPRoute, "route", &api.QueryOptions{
Namespace: namespaceForConsul(c.namespaceMirroring, routeNamespace),
Expand All @@ -239,7 +239,7 @@ func TestAPIGateway_Tenancy(t *testing.T) {
})

// and check to make sure that the certificate exists
retryCheck(t, 10, func(r *retry.R) {
retryCheck(t, 30, func(r *retry.R) {
entry, _, err := consulClient.ConfigEntries().Get(api.InlineCertificate, "certificate", &api.QueryOptions{
Namespace: namespaceForConsul(c.namespaceMirroring, certificateNamespace),
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ func (r *GatewayController) transformSecret(ctx context.Context) func(o client.O
secret := o.(*corev1.Secret)
gatewayList := &gwv1beta1.GatewayList{}
if err := r.Client.List(ctx, gatewayList, &client.ListOptions{
FieldSelector: fields.OneTermEqualSelector(Secret_GatewayIndex, secret.Name),
FieldSelector: fields.OneTermEqualSelector(Secret_GatewayIndex, client.ObjectKeyFromObject(secret).String()),
}); err != nil {
return nil
}
Expand Down
91 changes: 91 additions & 0 deletions control-plane/api-gateway/controllers/gateway_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ import (
"testing"

"github.com/hashicorp/consul-k8s/control-plane/api-gateway/common"
"github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
gwv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
Expand Down Expand Up @@ -295,3 +300,89 @@ func TestTransformTCPRoute(t *testing.T) {
})
}
}

func TestTransformSecret(t *testing.T) {
t.Parallel()

gateway := &gwv1beta1.Gateway{
ObjectMeta: metav1.ObjectMeta{
Name: "gateway",
Namespace: "test",
},
Spec: gwv1beta1.GatewaySpec{
Listeners: []gwv1beta1.Listener{
{Name: "terminate", TLS: &gwv1beta1.GatewayTLSConfig{
Mode: common.PointerTo(gwv1beta1.TLSModeTerminate),
CertificateRefs: []gwv1beta1.SecretObjectReference{
{Name: "secret-no-namespace"},
{Name: "secret-namespace", Namespace: common.PointerTo(gwv1beta1.Namespace("other"))},
},
}},
{Name: "passthrough", TLS: &gwv1beta1.GatewayTLSConfig{
Mode: common.PointerTo(gwv1beta1.TLSModePassthrough),
CertificateRefs: []gwv1beta1.SecretObjectReference{
{Name: "passthrough", Namespace: common.PointerTo(gwv1beta1.Namespace("other"))},
},
}},
},
},
}

for name, tt := range map[string]struct {
secret *corev1.Secret
expected []reconcile.Request
}{
"explicit namespace from parent": {
secret: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Name: "secret-namespace", Namespace: "other"},
},
expected: []reconcile.Request{
{NamespacedName: types.NamespacedName{Name: "gateway", Namespace: "test"}},
},
},
"implicit namespace from parent": {
secret: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Name: "secret-no-namespace", Namespace: "test"},
},
expected: []reconcile.Request{
{NamespacedName: types.NamespacedName{Name: "gateway", Namespace: "test"}},
},
},
"mismatched namespace": {
secret: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Name: "secret-no-namespace", Namespace: "other"},
},
},
"mismatched names": {
secret: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Name: "something", Namespace: "test"},
},
},
"passthrough ignored": {
secret: &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Name: "passthrough", Namespace: "other"},
},
},
} {
t.Run(name, func(t *testing.T) {
tt := tt

t.Parallel()

s := runtime.NewScheme()
require.NoError(t, clientgoscheme.AddToScheme(s))
require.NoError(t, gwv1alpha2.Install(s))
require.NoError(t, gwv1beta1.Install(s))
require.NoError(t, v1alpha1.AddToScheme(s))

fakeClient := registerFieldIndexersForTest(fake.NewClientBuilder().WithScheme(s)).WithRuntimeObjects(gateway).Build()

controller := GatewayController{
Client: fakeClient,
}

fn := controller.transformSecret(context.Background())
require.ElementsMatch(t, tt.expected, fn(tt.secret))
})
}
}

0 comments on commit 2684338

Please sign in to comment.