Skip to content

Commit

Permalink
Pick up gateway rc2 (istio#50831)
Browse files Browse the repository at this point in the history
* Pick up gateway rc2

* new test

* initial attempt

* working

* address comments
  • Loading branch information
howardjohn authored May 8, 2024
1 parent 199f76a commit 9c69544
Show file tree
Hide file tree
Showing 10 changed files with 729 additions and 26 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ require (
k8s.io/kubectl v0.30.0
k8s.io/utils v0.0.0-20240423183400-0849a56e8f22
sigs.k8s.io/controller-runtime v0.18.0
sigs.k8s.io/gateway-api v1.1.0-rc1.0.20240430231933-e1b774d9e0c6
sigs.k8s.io/gateway-api v1.1.0-rc2
sigs.k8s.io/mcs-api v0.1.0
sigs.k8s.io/yaml v1.4.0
)
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1145,8 +1145,8 @@ sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gE
sigs.k8s.io/controller-runtime v0.18.0 h1:Z7jKuX784TQSUL1TIyeuF7j8KXZ4RtSX0YgtjKcSTME=
sigs.k8s.io/controller-runtime v0.18.0/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw=
sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI=
sigs.k8s.io/gateway-api v1.1.0-rc1.0.20240430231933-e1b774d9e0c6 h1:Xy/M/WmBcz3zNZbQWX842vq3WRrILRiJsCss2oBq6/Q=
sigs.k8s.io/gateway-api v1.1.0-rc1.0.20240430231933-e1b774d9e0c6/go.mod h1:HdG3/Tr9DbQ3zs1/Dx5t8l+15qmSkJ9nE9Kqe+nasog=
sigs.k8s.io/gateway-api v1.1.0-rc2 h1:uMHSylqzNHYD4kgp6OCDZv9o7ukzgtjuI6G6/e+TSUo=
sigs.k8s.io/gateway-api v1.1.0-rc2/go.mod h1:ZH4lHrL2sDi0FHZ9jjneb8kKnGzFWyrTya35sWUTrRs=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/kind v0.8.1/go.mod h1:oNKTxUVPYkV9lWzY6CVMNluVq8cBsyq+UgPJdvA3uu4=
Expand Down
63 changes: 58 additions & 5 deletions pilot/pkg/config/kube/gateway/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,10 @@ func buildHTTPVirtualServices(
// Create one VS per hostname with a single hostname.
// This ensures we can treat each hostname independently, as the spec requires
for _, h := range vsHosts {
if !parent.hostnameAllowedByIsolation(h) {
// TODO: standardize a status message for this upstream and report
continue
}
if cfg := routeMap[routeKey][h]; cfg != nil {
// merge http routes
vs := cfg.Spec.(*istio.VirtualService)
Expand Down Expand Up @@ -981,24 +985,40 @@ func extractParentReferenceInfo(gateways map[parentKey][]*parentInfo, routeRefs
SectionName: ptr.OrEmpty(ref.SectionName),
Port: ptr.OrEmpty(ref.Port),
}
gk := ir
if ir.Kind == gvk.Service || ir.Kind == gvk.ServiceEntry {
gk = meshParentKey
}
appendParent := func(pr *parentInfo, pk parentReference) {
bannedHostnames := sets.New[string]()
for _, gw := range gateways[gk] {
if gw == pr {
continue // do not ban ourself
}
if gw.Port != pr.Port {
// We only care about listeners on the same port
continue
}
if gw.Protocol != pr.Protocol {
// We only care about listeners on the same protocol
continue
}
bannedHostnames.Insert(gw.OriginalHostname)
}
rpi := routeParentReference{
InternalName: pr.InternalName,
InternalKind: ir.Kind,
Hostname: pr.OriginalHostname,
DeniedReason: referenceAllowed(pr, kind, pk, hostnames, localNamespace),
OriginalReference: ref,
BannedHostnames: bannedHostnames.Copy().Delete(pr.OriginalHostname),
}
if rpi.DeniedReason == nil {
// Record that we were able to bind to the parent
pr.AttachedRoutes++
}
parentRefs = append(parentRefs, rpi)
}
gk := ir
if ir.Kind == gvk.Service || ir.Kind == gvk.ServiceEntry {
gk = meshParentKey
}
for _, gw := range gateways[gk] {
// Append all matches. Note we may be adding mismatch section or ports; this is handled later
appendParent(gw, pk)
Expand Down Expand Up @@ -1926,6 +1946,7 @@ type parentInfo struct {
ReportAttachedRoutes func()
SectionName k8s.SectionName
Port k8s.PortNumber
Protocol k8s.ProtocolType
}

// routeParentReference holds information about a route's parent reference
Expand All @@ -1939,13 +1960,44 @@ type routeParentReference struct {
// OriginalReference contains the original reference
OriginalReference k8s.ParentReference
// Hostname is the hostname match of the parent, if any
Hostname string
Hostname string
BannedHostnames sets.Set[string]
}

func (r routeParentReference) IsMesh() bool {
return r.InternalName == "mesh"
}

func (r routeParentReference) hostnameAllowedByIsolation(rawRouteHost string) bool {
routeHost := host.Name(rawRouteHost)
ourListener := host.Name(r.Hostname)
if len(ourListener) > 0 && !ourListener.IsWildCarded() {
// Short circuit: this logic only applies to wildcards
// Not required for correctness, just an optimization
return true
}
if len(ourListener) > 0 && !routeHost.Matches(ourListener) {
return false
}
for checkListener := range r.BannedHostnames {
// We have 3 hostnames here:
// * routeHost, the hostname in the route entry
// * ourListener, the hostname of the listener the route is bound to
// * checkListener, the hostname of the other listener we are comparing to
// We want to return false if checkListener would match the routeHost and it would be a more exact match
if len(ourListener) > len(checkListener) {
// If our hostname is longer, it must be more exact than the check
continue
}
// Ours is shorter. If it matches the checkListener, then it should ONLY match that one
// Note protocol, port, etc are already considered when we construct bannedHostnames
if routeHost.SubsetOf(host.Name(checkListener)) {
return false
}
}
return true
}

func filteredReferences(parents []routeParentReference) []routeParentReference {
ret := make([]routeParentReference, 0, len(parents))
for _, p := range parents {
Expand Down Expand Up @@ -2049,6 +2101,7 @@ func convertGateways(r configContext) ([]config.Config, map[parentKey][]*parentI
OriginalHostname: string(ptr.OrEmpty(l.Hostname)),
SectionName: l.Name,
Port: l.Port,
Protocol: l.Protocol,
}
pri.ReportAttachedRoutes = func() {
reportListenerAttachedRoutes(i, obj, pri.AttachedRoutes)
Expand Down
1 change: 1 addition & 0 deletions pilot/pkg/config/kube/gateway/conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ func TestConvertResources(t *testing.T) {
{name: "mcs"},
{name: "route-precedence"},
{name: "waypoint"},
{name: "isolation"},
}
for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
Expand Down
242 changes: 242 additions & 0 deletions pilot/pkg/config/kube/gateway/testdata/isolation.status.yaml.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
creationTimestamp: null
name: isolation
namespace: gateway-conformance-infra
spec: null
status:
conditions:
- lastTransitionTime: fake
message: Resource accepted
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: 'Failed to assign to any requested addresses: hostname "isolation-istio.gateway-conformance-infra.svc.domain.suffix"
not found'
reason: AddressNotUsable
status: "False"
type: Programmed
listeners:
- attachedRoutes: 1
conditions:
- lastTransitionTime: fake
message: No errors found
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: No errors found
reason: NoConflicts
status: "False"
type: Conflicted
- lastTransitionTime: fake
message: No errors found
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: fake
message: No errors found
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
name: empty-hostname
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
- attachedRoutes: 1
conditions:
- lastTransitionTime: fake
message: No errors found
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: No errors found
reason: NoConflicts
status: "False"
type: Conflicted
- lastTransitionTime: fake
message: No errors found
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: fake
message: No errors found
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
name: wildcard-example-com
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
- attachedRoutes: 1
conditions:
- lastTransitionTime: fake
message: No errors found
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: No errors found
reason: NoConflicts
status: "False"
type: Conflicted
- lastTransitionTime: fake
message: No errors found
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: fake
message: No errors found
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
name: wildcard-foo-example-com
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
- attachedRoutes: 1
conditions:
- lastTransitionTime: fake
message: No errors found
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: No errors found
reason: NoConflicts
status: "False"
type: Conflicted
- lastTransitionTime: fake
message: No errors found
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: fake
message: No errors found
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
name: abc-foo-example-com
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: attaches-to-abc-foo-example-com-with-hostname-intersection
namespace: gateway-conformance-infra
spec: null
status:
parents:
- conditions:
- lastTransitionTime: fake
message: Route was valid
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: backend(infra-backend-v1.gateway-conformance-infra.svc.domain.suffix)
not found
reason: BackendNotFound
status: "False"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
parentRef:
name: isolation
namespace: gateway-conformance-infra
sectionName: abc-foo-example-com
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: attaches-to-empty-hostname-with-hostname-intersection
namespace: gateway-conformance-infra
spec: null
status:
parents:
- conditions:
- lastTransitionTime: fake
message: Route was valid
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: backend(infra-backend-v1.gateway-conformance-infra.svc.domain.suffix)
not found
reason: BackendNotFound
status: "False"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
parentRef:
name: isolation
namespace: gateway-conformance-infra
sectionName: empty-hostname
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: attaches-to-wildcard-example-com-with-hostname-intersection
namespace: gateway-conformance-infra
spec: null
status:
parents:
- conditions:
- lastTransitionTime: fake
message: Route was valid
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: backend(infra-backend-v1.gateway-conformance-infra.svc.domain.suffix)
not found
reason: BackendNotFound
status: "False"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
parentRef:
name: isolation
namespace: gateway-conformance-infra
sectionName: wildcard-example-com
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: attaches-to-wildcard-foo-example-com-with-hostname-intersection
namespace: gateway-conformance-infra
spec: null
status:
parents:
- conditions:
- lastTransitionTime: fake
message: Route was valid
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: fake
message: backend(infra-backend-v1.gateway-conformance-infra.svc.domain.suffix)
not found
reason: BackendNotFound
status: "False"
type: ResolvedRefs
controllerName: istio.io/gateway-controller
parentRef:
name: isolation
namespace: gateway-conformance-infra
sectionName: wildcard-foo-example-com
---
Loading

0 comments on commit 9c69544

Please sign in to comment.