Skip to content

Commit e2fec25

Browse files
Add relations package to serve as a central place of finding relations between resources
1 parent 1475659 commit e2fec25

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

gwctl/pkg/relations/relations.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
Copyright 2024 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package relations provides functions for navigating relationships between
18+
// Gateway API resources.
19+
package relations
20+
21+
import (
22+
gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
23+
24+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25+
types "k8s.io/apimachinery/pkg/types"
26+
)
27+
28+
// ObjRef defines a reference to a Kubernetes resource, using plain strings for
29+
// easier comparison.
30+
type ObjRef struct {
31+
Group string `json:",omitempty"`
32+
Kind string `json:",omitempty"`
33+
Name string `json:",omitempty"`
34+
Namespace string `json:",omitempty"`
35+
}
36+
37+
// FindGatewayRefsForHTTPRoute returns Gateways which the HTTPRoute is attached
38+
// to.
39+
func FindGatewayRefsForHTTPRoute(httpRoute gatewayv1.HTTPRoute) []types.NamespacedName {
40+
result := []types.NamespacedName{}
41+
for _, gatewayRef := range httpRoute.Spec.ParentRefs {
42+
namespace := httpRoute.GetNamespace()
43+
if namespace == "" {
44+
namespace = metav1.NamespaceDefault
45+
}
46+
if gatewayRef.Namespace != nil {
47+
namespace = string(*gatewayRef.Namespace)
48+
}
49+
50+
result = append(result, types.NamespacedName{
51+
Namespace: namespace,
52+
Name: string(gatewayRef.Name),
53+
})
54+
}
55+
return result
56+
}
57+
58+
// FindGatewayClassNameForGateway returns GatewayClass for the Gateway.
59+
func FindGatewayClassNameForGateway(gateway gatewayv1.Gateway) string {
60+
return string(gateway.Spec.GatewayClassName)
61+
}
62+
63+
// FindBackendRefsForHTTPRoute returns Backends which the HTTPRoute references.
64+
func FindBackendRefsForHTTPRoute(httpRoute gatewayv1.HTTPRoute) []ObjRef {
65+
// Aggregate all BackendRefs
66+
var backendRefs []gatewayv1.BackendObjectReference
67+
for _, rule := range httpRoute.Spec.Rules {
68+
for _, backendRef := range rule.BackendRefs {
69+
backendRefs = append(backendRefs, backendRef.BackendObjectReference)
70+
}
71+
for _, filter := range rule.Filters {
72+
if filter.Type != gatewayv1.HTTPRouteFilterRequestMirror {
73+
continue
74+
}
75+
if filter.RequestMirror == nil {
76+
continue
77+
}
78+
backendRefs = append(backendRefs, filter.RequestMirror.BackendRef)
79+
}
80+
}
81+
82+
// Convert each BackendRef to ObjRef. ObjRef does not use pointers and thus is
83+
// easily comparable.
84+
resultSet := make(map[ObjRef]bool)
85+
for _, backendRef := range backendRefs {
86+
objRef := ObjRef{
87+
Name: string(backendRef.Name),
88+
// Assume namespace is unspecified in the backendRef and check later to
89+
// override the default value.
90+
Namespace: httpRoute.GetNamespace(),
91+
}
92+
if backendRef.Group != nil {
93+
objRef.Group = string(*backendRef.Group)
94+
}
95+
if backendRef.Kind != nil {
96+
objRef.Kind = string(*backendRef.Kind)
97+
}
98+
if backendRef.Namespace != nil {
99+
objRef.Namespace = string(*backendRef.Namespace)
100+
}
101+
resultSet[objRef] = true
102+
}
103+
104+
// Return unique objRefs
105+
var result []ObjRef
106+
for objRef := range resultSet {
107+
result = append(result, objRef)
108+
}
109+
return result
110+
}

0 commit comments

Comments
 (0)