Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
4f708f8
TLS Passthrough support
chauhanshubham Oct 1, 2022
b8033ec
Adding tlsroute experimental crd in testdata
chauhanshubham Sep 21, 2022
0b3f5be
keep other testdata changes out of this PR
chauhanshubham Sep 22, 2022
7473cfb
added testcases for tlsroutes, include serviceport in irInfraPortName
chauhanshubham Sep 22, 2022
e4563ba
lintfix
chauhanshubham Sep 22, 2022
9edaa03
tlroute kubernetes provider test
chauhanshubham Sep 22, 2022
813ced8
added xds tls config validate test for passthrough
chauhanshubham Sep 22, 2022
499b752
types test tlsroute
chauhanshubham Sep 22, 2022
f8024b8
test fixes
chauhanshubham Sep 22, 2022
33e9f1b
xds config tests for tls passthrough
chauhanshubham Sep 22, 2022
441ed9e
increase test coverage
chauhanshubham Sep 22, 2022
14f9a46
testfix
chauhanshubham Sep 22, 2022
aba3fd2
separate xds tls listener
chauhanshubham Sep 24, 2022
5275fac
additional xds validate tests
chauhanshubham Sep 24, 2022
5803a54
tlsroute refgrant test
chauhanshubham Sep 24, 2022
754083f
add rbac permissions for tlsroute
chauhanshubham Sep 26, 2022
48df046
updates post rebase
chauhanshubham Oct 5, 2022
8a5632f
add status updater, gateway watcher for tlsroute
chauhanshubham Oct 5, 2022
fa840ed
add status update framework for tlsroute
chauhanshubham Oct 6, 2022
b674402
lintfix, testfix, fix post rebase
chauhanshubham Oct 7, 2022
3f348b8
yet another lintfix
chauhanshubham Oct 7, 2022
bf204fa
refactor tlslistener/route -> tcplistener/route, xds updates
chauhanshubham Oct 7, 2022
6a8e114
missed a file
chauhanshubham Oct 7, 2022
0ca160b
lintfix
chauhanshubham Oct 7, 2022
8bf39b3
rebase, review comments
chauhanshubham Oct 8, 2022
932334c
minor testfix
chauhanshubham Oct 8, 2022
991b869
more
chauhanshubham Oct 8, 2022
b54f2fe
review comments, status deepcopy, check routes in ns
chauhanshubham Oct 10, 2022
c09d71c
revert bad import, testfix, new test
chauhanshubham Oct 10, 2022
5475f5b
rev sort
chauhanshubham Oct 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions internal/cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ func setupRunners(cfg *config.Server) error {
pResources.Namespaces.Close()
pResources.GatewayStatuses.Close()
pResources.HTTPRouteStatuses.Close()
pResources.TLSRoutes.Close()
pResources.TLSRouteStatuses.Close()
xdsIR.Close()
infraIR.Close()
xds.Close()
Expand Down
6 changes: 5 additions & 1 deletion internal/envoygateway/scheme.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ package envoygateway
import (
"k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"
gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1beta1"

"github.com/envoyproxy/gateway/api/config/v1alpha1"
)
Expand All @@ -28,6 +29,9 @@ func init() {
if err := gwapiv1b1.AddToScheme(scheme); err != nil {
panic(err)
}
if err := gwapiv1a2.AddToScheme(scheme); err != nil {
panic(err)
}
}

// GetScheme returns a scheme with types supported by the Kubernetes provider.
Expand Down
215 changes: 192 additions & 23 deletions internal/gatewayapi/contexts.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/gateway-api/apis/v1alpha2"
"sigs.k8s.io/gateway-api/apis/v1beta1"

egv1alpha1 "github.com/envoyproxy/gateway/api/config/v1alpha1"
Expand All @@ -20,6 +22,10 @@ type GatewayContext struct {
listeners map[v1beta1.SectionName]*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(map[v1beta1.SectionName]*ListenerContext)
Expand Down Expand Up @@ -167,6 +173,30 @@ func (l *ListenerContext) SetTLSSecret(tlsSecret *v1.Secret) {
l.tlsSecret = tlsSecret
}

// RouteContext represents a generic Route object (HTTPRoute, TLSRoute, etc.)
// that can reference Gateway objects.
type RouteContext interface {
client.Object

// GetRouteType returns the Kind of the Route object, HTTPRoute,
// TLSRoute, TCPRoute, UDPRoute etc.
GetRouteType() string

// TODO: [v1alpha2-v1beta1] This should not be required once all Route
// objects being implemented are of type v1beta1.
// GetHostnames returns the hosts targeted by the Route object.
GetHostnames() []string

// TODO: [v1alpha2-v1beta1] This should not be required once all Route
// objects being implemented are of type v1beta1.
// GetParentReferences returns the ParentReference of the Route object.
GetParentReferences() []v1beta1.ParentReference

// GetRouteParentContext returns RouteParentContext by using the Route
// objects' ParentReference.
GetRouteParentContext(forParentRef v1beta1.ParentReference) *RouteParentContext
}

// HTTPRouteContext wraps an HTTPRoute and provides helper methods for
// accessing the route's parents.
type HTTPRouteContext struct {
Expand All @@ -175,6 +205,22 @@ type HTTPRouteContext struct {
parentRefs map[v1beta1.ParentReference]*RouteParentContext
}

func (h *HTTPRouteContext) GetRouteType() string {
return KindHTTPRoute
}

func (h *HTTPRouteContext) GetHostnames() []string {
hostnames := make([]string, len(h.Spec.Hostnames))
for idx, s := range h.Spec.Hostnames {
hostnames[idx] = string(s)
}
return hostnames
}

func (h *HTTPRouteContext) GetParentReferences() []v1beta1.ParentReference {
return h.Spec.ParentRefs
}

func (h *HTTPRouteContext) GetRouteParentContext(forParentRef v1beta1.ParentReference) *RouteParentContext {
if h.parentRefs == nil {
h.parentRefs = make(map[v1beta1.ParentReference]*RouteParentContext)
Expand Down Expand Up @@ -215,20 +261,109 @@ func (h *HTTPRouteContext) GetRouteParentContext(forParentRef v1beta1.ParentRefe
ctx := &RouteParentContext{
ParentReference: parentRef,

route: h.HTTPRoute,
httpRoute: h.HTTPRoute,
routeParentStatusIdx: routeParentStatusIdx,
}
h.parentRefs[forParentRef] = ctx
return ctx
}

// TLSRouteContext wraps a TLSRoute and provides helper methods for
// accessing the route's parents.
type TLSRouteContext struct {
*v1alpha2.TLSRoute

parentRefs map[v1beta1.ParentReference]*RouteParentContext
}

func (t *TLSRouteContext) GetRouteType() string {
return KindTLSRoute
}

func (t *TLSRouteContext) GetHostnames() []string {
hostnames := make([]string, len(t.Spec.Hostnames))
for idx, s := range t.Spec.Hostnames {
hostnames[idx] = string(s)
}
return hostnames
}

func (t *TLSRouteContext) GetParentReferences() []v1beta1.ParentReference {
parentReferences := make([]v1beta1.ParentReference, len(t.Spec.ParentRefs))
for idx, p := range t.Spec.ParentRefs {
parentReferences[idx] = UpgradeParentReference(p)
}
return parentReferences
}

func (t *TLSRouteContext) GetRouteParentContext(forParentRef v1beta1.ParentReference) *RouteParentContext {
if t.parentRefs == nil {
t.parentRefs = make(map[v1beta1.ParentReference]*RouteParentContext)
}

if ctx := t.parentRefs[forParentRef]; ctx != nil {
return ctx
}

var parentRef *v1beta1.ParentReference
for i, p := range t.Spec.ParentRefs {
p := UpgradeParentReference(p)
if reflect.DeepEqual(p, forParentRef) {
upgraded := UpgradeParentReference(t.Spec.ParentRefs[i])
parentRef = &upgraded
break
}
}
if parentRef == nil {
panic("parentRef not found")
}

routeParentStatusIdx := -1
for i := range t.Status.Parents {
p := UpgradeParentReference(t.Status.Parents[i].ParentRef)
defaultNamespace := v1beta1.Namespace(metav1.NamespaceDefault)
if forParentRef.Namespace == nil {
forParentRef.Namespace = &defaultNamespace
}
if p.Namespace == nil {
p.Namespace = &defaultNamespace
}
if reflect.DeepEqual(p, forParentRef) {
routeParentStatusIdx = i
break
}
}
if routeParentStatusIdx == -1 {
rParentStatus := v1alpha2.RouteParentStatus{
// TODO: get this value from the config
ControllerName: v1alpha2.GatewayController(egv1alpha1.GatewayControllerName),
ParentRef: DowngradeParentReference(forParentRef),
}
t.Status.Parents = append(t.Status.Parents, rParentStatus)
routeParentStatusIdx = len(t.Status.Parents) - 1
}

ctx := &RouteParentContext{
ParentReference: parentRef,

tlsRoute: t.TLSRoute,
routeParentStatusIdx: routeParentStatusIdx,
}
t.parentRefs[forParentRef] = ctx
return ctx
}

// RouteParentContext wraps a ParentReference and provides helper methods for
// setting conditions and other status information on the associated
// HTTPRoute, etc.
// HTTPRoute, TLSRoute etc.
type RouteParentContext struct {
*v1beta1.ParentReference

route *v1beta1.HTTPRoute
// TODO: [v1alpha2-v1beta1] This can probably be replaced with
// a single field pointing to *v1beta1.RouteStatus.
httpRoute *v1beta1.HTTPRoute
tlsRoute *v1alpha2.TLSRoute

routeParentStatusIdx int
listeners []*ListenerContext
}
Expand All @@ -237,43 +372,77 @@ func (r *RouteParentContext) SetListeners(listeners ...*ListenerContext) {
r.listeners = append(r.listeners, listeners...)
}

func (r *RouteParentContext) SetCondition(conditionType v1beta1.RouteConditionType, status metav1.ConditionStatus, reason v1beta1.RouteConditionReason, message string) {
func (r *RouteParentContext) SetCondition(route RouteContext, conditionType v1beta1.RouteConditionType, status metav1.ConditionStatus, reason v1beta1.RouteConditionReason, message string) {
cond := metav1.Condition{
Type: string(conditionType),
Status: status,
Reason: string(reason),
Message: message,
ObservedGeneration: r.route.Generation,
ObservedGeneration: route.GetGeneration(),
LastTransitionTime: metav1.NewTime(time.Now()),
}

idx := -1
for i, existing := range r.route.Status.Parents[r.routeParentStatusIdx].Conditions {
if existing.Type == cond.Type {
// return early if the condition is unchanged
if existing.Status == cond.Status &&
existing.Reason == cond.Reason &&
existing.Message == cond.Message {
return
switch route.GetRouteType() {
case KindHTTPRoute:
for i, existing := range r.httpRoute.Status.Parents[r.routeParentStatusIdx].Conditions {
if existing.Type == cond.Type {
// return early if the condition is unchanged
if existing.Status == cond.Status &&
existing.Reason == cond.Reason &&
existing.Message == cond.Message {
return
}
idx = i
break
}
idx = i
break
}
}

if idx > -1 {
r.route.Status.Parents[r.routeParentStatusIdx].Conditions[idx] = cond
} else {
r.route.Status.Parents[r.routeParentStatusIdx].Conditions = append(r.route.Status.Parents[r.routeParentStatusIdx].Conditions, cond)
if idx > -1 {
r.httpRoute.Status.Parents[r.routeParentStatusIdx].Conditions[idx] = cond
} else {
r.httpRoute.Status.Parents[r.routeParentStatusIdx].Conditions = append(r.httpRoute.Status.Parents[r.routeParentStatusIdx].Conditions, cond)
}
case KindTLSRoute:
for i, existing := range r.tlsRoute.Status.Parents[r.routeParentStatusIdx].Conditions {
if existing.Type == cond.Type {
// return early if the condition is unchanged
if existing.Status == cond.Status &&
existing.Reason == cond.Reason &&
existing.Message == cond.Message {
return
}
idx = i
break
}
}

if idx > -1 {
r.tlsRoute.Status.Parents[r.routeParentStatusIdx].Conditions[idx] = cond
} else {
r.tlsRoute.Status.Parents[r.routeParentStatusIdx].Conditions = append(r.tlsRoute.Status.Parents[r.routeParentStatusIdx].Conditions, cond)
}
}
}

func (r *RouteParentContext) ResetConditions() {
r.route.Status.Parents[r.routeParentStatusIdx].Conditions = make([]metav1.Condition, 0)
func (r *RouteParentContext) ResetConditions(route RouteContext) {
switch route.GetRouteType() {
case KindHTTPRoute:
r.httpRoute.Status.Parents[r.routeParentStatusIdx].Conditions = make([]metav1.Condition, 0)
case KindTLSRoute:
r.tlsRoute.Status.Parents[r.routeParentStatusIdx].Conditions = make([]metav1.Condition, 0)
}
}

func (r *RouteParentContext) IsAccepted() bool {
for _, cond := range r.route.Status.Parents[r.routeParentStatusIdx].Conditions {
func (r *RouteParentContext) IsAccepted(route RouteContext) bool {
var conditions []metav1.Condition
switch route.GetRouteType() {
case KindHTTPRoute:
conditions = r.httpRoute.Status.Parents[r.routeParentStatusIdx].Conditions
case KindTLSRoute:
conditions = r.tlsRoute.Status.Parents[r.routeParentStatusIdx].Conditions
}
for _, cond := range conditions {
if cond.Type == string(v1beta1.RouteConditionAccepted) && cond.Status == metav1.ConditionTrue {
return true
}
Expand Down
11 changes: 8 additions & 3 deletions internal/gatewayapi/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ func FromNamespacesPtr(fromNamespaces v1beta1.FromNamespaces) *v1beta1.FromNames
return &fromNamespaces
}

func SectionNamePtr(name string) *v1beta1.SectionName {
sectionName := v1beta1.SectionName(name)
return &sectionName
}

func StringPtr(val string) *string {
return &val
}
Expand Down Expand Up @@ -138,9 +143,9 @@ func HasReadyListener(listeners []*ListenerContext) bool {
return false
}

// ComputeHosts returns a list of the intersecting hostnames between the route
// computeHosts returns a list of the intersecting hostnames between the route
// and the listener.
func ComputeHosts(routeHostnames []v1beta1.Hostname, listenerHostname *v1beta1.Hostname) []string {
func computeHosts(routeHostnames []string, listenerHostname *v1beta1.Hostname) []string {
var listenerHostnameVal string
if listenerHostname != nil {
listenerHostnameVal = string(*listenerHostname)
Expand All @@ -159,7 +164,7 @@ func ComputeHosts(routeHostnames []v1beta1.Hostname, listenerHostname *v1beta1.H
var hostnames []string

for i := range routeHostnames {
routeHostname := string(routeHostnames[i])
routeHostname := routeHostnames[i]

// TODO ensure routeHostname is a valid hostname

Expand Down
Loading