Skip to content

Commit

Permalink
internal/provisioner: add Gateway label to generated resources (#5969)
Browse files Browse the repository at this point in the history
Adds the gateway.networking.k8s.io/gateway-name label
to generated resources.

Signed-off-by: Steve Kriss <stephen.kriss@gmail.com>
  • Loading branch information
skriss authored Dec 7, 2023
1 parent f42a569 commit eece587
Show file tree
Hide file tree
Showing 19 changed files with 118 additions and 52 deletions.
1 change: 1 addition & 0 deletions changelogs/unreleased/5969-skriss-small.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Gateway API: add the `gateway.networking.k8s.io/gateway-name` label to generated resources.
55 changes: 55 additions & 0 deletions internal/provisioner/controller/gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

contourv1alpha1 "github.com/projectcontour/contour/apis/projectcontour/v1alpha1"
"github.com/projectcontour/contour/internal/provisioner"
"github.com/projectcontour/contour/internal/provisioner/model"
"github.com/projectcontour/contour/internal/ref"

"github.com/go-logr/logr"
Expand Down Expand Up @@ -1343,6 +1344,60 @@ func TestGatewayReconcile(t *testing.T) {
}
},
},
"Gateway owner labels are set on all resources": {
gatewayClass: reconcilableGatewayClass("gatewayclass-1", controller),
gateway: makeGateway(),
assertions: func(t *testing.T, r *gatewayReconciler, gw *gatewayv1beta1.Gateway, reconcileErr error) {
require.NoError(t, reconcileErr)

for _, obj := range []client.Object{
&appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{Namespace: "gateway-1", Name: "contour-gateway-1"},
},
&appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{Namespace: "gateway-1", Name: "envoy-gateway-1"},
},
&corev1.Service{
ObjectMeta: metav1.ObjectMeta{Namespace: "gateway-1", Name: "contour-gateway-1"},
},
&corev1.Service{
ObjectMeta: metav1.ObjectMeta{Namespace: "gateway-1", Name: "envoy-gateway-1"},
},
&contourv1alpha1.ContourConfiguration{
ObjectMeta: metav1.ObjectMeta{Namespace: "gateway-1", Name: "contourconfig-gateway-1"},
},
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Namespace: "gateway-1", Name: "contourcert-gateway-1"},
},
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{Namespace: "gateway-1", Name: "envoycert-gateway-1"},
},
&corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{Namespace: "gateway-1", Name: "contour-gateway-1"},
},
&corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{Namespace: "gateway-1", Name: "envoy-gateway-1"},
},
&rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: "contour-gateway-1-gateway-1"},
},
&rbacv1.ClusterRoleBinding{
ObjectMeta: metav1.ObjectMeta{Name: "contour-gateway-1-gateway-1"},
},
&rbacv1.Role{
ObjectMeta: metav1.ObjectMeta{Namespace: "gateway-1", Name: "contour-gateway-1"},
},
&rbacv1.RoleBinding{
ObjectMeta: metav1.ObjectMeta{Namespace: "gateway-1", Name: "contour-rolebinding-gateway-1"},
},
} {
require.NoError(t, r.client.Get(context.Background(), keyFor(obj), obj))

assert.Equal(t, gw.Name, obj.GetLabels()[model.ContourOwningGatewayNameLabel])
assert.Equal(t, gw.Name, obj.GetLabels()[model.GatewayAPIOwningGatewayNameLabel])
}
},
},
}

