Skip to content

Commit

Permalink
feat(gateway): add support for ExternalService refs
Browse files Browse the repository at this point in the history
Signed-off-by: Mike Beaumont <[email protected]>
  • Loading branch information
michaelbeaumont committed Dec 9, 2021
1 parent 6ef4fb5 commit 02cf866
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 17 deletions.
46 changes: 34 additions & 12 deletions pkg/plugins/runtime/k8s/controllers/gatewayapi/converter.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package controllers

import (
"context"
"errors"
"fmt"

gatewayapi "sigs.k8s.io/gateway-api/apis/v1alpha2"

mesh_proto "github.com/kumahq/kuma/api/mesh/v1alpha1"
core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh"
"github.com/kumahq/kuma/pkg/core/resources/store"
util_proto "github.com/kumahq/kuma/pkg/util/proto"
)

Expand All @@ -17,26 +20,45 @@ func k8sToKumaHeader(header gatewayapi.HTTPHeader) *mesh_proto.GatewayRoute_Http
}
}

func gapiToKumaRef(objectNamespace string, ref gatewayapi.BackendObjectReference) (map[string]string, error) {
func (r *HTTPRouteReconciler) gapiToKumaRef(ctx context.Context, mesh string, objectNamespace string, ref gatewayapi.BackendObjectReference) (map[string]string, error) {
// References to Services are required by GAPI to include a port
// TODO remove when https://github.com/kubernetes-sigs/gateway-api/pull/944
// is in master
if ref.Port == nil {
return nil, errors.New("backend reference must include port")
}

if *ref.Kind != "Service" {
return nil, errors.New("backend reference must be a Service") // TODO setappropriate status on gateway
}
switch *ref.Kind {
case "Service":
namespace := objectNamespace
if ref.Namespace != nil {
namespace = string(*ref.Namespace)
}

return map[string]string{
mesh_proto.ServiceTag: fmt.Sprintf("%s_%s_svc_%d", ref.Name, namespace, *ref.Port),
}, nil
case "ExternalService":
if *ref.Group != "kuma.io" {
break
}

name := string(ref.Name)

resource := core_mesh.NewExternalServiceResource()
if err := r.ResourceManager.Get(ctx, resource, store.GetByKey(name, mesh)); err != nil {
// TODO this shouldn't be a fatal error
return nil, fmt.Errorf("backend reference references a non-existent ExternalService %s", name)
}

service := resource.Spec.GetService()

namespace := objectNamespace
if ref.Namespace != nil {
namespace = string(*ref.Namespace)
return map[string]string{
mesh_proto.ServiceTag: service,
}, nil
}

return map[string]string{
mesh_proto.ServiceTag: fmt.Sprintf("%s_%s_svc_%d", ref.Name, namespace, *ref.Port),
}, nil
return nil, errors.New("backend reference must be a Service or an externalservice.kuma.io") // TODO setappropriate status on gateway
}

func gapiToKumaMatch(match gatewayapi.HTTPRouteMatch) (*mesh_proto.GatewayRoute_HttpRoute_Match, error) {
Expand Down Expand Up @@ -102,7 +124,7 @@ func gapiToKumaMatch(match gatewayapi.HTTPRouteMatch) (*mesh_proto.GatewayRoute_
return kumaMatch, nil
}

func gapiToKumaFilter(namespace string, filter gatewayapi.HTTPRouteFilter) (*mesh_proto.GatewayRoute_HttpRoute_Filter, error) {
func (r *HTTPRouteReconciler) gapiToKumaFilter(ctx context.Context, mesh string, namespace string, filter gatewayapi.HTTPRouteFilter) (*mesh_proto.GatewayRoute_HttpRoute_Filter, error) {
var kumaFilter mesh_proto.GatewayRoute_HttpRoute_Filter

switch filter.Type {
Expand All @@ -127,7 +149,7 @@ func gapiToKumaFilter(namespace string, filter gatewayapi.HTTPRouteFilter) (*mes
case gatewayapi.HTTPRouteFilterRequestMirror:
filter := filter.RequestMirror

destinationRef, err := gapiToKumaRef(namespace, filter.BackendRef)
destinationRef, err := r.gapiToKumaRef(ctx, mesh, namespace, filter.BackendRef)
if err != nil {
return nil, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (r *HTTPRouteReconciler) Reconcile(ctx context.Context, req kube_ctrl.Reque
resource := core_mesh.NewGatewayRouteResource()

if err := manager.Upsert(r.ResourceManager, model.ResourceKey{Mesh: mesh, Name: coreName}, resource, func(resource model.Resource) error {
spec, err := r.gapiToKumaRoute(httpRoute.Namespace, httpRoute)
spec, err := r.gapiToKumaRoute(ctx, mesh, httpRoute.Namespace, httpRoute)
if err != nil {
return errors.Wrap(err, "error generating GatewayRoute")
}
Expand All @@ -68,7 +68,7 @@ func (r *HTTPRouteReconciler) Reconcile(ctx context.Context, req kube_ctrl.Reque

var err error

resource.Spec, err = r.gapiToKumaRoute(httpRoute.Namespace, httpRoute)
resource.Spec, err = r.gapiToKumaRoute(ctx, mesh, httpRoute.Namespace, httpRoute)
if err != nil {
return kube_ctrl.Result{}, err
}
Expand All @@ -78,7 +78,7 @@ func (r *HTTPRouteReconciler) Reconcile(ctx context.Context, req kube_ctrl.Reque
return kube_ctrl.Result{}, errors.Wrap(err, "could not update GatewayRoute resource")
}

func (r *HTTPRouteReconciler) gapiToKumaRoute(namespace string, route *gatewayapi.HTTPRoute) (*mesh_proto.GatewayRoute, error) {
func (r *HTTPRouteReconciler) gapiToKumaRoute(ctx context.Context, mesh string, namespace string, route *gatewayapi.HTTPRoute) (*mesh_proto.GatewayRoute, error) {
var selectors []*mesh_proto.Selector

// Convert GAPI parent refs into Kuma tag matchers
Expand Down Expand Up @@ -114,7 +114,7 @@ func (r *HTTPRouteReconciler) gapiToKumaRoute(namespace string, route *gatewayap
for _, backend := range rule.BackendRefs {
ref := backend.BackendObjectReference

destination, err := gapiToKumaRef(namespace, ref)
destination, err := r.gapiToKumaRef(ctx, mesh, namespace, ref)
if err != nil {
return nil, err
}
Expand All @@ -140,7 +140,7 @@ func (r *HTTPRouteReconciler) gapiToKumaRoute(namespace string, route *gatewayap
var filters []*mesh_proto.GatewayRoute_HttpRoute_Filter

for _, filter := range rule.Filters {
kumaFilter, err := gapiToKumaFilter(namespace, filter)
kumaFilter, err := r.gapiToKumaFilter(ctx, mesh, namespace, filter)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 02cf866

Please sign in to comment.