From c37ccaeafdab51a2dd70753a590717cf3202cf1f Mon Sep 17 00:00:00 2001 From: Hamzah Qudsi Date: Tue, 17 Jan 2023 12:42:05 -0500 Subject: [PATCH 1/4] bugfix: remove stale listener condition Signed-off-by: Hamzah Qudsi --- internal/gatewayapi/contexts.go | 17 ++++ internal/gatewayapi/contexts_test.go | 93 ++++++++++++++++++ ...-with-preexisting-status-condition.in.yaml | 55 +++++++++++ ...with-preexisting-status-condition.out.yaml | 87 +++++++++++++++++ ...ateway-with-stale-status-condition.in.yaml | 69 ++++++++++++++ ...teway-with-stale-status-condition.out.yaml | 94 +++++++++++++++++++ internal/gatewayapi/translator.go | 11 +-- 7 files changed, 418 insertions(+), 8 deletions(-) create mode 100644 internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.in.yaml create mode 100644 internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.out.yaml create mode 100644 internal/gatewayapi/testdata/gateway-with-stale-status-condition.in.yaml create mode 100644 internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml diff --git a/internal/gatewayapi/contexts.go b/internal/gatewayapi/contexts.go index 835e394386..ff00c7c7bc 100644 --- a/internal/gatewayapi/contexts.go +++ b/internal/gatewayapi/contexts.go @@ -74,6 +74,23 @@ func (g *GatewayContext) GetListenerContext(listenerName v1beta1.SectionName) *L return ctx } +// ResetListeners resets the listener statuses and re-generates the GatewayContext +// ListenerContexts from the Gateway spec. +func (g *GatewayContext) ResetListeners() { + numListeners := len(g.Spec.Listeners) + g.Status.Listeners = make([]v1beta1.ListenerStatus, numListeners) + g.listeners = make([]*ListenerContext, numListeners) + for i := range g.Spec.Listeners { + listener := &g.Spec.Listeners[i] + g.Status.Listeners[i] = v1beta1.ListenerStatus{Name: listener.Name} + g.listeners[i] = &ListenerContext{ + Listener: listener, + gateway: g.Gateway, + listenerStatusIdx: i, + } + } +} + // ListenerContext wraps a Listener and provides helper methods for // setting conditions and other status information on the associated // Gateway, etc. diff --git a/internal/gatewayapi/contexts_test.go b/internal/gatewayapi/contexts_test.go index 7aa9d8bb91..e5d9a2675a 100644 --- a/internal/gatewayapi/contexts_test.go +++ b/internal/gatewayapi/contexts_test.go @@ -54,3 +54,96 @@ func TestContexts(t *testing.T) { lctx.ResetConditions() require.Len(t, gateway.Status.Listeners[0].Conditions, 0) } + +func TestContextsResetListeners(t *testing.T) { + gateway := &v1beta1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "envoy-gateway", + Name: "gateway-1", + }, + Spec: v1beta1.GatewaySpec{ + Listeners: []v1beta1.Listener{ + { + Name: "https", + }, + { + Name: "http", + }, + }, + }, + Status: v1beta1.GatewayStatus{ + Listeners: []v1beta1.ListenerStatus{ + { + Name: "https", + Conditions: []metav1.Condition{ + { + Status: metav1.ConditionStatus(v1beta1.ListenerConditionProgrammed), + }, + }, + }, + { + Name: "http", + Conditions: []metav1.Condition{ + { + Status: metav1.ConditionStatus(v1beta1.ListenerConditionProgrammed), + }, + }, + }, + }, + }, + } + + gCtx := &GatewayContext{Gateway: gateway} + + httpsListenerCtx := &ListenerContext{ + Listener: &v1beta1.Listener{ + Name: "https", + }, + gateway: gateway, + listenerStatusIdx: 0, + } + + httpListenerCtx := &ListenerContext{ + Listener: &v1beta1.Listener{ + Name: "http", + }, + gateway: gateway, + listenerStatusIdx: 1, + } + + gCtx.ResetListeners() + + require.EqualValues(t, 2, len(gCtx.listeners)) + + expectedListenerContexts := []*ListenerContext{ + httpsListenerCtx, + httpListenerCtx, + } + require.EqualValues(t, expectedListenerContexts, gCtx.listeners) + + require.EqualValues(t, 2, len(gCtx.Status.Listeners)) + + expectedListenerStatuses := []v1beta1.ListenerStatus{ + { + Name: "https", + }, + { + Name: "http", + }, + } + require.EqualValues(t, expectedListenerStatuses, gCtx.Status.Listeners) + + // Remove one of the listeners + gateway.Spec.Listeners = gateway.Spec.Listeners[:1] + + gCtx.ResetListeners() + + // Ensure the listener status has been updated and the stale listener has been + // removed. + expectedListenerStatus := []v1beta1.ListenerStatus{{Name: "https"}} + require.EqualValues(t, expectedListenerStatus, gCtx.Gateway.Status.Listeners) + + // Ensure that the listeners within GatewayContext have been properly updated. + expectedGCtxListeners := []*ListenerContext{httpsListenerCtx} + require.EqualValues(t, expectedGCtxListeners, gCtx.listeners) +} diff --git a/internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.in.yaml b/internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.in.yaml new file mode 100644 index 0000000000..c45b30d856 --- /dev/null +++ b/internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.in.yaml @@ -0,0 +1,55 @@ +gateways: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + namespace: default + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: Same + status: + listeners: + - name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + attachedRoutes: 1 + conditions: + - type: Programmed + status: "True" + reason: Programmed + message: Listener is ready +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + parentRefs: + - namespace: default + name: gateway-1 + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 + status: + parents: + - parentRef: + namespace: default + name: gateway-1 + controllerName: gateway.envoyproxy.io/gatewayclass-controller + conditions: + - type: Accepted + status: "True" + reason: Accepted + message: Route is accepted diff --git a/internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.out.yaml b/internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.out.yaml new file mode 100644 index 0000000000..e42768b310 --- /dev/null +++ b/internal/gatewayapi/testdata/gateway-with-preexisting-status-condition.out.yaml @@ -0,0 +1,87 @@ +gateways: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + namespace: default + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: Same + status: + listeners: + - name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + attachedRoutes: 1 + conditions: + - type: Programmed + status: "True" + reason: Programmed + message: Listener is ready +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + parentRefs: + - namespace: default + name: gateway-1 + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 + status: + parents: + - parentRef: + namespace: default + name: gateway-1 + controllerName: gateway.envoyproxy.io/gatewayclass-controller + conditions: + - type: Accepted + status: "True" + reason: Accepted + message: Route is accepted +xdsIR: + default-gateway-1: + http: + - name: default-gateway-1-http + address: 0.0.0.0 + port: 10080 + hostnames: + - "*" + routes: + - name: default-httproute-1-rule-0-match-0-* + pathMatch: + prefix: "/" + destinations: + - host: 7.7.7.7 + port: 8080 + weight: 1 +infraIR: + default-gateway-1: + proxy: + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-namespace: default + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + name: default-gateway-1 + image: envoyproxy/envoy:translator-tests + listeners: + - address: "" + ports: + - name: http + protocol: "HTTP" + servicePort: 80 + containerPort: 10080 diff --git a/internal/gatewayapi/testdata/gateway-with-stale-status-condition.in.yaml b/internal/gatewayapi/testdata/gateway-with-stale-status-condition.in.yaml new file mode 100644 index 0000000000..6555be006a --- /dev/null +++ b/internal/gatewayapi/testdata/gateway-with-stale-status-condition.in.yaml @@ -0,0 +1,69 @@ +gateways: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + namespace: default + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: https + protocol: HTTPS + port: 443 + allowedRoutes: + namespaces: + from: Same + tls: + mode: Terminate + certificateRefs: + - name: tls-secret-1 + status: + listeners: + - name: https + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + attachedRoutes: 1 + conditions: + - type: Programmed + status: "True" + reason: Programmed + message: Listener is ready + - name: http + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + attachedRoutes: 1 + conditions: + - type: Programmed + status: "True" + reason: Programmed + message: Listener is ready +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + parentRefs: + - name: gateway-1 + namespace: default + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 +secrets: + - apiVersion: v1 + kind: Secret + metadata: + namespace: default + name: tls-secret-1 + type: kubernetes.io/tls + data: + tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNxRENDQVpBQ0NRREVNZ1lZblFyQ29EQU5CZ2txaGtpRzl3MEJBUXNGQURBV01SUXdFZ1lEVlFRRERBdG0KYjI4dVltRnlMbU52YlRBZUZ3MHlNekF4TURVeE16UXpNalJhRncweU5EQXhNRFV4TXpRek1qUmFNQll4RkRBUwpCZ05WQkFNTUMyWnZieTVpWVhJdVkyOXRNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDCkFRRUFuZEh6d21wS2NUSUViamhGZ2RXd1RSTjc1Y3A4b3VsWnhMMUdydlI2SXc3ejdqaTBSNFcvTm85bkdmOU0KWVAyQ1JqaXN6NTFtd3hTeGVCcm9jTGVBK21reGkxK2lEdk5kQytyU0x4MTN6RUxTQ25xYnVzUHM3bUdmSlpxOAo5TGhlbmx5bzQzaDVjYTZINUxqTXd1L1JHVWlGMzFYck5yaVlGQlB2RTJyQitkd24vTkVrUTRoOFJxcXlwcmtuCkYvcWM5Sk1ZQVlGRld1VkNwa0lFbmRYMUN5dlFOT2FkZmN2cmd6dDV2SmwwT2kxQWdyaU5hWGJFUEdudWY3STQKcXBCSEdVWE5lMVdsOVdlVklxS1g0T2FFWERWQzZGQzdHOHptZWVMVzFBa1lFVm5pcFg2b1NCK0JjL1NIVlZOaApzQkxSbXRuc3pmTnRUMlFyZCttcGt4ODBaUUlEQVFBQk1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ1VKOElDCkJveUVqT3V3enBHYVJoR044QjRqT1B6aHVDT0V0ZDM3UzAybHUwN09IenlCdmJzVEd6S3dCZ0x5bVdmR2tINEIKajdDTHNwOEZ6TkhLWnVhQmdwblo5SjZETE9Od2ZXZTJBWXA3TGRmT0tWQlVkTVhRaU9tN2pKOUhob0Ntdk1ONwpic2pjaFdKb013ckZmK3dkQUthdHowcUFQeWhMeWUvRnFtaVZ4a09SWmF3K1Q5bURaK0g0OXVBU2d1SnVOTXlRClY2RXlYNmd0Z1dxMzc2SHZhWE1TLzNoYW1Zb1ZXWEk1TXhpUE9ZeG5BQmtKQjRTQ2dJUmVqYkpmVmFRdG9RNGEKejAyaVVMZW5ESUllUU9Zb2JLY01CWGYxQjRQQVFtc2VocVZJYnpzUUNHaTU0VkRyczZiWmQvN0pzMXpDcHBncwpKaUQ1SXFNaktXRHdxN2FLCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K + diff --git a/internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml b/internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml new file mode 100644 index 0000000000..9af65bf89f --- /dev/null +++ b/internal/gatewayapi/testdata/gateway-with-stale-status-condition.out.yaml @@ -0,0 +1,94 @@ +gateways: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + metadata: + namespace: default + name: gateway-1 + spec: + gatewayClassName: envoy-gateway-class + listeners: + - name: https + protocol: HTTPS + port: 443 + allowedRoutes: + namespaces: + from: Same + tls: + mode: Terminate + certificateRefs: + - name: tls-secret-1 + status: + listeners: + - name: https + supportedKinds: + - group: gateway.networking.k8s.io + kind: HTTPRoute + attachedRoutes: 1 + conditions: + - type: Programmed + status: "True" + reason: Programmed + message: Listener is ready +httpRoutes: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: HTTPRoute + metadata: + namespace: default + name: httproute-1 + spec: + parentRefs: + - name: gateway-1 + namespace: default + rules: + - matches: + - path: + value: "/" + backendRefs: + - name: service-1 + port: 8080 + status: + parents: + - parentRef: + namespace: default + name: gateway-1 + controllerName: gateway.envoyproxy.io/gatewayclass-controller + conditions: + - type: Accepted + status: "True" + reason: Accepted + message: Route is accepted +xdsIR: + default-gateway-1: + http: + - name: default-gateway-1-https + address: 0.0.0.0 + port: 10443 + hostnames: + - "*" + tls: + serverCertificate: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNxRENDQVpBQ0NRREVNZ1lZblFyQ29EQU5CZ2txaGtpRzl3MEJBUXNGQURBV01SUXdFZ1lEVlFRRERBdG0KYjI4dVltRnlMbU52YlRBZUZ3MHlNekF4TURVeE16UXpNalJhRncweU5EQXhNRFV4TXpRek1qUmFNQll4RkRBUwpCZ05WQkFNTUMyWnZieTVpWVhJdVkyOXRNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDCkFRRUFuZEh6d21wS2NUSUViamhGZ2RXd1RSTjc1Y3A4b3VsWnhMMUdydlI2SXc3ejdqaTBSNFcvTm85bkdmOU0KWVAyQ1JqaXN6NTFtd3hTeGVCcm9jTGVBK21reGkxK2lEdk5kQytyU0x4MTN6RUxTQ25xYnVzUHM3bUdmSlpxOAo5TGhlbmx5bzQzaDVjYTZINUxqTXd1L1JHVWlGMzFYck5yaVlGQlB2RTJyQitkd24vTkVrUTRoOFJxcXlwcmtuCkYvcWM5Sk1ZQVlGRld1VkNwa0lFbmRYMUN5dlFOT2FkZmN2cmd6dDV2SmwwT2kxQWdyaU5hWGJFUEdudWY3STQKcXBCSEdVWE5lMVdsOVdlVklxS1g0T2FFWERWQzZGQzdHOHptZWVMVzFBa1lFVm5pcFg2b1NCK0JjL1NIVlZOaApzQkxSbXRuc3pmTnRUMlFyZCttcGt4ODBaUUlEQVFBQk1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ1VKOElDCkJveUVqT3V3enBHYVJoR044QjRqT1B6aHVDT0V0ZDM3UzAybHUwN09IenlCdmJzVEd6S3dCZ0x5bVdmR2tINEIKajdDTHNwOEZ6TkhLWnVhQmdwblo5SjZETE9Od2ZXZTJBWXA3TGRmT0tWQlVkTVhRaU9tN2pKOUhob0Ntdk1ONwpic2pjaFdKb013ckZmK3dkQUthdHowcUFQeWhMeWUvRnFtaVZ4a09SWmF3K1Q5bURaK0g0OXVBU2d1SnVOTXlRClY2RXlYNmd0Z1dxMzc2SHZhWE1TLzNoYW1Zb1ZXWEk1TXhpUE9ZeG5BQmtKQjRTQ2dJUmVqYkpmVmFRdG9RNGEKejAyaVVMZW5ESUllUU9Zb2JLY01CWGYxQjRQQVFtc2VocVZJYnpzUUNHaTU0VkRyczZiWmQvN0pzMXpDcHBncwpKaUQ1SXFNaktXRHdxN2FLCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K + privateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2UUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktjd2dnU2pBZ0VBQW9JQkFRQ2QwZlBDYWtweE1nUnUKT0VXQjFiQk5FM3ZseW55aTZWbkV2VWF1OUhvakR2UHVPTFJIaGI4MmoyY1ovMHhnL1lKR09LelBuV2JERkxGNApHdWh3dDRENmFUR0xYNklPODEwTDZ0SXZIWGZNUXRJS2VwdTZ3K3p1WVo4bG1yejB1RjZlWEtqamVIbHhyb2ZrCnVNekM3OUVaU0lYZlZlczJ1SmdVRSs4VGFzSDUzQ2Y4MFNSRGlIeEdxckttdVNjWCtwejBreGdCZ1VWYTVVS20KUWdTZDFmVUxLOUEwNXAxOXkrdURPM204bVhRNkxVQ0N1STFwZHNROGFlNS9zamlxa0VjWlJjMTdWYVgxWjVVaQpvcGZnNW9SY05VTG9VTHNiek9aNTR0YlVDUmdSV2VLbGZxaElINEZ6OUlkVlUyR3dFdEdhMmV6TjgyMVBaQ3QzCjZhbVRIelJsQWdNQkFBRUNnZ0VBWTFGTUlLNDVXTkVNUHJ6RTZUY3NNdVV2RkdhQVZ4bVk5NW5SMEtwajdvb3IKY21CVys2ZXN0TTQ4S1AwaitPbXd3VFpMY29Cd3VoWGN0V1Bob1lXcDhteWUxRUlEdjNyaHRHMDdocEQ1NGg2dgpCZzh3ejdFYStzMk9sT0N6UnlKNzBSY281YlhjWDNGaGJjdnFlRWJwaFFyQnpOSEtLMjZ4cmZqNWZIT3p6T1FGCmJHdUZ3SDVic3JGdFhlajJXM3c4eW90N0ZQSDV3S3RpdnhvSWU5RjMyOXNnOU9EQnZqWnpiaG1LVTArckFTK1kKRGVield2bFJyaEUrbXVmQTN6M0N0QXhDOFJpNzNscFNoTDRQQWlvcG1SUXlxZXRXMjYzOFFxcnM0R3hnNzhwbApJUXJXTmNBc2s3Slg5d3RZenV6UFBXSXRWTTFscFJiQVRhNTJqdFl2NVFLQmdRRE5tMTFtZTRYam1ZSFV2cStZCmFTUzdwK2UybXZEMHVaOU9JeFluQnBWMGkrckNlYnFFMkE1Rm5hcDQ5Yld4QTgwUElldlVkeUpCL2pUUkoxcVMKRUpXQkpMWm1LVkg2K1QwdWw1ZUtOcWxFTFZHU0dCSXNpeE9SUXpDZHBoMkx0UmtBMHVjSVUzY3hiUmVMZkZCRQpiSkdZWENCdlNGcWd0VDlvZTFldVpMVmFOd0tCZ1FERWdENzJENk81eGIweEQ1NDQ1M0RPMUJhZmd6aThCWDRTCk1SaVd2LzFUQ0w5N05sRWtoeXovNmtQd1owbXJRcE5CMzZFdkpKZFVteHdkU2MyWDhrOGcxMC85NVlLQkdWQWoKL3d0YVZYbE9WeEFvK0ZSelpZeFpyQ29uWWFSMHVwUzFybDRtenN4REhlZU9mUVZUTUgwUjdZN0pnbTA5dXQ4SwplanAvSXZBb1F3S0JnQjNaRWlRUWhvMVYrWjBTMlpiOG5KS0plMy9zMmxJTXFHM0ZkaS9RS3Q0eWViQWx6OGY5ClBZVXBzRmZEQTg5Z3grSU1nSm5sZVptdTk2ZnRXSjZmdmJSenllN216TG5zZU05TXZua1lHbGFGWmJRWnZubXMKN3ZoRmtzY3dHRlh4d21GMlBJZmU1Z3pNMDRBeVdjeTFIaVhLS2dNOXM3cGsxWUdyZGowZzdacmRBb0dCQUtLNApDR3MrbkRmMEZTMFJYOWFEWVJrRTdBNy9YUFhtSG5YMkRnU1h5N0Q4NTRPaWdTTWNoUmtPNTErbVNJejNQbllvCk41T1FXM2lHVVl1M1YvYmhnc0VSUzM1V2xmRk9BdDBzRUR5bjF5SVdXcDF5dG93d3BUNkVvUXVuZ2NYZjA5RjMKS1NROXowd3M4VmsvRWkvSFVXcU5LOWFXbU51cmFaT0ZqL2REK1ZkOUFvR0FMWFN3dEE3K043RDRkN0VEMURSRQpHTWdZNVd3OHFvdDZSdUNlNkpUY0FnU3B1MkhNU3JVY2dXclpiQnJZb09FUnVNQjFoMVJydk5ybU1qQlM0VW9FClgyZC8vbGhpOG1wL2VESWN3UDNRa2puanBJRFJWMFN1eWxrUkVaZURKZjVZb3R6eDdFdkJhbzFIbkQrWEg4eUIKVUtmWGJTaHZKVUdhRmgxT3Q1Y3JoM1k9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K + routes: + - name: default-httproute-1-rule-0-match-0-* + pathMatch: + prefix: "/" + destinations: + - host: 7.7.7.7 + port: 8080 + weight: 1 +infraIR: + default-gateway-1: + proxy: + metadata: + labels: + gateway.envoyproxy.io/owning-gateway-namespace: default + gateway.envoyproxy.io/owning-gateway-name: gateway-1 + name: default-gateway-1 + image: envoyproxy/envoy:translator-tests + listeners: + - address: "" + ports: + - name: https + protocol: "HTTPS" + servicePort: 443 + containerPort: 10443 diff --git a/internal/gatewayapi/translator.go b/internal/gatewayapi/translator.go index 71a9b3aa84..8e491ea960 100644 --- a/internal/gatewayapi/translator.go +++ b/internal/gatewayapi/translator.go @@ -124,6 +124,8 @@ func (t *Translator) Translate(resources *Resources) *TranslateResult { return newTranslateResult(gateways, httpRoutes, tlsRoutes, tcpRoutes, udpRoutes, xdsIR, infraIR) } +// GetRelevantGateways returns GatewayContexts, containing a copy of the original +// Gateway with the Listener statuses reset. func (t *Translator) GetRelevantGateways(gateways []*v1beta1.Gateway) []*GatewayContext { var relevant []*GatewayContext @@ -136,14 +138,7 @@ func (t *Translator) GetRelevantGateways(gateways []*v1beta1.Gateway) []*Gateway gc := &GatewayContext{ Gateway: gateway.DeepCopy(), } - - for _, listener := range gateway.Spec.Listeners { - l := gc.GetListenerContext(listener.Name) - // Reset conditions and attached route count - // since it will be recomputed during translation. - l.ResetConditions() - l.ResetAttachedRoutes() - } + gc.ResetListeners() relevant = append(relevant, gc) } From e945405b17e91bb606caf1b03d8475a80dc2099e Mon Sep 17 00:00:00 2001 From: Hamzah Qudsi Date: Tue, 17 Jan 2023 12:53:30 -0500 Subject: [PATCH 2/4] lint Signed-off-by: Hamzah Qudsi --- internal/gatewayapi/contexts_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/gatewayapi/contexts_test.go b/internal/gatewayapi/contexts_test.go index e5d9a2675a..4350495d03 100644 --- a/internal/gatewayapi/contexts_test.go +++ b/internal/gatewayapi/contexts_test.go @@ -79,7 +79,7 @@ func TestContextsResetListeners(t *testing.T) { { Status: metav1.ConditionStatus(v1beta1.ListenerConditionProgrammed), }, - }, + }, }, { Name: "http", @@ -87,7 +87,7 @@ func TestContextsResetListeners(t *testing.T) { { Status: metav1.ConditionStatus(v1beta1.ListenerConditionProgrammed), }, - }, + }, }, }, }, @@ -99,7 +99,7 @@ func TestContextsResetListeners(t *testing.T) { Listener: &v1beta1.Listener{ Name: "https", }, - gateway: gateway, + gateway: gateway, listenerStatusIdx: 0, } @@ -107,7 +107,7 @@ func TestContextsResetListeners(t *testing.T) { Listener: &v1beta1.Listener{ Name: "http", }, - gateway: gateway, + gateway: gateway, listenerStatusIdx: 1, } From eacad84160940b50caf269858175082c199810f0 Mon Sep 17 00:00:00 2001 From: Hamzah Qudsi Date: Tue, 17 Jan 2023 14:56:05 -0500 Subject: [PATCH 3/4] remove ResetConditions & ResetAttachedRoutes methods Signed-off-by: Hamzah Qudsi --- internal/gatewayapi/contexts.go | 9 --------- internal/gatewayapi/contexts_test.go | 4 ++-- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/internal/gatewayapi/contexts.go b/internal/gatewayapi/contexts.go index ff00c7c7bc..5757ece1d8 100644 --- a/internal/gatewayapi/contexts.go +++ b/internal/gatewayapi/contexts.go @@ -135,19 +135,10 @@ func (l *ListenerContext) SetCondition(conditionType v1beta1.ListenerConditionTy } } -func (l *ListenerContext) ResetConditions() { - l.gateway.Status.Listeners[l.listenerStatusIdx].Conditions = make([]metav1.Condition, 0) -} - func (l *ListenerContext) SetSupportedKinds(kinds ...v1beta1.RouteGroupKind) { l.gateway.Status.Listeners[l.listenerStatusIdx].SupportedKinds = kinds } -func (l *ListenerContext) ResetAttachedRoutes() { - // Reset attached route count since it will be recomputed during translation. - l.gateway.Status.Listeners[l.listenerStatusIdx].AttachedRoutes = 0 -} - func (l *ListenerContext) IncrementAttachedRoutes() { l.gateway.Status.Listeners[l.listenerStatusIdx].AttachedRoutes++ } diff --git a/internal/gatewayapi/contexts_test.go b/internal/gatewayapi/contexts_test.go index 4350495d03..3ac0d2ea1b 100644 --- a/internal/gatewayapi/contexts_test.go +++ b/internal/gatewayapi/contexts_test.go @@ -51,11 +51,11 @@ func TestContexts(t *testing.T) { require.Len(t, gateway.Status.Listeners[0].SupportedKinds, 1) require.EqualValues(t, gateway.Status.Listeners[0].SupportedKinds[0].Kind, "HTTPRoute") - lctx.ResetConditions() + gctx.ResetListeners() require.Len(t, gateway.Status.Listeners[0].Conditions, 0) } -func TestContextsResetListeners(t *testing.T) { +func TestContextsStaleListener(t *testing.T) { gateway := &v1beta1.Gateway{ ObjectMeta: metav1.ObjectMeta{ Namespace: "envoy-gateway", From 5c80804d85ba96ec93c76ddc2333a29468d2f109 Mon Sep 17 00:00:00 2001 From: Hamzah Qudsi Date: Tue, 17 Jan 2023 16:18:33 -0500 Subject: [PATCH 4/4] remove GetListenerContext Signed-off-by: Hamzah Qudsi --- internal/gatewayapi/contexts.go | 47 ---------------------------- internal/gatewayapi/contexts_test.go | 8 +++-- 2 files changed, 5 insertions(+), 50 deletions(-) diff --git a/internal/gatewayapi/contexts.go b/internal/gatewayapi/contexts.go index 5757ece1d8..c97d177ed7 100644 --- a/internal/gatewayapi/contexts.go +++ b/internal/gatewayapi/contexts.go @@ -27,53 +27,6 @@ type GatewayContext struct { listeners []*ListenerContext } -// GetListenerContext returns the ListenerContext with listenerName. -// If the listener exists in the Gateway Spec but NOT yet in the GatewayContext, -// this creates a new ListenerContext for the listener and attaches it to the -// GatewayContext. -func (g *GatewayContext) GetListenerContext(listenerName v1beta1.SectionName) *ListenerContext { - if g.listeners == nil { - g.listeners = make([]*ListenerContext, 0) - } - - for _, l := range g.listeners { - if l.Name == listenerName { - return l - } - } - - var listener *v1beta1.Listener - for i, l := range g.Spec.Listeners { - if l.Name == listenerName { - listener = &g.Spec.Listeners[i] - break - } - } - if listener == nil { - panic("listener not found") - } - - listenerStatusIdx := -1 - for i := range g.Status.Listeners { - if g.Status.Listeners[i].Name == listenerName { - listenerStatusIdx = i - break - } - } - if listenerStatusIdx == -1 { - g.Status.Listeners = append(g.Status.Listeners, v1beta1.ListenerStatus{Name: listenerName}) - listenerStatusIdx = len(g.Status.Listeners) - 1 - } - - ctx := &ListenerContext{ - Listener: listener, - gateway: g.Gateway, - listenerStatusIdx: listenerStatusIdx, - } - g.listeners = append(g.listeners, ctx) - return ctx -} - // ResetListeners resets the listener statuses and re-generates the GatewayContext // ListenerContexts from the Gateway spec. func (g *GatewayContext) ResetListeners() { diff --git a/internal/gatewayapi/contexts_test.go b/internal/gatewayapi/contexts_test.go index 3ac0d2ea1b..3b1867b53d 100644 --- a/internal/gatewayapi/contexts_test.go +++ b/internal/gatewayapi/contexts_test.go @@ -31,8 +31,10 @@ func TestContexts(t *testing.T) { gctx := &GatewayContext{ Gateway: gateway, } + gctx.ResetListeners() + require.Len(t, gctx.listeners, 1) - lctx := gctx.GetListenerContext("http") + lctx := gctx.listeners[0] require.NotNil(t, lctx) lctx.SetCondition(v1beta1.ListenerConditionAccepted, metav1.ConditionFalse, v1beta1.ListenerReasonUnsupportedProtocol, "HTTPS protocol is not supported yet") @@ -113,7 +115,7 @@ func TestContextsStaleListener(t *testing.T) { gCtx.ResetListeners() - require.EqualValues(t, 2, len(gCtx.listeners)) + require.Len(t, gCtx.listeners, 2) expectedListenerContexts := []*ListenerContext{ httpsListenerCtx, @@ -121,7 +123,7 @@ func TestContextsStaleListener(t *testing.T) { } require.EqualValues(t, expectedListenerContexts, gCtx.listeners) - require.EqualValues(t, 2, len(gCtx.Status.Listeners)) + require.Len(t, gCtx.Status.Listeners, 2) expectedListenerStatuses := []v1beta1.ListenerStatus{ {