github.com/cilium/cilium@v1.16.2/operator/pkg/gateway-api/routechecks/tlsroute.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package routechecks
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"reflect"
    10  	"time"
    11  
    12  	"github.com/sirupsen/logrus"
    13  	corev1 "k8s.io/api/core/v1"
    14  	k8serrors "k8s.io/apimachinery/pkg/api/errors"
    15  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    16  	"k8s.io/apimachinery/pkg/runtime/schema"
    17  	"sigs.k8s.io/controller-runtime/pkg/client"
    18  	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
    19  	gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2"
    20  	gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
    21  
    22  	"github.com/cilium/cilium/operator/pkg/gateway-api/helpers"
    23  )
    24  
    25  // TLSRouteInput is used to implement the Input interface for TLSRoute
    26  type TLSRouteInput struct {
    27  	Ctx      context.Context
    28  	Logger   *logrus.Entry
    29  	Client   client.Client
    30  	Grants   *gatewayv1beta1.ReferenceGrantList
    31  	TLSRoute *gatewayv1alpha2.TLSRoute
    32  
    33  	gateways map[gatewayv1.ParentReference]*gatewayv1.Gateway
    34  }
    35  
    36  func (t *TLSRouteInput) SetParentCondition(ref gatewayv1.ParentReference, condition metav1.Condition) {
    37  	// fill in the condition
    38  	condition.LastTransitionTime = metav1.NewTime(time.Now())
    39  	condition.ObservedGeneration = t.TLSRoute.GetGeneration()
    40  
    41  	t.mergeStatusConditions(ref, []metav1.Condition{
    42  		condition,
    43  	})
    44  }
    45  
    46  func (t *TLSRouteInput) SetAllParentCondition(condition metav1.Condition) {
    47  	// fill in the condition
    48  	condition.LastTransitionTime = metav1.NewTime(time.Now())
    49  	condition.ObservedGeneration = t.TLSRoute.GetGeneration()
    50  
    51  	for _, parent := range t.TLSRoute.Spec.ParentRefs {
    52  		t.mergeStatusConditions(parent, []metav1.Condition{
    53  			condition,
    54  		})
    55  	}
    56  }
    57  
    58  func (t *TLSRouteInput) mergeStatusConditions(parentRef gatewayv1alpha2.ParentReference, updates []metav1.Condition) {
    59  	index := -1
    60  	for i, parent := range t.TLSRoute.Status.RouteStatus.Parents {
    61  		if reflect.DeepEqual(parent.ParentRef, parentRef) {
    62  			index = i
    63  			break
    64  		}
    65  	}
    66  	if index != -1 {
    67  		t.TLSRoute.Status.RouteStatus.Parents[index].Conditions = merge(t.TLSRoute.Status.RouteStatus.Parents[index].Conditions, updates...)
    68  		return
    69  	}
    70  	t.TLSRoute.Status.RouteStatus.Parents = append(t.TLSRoute.Status.RouteStatus.Parents, gatewayv1alpha2.RouteParentStatus{
    71  		ParentRef:      parentRef,
    72  		ControllerName: controllerName,
    73  		Conditions:     updates,
    74  	})
    75  }
    76  
    77  func (t *TLSRouteInput) GetGrants() []gatewayv1beta1.ReferenceGrant {
    78  	return t.Grants.Items
    79  }
    80  
    81  func (t *TLSRouteInput) GetNamespace() string {
    82  	return t.TLSRoute.GetNamespace()
    83  }
    84  
    85  func (t *TLSRouteInput) GetGVK() schema.GroupVersionKind {
    86  	return gatewayv1alpha2.SchemeGroupVersion.WithKind("TLSRoute")
    87  }
    88  
    89  func (t *TLSRouteInput) GetRules() []GenericRule {
    90  	var rules []GenericRule
    91  	for _, rule := range t.TLSRoute.Spec.Rules {
    92  		rules = append(rules, &TLSRouteRule{rule})
    93  	}
    94  	return rules
    95  }
    96  
    97  func (t *TLSRouteInput) GetClient() client.Client {
    98  	return t.Client
    99  }
   100  
   101  func (t *TLSRouteInput) GetContext() context.Context {
   102  	return t.Ctx
   103  }
   104  
   105  // TLSRouteRule is used to implement the GenericRule interface for TLSRoute
   106  type TLSRouteRule struct {
   107  	Rule gatewayv1alpha2.TLSRouteRule
   108  }
   109  
   110  func (t *TLSRouteRule) GetBackendRefs() []gatewayv1.BackendRef {
   111  	return t.Rule.BackendRefs
   112  }
   113  
   114  func (t *TLSRouteInput) GetHostnames() []gatewayv1.Hostname {
   115  	return t.TLSRoute.Spec.Hostnames
   116  }
   117  
   118  func (t *TLSRouteInput) GetGateway(parent gatewayv1.ParentReference) (*gatewayv1.Gateway, error) {
   119  	if t.gateways == nil {
   120  		t.gateways = make(map[gatewayv1.ParentReference]*gatewayv1.Gateway)
   121  	}
   122  
   123  	if gw, exists := t.gateways[parent]; exists {
   124  		return gw, nil
   125  	}
   126  
   127  	ns := helpers.NamespaceDerefOr(parent.Namespace, t.GetNamespace())
   128  	gw := &gatewayv1.Gateway{}
   129  
   130  	if err := t.Client.Get(t.Ctx, client.ObjectKey{Namespace: ns, Name: string(parent.Name)}, gw); err != nil {
   131  		if !k8serrors.IsNotFound(err) {
   132  			// if it is not just a not found error, we should return the error as something is bad
   133  			return nil, fmt.Errorf("error while getting gateway: %w", err)
   134  		}
   135  
   136  		// Gateway does not exist skip further checks
   137  		return nil, fmt.Errorf("gateway %q does not exist: %w", parent.Name, err)
   138  	}
   139  
   140  	t.gateways[parent] = gw
   141  
   142  	return gw, nil
   143  }
   144  
   145  func (t *TLSRouteInput) GetParentGammaService(parent gatewayv1.ParentReference) (*corev1.Service, error) {
   146  	return nil, fmt.Errorf("GAMMA support is not implemented in this reconciler")
   147  }
   148  
   149  func (t *TLSRouteInput) Log() *logrus.Entry {
   150  	return t.Logger
   151  }