You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ti...@apache.org on 2020/12/31 06:57:58 UTC
[servicecomb-service-center] branch master updated: [SCD-2133] add
new display data interface (#787)
This is an automated email from the ASF dual-hosted git repository.
tianxiaoliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-service-center.git
The following commit(s) were added to refs/heads/master by this push:
new e1239d1 [SCD-2133] add new display data interface (#787)
e1239d1 is described below
commit e1239d18cb22e22e7bd8865f81e27209fc6360d9
Author: GuoYL <53...@users.noreply.github.com>
AuthorDate: Thu Dec 31 14:57:48 2020 +0800
[SCD-2133] add new display data interface (#787)
* [SCD-2133] add new display data interface
* [SCD-2133] validate change / return 400 when error
* [SCD-2133] modify governance create return type
* [SCD-2133] add ut
* [SCD-2133] add all env
* [SCD-2133] modify ut
---
pkg/gov/governance.go | 7 ++
server/resource/v1/gov_resource.go | 47 ++++++--
server/service/gov/config_distributor.go | 26 +++--
server/service/gov/config_distributor_test.go | 71 +++++++++++-
server/service/gov/kie/kie_distributor.go | 159 ++++++++++++++++++--------
server/service/gov/kie/validate.go | 21 ++--
server/service/gov/mock/mock.go | 67 +++++++++--
7 files changed, 312 insertions(+), 86 deletions(-)
diff --git a/pkg/gov/governance.go b/pkg/gov/governance.go
index d2eb4a0..dd8682a 100644
--- a/pkg/gov/governance.go
+++ b/pkg/gov/governance.go
@@ -30,9 +30,16 @@ type GovernancePolicy struct {
Selector Selector `json:"selector,omitempty"`
}
+//DisplayData define display data
+type DisplayData struct {
+ Policies []*Policy `json:"policies,omitempty"`
+ MatchGroup *Policy `json:"matchGroup,omitempty"`
+}
+
//Policy define policy and fault tolerant policy
type Policy struct {
*GovernancePolicy
+ Kind string `json:"kind,omitempty"`
Spec interface{} `json:"spec,omitempty"`
}
diff --git a/server/resource/v1/gov_resource.go b/server/resource/v1/gov_resource.go
index 16694e0..81f1579 100644
--- a/server/resource/v1/gov_resource.go
+++ b/server/resource/v1/gov_resource.go
@@ -37,6 +37,7 @@ const (
KindKey = ":kind"
ProjectKey = ":project"
IDKey = ":id"
+ DisplayKey = "display"
)
//Create gov config
@@ -49,9 +50,18 @@ func (t *Governance) Create(w http.ResponseWriter, req *http.Request) {
controller.WriteError(w, discovery.ErrInternal, err.Error())
return
}
- err = gov.Create(kind, project, body)
+ id, err := gov.Create(kind, project, body)
+ //todo: 错误处理抽函数
if err != nil {
log.Error("create gov err", err)
+ w.WriteHeader(http.StatusBadRequest)
+ controller.WriteError(w, discovery.ErrInternal, err.Error())
+ return
+ }
+ _, err = w.Write(id)
+ if err != nil {
+ w.WriteHeader(http.StatusBadRequest)
+ log.Error("", err)
controller.WriteError(w, discovery.ErrInternal, err.Error())
return
}
@@ -71,28 +81,39 @@ func (t *Governance) Put(w http.ResponseWriter, req *http.Request) {
}
err = gov.Update(id, kind, project, body)
if err != nil {
- log.Error("create gov err", err)
+ log.Error("put gov err", err)
+ w.WriteHeader(http.StatusBadRequest)
controller.WriteError(w, discovery.ErrInternal, err.Error())
return
}
w.WriteHeader(http.StatusOK)
}
-//List return all gov config
-func (t *Governance) List(w http.ResponseWriter, req *http.Request) {
+//ListOrDisPlay return all gov config
+func (t *Governance) ListOrDisPlay(w http.ResponseWriter, req *http.Request) {
kind := req.URL.Query().Get(KindKey)
project := req.URL.Query().Get(ProjectKey)
app := req.URL.Query().Get(AppKey)
environment := req.URL.Query().Get(EnvironmentKey)
- body, err := gov.List(kind, project, app, environment)
+ var body []byte
+ var err error
+ if kind == DisplayKey {
+ body, err = gov.Display(project, app, environment)
+ } else {
+ body, err = gov.List(kind, project, app, environment)
+ }
if err != nil {
- log.Error("create gov err", err)
+ log.Error("list gov err", err)
+ w.WriteHeader(http.StatusBadRequest)
controller.WriteError(w, discovery.ErrInternal, err.Error())
return
}
_, err = w.Write(body)
if err != nil {
+ w.WriteHeader(http.StatusBadRequest)
log.Error("", err)
+ controller.WriteError(w, discovery.ErrInternal, err.Error())
+ return
}
w.WriteHeader(http.StatusOK)
w.Header().Set(rest.HeaderContentType, rest.ContentTypeJSON)
@@ -100,17 +121,22 @@ func (t *Governance) List(w http.ResponseWriter, req *http.Request) {
//Get gov config
func (t *Governance) Get(w http.ResponseWriter, req *http.Request) {
+ kind := req.URL.Query().Get(KindKey)
id := req.URL.Query().Get(IDKey)
project := req.URL.Query().Get(ProjectKey)
- body, err := gov.Get(id, project)
+ body, err := gov.Get(kind, id, project)
if err != nil {
- log.Error("create gov err", err)
+ w.WriteHeader(http.StatusBadRequest)
+ log.Error("get gov err", err)
controller.WriteError(w, discovery.ErrInternal, err.Error())
return
}
_, err = w.Write(body)
if err != nil {
+ w.WriteHeader(http.StatusBadRequest)
log.Error("", err)
+ controller.WriteError(w, discovery.ErrInternal, err.Error())
+ return
}
w.WriteHeader(http.StatusOK)
w.Header().Set(rest.HeaderContentType, rest.ContentTypeJSON)
@@ -122,7 +148,8 @@ func (t *Governance) Delete(w http.ResponseWriter, req *http.Request) {
project := req.URL.Query().Get(ProjectKey)
err := gov.Delete(id, project)
if err != nil {
- log.Error("create gov err", err)
+ w.WriteHeader(http.StatusBadRequest)
+ log.Error("delete gov err", err)
controller.WriteError(w, discovery.ErrInternal, err.Error())
return
}
@@ -135,7 +162,7 @@ func (t *Governance) URLPatterns() []rest.Route {
//servicecomb.rateLimiter.{name}
//....
{Method: http.MethodPost, Path: "/v1/:project/gov/" + KindKey, Func: t.Create},
- {Method: http.MethodGet, Path: "/v1/:project/gov/" + KindKey, Func: t.List},
+ {Method: http.MethodGet, Path: "/v1/:project/gov/" + KindKey, Func: t.ListOrDisPlay},
{Method: http.MethodGet, Path: "/v1/:project/gov/" + KindKey + "/" + IDKey, Func: t.Get},
{Method: http.MethodPut, Path: "/v1/:project/gov/" + KindKey + "/" + IDKey, Func: t.Put},
{Method: http.MethodDelete, Path: "/v1/:project/gov/" + KindKey + "/" + IDKey, Func: t.Delete},
diff --git a/server/service/gov/config_distributor.go b/server/service/gov/config_distributor.go
index c1c4224..45d4c7e 100644
--- a/server/service/gov/config_distributor.go
+++ b/server/service/gov/config_distributor.go
@@ -38,11 +38,12 @@ var distributorPlugins = map[string]NewDistributors{}
//or service mesh system like istio, linkerd.
//ConfigDistributor will convert standard servicecomb gov config to concrete spec, that data plane can recognize.
type ConfigDistributor interface {
- Create(kind, project string, spec []byte) error
+ Create(kind, project string, spec []byte) ([]byte, error)
Update(id, kind, project string, spec []byte) error
Delete(id, project string) error
+ Display(project, app, env string) ([]byte, error)
List(kind, project, app, env string) ([]byte, error)
- Get(id, project string) ([]byte, error)
+ Get(kind, id, project string) ([]byte, error)
Type() string
Name() string
}
@@ -74,15 +75,11 @@ func Init() error {
return nil
}
-func Create(kind, project string, spec []byte) error {
- var err error
+func Create(kind, project string, spec []byte) ([]byte, error) {
for _, cd := range distributors {
- err = cd.Create(kind, project, spec)
- if err != nil {
- return err
- }
+ return cd.Create(kind, project, spec)
}
- return nil
+ return nil, nil
}
func List(kind, project, app, env string) ([]byte, error) {
@@ -92,9 +89,16 @@ func List(kind, project, app, env string) ([]byte, error) {
return nil, nil
}
-func Get(id, project string) ([]byte, error) {
+func Display(project, app, env string) ([]byte, error) {
+ for _, cd := range distributors {
+ return cd.Display(project, app, env)
+ }
+ return nil, nil
+}
+
+func Get(kind, id, project string) ([]byte, error) {
for _, cd := range distributors {
- return cd.Get(id, project)
+ return cd.Get(kind, id, project)
}
return nil, nil
}
diff --git a/server/service/gov/config_distributor_test.go b/server/service/gov/config_distributor_test.go
index fbb0d73..a5a38df 100644
--- a/server/service/gov/config_distributor_test.go
+++ b/server/service/gov/config_distributor_test.go
@@ -28,7 +28,15 @@ import (
"github.com/stretchr/testify/assert"
)
-func TestCreate(t *testing.T) {
+const Project = "default"
+const MockKind = "default"
+const MatchGroup = "match-group"
+const MockEnv = ""
+const MockApp = ""
+
+var id = ""
+
+func init() {
config.Configurations = &config.Config{
Gov: &config.Gov{
DistOptions: []config.DistributorOptions{
@@ -40,13 +48,72 @@ func TestCreate(t *testing.T) {
},
}
err := svc.Init()
+ if err != nil {
+ panic(err)
+ }
+}
+
+func TestCreate(t *testing.T) {
+ b, _ := json.MarshalIndent(&gov.Policy{
+ GovernancePolicy: &gov.GovernancePolicy{
+ Name: "Traffic2adminAPI",
+ },
+ Spec: &gov.LBSpec{RetryNext: 3, MarkerName: "traffic2adminAPI"},
+ }, "", " ")
+ res, err := svc.Create(MockKind, Project, b)
+ id = string(res)
assert.NoError(t, err)
+}
+
+func TestUpdate(t *testing.T) {
b, _ := json.MarshalIndent(&gov.Policy{
GovernancePolicy: &gov.GovernancePolicy{
Name: "Traffic2adminAPI",
},
Spec: &gov.LBSpec{RetryNext: 3, MarkerName: "traffic2adminAPI"},
}, "", " ")
- err = svc.Create("lb", "default", b)
+ err := svc.Update(id, MockKind, Project, b)
+ assert.NoError(t, err)
+}
+
+func TestDisplay(t *testing.T) {
+ b, _ := json.MarshalIndent(&gov.Policy{
+ GovernancePolicy: &gov.GovernancePolicy{
+ Name: "Traffic2adminAPI",
+ },
+ }, "", " ")
+ res, err := svc.Create(MatchGroup, Project, b)
+ id = string(res)
+ assert.NoError(t, err)
+ policies := &[]*gov.DisplayData{}
+ res, err = svc.Display(Project, MockApp, MockEnv)
+ assert.NoError(t, err)
+ err = json.Unmarshal(res, policies)
+ assert.NoError(t, err)
+ assert.NotEmpty(t, policies)
+}
+
+func TestList(t *testing.T) {
+ policies := &[]*gov.Policy{}
+ res, err := svc.List(MockKind, Project, MockApp, MockEnv)
+ assert.NoError(t, err)
+ err = json.Unmarshal(res, policies)
+ assert.NoError(t, err)
+ assert.NotEmpty(t, policies)
+}
+
+func TestGet(t *testing.T) {
+ policy := &gov.Policy{}
+ res, err := svc.Get(MockKind, id, Project)
+ assert.NoError(t, err)
+ err = json.Unmarshal(res, policy)
+ assert.NoError(t, err)
+ assert.NotNil(t, policy)
+}
+
+func TestDelete(t *testing.T) {
+ err := svc.Delete(id, Project)
assert.NoError(t, err)
+ res, _ := svc.Get(MockKind, id, Project)
+ assert.Nil(t, res)
}
diff --git a/server/service/gov/kie/kie_distributor.go b/server/service/gov/kie/kie_distributor.go
index df43e31..0fc5bd0 100644
--- a/server/service/gov/kie/kie_distributor.go
+++ b/server/service/gov/kie/kie_distributor.go
@@ -5,9 +5,10 @@ import (
"context"
"encoding/json"
"fmt"
- "log"
"strings"
+ "github.com/apache/servicecomb-service-center/pkg/log"
+
"github.com/apache/servicecomb-service-center/pkg/gov"
"github.com/apache/servicecomb-service-center/server/config"
svc "github.com/apache/servicecomb-service-center/server/service/gov"
@@ -23,29 +24,33 @@ type Distributor struct {
const (
PREFIX = "servicecomb."
+ MatchGroup = "match-group"
EnableStatus = "enabled"
ValueType = "text"
AppKey = "app"
EnvironmentKey = "environment"
+ EnvAll = "all"
)
+var PolicyNames = []string{"retry", "rateLimiting", "circuitBreaker", "bulkhead"}
+
var rule = Validator{}
-func (d *Distributor) Create(kind, project string, spec []byte) error {
+func (d *Distributor) Create(kind, project string, spec []byte) ([]byte, error) {
p := &gov.Policy{}
err := json.Unmarshal(spec, p)
if err != nil {
- return err
+ return nil, err
}
- log.Println(fmt.Sprintf("create %v", &p))
+ log.Info(fmt.Sprintf("create %v", &p))
key := toSnake(kind) + "." + p.Name
err = rule.Validate(kind, p.Spec)
if err != nil {
- return err
+ return nil, err
}
yamlByte, err := yaml.Marshal(p.Spec)
if err != nil {
- return err
+ return nil, err
}
kv := kie.KVRequest{
Key: PREFIX + key,
@@ -54,13 +59,14 @@ func (d *Distributor) Create(kind, project string, spec []byte) error {
ValueType: ValueType,
Labels: map[string]string{AppKey: p.Selector.App, EnvironmentKey: p.Selector.Environment},
}
- _, err = d.client.Create(context.TODO(), kv, kie.WithProject(project))
+ res, err := d.client.Create(context.TODO(), kv, kie.WithProject(project))
if err != nil {
- log.Fatal("kie create failed", err)
- return err
+ log.Error("kie create failed", err)
+ return nil, err
}
d.lbPolicies[p.GovernancePolicy.Name] = p
- return nil
+ b, _ := json.MarshalIndent(res.ID, "", " ")
+ return b, nil
}
func (d *Distributor) Update(id, kind, project string, spec []byte) error {
@@ -69,7 +75,7 @@ func (d *Distributor) Update(id, kind, project string, spec []byte) error {
if err != nil {
return err
}
- log.Println(fmt.Sprintf("update %v", &p))
+ log.Info(fmt.Sprintf("update %v", &p))
err = rule.Validate(kind, p.Spec)
if err != nil {
return err
@@ -85,7 +91,7 @@ func (d *Distributor) Update(id, kind, project string, spec []byte) error {
}
_, err = d.client.Put(context.TODO(), kv, kie.WithProject(project))
if err != nil {
- log.Fatal("kie update failed", err)
+ log.Error("kie update failed", err)
return err
}
d.lbPolicies[p.GovernancePolicy.Name] = p
@@ -95,65 +101,80 @@ func (d *Distributor) Update(id, kind, project string, spec []byte) error {
func (d *Distributor) Delete(id, project string) error {
err := d.client.Delete(context.TODO(), id, kie.WithProject(project))
if err != nil {
- log.Fatal("kie delete failed", err)
+ log.Error("kie delete failed", err)
return err
}
return nil
}
+func (d *Distributor) Display(project, app, env string) ([]byte, error) {
+ list, _, err := d.listDataByKind(MatchGroup, project, app, env)
+ if err != nil {
+ return nil, err
+ }
+ policyMap := make(map[string]*gov.Policy)
+ for _, kind := range PolicyNames {
+ policies, _, err := d.listDataByKind(kind, project, app, env)
+ if err != nil {
+ continue
+ }
+ for _, policy := range policies.Data {
+ item, err := d.transform(policy, kind)
+ if err != nil {
+ continue
+ }
+ policyMap[item.Name+kind] = item
+ }
+ }
+ r := make([]*gov.DisplayData, 0, list.Total)
+ for _, item := range list.Data {
+ match, err := d.transform(item, MatchGroup)
+ if err != nil {
+ return nil, err
+ }
+ var policies []*gov.Policy
+ for _, kind := range PolicyNames {
+ if policyMap[match.Name+kind] != nil {
+ policies = append(policies, policyMap[match.Name+kind])
+ }
+ }
+ result := &gov.DisplayData{
+ Policies: policies,
+ MatchGroup: match,
+ }
+ r = append(r, result)
+ }
+ b, _ := json.MarshalIndent(r, "", " ")
+ return b, nil
+}
+
func (d *Distributor) List(kind, project, app, env string) ([]byte, error) {
- list, _, err := d.client.List(context.TODO(),
- kie.WithKey("beginWith("+PREFIX+toSnake(kind)+")"),
- kie.WithLabels(map[string]string{AppKey: app, EnvironmentKey: env}),
- kie.WithRevision(0),
- kie.WithGetProject(project))
+ list, _, err := d.listDataByKind(kind, project, app, env)
if err != nil {
return nil, err
}
r := make([]*gov.Policy, 0, list.Total)
for _, item := range list.Data {
- goc := &gov.Policy{
- GovernancePolicy: &gov.GovernancePolicy{},
- }
- spec := make(map[string]interface{})
- specJSON, _ := yaml.YAMLToJSON([]byte(item.Value))
- err = json.Unmarshal(specJSON, &spec)
+ policy, err := d.transform(item, kind)
if err != nil {
- log.Fatal("kie list failed", err)
return nil, err
}
- goc.ID = item.ID
- goc.Status = item.Status
- goc.Name = item.Key
- goc.Spec = spec
- goc.Selector.App = item.Labels[AppKey]
- goc.Selector.Environment = item.Labels[EnvironmentKey]
- goc.CreatTime = item.CreatTime
- goc.UpdateTime = item.UpdateTime
- r = append(r, goc)
+ r = append(r, policy)
}
b, _ := json.MarshalIndent(r, "", " ")
return b, nil
}
-func (d *Distributor) Get(id, project string) ([]byte, error) {
+func (d *Distributor) Get(kind, id, project string) ([]byte, error) {
kv, err := d.client.Get(context.TODO(), id, kie.WithGetProject(project))
if err != nil {
- log.Fatal("kie get failed", err)
return nil, err
}
- goc := &gov.Policy{
- GovernancePolicy: &gov.GovernancePolicy{},
+ policy, err := d.transform(kv, kind)
+ if err != nil {
+ return nil, err
}
- goc.ID = kv.ID
- goc.Status = kv.Status
- goc.Name = kv.Key
- goc.Spec = kv
- goc.Selector.App = kv.Labels[AppKey]
- goc.Selector.Environment = kv.Labels[EnvironmentKey]
- goc.CreatTime = kv.CreatTime
- goc.UpdateTime = kv.UpdateTime
- b, _ := json.MarshalIndent(goc, "", " ")
+ b, _ := json.MarshalIndent(policy, "", " ")
return b, nil
}
@@ -170,7 +191,7 @@ func initClient(endpoint string) *kie.Client {
DefaultLabels: map[string]string{},
})
if err != nil {
- log.Fatalf("init kie client failed, err: %s", err)
+ log.Fatal("init kie client failed, err: %s", err)
}
return client
}
@@ -201,6 +222,48 @@ func toSnake(name string) string {
return buffer.String()
}
+func (d *Distributor) listDataByKind(kind, project, app, env string) (*kie.KVResponse, int, error) {
+ ops := []kie.GetOption{
+ kie.WithKey("beginWith(" + PREFIX + toSnake(kind) + ")"),
+ kie.WithRevision(0),
+ kie.WithGetProject(project),
+ }
+ labels := map[string]string{}
+ if env != EnvAll {
+ labels[EnvironmentKey] = env
+ }
+ if app != "" {
+ labels[AppKey] = app
+ }
+ if len(labels) > 0 {
+ ops = append(ops, kie.WithLabels(labels))
+ }
+ return d.client.List(context.TODO(), ops...)
+}
+
+func (d *Distributor) transform(kv *kie.KVDoc, kind string) (*gov.Policy, error) {
+ goc := &gov.Policy{
+ GovernancePolicy: &gov.GovernancePolicy{},
+ }
+ spec := make(map[string]interface{})
+ specJSON, _ := yaml.YAMLToJSON([]byte(kv.Value))
+ err := json.Unmarshal(specJSON, &spec)
+ if err != nil {
+ log.Fatal("kie transform kv failed", err)
+ return nil, err
+ }
+ goc.Kind = kind
+ goc.ID = kv.ID
+ goc.Status = kv.Status
+ goc.Name = kv.Key[strings.LastIndex(kv.Key, ".")+1 : len(kv.Key)]
+ goc.Spec = spec
+ goc.Selector.App = kv.Labels[AppKey]
+ goc.Selector.Environment = kv.Labels[EnvironmentKey]
+ goc.CreatTime = kv.CreatTime
+ goc.UpdateTime = kv.UpdateTime
+ return goc, nil
+}
+
func init() {
svc.InstallDistributor(svc.ConfigDistributorKie, new)
}
diff --git a/server/service/gov/kie/validate.go b/server/service/gov/kie/validate.go
index fb9f0b4..bafe794 100644
--- a/server/service/gov/kie/validate.go
+++ b/server/service/gov/kie/validate.go
@@ -15,9 +15,9 @@ func (d *Validator) Validate(kind string, spec interface{}) error {
return matchValidate(spec)
case "retry":
return retryValidate(spec)
- case "rateLimiting":
+ case "rate-limiting":
return rateLimitingValidate(spec)
- case "circuitBreaker":
+ case "circuit-breaker":
case "bulkhead":
case "loadbalancer":
return nil
@@ -32,6 +32,9 @@ func matchValidate(val interface{}) error {
if !ok {
return fmt.Errorf("illegal item : %v", val)
}
+ if spec["matches"] == nil {
+ return nil
+ }
matches, ok := spec["matches"].([]interface{})
if !ok {
return fmt.Errorf("illegal item : %v", spec)
@@ -88,12 +91,14 @@ func policyValidate(val interface{}) error {
if !ok {
return fmt.Errorf("illegal item : %v", val)
}
- rules, ok := spec["rules"].(map[string]interface{})
- if !ok {
- return fmt.Errorf("illegal item : %v", spec)
- }
- if "" == rules["match"] {
- return fmt.Errorf("policy's match can not be nil: %v", spec)
+ if spec["rules"] != nil {
+ rules, ok := spec["rules"].(map[string]interface{})
+ if !ok {
+ return fmt.Errorf("illegal item : %v", spec)
+ }
+ if "" == rules["match"] {
+ return fmt.Errorf("policy's match can not be nil: %v", spec)
+ }
}
return nil
}
diff --git a/server/service/gov/mock/mock.go b/server/service/gov/mock/mock.go
index cc6359c..0ee948f 100644
--- a/server/service/gov/mock/mock.go
+++ b/server/service/gov/mock/mock.go
@@ -22,6 +22,8 @@ import (
"fmt"
"log"
+ uuid "github.com/satori/go.uuid"
+
"github.com/apache/servicecomb-service-center/pkg/gov"
"github.com/apache/servicecomb-service-center/server/config"
svc "github.com/apache/servicecomb-service-center/server/service/gov"
@@ -32,36 +34,87 @@ type Distributor struct {
name string
}
-func (d *Distributor) Create(kind, project string, spec []byte) error {
+const MatchGroup = "match-group"
+
+var PolicyNames = []string{"retry", "rateLimiting", "circuitBreaker", "bulkhead"}
+
+func (d *Distributor) Create(kind, project string, spec []byte) ([]byte, error) {
p := &gov.Policy{}
err := json.Unmarshal(spec, p)
+ p.ID = uuid.NewV4().String()
+ p.Kind = kind
log.Println(fmt.Sprintf("create %v", &p))
- d.lbPolicies[p.GovernancePolicy.Name] = p
- return err
+ d.lbPolicies[p.GovernancePolicy.ID] = p
+ return []byte(p.ID), err
}
+
func (d *Distributor) Update(id, kind, project string, spec []byte) error {
+ if d.lbPolicies[id] == nil {
+ return fmt.Errorf("id not exsit")
+ }
p := &gov.Policy{}
err := json.Unmarshal(spec, p)
+ p.ID = id
+ p.Kind = kind
log.Println("update ", p)
- d.lbPolicies[p.GovernancePolicy.Name] = p
+ d.lbPolicies[p.GovernancePolicy.ID] = p
return err
}
+
func (d *Distributor) Delete(id, project string) error {
delete(d.lbPolicies, id)
return nil
}
+
+func (d *Distributor) Display(project, app, env string) ([]byte, error) {
+ list := make([]*gov.Policy, 0)
+ for _, g := range d.lbPolicies {
+ if g.Kind == MatchGroup && g.Selector.App == app && g.Selector.Environment == env {
+ list = append(list, g)
+ }
+ }
+ policyMap := make(map[string]*gov.Policy)
+ for _, g := range d.lbPolicies {
+ for _, kind := range PolicyNames {
+ if g.Kind == kind && g.Selector.App == app && g.Selector.Environment == env {
+ policyMap[g.Name+kind] = g
+ }
+ }
+ }
+ r := make([]*gov.DisplayData, 0, len(list))
+ for _, g := range list {
+ policies := make([]*gov.Policy, 0)
+ for _, kind := range PolicyNames {
+ policies = append(policies, policyMap[g.Name+kind])
+ }
+ r = append(r, &gov.DisplayData{
+ MatchGroup: g,
+ Policies: policies,
+ })
+ }
+ b, _ := json.MarshalIndent(r, "", " ")
+ return b, nil
+}
func (d *Distributor) List(kind, project, app, env string) ([]byte, error) {
r := make([]*gov.Policy, 0, len(d.lbPolicies))
for _, g := range d.lbPolicies {
- r = append(r, g)
+ if g.Kind == kind && g.Selector.App == app && g.Selector.Environment == env {
+ r = append(r, g)
+ }
}
b, _ := json.MarshalIndent(r, "", " ")
return b, nil
}
-func (d *Distributor) Get(id, project string) ([]byte, error) {
- return nil, nil
+func (d *Distributor) Get(kind, id, project string) ([]byte, error) {
+ r := d.lbPolicies[id]
+ if r == nil {
+ return nil, nil
+ }
+ b, _ := json.MarshalIndent(r, "", " ")
+ return b, nil
}
+
func (d *Distributor) Type() string {
return svc.ConfigDistributorMock
}