This is an automated email from the ASF dual-hosted git repository.
alexstocks pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-go-pixiu.git
The following commit(s) were added to refs/heads/develop by this push:
new 9b15a875 Service Name Mapping (#543)
9b15a875 is described below
commit 9b15a87505a183487261876d59224f5ab718cdd1
Author: Mark4z <[email protected]>
AuthorDate: Fri Mar 24 10:41:12 2023 +0800
Service Name Mapping (#543)
* snp init
* istio build tools
* istio build tools
* license
* license
* add snp resource
* add snp resource
* snp push_context.go
* fix deploy pilot
* fix make gen
* rollback delete dir
* fix mac gocache permission
* snp push_context.go
* open dev & fix snp
* open dev
* snp register
* snp register
* snp register
* snp register
* snp register debounce
* Add GracefulShutdown Signal For Windows (#522)
* Add GracefulShutdown Signal
* fix format
* update shutdown signal & close wasm for windows
Co-authored-by: mark4z <[email protected]>
* add and modify nacos config arguments (#524)
* Update bootstrap.go
* Update config_load.go
* add snp clusterrole
* add snp clusterrole
* imports format
* imports format
* update dingding group img
* replace operator-api
* fmt
* rm Dockerfile
* do not start debounce on snp server not init.
* refactor func tryRegister
* refactor func debounce
* docs for debounce
* snp support multi namespace
* snp support multi namespace
* snp support multi namespace
* snp support multi namespace
---------
Co-authored-by: bobtthp <[email protected]>
Co-authored-by: bobtthp <[email protected]>
Co-authored-by: Nanno <[email protected]>
Co-authored-by: happyjack <[email protected]>
---
go.mod | 6 +-
go.sum | 8 +-
manifests/charts/base/crds/crd-all.gen.yaml | 60 ++++
manifests/charts/base/files/gen-istio-cluster.yaml | 60 ++++
.../istio-discovery/templates/clusterrole.yaml | 5 +
.../istiod-remote/templates/crd-all.gen.yaml | 60 ++++
pilot/pkg/bootstrap/server.go | 18 ++
pilot/pkg/config/kube/crdclient/gen/main.go | 1 +
pilot/pkg/config/kube/crdclient/types.gen.go | 52 ++++
pilot/pkg/features/pilot.go | 22 ++
pilot/pkg/model/push_context.go | 79 +++++-
pilot/pkg/model/push_context_test.go | 2 +-
.../dubbo/v1alpha1/servicenamemappingserver.go | 308 +++++++++++++++++++++
.../v1alpha1/servicenamemappingserver_test.go | 161 +++++++++++
pilot/pkg/networking/dubbogen/dubbogen.go | 41 +++
.../pkg/networking/dubbogen/servicenamemapping.go | 117 ++++++++
pilot/pkg/xds/ads.go | 4 +-
pilot/pkg/xds/discovery.go | 4 +
pilot/pkg/xds/discovery_test.go | 63 +++++
pilot/pkg/xds/v3/model.go | 3 +-
pixiu/pkg/prometheus/prometheus.go | 2 +-
.../schema/collections/collections.agent.gen.go | 22 ++
pkg/config/schema/collections/collections.gen.go | 22 ++
pkg/config/schema/gvk/resources.gen.go | 1 +
pkg/config/schema/metadata.yaml | 15 +
25 files changed, 1125 insertions(+), 11 deletions(-)
diff --git a/go.mod b/go.mod
index e1a3f0aa..bd07e835 100644
--- a/go.mod
+++ b/go.mod
@@ -8,6 +8,10 @@ exclude k8s.io/kubernetes v1.13.0
// Client-go does not handle different versions of mergo due to some breaking
changes - use the matching version
replace github.com/imdario/mergo => github.com/imdario/mergo v0.3.5
+replace istio.io/api => github.com/dubbo-go-pixiu/operator-api
v0.0.0-20221126054223-dda83ac319f4
+
+replace istio.io/client-go => github.com/dubbo-go-pixiu/operator-client-go
v1.14.6-0.20221126073212-882e30cca8f6
+
require (
cloud.google.com/go/compute v1.6.0
cloud.google.com/go/security v1.3.0
@@ -121,7 +125,7 @@ require (
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
helm.sh/helm/v3 v3.10.3
- istio.io/api v0.0.0-20220906212632-fa18ce1fc2da
+ istio.io/api v0.0.0-20221004225839-607aeaab2827
istio.io/client-go v1.14.4-0.20220906213432-736be6f83263
istio.io/pkg v0.0.0-20220906212832-f98e656e3df0
k8s.io/api v0.25.2
diff --git a/go.sum b/go.sum
index cc000084..db3e4689 100644
--- a/go.sum
+++ b/go.sum
@@ -528,6 +528,10 @@ github.com/docker/go-units v0.4.0/go.mod
h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod
h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod
h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod
h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
+github.com/dubbo-go-pixiu/operator-api v0.0.0-20221126054223-dda83ac319f4
h1:De7KZcGzrgYado/wA7PDBntNemkR7iYaO36gQagYYQY=
+github.com/dubbo-go-pixiu/operator-api
v0.0.0-20221126054223-dda83ac319f4/go.mod
h1:SWsRqLbdc3vFk5cIRylKHC28nx58hfikw2rjlpwR0Qs=
+github.com/dubbo-go-pixiu/operator-client-go
v1.14.6-0.20221126073212-882e30cca8f6
h1:GD5OCtBql9xl+UnWY+E7P4NCJBWyE+pE/JjY0jW+F8Y=
+github.com/dubbo-go-pixiu/operator-client-go
v1.14.6-0.20221126073212-882e30cca8f6/go.mod
h1:If8h1tIkt2k4P4hKsnQxR8m2bUF2hZBpfLP6VyaFO+g=
github.com/dubbo-go-pixiu/pixiu-api v0.1.6-0.20220612115254-d9a176b25b99
h1:UjDxgIEu6DbJVJTrxm5mwC0j54jNao1pkYVlT8X+KgY=
github.com/dubbo-go-pixiu/pixiu-api
v0.1.6-0.20220612115254-d9a176b25b99/go.mod
h1:1l+6pDTdEHwCyyyJmfckOAdGp6f5PZ33ZVMgxso9q/U=
github.com/dubbogo/go-zookeeper v1.0.3/go.mod
h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c=
@@ -2844,10 +2848,6 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod
h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
honnef.co/go/tools v0.0.1-2020.1.3/go.mod
h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod
h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.2.1/go.mod
h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY=
-istio.io/api v0.0.0-20220906212632-fa18ce1fc2da
h1:7Guipik1xjlsNAYyCsi0arsgNh2wqVdaNzW5Ba5noMw=
-istio.io/api v0.0.0-20220906212632-fa18ce1fc2da/go.mod
h1:00myJeQGWma4Y5pboJ+MM4P2uqEWulKA1duC8kYN5Wo=
-istio.io/client-go v1.14.4-0.20220906213432-736be6f83263
h1:4HEex3Q+PHftOkp94/K74ikFmUSzKvSlLZ9Mtrvp1eI=
-istio.io/client-go v1.14.4-0.20220906213432-736be6f83263/go.mod
h1:asShg/RoAW4pRK9zWmZGXgw6bt1YMRiCQZvBZoCW0Ic=
istio.io/pkg v0.0.0-20220906212832-f98e656e3df0
h1:OxnCRBQq2VIS/tqVIaNkTqSMGiI9TEsW28nBwmHdB5s=
istio.io/pkg v0.0.0-20220906212832-f98e656e3df0/go.mod
h1:kcBYN5TiyGFM2bs4b7K81j+YeDZ4JrINP+brV9ehZe0=
k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78=
diff --git a/manifests/charts/base/crds/crd-all.gen.yaml
b/manifests/charts/base/crds/crd-all.gen.yaml
index 043bdb62..dc04ae97 100644
--- a/manifests/charts/base/crds/crd-all.gen.yaml
+++ b/manifests/charts/base/crds/crd-all.gen.yaml
@@ -1,6 +1,66 @@
# DO NOT EDIT - Generated by Cue OpenAPI generator based on Istio APIs.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
+metadata:
+ annotations:
+ "helm.sh/resource-policy": keep
+ labels:
+ app: istio-pilot
+ chart: istio
+ heritage: Tiller
+ release: istio
+ name: servicenamemappings.extensions.istio.io
+spec:
+ group: extensions.istio.io
+ names:
+ categories:
+ - istio-io
+ - extensions-istio-io
+ kind: ServiceNameMapping
+ listKind: ServiceNameMappingList
+ plural: servicenamemappings
+ shortNames:
+ - snp
+ singular: servicenamemapping
+ scope: Namespaced
+ versions:
+ - additionalPrinterColumns:
+ - description: 'CreationTimestamp is a timestamp representing the server
time
+ when this object was created. It is not guaranteed to be set in
happens-before
+ order across separate operations. Clients may not set this value. It
is represented
+ in RFC3339 form and is in UTC. Populated by the system. Read-only.
Null for
+ lists. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata'
+ jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ properties:
+ spec:
+ description: 'it''s the spec of Service Name Mapping, which is
used to
+ map the interface name See more details at:'
+ properties:
+ applicationNames:
+ items:
+ type: string
+ type: array
+ interfaceName:
+ description: InterfaceName.
+ type: string
+ type: object
+ status:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
metadata:
annotations:
"helm.sh/resource-policy": keep
diff --git a/manifests/charts/base/files/gen-istio-cluster.yaml
b/manifests/charts/base/files/gen-istio-cluster.yaml
index 4192c313..06cd7846 100644
--- a/manifests/charts/base/files/gen-istio-cluster.yaml
+++ b/manifests/charts/base/files/gen-istio-cluster.yaml
@@ -3,6 +3,66 @@
# DO NOT EDIT - Generated by Cue OpenAPI generator based on Istio APIs.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
+metadata:
+ annotations:
+ "helm.sh/resource-policy": keep
+ labels:
+ app: istio-pilot
+ chart: istio
+ heritage: Tiller
+ release: istio
+ name: servicenamemappings.extensions.istio.io
+spec:
+ group: extensions.istio.io
+ names:
+ categories:
+ - istio-io
+ - extensions-istio-io
+ kind: ServiceNameMapping
+ listKind: ServiceNameMappingList
+ plural: servicenamemappings
+ shortNames:
+ - snp
+ singular: servicenamemapping
+ scope: Namespaced
+ versions:
+ - additionalPrinterColumns:
+ - description: 'CreationTimestamp is a timestamp representing the server
time
+ when this object was created. It is not guaranteed to be set in
happens-before
+ order across separate operations. Clients may not set this value. It
is represented
+ in RFC3339 form and is in UTC. Populated by the system. Read-only.
Null for
+ lists. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata'
+ jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ properties:
+ spec:
+ description: 'it''s the spec of Service Name Mapping, which is
used to
+ map the interface name See more details at:'
+ properties:
+ applicationNames:
+ items:
+ type: string
+ type: array
+ interfaceName:
+ description: InterfaceName.
+ type: string
+ type: object
+ status:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
metadata:
annotations:
"helm.sh/resource-policy": keep
diff --git
a/manifests/charts/istio-control/istio-discovery/templates/clusterrole.yaml
b/manifests/charts/istio-control/istio-discovery/templates/clusterrole.yaml
index 4848fd37..ad408ed2 100644
--- a/manifests/charts/istio-control/istio-discovery/templates/clusterrole.yaml
+++ b/manifests/charts/istio-control/istio-discovery/templates/clusterrole.yaml
@@ -119,6 +119,11 @@ rules:
- apiGroups: ["{{ $mcsAPIGroup }}"]
resources: ["serviceimports"]
verbs: ["get", "watch", "list"]
+
+ # Used for Service Name Mapping
+ - apiGroups: ["extensions.istio.io"]
+ resources: ["servicenamemappings"]
+ verbs: [ "get", "watch", "list", "update", "patch", "create", "delete" ]
---
{{- if not (eq (toString
.Values.pilot.env.PILOT_ENABLE_GATEWAY_API_DEPLOYMENT_CONTROLLER) "false") }}
apiVersion: rbac.authorization.k8s.io/v1
diff --git a/manifests/charts/istiod-remote/templates/crd-all.gen.yaml
b/manifests/charts/istiod-remote/templates/crd-all.gen.yaml
index 775e53a7..f5f05073 100644
--- a/manifests/charts/istiod-remote/templates/crd-all.gen.yaml
+++ b/manifests/charts/istiod-remote/templates/crd-all.gen.yaml
@@ -2,6 +2,66 @@
# DO NOT EDIT - Generated by Cue OpenAPI generator based on Istio APIs.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
+metadata:
+ annotations:
+ "helm.sh/resource-policy": keep
+ labels:
+ app: istio-pilot
+ chart: istio
+ heritage: Tiller
+ release: istio
+ name: servicenamemappings.extensions.istio.io
+spec:
+ group: extensions.istio.io
+ names:
+ categories:
+ - istio-io
+ - extensions-istio-io
+ kind: ServiceNameMapping
+ listKind: ServiceNameMappingList
+ plural: servicenamemappings
+ shortNames:
+ - snp
+ singular: servicenamemapping
+ scope: Namespaced
+ versions:
+ - additionalPrinterColumns:
+ - description: 'CreationTimestamp is a timestamp representing the server
time
+ when this object was created. It is not guaranteed to be set in
happens-before
+ order across separate operations. Clients may not set this value. It
is represented
+ in RFC3339 form and is in UTC. Populated by the system. Read-only.
Null for
+ lists. More info:
https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata'
+ jsonPath: .metadata.creationTimestamp
+ name: Age
+ type: date
+ name: v1alpha1
+ schema:
+ openAPIV3Schema:
+ properties:
+ spec:
+ description: 'it''s the spec of Service Name Mapping, which is
used to
+ map the interface name See more details at:'
+ properties:
+ applicationNames:
+ items:
+ type: string
+ type: array
+ interfaceName:
+ description: InterfaceName.
+ type: string
+ type: object
+ status:
+ type: object
+ x-kubernetes-preserve-unknown-fields: true
+ type: object
+ served: true
+ storage: true
+ subresources:
+ status: {}
+
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
metadata:
annotations:
"helm.sh/resource-policy": keep
diff --git a/pilot/pkg/bootstrap/server.go b/pilot/pkg/bootstrap/server.go
index 38cbfae7..fc2da178 100644
--- a/pilot/pkg/bootstrap/server.go
+++ b/pilot/pkg/bootstrap/server.go
@@ -54,6 +54,7 @@ import (
istiogrpc "github.com/apache/dubbo-go-pixiu/pilot/pkg/grpc"
"github.com/apache/dubbo-go-pixiu/pilot/pkg/keycertbundle"
"github.com/apache/dubbo-go-pixiu/pilot/pkg/model"
+ dubbov1alpha1
"github.com/apache/dubbo-go-pixiu/pilot/pkg/networking/dubbo/v1alpha1"
"github.com/apache/dubbo-go-pixiu/pilot/pkg/server"
"github.com/apache/dubbo-go-pixiu/pilot/pkg/serviceregistry/aggregate"
kubecontroller
"github.com/apache/dubbo-go-pixiu/pilot/pkg/serviceregistry/kube/controller"
@@ -178,6 +179,9 @@ type Server struct {
statusManager *status.Manager
// RWConfigStore is the configstore which allows updates, particularly
for status.
RWConfigStore model.ConfigStoreController
+
+ //Service Name mapping register
+ snpServer *dubbov1alpha1.Snp
}
// NewServer creates a new Server instance based on the provided arguments.
@@ -273,6 +277,11 @@ func NewServer(args *PilotArgs, initFuncs
...func(*Server)) (*Server, error) {
return nil, err
}
+ // Create Service Name mapping server
+ if s.kubeClient != nil {
+ s.snpServer = dubbov1alpha1.NewSnp(s.kubeClient)
+ }
+
// Secure gRPC Server must be initialized after CA is created as may
use a Citadel generated cert.
if err := s.initSecureDiscoveryService(args); err != nil {
return nil, fmt.Errorf("error initializing secure gRPC
Listener: %v", err)
@@ -647,6 +656,13 @@ func (s *Server) initDiscoveryService(args *PilotArgs) {
return nil
})
+ // Implement ServiceNameMapping grace shutdown
+ s.addStartFunc(func(stop <-chan struct{}) error {
+ log.Infof("Starting ADS server")
+ s.snpServer.Start(stop)
+ return nil
+ })
+
s.initGrpcServer(args.KeepaliveOptions)
if args.ServerOptions.GRPCAddr != "" {
@@ -729,6 +745,7 @@ func (s *Server) initGrpcServer(options
*istiokeepalive.Options) {
s.grpcServer = grpc.NewServer(grpcOptions...)
s.XDSServer.Register(s.grpcServer)
reflection.Register(s.grpcServer)
+ s.snpServer.Register(s.grpcServer)
}
// initialize secureGRPCServer.
@@ -777,6 +794,7 @@ func (s *Server) initSecureDiscoveryService(args
*PilotArgs) error {
s.secureGrpcServer = grpc.NewServer(opts...)
s.XDSServer.Register(s.secureGrpcServer)
reflection.Register(s.secureGrpcServer)
+ s.snpServer.Register(s.secureGrpcServer)
s.addStartFunc(func(stop <-chan struct{}) error {
go func() {
diff --git a/pilot/pkg/config/kube/crdclient/gen/main.go
b/pilot/pkg/config/kube/crdclient/gen/main.go
index cb78839f..fac0e734 100644
--- a/pilot/pkg/config/kube/crdclient/gen/main.go
+++ b/pilot/pkg/config/kube/crdclient/gen/main.go
@@ -164,6 +164,7 @@ var (
"nodes": "Nodes",
"secrets": "Secrets",
"ingresses": "Ingresses",
+ "servicenamemappings": "ServiceNameMappings",
}
noSpec = map[string]struct{}{
diff --git a/pilot/pkg/config/kube/crdclient/types.gen.go
b/pilot/pkg/config/kube/crdclient/types.gen.go
index d4a5a6d7..728a56d5 100644
--- a/pilot/pkg/config/kube/crdclient/types.gen.go
+++ b/pilot/pkg/config/kube/crdclient/types.gen.go
@@ -58,6 +58,11 @@ import (
func create(ic versionedclient.Interface, sc gatewayapiclient.Interface, cfg
config.Config, objMeta metav1.ObjectMeta) (metav1.Object, error) {
switch cfg.GroupVersionKind {
+ case
collections.IstioExtensionsV1Alpha1Servicenamemappings.Resource().GroupVersionKind():
+ return
ic.ExtensionsV1alpha1().ServiceNameMappings(cfg.Namespace).Create(context.TODO(),
&clientextensionsv1alpha1.ServiceNameMapping{
+ ObjectMeta: objMeta,
+ Spec:
*(cfg.Spec.(*extensionsv1alpha1.ServiceNameMapping)),
+ }, metav1.CreateOptions{})
case
collections.IstioExtensionsV1Alpha1Wasmplugins.Resource().GroupVersionKind():
return
ic.ExtensionsV1alpha1().WasmPlugins(cfg.Namespace).Create(context.TODO(),
&clientextensionsv1alpha1.WasmPlugin{
ObjectMeta: objMeta,
@@ -165,6 +170,11 @@ func create(ic versionedclient.Interface, sc
gatewayapiclient.Interface, cfg con
func update(ic versionedclient.Interface, sc gatewayapiclient.Interface, cfg
config.Config, objMeta metav1.ObjectMeta) (metav1.Object, error) {
switch cfg.GroupVersionKind {
+ case
collections.IstioExtensionsV1Alpha1Servicenamemappings.Resource().GroupVersionKind():
+ return
ic.ExtensionsV1alpha1().ServiceNameMappings(cfg.Namespace).Update(context.TODO(),
&clientextensionsv1alpha1.ServiceNameMapping{
+ ObjectMeta: objMeta,
+ Spec:
*(cfg.Spec.(*extensionsv1alpha1.ServiceNameMapping)),
+ }, metav1.UpdateOptions{})
case
collections.IstioExtensionsV1Alpha1Wasmplugins.Resource().GroupVersionKind():
return
ic.ExtensionsV1alpha1().WasmPlugins(cfg.Namespace).Update(context.TODO(),
&clientextensionsv1alpha1.WasmPlugin{
ObjectMeta: objMeta,
@@ -273,6 +283,12 @@ func update(ic versionedclient.Interface, sc
gatewayapiclient.Interface, cfg con
func updateStatus(ic versionedclient.Interface, sc gatewayapiclient.Interface,
cfg config.Config, objMeta metav1.ObjectMeta) (metav1.Object, error) {
switch cfg.GroupVersionKind {
+ case
collections.IstioExtensionsV1Alpha1Servicenamemappings.Resource().GroupVersionKind():
+ return
ic.ExtensionsV1alpha1().ServiceNameMappings(cfg.Namespace).UpdateStatus(context.TODO(),
&clientextensionsv1alpha1.ServiceNameMapping{
+ ObjectMeta: objMeta,
+ Status: *(cfg.Status.(*metav1alpha1.IstioStatus)),
+ }, metav1.UpdateOptions{})
+
case
collections.IstioExtensionsV1Alpha1Wasmplugins.Resource().GroupVersionKind():
return
ic.ExtensionsV1alpha1().WasmPlugins(cfg.Namespace).UpdateStatus(context.TODO(),
&clientextensionsv1alpha1.WasmPlugin{
ObjectMeta: objMeta,
@@ -397,6 +413,21 @@ func patch(ic versionedclient.Interface, sc
gatewayapiclient.Interface, orig con
}
// TODO support setting field manager
switch orig.GroupVersionKind {
+ case
collections.IstioExtensionsV1Alpha1Servicenamemappings.Resource().GroupVersionKind():
+ oldRes := &clientextensionsv1alpha1.ServiceNameMapping{
+ ObjectMeta: origMeta,
+ Spec:
*(orig.Spec.(*extensionsv1alpha1.ServiceNameMapping)),
+ }
+ modRes := &clientextensionsv1alpha1.ServiceNameMapping{
+ ObjectMeta: modMeta,
+ Spec:
*(mod.Spec.(*extensionsv1alpha1.ServiceNameMapping)),
+ }
+ patchBytes, err := genPatchBytes(oldRes, modRes, typ)
+ if err != nil {
+ return nil, err
+ }
+ return
ic.ExtensionsV1alpha1().ServiceNameMappings(orig.Namespace).
+ Patch(context.TODO(), orig.Name, typ, patchBytes,
metav1.PatchOptions{FieldManager: "pilot-discovery"})
case
collections.IstioExtensionsV1Alpha1Wasmplugins.Resource().GroupVersionKind():
oldRes := &clientextensionsv1alpha1.WasmPlugin{
ObjectMeta: origMeta,
@@ -708,6 +739,8 @@ func delete(ic versionedclient.Interface, sc
gatewayapiclient.Interface, typ con
deleteOptions.Preconditions =
&metav1.Preconditions{ResourceVersion: resourceVersion}
}
switch typ {
+ case
collections.IstioExtensionsV1Alpha1Servicenamemappings.Resource().GroupVersionKind():
+ return
ic.ExtensionsV1alpha1().ServiceNameMappings(namespace).Delete(context.TODO(),
name, deleteOptions)
case
collections.IstioExtensionsV1Alpha1Wasmplugins.Resource().GroupVersionKind():
return
ic.ExtensionsV1alpha1().WasmPlugins(namespace).Delete(context.TODO(), name,
deleteOptions)
case
collections.IstioNetworkingV1Alpha3Destinationrules.Resource().GroupVersionKind():
@@ -754,6 +787,25 @@ func delete(ic versionedclient.Interface, sc
gatewayapiclient.Interface, typ con
}
var translationMap = map[config.GroupVersionKind]func(r runtime.Object)
config.Config{
+
collections.IstioExtensionsV1Alpha1Servicenamemappings.Resource().GroupVersionKind():
func(r runtime.Object) config.Config {
+ obj := r.(*clientextensionsv1alpha1.ServiceNameMapping)
+ return config.Config{
+ Meta: config.Meta{
+ GroupVersionKind:
collections.IstioExtensionsV1Alpha1Servicenamemappings.Resource().GroupVersionKind(),
+ Name: obj.Name,
+ Namespace: obj.Namespace,
+ Labels: obj.Labels,
+ Annotations: obj.Annotations,
+ ResourceVersion: obj.ResourceVersion,
+ CreationTimestamp: obj.CreationTimestamp.Time,
+ OwnerReferences: obj.OwnerReferences,
+ UID: string(obj.UID),
+ Generation: obj.Generation,
+ },
+ Spec: &obj.Spec,
+ Status: &obj.Status,
+ }
+ },
collections.IstioExtensionsV1Alpha1Wasmplugins.Resource().GroupVersionKind():
func(r runtime.Object) config.Config {
obj := r.(*clientextensionsv1alpha1.WasmPlugin)
return config.Config{
diff --git a/pilot/pkg/features/pilot.go b/pilot/pkg/features/pilot.go
index 1bf24661..484c1055 100644
--- a/pilot/pkg/features/pilot.go
+++ b/pilot/pkg/features/pilot.go
@@ -110,6 +110,28 @@ var (
" EDS pushes may be delayed, but there will be fewer
pushes. By default this is enabled",
).Get()
+ SNPDebounceAfter = env.RegisterDurationVar(
+ "PILOT_SNP_DEBOUNCE_AFTER",
+ 100*time.Millisecond,
+ "The delay added to config/registry events for debouncing. This
will delay the push by "+
+ "at least this interval. If no change is detected
within this period, the push will happen, "+
+ " otherwise we'll keep delaying until things settle, up
to a max of PILOT_SNP_DEBOUNCE_MAX.",
+ ).Get()
+
+ SNPDebounceMax = env.RegisterDurationVar(
+ "PILOT_SNP_DEBOUNCE_MAX",
+ 1*time.Second,
+ "The maximum amount of time to wait for events while
debouncing. If events keep showing up with no breaks "+
+ "for this time, we'll trigger a push.",
+ ).Get()
+
+ SNPEnableDebounce = env.RegisterBoolVar(
+ "PILOT_SNP_ENABLE_DEBOUNCE",
+ true,
+ "If enabled, Pilot will include EDS pushes in the push
debouncing, configured by PILOT_SNP_DEBOUNCE_AFTER and PILOT_SNP_DEBOUNCE_MAX."+
+ " SNP register may be delayed, but there will be fewer
pushes. By default this is enabled",
+ ).Get()
+
SendUnhealthyEndpoints = env.RegisterBoolVar(
"PILOT_SEND_UNHEALTHY_ENDPOINTS",
false,
diff --git a/pilot/pkg/model/push_context.go b/pilot/pkg/model/push_context.go
index 6c42cf4f..f7a3076d 100644
--- a/pilot/pkg/model/push_context.go
+++ b/pilot/pkg/model/push_context.go
@@ -28,6 +28,7 @@ import (
import (
"go.uber.org/atomic"
extensions "istio.io/api/extensions/v1alpha1"
+ istioioapiextensionsv1alpha1 "istio.io/api/extensions/v1alpha1"
meshconfig "istio.io/api/mesh/v1alpha1"
networking "istio.io/api/networking/v1alpha3"
"istio.io/pkg/monitoring"
@@ -172,6 +173,24 @@ func newGatewayIndex() gatewayIndex {
}
}
+// serviceNameMappingIndex is the index of Service Name Mapping by various
fields.
+type serviceNameMappingIndex struct {
+ // namespace contains Service Name Mapping by namespace.
+ namespace map[string][]*config.Config
+ // interface by namespace
+ interfaceByNamespace map[string]map[string]*config.Config
+ // all contains all Service Name Mapping.
+ all []*config.Config
+}
+
+func newServiceNameMappingIndex() serviceNameMappingIndex {
+ return serviceNameMappingIndex{
+ namespace: map[string][]*config.Config{},
+ interfaceByNamespace: map[string]map[string]*config.Config{},
+ all: []*config.Config{},
+ }
+}
+
// PushContext tracks the status of a push - metrics and errors.
// Metrics are reset after a push - at the beginning all
// values are zero, and when push completes the status is reset.
@@ -207,6 +226,9 @@ type PushContext struct {
// sidecarIndex stores sidecar resources
sidecarIndex sidecarIndex
+ // serviceNameMappingIndex is the index of service name mapping.
+ serviceNameMappingIndex serviceNameMappingIndex
+
// envoy filters for each namespace including global config namespace
envoyFiltersByNamespace map[string][]*EnvoyFilterWrapper
@@ -638,6 +660,7 @@ func NewPushContext() *PushContext {
gatewayIndex: newGatewayIndex(),
ProxyStatus:
map[string]map[string]ProxyPushStatus{},
ServiceAccounts: map[host.Name]map[int][]string{},
+ serviceNameMappingIndex: newServiceNameMappingIndex(),
}
}
@@ -878,6 +901,15 @@ func (ps *PushContext)
VirtualServicesForGateway(proxyNamespace, gateway string)
return res
}
+func (ps *PushContext)
ServiceNameMappingsByNameSpaceAndInterfaceName(proxyNamespace, interfaceName
string) *config.Config {
+ if namespace, exists :=
ps.serviceNameMappingIndex.interfaceByNamespace[proxyNamespace]; exists {
+ if snp, exists := namespace[interfaceName]; exists {
+ return snp
+ }
+ }
+ return nil
+}
+
// DelegateVirtualServicesConfigKey lists all the delegate virtual services
configkeys associated with the provided virtual services
func (ps *PushContext) DelegateVirtualServicesConfigKey(vses []config.Config)
[]ConfigKey {
var out []ConfigKey
@@ -1183,6 +1215,10 @@ func (ps *PushContext) createNewContext(env
*Environment) error {
if err := ps.initSidecarScopes(env); err != nil {
return err
}
+ // service name mapping context init
+ if err := ps.initServiceNameMappings(env); err != nil {
+ return err
+ }
return nil
}
@@ -1192,7 +1228,7 @@ func (ps *PushContext) updateContext(
pushReq *PushRequest) error {
var servicesChanged, virtualServicesChanged, destinationRulesChanged,
gatewayChanged,
authnChanged, authzChanged, envoyFiltersChanged,
sidecarsChanged, telemetryChanged, gatewayAPIChanged,
- wasmPluginsChanged, proxyConfigsChanged bool
+ wasmPluginsChanged, proxyConfigsChanged,
servicenamemappingsChanged bool
for conf := range pushReq.ConfigsUpdated {
switch conf.Kind {
@@ -1224,6 +1260,8 @@ func (ps *PushContext) updateContext(
telemetryChanged = true
case gvk.ProxyConfig:
proxyConfigsChanged = true
+ case gvk.ServiceNameMapping:
+ servicenamemappingsChanged = true
}
}
@@ -1327,6 +1365,13 @@ func (ps *PushContext) updateContext(
} else {
ps.sidecarIndex.sidecarsByNamespace =
oldPushContext.sidecarIndex.sidecarsByNamespace
}
+ if servicenamemappingsChanged {
+ if err := ps.initServiceNameMappings(env); err != nil {
+ return err
+ }
+ } else {
+ ps.serviceNameMappingIndex =
oldPushContext.serviceNameMappingIndex
+ }
return nil
}
@@ -2185,6 +2230,38 @@ func (ps *PushContext) initKubernetesGateways(env
*Environment) error {
return nil
}
+// Split out of ServiceNameMapping expensive conversions - once per push.
+func (ps *PushContext) initServiceNameMappings(env *Environment) error {
+ configs, err := env.List(gvk.ServiceNameMapping, NamespaceAll)
+ if err != nil {
+ return err
+ }
+
+ // values returned from ConfigStore.List are immutable.
+ // Therefore, we make a copy
+ snpMappings := make([]*config.Config, len(configs))
+ for i := range snpMappings {
+ deepCopy := configs[i].DeepCopy()
+ snpMappings[i] = &deepCopy
+ }
+ for _, snp := range snpMappings {
+ byNamespace := ps.serviceNameMappingIndex.namespace
+ if _, exists := byNamespace[snp.Namespace]; !exists {
+ byNamespace[snp.Namespace] = make([]*config.Config, 0)
+ }
+ byNamespace[snp.Namespace] = append(byNamespace[snp.Namespace],
snp)
+
+ interfaceByNamespace :=
ps.serviceNameMappingIndex.interfaceByNamespace
+ if _, exists := interfaceByNamespace[snp.Namespace]; !exists {
+ interfaceByNamespace[snp.Namespace] =
make(map[string]*config.Config, 0)
+ }
+ mapping :=
snp.Spec.(*istioioapiextensionsv1alpha1.ServiceNameMapping)
+ interfaceByNamespace[snp.Namespace][mapping.GetInterfaceName()]
= snp
+ }
+ ps.serviceNameMappingIndex.all = snpMappings
+ return nil
+}
+
// ReferenceAllowed determines if a given resource (of type `kind` and name
`resourceName`) can be
// accessed by `namespace`, based of specific reference policies.
// Note: this function only determines if a reference is *explicitly* allowed;
the reference may not require
diff --git a/pilot/pkg/model/push_context_test.go
b/pilot/pkg/model/push_context_test.go
index b3de17ed..cdf6c068 100644
--- a/pilot/pkg/model/push_context_test.go
+++ b/pilot/pkg/model/push_context_test.go
@@ -949,7 +949,7 @@ func TestInitPushContext(t *testing.T) {
// Allow looking into exported fields for parts of push context
cmp.AllowUnexported(PushContext{}, exportToDefaults{},
serviceIndex{}, virtualServiceIndex{},
destinationRuleIndex{}, gatewayIndex{},
consolidatedDestRules{}, IstioEgressListenerWrapper{}, SidecarScope{},
- AuthenticationPolicies{}, NetworkManager{},
sidecarIndex{}, Telemetries{}, ProxyConfigs{}, consolidatedDestRule{}),
+ AuthenticationPolicies{}, NetworkManager{},
sidecarIndex{}, Telemetries{}, ProxyConfigs{}, consolidatedDestRule{},
serviceNameMappingIndex{}),
// These are not feasible/worth comparing
cmpopts.IgnoreTypes(sync.RWMutex{}, localServiceDiscovery{},
FakeStore{}, atomic.Bool{}, sync.Mutex{}),
cmpopts.IgnoreInterfaces(struct{ mesh.Holder }{}),
diff --git a/pilot/pkg/networking/dubbo/v1alpha1/servicenamemappingserver.go
b/pilot/pkg/networking/dubbo/v1alpha1/servicenamemappingserver.go
new file mode 100644
index 00000000..ddea4746
--- /dev/null
+++ b/pilot/pkg/networking/dubbo/v1alpha1/servicenamemappingserver.go
@@ -0,0 +1,308 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package v1alpha1
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "time"
+)
+
+import (
+ "github.com/pkg/errors"
+ "google.golang.org/grpc"
+ dubbov1alpha1 "istio.io/api/dubbo/v1alpha1"
+ extensionsv1alpha1 "istio.io/api/extensions/v1alpha1"
+ "istio.io/client-go/pkg/apis/extensions/v1alpha1"
+ istiolog "istio.io/pkg/log"
+ apierror "k8s.io/apimachinery/pkg/api/errors"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+import (
+ "github.com/apache/dubbo-go-pixiu/pilot/pkg/features"
+ "github.com/apache/dubbo-go-pixiu/pilot/pkg/model"
+ "github.com/apache/dubbo-go-pixiu/pkg/kube"
+)
+
+var log = istiolog.RegisterScope("Snp server", "Snp register server for
Proxyless dubbo", 0)
+
+type Snp struct {
+ dubbov1alpha1.UnimplementedServiceNameMappingServiceServer
+
+ KubeClient kube.Client
+ queue chan *RegisterRequest
+ debounceAfter time.Duration
+ debounceMax time.Duration
+ enableDebounce bool
+}
+
+func NewSnp(kubeClient kube.Client) *Snp {
+ return &Snp{
+ KubeClient: kubeClient,
+ queue: make(chan *RegisterRequest, 10),
+ debounceAfter: features.SNPDebounceAfter,
+ debounceMax: features.SNPDebounceMax,
+ enableDebounce: features.SNPEnableDebounce,
+ }
+}
+
+// RegisterServiceAppMapping register service app mapping.
+func (s *Snp) RegisterServiceAppMapping(ctx context.Context, req
*dubbov1alpha1.ServiceMappingRequest) (*dubbov1alpha1.ServiceMappingResponse,
error) {
+ namespace := req.GetNamespace()
+ interfaces := req.GetInterfaceNames()
+ applicationName := req.GetApplicationName()
+
+ registerReq := &RegisterRequest{ConfigsUpdated:
map[model.ConfigKey]map[string]struct{}{}}
+ for _, interfaceName := range interfaces {
+ key := model.ConfigKey{
+ Name: interfaceName,
+ Namespace: namespace,
+ }
+ if _, ok := registerReq.ConfigsUpdated[key]; !ok {
+ registerReq.ConfigsUpdated[key] =
make(map[string]struct{})
+ }
+ registerReq.ConfigsUpdated[key][applicationName] = struct{}{}
+ }
+ s.queue <- registerReq
+
+ return &dubbov1alpha1.ServiceMappingResponse{}, nil
+}
+
+func (s *Snp) Register(server *grpc.Server) {
+ dubbov1alpha1.RegisterServiceNameMappingServiceServer(server, s)
+}
+
+func (s *Snp) Start(stop <-chan struct{}) {
+ if s == nil {
+ log.Warn("Snp server is not init, skip start")
+ return
+ }
+ go s.debounce(stop, s.push)
+}
+
+func (s *Snp) push(req *RegisterRequest) {
+ for key, m := range req.ConfigsUpdated {
+ var appNames []string
+ for app := range m {
+ appNames = append(appNames, app)
+ }
+ for i := 0; i < 3; i++ {
+ if err := tryRegister(s.KubeClient, key.Namespace,
key.Name, appNames); err != nil {
+ log.Errorf(" register [%v] failed: %v, try
again later", key, err)
+ } else {
+ break
+ }
+ }
+ }
+}
+
+// Each application registers its services with the Snp server at startup,
+// and there are usually multiple copies of a deployment. They make requests
+// at the same time. So we need to debounce these requests,
+// because only one request is valid for the same deployment!
+// So we wait for a while, merge incoming requests, and submit them when
+// there is a timeout or a short period of no subsequent requests,
+// by default a minimum of 200ms and a maximum of 1s, which is usually
acceptable.
+// The above can significantly reduce the pressure on the registry.
+func (s *Snp) debounce(stopCh <-chan struct{}, pushFn func(req
*RegisterRequest)) {
+ ch := s.queue
+ var timeChan <-chan time.Time
+ var startDebounce time.Time
+ var lastConfigUpdateTime time.Time
+
+ pushCounter := 0
+ debouncedEvents := 0
+
+ var req *RegisterRequest
+
+ free := true
+ freeCh := make(chan struct{}, 1)
+
+ push := func(req *RegisterRequest) {
+ pushFn(req)
+ freeCh <- struct{}{}
+ }
+
+ pushWorker := func() {
+ eventDelay := time.Since(startDebounce)
+ quietTime := time.Since(lastConfigUpdateTime)
+ // it has been too long or quiet enough
+ if eventDelay >= s.debounceMax || quietTime >= s.debounceAfter {
+ if req != nil {
+ pushCounter++
+
+ if req.ConfigsUpdated != nil {
+ log.Infof(" Push debounce stable[%d] %d
for config %s: %v since last change, %v since last push",
+ pushCounter, debouncedEvents,
configsUpdated(req),
+ quietTime, eventDelay)
+ }
+ free = false
+ go push(req)
+ req = nil
+ debouncedEvents = 0
+ }
+ } else {
+ timeChan = time.After(s.debounceAfter - quietTime)
+ }
+ }
+
+ for {
+ select {
+ case <-freeCh:
+ free = true
+ pushWorker()
+ case r := <-ch:
+ // if debounce is disabled, push immediately
+ if !s.enableDebounce {
+ go push(r)
+ req = nil
+ continue
+ }
+
+ lastConfigUpdateTime = time.Now()
+ if debouncedEvents == 0 {
+ timeChan = time.After(200 * time.Millisecond)
+ startDebounce = lastConfigUpdateTime
+ }
+ debouncedEvents++
+
+ req = req.Merge(r)
+ case <-timeChan:
+ if free {
+ pushWorker()
+ }
+ case <-stopCh:
+ return
+ }
+ }
+}
+
+func tryRegister(kubeClient kube.Client, namespace, interfaceName string,
newApps []string) error {
+ log.Debugf("try register [%s] in namespace [%s] with [%v] apps",
interfaceName, namespace, len(newApps))
+ snp, created, err := getOrCreateSnp(kubeClient, namespace,
interfaceName, newApps)
+ if created {
+ log.Debugf("register success, revision:%s", snp.ResourceVersion)
+ return nil
+ }
+ if err != nil {
+ return err
+ }
+
+ previousLen := len(snp.Spec.ApplicationNames)
+ previousAppNames := make(map[string]struct{}, previousLen)
+ for _, name := range snp.Spec.ApplicationNames {
+ previousAppNames[name] = struct{}{}
+ }
+ for _, newApp := range newApps {
+ previousAppNames[newApp] = struct{}{}
+ }
+ if len(previousAppNames) == previousLen {
+ log.Debugf("[%s] has been registered: %v", interfaceName,
newApps)
+ return nil
+ }
+
+ mergedApps := make([]string, 0, len(previousAppNames))
+ for name := range previousAppNames {
+ mergedApps = append(mergedApps, name)
+ }
+ snp.Spec.ApplicationNames = mergedApps
+ snpInterface :=
kubeClient.Istio().ExtensionsV1alpha1().ServiceNameMappings(namespace)
+ snp, err = snpInterface.Update(context.Background(), snp,
v1.UpdateOptions{})
+ if err != nil {
+ return errors.Wrap(err, " update failed")
+ }
+ log.Debugf("register update success, revision:%s", snp.ResourceVersion)
+ return nil
+}
+
+func getOrCreateSnp(kubeClient kube.Client, namespace string, interfaceName
string, newApps []string) (*v1alpha1.ServiceNameMapping, bool, error) {
+ ctx := context.TODO()
+ // snp name is a lowercase RFC 1123 label must consist of lower case
alphanumeric characters or '-'
+ lowerCaseName := strings.ToLower(strings.ReplaceAll(interfaceName, ".",
"-"))
+ snpInterface :=
kubeClient.Istio().ExtensionsV1alpha1().ServiceNameMappings(namespace)
+ snp, err := snpInterface.Get(ctx, lowerCaseName, v1.GetOptions{})
+ if err != nil {
+ if apierror.IsNotFound(err) {
+ //try to create snp, this operation may be conflict
with other goroutine
+ snp, err = snpInterface.Create(ctx,
&v1alpha1.ServiceNameMapping{
+ ObjectMeta: v1.ObjectMeta{
+ Name: lowerCaseName,
+ Namespace: namespace,
+ Labels: map[string]string{
+ "interface": interfaceName,
+ },
+ },
+ Spec: extensionsv1alpha1.ServiceNameMapping{
+ InterfaceName: interfaceName,
+ ApplicationNames: newApps,
+ },
+ }, v1.CreateOptions{})
+ // create success
+ if err == nil {
+ log.Debugf("create snp %s revision %s",
interfaceName, snp.ResourceVersion)
+ return snp, true, nil
+ }
+ // If the creation fails, meaning it already created by
other goroutine, then get it
+ if apierror.IsAlreadyExists(err) {
+ log.Debugf("[%s] has been exists, err: %v", err)
+ snp, err = snpInterface.Get(ctx, lowerCaseName,
v1.GetOptions{})
+ // maybe failed to get snp cause of network
issue, just return error
+ if err != nil {
+ return nil, false, errors.Wrap(err,
"tryRegister retry get snp error")
+ }
+ }
+ } else {
+ return nil, false, errors.Wrap(err, "tryRegister get
snp error")
+ }
+ }
+ return snp, false, nil
+}
+
+type RegisterRequest struct {
+ ConfigsUpdated map[model.ConfigKey]map[string]struct{}
+}
+
+func (r *RegisterRequest) Merge(req *RegisterRequest) *RegisterRequest {
+ if r == nil {
+ return req
+ }
+ for key, newApps := range req.ConfigsUpdated {
+ if _, ok := r.ConfigsUpdated[key]; !ok {
+ r.ConfigsUpdated[key] = make(map[string]struct{})
+ }
+ for app, _ := range newApps {
+ r.ConfigsUpdated[key][app] = struct{}{}
+ }
+ }
+ return r
+}
+
+func configsUpdated(req *RegisterRequest) string {
+ configs := ""
+ for key := range req.ConfigsUpdated {
+ configs += key.String()
+ break
+ }
+ if len(req.ConfigsUpdated) > 1 {
+ more := fmt.Sprintf(" and %d more configs",
len(req.ConfigsUpdated)-1)
+ configs += more
+ }
+ return configs
+}
diff --git
a/pilot/pkg/networking/dubbo/v1alpha1/servicenamemappingserver_test.go
b/pilot/pkg/networking/dubbo/v1alpha1/servicenamemappingserver_test.go
new file mode 100644
index 00000000..09ce1e89
--- /dev/null
+++ b/pilot/pkg/networking/dubbo/v1alpha1/servicenamemappingserver_test.go
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package v1alpha1
+
+import (
+ "context"
+ "strconv"
+ "strings"
+ "sync"
+ "testing"
+ "time"
+)
+
+import (
+ dubbov1alpha1 "istio.io/api/dubbo/v1alpha1"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+import (
+ "github.com/apache/dubbo-go-pixiu/pilot/pkg/model"
+ "github.com/apache/dubbo-go-pixiu/pkg/kube"
+ "github.com/apache/dubbo-go-pixiu/pkg/test/util/assert"
+)
+
+func TestRegisterServiceAppMapping(t *testing.T) {
+ client := kube.NewFakeClient()
+ s := NewSnp(client)
+ stop := make(chan struct{})
+
+ s.Start(stop)
+ w := sync.WaitGroup{}
+ for i := 0; i < 100; i++ {
+ w.Add(1)
+ j := i
+ go func() {
+ _, _ =
s.RegisterServiceAppMapping(context.Background(),
&dubbov1alpha1.ServiceMappingRequest{
+ Namespace: "default",
+ ApplicationName: "app" + strconv.Itoa(j),
+ InterfaceNames:
[]string{"com.test.TestService"},
+ })
+ w.Done()
+ }()
+ }
+
+ w.Wait()
+ time.Sleep(s.debounceMax)
+ stop <- struct{}{}
+
+ lowerCaseName :=
strings.ToLower(strings.ReplaceAll("com.test.TestService", ".", "-"))
+ mapping, err :=
client.Istio().ExtensionsV1alpha1().ServiceNameMappings("default").Get(context.Background(),
lowerCaseName, v1.GetOptions{})
+ if err != nil {
+ t.Fatal(err)
+ }
+ assert.Equal(t, len(mapping.Spec.ApplicationNames), 100)
+}
+
+func TestReqMerge(t *testing.T) {
+ tests := []struct {
+ name string
+ reqs []*RegisterRequest
+ want *RegisterRequest
+ }{
+ {
+ name: "different",
+ reqs: []*RegisterRequest{
+ {
+ ConfigsUpdated:
map[model.ConfigKey]map[string]struct{}{
+ model.ConfigKey{
+ Name:
"a-b-c-demoservice",
+ Namespace: "default",
+ }: {
+ "app1": struct{}{},
+ "app2": struct{}{},
+ },
+ },
+ },
+ {
+ ConfigsUpdated:
map[model.ConfigKey]map[string]struct{}{
+ model.ConfigKey{
+ Name:
"a-b-c-demoservice",
+ Namespace: "default",
+ }: {
+ "app3": struct{}{},
+ },
+ },
+ },
+ },
+ want: &RegisterRequest{
+ ConfigsUpdated:
map[model.ConfigKey]map[string]struct{}{
+ model.ConfigKey{
+ Name: "a-b-c-demoservice",
+ Namespace: "default",
+ }: {
+ "app1": struct{}{},
+ "app2": struct{}{},
+ "app3": struct{}{},
+ },
+ },
+ },
+ },
+ {
+ name: "same",
+ reqs: []*RegisterRequest{
+ {
+ ConfigsUpdated:
map[model.ConfigKey]map[string]struct{}{
+ model.ConfigKey{
+ Name:
"a-b-c-demoservice",
+ Namespace: "default",
+ }: {
+ "app1": struct{}{},
+ },
+ },
+ },
+ {
+ ConfigsUpdated:
map[model.ConfigKey]map[string]struct{}{
+ model.ConfigKey{
+ Name:
"a-b-c-demoservice",
+ Namespace: "default",
+ }: {
+ "app1": struct{}{},
+ },
+ },
+ },
+ },
+ want: &RegisterRequest{
+ ConfigsUpdated:
map[model.ConfigKey]map[string]struct{}{
+ model.ConfigKey{
+ Name: "a-b-c-demoservice",
+ Namespace: "default",
+ }: {
+ "app1": struct{}{},
+ },
+ },
+ },
+ },
+ }
+ for _, tt := range tests {
+ var got *RegisterRequest
+ t.Run(tt.name, func(t *testing.T) {
+ for _, r := range tt.reqs {
+ got = got.Merge(r)
+ }
+ assert.Equal(t, got, tt.want)
+ })
+ }
+}
diff --git a/pilot/pkg/networking/dubbogen/dubbogen.go
b/pilot/pkg/networking/dubbogen/dubbogen.go
new file mode 100644
index 00000000..168b2836
--- /dev/null
+++ b/pilot/pkg/networking/dubbogen/dubbogen.go
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dubbogen
+
+import (
+ istiolog "istio.io/pkg/log"
+)
+
+import (
+ "github.com/apache/dubbo-go-pixiu/pilot/pkg/model"
+ v3 "github.com/apache/dubbo-go-pixiu/pilot/pkg/xds/v3"
+)
+
+var log = istiolog.RegisterScope("dubbogen", "xDS Generator for Proxyless
dubbo", 0)
+
+type DubboConfigGenerator struct{}
+
+func (d *DubboConfigGenerator) Generate(proxy *model.Proxy, w
*model.WatchedResource, req *model.PushRequest) (model.Resources,
model.XdsLogDetails, error) {
+ switch w.TypeUrl {
+ case v3.DubboServiceNameMappingType:
+ return d.buildServiceNameMappings(proxy, req, w.ResourceNames),
model.DefaultXdsLogDetails, nil
+ default:
+ log.Warnf("not support now %s", w.TypeUrl)
+ return nil, model.DefaultXdsLogDetails, nil
+ }
+}
diff --git a/pilot/pkg/networking/dubbogen/servicenamemapping.go
b/pilot/pkg/networking/dubbogen/servicenamemapping.go
new file mode 100644
index 00000000..62509f47
--- /dev/null
+++ b/pilot/pkg/networking/dubbogen/servicenamemapping.go
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dubbogen
+
+import (
+ "strings"
+)
+
+import (
+ discovery
"github.com/envoyproxy/go-control-plane/envoy/service/discovery/v3"
+ istioioapidubbov1alpha1 "istio.io/api/dubbo/v1alpha1"
+ istioioapiextensionsv1alpha1 "istio.io/api/extensions/v1alpha1"
+)
+
+import (
+ "github.com/apache/dubbo-go-pixiu/pilot/pkg/model"
+ "github.com/apache/dubbo-go-pixiu/pilot/pkg/networking/util"
+ "github.com/apache/dubbo-go-pixiu/pkg/config"
+ "github.com/apache/dubbo-go-pixiu/pkg/config/schema/gvk"
+)
+
+// Map of all configs that do not impact LDS
+var snpConfigs = map[model.NodeType]map[config.GroupVersionKind]struct{}{
+ model.SidecarProxy: {
+ gvk.ServiceNameMapping: {},
+ },
+}
+
+func snpNeedsPush(proxy *model.Proxy, req *model.PushRequest) bool {
+ if req == nil {
+ return true
+ }
+ if !req.Full {
+ // SNP only handles full push
+ return false
+ }
+ // If none set, we will always push
+ if len(req.ConfigsUpdated) == 0 {
+ return true
+ }
+ for conf := range req.ConfigsUpdated {
+ if _, f := snpConfigs[proxy.Type][conf.Kind]; f {
+ return true
+ }
+ }
+ return false
+}
+
+func (d *DubboConfigGenerator) buildServiceNameMappings(node *model.Proxy, req
*model.PushRequest, watchedResourceNames []string) model.Resources {
+ log.Debugf("building snp for %s", node.ID)
+ if !snpNeedsPush(node, req) {
+ return nil
+ }
+ snps := buildSnp(node, req, watchedResourceNames)
+ log.Debugf("snp res for %s:\n%v", node.ID, snps)
+ resources := model.Resources{}
+ for _, c := range snps {
+ resources = append(resources, &discovery.Resource{
+ Name: c.InterfaceName,
+ Resource: util.MessageToAny(c),
+ })
+ }
+ return resources
+}
+
+func buildSnp(node *model.Proxy, req *model.PushRequest, watchedResourceNames
[]string) []*istioioapidubbov1alpha1.ServiceMappingXdsResponse {
+ defaultNs := node.ConfigNamespace
+ res := make([]*istioioapidubbov1alpha1.ServiceMappingXdsResponse, 0,
len(watchedResourceNames))
+
+ watchedResourceNamesMap := map[string]interface{}{}
+ for _, name := range watchedResourceNames {
+ watchedResourceNamesMap[name] = struct{}{}
+ }
+ updatedMap := map[string]interface{}{}
+ for update, _ := range req.ConfigsUpdated {
+ updatedMap[update.Name] = struct{}{}
+ }
+ // if req.ConfigsUpdated is empty, it means that all watched resources
need to be pushed
+ for _, w := range watchedResourceNames {
+ // if configsUpdated empty, meaning a full push of watched snp
resources.
+ if _, exists := updatedMap[w]; exists ||
len(req.ConfigsUpdated) == 0 {
+ namespace, snpName := extractNameAndNameSpace(w,
defaultNs)
+ if snp :=
req.Push.ServiceNameMappingsByNameSpaceAndInterfaceName(namespace, snpName);
snp != nil {
+ mapping :=
snp.Spec.(*istioioapiextensionsv1alpha1.ServiceNameMapping)
+ res = append(res,
&istioioapidubbov1alpha1.ServiceMappingXdsResponse{
+ Namespace: snp.Namespace,
+ InterfaceName: mapping.InterfaceName,
+ ApplicationNames:
mapping.ApplicationNames,
+ })
+ }
+ }
+ }
+ return res
+}
+
+func extractNameAndNameSpace(watchedResource, defaultNamespace string)
(string, string) {
+ split := strings.Split(watchedResource, "|")
+ if len(split) == 1 || split[1] == "" {
+ return defaultNamespace, split[1]
+ }
+ return split[1], split[0]
+}
diff --git a/pilot/pkg/xds/ads.go b/pilot/pkg/xds/ads.go
index bb1790f7..5527feb4 100644
--- a/pilot/pkg/xds/ads.go
+++ b/pilot/pkg/xds/ads.go
@@ -437,7 +437,7 @@ func shouldUnsubscribe(request *discovery.DiscoveryRequest)
bool {
// resource names.
func isWildcardTypeURL(typeURL string) bool {
switch typeURL {
- case v3.SecretType, v3.EndpointType, v3.RouteType,
v3.ExtensionConfigurationType:
+ case v3.SecretType, v3.EndpointType, v3.RouteType,
v3.ExtensionConfigurationType, v3.DubboServiceNameMappingType:
// By XDS spec, these are not wildcard
return false
case v3.ClusterType, v3.ListenerType:
@@ -630,7 +630,7 @@ func (s *DiscoveryServer) computeProxyState(proxy
*model.Proxy, request *model.P
}
for conf := range request.ConfigsUpdated {
switch conf.Kind {
- case gvk.ServiceEntry, gvk.DestinationRule,
gvk.VirtualService, gvk.Sidecar, gvk.HTTPRoute, gvk.TCPRoute:
+ case gvk.ServiceEntry, gvk.DestinationRule,
gvk.VirtualService, gvk.Sidecar, gvk.HTTPRoute, gvk.TCPRoute,
gvk.ServiceNameMapping:
sidecar = true
case gvk.Gateway, gvk.KubernetesGateway,
gvk.GatewayClass:
gateway = true
diff --git a/pilot/pkg/xds/discovery.go b/pilot/pkg/xds/discovery.go
index 336333dd..b80a6b58 100644
--- a/pilot/pkg/xds/discovery.go
+++ b/pilot/pkg/xds/discovery.go
@@ -37,6 +37,7 @@ import (
"github.com/apache/dubbo-go-pixiu/pilot/pkg/networking/apigen"
"github.com/apache/dubbo-go-pixiu/pilot/pkg/networking/core"
"github.com/apache/dubbo-go-pixiu/pilot/pkg/networking/core/v1alpha3/envoyfilter"
+ "github.com/apache/dubbo-go-pixiu/pilot/pkg/networking/dubbogen"
"github.com/apache/dubbo-go-pixiu/pilot/pkg/networking/grpcgen"
"github.com/apache/dubbo-go-pixiu/pilot/pkg/serviceregistry"
"github.com/apache/dubbo-go-pixiu/pilot/pkg/serviceregistry/aggregate"
@@ -588,6 +589,9 @@ func (s *DiscoveryServer) InitGenerators(env
*model.Environment, systemNameSpace
s.Generators["grpc/"+v3.RouteType] = s.Generators["grpc"]
s.Generators["grpc/"+v3.ClusterType] = s.Generators["grpc"]
+ s.Generators["dubbo"] = &dubbogen.DubboConfigGenerator{}
+ s.Generators[v3.DubboServiceNameMappingType] = s.Generators["dubbo"]
+
s.Generators["api"] = apigen.NewGenerator(env.ConfigStore)
s.Generators["api/"+v3.EndpointType] = edsGen
diff --git a/pilot/pkg/xds/discovery_test.go b/pilot/pkg/xds/discovery_test.go
index 3549c098..42e55f67 100644
--- a/pilot/pkg/xds/discovery_test.go
+++ b/pilot/pkg/xds/discovery_test.go
@@ -464,6 +464,69 @@ func TestShouldRespond(t *testing.T) {
},
response: false,
},
+ {
+ name: "resources change",
+ connection: &Connection{
+ proxy: &model.Proxy{
+ WatchedResources:
map[string]*model.WatchedResource{
+ v3.DubboServiceNameMappingType:
{
+ VersionSent: "v1",
+ NonceSent: "nonce",
+ ResourceNames:
[]string{"dubbo.demo.hello1"},
+ },
+ },
+ },
+ },
+ request: &discovery.DiscoveryRequest{
+ TypeUrl: v3.DubboServiceNameMappingType,
+ VersionInfo: "v1",
+ ResponseNonce: "nonce",
+ ResourceNames: []string{"dubbo.demo.hello1",
"dubbo.demo.hello2"},
+ },
+ response: true,
+ },
+ {
+ name: "ack with same resources",
+ connection: &Connection{
+ proxy: &model.Proxy{
+ WatchedResources:
map[string]*model.WatchedResource{
+ v3.DubboServiceNameMappingType:
{
+ VersionSent: "v1",
+ NonceSent: "nonce",
+ ResourceNames:
[]string{"dubbo.demo.hello1", "dubbo.demo.hello2"},
+ },
+ },
+ },
+ },
+ request: &discovery.DiscoveryRequest{
+ TypeUrl: v3.DubboServiceNameMappingType,
+ VersionInfo: "v1",
+ ResponseNonce: "nonce",
+ ResourceNames: []string{"dubbo.demo.hello1",
"dubbo.demo.hello2"},
+ },
+ response: false,
+ },
+ {
+ name: "unsubscribe snp",
+ connection: &Connection{
+ proxy: &model.Proxy{
+ WatchedResources:
map[string]*model.WatchedResource{
+ v3.DubboServiceNameMappingType:
{
+ VersionSent: "v1",
+ NonceSent: "nonce",
+ ResourceNames:
[]string{"dubbo.demo.hello1", "dubbo.demo.hello2"},
+ },
+ },
+ },
+ },
+ request: &discovery.DiscoveryRequest{
+ TypeUrl: v3.DubboServiceNameMappingType,
+ VersionInfo: "v1",
+ ResponseNonce: "nonce",
+ ResourceNames: []string{},
+ },
+ response: false,
+ },
}
for _, tt := range tests {
diff --git a/pilot/pkg/xds/v3/model.go b/pilot/pkg/xds/v3/model.go
index eb5510d7..a3bab3f0 100644
--- a/pilot/pkg/xds/v3/model.go
+++ b/pilot/pkg/xds/v3/model.go
@@ -40,7 +40,8 @@ const (
BootstrapType = resource.APITypePrefix +
"envoy.config.bootstrap.v3.Bootstrap"
// nolint
- HttpProtocolOptionsType =
"envoy.extensions.upstreams.http.v3.HttpProtocolOptions"
+ HttpProtocolOptionsType =
"envoy.extensions.upstreams.http.v3.HttpProtocolOptions"
+ DubboServiceNameMappingType =
"dubbo.networking.v1alpha1.v1.servicenamemapping"
)
// GetShortType returns an abbreviated form of a type, useful for logging or
human friendly messages
diff --git a/pixiu/pkg/prometheus/prometheus.go
b/pixiu/pkg/prometheus/prometheus.go
index d8e23d62..6d28819e 100644
--- a/pixiu/pkg/prometheus/prometheus.go
+++ b/pixiu/pkg/prometheus/prometheus.go
@@ -28,6 +28,7 @@ import (
)
import (
+ "github.com/dubbo-go-pixiu/pixiu-api/pkg/context"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/expfmt"
)
@@ -36,7 +37,6 @@ import (
"github.com/apache/dubbo-go-pixiu/pixiu/pkg/client"
contextHttp "github.com/apache/dubbo-go-pixiu/pixiu/pkg/context/http"
"github.com/apache/dubbo-go-pixiu/pixiu/pkg/logger"
- "github.com/dubbo-go-pixiu/pixiu-api/pkg/context"
)
var defaultSubsystem = "pixiu"
diff --git a/pkg/config/schema/collections/collections.agent.gen.go
b/pkg/config/schema/collections/collections.agent.gen.go
index ebcc7f5a..7fc72567 100755
--- a/pkg/config/schema/collections/collections.agent.gen.go
+++ b/pkg/config/schema/collections/collections.agent.gen.go
@@ -28,6 +28,24 @@ import (
var (
+ // IstioExtensionsV1Alpha1Servicenamemappings describes the collection
+ // istio/extensions/v1alpha1/servicenamemappings
+ IstioExtensionsV1Alpha1Servicenamemappings = collection.Builder{
+ Name: "istio/extensions/v1alpha1/servicenamemappings",
+ VariableName: "IstioExtensionsV1Alpha1Servicenamemappings",
+ Resource: resource.Builder{
+ Group: "extensions.istio.io",
+ Kind: "ServiceNameMapping",
+ Plural: "servicenamemappings",
+ Version: "v1alpha1",
+ Proto:
"istio.extensions.v1alpha1.ServiceNameMapping", StatusProto:
"istio.meta.v1alpha1.IstioStatus",
+ ReflectType:
reflect.TypeOf(&istioioapiextensionsv1alpha1.ServiceNameMapping{}).Elem(),
StatusType: reflect.TypeOf(&istioioapimetav1alpha1.IstioStatus{}).Elem(),
+ ProtoPackage: "istio.io/api/extensions/v1alpha1",
StatusPackage: "istio.io/api/meta/v1alpha1",
+ ClusterScoped: false,
+ ValidateProto: validation.EmptyValidate,
+ }.MustBuild(),
+ }.MustBuild()
+
// IstioExtensionsV1Alpha1Wasmplugins describes the collection
// istio/extensions/v1alpha1/wasmplugins
IstioExtensionsV1Alpha1Wasmplugins = collection.Builder{
@@ -318,6 +336,7 @@ var (
// All contains all collections in the system.
All = collection.NewSchemasBuilder().
+ MustAdd(IstioExtensionsV1Alpha1Servicenamemappings).
MustAdd(IstioExtensionsV1Alpha1Wasmplugins).
MustAdd(IstioMeshV1Alpha1MeshConfig).
MustAdd(IstioMeshV1Alpha1MeshNetworks).
@@ -338,6 +357,7 @@ var (
// Istio contains only Istio collections.
Istio = collection.NewSchemasBuilder().
+ MustAdd(IstioExtensionsV1Alpha1Servicenamemappings).
MustAdd(IstioExtensionsV1Alpha1Wasmplugins).
MustAdd(IstioMeshV1Alpha1MeshConfig).
MustAdd(IstioMeshV1Alpha1MeshNetworks).
@@ -367,6 +387,7 @@ var (
// Pilot contains only collections used by Pilot.
Pilot = collection.NewSchemasBuilder().
+ MustAdd(IstioExtensionsV1Alpha1Servicenamemappings).
MustAdd(IstioExtensionsV1Alpha1Wasmplugins).
MustAdd(IstioNetworkingV1Alpha3Destinationrules).
MustAdd(IstioNetworkingV1Alpha3Envoyfilters).
@@ -385,6 +406,7 @@ var (
// PilotGatewayAPI contains only collections used by Pilot, including
experimental Service Api.
PilotGatewayAPI = collection.NewSchemasBuilder().
+ MustAdd(IstioExtensionsV1Alpha1Servicenamemappings).
MustAdd(IstioExtensionsV1Alpha1Wasmplugins).
MustAdd(IstioNetworkingV1Alpha3Destinationrules).
MustAdd(IstioNetworkingV1Alpha3Envoyfilters).
diff --git a/pkg/config/schema/collections/collections.gen.go
b/pkg/config/schema/collections/collections.gen.go
index 0125f23d..df9d0fa5 100755
--- a/pkg/config/schema/collections/collections.gen.go
+++ b/pkg/config/schema/collections/collections.gen.go
@@ -34,6 +34,24 @@ import (
var (
+ // IstioExtensionsV1Alpha1Servicenamemappings describes the collection
+ // istio/extensions/v1alpha1/servicenamemappings
+ IstioExtensionsV1Alpha1Servicenamemappings = collection.Builder{
+ Name: "istio/extensions/v1alpha1/servicenamemappings",
+ VariableName: "IstioExtensionsV1Alpha1Servicenamemappings",
+ Resource: resource.Builder{
+ Group: "extensions.istio.io",
+ Kind: "ServiceNameMapping",
+ Plural: "servicenamemappings",
+ Version: "v1alpha1",
+ Proto:
"istio.extensions.v1alpha1.ServiceNameMapping", StatusProto:
"istio.meta.v1alpha1.IstioStatus",
+ ReflectType:
reflect.TypeOf(&istioioapiextensionsv1alpha1.ServiceNameMapping{}).Elem(),
StatusType: reflect.TypeOf(&istioioapimetav1alpha1.IstioStatus{}).Elem(),
+ ProtoPackage: "istio.io/api/extensions/v1alpha1",
StatusPackage: "istio.io/api/meta/v1alpha1",
+ ClusterScoped: false,
+ ValidateProto: validation.EmptyValidate,
+ }.MustBuild(),
+ }.MustBuild()
+
// IstioExtensionsV1Alpha1Wasmplugins describes the collection
// istio/extensions/v1alpha1/wasmplugins
IstioExtensionsV1Alpha1Wasmplugins = collection.Builder{
@@ -623,6 +641,7 @@ var (
// All contains all collections in the system.
All = collection.NewSchemasBuilder().
+ MustAdd(IstioExtensionsV1Alpha1Servicenamemappings).
MustAdd(IstioExtensionsV1Alpha1Wasmplugins).
MustAdd(IstioMeshV1Alpha1MeshConfig).
MustAdd(IstioMeshV1Alpha1MeshNetworks).
@@ -660,6 +679,7 @@ var (
// Istio contains only Istio collections.
Istio = collection.NewSchemasBuilder().
+ MustAdd(IstioExtensionsV1Alpha1Servicenamemappings).
MustAdd(IstioExtensionsV1Alpha1Wasmplugins).
MustAdd(IstioMeshV1Alpha1MeshConfig).
MustAdd(IstioMeshV1Alpha1MeshNetworks).
@@ -717,6 +737,7 @@ var (
// Pilot contains only collections used by Pilot.
Pilot = collection.NewSchemasBuilder().
+ MustAdd(IstioExtensionsV1Alpha1Servicenamemappings).
MustAdd(IstioExtensionsV1Alpha1Wasmplugins).
MustAdd(IstioNetworkingV1Alpha3Destinationrules).
MustAdd(IstioNetworkingV1Alpha3Envoyfilters).
@@ -735,6 +756,7 @@ var (
// PilotGatewayAPI contains only collections used by Pilot, including
experimental Service Api.
PilotGatewayAPI = collection.NewSchemasBuilder().
+ MustAdd(IstioExtensionsV1Alpha1Servicenamemappings).
MustAdd(IstioExtensionsV1Alpha1Wasmplugins).
MustAdd(IstioNetworkingV1Alpha3Destinationrules).
MustAdd(IstioNetworkingV1Alpha3Envoyfilters).
diff --git a/pkg/config/schema/gvk/resources.gen.go
b/pkg/config/schema/gvk/resources.gen.go
index 1c803289..20703626 100755
--- a/pkg/config/schema/gvk/resources.gen.go
+++ b/pkg/config/schema/gvk/resources.gen.go
@@ -33,6 +33,7 @@ var (
Secret = config.GroupVersionKind{Group: "",
Version: "v1", Kind: "Secret"}
Service = config.GroupVersionKind{Group: "",
Version: "v1", Kind: "Service"}
ServiceEntry = config.GroupVersionKind{Group:
"networking.istio.io", Version: "v1alpha3", Kind: "ServiceEntry"}
+ ServiceNameMapping = config.GroupVersionKind{Group:
"extensions.istio.io", Version: "v1alpha1", Kind: "ServiceNameMapping"}
Sidecar = config.GroupVersionKind{Group:
"networking.istio.io", Version: "v1alpha3", Kind: "Sidecar"}
TCPRoute = config.GroupVersionKind{Group:
"gateway.networking.k8s.io", Version: "v1alpha2", Kind: "TCPRoute"}
TLSRoute = config.GroupVersionKind{Group:
"gateway.networking.k8s.io", Version: "v1alpha2", Kind: "TLSRoute"}
diff --git a/pkg/config/schema/metadata.yaml b/pkg/config/schema/metadata.yaml
index cc0a202c..9815f135 100644
--- a/pkg/config/schema/metadata.yaml
+++ b/pkg/config/schema/metadata.yaml
@@ -180,6 +180,11 @@ collections:
name: "k8s/gateway_api/v1alpha2/referencepolicies"
group: "gateway.networking.k8s.io"
+ - name: "istio/extensions/v1alpha1/servicenamemappings"
+ kind: ServiceNameMapping
+ group: "extensions.istio.io"
+ pilot: true
+
# Configuration for resource types.
resources:
# Kubernetes specific configuration.
@@ -468,3 +473,13 @@ resources:
description: ""
statusProto: "istio.meta.v1alpha1.IstioStatus"
statusProtoPackage: "istio.io/api/meta/v1alpha1"
+
+ - kind: ServiceNameMapping
+ plural: "servicenamemappings"
+ group: "extensions.istio.io"
+ version: "v1alpha1"
+ proto: "istio.extensions.v1alpha1.ServiceNameMapping"
+ protoPackage: "istio.io/api/extensions/v1alpha1"
+ description: "describes service name mappings"
+ statusProto: "istio.meta.v1alpha1.IstioStatus"
+ statusProtoPackage: "istio.io/api/meta/v1alpha1"
\ No newline at end of file