From 7716bfc5fe86ec12aa13a6d66bc9512d66a49f4e Mon Sep 17 00:00:00 2001 From: rongxin Date: Tue, 15 Apr 2025 08:07:00 +0800 Subject: [PATCH 01/10] feat: support translate backendtrafficpolicy CRD --- api/adc/types.go | 6 +- api/v1alpha1/backendtrafficpolicy_types.go | 8 +- api/v1alpha1/policies_type.go | 8 ++ api/v1alpha1/zz_generated.deepcopy.go | 46 +++++++- ...eway.apisix.io_backendtrafficpolicies.yaml | 2 + internal/controller/consumer_controller.go | 2 +- internal/controller/httproute_controller.go | 10 +- internal/controller/indexer/indexer.go | 31 +++++ internal/controller/ingress_controller.go | 20 ++-- internal/controller/policies.go | 108 ++++++++++++++++++ internal/controller/status.go | 44 +++++++ internal/provider/adc/translator/httproute.go | 10 +- internal/provider/adc/translator/ingress.go | 2 + internal/provider/adc/translator/policies.go | 60 ++++++++++ internal/provider/provider.go | 33 +++--- 15 files changed, 345 insertions(+), 45 deletions(-) create mode 100644 api/v1alpha1/policies_type.go create mode 100644 internal/controller/policies.go create mode 100644 internal/provider/adc/translator/policies.go diff --git a/api/adc/types.go b/api/adc/types.go index 2e510b7f4..2ad73a998 100644 --- a/api/adc/types.go +++ b/api/adc/types.go @@ -128,9 +128,9 @@ type Route struct { } type Timeout struct { - Connect float64 `json:"connect"` - Read float64 `json:"read"` - Send float64 `json:"send"` + Connect *int64 `json:"connect,omitempty"` + Read *int64 `json:"read,omitempty"` + Send *int64 `json:"send,omitempty"` } type StreamRoute struct { diff --git a/api/v1alpha1/backendtrafficpolicy_types.go b/api/v1alpha1/backendtrafficpolicy_types.go index 2bdf5b553..3cf4ad767 100644 --- a/api/v1alpha1/backendtrafficpolicy_types.go +++ b/api/v1alpha1/backendtrafficpolicy_types.go @@ -2,8 +2,6 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" ) // +kubebuilder:object:root=true @@ -12,8 +10,8 @@ type BackendTrafficPolicy struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec BackendTrafficPolicySpec `json:"spec,omitempty"` - Status gatewayv1alpha2.PolicyStatus `json:"status,omitempty"` + Spec BackendTrafficPolicySpec `json:"spec,omitempty"` + Status PolicyStatus `json:"status,omitempty"` } type BackendTrafficPolicySpec struct { @@ -27,7 +25,7 @@ type BackendTrafficPolicySpec struct { // +listMapKey=name // +kubebuilder:validation:MinItems=1 // +kubebuilder:validation:MaxItems=16 - TargetRefs []gatewayv1alpha2.LocalPolicyTargetReferenceWithSectionName `json:"targetRefs"` + TargetRefs []BackendPolicyTargetReferenceWithSectionName `json:"targetRefs"` // LoadBalancer represents the load balancer configuration for Kubernetes Service. // The default strategy is round robin. LoadBalancer *LoadBalancer `json:"loadbalancer,omitempty" yaml:"loadbalancer,omitempty"` diff --git a/api/v1alpha1/policies_type.go b/api/v1alpha1/policies_type.go new file mode 100644 index 000000000..527226e4f --- /dev/null +++ b/api/v1alpha1/policies_type.go @@ -0,0 +1,8 @@ +package v1alpha1 + +import gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + +type PolicyStatus gatewayv1alpha2.PolicyStatus + +// +kubebuilder:validation:XValidation:rule="self.kind == 'Service' && self.group == \"\"" +type BackendPolicyTargetReferenceWithSectionName gatewayv1alpha2.LocalPolicyTargetReferenceWithSectionName diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 04ff10e12..8f4a5b117 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -25,6 +25,7 @@ import ( "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + apisv1 "sigs.k8s.io/gateway-api/apis/v1" "sigs.k8s.io/gateway-api/apis/v1alpha2" ) @@ -68,6 +69,27 @@ func (in *AdminKeyValueFrom) DeepCopy() *AdminKeyValueFrom { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BackendPolicyTargetReferenceWithSectionName) DeepCopyInto(out *BackendPolicyTargetReferenceWithSectionName) { + *out = *in + out.LocalPolicyTargetReference = in.LocalPolicyTargetReference + if in.SectionName != nil { + in, out := &in.SectionName, &out.SectionName + *out = new(apisv1.SectionName) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendPolicyTargetReferenceWithSectionName. +func (in *BackendPolicyTargetReferenceWithSectionName) DeepCopy() *BackendPolicyTargetReferenceWithSectionName { + if in == nil { + return nil + } + out := new(BackendPolicyTargetReferenceWithSectionName) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BackendTrafficPolicy) DeepCopyInto(out *BackendTrafficPolicy) { *out = *in @@ -132,7 +154,7 @@ func (in *BackendTrafficPolicySpec) DeepCopyInto(out *BackendTrafficPolicySpec) *out = *in if in.TargetRefs != nil { in, out := &in.TargetRefs, &out.TargetRefs - *out = make([]v1alpha2.LocalPolicyTargetReferenceWithSectionName, len(*in)) + *out = make([]BackendPolicyTargetReferenceWithSectionName, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } @@ -688,6 +710,28 @@ func (in *PluginConfigSpec) DeepCopy() *PluginConfigSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PolicyStatus) DeepCopyInto(out *PolicyStatus) { + *out = *in + if in.Ancestors != nil { + in, out := &in.Ancestors, &out.Ancestors + *out = make([]v1alpha2.PolicyAncestorStatus, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PolicyStatus. +func (in *PolicyStatus) DeepCopy() *PolicyStatus { + if in == nil { + return nil + } + out := new(PolicyStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretKeySelector) DeepCopyInto(out *SecretKeySelector) { *out = *in diff --git a/config/crd/bases/gateway.apisix.io_backendtrafficpolicies.yaml b/config/crd/bases/gateway.apisix.io_backendtrafficpolicies.yaml index 3e325bf7f..2d3130080 100644 --- a/config/crd/bases/gateway.apisix.io_backendtrafficpolicies.yaml +++ b/config/crd/bases/gateway.apisix.io_backendtrafficpolicies.yaml @@ -153,6 +153,8 @@ spec: - kind - name type: object + x-kubernetes-validations: + - rule: self.kind == 'Service' && self.group == "" maxItems: 16 minItems: 1 type: array diff --git a/internal/controller/consumer_controller.go b/internal/controller/consumer_controller.go index 1d5054aca..2ef6e30e2 100644 --- a/internal/controller/consumer_controller.go +++ b/internal/controller/consumer_controller.go @@ -136,7 +136,7 @@ func (r *ConsumerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c } var statusErr error - tctx := provider.NewDefaultTranslateContext() + tctx := provider.NewDefaultTranslateContext(ctx) if err := r.processSpec(ctx, tctx, consumer); err != nil { r.Log.Error(err, "failed to process consumer spec", "consumer", consumer) diff --git a/internal/controller/httproute_controller.go b/internal/controller/httproute_controller.go index afe21a884..bc33dd79b 100644 --- a/internal/controller/httproute_controller.go +++ b/internal/controller/httproute_controller.go @@ -112,7 +112,7 @@ func (r *HTTPRouteReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( return ctrl.Result{}, nil } - tctx := provider.NewDefaultTranslateContext() + tctx := provider.NewDefaultTranslateContext(ctx) if err := r.processHTTPRoute(tctx, hr); err != nil { acceptStatus.status = false @@ -249,7 +249,7 @@ func (r *HTTPRouteReconciler) processHTTPRouteBackendRefs(tctx *provider.Transla } var service corev1.Service - if err := r.Get(context.TODO(), client.ObjectKey{ + if err := r.Get(tctx, client.ObjectKey{ Namespace: namespace, Name: name, }, &service); err != nil { @@ -268,9 +268,13 @@ func (r *HTTPRouteReconciler) processHTTPRouteBackendRefs(tctx *provider.Transla terr = fmt.Errorf("port %d not found in service %s", *backend.Port, name) continue } + tctx.Services[client.ObjectKey{ + Namespace: namespace, + Name: name, + }] = &service endpointSliceList := new(discoveryv1.EndpointSliceList) - if err := r.List(context.TODO(), endpointSliceList, + if err := r.List(tctx, endpointSliceList, client.InNamespace(namespace), client.MatchingLabels{ discoveryv1.LabelServiceName: name, diff --git a/internal/controller/indexer/indexer.go b/internal/controller/indexer/indexer.go index 5b20ea121..f07024dd4 100644 --- a/internal/controller/indexer/indexer.go +++ b/internal/controller/indexer/indexer.go @@ -5,6 +5,8 @@ import ( "github.com/api7/api7-ingress-controller/api/v1alpha1" networkingv1 "k8s.io/api/networking/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" @@ -19,6 +21,7 @@ const ( SecretIndexRef = "secretRefs" IngressClassRef = "ingressClassRef" ConsumerGatewayRef = "consumerGatewayRef" + PolicyTargetRefs = "targetRefs" ) func SetupIndexer(mgr ctrl.Manager) error { @@ -227,6 +230,18 @@ func IngressSecretIndexFunc(rawObj client.Object) []string { return secrets } +func GenIndexKeyWithGK(group, kind, namespace, name string) string { + gvk := schema.GroupKind{ + Group: group, + Kind: kind, + } + nsName := types.NamespacedName{ + Namespace: namespace, + Name: name, + } + return gvk.String() + "/" + nsName.String() +} + func GenIndexKey(namespace, name string) string { return client.ObjectKey{ Namespace: namespace, @@ -292,3 +307,19 @@ func GatewayParametersRefIndexFunc(rawObj client.Object) []string { } return nil } + +func BackendTrafficPolicyIndexFunc(rawObj client.Object) []string { + btp := rawObj.(*v1alpha1.BackendTrafficPolicy) + keys := make([]string, 0, len(btp.Spec.TargetRefs)) + for _, ref := range btp.Spec.TargetRefs { + keys = append(keys, + GenIndexKeyWithGK( + v1alpha1.GroupVersion.Group, + string(ref.Kind), + btp.GetNamespace(), + string(ref.Name), + ), + ) + } + return keys +} diff --git a/internal/controller/ingress_controller.go b/internal/controller/ingress_controller.go index 2e1636eed..ac22a0ea7 100644 --- a/internal/controller/ingress_controller.go +++ b/internal/controller/ingress_controller.go @@ -93,16 +93,16 @@ func (r *IngressReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct r.Log.Info("reconciling ingress", "ingress", ingress.Name) // create a translate context - tctx := provider.NewDefaultTranslateContext() + tctx := provider.NewDefaultTranslateContext(ctx) // process TLS configuration - if err := r.processTLS(ctx, tctx, ingress); err != nil { + if err := r.processTLS(tctx, ingress); err != nil { r.Log.Error(err, "failed to process TLS configuration", "ingress", ingress.Name) return ctrl.Result{}, err } // process backend services - if err := r.processBackends(ctx, tctx, ingress); err != nil { + if err := r.processBackends(tctx, ingress); err != nil { r.Log.Error(err, "failed to process backend services", "ingress", ingress.Name) return ctrl.Result{}, err } @@ -295,14 +295,14 @@ func (r *IngressReconciler) listIngressesBySecret(ctx context.Context, obj clien } // processTLS process the TLS configuration of the ingress -func (r *IngressReconciler) processTLS(ctx context.Context, tctx *provider.TranslateContext, ingress *networkingv1.Ingress) error { +func (r *IngressReconciler) processTLS(tctx *provider.TranslateContext, ingress *networkingv1.Ingress) error { for _, tls := range ingress.Spec.TLS { if tls.SecretName == "" { continue } secret := corev1.Secret{} - if err := r.Get(ctx, client.ObjectKey{ + if err := r.Get(tctx, client.ObjectKey{ Namespace: ingress.Namespace, Name: tls.SecretName, }, &secret); err != nil { @@ -323,7 +323,7 @@ func (r *IngressReconciler) processTLS(ctx context.Context, tctx *provider.Trans } // processBackends process the backend services of the ingress -func (r *IngressReconciler) processBackends(ctx context.Context, tctx *provider.TranslateContext, ingress *networkingv1.Ingress) error { +func (r *IngressReconciler) processBackends(tctx *provider.TranslateContext, ingress *networkingv1.Ingress) error { var terr error // process all the backend services in the rules @@ -336,7 +336,7 @@ func (r *IngressReconciler) processBackends(ctx context.Context, tctx *provider. continue } service := path.Backend.Service - if err := r.processBackendService(ctx, tctx, ingress.Namespace, service); err != nil { + if err := r.processBackendService(tctx, ingress.Namespace, service); err != nil { terr = err } } @@ -345,10 +345,10 @@ func (r *IngressReconciler) processBackends(ctx context.Context, tctx *provider. } // processBackendService process a single backend service -func (r *IngressReconciler) processBackendService(ctx context.Context, tctx *provider.TranslateContext, namespace string, backendService *networkingv1.IngressServiceBackend) error { +func (r *IngressReconciler) processBackendService(tctx *provider.TranslateContext, namespace string, backendService *networkingv1.IngressServiceBackend) error { // get the service var service corev1.Service - if err := r.Get(ctx, client.ObjectKey{ + if err := r.Get(tctx, client.ObjectKey{ Namespace: namespace, Name: backendService.Name, }, &service); err != nil { @@ -385,7 +385,7 @@ func (r *IngressReconciler) processBackendService(ctx context.Context, tctx *pro // get the endpoint slices endpointSliceList := &discoveryv1.EndpointSliceList{} - if err := r.List(ctx, endpointSliceList, + if err := r.List(tctx, endpointSliceList, client.InNamespace(namespace), client.MatchingLabels{ discoveryv1.LabelServiceName: backendService.Name, diff --git a/internal/controller/policies.go b/internal/controller/policies.go new file mode 100644 index 000000000..9a457011d --- /dev/null +++ b/internal/controller/policies.go @@ -0,0 +1,108 @@ +package controller + +import ( + "fmt" + + gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" + gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + + "github.com/api7/api7-ingress-controller/api/v1alpha1" + "github.com/api7/api7-ingress-controller/internal/controller/config" + "github.com/api7/api7-ingress-controller/internal/controller/indexer" + "github.com/api7/api7-ingress-controller/internal/provider" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type PolicyTargetKey struct { + NsName types.NamespacedName + GroupKind schema.GroupKind +} + +func (p PolicyTargetKey) String() string { + return p.NsName.String() + "/" + p.GroupKind.String() +} + +func ProcessBackendTrafficPolicy(c client.Client, tctx *provider.TranslateContext) { + conflicts := map[string]v1alpha1.BackendTrafficPolicy{} + for _, service := range tctx.Services { + backendTrafficPolicyList := &v1alpha1.BackendTrafficPolicyList{} + if err := c.List(tctx, backendTrafficPolicyList, + client.MatchingFields{ + indexer.PolicyTargetRefs: indexer.GenIndexKeyWithGK("", "Service", service.Namespace, service.Name), + }, + ); err != nil { + if client.IgnoreNotFound(err) == nil { + continue + } + return + } + if len(backendTrafficPolicyList.Items) == 0 { + continue + } + + portNameExist := make(map[string]bool, len(service.Spec.Ports)) + for _, port := range service.Spec.Ports { + portNameExist[port.Name] = true + } + for _, policy := range backendTrafficPolicyList.Items { + targetRefs := policy.Spec.TargetRefs + for _, targetRef := range targetRefs { + sectionName := targetRef.SectionName + key := PolicyTargetKey{ + NsName: types.NamespacedName{Namespace: service.Namespace, Name: service.Name}, + GroupKind: schema.GroupKind{Group: "", Kind: "Service"}, + } + condition := NewPolicyCondition(policy.Generation, true, "Policy has been accepted") + if sectionName != nil && !portNameExist[string(*sectionName)] { + condition = NewPolicyCondition(policy.Generation, false, fmt.Sprintf("SectionName %s not found in Service %s/%s", *sectionName, service.Namespace, service.Name)) + goto record_status + } + if p, ok := conflicts[key.String()]; ok && (p.Name == policy.Name && p.Namespace != policy.Namespace) { + condition = NewPolicyConflictCondition(policy.Generation, fmt.Sprintf("Unable to target Service %s/%s with BackendTrafficPolicy %s/%s", service.Namespace, service.Name, policy.Namespace, policy.Name)) + goto record_status + } + conflicts[key.String()] = policy + record_status: + if ok := SetAncestors(&policy.Status, tctx.ParentRefs, condition); ok { + tctx.StatusUpdaters = append(tctx.StatusUpdaters, policy.DeepCopy()) + } + } + + tctx.BackendTrafficPolicies[types.NamespacedName{ + Name: policy.Name, + Namespace: policy.Namespace, + }] = policy.DeepCopy() + } + } +} +func SetAncestors(status *v1alpha1.PolicyStatus, parentRefs []gatewayv1.ParentReference, condition metav1.Condition) bool { + updated := false + for _, parent := range parentRefs { + ancestorStatus := gatewayv1alpha2.PolicyAncestorStatus{ + AncestorRef: parent, + Conditions: []metav1.Condition{condition}, + ControllerName: gatewayv1alpha2.GatewayController(config.ControllerConfig.ControllerName), + } + if SetAncestorStatus(status, ancestorStatus) { + updated = true + } + } + return updated +} + +func SetAncestorStatus(status *v1alpha1.PolicyStatus, ancestorStatus gatewayv1alpha2.PolicyAncestorStatus) bool { + for _, c := range status.Ancestors { + if c.AncestorRef == ancestorStatus.AncestorRef { + if c.Conditions[0].ObservedGeneration < ancestorStatus.Conditions[0].ObservedGeneration { + c.Conditions = ancestorStatus.Conditions + return true + } + return false + } + } + status.Ancestors = append(status.Ancestors, ancestorStatus) + return true +} diff --git a/internal/controller/status.go b/internal/controller/status.go index d60e2616b..cae419995 100644 --- a/internal/controller/status.go +++ b/internal/controller/status.go @@ -1,8 +1,12 @@ package controller import ( + "github.com/api7/api7-ingress-controller/internal/provider" + "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + gatewayv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" ) const ( @@ -44,3 +48,43 @@ func VerifyConditions(conditions *[]metav1.Condition, newCondition metav1.Condit } return true } + +func NewPolicyCondition(observedGeneration int64, status bool, message string) metav1.Condition { + conditionStatus := metav1.ConditionTrue + reason := string(gatewayv1alpha2.PolicyReasonAccepted) + if !status { + conditionStatus = metav1.ConditionFalse + reason = string(gatewayv1alpha2.PolicyReasonInvalid) + } + + return metav1.Condition{ + Type: string(gatewayv1alpha2.PolicyConditionAccepted), + Reason: reason, + Status: conditionStatus, + Message: message, + ObservedGeneration: observedGeneration, + } +} + +func NewPolicyConflictCondition(observedGeneration int64, message string) metav1.Condition { + return metav1.Condition{ + Type: string(gatewayv1alpha2.PolicyConditionAccepted), + Reason: string(gatewayv1alpha2.PolicyReasonConflicted), + Status: metav1.ConditionFalse, + Message: message, + ObservedGeneration: observedGeneration, + } +} + +func UpdateStatus( + c client.Client, + log logr.Logger, + tctx *provider.TranslateContext, +) { + for _, obj := range tctx.StatusUpdaters { + if err := c.Status().Update(tctx, obj); err != nil { + log.Error(err, "failed to update status", "object", obj) + continue + } + } +} diff --git a/internal/provider/adc/translator/httproute.go b/internal/provider/adc/translator/httproute.go index 8dea67a97..37dc9687a 100644 --- a/internal/provider/adc/translator/httproute.go +++ b/internal/provider/adc/translator/httproute.go @@ -290,15 +290,7 @@ func (t *Translator) TranslateHTTPRoute(tctx *provider.TranslateContext, httpRou upNodes := t.translateBackendRef(tctx, backend.BackendRef) upstream.Nodes = append(upstream.Nodes, upNodes...) } - if len(upstream.Nodes) == 0 { - upstream.Nodes = adctypes.UpstreamNodes{ - { - Host: "0.0.0.0", - Port: 80, - Weight: 1, - }, - } - } + t.attachBackendTrafficPolicyToUpstream(nil, upstream) // todo: support multiple backends service := adctypes.NewDefaultService() diff --git a/internal/provider/adc/translator/ingress.go b/internal/provider/adc/translator/ingress.go index 19cc09034..fa0ca853c 100644 --- a/internal/provider/adc/translator/ingress.go +++ b/internal/provider/adc/translator/ingress.go @@ -109,6 +109,8 @@ func (t *Translator) TranslateIngress(tctx *provider.TranslateContext, obj *netw Name: backendService.Name, }] + t.attachBackendTrafficPolicyToUpstream(nil, upstream) + // get the service port configuration var servicePort int32 = 0 var servicePortName string diff --git a/internal/provider/adc/translator/policies.go b/internal/provider/adc/translator/policies.go new file mode 100644 index 000000000..07024f566 --- /dev/null +++ b/internal/provider/adc/translator/policies.go @@ -0,0 +1,60 @@ +package translator + +import ( + "github.com/api7/api7-ingress-controller/api/adc" + "github.com/api7/api7-ingress-controller/api/v1alpha1" + "k8s.io/apimachinery/pkg/types" + + adctypes "github.com/api7/api7-ingress-controller/api/adc" +) + +func (t *Translator) AttachBackendTrafficPolicyToUpstream(policies map[types.NamespacedName]*v1alpha1.BackendTrafficPolicy, upstream *adctypes.Upstream) { + if len(policies) == 0 { + return + } + for _, policy := range policies { + t.attachBackendTrafficPolicyToUpstream(policy, upstream) + } + +} + +func (t *Translator) attachBackendTrafficPolicyToUpstream(policy *v1alpha1.BackendTrafficPolicy, upstream *adctypes.Upstream) { + if policy == nil { + return + } + upstream.UpstreamHost = string(policy.Spec.Host) + upstream.Scheme = policy.Spec.Scheme + if policy.Spec.Retries != nil { + upstream.Retries = new(int64) + *upstream.Retries = int64(*policy.Spec.Retries) + } + if policy.Spec.Timeout != nil { + var ( + connect *int64 + read *int64 + send *int64 + ) + if policy.Spec.Timeout.Connect.Duration > 0 { + connect = new(int64) + *connect = policy.Spec.Timeout.Connect.Duration.Milliseconds() + } + if policy.Spec.Timeout.Read.Duration > 0 { + read = new(int64) + *read = policy.Spec.Timeout.Read.Duration.Milliseconds() + } + if policy.Spec.Timeout.Send.Duration > 0 { + send = new(int64) + *send = policy.Spec.Timeout.Send.Duration.Milliseconds() + } + upstream.Timeout = &adctypes.Timeout{ + Connect: connect, + Read: read, + Send: send, + } + } + if policy.Spec.LoadBalancer != nil { + upstream.Type = adc.UpstreamType(policy.Spec.LoadBalancer.Type) + upstream.HashOn = policy.Spec.LoadBalancer.HashOn + upstream.Key = policy.Spec.LoadBalancer.Key + } +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index a57675f27..395d7eaa7 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -18,21 +18,28 @@ type Provider interface { } type TranslateContext struct { - BackendRefs []gatewayv1.BackendRef - GatewayTLSConfig []gatewayv1.GatewayTLSConfig - GatewayProxy *v1alpha1.GatewayProxy - Credentials []v1alpha1.Credential - EndpointSlices map[types.NamespacedName][]discoveryv1.EndpointSlice - Secrets map[types.NamespacedName]*corev1.Secret - PluginConfigs map[types.NamespacedName]*v1alpha1.PluginConfig - Services map[types.NamespacedName]*corev1.Service + context.Context + ParentRefs []gatewayv1.ParentReference + BackendRefs []gatewayv1.BackendRef + GatewayTLSConfig []gatewayv1.GatewayTLSConfig + GatewayProxy *v1alpha1.GatewayProxy + Credentials []v1alpha1.Credential + EndpointSlices map[types.NamespacedName][]discoveryv1.EndpointSlice + Secrets map[types.NamespacedName]*corev1.Secret + PluginConfigs map[types.NamespacedName]*v1alpha1.PluginConfig + Services map[types.NamespacedName]*corev1.Service + BackendTrafficPolicies map[types.NamespacedName]*v1alpha1.BackendTrafficPolicy + + StatusUpdaters []client.Object } -func NewDefaultTranslateContext() *TranslateContext { +func NewDefaultTranslateContext(ctx context.Context) *TranslateContext { return &TranslateContext{ - EndpointSlices: make(map[types.NamespacedName][]discoveryv1.EndpointSlice), - Secrets: make(map[types.NamespacedName]*corev1.Secret), - PluginConfigs: make(map[types.NamespacedName]*v1alpha1.PluginConfig), - Services: make(map[types.NamespacedName]*corev1.Service), + Context: ctx, + EndpointSlices: make(map[types.NamespacedName][]discoveryv1.EndpointSlice), + Secrets: make(map[types.NamespacedName]*corev1.Secret), + PluginConfigs: make(map[types.NamespacedName]*v1alpha1.PluginConfig), + Services: make(map[types.NamespacedName]*corev1.Service), + BackendTrafficPolicies: make(map[types.NamespacedName]*v1alpha1.BackendTrafficPolicy), } } From 0a99a0b26c5d880b784d30039b2337fc2d86c37f Mon Sep 17 00:00:00 2001 From: rongxin Date: Tue, 15 Apr 2025 11:01:09 +0800 Subject: [PATCH 02/10] fix status --- internal/controller/policies.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/internal/controller/policies.go b/internal/controller/policies.go index 9a457011d..16d4dcb81 100644 --- a/internal/controller/policies.go +++ b/internal/controller/policies.go @@ -49,6 +49,7 @@ func ProcessBackendTrafficPolicy(c client.Client, tctx *provider.TranslateContex } for _, policy := range backendTrafficPolicyList.Items { targetRefs := policy.Spec.TargetRefs + updated := false for _, targetRef := range targetRefs { sectionName := targetRef.SectionName key := PolicyTargetKey{ @@ -60,16 +61,26 @@ func ProcessBackendTrafficPolicy(c client.Client, tctx *provider.TranslateContex condition = NewPolicyCondition(policy.Generation, false, fmt.Sprintf("SectionName %s not found in Service %s/%s", *sectionName, service.Namespace, service.Name)) goto record_status } - if p, ok := conflicts[key.String()]; ok && (p.Name == policy.Name && p.Namespace != policy.Namespace) { - condition = NewPolicyConflictCondition(policy.Generation, fmt.Sprintf("Unable to target Service %s/%s with BackendTrafficPolicy %s/%s", service.Namespace, service.Name, policy.Namespace, policy.Name)) + if p, ok := conflicts[key.String()]; ok && (p.Name == policy.Name && p.Namespace == policy.Namespace) { + condition = NewPolicyConflictCondition(policy.Generation, fmt.Sprintf("Unable to target Service %s/%s, because it conflicts with another BackendTrafficPolicy", service.Namespace, service.Name)) goto record_status } conflicts[key.String()] = policy record_status: if ok := SetAncestors(&policy.Status, tctx.ParentRefs, condition); ok { - tctx.StatusUpdaters = append(tctx.StatusUpdaters, policy.DeepCopy()) + updated = true } } + if _, ok := tctx.BackendTrafficPolicies[types.NamespacedName{ + Name: policy.Name, + Namespace: policy.Namespace, + }]; ok { + continue + } + + if updated { + tctx.StatusUpdaters = append(tctx.StatusUpdaters, policy.DeepCopy()) + } tctx.BackendTrafficPolicies[types.NamespacedName{ Name: policy.Name, From 9223a02569e2f66b59e93029578bfdaf25aff671 Mon Sep 17 00:00:00 2001 From: AlinsRan Date: Tue, 15 Apr 2025 09:17:55 +0000 Subject: [PATCH 03/10] fix --- api/adc/types.go | 6 +-- api/v1alpha1/backendtrafficpolicy_types.go | 7 ++- ...eway.apisix.io_backendtrafficpolicies.yaml | 3 ++ internal/controller/indexer/indexer.go | 17 ++++++- internal/controller/policies.go | 11 +++-- internal/provider/adc/translator/policies.go | 46 +++++++++---------- 6 files changed, 55 insertions(+), 35 deletions(-) diff --git a/api/adc/types.go b/api/adc/types.go index 2ad73a998..2c9bede84 100644 --- a/api/adc/types.go +++ b/api/adc/types.go @@ -128,9 +128,9 @@ type Route struct { } type Timeout struct { - Connect *int64 `json:"connect,omitempty"` - Read *int64 `json:"read,omitempty"` - Send *int64 `json:"send,omitempty"` + Connect int64 `json:"connect"` + Read int64 `json:"read"` + Send int64 `json:"send"` } type StreamRoute struct { diff --git a/api/v1alpha1/backendtrafficpolicy_types.go b/api/v1alpha1/backendtrafficpolicy_types.go index 3cf4ad767..6477bd38f 100644 --- a/api/v1alpha1/backendtrafficpolicy_types.go +++ b/api/v1alpha1/backendtrafficpolicy_types.go @@ -72,9 +72,12 @@ type LoadBalancer struct { } type Timeout struct { + // +kubebuilder:default="60s" Connect metav1.Duration `json:"connect,omitempty" yaml:"connect,omitempty"` - Send metav1.Duration `json:"send,omitempty" yaml:"send,omitempty"` - Read metav1.Duration `json:"read,omitempty" yaml:"read,omitempty"` + // +kubebuilder:default="60s" + Send metav1.Duration `json:"send,omitempty" yaml:"send,omitempty"` + // +kubebuilder:default="60s" + Read metav1.Duration `json:"read,omitempty" yaml:"read,omitempty"` } // +kubebuilder:object:root=true diff --git a/config/crd/bases/gateway.apisix.io_backendtrafficpolicies.yaml b/config/crd/bases/gateway.apisix.io_backendtrafficpolicies.yaml index 2d3130080..a76601cd5 100644 --- a/config/crd/bases/gateway.apisix.io_backendtrafficpolicies.yaml +++ b/config/crd/bases/gateway.apisix.io_backendtrafficpolicies.yaml @@ -168,10 +168,13 @@ spec: upstream. properties: connect: + default: 60s type: string read: + default: 60s type: string send: + default: 60s type: string type: object upstream_host: diff --git a/internal/controller/indexer/indexer.go b/internal/controller/indexer/indexer.go index f07024dd4..f245e2374 100644 --- a/internal/controller/indexer/indexer.go +++ b/internal/controller/indexer/indexer.go @@ -37,6 +37,9 @@ func SetupIndexer(mgr ctrl.Manager) error { if err := setupConsumerIndexer(mgr); err != nil { return err } + if err := setupBackendTrafficPolicyIndexer(mgr); err != nil { + return err + } return nil } @@ -178,6 +181,18 @@ func setupIngressIndexer(mgr ctrl.Manager) error { return nil } +func setupBackendTrafficPolicyIndexer(mgr ctrl.Manager) error { + if err := mgr.GetFieldIndexer().IndexField( + context.Background(), + &v1alpha1.BackendTrafficPolicy{}, + PolicyTargetRefs, + BackendTrafficPolicyIndexFunc, + ); err != nil { + return err + } + return nil +} + func IngressClassIndexFunc(rawObj client.Object) []string { ingressClass := rawObj.(*networkingv1.IngressClass) if ingressClass.Spec.Controller == "" { @@ -314,7 +329,7 @@ func BackendTrafficPolicyIndexFunc(rawObj client.Object) []string { for _, ref := range btp.Spec.TargetRefs { keys = append(keys, GenIndexKeyWithGK( - v1alpha1.GroupVersion.Group, + string(ref.Group), string(ref.Kind), btp.GetNamespace(), string(ref.Name), diff --git a/internal/controller/policies.go b/internal/controller/policies.go index 16d4dcb81..7a9e870df 100644 --- a/internal/controller/policies.go +++ b/internal/controller/policies.go @@ -10,6 +10,7 @@ import ( "github.com/api7/api7-ingress-controller/internal/controller/config" "github.com/api7/api7-ingress-controller/internal/controller/indexer" "github.com/api7/api7-ingress-controller/internal/provider" + "github.com/go-logr/logr" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" @@ -25,7 +26,9 @@ func (p PolicyTargetKey) String() string { return p.NsName.String() + "/" + p.GroupKind.String() } -func ProcessBackendTrafficPolicy(c client.Client, tctx *provider.TranslateContext) { +func ProcessBackendTrafficPolicy(c client.Client, + log logr.Logger, + tctx *provider.TranslateContext) { conflicts := map[string]v1alpha1.BackendTrafficPolicy{} for _, service := range tctx.Services { backendTrafficPolicyList := &v1alpha1.BackendTrafficPolicyList{} @@ -34,10 +37,8 @@ func ProcessBackendTrafficPolicy(c client.Client, tctx *provider.TranslateContex indexer.PolicyTargetRefs: indexer.GenIndexKeyWithGK("", "Service", service.Namespace, service.Name), }, ); err != nil { - if client.IgnoreNotFound(err) == nil { - continue - } - return + log.Error(err, "failed to list BackendTrafficPolicy for Service") + continue } if len(backendTrafficPolicyList.Items) == 0 { continue diff --git a/internal/provider/adc/translator/policies.go b/internal/provider/adc/translator/policies.go index 07024f566..894180756 100644 --- a/internal/provider/adc/translator/policies.go +++ b/internal/provider/adc/translator/policies.go @@ -3,19 +3,34 @@ package translator import ( "github.com/api7/api7-ingress-controller/api/adc" "github.com/api7/api7-ingress-controller/api/v1alpha1" + "github.com/api7/gopkg/pkg/log" + "go.uber.org/zap" "k8s.io/apimachinery/pkg/types" + gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" adctypes "github.com/api7/api7-ingress-controller/api/adc" ) -func (t *Translator) AttachBackendTrafficPolicyToUpstream(policies map[types.NamespacedName]*v1alpha1.BackendTrafficPolicy, upstream *adctypes.Upstream) { +func (t *Translator) AttachBackendTrafficPolicyToUpstream(ref gatewayv1.BackendRef, policies map[types.NamespacedName]*v1alpha1.BackendTrafficPolicy, upstream *adctypes.Upstream) { if len(policies) == 0 { return } - for _, policy := range policies { - t.attachBackendTrafficPolicyToUpstream(policy, upstream) + var policy *v1alpha1.BackendTrafficPolicy + for _, po := range policies { + for _, targetRef := range po.Spec.TargetRefs { + if ref.Name == targetRef.Name && + (ref.Namespace != nil && string(*ref.Namespace) == po.Namespace) { + policy = po + break + } + } } - + if policy == nil { + return + } + log.Errorw("attach backend traffic policy to upstream", + zap.String("policy", policy.Name)) + t.attachBackendTrafficPolicyToUpstream(policy, upstream) } func (t *Translator) attachBackendTrafficPolicyToUpstream(policy *v1alpha1.BackendTrafficPolicy, upstream *adctypes.Upstream) { @@ -29,27 +44,10 @@ func (t *Translator) attachBackendTrafficPolicyToUpstream(policy *v1alpha1.Backe *upstream.Retries = int64(*policy.Spec.Retries) } if policy.Spec.Timeout != nil { - var ( - connect *int64 - read *int64 - send *int64 - ) - if policy.Spec.Timeout.Connect.Duration > 0 { - connect = new(int64) - *connect = policy.Spec.Timeout.Connect.Duration.Milliseconds() - } - if policy.Spec.Timeout.Read.Duration > 0 { - read = new(int64) - *read = policy.Spec.Timeout.Read.Duration.Milliseconds() - } - if policy.Spec.Timeout.Send.Duration > 0 { - send = new(int64) - *send = policy.Spec.Timeout.Send.Duration.Milliseconds() - } upstream.Timeout = &adctypes.Timeout{ - Connect: connect, - Read: read, - Send: send, + Connect: policy.Spec.Timeout.Connect.Duration.Milliseconds(), + Read: policy.Spec.Timeout.Read.Duration.Milliseconds(), + Send: policy.Spec.Timeout.Send.Duration.Milliseconds(), } } if policy.Spec.LoadBalancer != nil { From a935f15fa407124994fc4ae46686a7603ff4442e Mon Sep 17 00:00:00 2001 From: AlinsRan Date: Tue, 15 Apr 2025 09:25:15 +0000 Subject: [PATCH 04/10] remove debug log --- internal/provider/adc/translator/policies.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/internal/provider/adc/translator/policies.go b/internal/provider/adc/translator/policies.go index 894180756..90b579fb7 100644 --- a/internal/provider/adc/translator/policies.go +++ b/internal/provider/adc/translator/policies.go @@ -3,8 +3,6 @@ package translator import ( "github.com/api7/api7-ingress-controller/api/adc" "github.com/api7/api7-ingress-controller/api/v1alpha1" - "github.com/api7/gopkg/pkg/log" - "go.uber.org/zap" "k8s.io/apimachinery/pkg/types" gatewayv1 "sigs.k8s.io/gateway-api/apis/v1" @@ -28,8 +26,6 @@ func (t *Translator) AttachBackendTrafficPolicyToUpstream(ref gatewayv1.BackendR if policy == nil { return } - log.Errorw("attach backend traffic policy to upstream", - zap.String("policy", policy.Name)) t.attachBackendTrafficPolicyToUpstream(policy, upstream) } From 12ac6dbe7c12e371b75e64614628748a0fb3759c Mon Sep 17 00:00:00 2001 From: AlinsRan Date: Tue, 15 Apr 2025 10:21:00 +0000 Subject: [PATCH 05/10] add rbac --- test/e2e/framework/manifests/ingress.yaml | 30 +++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/e2e/framework/manifests/ingress.yaml b/test/e2e/framework/manifests/ingress.yaml index 0a7296821..207916c2c 100644 --- a/test/e2e/framework/manifests/ingress.yaml +++ b/test/e2e/framework/manifests/ingress.yaml @@ -106,6 +106,21 @@ rules: - get - list - watch +- apiGroups: + - gateway.apisix.io + resources: + - backendtrafficpolicies + verbs: + - get + - list + - watch +- apiGroups: + - gateway.apisix.io + resources: + - backendtrafficpolicies/status + verbs: + - get + - update - apiGroups: - gateway.apisix.io resources: @@ -129,6 +144,21 @@ rules: - get - list - watch +- apiGroups: + - gateway.apisix.io + resources: + - httproutepolicies + verbs: + - get + - list + - watch +- apiGroups: + - gateway.apisix.io + resources: + - httproutepolicies/status + verbs: + - get + - update - apiGroups: - gateway.apisix.io resources: From eff13dafc8f8ba8526e2e96bfe213583d4996931 Mon Sep 17 00:00:00 2001 From: AlinsRan Date: Tue, 15 Apr 2025 10:23:23 +0000 Subject: [PATCH 06/10] fix test --- internal/controller/indexer/indexer.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/internal/controller/indexer/indexer.go b/internal/controller/indexer/indexer.go index f245e2374..f2cb1a7d4 100644 --- a/internal/controller/indexer/indexer.go +++ b/internal/controller/indexer/indexer.go @@ -37,9 +37,11 @@ func SetupIndexer(mgr ctrl.Manager) error { if err := setupConsumerIndexer(mgr); err != nil { return err } - if err := setupBackendTrafficPolicyIndexer(mgr); err != nil { - return err - } + /* + if err := setupBackendTrafficPolicyIndexer(mgr); err != nil { + return err + } + */ return nil } From c9fa9f4a4c2a13b9bb175f563b5419cc639caa0c Mon Sep 17 00:00:00 2001 From: AlinsRan Date: Wed, 16 Apr 2025 00:30:01 +0000 Subject: [PATCH 07/10] fix lint --- internal/controller/indexer/indexer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/controller/indexer/indexer.go b/internal/controller/indexer/indexer.go index f2cb1a7d4..2709793d1 100644 --- a/internal/controller/indexer/indexer.go +++ b/internal/controller/indexer/indexer.go @@ -183,7 +183,7 @@ func setupIngressIndexer(mgr ctrl.Manager) error { return nil } -func setupBackendTrafficPolicyIndexer(mgr ctrl.Manager) error { +func SetupBackendTrafficPolicyIndexer(mgr ctrl.Manager) error { if err := mgr.GetFieldIndexer().IndexField( context.Background(), &v1alpha1.BackendTrafficPolicy{}, From 31522577d6d6b70882db21f5c4a898378c799782 Mon Sep 17 00:00:00 2001 From: rongxin Date: Wed, 16 Apr 2025 16:06:48 +0800 Subject: [PATCH 08/10] resolve coment --- api/adc/types.go | 6 +++--- internal/controller/policies.go | 16 ++++++++++------ internal/provider/adc/translator/policies.go | 6 +++--- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/api/adc/types.go b/api/adc/types.go index 2c9bede84..2e510b7f4 100644 --- a/api/adc/types.go +++ b/api/adc/types.go @@ -128,9 +128,9 @@ type Route struct { } type Timeout struct { - Connect int64 `json:"connect"` - Read int64 `json:"read"` - Send int64 `json:"send"` + Connect float64 `json:"connect"` + Read float64 `json:"read"` + Send float64 `json:"send"` } type StreamRoute struct { diff --git a/internal/controller/policies.go b/internal/controller/policies.go index 7a9e870df..e19511186 100644 --- a/internal/controller/policies.go +++ b/internal/controller/policies.go @@ -60,17 +60,17 @@ func ProcessBackendTrafficPolicy(c client.Client, condition := NewPolicyCondition(policy.Generation, true, "Policy has been accepted") if sectionName != nil && !portNameExist[string(*sectionName)] { condition = NewPolicyCondition(policy.Generation, false, fmt.Sprintf("SectionName %s not found in Service %s/%s", *sectionName, service.Namespace, service.Name)) - goto record_status + if ok := SetAncestors(&policy.Status, tctx.ParentRefs, condition); ok { + updated = true + } } if p, ok := conflicts[key.String()]; ok && (p.Name == policy.Name && p.Namespace == policy.Namespace) { condition = NewPolicyConflictCondition(policy.Generation, fmt.Sprintf("Unable to target Service %s/%s, because it conflicts with another BackendTrafficPolicy", service.Namespace, service.Name)) - goto record_status + if ok := SetAncestors(&policy.Status, tctx.ParentRefs, condition); ok { + updated = true + } } conflicts[key.String()] = policy - record_status: - if ok := SetAncestors(&policy.Status, tctx.ParentRefs, condition); ok { - updated = true - } } if _, ok := tctx.BackendTrafficPolicies[types.NamespacedName{ Name: policy.Name, @@ -108,6 +108,10 @@ func SetAncestors(status *v1alpha1.PolicyStatus, parentRefs []gatewayv1.ParentRe func SetAncestorStatus(status *v1alpha1.PolicyStatus, ancestorStatus gatewayv1alpha2.PolicyAncestorStatus) bool { for _, c := range status.Ancestors { if c.AncestorRef == ancestorStatus.AncestorRef { + if len(c.Conditions) == 0 || len(ancestorStatus.Conditions) == 0 { + c.Conditions = ancestorStatus.Conditions + return true + } if c.Conditions[0].ObservedGeneration < ancestorStatus.Conditions[0].ObservedGeneration { c.Conditions = ancestorStatus.Conditions return true diff --git a/internal/provider/adc/translator/policies.go b/internal/provider/adc/translator/policies.go index 90b579fb7..1ed0c0081 100644 --- a/internal/provider/adc/translator/policies.go +++ b/internal/provider/adc/translator/policies.go @@ -41,9 +41,9 @@ func (t *Translator) attachBackendTrafficPolicyToUpstream(policy *v1alpha1.Backe } if policy.Spec.Timeout != nil { upstream.Timeout = &adctypes.Timeout{ - Connect: policy.Spec.Timeout.Connect.Duration.Milliseconds(), - Read: policy.Spec.Timeout.Read.Duration.Milliseconds(), - Send: policy.Spec.Timeout.Send.Duration.Milliseconds(), + Connect: policy.Spec.Timeout.Connect.Duration.Seconds(), + Read: policy.Spec.Timeout.Read.Duration.Seconds(), + Send: policy.Spec.Timeout.Send.Duration.Seconds(), } } if policy.Spec.LoadBalancer != nil { From 065133b65b6b900ca24706f4352396663070ff5f Mon Sep 17 00:00:00 2001 From: rongxin Date: Wed, 16 Apr 2025 16:27:18 +0800 Subject: [PATCH 09/10] f2 --- internal/controller/policies.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/internal/controller/policies.go b/internal/controller/policies.go index e19511186..ee1770fa8 100644 --- a/internal/controller/policies.go +++ b/internal/controller/policies.go @@ -60,17 +60,16 @@ func ProcessBackendTrafficPolicy(c client.Client, condition := NewPolicyCondition(policy.Generation, true, "Policy has been accepted") if sectionName != nil && !portNameExist[string(*sectionName)] { condition = NewPolicyCondition(policy.Generation, false, fmt.Sprintf("SectionName %s not found in Service %s/%s", *sectionName, service.Namespace, service.Name)) - if ok := SetAncestors(&policy.Status, tctx.ParentRefs, condition); ok { - updated = true - } + processPolicyStatus(&policy, tctx, condition, &updated) + continue } if p, ok := conflicts[key.String()]; ok && (p.Name == policy.Name && p.Namespace == policy.Namespace) { condition = NewPolicyConflictCondition(policy.Generation, fmt.Sprintf("Unable to target Service %s/%s, because it conflicts with another BackendTrafficPolicy", service.Namespace, service.Name)) - if ok := SetAncestors(&policy.Status, tctx.ParentRefs, condition); ok { - updated = true - } + processPolicyStatus(&policy, tctx, condition, &updated) + continue } conflicts[key.String()] = policy + processPolicyStatus(&policy, tctx, condition, &updated) } if _, ok := tctx.BackendTrafficPolicies[types.NamespacedName{ Name: policy.Name, @@ -90,6 +89,16 @@ func ProcessBackendTrafficPolicy(c client.Client, } } } + +func processPolicyStatus(policy *v1alpha1.BackendTrafficPolicy, + tctx *provider.TranslateContext, + condition metav1.Condition, + updated *bool) { + if ok := SetAncestors(&policy.Status, tctx.ParentRefs, condition); ok { + *updated = true + } +} + func SetAncestors(status *v1alpha1.PolicyStatus, parentRefs []gatewayv1.ParentReference, condition metav1.Condition) bool { updated := false for _, parent := range parentRefs { From 8663b8297d3847589afc78a4851da4150884fd77 Mon Sep 17 00:00:00 2001 From: rongxin Date: Wed, 16 Apr 2025 16:29:11 +0800 Subject: [PATCH 10/10] f3 --- api/v1alpha1/backendtrafficpolicy_types.go | 4 ---- .../crd/bases/gateway.apisix.io_backendtrafficpolicies.yaml | 5 ----- 2 files changed, 9 deletions(-) diff --git a/api/v1alpha1/backendtrafficpolicy_types.go b/api/v1alpha1/backendtrafficpolicy_types.go index 6477bd38f..3d438349d 100644 --- a/api/v1alpha1/backendtrafficpolicy_types.go +++ b/api/v1alpha1/backendtrafficpolicy_types.go @@ -19,10 +19,6 @@ type BackendTrafficPolicySpec struct { // Currently, Backends (i.e. Service, ServiceImport, or any // implementation-specific backendRef) are the only valid API // target references. - // +listType=map - // +listMapKey=group - // +listMapKey=kind - // +listMapKey=name // +kubebuilder:validation:MinItems=1 // +kubebuilder:validation:MaxItems=16 TargetRefs []BackendPolicyTargetReferenceWithSectionName `json:"targetRefs"` diff --git a/config/crd/bases/gateway.apisix.io_backendtrafficpolicies.yaml b/config/crd/bases/gateway.apisix.io_backendtrafficpolicies.yaml index a76601cd5..99e2fdea4 100644 --- a/config/crd/bases/gateway.apisix.io_backendtrafficpolicies.yaml +++ b/config/crd/bases/gateway.apisix.io_backendtrafficpolicies.yaml @@ -158,11 +158,6 @@ spec: maxItems: 16 minItems: 1 type: array - x-kubernetes-list-map-keys: - - group - - kind - - name - x-kubernetes-list-type: map timeout: description: Timeout settings for the read, send and connect to the upstream.