Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/service import backend support #1705

Merged
merged 11 commits into from
Aug 23, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
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
13 changes: 13 additions & 0 deletions charts/gateway-helm/templates/_rbac.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ All cluster scoped resources for Envoy Gateway RBAC.
- {{ include "eg.rbac.cluster.basic" . | nindent 2 | trim }}
- {{ include "eg.rbac.cluster.gateway.networking" . | nindent 2 | trim }}
- {{ include "eg.rbac.cluster.gateway.networking.status" . | nindent 2 | trim }}
- {{ include "eg.rbac.cluster.multiclusterservices" . | nindent 2 | trim }}
{{- end }}

{{/*
Expand Down Expand Up @@ -158,6 +159,18 @@ verbs:
- watch
{{- end }}


{{- define "eg.rbac.cluster.multiclusterservices" -}}
apiGroups:
- multicluster.x-k8s.io
resources:
- serviceimports
verbs:
- get
- list
- watch
{{- end }}

{{- define "eg.rbac.cluster.gateway.networking.status" -}}
apiGroups:
- gateway.networking.k8s.io
Expand Down
1 change: 1 addition & 0 deletions docs/latest/api/config_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ _Appears in:_
| Field | Description |
| --- | --- |
| `enableEnvoyPatchPolicy` _boolean_ | EnableEnvoyPatchPolicy enables Envoy Gateway to reconcile and implement the EnvoyPatchPolicy resources. |
| `enableMultiClusterServiceAPI` _boolean_ | EnableMultiClusterServiceAPI enables Envoy Gateway to reconcile and implement the Multicluster services' ServiceImport resource. |


## ExtensionHooks
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -112,5 +112,6 @@ require (
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kustomize/api v0.13.2 // indirect
sigs.k8s.io/kustomize/kyaml v0.14.1 // indirect
sigs.k8s.io/mcs-api v0.1.0
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
)
376 changes: 376 additions & 0 deletions go.sum

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions internal/envoygateway/scheme.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
gwapiv1a2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
gwapiv1b1 "sigs.k8s.io/gateway-api/apis/v1beta1"
mcsapi "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1"

egcfgv1a1 "github.com/envoyproxy/gateway/api/config/v1alpha1"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
Expand Down Expand Up @@ -43,6 +44,10 @@ func init() {
if err := gwapiv1a2.AddToScheme(scheme); err != nil {
panic(err)
}
// Add mcs api types.
if err := mcsapi.AddToScheme(scheme); err != nil {
panic(err)
}
}

// GetScheme returns a scheme with types supported by the Kubernetes provider.
Expand Down
7 changes: 7 additions & 0 deletions internal/gatewayapi/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,13 @@ func GroupDerefOr(group *v1beta1.Group, defaultGroup string) string {
return defaultGroup
}

func KindDerefOr(kind *v1beta1.Kind, defaultKind string) string {
if kind != nil && *kind != "" {
return string(*kind)
}
return defaultKind
}

// IsRefToGateway returns whether the provided parent ref is a reference
// to a Gateway with the given namespace/name, irrespective of whether a
// section/listener name has been specified (i.e. a parent ref to a listener
Expand Down
12 changes: 12 additions & 0 deletions internal/gatewayapi/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"sigs.k8s.io/gateway-api/apis/v1alpha2"
"sigs.k8s.io/gateway-api/apis/v1beta1"
mcsapi "sigs.k8s.io/mcs-api/pkg/apis/v1alpha1"

egcfgv1a1 "github.com/envoyproxy/gateway/api/config/v1alpha1"
egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
Expand All @@ -36,6 +37,7 @@ type Resources struct {
ReferenceGrants []*v1alpha2.ReferenceGrant `json:"referenceGrants,omitempty" yaml:"referenceGrants,omitempty"`
Namespaces []*v1.Namespace `json:"namespaces,omitempty" yaml:"namespaces,omitempty"`
Services []*v1.Service `json:"services,omitempty" yaml:"services,omitempty"`
ServiceImports []*mcsapi.ServiceImport `json:"serviceImports,omitempty" yaml:"serviceImports,omitempty"`
EndpointSlices []*discoveryv1.EndpointSlice `json:"endpointSlices,omitempty" yaml:"endpointSlices,omitempty"`
Secrets []*v1.Secret `json:"secrets,omitempty" yaml:"secrets,omitempty"`
AuthenticationFilters []*egv1a1.AuthenticationFilter `json:"authenticationFilters,omitempty" yaml:"authenticationFilters,omitempty"`
Expand Down Expand Up @@ -83,6 +85,16 @@ func (r *Resources) GetService(namespace, name string) *v1.Service {
return nil
}

func (r *Resources) GetServiceImport(namespace, name string) *mcsapi.ServiceImport {
for _, svcImp := range r.ServiceImports {
if svcImp.Namespace == namespace && svcImp.Name == name {
return svcImp
}
}

return nil
}

func (r *Resources) GetSecret(namespace, name string) *v1.Secret {
for _, secret := range r.Secrets {
if secret.Namespace == namespace && secret.Name == name {
Expand Down
39 changes: 24 additions & 15 deletions internal/gatewayapi/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -971,27 +971,36 @@ func (t *Translator) processDestEndpoints(backendRef v1beta1.BackendRef,
weight = uint32(*backendRef.Weight)
}

serviceNamespace := NamespaceDerefOr(backendRef.Namespace, route.GetNamespace())
service := resources.GetService(serviceNamespace, string(backendRef.Name))
backendNamespace := NamespaceDerefOr(backendRef.Namespace, route.GetNamespace())

routeType := GetRouteType(route)
if !t.validateBackendRef(&backendRef, parentRef, route, resources, serviceNamespace, routeType) {
if !t.validateBackendRef(&backendRef, parentRef, route, resources, backendNamespace, routeType) {
return nil, weight
}

var ep *ir.DestinationEndpoint
// Weights are not relevant for TCP and UDP Routes
if routeType == KindTCPRoute || routeType == KindUDPRoute {
ep = ir.NewDestEndpoint(
service.Spec.ClusterIP,
uint32(*backendRef.Port))
} else {
ep = ir.NewDestEndpointWithWeight(
service.Spec.ClusterIP,
uint32(*backendRef.Port),
weight)
var backendIps []string
switch KindDerefOr(backendRef.Kind, KindService) {
case KindServiceImport:
backendIps = resources.GetServiceImport(backendNamespace, string(backendRef.Name)).Spec.IPs
case KindService:
backendIps = []string{resources.GetService(backendNamespace, string(backendRef.Name)).Spec.ClusterIP}
}

for _, ip := range backendIps {
var ep *ir.DestinationEndpoint
// Weights are not relevant for TCP and UDP Routes
if routeType == KindTCPRoute || routeType == KindUDPRoute {
ep = ir.NewDestEndpoint(
ip,
uint32(*backendRef.Port))
} else {
ep = ir.NewDestEndpointWithWeight(
ip,
uint32(*backendRef.Port),
weight)
}
endpoints = append(endpoints, ep)
}
endpoints = append(endpoints, ep)
return endpoints, weight
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
gateways:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
namespace: default
name: httproute-1
spec:
parentRefs:
- namespace: envoy-gateway
name: gateway-1
sectionName: http
rules:
- matches:
- path:
value: "/"
backendRefs:
- group: multicluster.x-k8s.io
kind: ServiceImport
name: service-import-1
port: 8080
serviceImports:
- apiVersion: multicluster.x-k8s.io/v1alpha1
kind: ServiceImport
metadata:
namespace: default
name: service-import-1
spec:
ips:
- 7.7.7.7
ports:
- port: 8080
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
gateways:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
creationTimestamp: null
name: gateway-1
namespace: envoy-gateway
spec:
gatewayClassName: envoy-gateway-class
listeners:
- allowedRoutes:
namespaces:
from: All
name: http
port: 80
protocol: HTTP
status:
listeners:
- attachedRoutes: 1
conditions:
- lastTransitionTime: null
message: Sending translated listener configuration to the data plane
reason: Programmed
status: "True"
type: Programmed
- lastTransitionTime: null
message: Listener has been successfully translated
reason: Accepted
status: "True"
type: Accepted
name: http
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
- group: gateway.networking.k8s.io
kind: GRPCRoute
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
creationTimestamp: null
name: httproute-1
namespace: default
spec:
parentRefs:
- name: gateway-1
namespace: envoy-gateway
sectionName: http
rules:
- backendRefs:
- group: multicluster.x-k8s.io
kind: ServiceImport
name: service-import-1
port: 8080
matches:
- path:
value: /
status:
parents:
- conditions:
- lastTransitionTime: null
message: Route is accepted
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: null
message: Resolved all the Object references for the Route
reason: ResolvedRefs
status: "True"
type: ResolvedRefs
controllerName: gateway.envoyproxy.io/gatewayclass-controller
parentRef:
name: gateway-1
namespace: envoy-gateway
sectionName: http
infraIR:
envoy-gateway/gateway-1:
proxy:
listeners:
- address: ""
ports:
- containerPort: 10080
name: http
protocol: HTTP
servicePort: 80
metadata:
labels:
gateway.envoyproxy.io/owning-gateway-name: gateway-1
gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
name: envoy-gateway/gateway-1
xdsIR:
envoy-gateway/gateway-1:
accessLog:
text:
- path: /dev/stdout
http:
- address: 0.0.0.0
hostnames:
- '*'
isHTTP2: false
name: envoy-gateway/gateway-1/http
port: 10080
routes:
- backendWeights:
invalid: 0
valid: 0
destinations:
- host: 7.7.7.7
port: 8080
weight: 1
name: default/httproute-1/rule/0/match/0-*
pathMatch:
distinct: false
name: ""
prefix: /
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
gateways:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gateway-1
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
httpRoutes:
- apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
namespace: default
name: httproute-1
spec:
parentRefs:
- namespace: envoy-gateway
name: gateway-1
rules:
- matches:
- path:
type: Exact
value: "/exact"
backendRefs:
- group: multicluster.x-k8s.io
kind: ServiceImport
name: service-import-1
namespace: backends
port: 8080
serviceImports:
- apiVersion: multicluster.x-k8s.io/v1alpha1
kind: ServiceImport
metadata:
namespace: backends
name: service-import-1
spec:
ips:
- 7.7.7.7
ports:
- port: 8080
referenceGrants:
- apiVersion: gateway.networking.k8s.io/v1alpha2
kind: ReferenceGrant
metadata:
namespace: backends
name: referencegrant-1
spec:
from:
- group: gateway.networking.k8s.io
kind: HTTPRoute
namespace: default
to:
- group: multicluster.x-k8s.io
kind: ServiceImport
Loading