Skip to content

Commit

Permalink
Update AllowedRoutes compatibility with .Kinds support.
Browse files Browse the repository at this point in the history
  • Loading branch information
zongzw committed Jan 8, 2023
1 parent 3541a1a commit b4bbffb
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 29 deletions.
45 changes: 30 additions & 15 deletions pkg/cache.go
Expand Up @@ -51,6 +51,13 @@ func (c *SIGCache) UnsetNamespace(keyname string) {
delete(c.Namespace, keyname)
}

func (c *SIGCache) GetNamespace(keyname string) *v1.Namespace {
c.mutex.Lock()
defer c.mutex.Unlock()

return c.Namespace[keyname]
}

func (c *SIGCache) SetGatewayClass(obj *gatewayv1beta1.GatewayClass) {
c.mutex.Lock()
defer c.mutex.Unlock()
Expand Down Expand Up @@ -208,7 +215,17 @@ func (c *SIGCache) _gatewayRefsOf(hr *gatewayv1beta1.HTTPRoute) []*gatewayv1beta
}
name := utils.Keyname(utils.Keyname(ns, string(pr.Name)))
if gw, ok := c.Gateway[name]; ok {
gws = append(gws, gw)
for _, listener := range gw.Spec.Listeners {
if listener.Name != *pr.SectionName {
continue
}
routetype := reflect.TypeOf(*hr).Name()
if routeMatches(gw.Namespace, &listener, ActiveSIGs.Namespace[hr.Namespace], routetype) {
gws = append(gws, gw)
break
}
}

}
}
return gws
Expand All @@ -228,13 +245,13 @@ func (c *SIGCache) _attachedHTTPRoutes(gw *gatewayv1beta1.Gateway) []*gatewayv1b
return []*gatewayv1beta1.HTTPRoute{}
}

allowedRoutes := map[string]*gatewayv1beta1.AllowedRoutes{}
for _, listener := range gw.Spec.Listeners {
vsname := gwListenerName(gw, &listener)

if listener.AllowedRoutes != nil {
allowedRoutes[vsname] = listener.AllowedRoutes
}
listeners := map[string]*gatewayv1beta1.Listener{}
// &listener, the local variable, will point to the latest listener
// it can be used but cannot be taken way.
// for _, listener := range gw.Spec.Listeners { wrong!
for i := range gw.Spec.Listeners {
vsname := gwListenerName(gw, &gw.Spec.Listeners[i])
listeners[vsname] = &gw.Spec.Listeners[i]
}

hrs := []*gatewayv1beta1.HTTPRoute{}
Expand All @@ -246,13 +263,11 @@ func (c *SIGCache) _attachedHTTPRoutes(gw *gatewayv1beta1.Gateway) []*gatewayv1b
}
if utils.Keyname(ns, string(pr.Name)) == utils.Keyname(gw.Namespace, gw.Name) {
vsname := hrParentName(hr, &pr)
if allowed, ok := allowedRoutes[vsname]; ok {
if routeNs, ok := ActiveSIGs.Namespace[hr.Namespace]; ok {
matched := namespaceMatches(gw.Namespace, allowed.Namespaces, routeNs)
if matched {
hrs = append(hrs, hr)
}
}
routeNamespace := ActiveSIGs.Namespace[hr.Namespace]
routetype := reflect.TypeOf(*hr).Name()
if routeMatches(gw.Namespace, listeners[vsname], routeNamespace, routetype) {
hrs = append(hrs, hr)
break
}
}
}
Expand Down
20 changes: 13 additions & 7 deletions pkg/parser.go
Expand Up @@ -2,6 +2,7 @@ package pkg

