Skip to content

Commit

Permalink
Add conformance tests for in-cluster Gateway infrastructure (kubernet…
Browse files Browse the repository at this point in the history
…es-sigs#3192)

* Add conformance tests for in-cluster Gateway infrastructure

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Fix lint and type errors

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* gofmt

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Check services as well

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Promote GEP to standard

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Add boilerplate

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Fix args

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

* Rewrite logic to check for metadata propagation for each matching resource

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>

---------

Signed-off-by: Keith Mattix II <keithmattix@microsoft.com>
  • Loading branch information
keithmattix authored and xtineskim committed Aug 8, 2024
1 parent 1b2a59d commit 6330904
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 2 deletions.
119 changes: 119 additions & 0 deletions conformance/tests/gateway-infrastructure.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
Copyright 2024 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package tests

import (
"context"
"testing"

"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"

v1 "sigs.k8s.io/gateway-api/apis/v1"
"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
"sigs.k8s.io/gateway-api/conformance/utils/suite"
"sigs.k8s.io/gateway-api/pkg/features"
)

func init() {
ConformanceTests = append(ConformanceTests, GatewayInfrastructure)
}

var GatewayInfrastructure = suite.ConformanceTest{
ShortName: "GatewayInfrastructure",
Description: "Propagation of metadata from Gateway infrastructure to generated components",
Features: []features.SupportedFeature{
features.SupportGateway,
features.SupportGatewayInfrastructurePropagation,
},
Manifests: []string{
"tests/gateway-infrastructure.yaml",
},
Test: func(t *testing.T, s *suite.ConformanceTestSuite) {
ns := "gateway-conformance-infra"

kubernetes.NamespacesMustBeReady(t, s.Client, s.TimeoutConfig, []string{ns})

gwNN := types.NamespacedName{
Name: "gateway-with-infrastructure-metadata",
Namespace: "gateway-conformance-infra",
}
ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.DefaultTestTimeout)
defer cancel()

t.Logf("waiting for namespace %s and Gateway %s to be ready for testing", gwNN.Namespace, gwNN.Name)
kubernetes.GatewayMustHaveLatestConditions(t, s.Client, s.TimeoutConfig, gwNN)

t.Logf("retrieving Gateway %s/%s", gwNN.Namespace, gwNN.Name)
currentGW := &v1.Gateway{}
err := s.Client.Get(ctx, gwNN, currentGW)
require.NoError(t, err, "error getting Gateway: %v", err)
t.Logf("verifying that the Gateway %s/%s is accepted with infrastructure declared", gwNN.Namespace, gwNN.Name)
kubernetes.GatewayMustHaveCondition(t, s.Client, s.TimeoutConfig, gwNN, metav1.Condition{
Type: string(v1.GatewayConditionAccepted),
Status: metav1.ConditionTrue,
})

t.Logf("verifying that generated resources for Gateway %s/%s have the proper gateway name label", gwNN.Namespace, gwNN.Name)
// Don't check services because implementations may have special filtering logic (e.g. for LB annotations)
// Instead, check service accounts for the gateway-name label first and then
// fallback to Pod if that fails
annotations := make(map[string]string, len(currentGW.Spec.Infrastructure.Annotations))
labels := make(map[string]string, len(currentGW.Spec.Infrastructure.Labels))
// Need to translate from (Annotation|Label)Key to string
for k, v := range currentGW.Spec.Infrastructure.Annotations {
annotations[string(k)] = string(v)
}

for k, v := range currentGW.Spec.Infrastructure.Labels {
labels[string(k)] = string(v)
}
var foundResource bool
saList := corev1.ServiceAccountList{}
podList := corev1.PodList{}
serviceList := corev1.ServiceList{}
err = s.Client.List(ctx, &saList, client.MatchingLabels{"gateway.networking.k8s.io/gateway-name": gwNN.Name}, client.InNamespace(ns))
require.NoError(t, err, "error listing ServiceAccounts")
err = s.Client.List(ctx, &podList, client.MatchingLabels{"gateway.networking.k8s.io/gateway-name": gwNN.Name}, client.InNamespace(ns))
require.NoError(t, err, "error listing Pods")
err = s.Client.List(ctx, &serviceList, client.MatchingLabels{"gateway.networking.k8s.io/gateway-name": gwNN.Name}, client.InNamespace(ns))
require.NoError(t, err, "error listing Services")
if len(saList.Items) > 0 {
foundResource = true
sa := saList.Items[0]
require.Subsetf(t, sa.Labels, labels, "expected Pod label set %v to contain all Gateway infrastructure labels %v", sa.Labels, labels)
require.Subsetf(t, sa.Annotations, annotations, "expected Pod annotation set %v to contain all Gateway infrastructure annotations %v", sa.Annotations, annotations)
}
if len(podList.Items) > 0 {
foundResource = true
pod := podList.Items[0]
require.Subsetf(t, pod.Labels, labels, "expected Pod label set %v to contain all Gateway infrastructure labels %v", pod.Labels, labels)
require.Subsetf(t, pod.Annotations, annotations, "expected Pod annotation set %v to contain all Gateway infrastructure annotations %v", pod.Annotations, annotations)
}
if len(serviceList.Items) > 0 {
foundResource = true
service := serviceList.Items[0]
require.Subsetf(t, service.Labels, labels, "expected Pod label set %v to contain all Gateway infrastructure labels %v", service.Labels, labels)
require.Subsetf(t, service.Annotations, annotations, "expected Pod annotation set %v to contain all Gateway infrastructure annotations %v", service.Annotations, annotations)
}

require.True(t, foundResource, "expected to find a ServiceAccount, Pod, or Service with the gateway-name label")
},
}
17 changes: 17 additions & 0 deletions conformance/tests/gateway-infrastructure.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: gateway-with-infrastructure-metadata
namespace: gateway-conformance-infra
spec:
gatewayClassName: "{GATEWAY_CLASS_NAME}"
infrastructure:
annotations:
key1: value1
labels:
key2: value2
listeners:
- name: http
port: 8080
protocol: HTTP
2 changes: 1 addition & 1 deletion geps/gep-1867/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# GEP-1867: Per-Gateway Infrastructure

* Status: Experimental
* Status: Standard
* Issue: [#1867](https://github.com/kubernetes-sigs/gateway-api/issues/1867)

## Overview
Expand Down
2 changes: 1 addition & 1 deletion geps/gep-1867/metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: internal.gateway.networking.k8s.io/v1alpha1
kind: GEPDetails
number: 1867
name: Per-Gateway Infrastructure
status: Experimental
status: Standard
authors:
- howardjohn
relationships:
Expand Down
5 changes: 5 additions & 0 deletions pkg/features/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ const (
// SupportGatewayHTTPListenerIsolation option indicates support for the isolation
// of HTTP listeners.
SupportGatewayHTTPListenerIsolation SupportedFeature = "GatewayHTTPListenerIsolation"

// SupportGatewayInfrastructureAnnotations option indicates support for
// spec.infrastructure.annotations and spec.infrastrucutre.labels
SupportGatewayInfrastructurePropagation SupportedFeature = "GatewayInfrastructurePropagation"
)

// GatewayExtendedFeatures are extra generic features that implementations may
Expand All @@ -66,6 +70,7 @@ var GatewayExtendedFeatures = sets.New(
SupportGatewayPort8080,
SupportGatewayStaticAddresses,
SupportGatewayHTTPListenerIsolation,
SupportGatewayInfrastructurePropagation,
)

// -----------------------------------------------------------------------------
Expand Down

0 comments on commit 6330904

Please sign in to comment.