[ https://issues.apache.org/jira/browse/SCB-953?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16654894#comment-16654894 ]
ASF GitHub Bot commented on SCB-953: ------------------------------------ asifdxtreme closed pull request #458: SCB-953 Support sync distinct Kubernetes service types to service-center URL: https://github.com/apache/incubator-servicecomb-service-center/pull/458 This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/README.md b/README.md index e2fd849f..ecdf7d9c 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Apache ServiceComb (incubating) Service-Center is a Restful based service-regist - **[`Open API`](/server/core/swagger/v4.yaml)**: API doc(Open API format) management for microservice - **Metadata**: Metadata management for both microservice and microservice instance - **Dependency**: Microservice dependency management - - **Seperated**: Seperated microservice and microservice instance entity management + - **Separated**: Separated microservice and microservice instance entity management - **Domains**: Logical multiple domains management - **Security**: White and back list configuration for service discovery - **Discovery**: Support query instance by criteria @@ -17,8 +17,12 @@ Apache ServiceComb (incubating) Service-Center is a Restful based service-regist - **Performance**: Performance/Caching design - **[`Metrics`](/docs/integration-grafana.md)**: Able to expose Prometheus metric API automatically - **[`Tracing`](/docs/tracing.md)**: Able to report tracing data to Zipkin server - - **[`Multi Datacenter`](/docs/multidcs.md)**: Additional layer of abstraction to clusters deployed in multiple datacenters - - **[`Dynmaic Plug-in`](/docs/plugin.md)**: Able to load custom authentication, tls and other dynamic libraries + - **[`Pluginable`](/docs/plugin.md)**: Able to load custom authentication, tls and other dynamic libraries + - **[`CLI`](/scctl/pkg/plugin/README.md)**: Easy to control service center + - **[`Kubernetes`](/docs/kubeclusters.md)**: Embrace kubernetes ecosystem and support multi cluster service discovery + - **[`Datacenters`](/docs/multidcs.md)**: Additional layer of abstraction to clusters deployed in multiple datacenters + - **[`Aggregation`](/docs/aggregate.md)**: Able to aggregate microservices from multiple registry platforms and + support platform registry and client side registry at the same time ## Documentation diff --git a/docs/README.md b/docs/README.md index c827fb4d..0d9d7197 100644 --- a/docs/README.md +++ b/docs/README.md @@ -30,7 +30,7 @@ Swagger [`v4`](/server/core/swagger/v4.yaml)|[`v3`](/server/core/swagger/v3.yaml + **Kubernetes** - [Helm Chart](/docs/helm.md) - [Access Distinct Clusters](/docs/kubeclusters.md) - - [Multiple Platforms Micro-services Manage](/docs/aggregate.md) + - [Multiple Registry Aggregation](/docs/aggregate.md) #### Monitoring Service-Center diff --git a/docs/helm.md b/docs/helm.md index 9c04507a..405ea11f 100644 --- a/docs/helm.md +++ b/docs/helm.md @@ -72,25 +72,11 @@ cd ${PROJECT_ROOT}/examples/infrastructures/k8s # install etcd cluster helm install --name coreos --namespace default etcd/ # install sc cluster -helm install --name dc1 --namespace default \ - --set frontend.deployment=false \ - --set sc.image.repository="desktop-0028:5000/servicecomb/service-center" \ - --set sc.discovery.type="aggregate" \ - --set sc.discovery.aggregate="etcd\,servicecenter" \ - --set sc.discovery.clusters="sc-1=http://c1-etcd-client:2379\,sc-2=http://dc2-service-center:30100" \ - --set sc.registry.enabled=true \ - --set sc.registry.type="etcd" \ - --set sc.registry.name="sc-1" \ - service-center/ -helm install --name dc2 --namespace default \ - --set frontend.deployment=false \ - --set sc.image.repository="desktop-0028:5000/servicecomb/service-center" \ - --set sc.discovery.type="aggregate" \ - --set sc.discovery.aggregate="etcd\,servicecenter" \ - --set sc.discovery.clusters="sc-2=http://c2-etcd-client:2379\,sc-1=http://dc1-service-center:30100" \ +helm install --name servicecomb --namespace default \ + --set sc.discovery.type="etcd" \ + --set sc.discovery.clusters="http://coreos-etcd-client:2379" \ --set sc.registry.enabled=true \ --set sc.registry.type="etcd" \ - --set sc.registry.name="sc-2" \ service-center/ ``` diff --git a/docs/multidcs.md b/docs/multidcs.md index ecba0eac..3354ff60 100644 --- a/docs/multidcs.md +++ b/docs/multidcs.md @@ -14,6 +14,15 @@ isolated from each other. Another implementation of the discovery plug-in, `Serv access multiple SC instances and periodically pull up micro-service instance information so that if some micro-services can request aggregate, cross-DCs can be implemented using the same API as SC cluster. +If SC aggregate is not deployed globally, SC also supports another way to implement multiple DCs discovery, +as shown below. + +![architecture](/docs/multidcs2.PNG) + +The difference between the two approaches is that global deployment aggregate can divert service discovery traffic, +the whole architecture is more like a read-write separation architecture, and the SC of each DC manage microservice +information independently, which reduces the complexity. So we recommend the first architecture. + ## Quick Start Let's assume you want to install 2 clusters of Service-Center in different DCs with following details. diff --git a/docs/multidcs2.PNG b/docs/multidcs2.PNG new file mode 100644 index 00000000..1190e4c4 Binary files /dev/null and b/docs/multidcs2.PNG differ diff --git a/examples/infrastructures/k8s/service-center/templates/configmap.yaml b/examples/infrastructures/k8s/service-center/templates/configmap.yaml index 1a2c72d9..56820b8c 100644 --- a/examples/infrastructures/k8s/service-center/templates/configmap.yaml +++ b/examples/infrastructures/k8s/service-center/templates/configmap.yaml @@ -35,8 +35,7 @@ data: ssl_mode = 0 enable_pprof = 1 {{- end }} - -{{- if .Values.frontend.deployment -}} +{{- if .Values.frontend.deployment }} --- apiVersion: v1 kind: ConfigMap diff --git a/examples/infrastructures/k8s/service-center/templates/deployment.yaml b/examples/infrastructures/k8s/service-center/templates/deployment.yaml index 8bf74187..ddaf8f59 100644 --- a/examples/infrastructures/k8s/service-center/templates/deployment.yaml +++ b/examples/infrastructures/k8s/service-center/templates/deployment.yaml @@ -53,8 +53,7 @@ spec: {{ toYaml .Values.sc.nodeSelector | indent 8 }} {{- end }} {{- end }} - -{{- if .Values.frontend.deployment -}} +{{- if .Values.frontend.deployment }} --- apiVersion: extensions/v1beta1 kind: Deployment diff --git a/examples/infrastructures/k8s/service-center/templates/service.yaml b/examples/infrastructures/k8s/service-center/templates/service.yaml index 078b6df9..f835ef6a 100644 --- a/examples/infrastructures/k8s/service-center/templates/service.yaml +++ b/examples/infrastructures/k8s/service-center/templates/service.yaml @@ -24,8 +24,7 @@ spec: app: {{ template "service-center.name" . }} release: {{ .Release.Name }} {{- end }} - -{{- if .Values.frontend.deployment -}} +{{- if .Values.frontend.deployment }} --- apiVersion: v1 kind: Service diff --git a/server/admin/service.go b/server/admin/service.go index 2a86d80f..6255f382 100644 --- a/server/admin/service.go +++ b/server/admin/service.go @@ -95,7 +95,12 @@ func (service *AdminService) dumpAll(ctx context.Context, cache *model.Cache) { } func setValue(e discovery.Adaptor, setter model.Setter) { + exists := make(map[string]struct{}) e.Cache().ForEach(func(k string, kv *discovery.KeyValue) (next bool) { + if _, ok := exists[k]; ok { + return true + } + exists[k] = struct{}{} setter.SetValue(&model.KV{Key: k, Rev: kv.ModRevision, Value: kv.Value}) return true }) diff --git a/server/plugin/pkg/discovery/aggregate/adaptor.go b/server/plugin/pkg/discovery/aggregate/adaptor.go index 7196d115..cb669806 100644 --- a/server/plugin/pkg/discovery/aggregate/adaptor.go +++ b/server/plugin/pkg/discovery/aggregate/adaptor.go @@ -16,6 +16,7 @@ package aggregate import ( + "github.com/apache/incubator-servicecomb-service-center/pkg/util" mgr "github.com/apache/incubator-servicecomb-service-center/server/plugin" "github.com/apache/incubator-servicecomb-service-center/server/plugin/pkg/discovery" "github.com/apache/incubator-servicecomb-service-center/server/plugin/pkg/registry" @@ -26,13 +27,22 @@ import ( type Aggregator []discovery.Adaptor func (as Aggregator) Search(ctx context.Context, opts ...registry.PluginOpOption) (*discovery.Response, error) { - var response discovery.Response + var ( + response discovery.Response + exists = make(map[string]struct{}) + ) for _, a := range as { resp, err := a.Search(ctx, opts...) if err != nil { continue } - response.Kvs = append(response.Kvs, resp.Kvs...) + for _, kv := range resp.Kvs { + key := util.BytesToStringWithNoCopy(kv.Key) + if _, ok := exists[key]; !ok { + exists[key] = struct{}{} + response.Kvs = append(response.Kvs, kv) + } + } response.Count += resp.Count } return &response, nil diff --git a/server/plugin/pkg/discovery/k8s/adaptor/cacher_index.go b/server/plugin/pkg/discovery/k8s/adaptor/cacher_index.go index 2f0651c2..b03a637f 100644 --- a/server/plugin/pkg/discovery/k8s/adaptor/cacher_index.go +++ b/server/plugin/pkg/discovery/k8s/adaptor/cacher_index.go @@ -20,7 +20,6 @@ import ( pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto" "github.com/apache/incubator-servicecomb-service-center/server/plugin/pkg/discovery" "k8s.io/api/core/v1" - meta "k8s.io/apimachinery/pkg/apis/meta/v1" ) type ServiceIndexCacher struct { @@ -30,14 +29,18 @@ type ServiceIndexCacher struct { // onServiceEvent is the method to refresh service cache func (c *ServiceIndexCacher) onServiceEvent(evt K8sEvent) { svc := evt.Object.(*v1.Service) - if svc.Namespace == meta.NamespaceSystem { - return - } - domainProject := Kubernetes().GetDomainProject() serviceId := string(svc.UID) indexKey := core.GenerateServiceIndexKey(generateServiceKey(domainProject, svc)) + if !ShouldRegisterService(svc) { + kv := c.Cache().Get(indexKey) + if kv != nil { + c.Notify(pb.EVT_DELETE, indexKey, kv) + } + return + } + switch evt.EventType { case pb.EVT_CREATE: kv := AsKeyValue(indexKey, serviceId, svc.ResourceVersion) diff --git a/server/plugin/pkg/discovery/k8s/adaptor/cacher_instance.go b/server/plugin/pkg/discovery/k8s/adaptor/cacher_instance.go index 852c69e7..55c0f3eb 100644 --- a/server/plugin/pkg/discovery/k8s/adaptor/cacher_instance.go +++ b/server/plugin/pkg/discovery/k8s/adaptor/cacher_instance.go @@ -21,7 +21,6 @@ import ( pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto" "github.com/apache/incubator-servicecomb-service-center/server/plugin/pkg/discovery" "k8s.io/api/core/v1" - meta "k8s.io/apimachinery/pkg/apis/meta/v1" "reflect" "strconv" ) @@ -33,29 +32,25 @@ type InstanceCacher struct { // onServiceEvent is the method to refresh service cache func (c *InstanceCacher) onServiceEvent(evt K8sEvent) { svc := evt.Object.(*v1.Service) - if svc.Namespace == meta.NamespaceSystem { - return - } - domainProject := Kubernetes().GetDomainProject() serviceId := string(svc.UID) - instKey := core.GenerateInstanceKey(domainProject, serviceId, "") switch evt.EventType { case pb.EVT_DELETE: - // instances - var kvs []*discovery.KeyValue - c.Cache().GetPrefix(instKey, &kvs) - for _, kv := range kvs { - key := util.BytesToStringWithNoCopy(kv.Key) - c.Notify(pb.EVT_DELETE, key, kv) + c.deleteInstances(domainProject, serviceId) + case pb.EVT_UPDATE: + if !ShouldRegisterService(svc) { + c.deleteInstances(domainProject, serviceId) + return } + ep := Kubernetes().GetEndpoints(svc.Namespace, svc.Name) + c.onEndpointsEvent(K8sEvent{pb.EVT_CREATE, ep, nil}) } } -func (c *InstanceCacher) getInstances(serviceId string) (m map[string]*discovery.KeyValue) { +func (c *InstanceCacher) getInstances(domainProject, serviceId string) (m map[string]*discovery.KeyValue) { var arr []*discovery.KeyValue - key := core.GenerateInstanceKey(Kubernetes().GetDomainProject(), serviceId, "") + key := core.GenerateInstanceKey(domainProject, serviceId, "") if l := c.Cache().GetPrefix(key, &arr); l > 0 { m = make(map[string]*discovery.KeyValue, l) for _, kv := range arr { @@ -65,20 +60,26 @@ func (c *InstanceCacher) getInstances(serviceId string) (m map[string]*discovery return } +func (c *InstanceCacher) deleteInstances(domainProject, serviceId string) { + var kvs []*discovery.KeyValue + c.Cache().GetPrefix(core.GenerateInstanceKey(domainProject, serviceId, ""), &kvs) + for _, kv := range kvs { + key := util.BytesToStringWithNoCopy(kv.Key) + c.Notify(pb.EVT_DELETE, key, kv) + } +} + // onEndpointsEvent is the method to refresh instance cache func (c *InstanceCacher) onEndpointsEvent(evt K8sEvent) { ep := evt.Object.(*v1.Endpoints) - if ep.Namespace == meta.NamespaceSystem { - return - } - svc := Kubernetes().GetService(ep.Namespace, ep.Name) - if svc == nil { + if svc == nil || !ShouldRegisterService(svc) { return } serviceId := string(svc.UID) - oldKvs := c.getInstances(serviceId) + domainProject := Kubernetes().GetDomainProject() + oldKvs := c.getInstances(domainProject, serviceId) newKvs := make(map[string]*discovery.KeyValue) for _, ss := range ep.Subsets { for _, ea := range ss.Addresses { @@ -108,6 +109,9 @@ func (c *InstanceCacher) onEndpointsEvent(evt K8sEvent) { DataCenterInfo: &pb.DataCenterInfo{}, Timestamp: strconv.FormatInt(pod.CreationTimestamp.Unix(), 10), Version: getLabel(svc.Labels, LabelVersion, pb.VERSION), + Properties: map[string]string{ + PropNodeIP: pod.Status.HostIP, + }, } inst.DataCenterInfo.Region, inst.DataCenterInfo.AvailableZone = getRegionAZ(node) inst.ModTimestamp = inst.Timestamp diff --git a/server/plugin/pkg/discovery/k8s/adaptor/cacher_service.go b/server/plugin/pkg/discovery/k8s/adaptor/cacher_service.go index c1455ba7..cb5fcf04 100644 --- a/server/plugin/pkg/discovery/k8s/adaptor/cacher_service.go +++ b/server/plugin/pkg/discovery/k8s/adaptor/cacher_service.go @@ -20,7 +20,6 @@ import ( pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto" "github.com/apache/incubator-servicecomb-service-center/server/plugin/pkg/discovery" "k8s.io/api/core/v1" - meta "k8s.io/apimachinery/pkg/apis/meta/v1" ) type ServiceCacher struct { @@ -30,18 +29,25 @@ type ServiceCacher struct { // onServiceEvent is the method to refresh service cache func (c *ServiceCacher) onServiceEvent(evt K8sEvent) { svc := evt.Object.(*v1.Service) - if svc.Namespace == meta.NamespaceSystem { - return - } - domainProject := Kubernetes().GetDomainProject() serviceId := string(svc.UID) key := core.GenerateServiceKey(domainProject, serviceId) + if !ShouldRegisterService(svc) { + kv := c.Cache().Get(key) + if kv != nil { + c.Notify(pb.EVT_DELETE, key, kv) + } + return + } + switch evt.EventType { case pb.EVT_CREATE, pb.EVT_UPDATE: ms := FromK8sService(svc) kv := AsKeyValue(key, ms, svc.ResourceVersion) + if c.Cache().Get(key) == nil { + evt.EventType = pb.EVT_CREATE + } c.Notify(evt.EventType, key, kv) case pb.EVT_DELETE: // service diff --git a/server/plugin/pkg/discovery/k8s/adaptor/common.go b/server/plugin/pkg/discovery/k8s/adaptor/common.go index ed9a88f6..cf67a628 100644 --- a/server/plugin/pkg/discovery/k8s/adaptor/common.go +++ b/server/plugin/pkg/discovery/k8s/adaptor/common.go @@ -18,6 +18,8 @@ package adaptor import ( "github.com/apache/incubator-servicecomb-service-center/pkg/queue" "github.com/apache/incubator-servicecomb-service-center/pkg/util" + "k8s.io/api/core/v1" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" "time" @@ -44,10 +46,14 @@ const ( LabelNodeRegion = "failure-domain.beta.kubernetes.io/region" LabelNodeAZ = "failure-domain.beta.kubernetes.io/zone" + // register annotations + AnnotationRegister = "service-center.servicecomb.io/register" + // properties PropNamespace = "namespace" PropExternalName = "externalName" PropServiceType = "type" + PropNodeIP = "nodeIP" minWaitInterval = 5 * time.Second defaultResyncInterval = 60 * time.Second @@ -79,3 +85,13 @@ func Queue(t K8sType) *queue.TaskQueue { }) return q.(*queue.TaskQueue) } + +func ShouldRegisterService(service *v1.Service) bool { + if service.Namespace == meta.NamespaceSystem { + return false + } + if register, ok := service.ObjectMeta.Annotations[AnnotationRegister]; ok && register == "false" { + return false + } + return true +} diff --git a/server/plugin/pkg/discovery/k8s/adaptor/kube_client.go b/server/plugin/pkg/discovery/k8s/adaptor/kube_client.go index 422d9a93..b1422d07 100644 --- a/server/plugin/pkg/discovery/k8s/adaptor/kube_client.go +++ b/server/plugin/pkg/discovery/k8s/adaptor/kube_client.go @@ -178,6 +178,19 @@ func (c *K8sClient) GetService(namespace, name string) (svc *v1.Service) { return } +func (c *K8sClient) GetEndpoints(namespace, name string) (ep *v1.Endpoints) { + obj, ok, err := c.Endpoints().GetStore().GetByKey(getFullName(namespace, name)) + if err != nil { + log.Errorf(err, "get k8s endpoints[%s/%s] failed", namespace, name) + return + } + if !ok { + return + } + ep = obj.(*v1.Endpoints) + return +} + func (c *K8sClient) GetPodByIP(ip string) (pod *v1.Pod) { itf, ok := c.ipIndex.Get(ip) if !ok { diff --git a/server/plugin/pkg/discovery/servicecenter/aggregate.go b/server/plugin/pkg/discovery/servicecenter/aggregate.go index fd14ad63..fb3e818a 100644 --- a/server/plugin/pkg/discovery/servicecenter/aggregate.go +++ b/server/plugin/pkg/discovery/servicecenter/aggregate.go @@ -16,16 +16,30 @@ package servicecenter import ( + "crypto/tls" "github.com/apache/incubator-servicecomb-service-center/pkg/client/sc" "github.com/apache/incubator-servicecomb-service-center/pkg/log" "github.com/apache/incubator-servicecomb-service-center/server/admin/model" pb "github.com/apache/incubator-servicecomb-service-center/server/core/proto" scerr "github.com/apache/incubator-servicecomb-service-center/server/error" + mgr "github.com/apache/incubator-servicecomb-service-center/server/plugin" "github.com/apache/incubator-servicecomb-service-center/server/plugin/pkg/registry" + "strings" ) type SCClientAggregate []*sc.SCClient +var clientTLS *tls.Config + +func getClientTLS() (*tls.Config, error) { + if clientTLS != nil { + return clientTLS, nil + } + var err error + clientTLS, err = mgr.Plugins().TLS().ClientConfig() + return clientTLS, err +} + func (c *SCClientAggregate) GetScCache() (*model.Cache, error) { var caches model.Cache for _, client := range *c { @@ -90,6 +104,14 @@ func NewSCClientAggregate() *SCClientAggregate { continue } client.Timeout = registry.Configuration().RequestTimeOut + if strings.Index(addr[0], "https") >= 0 { + client.TLS, err = getClientTLS() + if err != nil { + log.Errorf(err, "get service center[%s][%s] tls config failed", name, addr) + continue + } + } + *c = append(*c, client) log.Infof("new service center[%s][%s] client", name, addr) } diff --git a/server/plugin/pkg/discovery/servicecenter/cluster.go b/server/plugin/pkg/discovery/servicecenter/cluster.go index 5c0bdd01..e6f4be93 100644 --- a/server/plugin/pkg/discovery/servicecenter/cluster.go +++ b/server/plugin/pkg/discovery/servicecenter/cluster.go @@ -93,7 +93,6 @@ func (c *ServiceCenterCluster) Sync(ctx context.Context) error { } // microservice - // TODO remove duplicate SERVICECENTER serviceCacher, ok := c.cachers[backend.SERVICE] if ok { c.check(serviceCacher, &cache.Microservices) @@ -132,7 +131,12 @@ func (c *ServiceCenterCluster) Sync(ctx context.Context) error { } func (c *ServiceCenterCluster) check(local *ServiceCenterCacher, remote model.Getter) { + exists := make(map[string]struct{}) remote.ForEach(func(_ int, v *model.KV) bool { + if _, ok := exists[v.Key]; ok { + return true + } + exists[v.Key] = struct{}{} kv := local.Cache().Get(v.Key) newKv := &discovery.KeyValue{ Key: util.StringToBytesWithNoCopy(v.Key), diff --git a/server/plugin/pkg/registry/config.go b/server/plugin/pkg/registry/config.go index fbfa9f3b..b75cfa4b 100644 --- a/server/plugin/pkg/registry/config.go +++ b/server/plugin/pkg/registry/config.go @@ -43,23 +43,39 @@ type Config struct { func (c *Config) InitClusters() { c.Clusters = make(Clusters) - kvs := strings.Split(c.ClusterAddresses, ",") - for _, cluster := range kvs { - // sc-0=http(s)://host1:port1|http(s)://host2:port2 - names := strings.Split(cluster, "=") - if len(names) != 2 { - continue + // sc-0=http(s)://host1:port1,http(s)://host2:port2,sc-1=http(s)://host3:port3 + kvs := strings.Split(c.ClusterAddresses, "=") + if l := len(kvs); l >= 2 { + var ( + names []string + addrs [][]string + ) + for i := 0; i < l; i++ { + ss := strings.Split(kvs[i], ",") + sl := len(ss) + if i != l-1 { + names = append(names, ss[sl-1]) + } + if i != 0 { + if sl > 1 && i != l-1 { + addrs = append(addrs, ss[:sl-1]) + } else { + addrs = append(addrs, ss) + } + } + } + for i, name := range names { + c.Clusters[name] = addrs[i] } - c.Clusters[names[0]] = strings.Split(names[1], "|") } if len(c.Clusters) == 0 { c.Clusters[c.ClusterName] = []string{c.ClusterAddresses} } } -// ClusterAddress return the address of current SC's registry backend -func (c *Config) ClusterAddress() string { - return c.Clusters[c.ClusterName][0] +// RegistryAddresses return the address of current SC's registry backend +func (c *Config) RegistryAddresses() []string { + return c.Clusters[c.ClusterName] } func Configuration() *Config { diff --git a/server/plugin/pkg/registry/etcd/etcd.go b/server/plugin/pkg/registry/etcd/etcd.go index c940828b..0dd4f837 100644 --- a/server/plugin/pkg/registry/etcd/etcd.go +++ b/server/plugin/pkg/registry/etcd/etcd.go @@ -751,7 +751,7 @@ func (c *EtcdClient) ReOpen() error { func (c *EtcdClient) parseEndpoints() { // use the default cluster endpoints - addrs := strings.Split(registry.Configuration().ClusterAddress(), ",") + addrs := registry.Configuration().RegistryAddresses() endpoints := make([]string, 0, len(addrs)) for _, addr := range addrs { diff --git a/server/plugin/pkg/registry/etcd/etcd_test.go b/server/plugin/pkg/registry/etcd/etcd_test.go index 5fc3fa67..f3856b47 100644 --- a/server/plugin/pkg/registry/etcd/etcd_test.go +++ b/server/plugin/pkg/registry/etcd/etcd_test.go @@ -29,6 +29,7 @@ import ( "net/http" "os" "strconv" + "strings" "sync" "testing" "time" @@ -42,6 +43,49 @@ var ( endpoint = registry.Configuration().ClusterAddresses ) +func TestInitCluster(t *testing.T) { + registry.Configuration().ClusterAddresses = "127.0.0.1:2379" + registry.Configuration().InitClusters() + if strings.Join(registry.Configuration().RegistryAddresses(), ",") != "127.0.0.1:2379" { + t.Fatalf("TestInitCluster failed, %v", registry.Configuration().RegistryAddresses()) + } + registry.Configuration().ClusterAddresses = "127.0.0.1:2379,127.0.0.2:2379" + registry.Configuration().InitClusters() + if strings.Join(registry.Configuration().RegistryAddresses(), ",") != "127.0.0.1:2379,127.0.0.2:2379" { + t.Fatalf("TestInitCluster failed, %v", registry.Configuration().RegistryAddresses()) + } + registry.Configuration().ClusterName = "sc-0" + registry.Configuration().ClusterAddresses = "sc-0=127.0.0.1:2379,127.0.0.2:2379" + registry.Configuration().InitClusters() + if strings.Join(registry.Configuration().RegistryAddresses(), ",") != "127.0.0.1:2379,127.0.0.2:2379" { + t.Fatalf("TestInitCluster failed, %v", registry.Configuration().RegistryAddresses()) + } + if strings.Join(registry.Configuration().Clusters["sc-0"], ",") != "127.0.0.1:2379,127.0.0.2:2379" { + t.Fatalf("TestInitCluster failed, %v", registry.Configuration().RegistryAddresses()) + } + registry.Configuration().ClusterName = "sc-0" + registry.Configuration().ClusterAddresses = "sc-1=127.0.0.1:2379,127.0.0.2:2379,sc-2=127.0.0.3:2379" + registry.Configuration().InitClusters() + if strings.Join(registry.Configuration().RegistryAddresses(), ",") != "" { + t.Fatalf("TestInitCluster failed, %v", registry.Configuration().RegistryAddresses()) + } + if strings.Join(registry.Configuration().Clusters["sc-1"], ",") != "127.0.0.1:2379,127.0.0.2:2379" { + t.Fatalf("TestInitCluster failed, %v", registry.Configuration().RegistryAddresses()) + } + if strings.Join(registry.Configuration().Clusters["sc-2"], ",") != "127.0.0.3:2379" { + t.Fatalf("TestInitCluster failed, %v", registry.Configuration().RegistryAddresses()) + } + registry.Configuration().ClusterName = "sc-0" + registry.Configuration().ClusterAddresses = "sc-0=127.0.0.1:2379,sc-1=127.0.0.3:2379,127.0.0.4:2379" + registry.Configuration().InitClusters() + if strings.Join(registry.Configuration().RegistryAddresses(), ",") != "127.0.0.1:2379" { + t.Fatalf("TestInitCluster failed, %v", registry.Configuration().RegistryAddresses()) + } + if strings.Join(registry.Configuration().Clusters["sc-1"], ",") != "127.0.0.3:2379,127.0.0.4:2379" { + t.Fatalf("TestInitCluster failed, %v", registry.Configuration().RegistryAddresses()) + } +} + func TestEtcdClient(t *testing.T) { etcd := &EtcdClient{ Endpoints: []string{endpoint}, ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org > Support sync distinct Kubernetes service types to service-center > ---------------------------------------------------------------- > > Key: SCB-953 > URL: https://issues.apache.org/jira/browse/SCB-953 > Project: Apache ServiceComb > Issue Type: Improvement > Components: Service-Center > Reporter: little-cui > Assignee: little-cui > Priority: Major > Fix For: service-center-1.1.0 > > -- This message was sent by Atlassian JIRA (v7.6.3#76005)