blob: 9a77b32aa1fc9ef38e80f91056e72da25f9e2e40 [file] [log] [blame]
/*
* 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 gov
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
model "github.com/apache/servicecomb-service-center/pkg/gov"
"github.com/apache/servicecomb-service-center/pkg/log"
"github.com/apache/servicecomb-service-center/pkg/rest"
"github.com/apache/servicecomb-service-center/server/service/gov"
"github.com/apache/servicecomb-service-center/server/service/gov/kie"
"github.com/go-chassis/cari/discovery"
)
type Governance struct {
}
const (
AppKey = "app"
EnvironmentKey = "environment"
KindKey = ":kind"
ProjectKey = ":project"
IDKey = ":id"
DisplayKey = "display"
)
//Create gov config
func (t *Governance) Create(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
kind := query.Get(KindKey)
project := query.Get(ProjectKey)
body, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Error("read body err", err)
rest.WriteError(w, discovery.ErrInternal, err.Error())
return
}
p := &model.Policy{
GovernancePolicy: &model.GovernancePolicy{Selector: model.Selector{}},
}
err = json.Unmarshal(body, p)
if err != nil {
log.Error("json err", err)
rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
return
}
err = gov.ValidateSpec(kind, p.Spec)
if err != nil {
log.Error("validate policy err", err)
rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
return
}
id, err := gov.Create(r.Context(), kind, project, p)
if err != nil {
if _, ok := err.(*kie.ErrIllegalItem); ok {
log.Error("", err)
rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
return
}
processError(w, err, "create gov data err")
return
}
log.Info(fmt.Sprintf("created %+v", p))
rest.WriteResponse(w, r, nil, &model.Policy{GovernancePolicy: &model.GovernancePolicy{ID: string(id)}})
}
//Put gov config
func (t *Governance) Put(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
kind := query.Get(KindKey)
id := query.Get(IDKey)
project := query.Get(ProjectKey)
body, err := ioutil.ReadAll(r.Body)
if err != nil {
processError(w, err, "read body err")
return
}
p := &model.Policy{}
err = json.Unmarshal(body, p)
if err != nil {
log.Error("json err", err)
rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
return
}
err = gov.ValidateSpec(kind, p.Spec)
if err != nil {
log.Error("validate policy err", err)
rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
return
}
log.Info(fmt.Sprintf("update %v", &p))
err = gov.Update(r.Context(), kind, id, project, p)
if err != nil {
if _, ok := err.(*kie.ErrIllegalItem); ok {
log.Error("", err)
rest.WriteError(w, discovery.ErrInvalidParams, err.Error())
return
}
processError(w, err, "put gov err")
return
}
rest.WriteResponse(w, r, nil, nil)
}
//ListOrDisPlay return all gov config
func (t *Governance) ListOrDisPlay(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
kind := query.Get(KindKey)
project := query.Get(ProjectKey)
app := query.Get(AppKey)
environment := query.Get(EnvironmentKey)
var body []byte
var err error
if kind == DisplayKey {
body, err = gov.Display(r.Context(), project, app, environment)
} else {
body, err = gov.List(r.Context(), kind, project, app, environment)
}
if err != nil {
processError(w, err, "list gov err")
return
}
rest.WriteResponse(w, r, nil, body)
}
//Get gov config
func (t *Governance) Get(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
kind := query.Get(KindKey)
id := query.Get(IDKey)
project := query.Get(ProjectKey)
body, err := gov.Get(r.Context(), kind, id, project)
if err != nil {
processError(w, err, "get gov err")
return
}
rest.WriteResponse(w, r, nil, body)
}
//Delete delete gov config
func (t *Governance) Delete(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
kind := query.Get(KindKey)
id := query.Get(IDKey)
project := query.Get(ProjectKey)
err := gov.Delete(r.Context(), kind, id, project)
if err != nil {
processError(w, err, "delete gov err")
return
}
rest.WriteResponse(w, r, nil, nil)
}
func processError(w http.ResponseWriter, err error, msg string) {
log.Error(msg, err)
rest.WriteServiceError(w, err)
}
func (t *Governance) URLPatterns() []rest.Route {
return []rest.Route{
//servicecomb.marker.{name}
//servicecomb.rateLimiter.{name}
//....
{Method: http.MethodPost, Path: "/v1/:project/gov/" + KindKey, Func: t.Create},
{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},
}
}