Merge pull request #2 from crystaldust/docs/istio-as-controlplane
Add docs to use Istio as control plane.
diff --git a/.gitignore b/.gitignore
index 6a5366d..e50b616 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,4 +28,4 @@
_build
coverage.txt
-go.sum
\ No newline at end of file
+go.sum
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..4f90ccd
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,49 @@
+language: go
+sudo: required
+go:
+ - 1.11
+install: true
+
+before_script:
+ - mkdir -p $HOME/gopath/src/github.com/go-mesh/mesher
+ - rsync -az ${TRAVIS_BUILD_DIR}/ $HOME/gopath/src/github.com/go-mesh/mesher
+ - export TRAVIS_BUILD_DIR=$HOME/gopath/src/github.com/go-mesh/mesher
+ - export KUBE_CONFIG=$HOME/gopath/src/github.com/go-mesh/mesher/vendor/github.com/go-mesh/mesher-tools/test/util/sample_kubeconfig
+ - cd $HOME/gopath/src/github.com/go-mesh/mesher
+jobs:
+ include:
+ - stage: Format Checker
+ script: bash -x scripts/travis/formatChecker.sh
+ - stage: DeadCode Checker
+ script:
+ - go get -u github.com/tsenart/deadcode
+ - bash -x scripts/travis/deadCodeChecker.sh
+ - stage: Misspell Checker
+ script:
+ - go get -u github.com/client9/misspell
+ - bash -x scripts/travis/misspellChecker.sh
+ - stage: GoConst Checker
+ script:
+ - go get -u github.com/jgautheron/goconst/cmd/goconst
+ - bash -x scripts/travis/goConstChecker.sh
+ - stage: GoLint Checker
+ script:
+ - go get -u github.com/golang/lint/golint
+ - bash -x scripts/travis/goLintChecker.sh
+ - stage: GoCyclo Checker
+ script:
+ - go get github.com/fzipp/gocyclo
+ - bash -x scripts/travis/goCycloChecker.sh
+ - stage: Build
+ script:
+ - GO111MODULE=on go mod download
+ - GO111MODULE=on go mod vendor
+ - go build
+ - stage: Unit Test
+ script:
+ - go get github.com/mattn/goveralls
+ - go get golang.org/x/tools/cmd/cover
+ - GO111MODULE=on go mod download
+ - GO111MODULE=on go mod vendor
+ - bash -x scripts/travis/unit_test.sh && $HOME/gopath/bin/goveralls -coverprofile=coverage.txt -service=travis-ci
+
diff --git a/README.md b/README.md
index 3519ed0..ab9f9ea 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Mesher
-[![Build Status](https://travis-ci.org/go-chassis/mesher.svg?branch=master)](https://travis-ci.org/go-chassis/mesher) [![Coverage Status](https://coveralls.io/repos/github/go-chassis/mesher/badge.svg?branch=master)](https://coveralls.io/github/go-chassis/mesher?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/go-chassis/mesher)](https://goreportcard.com/report/github.com/go-chassis/mesher) [![GoDoc](https://godoc.org/github.com/go-chassis/mesher?status.svg)](https://godoc.org/github.com/go-chassis/mesher) [![HitCount](http://hits.dwyl.io/go-chassis/mesher.svg)](http://hits.dwyl.io/go-chassis/mesher) [![Join Slack](https://img.shields.io/badge/Join-Slack-orange.svg)](https://join.slack.com/t/go-chassis/shared_invite/enQtMzk0MzAyMjEzNzEyLTRjOWE3NzNmN2IzOGZhMzZkZDFjODM1MDc5ZWI0YjcxYjM1ODNkY2RkNmIxZDdlOWI3NmQ0MTg3NzBkNGExZGU)
+[![Build Status](https://travis-ci.org/go-mesh/mesher.svg?branch=master)](https://travis-ci.org/go-mesh/mesher) [![Coverage Status](https://coveralls.io/repos/github/go-mesh/mesher/badge.svg?branch=master)](https://coveralls.io/github/go-mesh/mesher?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/go-mesh/mesher)](https://goreportcard.com/report/github.com/go-mesh/mesher) [![GoDoc](https://godoc.org/github.com/go-mesh/mesher?status.svg)](https://godoc.org/github.com/go-mesh/mesher) [![HitCount](http://hits.dwyl.io/go-mesh/mesher.svg)](http://hits.dwyl.io/go-mesh/mesher) [![Join Slack](https://img.shields.io/badge/Join-Slack-orange.svg)](https://join.slack.com/t/go-chassis/shared_invite/enQtMzk0MzAyMjEzNzEyLTRjOWE3NzNmN2IzOGZhMzZkZDFjODM1MDc5ZWI0YjcxYjM1ODNkY2RkNmIxZDdlOWI3NmQ0MTg3NzBkNGExZGU)
A service mesh implementation based on [go chassis](https://github.com/go-chassis/go-chassis).
@@ -20,7 +20,7 @@
# Get started
-Refer to [mesher-examples](https://github.com/go-chassis/mesher-examples)
+Refer to [mesher-examples](https://github.com/go-mesh/mesher-examples)
### How to build and run
diff --git a/adminapi/adminService.go b/adminapi/adminService.go
index deaa53d..9fd8dea 100644
--- a/adminapi/adminService.go
+++ b/adminapi/adminService.go
@@ -25,6 +25,5 @@
//RegisterWebService creates route and returns all admin api's
func RegisterWebService() {
-
chassis.RegisterSchema("rest-admin", &Admin{})
}
diff --git a/adminapi/router.go b/adminapi/router.go
index d007553..fcf808f 100644
--- a/adminapi/router.go
+++ b/adminapi/router.go
@@ -26,22 +26,20 @@
chassisTLS "github.com/go-chassis/go-chassis/core/tls"
"github.com/go-mesh/mesher/common"
"github.com/go-mesh/mesher/config"
- "github.com/go-mesh/mesher/metrics"
+ "github.com/go-mesh/openlogging"
)
//Init function initiates admin server config and runs it
func Init() (err error) {
isAdminEnable := config.GetConfig().Admin.Enable
- if isAdminEnable != nil && *isAdminEnable == false {
+ if !isAdminEnable {
lager.Logger.Infof("admin api are not enable")
return nil
}
- metrics.Init()
- go func() {
- RegisterWebService()
- }()
+ openlogging.GetLogger().Info("enable admin API")
+ RegisterWebService()
return
}
diff --git a/bootstrap/bootstrap.go b/bootstrap/bootstrap.go
index a5563a7..2c2c516 100644
--- a/bootstrap/bootstrap.go
+++ b/bootstrap/bootstrap.go
@@ -33,6 +33,8 @@
chassisHandler "github.com/go-chassis/go-chassis/core/handler"
"github.com/go-chassis/go-chassis/core/lager"
"github.com/go-chassis/go-chassis/core/metadata"
+ "github.com/go-mesh/mesher/pkg/metrics"
+ "github.com/go-mesh/mesher/pkg/runtime"
)
// Start initialize configs and components
@@ -49,6 +51,7 @@
if err := DecideMode(); err != nil {
return err
}
+ metrics.Init()
if err := adminapi.Init(); err != nil {
log.Println("Error occurred in starting admin server", err)
}
@@ -65,8 +68,8 @@
//DecideMode get config mode
func DecideMode() error {
- config.Mode = cmd.Configs.Mode
- lager.Logger.Info("Running as "+config.Mode, nil)
+ runtime.Mode = cmd.Configs.Mode
+ lager.Logger.Info("Running as "+runtime.Mode, nil)
return nil
}
@@ -109,6 +112,7 @@
}
providerChainMap := map[string]string{
common.ChainProviderIncoming: providerChain,
+ "default": chassisHandler.RatelimiterProvider,
}
chassis.SetDefaultConsumerChains(consumerChainMap)
chassis.SetDefaultProviderChains(providerChainMap)
diff --git a/conf/chassis.yaml b/conf/chassis.yaml
index 6858121..c0a03ac 100644
--- a/conf/chassis.yaml
+++ b/conf/chassis.yaml
@@ -6,7 +6,7 @@
http:
listenAddress: 127.0.0.1:30101
rest-admin:
- listenAddress: 0.0.0.0:30102 # listen addr use to adminAPI
+ listenAddress: 127.0.0.1:30102 # listen addr use to adminAPI
service:
registry:
address: http://127.0.0.1:30100 # uri of service center
diff --git a/conf/mesher.yaml b/conf/mesher.yaml
index 0355e3e..f812844 100644
--- a/conf/mesher.yaml
+++ b/conf/mesher.yaml
@@ -3,8 +3,9 @@
# destinationResolver:
# http: host # how to turn host to destination name. default to service name,
-##admin: #admin API
-# goRuntimeMetrics : true # enable metrics
+admin: #admin API
+ goRuntimeMetrics : true # enable metrics
+ enable: true
## enable pprof to profile mesher runtime
#pprof:
diff --git a/config/config.go b/config/config.go
index 915c361..14f6cd5 100644
--- a/config/config.go
+++ b/config/config.go
@@ -37,8 +37,6 @@
ConfFile = "mesher.yaml"
)
-//Mode is of type string which gives mode of mesher deployment
-var Mode string
var mesherConfig *MesherConfig
//GetConfig returns mesher config
diff --git a/config/struct.go b/config/struct.go
index 59c9852..e36e6aa 100644
--- a/config/struct.go
+++ b/config/struct.go
@@ -45,7 +45,7 @@
//Admin has attributes for enabling, serverURI and metrics for admin data
type Admin struct {
- Enable *bool `yaml:"enable"`
+ Enable bool `yaml:"enable"`
ServerURI string `yaml:"serverUri"`
GoRuntimeMetrics bool `yaml:"goRuntimeMetrics"`
}
diff --git a/docs/getstarted/install.md b/docs/getstarted/install.md
index 4eed0d0..22dd962 100644
--- a/docs/getstarted/install.md
+++ b/docs/getstarted/install.md
@@ -40,7 +40,7 @@
### Run on different infrastructure
Mesher does not bind to any platform or infrastructures, plz refer to
-https://github.com/go-chassis/mesher-examples/tree/master/Infrastructure
+https://github.com/go-mesh/mesher-examples/tree/master/Infrastructure
to know how to run mesher on different infra
### Sidecar injector
diff --git a/docs/protocols/grpc.md b/docs/protocols/grpc.md
index f556c7b..3047ef5 100644
--- a/docs/protocols/grpc.md
+++ b/docs/protocols/grpc.md
@@ -29,3 +29,7 @@
return net.DialTimeout("tcp", "127.0.0.1:40101", time)
}))
```
+
+
+## example
+A gRPC example is [here](https://github.com/go-mesh/mesher-examples/tree/master/protocol/grpc-go)
diff --git a/docs/sidecar.rst b/docs/sidecar.rst
index c14df2f..7f86ad6 100644
--- a/docs/sidecar.rst
+++ b/docs/sidecar.rst
@@ -151,7 +151,7 @@
~~~~~~~~~~~~~~~~~~~~
To use service-center following are the required annotation to be given in client and server yaml file
-sidecar.mesher.io/inject: "yes" and sidecar.mesher.io/discoveryType:"pilot"
+sidecar.mesher.io/inject: "yes" and sidecar.mesher.io/discoveryType:"sc"
`Example to use sc registry <https://github.com/go-chassis/sidecar-injector/tree/master/example/WithoutServicePort/sc>`_
diff --git a/go.mod b/go.mod
index 92a15e2..bbadbc6 100644
--- a/go.mod
+++ b/go.mod
@@ -1,16 +1,79 @@
-module github.com/go-chassis/mesher
+module github.com/go-mesh/mesher
require (
+ cloud.google.com/go v0.28.0 // indirect
+ code.cloudfoundry.org/copilot v0.0.0-20180928002835-76734bdb9045 // indirect
+ fortio.org/fortio v1.3.0 // indirect
github.com/emicklei/go-restful-swagger12 v0.0.0-20170926063155-7524189396c6 // indirect
+ github.com/envoyproxy/go-control-plane v0.6.0
+
github.com/go-chassis/go-cc-client v0.0.0-20180831085349-c2bb6cef1640
- github.com/go-chassis/go-chassis v0.8.2-0.20180831125844-6a2f0ab47244
+ github.com/go-chassis/go-chassis v0.8.3-0.20180914033538-0791a5cec8b4
github.com/go-chassis/gohessian v0.0.0-20180702061429-e5130c25af55
+ github.com/go-mesh/mesher-tools v0.0.0-20181006103649-cdc091b78a72
+ github.com/go-mesh/openlogging v0.0.0-20180831021158-f5d1c4e7e506
github.com/gogo/protobuf v1.1.1
+ github.com/gogo/status v1.0.3 // indirect
+ github.com/golang/groupcache v0.0.0-20180924190550-6f2cf27854a4 // indirect
+ github.com/golang/sync v0.0.0-20180314180146-1d60e4601c6f // indirect
+ github.com/google/go-github v17.0.0+incompatible // indirect
+ github.com/google/go-querystring v1.0.0 // indirect
+ github.com/google/uuid v1.0.0 // indirect
+ github.com/gorilla/context v1.1.1 // indirect
+ github.com/gorilla/mux v1.6.2 // indirect
+ github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect
+ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
+ github.com/hashicorp/consul v1.2.3 // indirect
+ github.com/hashicorp/go-cleanhttp v0.5.0 // indirect
+ github.com/hashicorp/go-multierror v1.0.0 // indirect
+ github.com/hashicorp/go-rootcerts v0.0.0-20160503143440-6bb64b370b90 // indirect
+ github.com/hashicorp/serf v0.8.1 // indirect
+ github.com/howeyc/fsnotify v0.9.0 // indirect
+ github.com/inconshreveable/mousetrap v1.0.0 // indirect
+ github.com/mitchellh/go-homedir v1.0.0 // indirect
+ github.com/mitchellh/mapstructure v1.0.0 // indirect
+ github.com/natefinch/lumberjack v2.0.0+incompatible // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible
+ github.com/pkg/errors v0.8.0 // indirect
github.com/prometheus/client_golang v0.8.0
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910
+ github.com/prometheus/prom2json v0.0.0-20180620215746-7b8ed2aed129 // indirect
+ github.com/spf13/cobra v0.0.3 // indirect
github.com/stretchr/testify v1.2.2
github.com/urfave/cli v0.0.0-20180821064027-934abfb2f102
+ go.uber.org/atomic v1.3.2 // indirect
+ go.uber.org/multierr v1.1.0 // indirect
+ go.uber.org/zap v1.9.1 // indirect
+ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be // indirect
+ google.golang.org/appengine v1.2.0 // indirect
google.golang.org/grpc v1.14.0
+ gopkg.in/validator.v2 v2.0.0-20180514200540-135c24b11c19 // indirect
gopkg.in/yaml.v2 v2.2.1
+ istio.io/api v0.0.0-20180926203357-0cf306e2fd19 // indirect
+ istio.io/fortio v1.3.0 // indirect
+ istio.io/istio v0.0.0-20180929031539-a8986e2dc2c3
+ k8s.io/apiextensions-apiserver v0.0.0-20180925155151-ce69c54e57693220512104c84941e2ef1876449a // indirect
+ k8s.io/apimachinery v0.0.0-20180823151430-fda675fbe85280c4550452dae2a5ebf74e4a59b7
+ k8s.io/client-go v8.0.0+incompatible
+ k8s.io/cluster-registry v0.0.6 // indirect
+
+ k8s.io/ingress v0.0.0-20170803151325-fe19ebb09ee2 // indirect
+ k8s.io/kube-openapi v0.0.0-20180928070517-c01ed926f124 // indirect
+)
+
+replace (
+ cloud.google.com/go v0.28.0 => github.com/GoogleCloudPlatform/google-cloud-go v0.28.0
+ github.com/envoyproxy/go-control-plane v0.6.0 => github.com/envoyproxy/go-control-plane v0.0.0-20180918192855-2137d919632883e52e7786f55f0f84e52a44fbf3
+ github.com/kubernetes/client-go => ../k8s.io/client-go
+ golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac => github.com/golang/crypto v0.0.0-20180820150726-614d502a4dac
+ golang.org/x/net v0.0.0-20180724234803-3673e40ba225 => github.com/golang/net v0.0.0-20180724234803-3673e40ba225
+ golang.org/x/net v0.0.0-20180824152047-4bcd98cce591 => github.com/golang/net v0.0.0-20180824152047-4bcd98cce591
+
+ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be => github.com/golang/oauth2 v0.0.0-20180821212333-d2e6202438be
+ golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87 => github.com/golang/sys v0.0.0-20180824143301-4910a1d54f87
+ golang.org/x/text v0.3.0 => github.com/golang/text v0.3.0
+ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 => github.com/golang/time v0.0.0-20180412165947-fbb02b2291d2
+ google.golang.org/appengine v1.2.0 => github.com/golang/appengine v1.2.0
+ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 => github.com/google/go-genproto v0.0.0-20180817151627-c66870c02cf8
+ google.golang.org/grpc v1.14.0 => github.com/grpc/grpc-go v1.14.0
)
diff --git a/go.sum b/go.sum
deleted file mode 100644
index d926a62..0000000
--- a/go.sum
+++ /dev/null
@@ -1,155 +0,0 @@
-github.com/DataDog/datadog-go v0.0.0-20180330214955-e67964b4021a/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
-github.com/Shopify/sarama v1.17.0 h1:Y2/FBwElFVwt7aLKL3fDG6hh+rrlywR6uLgTgKObwTc=
-github.com/Shopify/sarama v1.17.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
-github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
-github.com/apache/thrift v0.0.0-20180807212849-6e67faa92827 h1:47CwjpyuyVwNGpyQfraO51g8eYske6pu/mb2Q4vB3SY=
-github.com/apache/thrift v0.0.0-20180807212849-6e67faa92827/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
-github.com/apache/thrift v0.0.0-20180829120307-8de3749235db h1:wK8K96PXMirNKpbyEdOuDHSGC50bDH4iOJNO5jvZeNI=
-github.com/apache/thrift v0.0.0-20180829120307-8de3749235db/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
-github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
-github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
-github.com/cactus/go-statsd-client v3.1.1+incompatible/go.mod h1:cMRcwZDklk7hXp+Law83urTHUiHMzCev/r4JMYr/zU0=
-github.com/cenkalti/backoff v2.0.0+incompatible h1:5IIPUHhlnUZbcHQsQou5k1Tn58nJkeJL9U+ig5CHJbY=
-github.com/cenkalti/backoff v2.0.0+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
-github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/eapache/go-resiliency v1.1.0 h1:1NtRmCAqadE2FN4ZcN6g90TP3uk8cg9rn9eNK2197aU=
-github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
-github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
-github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
-github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc=
-github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
-github.com/emicklei/go-restful v2.8.0+incompatible h1:wN8GCRDPGHguIynsnBartv5GUgGUg1LAU7+xnSn1j7Q=
-github.com/emicklei/go-restful v2.8.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
-github.com/emicklei/go-restful-swagger12 v0.0.0-20170208215640-dcef7f557305/go.mod h1:qr0VowGBT4CS4Q8vFF8BSeKz34PuqKGxs/L0IAQA9DQ=
-github.com/emicklei/go-restful-swagger12 v0.0.0-20170926063155-7524189396c6 h1:V94anc0ZG3Pa/cAMwP2m1aQW3+/FF8Qmw/GsFyTJAp4=
-github.com/emicklei/go-restful-swagger12 v0.0.0-20170926063155-7524189396c6/go.mod h1:qr0VowGBT4CS4Q8vFF8BSeKz34PuqKGxs/L0IAQA9DQ=
-github.com/envoyproxy/go-control-plane v0.5.0 h1:sXNEwucP7EkLn00DBvEJRXrRs5sQyZW45LzBR2AhYxs=
-github.com/envoyproxy/go-control-plane v0.5.0/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
-github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
-github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/go-chassis/go-archaius v0.0.0-20180801075410-885b00ca6929 h1:crQCNWCeyZTHKfHdDC7xDmXpdTAA/zXk2ou6qZXPgdI=
-github.com/go-chassis/go-archaius v0.0.0-20180801075410-885b00ca6929/go.mod h1:wahnwKS5N7/4ozbNiqPgctqjT7DxL7JH5VKd3FnSWDI=
-github.com/go-chassis/go-archaius v0.0.0-20180831094429-1e6b20d2a085 h1:iR8lcvTCIJDDyALxDLrxoLZUfiWwUJwZOaItjJXgbFY=
-github.com/go-chassis/go-archaius v0.0.0-20180831094429-1e6b20d2a085/go.mod h1:wahnwKS5N7/4ozbNiqPgctqjT7DxL7JH5VKd3FnSWDI=
-github.com/go-chassis/go-cc-client v0.0.0-20180803084655-75b751c2f183 h1:tOCz2KrXKBz1i0tE0JAkQ/fL7uXQtDcJi1CUbe0/oQo=
-github.com/go-chassis/go-cc-client v0.0.0-20180803084655-75b751c2f183/go.mod h1:6P5JmlcKZBlAVebxGgfGnKlsZ3UKLfO2VfyhJ1nO82c=
-github.com/go-chassis/go-cc-client v0.0.0-20180831085349-c2bb6cef1640 h1:o4wHmHChm8sOe++xtGXQsmeFpugdqW+yGZN2VuQaPwY=
-github.com/go-chassis/go-cc-client v0.0.0-20180831085349-c2bb6cef1640/go.mod h1:6P5JmlcKZBlAVebxGgfGnKlsZ3UKLfO2VfyhJ1nO82c=
-github.com/go-chassis/go-chassis v0.0.0-20180825083348-3f0dea26ded2 h1:EACl4+vnfD0IAqJCchdoNXP+xfmvBMZlnlARu6nRvqo=
-github.com/go-chassis/go-chassis v0.0.0-20180825083348-3f0dea26ded2/go.mod h1:yoQcnkPOT3nLE+FLITgktmqKziiXtnztO4PlVAMU/nQ=
-github.com/go-chassis/go-chassis v0.7.2-0.20180828015440-350cf4bb7119 h1:5z9ooiNcBOaLxWrL/3Rk+DQfajpT0Ipq4jRyqc4z2IM=
-github.com/go-chassis/go-chassis v0.7.2-0.20180828015440-350cf4bb7119/go.mod h1:yoQcnkPOT3nLE+FLITgktmqKziiXtnztO4PlVAMU/nQ=
-github.com/go-chassis/go-chassis v0.7.2-0.20180828032500-d9b2138fb00b h1:lYezzXzKmmPG+oYvcTAQkRZFV+1aPZPbuIpsIj1hIZY=
-github.com/go-chassis/go-chassis v0.7.2-0.20180828032500-d9b2138fb00b/go.mod h1:yoQcnkPOT3nLE+FLITgktmqKziiXtnztO4PlVAMU/nQ=
-github.com/go-chassis/go-chassis v0.8.2-0.20180831125844-6a2f0ab47244 h1:elNu5tWleXV5uZmdEpW7Y1PJD6OyhBPN+ZZSKuPWJKM=
-github.com/go-chassis/go-chassis v0.8.2-0.20180831125844-6a2f0ab47244/go.mod h1:qYnF5AEh6HjcZsDcFVwDr00K06q5BDGhdzWnmC8AtHk=
-github.com/go-chassis/go-chassis-plugins v0.0.0-20180731065901-7b05d8d2fbe6/go.mod h1:DqeW7HKONWncHIQhtEus/nNpe7N15F7c43V9p4AqaHM=
-github.com/go-chassis/go-sc-client v0.0.0-20180817094046-3be308d3a0a3 h1:gF6sWwBMfEPtEVr5aRY2yj57+CiagrcMofND1Co6CU8=
-github.com/go-chassis/go-sc-client v0.0.0-20180817094046-3be308d3a0a3/go.mod h1:evzKZXMnMFCLPc5oGHYx8MAJlQRYMptkMYdvJN8GzwI=
-github.com/go-chassis/go-sc-client v0.0.0-20180831081217-8135c6df7f96 h1:+CwasSmqeqHut6G4CxURqCqd6QcRjCl5LoUZHaL148Y=
-github.com/go-chassis/go-sc-client v0.0.0-20180831081217-8135c6df7f96/go.mod h1:IS3XXS6JdNbKP4K7duT+q2Gk8+yJq5EUh+5zTMWnCDg=
-github.com/go-chassis/gohessian v0.0.0-20180702061429-e5130c25af55 h1:7DMPFTM7YBCSWfk1G3O/EpksFz+7BcjEEGR0rUSpB2c=
-github.com/go-chassis/gohessian v0.0.0-20180702061429-e5130c25af55/go.mod h1:UkW8yQ1q1hUoiHEMadjc3psAf4nSZdDIPVP4lt4bqlE=
-github.com/go-chassis/paas-lager v0.0.0-20180727081842-50655443dc96 h1:VViSMNCEKU0iqveFWVJpmel5aGgE6UOOUr/ZHhWa8B4=
-github.com/go-chassis/paas-lager v0.0.0-20180727081842-50655443dc96/go.mod h1:tILYbn3+0jjCxhY6/ue9L8eRq+VJ60U6VYIdugqchB4=
-github.com/go-chassis/paas-lager v0.0.0-20180831030822-312e8737a225 h1:rMCN+v6YrQsliVFo/ThdZpu0XIQN6+4HHz2uPOa7/2Q=
-github.com/go-chassis/paas-lager v0.0.0-20180831030822-312e8737a225/go.mod h1:tILYbn3+0jjCxhY6/ue9L8eRq+VJ60U6VYIdugqchB4=
-github.com/go-logfmt/logfmt v0.3.0 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2ic=
-github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
-github.com/go-mesh/openlogging v0.0.0-20180831021158-f5d1c4e7e506 h1:o2Hx9jC8VVv406dDh+Dy8Hi2ZCGAGA+0WpnezaMb0DY=
-github.com/go-mesh/openlogging v0.0.0-20180831021158-f5d1c4e7e506/go.mod h1:qaKi+amO+hsGin2q1GmW+/NcbZpMPnTufwrWzDmIuuU=
-github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
-github.com/gogo/googleapis v1.1.0 h1:kFkMAZBNAn4j7K0GiZr8cRYzejq68VbheufiV3YuyFI=
-github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
-github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
-github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
-github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
-github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
-github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
-github.com/gopherjs/gopherjs v0.0.0-20180820052304-89baedc74dd7/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gorilla/websocket v1.3.0 h1:r/LXc0VJIMd0rCMsc6DxgczaQtoCwCLatnfXmSYcXx8=
-github.com/gorilla/websocket v1.3.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
-github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
-github.com/hashicorp/go-version v1.0.0 h1:21MVWPKDphxa7ineQQTrCU5brh7OuVVAzGOCnnCPtE8=
-github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
-github.com/hashicorp/golang-lru v0.0.0-20180201235237-0fb14efe8c47/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/json-iterator/go v0.0.0-20180806060727-1624edc4454b h1:X61dhFTE1Au92SvyF8HyAwdjWqiSdfBgFR7wTxC0+uU=
-github.com/json-iterator/go v0.0.0-20180806060727-1624edc4454b/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
-github.com/lyft/protoc-gen-validate v0.0.6 h1:4YInPV0jraTH7uUZl/xq5m9nhckBdUSAl9HlFgq1HPA=
-github.com/lyft/protoc-gen-validate v0.0.6/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
-github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
-github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 h1:lM6RxxfUMrYL/f8bWEUqdXrANWtrL7Nndbm9iFN0DlU=
-github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
-github.com/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg=
-github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
-github.com/openzipkin-contrib/zipkin-go-opentracing v0.0.0-20180726151020-b85dc675b16b h1:sM8Q+fCKUVflyDurBCk+3Cwl8KG12QAeO0eE3HzPRCg=
-github.com/openzipkin-contrib/zipkin-go-opentracing v0.0.0-20180726151020-b85dc675b16b/go.mod h1:uVHyebswE1cCXr2A73cRM2frx5ld1RJUCJkFNZ90ZiI=
-github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
-github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
-github.com/petar/GoLLRB v0.0.0-20130427215148-53be0d36a84c/go.mod h1:HUpKUBZnpzkdx0kD/+Yfuft+uD3zHGtXF/XJB14TUr4=
-github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
-github.com/pierrec/lz4 v2.0.3+incompatible h1:h0ipQUMRrnr+/HHhxhceftyXk4QcZsmxSNliSG75Bi0=
-github.com/pierrec/lz4 v2.0.3+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
-github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
-github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v0.8.0 h1:1921Yw9Gc3iSc4VQh3PIoOqgPCZS7G/4xQNVUp8Mda8=
-github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 h1:idejC8f05m9MGOsuEi1ATq9shN03HrxNkD/luQvxCv8=
-github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e h1:n/3MEhJQjQxrOUCzh1Y3Re6aJUUWRp2M9+Oc3eVn/54=
-github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
-github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273 h1:agujYaXJSxSo18YNX3jzl+4G6Bstwt+kqv47GS12uL0=
-github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165 h1:nkcn14uNmFEuGCb2mBZbBb24RdNRL08b/wb+xBOYpuk=
-github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
-github.com/shirou/gopsutil v0.0.0-20180801053943-8048a2e9c577/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
-github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
-github.com/smartystreets/assertions v0.0.0-20180301161246-7678a5452ebe/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
-github.com/smartystreets/goconvey v0.0.0-20170602164621-9e8dc3f972df/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
-github.com/spf13/cast v1.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg=
-github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
-github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
-github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/urfave/cli v0.0.0-20180821064027-934abfb2f102 h1:Er7kUEUX12vAWCp23Uv6Nrza7kEzEm/Z77amjMT7/Lo=
-github.com/urfave/cli v0.0.0-20180821064027-934abfb2f102/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
-go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277 h1:d9qaMM+ODpCq+9We41//fu/sHsTnXcrqd1en3x+GKy4=
-go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277/go.mod h1:2X8KaoNd1J0lZV+PxJk/5+DGbO/tpwLR1m++a7FnB/Y=
-golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
-golang.org/x/net v0.0.0-20180824152047-4bcd98cce591 h1:4S2XUgvg3hUNTvxI307qkFPb9zKHG3Nf9TXFzX/DZZI=
-golang.org/x/net v0.0.0-20180824152047-4bcd98cce591/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87 h1:GqwDwfvIpC33dK9bA1fD+JiDUNsuAiQiEkpHqUKze4o=
-golang.org/x/sys v0.0.0-20180824143301-4910a1d54f87/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
-google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/grpc v1.14.0 h1:ArxJuB1NWfPY6r9Gp9gqwplT0Ge7nqv9msgu03lHLmo=
-google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
-gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
-gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
-gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-k8s.io/api v0.0.0-20180824172530-dd5c735cbff9/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
-k8s.io/apimachinery v0.0.0-20180823151430-017bf4f8f588 h1:27Eed77htcD+xKyRQpbq8thV+F1tv611laPnUFMZoeg=
-k8s.io/apimachinery v0.0.0-20180823151430-017bf4f8f588/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
-k8s.io/client-go v8.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
diff --git a/integration/mesher-grafana-dashboard.json b/integration/mesher-grafana-dashboard.json
index 4baf3e0..cc5170d 100644
--- a/integration/mesher-grafana-dashboard.json
+++ b/integration/mesher-grafana-dashboard.json
@@ -203,7 +203,7 @@
"tableColumn": "",
"targets": [
{
- "expr": "count(count(requests_total{instance=~\"$node\"}) by(servicename))",
+ "expr": "count(count(requests_total{instance=~\"$node\"}) by(service_name))",
"format": "time_series",
"intervalFactor": 2,
"refId": "A",
@@ -734,10 +734,10 @@
"steppedLine": false,
"targets": [
{
- "expr": "(sum(successes_total{instance=~\"$node\"}) by (servicename,appid,version))/(sum(requests_total{instance=~\"$node\"}) by (servicename,appid,version))",
+ "expr": "(sum(successes_total{instance=~\"$node\"}) by (service_name,app,version))/(sum(requests_total{instance=~\"$node\"}) by (service_name,app,version))",
"format": "time_series",
"intervalFactor": 2,
- "legendFormat": "{{servicename}}@{{appid}}#{{version}}",
+ "legendFormat": "{{service_name}}@{{app}}#{{version}}",
"refId": "A",
"step": 10
}
@@ -810,10 +810,10 @@
"steppedLine": false,
"targets": [
{
- "expr": "sum(rate(requests_total{instance=~\"$node\"} [5m])) by(servicename,appid,version)",
+ "expr": "sum(rate(requests_total{instance=~\"$node\"} [5m])) by(service_name,app,version)",
"format": "time_series",
"intervalFactor": 2,
- "legendFormat": "{{servicename}}@{{appid}}#{{version}}",
+ "legendFormat": "{{service_name}}@{{app}}#{{version}}",
"refId": "A",
"step": 10
}
@@ -934,7 +934,7 @@
"tableColumn": "",
"targets": [
{
- "expr": "requests_total{instance=~\"$node\",servicename=~\"$service\",appid=~\"$appid\",version=~\"$version\"}",
+ "expr": "requests_total{instance=~\"$node\",service_name=~\"$service\",app=~\"$app\",version=~\"$version\"}",
"format": "time_series",
"intervalFactor": 2,
"refId": "A",
@@ -1011,7 +1011,7 @@
"tableColumn": "",
"targets": [
{
- "expr": "sum(successes_total{instance=~\"$node\",servicename=~\"$service\",appid=~\"$appid\",version=~\"$version\"})/sum(requests_total{instance=~\"$node\",servicename=~\"$service\",appid=~\"$appid\",version=~\"$version\"}) ",
+ "expr": "sum(successes_total{instance=~\"$node\",service_name=~\"$service\",app=~\"$app\",version=~\"$version\"})/sum(requests_total{instance=~\"$node\",service_name=~\"$service\",app=~\"$app\",version=~\"$version\"}) ",
"format": "time_series",
"intervalFactor": 2,
"refId": "A",
@@ -1088,7 +1088,7 @@
"tableColumn": "",
"targets": [
{
- "expr": "rate(status_5xx{instance=~\"$node\",servicename=~\"$service\",appid=~\"$appid\",version=~\"$version\"} [5m])",
+ "expr": "rate(status_5xx{instance=~\"$node\",service_name=~\"$service\",app=~\"$app\",version=~\"$version\"} [5m])",
"format": "time_series",
"intervalFactor": 2,
"refId": "A",
@@ -1165,7 +1165,7 @@
"tableColumn": "",
"targets": [
{
- "expr": "rate(status_4xx{instance=~\"$node\",servicename=~\"$service\",appid=~\"$appid\",version=~\"$version\"} [5m])",
+ "expr": "rate(status_4xx{instance=~\"$node\",service_name=~\"$service\",app=~\"$app\",version=~\"$version\"} [5m])",
"format": "time_series",
"intervalFactor": 2,
"refId": "A",
@@ -1217,7 +1217,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "sum(successes_total{instance=~\"$node\",servicename=~\"$service\",appid=~\"$appid\",version=~\"$version\"})/sum(requests_total{instance=~\"$node\",servicename=~\"$service\",appid=~\"$appid\",version=~\"$version\"}) ",
+ "expr": "sum(successes_total{instance=~\"$node\",service_name=~\"$service\",app=~\"$app\",version=~\"$version\"})/sum(requests_total{instance=~\"$node\",service_name=~\"$service\",app=~\"$app\",version=~\"$version\"}) ",
"format": "time_series",
"intervalFactor": 2,
"legendFormat": "Quantile : {{quantile}}",
@@ -1293,10 +1293,10 @@
"steppedLine": false,
"targets": [
{
- "expr": "rate(requests_total{instance=~\"$node\",servicename=~\"$service\",appid=~\"$appid\",version=~\"$version\"} [5m])",
+ "expr": "rate(requests_total{instance=~\"$node\",service_name=~\"$service\",app=~\"$app\",version=~\"$version\"} [5m])",
"format": "time_series",
"intervalFactor": 2,
- "legendFormat": "{{servicename}}",
+ "legendFormat": "{{service_name}}",
"refId": "A",
"step": 10
}
@@ -1369,7 +1369,7 @@
"steppedLine": false,
"targets": [
{
- "expr": "request_latency_seconds{instance=~\"$node\",servicename=~\"$service\",appid=~\"$appid\",version=~\"$version\"} ",
+ "expr": "request_latency_seconds{instance=~\"$node\",service_name=~\"$service\",app=~\"$app\",version=~\"$version\"} ",
"format": "time_series",
"intervalFactor": 2,
"legendFormat": "Quantile : {{quantile}}",
@@ -1945,7 +1945,7 @@
"multi": false,
"name": "service",
"options": [],
- "query": "label_values(requests_total{instance=~\"$node\"},servicename)",
+ "query": "label_values(requests_total{instance=~\"$node\"},service_name)",
"refresh": 2,
"regex": "",
"sort": 1,
@@ -1967,9 +1967,9 @@
"includeAll": false,
"label": "",
"multi": false,
- "name": "appid",
+ "name": "app",
"options": [],
- "query": "label_values(requests_total{instance=~\"$node\",servicename=~\"$service\"},appid)",
+ "query": "label_values(requests_total{instance=~\"$node\",service_name=~\"$service\"},app)",
"refresh": 2,
"regex": "",
"sort": 1,
@@ -1992,7 +1992,7 @@
"multi": false,
"name": "version",
"options": [],
- "query": "label_values(requests_total{instance=~\"$node\",servicename=~\"$service\",appid=~\"$appid\"},version)",
+ "query": "label_values(requests_total{instance=~\"$node\",service_name=~\"$service\",app=~\"$app\"},version)",
"refresh": 2,
"regex": "",
"sort": 1,
diff --git a/metrics/metrics.go b/metrics/metrics.go
deleted file mode 100755
index 23b71b3..0000000
--- a/metrics/metrics.go
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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 metrics
-
-import (
- "net/http"
- "os"
- "sync"
- "time"
-
- "github.com/go-chassis/go-chassis/core/config"
- "github.com/go-chassis/go-chassis/core/invocation"
- mesherconfig "github.com/go-mesh/mesher/config"
- "github.com/prometheus/client_golang/prometheus"
-)
-
-//Constants with attributes for metrics data
-const (
- TotalRequest = "requests_total"
- TotalSuccess = "successes_total"
- TotalFailures = "failures_total"
- RequestLatencySeconds = "request_latency_seconds"
- Error4XX = "status_4xx"
- Error5XX = "status_5xx"
- ServiceName = "servicename"
- AppID = "appid"
- Version = "version"
-)
-
-var (
- //LabelNames is a list with servicename, appID, version
- LabelNames = []string{ServiceName, AppID, Version}
- mutex = sync.Mutex{}
-)
-
-var onceEnable sync.Once
-
-//Init function initiates all config
-func Init() {
- mesherLabelValues := map[string]string{ServiceName: config.SelfServiceName, AppID: config.GlobalDefinition.AppID, Version: config.SelfVersion}
- mesherStartTime := time.Now().Unix()
- DefaultPrometheusExporter.Gauge("start_time_seconds", float64(mesherStartTime), LabelNames, mesherLabelValues)
- mesherConfig := mesherconfig.GetConfig()
- promConfig := getPrometheusSinker(getSystemPrometheusRegistry())
- if mesherConfig.Admin.GoRuntimeMetrics == true {
- onceEnable.Do(func() {
- promConfig.PromRegistry.MustRegister(prometheus.NewProcessCollector(os.Getpid(), ""))
- promConfig.PromRegistry.MustRegister(prometheus.NewGoCollector())
- })
- }
-}
-
-//RecordResponse record the response
-func RecordResponse(inv *invocation.Invocation, statusCode int) {
- mutex.Lock()
- defer mutex.Unlock()
- serviceLabelValues := map[string]string{ServiceName: inv.MicroServiceName, AppID: inv.RouteTags.AppID(), Version: inv.RouteTags.Version()}
- if statusCode >= http.StatusBadRequest && statusCode <= http.StatusUnavailableForLegalReasons {
- DefaultPrometheusExporter.Count(Error4XX, LabelNames, serviceLabelValues)
- DefaultPrometheusExporter.Count(TotalFailures, LabelNames, serviceLabelValues)
- } else if statusCode >= http.StatusInternalServerError && statusCode <= http.StatusNetworkAuthenticationRequired {
- DefaultPrometheusExporter.Count(Error5XX, LabelNames, serviceLabelValues)
- DefaultPrometheusExporter.Count(TotalFailures, LabelNames, serviceLabelValues)
- } else if statusCode >= http.StatusOK && statusCode <= http.StatusIMUsed {
- DefaultPrometheusExporter.Count(TotalSuccess, LabelNames, serviceLabelValues)
- }
-
- DefaultPrometheusExporter.Count(TotalRequest, LabelNames, serviceLabelValues)
-}
diff --git a/pkg/infras/istio/xds.go b/pkg/infras/istio/xds.go
new file mode 100644
index 0000000..25d95a2
--- /dev/null
+++ b/pkg/infras/istio/xds.go
@@ -0,0 +1,458 @@
+package pilotv2
+
+import (
+ "context"
+ "crypto/tls"
+ "encoding/json"
+ "fmt"
+ "strings"
+
+ apiv2 "github.com/envoyproxy/go-control-plane/envoy/api/v2"
+ apiv2core "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
+ apiv2endpoint "github.com/envoyproxy/go-control-plane/envoy/api/v2/endpoint"
+ apiv2route "github.com/envoyproxy/go-control-plane/envoy/api/v2/route"
+ k8sinfra "github.com/go-mesh/mesher/pkg/infras/k8s"
+
+ "github.com/envoyproxy/go-control-plane/envoy/service/discovery/v2"
+ "github.com/go-mesh/openlogging"
+ "github.com/gogo/protobuf/proto"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/credentials"
+ "k8s.io/client-go/rest"
+)
+
+//XdsClient provides the XDS API calls.
+type XdsClient struct {
+ PilotAddr string
+ TlsConfig *tls.Config
+ ReqCaches map[XdsType]*XdsReqCache
+ nodeInfo *NodeInfo
+ NodeID string
+ NodeCluster string
+ k8sClient *rest.RESTClient
+}
+
+//XdsType is the wrapper of string, the wrapper type should be "cds", "eds", "lds" or "rds"
+type XdsType string
+
+const (
+ TypeCds XdsType = "cds"
+ TypeEds XdsType = "eds"
+ TypeLds XdsType = "lds"
+ TypeRds XdsType = "rds"
+)
+
+//XdsReqCache stores the VersionInfo and Nonce for the XDS calls
+type XdsReqCache struct {
+ Nonce string
+ VersionInfo string
+}
+
+//NodeInfo stores the info of the node, which will be used to make a
+//XDS call
+type NodeInfo struct {
+ PodName string
+ Namespace string
+ InstanceIP string
+}
+
+//XdsClusterInfo stores all the infos from a cluster name, which is in
+//the format direction|port|subset|hostName
+type XdsClusterInfo struct {
+ ClusterName string
+ Direction string
+ Port string
+ Subset string
+ HostName string
+ ServiceName string
+ Namespace string
+ DomainSuffix string // DomainSuffix might not be used
+ Tags map[string]string
+ Addrs []string // The accessible addresses of the endpoints
+}
+
+//NewXdsClient returns the new XDS client.
+func NewXdsClient(pilotAddr string, tlsConfig *tls.Config, nodeInfo *NodeInfo, kubeconfigPath string) (*XdsClient, error) {
+ // TODO Handle the array
+ xdsClient := &XdsClient{
+ PilotAddr: pilotAddr,
+ nodeInfo: nodeInfo,
+ }
+ xdsClient.NodeID = "sidecar~" + nodeInfo.InstanceIP + "~" + nodeInfo.PodName + "~" + nodeInfo.Namespace
+ xdsClient.NodeCluster = nodeInfo.PodName
+
+ xdsClient.ReqCaches = map[XdsType]*XdsReqCache{
+ TypeCds: {},
+ TypeEds: {},
+ TypeLds: {},
+ TypeRds: {},
+ }
+
+ if k8sClient, err := k8sinfra.CreateK8SRestClient(kubeconfigPath, "apis", "networking.istio.io", "v1alpha3"); err != nil {
+ return nil, err
+ } else {
+ xdsClient.k8sClient = k8sClient
+ }
+
+ return xdsClient, nil
+}
+
+//GetSubsetTags returns the tags of the specified subset.
+func (client *XdsClient) GetSubsetTags(namespace, hostName, subsetName string) (map[string]string, error) {
+ req := client.k8sClient.Get()
+ req.Resource("destinationrules")
+ req.Namespace(namespace)
+
+ result := req.Do()
+ rawBody, err := result.Raw()
+ if err != nil {
+ return nil, err
+ }
+
+ var drResult k8sinfra.DestinationRuleResult
+ if err := json.Unmarshal(rawBody, &drResult); err != nil {
+ return nil, err
+ }
+
+ // Find the subset
+ tags := map[string]string{}
+ for _, dr := range drResult.Items {
+ if dr.Spec.Host == hostName {
+ for _, subset := range dr.Spec.Subsets {
+ if subset.Name == subsetName {
+ for k, v := range subset.Labels {
+ tags[k] = v
+ }
+ break
+ }
+ }
+ break
+ }
+ }
+
+ return tags, nil
+}
+
+func (client *XdsClient) getGrpcConn() (*grpc.ClientConn, error) {
+ var conn *grpc.ClientConn
+ var err error
+ if client.TlsConfig != nil {
+ creds := credentials.NewTLS(client.TlsConfig)
+ conn, err = grpc.Dial(client.PilotAddr, grpc.WithTransportCredentials(creds))
+ } else {
+ conn, err = grpc.Dial(client.PilotAddr, grpc.WithInsecure())
+ }
+
+ return conn, err
+}
+
+func getAdsResClient(client *XdsClient) (v2.AggregatedDiscoveryService_StreamAggregatedResourcesClient, *grpc.ClientConn, error) {
+ conn, err := client.getGrpcConn()
+ if err != nil {
+ return nil, nil, err
+ }
+
+ adsClient := v2.NewAggregatedDiscoveryServiceClient(conn)
+ adsResClient, err := adsClient.StreamAggregatedResources(context.Background())
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return adsResClient, conn, nil
+}
+
+func (client *XdsClient) getRouterClusters(clusterName string) ([]string, error) {
+ virtualHosts, err := client.RDS(clusterName)
+ if err != nil {
+ return nil, err
+ }
+
+ routerClusters := []string{}
+ for _, h := range virtualHosts {
+ for _, r := range h.Routes {
+ routerClusters = append(routerClusters, r.GetRoute().GetCluster())
+ }
+ }
+
+ return routerClusters, nil
+}
+
+func (client *XdsClient) getVersionInfo(resType XdsType) string {
+ return client.ReqCaches[resType].VersionInfo
+}
+func (client *XdsClient) getNonce(resType XdsType) string {
+ return client.ReqCaches[resType].Nonce
+}
+
+func (client *XdsClient) setVersionInfo(resType XdsType, versionInfo string) {
+ client.ReqCaches[resType].VersionInfo = versionInfo
+}
+
+func (client *XdsClient) setNonce(resType XdsType, nonce string) {
+ client.ReqCaches[resType].Nonce = nonce
+}
+
+//CDS s the Clsuter Discovery Service API, which fetches all the clusters from istio pilot
+func (client *XdsClient) CDS() ([]apiv2.Cluster, error) {
+ adsResClient, conn, err := getAdsResClient(client)
+ if err != nil {
+ return nil, err
+ }
+ defer conn.Close()
+
+ req := &apiv2.DiscoveryRequest{
+ TypeUrl: "type.googleapis.com/envoy.api.v2.Cluster",
+ VersionInfo: client.getVersionInfo(TypeCds),
+ ResponseNonce: client.getNonce(TypeCds),
+ }
+ req.Node = &apiv2core.Node{
+ // Sample taken from istio: router~172.30.77.6~istio-egressgateway-84b4d947cd-rqt45.istio-system~istio-system.svc.cluster.local-2
+ // The Node.Id should be in format {nodeType}~{ipAddr}~{serviceId~{domain}, splitted by '~'
+ // The format is required by pilot
+ Id: client.NodeID,
+ Cluster: client.NodeCluster,
+ }
+
+ if err := adsResClient.Send(req); err != nil {
+ return nil, err
+ }
+
+ resp, err := adsResClient.Recv()
+ if err != nil {
+ return nil, err
+ }
+
+ client.setNonce(TypeCds, resp.GetNonce())
+ client.setVersionInfo(TypeCds, resp.GetVersionInfo())
+ resources := resp.GetResources()
+
+ var cluster apiv2.Cluster
+ clusters := []apiv2.Cluster{}
+ for _, res := range resources {
+ if err := proto.Unmarshal(res.GetValue(), &cluster); err != nil {
+ openlogging.GetLogger().Warnf("Failed to unmarshal cluster resource: %s", err.Error())
+ } else {
+ clusters = append(clusters, cluster)
+ }
+ }
+ return clusters, nil
+}
+
+//EDS is the Endpoint Discovery Service API, the API takes the cluster's name and return all its endpoints(which provide address and port)
+func (client *XdsClient) EDS(clusterName string) (*apiv2.ClusterLoadAssignment, error) {
+ adsResClient, conn, err := getAdsResClient(client)
+ if err != nil {
+ return nil, err
+ }
+ defer conn.Close()
+
+ req := &apiv2.DiscoveryRequest{
+ TypeUrl: "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
+ VersionInfo: client.getVersionInfo(TypeEds),
+ ResponseNonce: client.getNonce(TypeEds),
+ }
+
+ req.Node = &apiv2core.Node{
+ Id: client.NodeID,
+ Cluster: client.NodeCluster,
+ }
+ req.ResourceNames = []string{clusterName}
+ if err := adsResClient.Send(req); err != nil {
+ return nil, err
+ }
+
+ resp, err := adsResClient.Recv()
+ if err != nil {
+ return nil, err
+ }
+
+ resources := resp.GetResources()
+ client.setNonce(TypeEds, resp.GetNonce())
+ client.setVersionInfo(TypeEds, resp.GetVersionInfo())
+
+ var loadAssignment apiv2.ClusterLoadAssignment
+ var e error
+ // endpoints := []apiv2.ClusterLoadAssignment{}
+
+ for _, res := range resources {
+ if err := proto.Unmarshal(res.GetValue(), &loadAssignment); err != nil {
+ e = err
+ } else {
+ // The cluster's LoadAssignment will always be ONE, with Endpoints as its field
+ break
+ }
+ }
+ return &loadAssignment, e
+}
+
+//GetEndpointsByTags fetches the cluster's endpoints with tags. The tags is usually specified in a DestinationRule.
+func (client *XdsClient) GetEndpointsByTags(serviceName string, tags map[string]string) ([]apiv2endpoint.LbEndpoint, string, error) {
+ clusters, err := client.CDS()
+ if err != nil {
+ return nil, "", err
+ }
+
+ lbendpoints := []apiv2endpoint.LbEndpoint{}
+ clusterName := ""
+ for _, cluster := range clusters {
+ clusterInfo := ParseClusterName(cluster.Name)
+ if clusterInfo == nil || clusterInfo.Subset == "" || clusterInfo.ServiceName != serviceName {
+ continue
+ }
+ // So clusterInfo is not nil and subset is not empty
+ if subsetTags, err := client.GetSubsetTags(clusterInfo.Namespace, clusterInfo.ServiceName, clusterInfo.Subset); err == nil {
+ // filter with tags
+ matched := true
+ for k, v := range tags {
+ if subsetTagValue, exists := subsetTags[k]; exists == false || subsetTagValue != v {
+ matched = false
+ break
+ }
+ }
+
+ if matched { // We got the cluster!
+ clusterName = cluster.Name
+ loadAssignment, err := client.EDS(cluster.Name)
+ if err != nil {
+ return nil, clusterName, err
+ }
+
+ for _, item := range loadAssignment.Endpoints {
+ lbendpoints = append(lbendpoints, item.LbEndpoints...)
+ }
+
+ return lbendpoints, clusterName, nil
+ }
+ }
+ }
+
+ return lbendpoints, clusterName, nil
+}
+
+//RDS is the Router Discovery Service API, it returns the virtual hosts which contains Routes
+func (client *XdsClient) RDS(clusterName string) ([]apiv2route.VirtualHost, error) {
+ clusterInfo := ParseClusterName(clusterName)
+ if clusterInfo == nil {
+ return nil, fmt.Errorf("Invalid clusterName for routers: %s", clusterName)
+ }
+
+ adsResClient, conn, err := getAdsResClient(client)
+ if err != nil {
+ return nil, err
+ }
+ defer conn.Close()
+
+ req := &apiv2.DiscoveryRequest{
+ TypeUrl: "type.googleapis.com/envoy.api.v2.RouteConfiguration",
+ VersionInfo: client.getVersionInfo(TypeRds),
+ ResponseNonce: client.getNonce(TypeRds),
+ }
+
+ req.Node = &apiv2core.Node{
+ Id: client.NodeID,
+ Cluster: client.NodeCluster,
+ }
+ req.ResourceNames = []string{clusterName}
+ if err := adsResClient.Send(req); err != nil {
+ return nil, err
+ }
+
+ resp, err := adsResClient.Recv()
+ if err != nil {
+ return nil, err
+ }
+
+ resources := resp.GetResources()
+ client.setNonce(TypeRds, resp.GetNonce())
+ client.setVersionInfo(TypeRds, resp.GetVersionInfo())
+
+ var route apiv2.RouteConfiguration
+ virtualHosts := []apiv2route.VirtualHost{}
+
+ for _, res := range resources {
+ if err := proto.Unmarshal(res.GetValue(), &route); err != nil {
+ openlogging.GetLogger().Warnf("Failed to unmarshal router resource: ", err.Error())
+ } else {
+ vhosts := route.GetVirtualHosts()
+ for _, vhost := range vhosts {
+ if vhost.Name == clusterInfo.ServiceName+":"+clusterInfo.Port {
+ virtualHosts = append(virtualHosts, vhost)
+ }
+ }
+ }
+ }
+ return virtualHosts, nil
+}
+
+//LDS is the Listener Discovery Service API, which returns all the listerns
+func (client *XdsClient) LDS() ([]apiv2.Listener, error) {
+ adsResClient, conn, err := getAdsResClient(client)
+ if err != nil {
+ return nil, err
+ }
+ defer conn.Close()
+
+ req := &apiv2.DiscoveryRequest{
+ TypeUrl: "type.googleapis.com/envoy.api.v2.Listener",
+ VersionInfo: client.getVersionInfo(TypeLds),
+ ResponseNonce: client.getNonce(TypeLds),
+ }
+
+ req.Node = &apiv2core.Node{
+ Id: client.NodeID,
+ Cluster: client.NodeCluster,
+ }
+ if err := adsResClient.Send(req); err != nil {
+ return nil, err
+ }
+
+ resp, err := adsResClient.Recv()
+ if err != nil {
+ return nil, err
+ }
+
+ resources := resp.GetResources()
+ client.setNonce(TypeLds, resp.GetNonce())
+ client.setVersionInfo(TypeLds, resp.GetVersionInfo())
+
+ var listener apiv2.Listener
+ listeners := []apiv2.Listener{}
+
+ for _, res := range resources {
+ if err := proto.Unmarshal(res.GetValue(), &listener); err != nil {
+ openlogging.GetLogger().Warnf("Failed to unmarshal listener resource: ", err.Error())
+ } else {
+ listeners = append(listeners, listener)
+ }
+ }
+ return listeners, nil
+}
+
+//ParseClusterName parse the cluster's name, which is in the format direction|port|subset|hostName, the 4 items will be parsed into different fields. The hostName item will also be parsed into ServcieName, Namespace etc.
+func ParseClusterName(clusterName string) *XdsClusterInfo {
+ // clusterName format: direction|port|subset|hostName
+ // hostName format: |svc.namespace.svc.cluster.local
+
+ parts := strings.Split(clusterName, "|")
+ if len(parts) != 4 {
+ return nil
+ }
+
+ hostnameParts := strings.Split(parts[3], ".")
+ if len(hostnameParts) < 2 {
+ return nil
+ }
+
+ cluster := &XdsClusterInfo{
+ Direction: parts[0],
+ Port: parts[1],
+ Subset: parts[2],
+ HostName: parts[3],
+ ServiceName: hostnameParts[0],
+ Namespace: hostnameParts[1],
+ DomainSuffix: strings.Join(hostnameParts[2:], "."),
+ ClusterName: clusterName,
+ }
+
+ return cluster
+}
diff --git a/pkg/infras/istio/xds_test.go b/pkg/infras/istio/xds_test.go
new file mode 100644
index 0000000..be3c1e1
--- /dev/null
+++ b/pkg/infras/istio/xds_test.go
@@ -0,0 +1,248 @@
+package pilotv2
+
+import (
+ "os"
+ "os/user"
+ "testing"
+ "time"
+
+ apiv2 "github.com/envoyproxy/go-control-plane/envoy/api/v2"
+ "github.com/go-chassis/go-chassis/core/lager"
+ "github.com/go-chassis/go-chassis/pkg/util/iputil"
+ testutil "github.com/go-mesh/mesher-tools/test/util"
+ "istio.io/istio/tests/util"
+)
+
+const (
+ TEST_POD_NAME = "testpod"
+ NAMESPACE_DEFAULT = "default"
+)
+
+var (
+ ValidXdsClient *XdsClient
+ TestClusters []apiv2.Cluster
+)
+var (
+ KubeConfig string
+ ValidPilotAddr string
+ LocalIPAddress string
+ nodeInfo *NodeInfo
+
+ err error
+)
+
+func TestMain(t *testing.T) {
+ lager.Initialize("", "DEBUG", "", "size", true, 1, 10, 7)
+ // Get kube config path and local ip
+ if KUBE_CONFIG := os.Getenv("KUBE_CONFIG"); KUBE_CONFIG != "" {
+ KubeConfig = KUBE_CONFIG
+ } else {
+ usr, err := user.Current()
+ if err != nil {
+ panic("Failed to get current user info: " + err.Error())
+ } else {
+ KubeConfig = usr.HomeDir + "/" + ".kube/config"
+ }
+ }
+
+ if PILOT_ADDR := os.Getenv("PILOT_ADDR"); PILOT_ADDR != "" {
+ ValidPilotAddr = PILOT_ADDR
+ } else {
+ // panic("PILOT_ADDR should be specified to pass the pilot address")
+ testutil.InitLocalPilotTestEnv(t)
+ ValidPilotAddr = util.MockPilotGrpcAddr
+ }
+
+ if INSTANCE_IP := os.Getenv("INSTANCE_IP"); INSTANCE_IP != "" {
+ LocalIPAddress = INSTANCE_IP
+ } else if LocalIPAddress = iputil.GetLocalIP(); LocalIPAddress == "" {
+ panic("Failed to get the local ip address, please check the network environment")
+ }
+
+ nodeInfo = &NodeInfo{
+ PodName: TEST_POD_NAME,
+ Namespace: NAMESPACE_DEFAULT,
+ InstanceIP: LocalIPAddress,
+ }
+}
+
+func TestNewXdsClient(t *testing.T) {
+ client, err := NewXdsClient(ValidPilotAddr, nil, nodeInfo, KubeConfig)
+
+ if err != nil {
+ t.Errorf("Failed to create xds client: %s", err.Error())
+ }
+
+ ValidXdsClient = client
+}
+
+func TestCDS(t *testing.T) {
+ clusters, err := ValidXdsClient.CDS()
+ if err != nil {
+ t.Errorf("Failed to get clusters by CDS: %s", err.Error())
+ }
+
+ t.Logf("Got %d clusters\n", len(clusters))
+ TestClusters = clusters
+}
+
+func TestEDS(t *testing.T) {
+ if len(TestClusters) == 0 { // With istio, there should always be clusters
+ t.Errorf("No clusters found")
+ }
+
+ loadAssignment, err := ValidXdsClient.EDS(TestClusters[0].Name)
+ if err != nil {
+ t.Errorf("Failed to get endpoints by EDS: %s", err.Error())
+ }
+
+ if loadAssignment == nil {
+ t.Errorf("Failed to get load assginment with EDS: %s", err.Error())
+ }
+}
+
+func TestRDS(t *testing.T) {
+ targetClusterName := ""
+ for _, c := range TestClusters {
+ info := ParseClusterName(c.Name)
+ if info != nil {
+ targetClusterName = c.Name
+ break
+ }
+ }
+
+ if targetClusterName == "" {
+ t.Log("We don't find a valid cluster")
+ }
+
+ _, err := ValidXdsClient.RDS(targetClusterName)
+ if err != nil {
+ t.Errorf("Failed to get routers: %s", err.Error())
+ }
+}
+
+func TestLDS(t *testing.T) {
+ listeners, err := ValidXdsClient.LDS()
+ if err != nil {
+ t.Errorf("Failed to get listeners with LDS: %s", err.Error())
+ }
+
+ t.Logf("%d listeners found\n", len(listeners))
+}
+
+func TestNonce(t *testing.T) {
+ nowStr := time.Now().String()
+ ValidXdsClient.setNonce(TypeCds, nowStr)
+ ValidXdsClient.setNonce(TypeEds, nowStr)
+ ValidXdsClient.setNonce(TypeRds, nowStr)
+ ValidXdsClient.setNonce(TypeLds, nowStr)
+
+ cdsNonce := ValidXdsClient.getNonce(TypeCds)
+ if cdsNonce != nowStr {
+ t.Errorf("Failed to test nonce: %s should be equal to %s", cdsNonce, nowStr)
+ }
+
+ edsNonce := ValidXdsClient.getNonce(TypeEds)
+ if edsNonce != nowStr {
+ t.Errorf("Failed to test nonce: %s should be equal to %s", edsNonce, nowStr)
+ }
+
+ ldsNonce := ValidXdsClient.getNonce(TypeLds)
+ if ldsNonce != nowStr {
+ t.Errorf("Failed to test nonce: %s should be equal to %s", ldsNonce, nowStr)
+ }
+
+ rdsNonce := ValidXdsClient.getNonce(TypeRds)
+ if rdsNonce != nowStr {
+ t.Errorf("Failed to test nonce: %s should be equal to %s", rdsNonce, nowStr)
+ }
+}
+
+func TestVersionInfo(t *testing.T) {
+ nowStr := time.Now().String()
+ ValidXdsClient.setVersionInfo(TypeCds, nowStr)
+ ValidXdsClient.setVersionInfo(TypeEds, nowStr)
+ ValidXdsClient.setVersionInfo(TypeRds, nowStr)
+ ValidXdsClient.setVersionInfo(TypeLds, nowStr)
+
+ cdsVersionInfo := ValidXdsClient.getVersionInfo(TypeCds)
+ if cdsVersionInfo != nowStr {
+ t.Errorf("Failed to test VersionInfo: %s should be equal to %s", cdsVersionInfo, nowStr)
+ }
+
+ edsVersionInfo := ValidXdsClient.getVersionInfo(TypeEds)
+ if edsVersionInfo != nowStr {
+ t.Errorf("Failed to test VersionInfo: %s should be equal to %s", edsVersionInfo, nowStr)
+ }
+
+ ldsVersionInfo := ValidXdsClient.getVersionInfo(TypeLds)
+ if ldsVersionInfo != nowStr {
+ t.Errorf("Failed to test VersionInfo: %s should be equal to %s", ldsVersionInfo, nowStr)
+ }
+
+ rdsVersionInfo := ValidXdsClient.getVersionInfo(TypeRds)
+ if rdsVersionInfo != nowStr {
+ t.Errorf("Failed to test VersionInfo: %s should be equal to %s", rdsVersionInfo, nowStr)
+ }
+}
+
+func TestGetSubsetTags(t *testing.T) {
+ var targetClusterInfo *XdsClusterInfo = nil
+ for _, c := range TestClusters {
+ if info := ParseClusterName(c.Name); info != nil && info.Subset != "" {
+ targetClusterInfo = info
+ break
+ }
+ }
+
+ if targetClusterInfo == nil {
+ t.Log("No tagged services in test environment, skip")
+ } else {
+ tags, err := ValidXdsClient.GetSubsetTags(targetClusterInfo.Namespace, targetClusterInfo.ServiceName, targetClusterInfo.Subset)
+ if err != nil {
+ t.Errorf("Failed to get subset tags: %s", err.Error())
+ } else if len(tags) == 0 {
+ t.Logf("Should not return empty tags %s", targetClusterInfo.ClusterName)
+ }
+ }
+}
+
+func TestGetAdsResClient(t *testing.T) {
+ _, conn, err := getAdsResClient(ValidXdsClient)
+
+ if err != nil {
+ t.Errorf("Failed to get ads resource client: %s", err.Error())
+ }
+ conn.Close()
+}
+
+func TestParseClusterName(t *testing.T) {
+ validClusterName := "inbound|3030||client.default.svc.cluster.local"
+
+ clusterInfo := ParseClusterName(validClusterName)
+
+ if clusterInfo == nil {
+ t.Errorf("Failed to parse cluster name: %s, should return cluster info", validClusterName)
+ }
+ if clusterInfo.Direction != "inbound" {
+ t.Errorf("Failed to parse cluster name: %s, direction should be inbound", validClusterName)
+ }
+ if clusterInfo.Port != "3030" {
+ t.Errorf("Failed to parse cluster name: %s, port should be 3030", validClusterName)
+ }
+ if clusterInfo.ServiceName != "client" {
+ t.Errorf("Failed to parse cluster name: %s, servicename should be client", validClusterName)
+ }
+
+ invalidClusterName := "BlackHoleCluster"
+ clusterInfo = ParseClusterName(invalidClusterName)
+ if clusterInfo != nil {
+ t.Errorf("Failed to parse cluster name: %s, should return nil", validClusterName)
+ }
+
+ invalidClusterName = "outbound|9080|v2|black"
+ clusterInfo = ParseClusterName(invalidClusterName)
+ if clusterInfo != nil {
+ t.Errorf("Failed to parse cluster name: %s, should return nil", validClusterName)
+ }
+}
diff --git a/pkg/infras/k8s/k8s.go b/pkg/infras/k8s/k8s.go
new file mode 100644
index 0000000..998d652
--- /dev/null
+++ b/pkg/infras/k8s/k8s.go
@@ -0,0 +1,60 @@
+package pilotv2
+
+import (
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/apimachinery/pkg/runtime/schema"
+ "k8s.io/apimachinery/pkg/runtime/serializer"
+ "k8s.io/client-go/rest"
+ "k8s.io/client-go/tools/clientcmd"
+)
+
+//DestinationRuleResult is the list of MinDestinationRules
+type DestinationRuleResult struct {
+ Items []MinDestinationRule
+}
+
+// MinDestinationRule is the minimum structure we need to get subsets
+type MinDestinationRule struct {
+ Metadata struct {
+ Name string `json:"name"`
+ Namespace string `json:"namespace"`
+ } `json:"metadata"`
+ Spec struct {
+ Host string `json:"host"`
+ Subsets []struct {
+ Labels map[string]string `json:"labels"`
+ Name string `json:"name"`
+ } `json:"subsets"`
+ } `json:"spec"`
+}
+
+//CreateK8SRestClient returns the kubernetes client for RESTful API calls
+func CreateK8SRestClient(kubeconfig, apiPath, group, version string) (*rest.RESTClient, error) {
+ var config *rest.Config
+ var err error
+ if kubeconfig != "" {
+ config, err = clientcmd.BuildConfigFromFlags("", kubeconfig)
+ if err != nil {
+ config, err = rest.InClusterConfig()
+ }
+ } else {
+ config, err = rest.InClusterConfig()
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ config.APIPath = apiPath
+ config.GroupVersion = &schema.GroupVersion{
+ Group: group,
+ Version: version,
+ }
+ config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: serializer.NewCodecFactory(runtime.NewScheme())}
+
+ k8sRestClient, err := rest.RESTClientFor(config)
+ if err != nil {
+ return nil, err
+ }
+ return k8sRestClient, nil
+}
diff --git a/pkg/infras/k8s/k8s_test.go b/pkg/infras/k8s/k8s_test.go
new file mode 100644
index 0000000..3a6992c
--- /dev/null
+++ b/pkg/infras/k8s/k8s_test.go
@@ -0,0 +1,42 @@
+package pilotv2
+
+import (
+ "os"
+ "os/user"
+ "testing"
+)
+
+var KubeConfig string
+
+func init() {
+ if KUBE_CONFIG := os.Getenv("KUBE_CONFIG"); KUBE_CONFIG != "" {
+ KubeConfig = KUBE_CONFIG
+ } else {
+ usr, err := user.Current()
+ if err != nil {
+ panic("Failed to get current user info: " + err.Error())
+ } else {
+ KubeConfig = usr.HomeDir + "/" + ".kube/config"
+ }
+ }
+
+}
+
+func TestCreateK8sClient(t *testing.T) {
+ _, err := CreateK8SRestClient(KubeConfig, "apis", "networking.istio.io", "v1alpha3")
+ if err != nil {
+ t.Errorf("Failed to create k8s rest client: %s", err.Error())
+ }
+
+ _, err = CreateK8SRestClient("*nonfile", "apis", "networking.istio.io", "v1alpha3")
+ if err == nil {
+ t.Errorf("Test failed, should return error with invalid kube config path")
+ }
+}
+
+func TestCreateInvalidK8sClient(t *testing.T) {
+ _, err := CreateK8SRestClient("", "apis", "networking.istio.io", "v1alpha3")
+ if err == nil {
+ t.Errorf("Passing a nil config for k8s client should return error")
+ }
+}
diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go
new file mode 100644
index 0000000..6cc85b4
--- /dev/null
+++ b/pkg/metrics/metrics.go
@@ -0,0 +1,101 @@
+/*
+ * 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 metrics is a system-independent module
+//it consider metrics key as first-class citizen
+//each function is for recording one kind of metrics key and value
+//it expose standard API to record runtime metrics for a service
+//use prom as default metrics system
+package metrics
+
+import (
+ "github.com/go-chassis/go-chassis/pkg/runtime"
+ mesherConf "github.com/go-mesh/mesher/config"
+ "sync"
+ "time"
+)
+
+//Constants with attributes for metrics data
+//Label start with word "L"
+const (
+ LTotalRequest = "requests_total"
+ LTotalSuccess = "successes_total"
+ LTotalFailures = "failures_total"
+ LRequestLatencySeconds = "request_latency_seconds"
+ LError4XX = "status_4xx"
+ LError5XX = "status_5xx"
+ LServiceName = "service_name"
+ LApp = "app"
+ LVersion = "version"
+ LStartTime = "start_time_seconds"
+)
+
+var (
+ //LabelNames is a fixed list with service name, appID, version
+ LabelNames = []string{LServiceName, LApp, LVersion}
+ mutex = sync.Mutex{}
+)
+
+//Recorder export the metrics into various of system
+type Recorder interface {
+ RecordStatus(labelValues map[string]string, status int, opts *RecordOptions)
+ RecordLatency(labelValues map[string]string, latency float64, opts *RecordOptions)
+ RecordStartTime(labelValues map[string]string, start time.Time, opts *RecordOptions)
+}
+
+//Options define recorder options
+type Options struct {
+ LabelNames []string //default label names, if RecordOptions LabelNames is nil
+ EnableGoRuntimeMetrics bool
+}
+
+//RecordOptions is options for record method
+type RecordOptions struct {
+ LabelNames []string // able top custom label names
+}
+
+var defaultRecorder Recorder = &promRecorder{}
+
+//RecordStatus record an operation status
+func RecordStatus(labelValues map[string]string, statusCode int, opts *RecordOptions) {
+ defaultRecorder.RecordStatus(labelValues, statusCode, opts)
+}
+
+//RecordLatency record an operation latency
+func RecordLatency(labelValues map[string]string, latency float64, opts *RecordOptions) {
+ defaultRecorder.RecordLatency(labelValues, latency, opts)
+}
+
+//RecordStartTime record app start time
+func RecordStartTime(labelValues map[string]string, start time.Time, opts *RecordOptions) {
+ defaultRecorder.RecordStartTime(labelValues, start, opts)
+}
+
+//Init initiate the recorder
+func Init() error {
+ var err error
+ LabelValues := map[string]string{LServiceName: runtime.ServiceName, LApp: runtime.App, LVersion: runtime.Version}
+ defaultRecorder, err = NewPromRecorder(&Options{
+ LabelNames: LabelNames,
+ EnableGoRuntimeMetrics: mesherConf.GetConfig().Admin.GoRuntimeMetrics,
+ })
+ if err != nil {
+ return err
+ }
+ RecordStartTime(LabelValues, time.Now(), nil)
+ return nil
+}
diff --git a/pkg/metrics/metrics_test.go b/pkg/metrics/metrics_test.go
new file mode 100644
index 0000000..ed1bbd1
--- /dev/null
+++ b/pkg/metrics/metrics_test.go
@@ -0,0 +1,72 @@
+/*
+ * 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 metrics_test
+
+import (
+ "net/http"
+ "strings"
+ "testing"
+
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/stretchr/testify/assert"
+
+ "github.com/go-chassis/go-chassis/pkg/runtime"
+ mc "github.com/go-mesh/mesher/config"
+ "github.com/go-mesh/mesher/pkg/metrics"
+)
+
+func TestInit(t *testing.T) {
+ mc.SetConfig(&mc.MesherConfig{
+ Admin: mc.Admin{
+ GoRuntimeMetrics: false,
+ },
+ })
+ err := metrics.Init()
+ runtime.ServiceName = "A"
+ runtime.Version = "v1.1"
+ runtime.App = "app"
+ assert.NoError(t, err)
+}
+func TestRecordStatus(t *testing.T) {
+ assert := assert.New(t)
+ var errorcount4xx float64
+ var errorcount5xx float64
+ lvs := map[string]string{
+ metrics.LServiceName: "service",
+ metrics.LVersion: "",
+ metrics.LApp: "",
+ }
+ metrics.RecordStatus(lvs, http.StatusOK, nil)
+ metrics.RecordStatus(lvs, http.StatusNotFound, nil)
+ metrics.RecordStatus(lvs, http.StatusInternalServerError, nil)
+ metricFamilies, err := prometheus.DefaultGatherer.Gather()
+ assert.Nil(err, "error should be nil while collecting metrics from prometheus")
+ for _, metricFamily := range metricFamilies {
+ if name := metricFamily.GetName(); strings.Contains(name, metrics.LError5XX) {
+ errorcount4xx += *metricFamily.Metric[0].Counter.Value
+ }
+ }
+ for _, metricFamily := range metricFamilies {
+ if name := metricFamily.GetName(); strings.Contains(name, metrics.LError5XX) {
+ errorcount5xx += *metricFamily.Metric[0].Counter.Value
+ }
+ }
+ assert.Equal(errorcount4xx, float64(1))
+ assert.Equal(errorcount5xx, float64(1))
+
+}
diff --git a/pkg/metrics/prom_recorder.go b/pkg/metrics/prom_recorder.go
new file mode 100644
index 0000000..a1bc62d
--- /dev/null
+++ b/pkg/metrics/prom_recorder.go
@@ -0,0 +1,69 @@
+package metrics
+
+import (
+ "errors"
+ "github.com/prometheus/client_golang/prometheus"
+ "net/http"
+ "os"
+ "sync"
+ "time"
+)
+
+var onceEnable sync.Once
+
+type promRecorder struct {
+ LabelNames []string
+}
+
+//NewPromRecorder return a prom recorder
+func NewPromRecorder(opts *Options) (Recorder, error) {
+ promConfig := getPrometheusSinker(getSystemPrometheusRegistry())
+ if opts != nil {
+ if opts.EnableGoRuntimeMetrics {
+ onceEnable.Do(func() {
+ promConfig.PromRegistry.MustRegister(prometheus.NewProcessCollector(os.Getpid(), ""))
+ promConfig.PromRegistry.MustRegister(prometheus.NewGoCollector())
+ })
+ }
+ return &promRecorder{LabelNames: opts.LabelNames}, nil
+ }
+ return nil, errors.New("options can not be nil")
+}
+
+//GetLN return label names based on options
+func (e *promRecorder) GetLN(opts *RecordOptions) (ln []string) {
+ ln = e.LabelNames
+ if opts != nil && len(opts.LabelNames) != 0 {
+ ln = opts.LabelNames
+ }
+ return
+}
+
+//RecordStatus record different metrics based on status
+func (e *promRecorder) RecordStatus(LabelValues map[string]string, statusCode int, opts *RecordOptions) {
+ ln := e.GetLN(opts)
+ if statusCode >= http.StatusBadRequest && statusCode <= http.StatusUnavailableForLegalReasons {
+ DefaultPrometheusExporter.Count(LError4XX, ln, LabelValues)
+ DefaultPrometheusExporter.Count(LTotalFailures, ln, LabelValues)
+ } else if statusCode >= http.StatusInternalServerError && statusCode <= http.StatusNetworkAuthenticationRequired {
+ DefaultPrometheusExporter.Count(LError5XX, ln, LabelValues)
+ DefaultPrometheusExporter.Count(LTotalFailures, ln, LabelValues)
+ } else if statusCode >= http.StatusOK && statusCode <= http.StatusIMUsed {
+ DefaultPrometheusExporter.Count(LTotalSuccess, ln, LabelValues)
+ }
+ DefaultPrometheusExporter.Count(LTotalRequest, ln, LabelValues)
+}
+
+//RecordLatency record operation latency
+func (e *promRecorder) RecordLatency(LabelValues map[string]string, latency float64, opts *RecordOptions) {
+ ln := e.GetLN(opts)
+ DefaultPrometheusExporter.Summary(LRequestLatencySeconds, latency, ln, LabelValues)
+
+}
+
+//RecordStartTime save start time
+func (e *promRecorder) RecordStartTime(LabelValues map[string]string, start time.Time, opts *RecordOptions) {
+ ln := e.GetLN(opts)
+ DefaultPrometheusExporter.Gauge(LStartTime, float64(start.Unix()), ln, LabelValues)
+
+}
diff --git a/pkg/metrics/prom_recorder_test.go b/pkg/metrics/prom_recorder_test.go
new file mode 100644
index 0000000..065c342
--- /dev/null
+++ b/pkg/metrics/prom_recorder_test.go
@@ -0,0 +1,12 @@
+package metrics
+
+import (
+ "github.com/stretchr/testify/assert"
+ "testing"
+)
+
+func TestNewPromRecorder(t *testing.T) {
+ _,err := NewPromRecorder(nil)
+ assert.Error(t, err)
+
+}
diff --git a/metrics/prometheus.go b/pkg/metrics/prometheus_exporter.go
similarity index 100%
rename from metrics/prometheus.go
rename to pkg/metrics/prometheus_exporter.go
diff --git a/metrics/metrics_test.go b/pkg/metrics/prometheusexporter_test.go
similarity index 72%
rename from metrics/metrics_test.go
rename to pkg/metrics/prometheusexporter_test.go
index 526586b..fa8215e 100644
--- a/metrics/metrics_test.go
+++ b/pkg/metrics/prometheusexporter_test.go
@@ -18,17 +18,12 @@
package metrics
import (
- "net/http"
"strings"
"testing"
- "github.com/go-chassis/go-chassis/core/config"
- "github.com/go-chassis/go-chassis/core/invocation"
"github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go"
"github.com/stretchr/testify/assert"
-
- "github.com/go-chassis/go-chassis/core/config/model"
)
var (
@@ -86,33 +81,3 @@
assert.Equal(totalMetricCreated, 1)
assert.Equal(*sampleCount, uint64(1))
}
-
-func TestPrepare(t *testing.T) {
- assert := assert.New(t)
- config.GlobalDefinition = new(model.GlobalCfg)
- config.GlobalDefinition.AppID = "sockshop"
- config.SelfVersion = "0.1"
- var inv = &invocation.Invocation{
- MicroServiceName: "service",
- }
- var errorcount4xx float64
- var errorcount5xx float64
- RecordResponse(inv, http.StatusOK)
- RecordResponse(inv, http.StatusNotFound)
- RecordResponse(inv, http.StatusInternalServerError)
- metricFamilies, err := prometheus.DefaultGatherer.Gather()
- assert.Nil(err, "error should be nil while collecting metrics from prometheus")
- for _, metricFamily := range metricFamilies {
- if name := metricFamily.GetName(); strings.Contains(name, Error5XX) {
- errorcount4xx += *metricFamily.Metric[0].Counter.Value
- }
- }
- for _, metricFamily := range metricFamilies {
- if name := metricFamily.GetName(); strings.Contains(name, Error5XX) {
- errorcount5xx += *metricFamily.Metric[0].Counter.Value
- }
- }
- assert.Equal(errorcount4xx, float64(1))
- assert.Equal(errorcount5xx, float64(1))
-
-}
diff --git a/pkg/runtime/runtime.go b/pkg/runtime/runtime.go
new file mode 100644
index 0000000..bf2603c
--- /dev/null
+++ b/pkg/runtime/runtime.go
@@ -0,0 +1,6 @@
+package runtime
+
+var (
+ //Mode is of type string which gives mode of mesher deployment
+ Mode string
+)
diff --git a/plugins/registry/istiov2/cache.go b/plugins/registry/istiov2/cache.go
new file mode 100644
index 0000000..ec05328
--- /dev/null
+++ b/plugins/registry/istiov2/cache.go
@@ -0,0 +1,286 @@
+package istiov2
+
+import (
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ apiv2endpoint "github.com/envoyproxy/go-control-plane/envoy/api/v2/endpoint"
+ istioinfra "github.com/go-mesh/mesher/pkg/infras/istio"
+
+ "github.com/go-chassis/go-chassis/core/archaius"
+ "github.com/go-chassis/go-chassis/core/common"
+ "github.com/go-chassis/go-chassis/core/config"
+ "github.com/go-chassis/go-chassis/core/lager"
+ "github.com/go-chassis/go-chassis/core/registry"
+)
+
+const (
+ DefaultRefreshInterval = time.Second * 30
+)
+
+var simpleCache *EndpointCache
+
+func init() {
+ simpleCache = &EndpointCache{
+ cache: map[string]EndpointSubset{},
+ }
+}
+
+//CacheManager manages the caches for istio pilot results.
+type CacheManager struct {
+ xdsClient *istioinfra.XdsClient
+}
+
+//AutoSync fetches and updates the cluster and endpoint info periodically
+func (cm *CacheManager) AutoSync() {
+ cm.refreshCache()
+
+ var ticker *time.Ticker
+ refreshInterval := config.GetServiceDiscoveryRefreshInterval()
+ if refreshInterval == "" {
+ ticker = time.NewTicker(DefaultRefreshInterval)
+ } else {
+ timeValue, err := time.ParseDuration(refreshInterval)
+ if err != nil {
+ lager.Logger.Errorf("refeshInterval is invalid. So use Default value: %s", err.Error())
+ timeValue = DefaultRefreshInterval
+ }
+
+ ticker = time.NewTicker(timeValue)
+ }
+ go func() {
+ for range ticker.C {
+ cm.refreshCache()
+ }
+ }()
+}
+
+func (cm *CacheManager) refreshCache() {
+ // TODO What is the design of autodiscovery
+ if archaius.GetBool("cse.service.registry.autodiscovery", false) {
+ lager.Logger.Errorf("SyncPilotEndpoints failed: not supported")
+ }
+
+ err := cm.pullMicroserviceInstance()
+ if err != nil {
+ lager.Logger.Errorf("AutoUpdateMicroserviceInstance failed: %s", err.Error())
+ }
+
+ if archaius.GetBool("cse.service.registry.autoSchemaIndex", false) {
+ lager.Logger.Errorf("MakeSchemaIndex failed: Not support operation")
+ }
+
+ if archaius.GetBool("cse.service.registry.autoIPIndex", false) {
+ err = cm.MakeIPIndex()
+ if err != nil {
+ lager.Logger.Errorf("Auto Update IP index failed: %s", err.Error())
+ }
+ }
+}
+
+func (cm *CacheManager) pullMicroserviceInstance() error {
+ clusterInfos, err := cm.getClusterInfos()
+ if err != nil {
+ return err
+ }
+
+ for _, clusterInfo := range clusterInfos {
+ if clusterInfo.Subset != "" {
+ // Update the cache
+ instances := []*registry.MicroServiceInstance{}
+ for _, addr := range clusterInfo.Addrs {
+ msi := ®istry.MicroServiceInstance{}
+ msi.InstanceID = strings.Replace(addr, ":", "_", 0)
+ msi.HostName = clusterInfo.ClusterName
+ msi.EndpointsMap = map[string]string{
+ common.ProtocolRest: addr,
+ }
+ msi.DefaultEndpoint = addr
+ msi.DefaultProtocol = common.ProtocolRest
+ msi.Metadata = clusterInfo.Tags
+
+ instances = append(instances, msi)
+ }
+
+ endpointSubset := EndpointSubset{
+ tags: clusterInfo.Tags,
+ instances: instances,
+ subsetName: clusterInfo.Subset,
+ }
+ simpleCache.Set(clusterInfo.ClusterName, endpointSubset)
+ }
+ }
+
+ return nil
+}
+
+//MakeIPIndex caches the cluster info with address as the key
+func (cm *CacheManager) MakeIPIndex() error {
+ // TODO Use getClusterInfo to replace the logic
+ clusterInfos, err := cm.getClusterInfos()
+ if err != nil {
+ return err
+ }
+
+ for _, clusterInfo := range clusterInfos {
+ for _, addr := range clusterInfo.Addrs {
+ si := ®istry.SourceInfo{}
+ // TODO Get tags by subset and put them into si.Tags
+ si.Name = clusterInfo.ClusterName
+ si.Tags = clusterInfo.Tags
+ registry.SetIPIndex(addr, si)
+ // TODO Why don't we have to index every endpoint?
+ // break
+ }
+ }
+
+ return nil
+}
+
+//NewCacheManager creates the CacheManager instance.
+func NewCacheManager(xdsClient *istioinfra.XdsClient) (*CacheManager, error) {
+ cacheManager := &CacheManager{
+ xdsClient: xdsClient,
+ }
+
+ return cacheManager, nil
+}
+
+func (cm *CacheManager) getClusterInfos() ([]istioinfra.XdsClusterInfo, error) {
+ clusterInfos := []istioinfra.XdsClusterInfo{}
+
+ clusters, err := cm.xdsClient.CDS()
+ if err != nil {
+ return nil, err
+ }
+
+ for _, cluster := range clusters {
+ // xDS v2 API: CDS won't obtain the cluster's endpoints, call EDS to get the endpoints
+
+ clusterInfo := istioinfra.ParseClusterName(cluster.Name)
+ if clusterInfo == nil {
+ continue
+ }
+
+ // Get Tags
+ if clusterInfo.Subset != "" { // Only clusters with subset contain labels
+ if tags, err := cm.xdsClient.GetSubsetTags(clusterInfo.Namespace, clusterInfo.ServiceName, clusterInfo.Subset); err == nil {
+ clusterInfo.Tags = tags
+ }
+ }
+
+ // Get cluster instances' addresses
+ loadAssignment, err := cm.xdsClient.EDS(cluster.Name)
+ if err != nil {
+ return nil, err
+ }
+ endpoints := loadAssignment.Endpoints
+ for _, endpoint := range endpoints {
+ for _, lbendpoint := range endpoint.LbEndpoints {
+ socketAddress := lbendpoint.Endpoint.Address.GetSocketAddress()
+ addr := socketAddress.GetAddress()
+ port := socketAddress.GetPortValue()
+ ipAddr := addr + ":" + strconv.FormatUint(uint64(port), 10)
+ clusterInfo.Addrs = append(clusterInfo.Addrs, ipAddr)
+ }
+ }
+
+ clusterInfos = append(clusterInfos, *clusterInfo)
+ }
+ return clusterInfos, nil
+}
+
+// TODO Cache with registry index cache
+func updateInstanceIndexCache(lbendpoints []apiv2endpoint.LbEndpoint, clusterName string, tags map[string]string) {
+ if len(lbendpoints) == 0 {
+ simpleCache.Delete(clusterName)
+ return
+ }
+
+ instances := make([]*registry.MicroServiceInstance, 0, len(lbendpoints))
+ for _, lbendpoint := range lbendpoints {
+ msi := toMicroServiceInstance(clusterName, &lbendpoint, tags)
+ instances = append(instances, msi)
+ }
+ subset := EndpointSubset{
+ tags: tags,
+ instances: instances,
+ }
+
+ info := istioinfra.ParseClusterName(clusterName)
+ if info != nil {
+ subset.subsetName = info.Subset
+ }
+
+ simpleCache.Set(clusterName, subset)
+}
+
+//EndpointCache caches the clusters' endpoint and tags
+type EndpointCache struct {
+ mux sync.Mutex
+ cache map[string]EndpointSubset
+}
+
+//EndpointSubset stores the tags and instances of a service
+type EndpointSubset struct {
+ subsetName string
+ tags map[string]string
+ instances []*registry.MicroServiceInstance
+}
+
+//Delete removes the cached instances of the specified cluster
+func (c *EndpointCache) Delete(clusterName string) {
+ c.mux.Lock()
+ delete(c.cache, clusterName)
+ c.mux.Unlock()
+}
+
+//Set updates the cluster's instance info
+func (c *EndpointCache) Set(clusterName string, subset EndpointSubset) {
+ c.mux.Lock()
+ c.cache[clusterName] = subset
+ c.mux.Unlock()
+}
+
+//GetWithTags returns the instances of the service, filtered with tags
+func (c *EndpointCache) GetWithTags(serviceName string, tags map[string]string) []*registry.MicroServiceInstance {
+ // Get subsets whose clusterName matches the service name
+ matchedSubsets := []EndpointSubset{}
+ c.mux.Lock()
+ for clusterName, subset := range c.cache {
+ info := istioinfra.ParseClusterName(clusterName)
+ if info != nil && info.ServiceName == serviceName {
+ matchedSubsets = append(matchedSubsets, subset)
+ }
+ }
+ c.mux.Unlock()
+
+ if len(matchedSubsets) == 0 {
+ return nil
+ }
+
+ var instances []*registry.MicroServiceInstance
+
+ for _, subset := range matchedSubsets {
+ if tagsMatch(subset.tags, tags) {
+ instances = subset.instances
+ break
+ }
+
+ }
+ return instances
+}
+
+// TODO There might be some utils in go-chassis doing the same thing
+func tagsMatch(tags, targetTags map[string]string) bool {
+ matched := true
+ for k, v := range targetTags {
+ if val, exists := tags[k]; !exists || val != v {
+ matched = false
+ break
+ }
+ }
+ return matched
+}
diff --git a/plugins/registry/istiov2/cache_test.go b/plugins/registry/istiov2/cache_test.go
new file mode 100644
index 0000000..6eedd34
--- /dev/null
+++ b/plugins/registry/istiov2/cache_test.go
@@ -0,0 +1,126 @@
+package istiov2
+
+import (
+ "os"
+ "os/user"
+ "testing"
+
+ "github.com/go-chassis/go-chassis/core/lager"
+ "github.com/go-chassis/go-chassis/core/registry"
+ "github.com/go-chassis/go-chassis/pkg/util/iputil"
+ testutil "github.com/go-mesh/mesher-tools/test/util"
+ istioinfra "github.com/go-mesh/mesher/pkg/infras/istio"
+ "istio.io/istio/tests/util"
+)
+
+const (
+ TEST_POD_NAME = "testpod"
+ NAMESPACE_DEFAULT = "default"
+)
+
+var (
+ KubeConfig string
+ ValidPilotAddr string
+ LocalIPAddress string
+ nodeInfo *istioinfra.NodeInfo
+
+ testXdsClient *istioinfra.XdsClient
+ testCacheManager *CacheManager
+ err error
+)
+
+func TestMain(t *testing.T) {
+ lager.Initialize("", "DEBUG", "", "size", true, 1, 10, 7)
+ // Get kube config path and local ip
+ if KUBE_CONFIG := os.Getenv("KUBE_CONFIG"); KUBE_CONFIG != "" {
+ KubeConfig = KUBE_CONFIG
+ } else {
+ usr, err := user.Current()
+ if err != nil {
+ panic("Failed to get current user info: " + err.Error())
+ } else {
+ KubeConfig = usr.HomeDir + "/" + ".kube/config"
+ }
+ }
+
+ if PILOT_ADDR := os.Getenv("PILOT_ADDR"); PILOT_ADDR != "" {
+ ValidPilotAddr = PILOT_ADDR
+ } else {
+ // panic("PILOT_ADDR should be specified to pass the pilot address")
+ testutil.InitLocalPilotTestEnv(t)
+ ValidPilotAddr = util.MockPilotGrpcAddr
+ }
+
+ if INSTANCE_IP := os.Getenv("INSTANCE_IP"); INSTANCE_IP != "" {
+ LocalIPAddress = INSTANCE_IP
+ } else if LocalIPAddress = iputil.GetLocalIP(); LocalIPAddress == "" {
+ panic("Failed to get the local ip address, please check the network environment")
+ }
+
+ nodeInfo = &istioinfra.NodeInfo{
+ PodName: TEST_POD_NAME,
+ Namespace: NAMESPACE_DEFAULT,
+ InstanceIP: LocalIPAddress,
+ }
+
+ testXdsClient, err = istioinfra.NewXdsClient(ValidPilotAddr, nil, nodeInfo, KubeConfig)
+ if err != nil {
+ panic("Failed to prepare test, xds client creation failed: " + err.Error())
+ }
+}
+
+func TestNewCacheManager(t *testing.T) {
+ testCacheManager, err = NewCacheManager(testXdsClient)
+ if err != nil {
+ t.Errorf("Failed to create CacheManager: %s", err.Error())
+ }
+}
+
+// func TestAutoSync(t *testing.T) {
+// testCacheManager.AutoSync()
+// }
+
+func TestPullImcroserviceInstance(t *testing.T) {
+ err = testCacheManager.pullMicroserviceInstance()
+ if err != nil {
+ t.Errorf("Failed to pull microservice instances: %s", err.Error())
+ }
+}
+
+// func TestMakeIPIndex(t *testing.T) {
+// err := testCacheManager.MakeIPIndex()
+// if err != nil {
+// t.Errorf("Failed to make ip index: %s", err.Error())
+// }
+// }
+
+func TestEndpointCache(t *testing.T) {
+ ec := EndpointCache{
+ cache: map[string]EndpointSubset{},
+ }
+
+ subset := EndpointSubset{
+ subsetName: "foo",
+ tags: map[string]string{},
+ instances: []*registry.MicroServiceInstance{},
+ }
+
+ defer func() {
+ if r := recover(); r != nil {
+ t.Error("should not panic")
+ }
+ }()
+
+ waitChannel := make(chan int)
+ for i := 0; i < 1000; i++ {
+ go func() {
+ ec.Set("foo", subset)
+ waitChannel <- 0
+
+ }()
+ }
+
+ for i := 0; i < 1000; i++ {
+ <-waitChannel
+ }
+}
diff --git a/plugins/registry/istiov2/registry.go b/plugins/registry/istiov2/registry.go
new file mode 100644
index 0000000..624dffc
--- /dev/null
+++ b/plugins/registry/istiov2/registry.go
@@ -0,0 +1,243 @@
+package istiov2
+
+import (
+ "fmt"
+ "log"
+ "os"
+ "strconv"
+ "strings"
+
+ apiv2 "github.com/envoyproxy/go-control-plane/envoy/api/v2"
+ apiv2endpoint "github.com/envoyproxy/go-control-plane/envoy/api/v2/endpoint"
+ istioinfra "github.com/go-mesh/mesher/pkg/infras/istio"
+
+ "github.com/go-chassis/go-chassis/core/common"
+ "github.com/go-chassis/go-chassis/core/metadata"
+ "github.com/go-chassis/go-chassis/core/registry"
+ "github.com/go-chassis/go-chassis/pkg/util/iputil"
+ "github.com/go-chassis/go-chassis/pkg/util/tags"
+ "github.com/go-mesh/openlogging"
+)
+
+var (
+ //PodName is the name of the pod that mesher runs in
+ PodName string
+ //PodNamespace is the namespace which the pod belongs to
+ PodNamespace string
+ //InstanceIP is the IP of the pod(the IP of the first network adaptor)
+ InstanceIP string
+)
+
+const (
+ PilotV2Registry = "pilotv2"
+)
+
+//ServiceDiscovery is the discovery service for istio pilot with xDS v2 API
+type ServiceDiscovery struct {
+ Name string
+ client *istioinfra.XdsClient
+ options registry.Options
+}
+
+//GetMicroServiceID returns the id of the micro service
+func (discovery *ServiceDiscovery) GetMicroServiceID(appID, microServiceName, version, env string) (string, error) {
+ return microServiceName, nil
+}
+
+//GetAllMicroServices returns all the micro services, which is mapped from xDS clusters
+func (discovery *ServiceDiscovery) GetAllMicroServices() ([]*registry.MicroService, error) {
+ clusters, err := discovery.client.CDS()
+ if err != nil {
+ return nil, err
+ }
+ microServices := []*registry.MicroService{}
+ for _, cluster := range clusters {
+ microServices = append(microServices, toMicroService(&cluster))
+ }
+ return microServices, nil
+}
+
+func toMicroService(cluster *apiv2.Cluster) *registry.MicroService {
+ svc := ®istry.MicroService{}
+ svc.ServiceID = cluster.Name
+ svc.ServiceName = cluster.Name
+ svc.Version = common.DefaultVersion
+ svc.AppID = common.DefaultApp
+ svc.Level = "BACK"
+ svc.Status = "UP"
+ svc.Framework = ®istry.Framework{
+ Name: "Istio",
+ Version: common.LatestVersion,
+ }
+ svc.RegisterBy = metadata.PlatformRegistrationComponent
+
+ return svc
+}
+
+func toMicroServiceInstance(clusterName string, lbendpoint *apiv2endpoint.LbEndpoint, tags map[string]string) *registry.MicroServiceInstance {
+ socketAddress := lbendpoint.Endpoint.Address.GetSocketAddress()
+ addr := socketAddress.Address
+ port := socketAddress.GetPortValue()
+ portStr := strconv.FormatUint(uint64(port), 10)
+ msi := ®istry.MicroServiceInstance{}
+ msi.InstanceID = addr + "_" + portStr
+ msi.HostName = clusterName
+ msi.DefaultEndpoint = addr + ":" + portStr
+ msi.EndpointsMap = map[string]string{
+ common.ProtocolRest: msi.DefaultEndpoint,
+ }
+ msi.DefaultProtocol = common.ProtocolRest
+ msi.Metadata = tags
+
+ return msi
+}
+
+//GetMicroService returns the micro service info
+func (discovery *ServiceDiscovery) GetMicroService(microServiceID string) (*registry.MicroService, error) {
+ // If the service is in the clusters, return it, or nil
+
+ clusters, err := discovery.client.CDS()
+ if err != nil {
+ return nil, err
+ }
+
+ var targetCluster apiv2.Cluster
+ for _, cluster := range clusters {
+ parts := strings.Split(cluster.Name, "|")
+ if len(parts) < 4 {
+ openlogging.GetLogger().Warnf("Invalid cluster name: %s", cluster.Name)
+ continue
+ }
+
+ svcName := parts[3]
+ if strings.Index(svcName, microServiceID+".") == 0 {
+ targetCluster = cluster
+ break
+ }
+ }
+
+ if &targetCluster == nil {
+ return nil, nil
+ }
+
+ return toMicroService(&targetCluster), nil
+}
+
+//GetMicroServiceInstances returns the instances of the micro service
+func (discovery *ServiceDiscovery) GetMicroServiceInstances(consumerID, providerID string) ([]*registry.MicroServiceInstance, error) {
+ // TODO Handle the registry.MicroserviceIndex cache
+ // TODO Handle the microServiceName
+ service, err := discovery.GetMicroService(providerID)
+ if err != nil {
+ return nil, err
+ }
+
+ loadAssignment, err := discovery.client.EDS(service.ServiceName)
+ if err != nil {
+ return nil, err
+ }
+
+ instances := []*registry.MicroServiceInstance{}
+ endpionts := loadAssignment.Endpoints
+ for _, item := range endpionts {
+ for _, lbendpoint := range item.LbEndpoints {
+ msi := toMicroServiceInstance(loadAssignment.ClusterName, &lbendpoint, nil) // The cluster without subset doesn't have tags
+ instances = append(instances, msi)
+ }
+ }
+
+ return instances, nil
+}
+
+//FindMicroServiceInstances returns the micro service's instances filtered with tags
+func (discovery *ServiceDiscovery) FindMicroServiceInstances(consumerID, microServiceName string, tags utiltags.Tags) ([]*registry.MicroServiceInstance, error) {
+ if tags.KV == nil || tags.Label == "" { // Chassis might pass an empty tags
+ return discovery.GetMicroServiceInstances(consumerID, microServiceName)
+ }
+
+ instances := simpleCache.GetWithTags(microServiceName, tags.KV)
+ if len(instances) == 0 {
+ var lbendpoints []apiv2endpoint.LbEndpoint
+ var err error
+ lbendpoints, clusterName, err := discovery.client.GetEndpointsByTags(microServiceName, tags.KV)
+ if err != nil {
+ return nil, err
+ }
+
+ updateInstanceIndexCache(lbendpoints, clusterName, tags.KV)
+
+ instances = simpleCache.GetWithTags(microServiceName, tags.KV)
+ if instances == nil {
+ return nil, fmt.Errorf("Failed to find microservice instances of %s from cache", microServiceName)
+ }
+ }
+ return instances, nil
+}
+
+var cacheManager *CacheManager
+
+//AutoSync updates the services' info periodically in the background
+func (discovery *ServiceDiscovery) AutoSync() {
+ var err error
+ cacheManager, err = NewCacheManager(discovery.client)
+ if err != nil {
+ openlogging.GetLogger().Errorf("Failed to create cache manager, indexing will not work: %s", err.Error())
+ } else {
+ cacheManager.AutoSync()
+ }
+}
+
+//Close closes the discovery service
+func (discovery *ServiceDiscovery) Close() error {
+ return nil
+}
+
+//NewDiscoveryService creates the new ServiceDiscovery instance
+func NewDiscoveryService(options registry.Options) registry.ServiceDiscovery {
+ if len(options.Addrs) == 0 {
+ panic("Failed to create discovery service: Address not specified")
+ }
+ pilotAddr := options.Addrs[0]
+ nodeInfo := &istioinfra.NodeInfo{
+ PodName: PodName,
+ Namespace: PodNamespace,
+ InstanceIP: InstanceIP,
+ }
+ xdsClient, err := istioinfra.NewXdsClient(pilotAddr, options.TLSConfig, nodeInfo, options.ConfigPath)
+ if err != nil {
+ panic("Failed to create XDS client: " + err.Error())
+ }
+
+ discovery := &ServiceDiscovery{
+ client: xdsClient,
+ Name: PilotV2Registry,
+ options: options,
+ }
+
+ return discovery
+}
+
+func init() {
+ // Init the node info
+ PodName = os.Getenv("POD_NAME")
+ PodNamespace = os.Getenv("POD_NAMESPACE")
+ InstanceIP = os.Getenv("INSTANCE_IP")
+
+ // TODO Handle the default value
+ if PodName == "" {
+ PodName = "pod_name_default"
+ }
+ if PodNamespace == "" {
+ PodNamespace = "default"
+ }
+ if InstanceIP == "" {
+ log.Println("[WARN] Env var INSTANCE_IP not set, try to get instance ip from local network, the service might not work properly.")
+ InstanceIP = iputil.GetLocalIP()
+ if InstanceIP == "" {
+ // Won't work without instance ip
+ panic("Failed to get instance ip")
+ }
+ }
+
+ registry.InstallServiceDiscovery(PilotV2Registry, NewDiscoveryService)
+}
diff --git a/plugins/registry/istiov2/registry_test.go b/plugins/registry/istiov2/registry_test.go
new file mode 100644
index 0000000..6bc0aca
--- /dev/null
+++ b/plugins/registry/istiov2/registry_test.go
@@ -0,0 +1,206 @@
+package istiov2
+
+import (
+ "os"
+ "strconv"
+ "testing"
+
+ apiv2 "github.com/envoyproxy/go-control-plane/envoy/api/v2"
+ apiv2core "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
+ apiv2endpoint "github.com/envoyproxy/go-control-plane/envoy/api/v2/endpoint"
+ istioinfra "github.com/go-mesh/mesher/pkg/infras/istio"
+
+ "github.com/go-chassis/go-chassis/core/registry"
+ "github.com/go-chassis/go-chassis/pkg/util/tags"
+)
+
+var VaildServiceDiscovery registry.ServiceDiscovery
+var AllServices []*registry.MicroService
+
+func TestNewDiscoveryService(t *testing.T) {
+ options := registry.Options{
+ Addrs: []string{ValidPilotAddr},
+ ConfigPath: KubeConfig,
+ }
+
+ // Explicitly set the env vars, though this is checkd in the init of cache_test
+ os.Setenv("POD_NAME", TEST_POD_NAME)
+ os.Setenv("NAMESPACE", NAMESPACE_DEFAULT)
+ os.Setenv("INSTANCE_IP", LocalIPAddress)
+
+ // No panic should happen
+ VaildServiceDiscovery = NewDiscoveryService(options)
+
+}
+
+// func TestAutoSync(t *testing.T) {
+// archaius.Init()
+// VaildServiceDiscovery.AutoSync()
+// }
+
+func TestEmptyPilotAddrs(t *testing.T) {
+ defer func() {
+ if err := recover(); err == nil {
+ t.Errorf("Panic should be caught")
+ }
+ }()
+
+ emptyAddrsOptions := registry.Options{
+ Addrs: []string{},
+ ConfigPath: KubeConfig,
+ }
+ NewDiscoveryService(emptyAddrsOptions)
+}
+
+func TestGetAllMicroServices(t *testing.T) {
+ services, err := VaildServiceDiscovery.GetAllMicroServices()
+ if err != nil {
+ t.Errorf("Failed to get all micro services: %s", err.Error())
+ }
+
+ if len(services) == 0 {
+ t.Log("Warn: no micro services found")
+ }
+
+}
+
+func TestGetMicroServiceID(t *testing.T) {
+ serviceName := "pilotv2server"
+ msID, err := VaildServiceDiscovery.GetMicroServiceID("default", serviceName, "v3", "")
+ if err != nil {
+ t.Errorf("Failed to get micro service id: %s", err.Error())
+ }
+
+ if msID != serviceName {
+ t.Errorf("In pilotv2 discovery, msID should be equal to serviceName(%s != %s)", msID, serviceName)
+ }
+}
+
+func TestGetMicroService(t *testing.T) {
+ serviceName := "istio-pilot"
+ svc, err := VaildServiceDiscovery.GetMicroService(serviceName)
+ if err != nil {
+ t.Errorf("Failed to get micro service: %s", err.Error())
+ }
+ if svc == nil {
+ t.Errorf("istio-pilot service should not be nil")
+ }
+}
+
+func TestGetMicroServiceInstance(t *testing.T) {
+ // serviceName := "istio-pilot"
+ serviceName := "hello"
+ instances, err := VaildServiceDiscovery.GetMicroServiceInstances("pilotv2client", serviceName)
+ if err != nil {
+ t.Errorf("Failed to get micro service instances of istio-pilot: %s", err.Error())
+ }
+ if len(instances) == 0 {
+ t.Errorf("istio-pilot's instances should not be empty")
+ }
+}
+
+func TestFindMicroServiceInstances(t *testing.T) {
+ discovery, ok := VaildServiceDiscovery.(*ServiceDiscovery)
+ if !ok {
+ t.Errorf("Failed to convert discovery into type istiov2.ServiceDiscovery")
+ return
+ }
+ client := discovery.client
+
+ clusters, err := client.CDS()
+ if err != nil {
+ t.Errorf("Failed to teset FindMicroServiceInstances, CDS failed: %s", err.Error())
+ }
+
+ var clusterWithSubset *istioinfra.XdsClusterInfo = nil
+ for _, c := range clusters {
+ if info := istioinfra.ParseClusterName(c.Name); info != nil && info.Subset != "" {
+ clusterWithSubset = info
+ }
+ }
+
+ if clusterWithSubset != nil {
+ // an empty tags will make sure target tag always match
+ emptyTags := utiltags.Tags{
+ KV: map[string]string{},
+ Label: "",
+ }
+ instances, err := VaildServiceDiscovery.FindMicroServiceInstances("pilotv2client", clusterWithSubset.ServiceName, emptyTags)
+ if err != nil {
+ t.Errorf("Failed to FindMicroServiceInstances of %s: %s", clusterWithSubset.ServiceName, err.Error())
+ }
+ if len(instances) == 0 {
+ t.Logf("%s's service instances is empty\n", clusterWithSubset.ServiceName)
+ t.Logf("Pls check if the destinationrule and corresponding pod tags are matching")
+ }
+ } else if len(clusters) != 0 {
+ t.Log("No clusters are with subsets")
+ targetCluster := clusters[0]
+
+ tags := utiltags.Tags{
+ KV: map[string]string{
+ "version": "v1",
+ },
+ Label: "version=v1",
+ }
+ _, err := VaildServiceDiscovery.FindMicroServiceInstances("pilotv2client", targetCluster.Name, tags)
+ if err == nil {
+ t.Errorf("Should caught error to get the endpoints of cluster without tags")
+ }
+ }
+
+}
+
+func TestToMicroService(t *testing.T) {
+ cluster := &apiv2.Cluster{
+ Name: "pilotv2server",
+ }
+
+ svc := toMicroService(cluster)
+
+ if svc.ServiceID != cluster.Name {
+ t.Errorf("service id should be equal to cluster name(%s != %s)", svc.ServiceID, cluster.Name)
+ }
+}
+
+func TestToMicroServiceInstance(t *testing.T) {
+ lbendpoint := &apiv2endpoint.LbEndpoint{
+ Endpoint: &apiv2endpoint.Endpoint{
+ Address: &apiv2core.Address{
+ Address: &apiv2core.Address_SocketAddress{
+ SocketAddress: &apiv2core.SocketAddress{
+ Address: "192.168.0.10:8822",
+ },
+ },
+ },
+ },
+ }
+ clusterName := "pilotv2server"
+ tags := map[string]string{
+ "version": "v1",
+ }
+ msi := toMicroServiceInstance(clusterName, lbendpoint, tags)
+
+ socketAddr := lbendpoint.Endpoint.Address.GetSocketAddress()
+ addr := socketAddr.GetAddress()
+ port := socketAddr.GetPortValue()
+
+ if msi.InstanceID != addr+"_"+strconv.FormatUint(uint64(port), 10) {
+ t.Errorf("Invalid msi.InstanceID: %s should be equal to %s_%d", msi.InstanceID, addr, port)
+ }
+
+ if msi.HostName != clusterName {
+ t.Errorf("Invalid msi.HostName: %s should be equal to %s", msi.HostName, clusterName)
+ }
+
+ // Test if the tags match
+ if !tagsMatch(tags, msi.Metadata) {
+ t.Errorf("Tags not match, %v should be subset of %s", tags, msi.Metadata)
+ }
+}
+
+func TestClose(t *testing.T) {
+ if err := VaildServiceDiscovery.Close(); err != nil {
+ t.Error(err)
+ }
+}
diff --git a/protocol/dubbo/proxy/dubbo_proxy_ouput.go b/protocol/dubbo/proxy/dubbo_proxy_ouput.go
index 6ee6e06..a1b026a 100755
--- a/protocol/dubbo/proxy/dubbo_proxy_ouput.go
+++ b/protocol/dubbo/proxy/dubbo_proxy_ouput.go
@@ -24,14 +24,6 @@
"net/http"
"net/url"
- mesherCommon "github.com/go-mesh/mesher/common"
- "github.com/go-mesh/mesher/config"
- "github.com/go-mesh/mesher/protocol/dubbo/client"
- "github.com/go-mesh/mesher/protocol/dubbo/dubbo"
- "github.com/go-mesh/mesher/protocol/dubbo/schema"
- "github.com/go-mesh/mesher/protocol/dubbo/utils"
- "github.com/go-mesh/mesher/resolver"
-
"github.com/go-chassis/go-chassis/client/rest"
"github.com/go-chassis/go-chassis/core/common"
chassisconfig "github.com/go-chassis/go-chassis/core/config"
@@ -43,7 +35,14 @@
"github.com/go-chassis/go-chassis/pkg/runtime"
"github.com/go-chassis/go-chassis/pkg/util/tags"
"github.com/go-chassis/go-chassis/third_party/forked/afex/hystrix-go/hystrix"
+ mesherCommon "github.com/go-mesh/mesher/common"
+ mesherRuntime "github.com/go-mesh/mesher/pkg/runtime"
"github.com/go-mesh/mesher/protocol"
+ "github.com/go-mesh/mesher/protocol/dubbo/client"
+ "github.com/go-mesh/mesher/protocol/dubbo/dubbo"
+ "github.com/go-mesh/mesher/protocol/dubbo/schema"
+ "github.com/go-mesh/mesher/protocol/dubbo/utils"
+ "github.com/go-mesh/mesher/resolver"
)
var dr = resolver.GetDestinationResolver("http")
@@ -197,7 +196,7 @@
ctx.Req.SetAttachment(common.HeaderSourceName, chassisconfig.SelfServiceName)
ctx.Req.SetAttachment(ProxyTag, "true")
- if config.Mode == mesherCommon.ModeSidecar {
+ if mesherRuntime.Mode == mesherCommon.ModeSidecar {
c, err = handler.GetChain(common.Consumer, mesherCommon.ChainConsumerOutgoing)
if err != nil {
lager.Logger.Error("Get Consumer chain failed: " + err.Error())
@@ -303,7 +302,7 @@
return err
}
- if config.Mode == mesherCommon.ModeSidecar {
+ if mesherRuntime.Mode == mesherCommon.ModeSidecar {
c, err = handler.GetChain(common.Consumer, mesherCommon.ChainConsumerOutgoing)
if err != nil {
lager.Logger.Error("Get chain failed: " + err.Error())
diff --git a/protocol/grpc/server.go b/protocol/grpc/server.go
index ab0e2e9..00cc4dc 100755
--- a/protocol/grpc/server.go
+++ b/protocol/grpc/server.go
@@ -22,7 +22,6 @@
"errors"
"fmt"
"github.com/go-mesh/mesher/common"
- "github.com/go-mesh/mesher/config"
"github.com/go-mesh/mesher/resolver"
"net"
"strings"
@@ -32,6 +31,7 @@
"github.com/go-chassis/go-chassis/core/lager"
"github.com/go-chassis/go-chassis/core/server"
chassisTLS "github.com/go-chassis/go-chassis/core/tls"
+ "github.com/go-mesh/mesher/pkg/runtime"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
@@ -72,7 +72,7 @@
return fmt.Errorf("only support ipv4, input is [%s]", hs.opts.Address)
}
- switch config.Mode {
+ switch runtime.Mode {
case common.ModeSidecar:
err = hs.startSidecar(host, port)
case common.ModePerHost:
diff --git a/protocol/http/http_server.go b/protocol/http/http_server.go
index e830c88..d6dbda0 100644
--- a/protocol/http/http_server.go
+++ b/protocol/http/http_server.go
@@ -34,6 +34,7 @@
"github.com/go-chassis/go-chassis/core/lager"
"github.com/go-chassis/go-chassis/core/server"
chassisTLS "github.com/go-chassis/go-chassis/core/tls"
+ "github.com/go-mesh/mesher/pkg/runtime"
)
const (
@@ -72,7 +73,7 @@
return fmt.Errorf("only support ipv4, input is [%s]", hs.opts.Address)
}
- switch config.Mode {
+ switch runtime.Mode {
case common.ModeSidecar:
err = hs.startSidecar(host, port)
case common.ModePerHost:
diff --git a/protocol/http/reverse_proxy.go b/protocol/http/reverse_proxy.go
index 1b280d6..2e708c0 100755
--- a/protocol/http/reverse_proxy.go
+++ b/protocol/http/reverse_proxy.go
@@ -39,7 +39,7 @@
"github.com/go-chassis/go-chassis/third_party/forked/afex/hystrix-go/hystrix"
"github.com/go-mesh/mesher/cmd"
"github.com/go-mesh/mesher/common"
- "github.com/go-mesh/mesher/metrics"
+ "github.com/go-mesh/mesher/pkg/metrics"
"github.com/go-mesh/mesher/protocol"
"github.com/go-mesh/mesher/resolver"
)
@@ -74,8 +74,7 @@
func consumerPreHandler(req *http.Request) *invocation.Invocation {
inv := preHandler(req)
inv.SourceServiceID = runtime.ServiceID
- inv.SourceMicroService = chassisconfig.SelfServiceName
- req.Header.Set(chassisCommon.HeaderSourceName, inv.SourceMicroService)
+ req.Header.Set(chassisCommon.HeaderSourceName, runtime.ServiceName)
inv.Ctx = context.TODO()
return inv
}
@@ -121,8 +120,8 @@
}
defer func(begin time.Time) {
timeTaken := time.Since(begin).Seconds()
- serviceLabelValues := map[string]string{metrics.ServiceName: inv.MicroServiceName, metrics.AppID: inv.RouteTags.AppID(), metrics.Version: inv.RouteTags.Version()}
- metrics.DefaultPrometheusExporter.Summary(metrics.RequestLatencySeconds, timeTaken, metrics.LabelNames, serviceLabelValues)
+ serviceLabelValues := map[string]string{metrics.LServiceName: inv.MicroServiceName, metrics.LApp: inv.RouteTags.AppID(), metrics.LVersion: inv.RouteTags.Version()}
+ metrics.RecordLatency(serviceLabelValues, timeTaken, nil)
}(time.Now())
var invRsp *invocation.Response
c.Next(inv, func(ir *invocation.Response) error {
@@ -138,7 +137,7 @@
lager.Logger.Error("Handle request failed: " + err.Error())
return
}
- metrics.RecordResponse(inv, resp.GetStatusCode())
+ RecordStatus(inv, resp.GetStatusCode())
}
//RemoteRequestHandler is for request from remote
@@ -237,7 +236,7 @@
return nil, ir.Err
}
copyChassisResp2HttpResp(w, resp)
- metrics.RecordResponse(inv, resp.Resp.StatusCode)
+ RecordStatus(inv, resp.Resp.StatusCode)
} else {
// unknown error, resp is nil, e.g. connection refused
handleErrorResponse(inv, w, http.StatusBadGateway, ir.Err)
@@ -283,9 +282,14 @@
if err != nil {
w.Write([]byte(err.Error()))
}
- metrics.RecordResponse(inv, statusCode)
+ RecordStatus(inv, statusCode)
}
+//RecordStatus record an operation status
+func RecordStatus(inv *invocation.Invocation, statusCode int) {
+ LabelValues := map[string]string{metrics.LServiceName: inv.MicroServiceName, metrics.LApp: inv.RouteTags.AppID(), metrics.LVersion: inv.RouteTags.Version()}
+ metrics.RecordStatus(LabelValues, statusCode, nil)
+}
func copyHeader(dst, src http.Header) {
for k, vs := range src {
for _, v := range vs {
diff --git a/resolver/log/chassis.log b/resolver/log/chassis.log
deleted file mode 100755
index e69de29..0000000
--- a/resolver/log/chassis.log
+++ /dev/null
diff --git a/scripts/build/build.sh b/scripts/build/build.sh
index 4364edd..af806f6 100644
--- a/scripts/build/build.sh
+++ b/scripts/build/build.sh
@@ -3,17 +3,24 @@
set -x
export PATH=$PATH:/usr/local/go/bin
export GOPATH=/var/lib/jenkins/workspace/Mesher
-rm -rf /var/lib/jenkins/workspace/Mesher
+rm -rf /var/lib/jenkins/workspace/Mesher/src
export BUILD_DIR=/var/lib/jenkins/workspace/Mesher
export PROJECT_DIR=$(dirname $BUILD_DIR)
-mkdir -p /var/lib/jenkins/workspace/Mesher/src/github.com/go-chassis/mesher
+mkdir -p /var/lib/jenkins/workspace/Mesher/src/github.com/go-mesh/mesher
-cp -r /var/lib/jenkins/workspace/mesher/* /var/lib/jenkins/workspace/Mesher/src/github.com/go-chassis/mesher/
+#To checkout to particular commit or tag
+if [ $CHECKOUT_VERSION == "latest" ]; then
+ echo "using latest code"
+else
+ git checkout $CHECKOUT_VERSION
+fi
+
+cp -r /var/lib/jenkins/workspace/mesher/* /var/lib/jenkins/workspace/Mesher/src/github.com/go-mesh/mesher/
release_dir=$PROJECT_DIR/release
repo="github.com"
-project="go-chassis"
+project="go-mesh"
if [ -d $release_dir ]; then
rm -rf $release_dir
@@ -21,16 +28,16 @@
mkdir -p $release_dir
cd $BUILD_DIR/src/$repo/$project/mesher
-#To checkout to particular commit or tag
-if [ $CHECKOUT_VERSION == "latest" ]; then
- echo "using latest code"
-else
- git checkout $CHECKOUT_VERSION
-fi
+
GO111MODULE=on go mod download
GO111MODULE=on go mod vendor
go build -o mesher -a
+if [ $VERSION != "latest" ]; then
+ cd $PROJECT_DIR/mesher
+ git tag -a $TAG_VERSION -m "$TAG_MESSAGE"
+ git push origin $TAG_VERSION
+fi
export WORK_DIR=$BUILD_DIR/src/$repo/$project/mesher
@@ -66,5 +73,12 @@
if [ $JOB_NAME != "" ]; then
cp $release_dir/$pkg_name /var/lib/jenkins/mesher-release
fi
+
+if [ $VERSION != "latest" ]; then
+ date=$(date +%Y-%m-%d)
+ DIR_NAME="mesher-release-$date"
+ mkdir -p /var/lib/jenkins/userContent/mesher-release/$DIR_NAME
+ cp $release_dir/$pkg_name /var/lib/jenkins/userContent/mesher-release/$DIR_NAME
+fi
tar zcvf $WORK_DIR/mesher.tar.gz licenses conf start.sh mesher VERSION
exit 0
diff --git a/scripts/build/build_image.sh b/scripts/build/build_image.sh
index 7779ccd..5d5f6ca 100644
--- a/scripts/build/build_image.sh
+++ b/scripts/build/build_image.sh
@@ -2,24 +2,24 @@
set -e
set -x
-cd /var/lib/jenkins/workspace/Mesher/src/github.com/go-chassis/mesher/
+cd /var/lib/jenkins/workspace/Mesher/src/github.com/go-mesh/mesher/
repo="github.com"
-project="go-chassis"
+project="go-mesh"
export BUILD_DIR=/var/lib/jenkins/workspace/Mesher
export WORK_DIR=$BUILD_DIR/src/$repo/$project/mesher
cd $WORK_DIR
-docker build -t gochassis/mesher:$VERSION .
+docker build -t gomesh/mesher:$VERSION .
cp /var/lib/jenkins/workspace/docker_login.sh .
bash docker_login.sh &> /dev/null
if [ $PUSH_WITH_LATEST_TAG == "YES" ]; then
- docker build -t gochassis/mesher:latest .
- docker push gochassis/mesher:latest
+ docker build -t gomesh/mesher:latest .
+ docker push gomesh/mesher:latest
fi
-docker push gochassis/mesher:$VERSION
+docker push gomesh/mesher:$VERSION
exit 0
diff --git a/scripts/travis/unit_test.sh b/scripts/travis/unit_test.sh
index 7e76a77..81d324b 100644
--- a/scripts/travis/unit_test.sh
+++ b/scripts/travis/unit_test.sh
@@ -9,7 +9,7 @@
if [ $(ls | grep _test.go | wc -l) -gt 0 ]; then
go test -cover -covermode atomic -coverprofile coverage.out
if [ -f coverage.out ]; then
- sed '1d;$d' coverage.out >> $GOPATH/src/github.com/go-chassis/mesher/coverage.txt
+ sed '1d;$d' coverage.out >> $GOPATH/src/github.com/go-mesh/mesher/coverage.txt
fi
fi
done
\ No newline at end of file
diff --git a/start.sh b/start.sh
index b36ca9e..8880e73 100644
--- a/start.sh
+++ b/start.sh
@@ -101,6 +101,27 @@
EOF
fi
+#add instance_properties if any provided
+if [ ! -z "$MD" ]; then
+ echo " instance_properties:" >> $MESHER_CONF_DIR/$MICROSERVICE_YAML
+ while :
+ do
+ KeyArray=$(echo $MD | cut -d '|' -f1)
+ RestArray=$(echo $MD | cut -d '|' -f2-)
+ Writer="-"
+ Key=$(echo $KeyArray | cut -d '=' -f1)
+ Value=$(echo $KeyArray | cut -d '=' -f2-)
+ Writer=" $Writer$Key"
+ Writer="$Writer: $Value"
+ echo $Writer| sed 's/-/ /'
+ echo $Writer | sed 's/-/ /'>> $MESHER_CONF_DIR/$MICROSERVICE_YAML
+ if [ "$KeyArray" = "$RestArray" ]; then
+ break
+ fi
+ MD=$RestArray
+ done
+fi
+
# ENABLE_PROXY_TLS decide whether mesher is https proxy or http proxy
if [[ $TLS_ENABLE && $TLS_ENABLE == true ]]; then
sed -i '/ssl:/a \ \ mesher.Provider.cipherPlugin: default \n \ mesher.Provider.verifyPeer: false \n \ mesher.Provider.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 \n \ mesher.Provider.protocol: TLSv1.2 \n \ mesher.Provider.caFile: \n \ mesher.Provider.certFile: /etc/ssl/meshercert/kubecfg.crt \n \ mesher.Provider.keyFile: /etc/ssl/meshercert/kubecfg.key \n \ mesher.Provider.certPwdFile: \n' $MESHER_CONF_DIR/$TLS_YAML
diff --git a/test/conf/auth.yaml b/test/conf/auth.yaml
deleted file mode 100644
index 56d7e02..0000000
--- a/test/conf/auth.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-## Huawei Public Cloud ak/sk
-cse:
- credentials:
- accessKey:
- secretKey:
- project:
- akskCustomCipher: default #used to decrypt sk when it is encrypted
diff --git a/test/conf/chassis.yaml b/test/conf/chassis.yaml
deleted file mode 100644
index 1d72915..0000000
--- a/test/conf/chassis.yaml
+++ /dev/null
@@ -1,114 +0,0 @@
----
-cse:
- protocols:
- grpc:
- listenAddress: 10.0.2.15:40105
- http:
- listenAddress: 10.0.2.15:30105
- service:
- registry:
- address: http://127.0.0.1:30100 # uri of service center
- #address: https://cse.cn-north-1.myhuaweicloud.com:443 # uri of service center
- scope: full #set full to be able to discover other app's service
- watch: false # set if you want to watch instance change event
- autoIPIndex: true # set to true if u want to resolve source IP to microservice
-# config:
-# client:
-# serverUri: https://cse.cn-north-1.myhuaweicloud.com:443 #uri of config center
-# refreshMode: 1 # 1: only pull config.
-# refreshInterval: 30 # unit is second
-# monitor: #Send monitoring data to CSE monitor Server
-# client:
-# serverUri: https://cse.cn-north-1.myhuaweicloud.com:443 # monitor server url
- handler:
- chain:
- Consumer:
- outgoing: #consumer handlers
- Provider:
- incoming: #provider handlers
-# loadbalance:
-# strategy:
-# name: RoundRobin # Random|RoundRobin|SessionStickiness
-# retryEnabled: false # if there is error, retry request or not
-# retryOnNext: 2 # times to switch to another instance based on strategy
-# retryOnSame: 3 # times to retry on the same instance
-# backoff: # backoff policy of retried request
-# kind: constant # jittered/constant/zero
-# MinMs: 200 # millisecond, Minimum duration to backoff
-# MaxMs: 400 # millisecond, Maximum duration to backoff
-## circuit breaker configurations
-# isolation:
-# Consumer:
-# timeout:
-# enabled: true
-# timeoutInMilliseconds: 1000
-# maxConcurrentRequests: 100
-# circuitBreaker:
-# Consumer:
-# enabled: true
-# forceOpen: false
-# forceClosed: false
-# sleepWindowInMilliseconds: 10000
-# requestVolumeThreshold: 20
-# errorThresholdPercentage: 50
-# fallback:
-# Consumer:
-# enabled: true
-# maxConcurrentRequests: 20
-# fallbackpolicy:
-# Consumer:
-# policy: throwexception
-# flowcontrol:
-# Consumer: # for consumer
-# qps:
-# enabled: true # enable rate limiting or not
-# global:
-# limit: 100 # default limit of consumer
-# limit:
-# Server: 100 # rate limit for request to a provider,it represents 100 request per second
-# Provider:
-# qps:
-# enabled: true # enable rate limiting or not
-# global:
-# limit: 100 # default limit of provider
-# limit:
-# Server: 100 # rate limit for request from a provider, it represents 100 request per second
-
-#ssl:
-## Set those config to make mesher as https service
-# mesher.Provider.cipherPlugin: default
-# mesher.Provider.verifyPeer: false
-# mesher.Provider.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
-# mesher.Provider.protocol: TLSv1.2
-# mesher.Provider.caFile:
-# mesher.Provider.certFile:
-# mesher.Provider.keyFile:
-# mesher.Provider.certPwdFile:
-## Mesher TLS is base on Go Chassis TLS config
-## If users wan't to use transparent, ssl config for consumer and provider must be supplied.
-## The provider is the service which run in the same host/pod with mesher. for example the service name of provider is AccountService, then the ssl tag is AccountService.rest.Provider
-## if u set this , no need to consider about expose your own service as https service,
-## your service can only listen on 127.0.0.1, mesher wil expose https and use http to communicate with your service
-# AccountService.rest.Provider.cipherPlugin: default
-# AccountService.rest.Provider.verifyPeer: false
-# AccountService.rest.Provider.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
-# AccountService.rest.Provider.protocol: TLSv1.2
-# AccountService.rest.Provider.caFile:
-# AccountService.rest.Provider.certFile:
-# AccountService.rest.Provider.keyFile:
-# AccountService.rest.Provider.certPwdFile:
-## If a service want to use transparent tls to call other services, it must supplies consumer ssl config for these services.
-## for example StoreWeb want to communicate with Account service the config is like below
-# AccountService.rest.Consumer.cipherPlugin: default
-# AccountService.rest.Consumer.verifyPeer: false
-# AccountService.rest.Consumer.cipherSuits: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
-# AccountService.rest.Consumer.protocol: TLSv1.2
-# AccountService.rest.Consumer.caFile:
-# AccountService.rest.Consumer.certFile:
-# AccountService.rest.Consumer.keyFile:
-# AccountService.rest.Consumer.certPwdFile:
-#tracing:
-# enabled: true #enable distribution tracing
-# collectorType: zipkin #zipkin: Send tracing info to zipkin server
-# #namedPipe: Write tracing info to linux named pipe.
-# collectorTarget: http://localhost:9411/api/v1/spans #If the collectorType is "zipkin", the target is a zipkin server url, if the collecterType is "file" or "namedPipe", the target is a file path.
diff --git a/test/conf/fault.yaml b/test/conf/fault.yaml
deleted file mode 100644
index d55c9e7..0000000
--- a/test/conf/fault.yaml
+++ /dev/null
@@ -1,51 +0,0 @@
-#cse:
-# governance:
-# Consumer:
-# _global: #最低优先级配置
-# policy: #治理策略 包括fault,loadbalance,circuit breaker等等,目前只是新的fault加入,旧的治理可考虑慢慢增加支持
-# fault: #
-# protocols: # 向协议模块注入错误,考虑未来扩展多任意组件注入错误,所以这么设计
-# rest:
-# delay:
-# fixedDelay: 5
-# percent: 10
-# abort:
-# httpStatus: 421
-# percent: 100
-# highway:
-# delay:
-# fixedDelay: 2
-# percent: 100
-# abort:
-# percent: 30
-# ms1:
-# route: |
-# - precedence: 2
-# match:
-# source: source.service
-# traffic:
-# - tags:
-# version: 1.0
-# weight: 90
-# - tags:
-# version: 1.1
-# weight: 10
-# policy:
-# fault:
-# schemas:
-# sid1:
-# policy:
-# fault:
-# operations:
-# policy:
-# fault:
-# policy: # 微服务名级别治理策略
-# fault:
-# schemas: #schema级别治理策略
-# sid1:
-# policy:
-# fault:
-# operations: #operation级别治理策略
-# policy:
-# fault:
-# Provider: # format same as Consumer
\ No newline at end of file
diff --git a/test/conf/lager.yaml b/test/conf/lager.yaml
deleted file mode 100644
index 0634de4..0000000
--- a/test/conf/lager.yaml
+++ /dev/null
@@ -1,23 +0,0 @@
----
-writers: file,stdout
-# LoggerLevel: |DEBUG|INFO|WARN|ERROR|FATAL
-logger_level: DEBUG
-
-# LoggerFile: used to output the name of log
-logger_file: log/mesher.log
-
-# LogFormatText: json/plaintext (such as log4j),default to false
-# if set logger_file and log_format_text to true, turns out log4j format log
-log_format_text: true
-
-#rollingPolicy daily/size; defines rotate according to daily or size
-rollingPolicy: size
-
-# MaxDaily of a log file before rotate. By D Days.
-log_rotate_date: 1
-
-# MaxSize of a log file before rotate. By M Bytes.
-log_rotate_size: 10
-
-# Max counts to keep of a log's backup files.
-log_backup_count: 7
\ No newline at end of file
diff --git a/test/conf/mesher.yaml b/test/conf/mesher.yaml
deleted file mode 100644
index a6eadeb..0000000
--- a/test/conf/mesher.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-## Router rules and fault injection rules are moved to router.yaml
-#plugin:
-# destinationResolver:
-# http: host # how to turn host to destination name. default to service name,
-
-##admin: #admin API
-# serverUri : 127.0.0.1:30102 # addr on listening
-# goRuntimeMetrics : true # enable metrics
-
-## enable pprof to profile mesher runtime
-#pprof:
-# enable: false
-
-#localHealthCheck:
-# - port: 8080
-# uri: /health
-# interval: 30s
-# match:
-# status: 200
-# body: ok
diff --git a/test/conf/microservice.yaml b/test/conf/microservice.yaml
deleted file mode 100644
index c8356d8..0000000
--- a/test/conf/microservice.yaml
+++ /dev/null
@@ -1,7 +0,0 @@
-## microservice property
-service_description:
- name: Server
- version: 0.0.1
- environment: #microservice environment
- properties:
- allowCrossApp: false #whether to allow calls across applications
diff --git a/test/conf/router.yaml b/test/conf/router.yaml
deleted file mode 100644
index 1146860..0000000
--- a/test/conf/router.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-#routeRule:
-# ShoppingCart: #service name
-# - precedence: 2 #precedence of route rule
-# route: #route rule list
-# - tags:
-# version: 0.2
-# app: HelloWorld
-# weight: 80 #weight of 80%
-# - tags:
-# version: 1.2
-# app: HelloWorld
-# weight: 20 #weight of 20%
\ No newline at end of file
diff --git a/test/log/mesher.log b/test/log/mesher.log
deleted file mode 100755
index b10fb48..0000000
--- a/test/log/mesher.log
+++ /dev/null
Binary files differ