feat(ingress/annotation): support external service in the mirror annotations (#2679)

This commit is contained in:
xingpiaoliang
2025-07-30 21:15:35 +08:00
committed by GitHub
parent 93ea5e7355
commit 27680223b9
2 changed files with 109 additions and 13 deletions

View File

@@ -22,8 +22,10 @@ import (
) )
const ( const (
mirrorTargetService = "mirror-target-service" mirrorTargetService = "mirror-target-service"
mirrorPercentage = "mirror-percentage" mirrorPercentage = "mirror-percentage"
mirrorTargetFQDN = "mirror-target-fqdn"
mirrorTargetFQDNPort = "mirror-target-fqdn-port"
) )
var ( var (
@@ -34,6 +36,8 @@ var (
type MirrorConfig struct { type MirrorConfig struct {
util.ServiceInfo util.ServiceInfo
Percentage *wrappers.DoubleValue Percentage *wrappers.DoubleValue
FQDN string
FPort uint32 // Port for FQDN
} }
type mirror struct{} type mirror struct{}
@@ -43,6 +47,24 @@ func (m mirror) Parse(annotations Annotations, config *Ingress, globalContext *G
return nil return nil
} }
// if FQDN is set, then parse FQDN
if fqdn, err := annotations.ParseStringASAP(mirrorTargetFQDN); err == nil {
// default is 80
var port uint32
port = 80
if p, err := annotations.ParseInt32ASAP(mirrorTargetFQDNPort); err == nil {
port = uint32(p)
}
config.Mirror = &MirrorConfig{
Percentage: parsePercentage(annotations),
FQDN: fqdn,
FPort: port,
}
return nil
}
target, err := annotations.ParseStringASAP(mirrorTargetService) target, err := annotations.ParseStringASAP(mirrorTargetService)
if err != nil { if err != nil {
IngressLog.Errorf("Get mirror target service fail, err: %v", err) IngressLog.Errorf("Get mirror target service fail, err: %v", err)
@@ -78,7 +100,16 @@ func (m mirror) Parse(annotations Annotations, config *Ingress, globalContext *G
serviceInfo.Port = uint32(service.Spec.Ports[0].Port) serviceInfo.Port = uint32(service.Spec.Ports[0].Port)
} }
config.Mirror = &MirrorConfig{
ServiceInfo: serviceInfo,
Percentage: parsePercentage(annotations),
}
return nil
}
func parsePercentage(annotations Annotations) *wrappers.DoubleValue {
var percentage *wrappers.DoubleValue var percentage *wrappers.DoubleValue
if value, err := annotations.ParseIntASAP(mirrorPercentage); err == nil { if value, err := annotations.ParseIntASAP(mirrorPercentage); err == nil {
if value < 100 { if value < 100 {
percentage = &wrappers.DoubleValue{ percentage = &wrappers.DoubleValue{
@@ -86,12 +117,7 @@ func (m mirror) Parse(annotations Annotations, config *Ingress, globalContext *G
} }
} }
} }
return percentage
config.Mirror = &MirrorConfig{
ServiceInfo: serviceInfo,
Percentage: percentage,
}
return nil
} }
func (m mirror) ApplyRoute(route *networking.HTTPRoute, config *Ingress) { func (m mirror) ApplyRoute(route *networking.HTTPRoute, config *Ingress) {
@@ -99,10 +125,21 @@ func (m mirror) ApplyRoute(route *networking.HTTPRoute, config *Ingress) {
return return
} }
var mirrorHost string
var mirrorPort uint32
if config.Mirror.FQDN != "" {
mirrorHost = config.Mirror.FQDN
mirrorPort = config.Mirror.FPort
} else {
mirrorHost = util.CreateServiceFQDN(config.Mirror.Namespace, config.Mirror.Name)
mirrorPort = config.Mirror.Port
}
route.Mirror = &networking.Destination{ route.Mirror = &networking.Destination{
Host: util.CreateServiceFQDN(config.Mirror.Namespace, config.Mirror.Name), Host: mirrorHost,
Port: &networking.PortSelector{ Port: &networking.PortSelector{
Number: config.Mirror.Port, Number: mirrorPort,
}, },
} }
@@ -114,5 +151,5 @@ func (m mirror) ApplyRoute(route *networking.HTTPRoute, config *Ingress) {
} }
func needMirror(annotations Annotations) bool { func needMirror(annotations Annotations) bool {
return annotations.HasASAP(mirrorTargetService) return annotations.HasASAP(mirrorTargetService) || annotations.HasASAP(mirrorTargetFQDN)
} }

View File

@@ -15,12 +15,13 @@
package annotations package annotations
import ( import (
"reflect"
"testing"
"github.com/alibaba/higress/pkg/ingress/kube/util" "github.com/alibaba/higress/pkg/ingress/kube/util"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
networking "istio.io/api/networking/v1alpha3" networking "istio.io/api/networking/v1alpha3"
"istio.io/istio/pilot/pkg/model" "istio.io/istio/pilot/pkg/model"
"reflect"
"testing"
) )
func TestParseMirror(t *testing.T) { func TestParseMirror(t *testing.T) {
@@ -29,6 +30,28 @@ func TestParseMirror(t *testing.T) {
expect *MirrorConfig expect *MirrorConfig
}{ }{
{}, {},
{
input: []map[string]string{
{buildHigressAnnotationKey(mirrorTargetFQDN): "www.example.com"},
{buildNginxAnnotationKey(mirrorTargetFQDN): "www.example.com"},
},
expect: &MirrorConfig{
ServiceInfo: util.ServiceInfo{},
FQDN: "www.example.com",
FPort: 80,
},
},
{
input: []map[string]string{
{buildHigressAnnotationKey(mirrorTargetFQDN): "192.168.252.112", buildHigressAnnotationKey(mirrorTargetFQDNPort): "8080"},
{buildNginxAnnotationKey(mirrorTargetFQDN): "192.168.252.112", buildNginxAnnotationKey(mirrorTargetFQDNPort): "8080"},
},
expect: &MirrorConfig{
ServiceInfo: util.ServiceInfo{},
FQDN: "192.168.252.112",
FPort: 8080,
},
},
{ {
input: []map[string]string{ input: []map[string]string{
{buildHigressAnnotationKey(mirrorTargetService): "test/app"}, {buildHigressAnnotationKey(mirrorTargetService): "test/app"},
@@ -149,6 +172,42 @@ func TestMirror_ApplyRoute(t *testing.T) {
}, },
}, },
}, },
{
config: &Ingress{
Mirror: &MirrorConfig{
ServiceInfo: util.ServiceInfo{},
FQDN: "www.example.com",
FPort: 80,
},
},
input: &networking.HTTPRoute{},
expect: &networking.HTTPRoute{
Mirror: &networking.Destination{
Host: "www.example.com",
Port: &networking.PortSelector{
Number: 80,
},
},
},
},
{
config: &Ingress{
Mirror: &MirrorConfig{
ServiceInfo: util.ServiceInfo{},
FQDN: "192.168.252.112",
FPort: 8080,
},
},
input: &networking.HTTPRoute{},
expect: &networking.HTTPRoute{
Mirror: &networking.Destination{
Host: "192.168.252.112",
Port: &networking.PortSelector{
Number: 8080,
},
},
},
},
} }
mirror := mirror{} mirror := mirror{}