server/service/grc/config_distributor.go (98 lines of code) (raw):

/* * 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 grc import ( "context" "errors" model "github.com/apache/servicecomb-service-center/pkg/gov" "github.com/apache/servicecomb-service-center/pkg/log" "github.com/apache/servicecomb-service-center/pkg/util" "github.com/apache/servicecomb-service-center/server/config" ) const ( ConfigDistributorKie = "kie" ConfigDistributorIstio = "istio" ConfigDistributorMock = "mock" ) var ErrNoConfig = errors.New("no gov config") type NewDistributors func(opts config.DistributorOptions) (ConfigDistributor, error) var distributors = map[string]ConfigDistributor{} var distributorPlugins = map[string]NewDistributors{} // ConfigDistributor persist and distribute Governance policy // typically, a ConfigDistributor interact with a config server, like ctrip apollo, kie. // 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(ctx context.Context, kind, project string, policy *model.Policy) ([]byte, error) Update(ctx context.Context, kind, id, project string, p *model.Policy) error Delete(ctx context.Context, kind, id, project string) error Display(ctx context.Context, project, app, env string) ([]byte, error) List(ctx context.Context, kind, project, app, env string) ([]byte, error) Get(ctx context.Context, kind, id, project string) ([]byte, error) Type() string Name() string } // InstallDistributor install a plugin to distribute and persist config func InstallDistributor(t string, newDistributors NewDistributors) { distributorPlugins[t] = newDistributors } // Init create distributors according to gov config. // it may creates multiple distributors and distribute policy one by one, // the policy config loaded from grc.json file. func Init() error { if config.GetGov() == nil { return ErrNoConfig } for name, opts := range config.GetGov().DistMap { opts.Name = name f, ok := distributorPlugins[name] if !ok { log.Warn("unsupported plugin " + opts.Type) continue } cd, err := f(opts) if err != nil { log.Error("can not init config distributor", err) return err } distributors[name+"::"+opts.Type] = cd } if config.GetGov().MatchGroup != nil { RegisterPolicySchema(KindMatchGroup, config.GetGov().MatchGroup.ValidationSpec) } if config.GetGov().Policies != nil { var names []string for kind, policy := range config.GetGov().Policies { RegisterPolicySchema(kind, policy.ValidationSpec) names = append(names, util.ToSnake(kind)) } PolicyNames = names } return nil } func Create(ctx context.Context, kind, project string, spec *model.Policy) ([]byte, error) { for _, cd := range distributors { return cd.Create(ctx, kind, project, spec) } return nil, nil } func List(ctx context.Context, kind, project, app, env string) ([]byte, error) { for _, cd := range distributors { return cd.List(ctx, kind, project, app, env) } return nil, nil } func Display(ctx context.Context, project, app, env string) ([]byte, error) { for _, cd := range distributors { return cd.Display(ctx, project, app, env) } return nil, nil } func Get(ctx context.Context, kind, id, project string) ([]byte, error) { for _, cd := range distributors { return cd.Get(ctx, kind, id, project) } return nil, nil } func Delete(ctx context.Context, kind, id, project string) error { for _, cd := range distributors { return cd.Delete(ctx, kind, id, project) } return nil } func Update(ctx context.Context, kind, id, project string, p *model.Policy) error { for _, cd := range distributors { return cd.Update(ctx, kind, id, project, p) } return nil }