for name, tc := range tests {
Expand Down
19 changes: 11 additions & 8 deletions internal/provisioner/labels/labels.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@ type LabeledObject interface {
GetLabels() map[string]string
}

// Exist returns true if obj contains labels m.
func Exist(obj LabeledObject, m map[string]string) bool {
labels := obj.GetLabels()
if labels == nil {
// AnyExist returns true if obj contains at least one of the provided labels.
func AnyExist(obj LabeledObject, labels map[string]string) bool {
objLabels := obj.GetLabels()

if len(objLabels) == 0 {
return false
}
for key, val := range m {
if found, ok := labels[key]; !ok || found != val {
return false

for k, v := range labels {
if val, ok := objLabels[k]; ok && val == v {
return true
}
}
return true

return false
}
35 changes: 21 additions & 14 deletions internal/provisioner/labels/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,28 @@ import (
"testing"

"github.com/projectcontour/contour/internal/provisioner/model"
"github.com/stretchr/testify/assert"
)

func TestExist(t *testing.T) {
func TestAnyExist(t *testing.T) {
testCases := []struct {
description string
current map[string]string
exist map[string]string
expected bool
}{
{
description: "nil labels",
current: nil,
exist: map[string]string{"name": "foo"},
expected: false,
},
{
description: "empty labels",
current: map[string]string{},
exist: map[string]string{"name": "foo"},
expected: false,
},
{
description: "one matched label",
current: map[string]string{"name": "foo"},
Expand All @@ -36,7 +49,7 @@ func TestExist(t *testing.T) {
description: "one of two matched labels",
current: map[string]string{"name": "foo"},
exist: map[string]string{"name": "foo", "ns": "foo-ns"},
expected: false,
expected: true,
},
{
description: "two matched labels",
Expand All @@ -56,20 +69,14 @@ func TestExist(t *testing.T) {
exist: map[string]string{"foo": "bar"},
expected: false,
},
{
description: "two unmatched labels",
current: map[string]string{"name": "bar"},
exist: map[string]string{"name": "bar", "ns": "foo-ns"},
expected: false,
},
}

contour := model.Contour{}
for _, tc := range testCases {
contour.Labels = tc.current
result := Exist(&contour, tc.exist)
if result != tc.expected {
t.Fatalf("%q: returned %t, expected %t.", tc.description, result, tc.expected)
}
t.Run(tc.description, func(t *testing.T) {
contour := model.Contour{}
contour.Labels = tc.current

assert.Equal(t, tc.expected, AnyExist(&contour, tc.exist))
})
}
}
22 changes: 9 additions & 13 deletions internal/provisioner/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ import (
)

const (
// OwningGatewayNameLabel is the owner reference label used for a Contour
// created by the gateway provisioner. The value should be the name of the Gateway.
OwningGatewayNameLabel = "projectcontour.io/owning-gateway-name"
// ContourOwningGatewayNameLabel is the Contour-defined owner reference label applied
// to generated resources. The value should be the name of the Gateway.
ContourOwningGatewayNameLabel = "projectcontour.io/owning-gateway-name"

// GatewayAPIOwningGatewayNameLabel is the Gateway API-defined owner reference label applied
// to generated resources. The value should be the name of the Gateway.
GatewayAPIOwningGatewayNameLabel = "gateway.networking.k8s.io/gateway-name"
)

// Default returns a default instance of a Contour
Expand Down Expand Up @@ -600,18 +604,10 @@ const (
ContourAvailableConditionType = "Available"
)

// OwningSelector returns a label selector using "projectcontour.io/owning-gateway-name".
func OwningSelector(contour *Contour) *metav1.LabelSelector {
return &metav1.LabelSelector{
MatchLabels: map[string]string{
OwningGatewayNameLabel: contour.Name,
},
}
}

// OwnerLabels returns owner labels for the provided contour.
func OwnerLabels(contour *Contour) map[string]string {
return map[string]string{
OwningGatewayNameLabel: contour.Name,
ContourOwningGatewayNameLabel: contour.Name,
GatewayAPIOwningGatewayNameLabel: contour.Name,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ func TestEnsureContourConfigDeleted(t *testing.T) {
Namespace: "contour-namespace",
Name: "contourconfig-contour-1",
Labels: map[string]string{
model.OwningGatewayNameLabel: "contour-1",
model.ContourOwningGatewayNameLabel: "contour-1",
},
},
},
Expand Down Expand Up @@ -292,7 +292,7 @@ func TestEnsureContourConfigDeleted(t *testing.T) {
Namespace: "contour-namespace",
Name: "contourconfig-contour-1",
Labels: map[string]string{
model.OwningGatewayNameLabel: "some-other-contour",
model.ContourOwningGatewayNameLabel: "some-other-contour",
},
},
},
Expand Down
4 changes: 2 additions & 2 deletions internal/provisioner/objects/dataplane/dataplane.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ func desiredDeployment(contour *model.Contour, contourImage, envoyImage string)
// updateDaemonSetIfNeeded updates a DaemonSet if current does not match desired,
// using contour to verify the existence of owner labels.
func updateDaemonSetIfNeeded(ctx context.Context, cli client.Client, contour *model.Contour, current, desired *appsv1.DaemonSet) error {
if labels.Exist(current, model.OwnerLabels(contour)) {
if labels.AnyExist(current, model.OwnerLabels(contour)) {
ds, updated := equality.DaemonsetConfigChanged(current, desired)
if updated {
if err := cli.Update(ctx, ds); err != nil {
Expand All @@ -503,7 +503,7 @@ func updateDaemonSetIfNeeded(ctx context.Context, cli client.Client, contour *mo
// updateDeploymentIfNeeded updates a Deployment if current does not match desired,
// using contour to verify the existence of owner labels.
func updateDeploymentIfNeeded(ctx context.Context, cli client.Client, contour *model.Contour, current, desired *appsv1.Deployment) error {
if labels.Exist(current, model.OwnerLabels(contour)) {
if labels.AnyExist(current, model.OwnerLabels(contour)) {
ds, updated := equality.DeploymentConfigChanged(current, desired)
if updated {
if err := cli.Update(ctx, ds); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/provisioner/objects/deployment/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ func DesiredDeployment(contour *model.Contour, image string) *appsv1.Deployment
// updateDeploymentIfNeeded updates a Deployment if current does not match desired,
// using contour to verify the existence of owner labels.
func updateDeploymentIfNeeded(ctx context.Context, cli client.Client, contour *model.Contour, current, desired *appsv1.Deployment) error {
if labels.Exist(current, model.OwnerLabels(contour)) {
if labels.AnyExist(current, model.OwnerLabels(contour)) {
deploy, updated := equality.DeploymentConfigChanged(current, desired)
if updated {
if err := cli.Update(ctx, deploy); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion internal/provisioner/objects/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func EnsureObjectDeleted[T client.Object](ctx context.Context, cli client.Client
return err
}

if !labels.Exist(obj, model.OwnerLabels(contour)) {
if !labels.AnyExist(obj, model.OwnerLabels(contour)) {
return nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ func desiredClusterRole(name string, contour *model.Contour) *rbacv1.ClusterRole
// updateClusterRoleIfNeeded updates a ClusterRole resource if current does not match desired,
// using contour to verify the existence of owner labels.
func updateClusterRoleIfNeeded(ctx context.Context, cli client.Client, contour *model.Contour, current, desired *rbacv1.ClusterRole) error {
if labels.Exist(current, model.OwnerLabels(contour)) {
if labels.AnyExist(current, model.OwnerLabels(contour)) {
cr, updated := equality.ClusterRoleConfigChanged(current, desired)
if updated {
if err := cli.Update(ctx, cr); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ func TestDesiredClusterRole(t *testing.T) {
cr := desiredClusterRole(name, cntr)
checkClusterRoleName(t, cr, name)
ownerLabels := map[string]string{
model.OwningGatewayNameLabel: cntr.Name,
model.ContourOwningGatewayNameLabel: cntr.Name,
model.GatewayAPIOwningGatewayNameLabel: cntr.Name,
}
checkClusterRoleLabels(t, cr, ownerLabels)
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func desiredClusterRoleBinding(name, roleRef, svcAcctRef string, contour *model.
// updateClusterRoleBindingIfNeeded updates a ClusterRoleBinding resource if current
// does not match desired, using contour to verify the existence of owner labels.
func updateClusterRoleBindingIfNeeded(ctx context.Context, cli client.Client, contour *model.Contour, current, desired *rbacv1.ClusterRoleBinding) error {
if labels.Exist(current, model.OwnerLabels(contour)) {
if labels.AnyExist(current, model.OwnerLabels(contour)) {
crb, updated := equality.ClusterRoleBindingConfigChanged(current, desired)
if updated {
if err := cli.Update(ctx, crb); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ func TestDesiredClusterRoleBinding(t *testing.T) {
crb := desiredClusterRoleBinding(name, testRoleRef, testSvcAcct, cntr)
checkClusterRoleBindingName(t, crb, name)
ownerLabels := map[string]string{
model.OwningGatewayNameLabel: cntr.Name,
model.ContourOwningGatewayNameLabel: cntr.Name,
model.GatewayAPIOwningGatewayNameLabel: cntr.Name,
}
checkClusterRoleBindingLabels(t, crb, ownerLabels)
checkClusterRoleBindingSvcAcct(t, crb, testSvcAcct, cntr.Namespace)
Expand Down
2 changes: 1 addition & 1 deletion internal/provisioner/objects/rbac/role/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func desiredControllerRole(name string, contour *model.Contour) *rbacv1.Role {
// updateRoleIfNeeded updates a Role resource if current does not match desired,
// using contour to verify the existence of owner labels.
func updateRoleIfNeeded(ctx context.Context, cli client.Client, contour *model.Contour, current, desired *rbacv1.Role) (*rbacv1.Role, error) {
if labels.Exist(current, model.OwnerLabels(contour)) {
if labels.AnyExist(current, model.OwnerLabels(contour)) {
role, updated := equality.RoleConfigChanged(current, desired)
if updated {
if err := cli.Update(ctx, role); err != nil {
Expand Down
3 changes: 2 additions & 1 deletion internal/provisioner/objects/rbac/role/role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ func TestDesiredControllerRole(t *testing.T) {
role := desiredControllerRole(name, cntr)
checkRoleName(t, role, name)
ownerLabels := map[string]string{
model.OwningGatewayNameLabel: cntr.Name,
model.ContourOwningGatewayNameLabel: cntr.Name,
model.GatewayAPIOwningGatewayNameLabel: cntr.Name,
}
checkRoleLabels(t, role, ownerLabels)
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func desiredRoleBinding(name, svcAcctRef, roleRef string, contour *model.Contour
// updateRoleBindingIfNeeded updates a RoleBinding resource if current does
// not match desired.
func updateRoleBindingIfNeeded(ctx context.Context, cli client.Client, contour *model.Contour, current, desired *rbacv1.RoleBinding) error {
if labels.Exist(current, model.OwnerLabels(contour)) {
if labels.AnyExist(current, model.OwnerLabels(contour)) {
rb, updated := equality.RoleBindingConfigChanged(current, desired)
if updated {
if err := cli.Update(ctx, rb); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ func TestDesiredRoleBinding(t *testing.T) {
rb := desiredRoleBinding(rbName, svcAcct, roleRef, cntr)
checkRoleBindingName(t, rb, rbName)
ownerLabels := map[string]string{
model.OwningGatewayNameLabel: cntr.Name,
model.ContourOwningGatewayNameLabel: cntr.Name,
model.GatewayAPIOwningGatewayNameLabel: cntr.Name,
}
checkRoleBindingLabels(t, rb, ownerLabels)
checkRoleBindingSvcAcct(t, rb, svcAcct, cntr.Namespace)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func desiredServiceAccount(name string, contour *model.Contour) *corev1.ServiceA
// updateSvcAcctIfNeeded updates a ServiceAccount resource if current does not match desired,
// using contour to verify the existence of owner labels.
func updateSvcAcctIfNeeded(ctx context.Context, cli client.Client, contour *model.Contour, current, desired *corev1.ServiceAccount) (*corev1.ServiceAccount, error) {
if labels.Exist(current, model.OwnerLabels(contour)) {
if labels.AnyExist(current, model.OwnerLabels(contour)) {
sa, updated := utilequality.ServiceAccountConfigChanged(current, desired)
if updated {
if err := cli.Update(ctx, sa); err != nil {
Expand Down
4 changes: 2 additions & 2 deletions internal/provisioner/objects/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ func DesiredEnvoyService(contour *model.Contour) *corev1.Service {

// updateContourServiceIfNeeded updates a Contour Service if current does not match desired.
func updateContourServiceIfNeeded(ctx context.Context, cli client.Client, contour *model.Contour, current, desired *corev1.Service) error {
if !labels.Exist(current, model.OwnerLabels(contour)) {
if !labels.AnyExist(current, model.OwnerLabels(contour)) {
return nil
}
_, updated := equality.ClusterIPServiceChanged(current, desired)
Expand All @@ -323,7 +323,7 @@ func updateContourServiceIfNeeded(ctx context.Context, cli client.Client, contou
// updateEnvoyServiceIfNeeded updates an Envoy Service if current does not match desired,
// using contour to verify the existence of owner labels.
func updateEnvoyServiceIfNeeded(ctx context.Context, cli client.Client, contour *model.Contour, current, desired *corev1.Service) error {
if !labels.Exist(current, model.OwnerLabels(contour)) {
if !labels.AnyExist(current, model.OwnerLabels(contour)) {
return nil
}

Expand Down

0 comments on commit eece587

Please sign in to comment.