import (
"fmt"
"reflect"
"strings"

"gitee.com/zongzw/bigip-kubernetes-gateway/k8s"
Expand Down Expand Up @@ -103,9 +104,6 @@ func parseHTTPRoute(className string, hr *gatewayv1beta1.HTTPRoute) (map[string]
}

rlt := map[string]interface{}{}
// if err := parsePoolsFrom(hr, rlt); err != nil {
// return map[string]interface{}{}, err
// }

if err := parseiRulesFrom(className, hr, rlt); err != nil {
return map[string]interface{}{}, err
Expand All @@ -123,10 +121,12 @@ func parseGateway(gw *gatewayv1beta1.Gateway) (map[string]interface{}, error) {

rlt := map[string]interface{}{}
irules := map[string][]string{}
listeners := map[string]*gatewayv1beta1.Listener{}

for _, listener := range gw.Spec.Listeners {
for i, listener := range gw.Spec.Listeners {
vsname := gwListenerName(gw, &listener)
listeners[vsname] = &gw.Spec.Listeners[i]
if listener.Hostname != nil {
vsname := gwListenerName(gw, &listener)
if _, ok := irules[vsname]; !ok {
irules[vsname] = []string{}
}
Expand All @@ -148,15 +148,21 @@ func parseGateway(gw *gatewayv1beta1.Gateway) (map[string]interface{}, error) {
hrs := ActiveSIGs.AttachedHTTPRoutes(gw)
for _, hr := range hrs {
for _, pr := range hr.Spec.ParentRefs {

ns := hr.Namespace
if pr.Namespace != nil {
ns = string(*pr.Namespace)
}
if pr.SectionName == nil {
return map[string]interface{}{}, fmt.Errorf("sectionName of paraentRefs is nil, not supported")
}
vsname := hrParentName(hr, &pr)
if _, ok := irules[vsname]; !ok {
irules[vsname] = []string{}
}
irules[vsname] = append(irules[vsname], hrName(hr))
routetype := reflect.TypeOf(*hr).Name()
if routeMatches(ns, listeners[vsname], ActiveSIGs.GetNamespace(hr.Namespace), routetype) {
irules[vsname] = append(irules[vsname], hrName(hr))
}
}
}
for _, addr := range gw.Spec.Addresses {
Expand Down
58 changes: 51 additions & 7 deletions pkg/utils.go
@@ -1,6 +1,7 @@
package pkg

import (
"reflect"
"strings"

v1 "k8s.io/api/core/v1"
Expand All @@ -18,30 +19,73 @@ func hrParentName(hr *gatewayv1beta1.HTTPRoute, pr *gatewayv1beta1.ParentReferen
if pr.Namespace != nil {
ns = string(*pr.Namespace)
}
return strings.Join([]string{"gw", ns, string(pr.Name), string(*pr.SectionName)}, ".")
sn := ""
if pr.SectionName != nil {
sn = string(*pr.SectionName)
}
return strings.Join([]string{"gw", ns, string(pr.Name), sn}, ".")
}

func gwListenerName(gw *gatewayv1beta1.Gateway, ls *gatewayv1beta1.Listener) string {
return strings.Join([]string{"gw", gw.Namespace, gw.Name, string(ls.Name)}, ".")
}

func namespaceMatches(gwNamespace string, namespaces *gatewayv1beta1.RouteNamespaces, routeNs *v1.Namespace) bool {
func routeMatches(gwNamespace string, listener *gatewayv1beta1.Listener, routeNamespace *v1.Namespace, routeType string) bool {
// actually, "listener" may be nil, but ".AllowedRoutes.Namespaces.From" will never be nil
if listener == nil || listener.AllowedRoutes == nil {
return false
}
namespaces := listener.AllowedRoutes.Namespaces
if namespaces == nil || namespaces.From == nil {
return true
return false
}

matchedFrom, matchedKind := false, false

// From
switch *namespaces.From {
case gatewayv1beta1.NamespacesFromAll:
return true
matchedFrom = true
case gatewayv1beta1.NamespacesFromSame:
return gwNamespace == routeNs.Name
matchedFrom = gwNamespace == routeNamespace.Name
case gatewayv1beta1.NamespacesFromSelector:
if selector, err := metav1.LabelSelectorAsSelector(namespaces.Selector); err != nil {
return false
} else {
return selector.Matches(labels.Set(routeNs.Labels))
matchedFrom = selector.Matches(labels.Set(routeNamespace.Labels))
}
}
if !matchedFrom {
return false
}

// Kind
allowedKinds := listener.AllowedRoutes.Kinds
if len(allowedKinds) == 0 {
switch listener.Protocol {
case gatewayv1beta1.HTTPProtocolType:
matchedKind = routeType == reflect.TypeOf(gatewayv1beta1.HTTPRoute{}).Name()
case gatewayv1beta1.HTTPSProtocolType:
return false
case gatewayv1beta1.TLSProtocolType:
return false
case gatewayv1beta1.TCPProtocolType:
return false
case gatewayv1beta1.UDPProtocolType:
return false
}
} else {
for _, k := range allowedKinds {
if k.Group != nil && *k.Group != gatewayv1beta1.GroupName {
return false
} else {
if k.Kind == gatewayv1beta1.Kind(routeType) {
matchedKind = true
break
}
}
}
}

return true
return matchedFrom && matchedKind
}

0 comments on commit b4bbffb

Please sign in to comment.