From 3e360f79693a61bcd89ef512dc1a595a754d65d2 Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Sat, 26 Sep 2020 23:21:15 +0200 Subject: [PATCH 01/16] refactoring to common adapter library Signed-off-by: Michael Gfeller --- consul/client.go | 197 ++++---- consul/consul.go | 597 ------------------------ consul/consul2.go | 17 + consul/consul_orig.go | 597 ++++++++++++++++++++++++ consul/install.go | 34 ++ consul/operations.go | 56 +++ consul/supported_ops.go | 91 ++-- go.mod | 29 +- go.sum | 565 +++++++++++++++++++++-- internal/config/config.go | 13 + internal/config/defaults.go | 22 + internal/config/keys.go | 9 + internal/config/viper.go | 69 +++ main.go | 67 ++- meshes/meshops.pb.go | 872 ------------------------------------ 15 files changed, 1525 insertions(+), 1710 deletions(-) delete mode 100644 consul/consul.go create mode 100644 consul/consul2.go create mode 100644 consul/consul_orig.go create mode 100644 consul/install.go create mode 100644 consul/operations.go create mode 100644 internal/config/config.go create mode 100644 internal/config/defaults.go create mode 100644 internal/config/keys.go create mode 100644 internal/config/viper.go delete mode 100644 meshes/meshops.pb.go diff --git a/consul/client.go b/consul/client.go index aec6e117..ab04dcf5 100644 --- a/consul/client.go +++ b/consul/client.go @@ -15,101 +15,102 @@ //Package consul ... package consul -import ( - "github.com/ghodss/yaml" - "github.com/layer5io/meshery-consul/meshes" - "github.com/sirupsen/logrus" - "k8s.io/client-go/dynamic" - "k8s.io/client-go/kubernetes" - - // auth is needed for initialization only - _ "k8s.io/client-go/plugin/pkg/client/auth" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" -) - -// Client represents an consul client in Meshery -type Client struct { - config *rest.Config - k8sClientset *kubernetes.Clientset - k8sDynamicClient dynamic.Interface - - eventChan chan *meshes.EventsResponse -} - -func configClient(kubeconfig []byte, contextName string) (*rest.Config, error) { - if len(kubeconfig) > 0 { - ccfg, err := clientcmd.Load(kubeconfig) - if err != nil { - return nil, err - } - if contextName != "" { - ccfg.CurrentContext = contextName - } - - return clientcmd.NewDefaultClientConfig(*ccfg, &clientcmd.ConfigOverrides{}).ClientConfig() - } - return rest.InClusterConfig() -} - -func newClient(kubeconfig []byte, contextName string) (*Client, error) { - kubeconfig = monkeyPatchingToSupportInsecureConn(kubeconfig) - client := Client{} - config, err := configClient(kubeconfig, contextName) - if err != nil { - return nil, err - } - config.QPS = 100 - config.Burst = 200 - - dynamicClient, err := dynamic.NewForConfig(config) - if err != nil { - return nil, err - } - client.k8sDynamicClient = dynamicClient - - k8sClientset, err := kubernetes.NewForConfig(config) - if err != nil { - return nil, err - } - client.k8sClientset = k8sClientset - client.config = config - - return &client, nil -} - -func monkeyPatchingToSupportInsecureConn(data []byte) []byte { - config := map[string]interface{}{} - if err := yaml.Unmarshal(data, &config); err != nil { - logrus.Warn(err) - return data // we will skip this process - } - // logrus.Infof("unmarshalled config: %+#v", config) - clusters, ok := config["clusters"].([]interface{}) - if !ok { - logrus.Warn("unable to type cast clusters to a map array") - return data - } - for _, clusterI := range clusters { - cluster, ok := clusterI.(map[string]interface{}) - if !ok { - logrus.Warn("unable to type case individual cluster to a map") - continue - } - indCluster, ok := cluster["cluster"].(map[string]interface{}) - if !ok { - logrus.Warn("unable to type case clusters.cluster to a map") - continue - } - indCluster["insecure-skip-tls-verify"] = true // TODO: should we persist this back? - delete(indCluster, "certificate-authority-data") - delete(indCluster, "certificate-authority") - } - // logrus.Debugf("New config: %+#v", config) - data1, err := yaml.Marshal(config) - if err != nil { - logrus.Warn(err) - return data - } - return data1 -} +// +//import ( +// "github.com/ghodss/yaml" +// "github.com/layer5io/meshery-consul/meshes" +// "github.com/sirupsen/logrus" +// "k8s.io/client-go/dynamic" +// "k8s.io/client-go/kubernetes" +// +// // auth is needed for initialization only +// _ "k8s.io/client-go/plugin/pkg/client/auth" +// "k8s.io/client-go/rest" +// "k8s.io/client-go/tools/clientcmd" +//) +// +//// Client represents an consul client in Meshery +//type Client struct { +// config *rest.Config +// k8sClientset *kubernetes.Clientset +// k8sDynamicClient dynamic.Interface +// +// eventChan chan *meshes.EventsResponse +//} +// +//func configClient(kubeconfig []byte, contextName string) (*rest.Config, error) { +// if len(kubeconfig) > 0 { +// ccfg, err := clientcmd.Load(kubeconfig) +// if err != nil { +// return nil, err +// } +// if contextName != "" { +// ccfg.CurrentContext = contextName +// } +// +// return clientcmd.NewDefaultClientConfig(*ccfg, &clientcmd.ConfigOverrides{}).ClientConfig() +// } +// return rest.InClusterConfig() +//} +// +//func newClient(kubeconfig []byte, contextName string) (*Client, error) { +// kubeconfig = monkeyPatchingToSupportInsecureConn(kubeconfig) +// client := Client{} +// config, err := configClient(kubeconfig, contextName) +// if err != nil { +// return nil, err +// } +// config.QPS = 100 +// config.Burst = 200 +// +// dynamicClient, err := dynamic.NewForConfig(config) +// if err != nil { +// return nil, err +// } +// client.k8sDynamicClient = dynamicClient +// +// k8sClientset, err := kubernetes.NewForConfig(config) +// if err != nil { +// return nil, err +// } +// client.k8sClientset = k8sClientset +// client.config = config +// +// return &client, nil +//} +// +//func monkeyPatchingToSupportInsecureConn(data []byte) []byte { +// config := map[string]interface{}{} +// if err := yaml.Unmarshal(data, &config); err != nil { +// logrus.Warn(err) +// return data // we will skip this process +// } +// // logrus.Infof("unmarshalled config: %+#v", config) +// clusters, ok := config["clusters"].([]interface{}) +// if !ok { +// logrus.Warn("unable to type cast clusters to a map array") +// return data +// } +// for _, clusterI := range clusters { +// cluster, ok := clusterI.(map[string]interface{}) +// if !ok { +// logrus.Warn("unable to type case individual cluster to a map") +// continue +// } +// indCluster, ok := cluster["cluster"].(map[string]interface{}) +// if !ok { +// logrus.Warn("unable to type case clusters.cluster to a map") +// continue +// } +// indCluster["insecure-skip-tls-verify"] = true // TODO: should we persist this back? +// delete(indCluster, "certificate-authority-data") +// delete(indCluster, "certificate-authority") +// } +// // logrus.Debugf("New config: %+#v", config) +// data1, err := yaml.Marshal(config) +// if err != nil { +// logrus.Warn(err) +// return data +// } +// return data1 +//} diff --git a/consul/consul.go b/consul/consul.go deleted file mode 100644 index 222fc8da..00000000 --- a/consul/consul.go +++ /dev/null @@ -1,597 +0,0 @@ -// Copyright 2019 Layer5.io -// -// Licensed 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 consul ... -package consul - -import ( - "bytes" - "context" - "fmt" - "html/template" - "io" - "io/ioutil" - "path" - "time" - - "strings" - - "github.com/ghodss/yaml" - "github.com/layer5io/meshery-consul/meshes" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" -) - -//CreateMeshInstance instantiates a new instance of Consul in a Kubernetes cluster. -func (iClient *Client) CreateMeshInstance(_ context.Context, k8sReq *meshes.CreateMeshInstanceRequest) (*meshes.CreateMeshInstanceResponse, error) { - var k8sConfig []byte - contextName := "" - if k8sReq != nil { - k8sConfig = k8sReq.K8SConfig - contextName = k8sReq.ContextName - } - logrus.Debugf("received contextName: %s", contextName) - - ic, err := newClient(k8sConfig, contextName) - if err != nil { - err = errors.Wrapf(err, "unable to create a new istio client") - logrus.Error(err) - return nil, err - } - iClient.k8sClientset = ic.k8sClientset - iClient.k8sDynamicClient = ic.k8sDynamicClient - iClient.eventChan = make(chan *meshes.EventsResponse, 100) - iClient.config = ic.config - - return &meshes.CreateMeshInstanceResponse{}, nil -} - -// MeshName just returns the name of the mesh the client is representing -func (iClient *Client) MeshName(context.Context, *meshes.MeshNameRequest) (*meshes.MeshNameResponse, error) { - return &meshes.MeshNameResponse{Name: "Consul"}, nil -} - -func (iClient *Client) createResource(ctx context.Context, res schema.GroupVersionResource, data *unstructured.Unstructured) error { - _, err := iClient.k8sDynamicClient.Resource(res).Namespace(data.GetNamespace()).Create(data, metav1.CreateOptions{}) - if err != nil { - err = errors.Wrapf(err, "unable to create the requested resource, attempting operation without namespace") - logrus.Warn(err) - _, err = iClient.k8sDynamicClient.Resource(res).Create(data, metav1.CreateOptions{}) - if err != nil { - err = errors.Wrapf(err, "unable to create the requested resource, attempting to update") - logrus.Error(err) - return err - } - } - logrus.Infof("Created Resource of type: %s and name: %s", data.GetKind(), data.GetName()) - return nil -} - -func (iClient *Client) deleteResource(ctx context.Context, res schema.GroupVersionResource, data *unstructured.Unstructured) error { - if iClient.k8sDynamicClient == nil { - return errors.New("mesh client has not been created") - } - - if res.Resource == "namespaces" && data.GetName() == "default" { // skipping deletion of default namespace - return nil - } - - // in the case with deployments, have to scale it down to 0 first and then delete. . . or else RS and pods will be left behind - if res.Resource == "deployments" { - data1, err := iClient.getResource(ctx, res, data) - if err != nil { - return err - } - depl := data1.UnstructuredContent() - spec1 := depl["spec"].(map[string]interface{}) - spec1["replicas"] = 0 - data1.SetUnstructuredContent(depl) - if err = iClient.updateResource(ctx, res, data1); err != nil { - return err - } - } - - err := iClient.k8sDynamicClient.Resource(res).Namespace(data.GetNamespace()).Delete(data.GetName(), &metav1.DeleteOptions{}) - if err != nil { - err = errors.Wrapf(err, "unable to delete the requested resource, attempting operation without namespace") - logrus.Warn(err) - - err := iClient.k8sDynamicClient.Resource(res).Delete(data.GetName(), &metav1.DeleteOptions{}) - if err != nil { - err = errors.Wrapf(err, "unable to delete the requested resource") - logrus.Error(err) - return err - } - } - logrus.Infof("Deleted Resource of type: %s and name: %s", data.GetKind(), data.GetName()) - return nil -} - -func (iClient *Client) getResource(ctx context.Context, res schema.GroupVersionResource, data *unstructured.Unstructured) (*unstructured.Unstructured, error) { - data1, err := iClient.k8sDynamicClient.Resource(res).Namespace(data.GetNamespace()).Get(data.GetName(), metav1.GetOptions{}) - if err != nil { - err = errors.Wrap(err, "unable to retrieve the resource with a matching name, attempting operation without namespace") - logrus.Warn(err) - - data1, err = iClient.k8sDynamicClient.Resource(res).Get(data.GetName(), metav1.GetOptions{}) - if err != nil { - err = errors.Wrap(err, "unable to retrieve the resource with a matching name, while attempting to apply the config") - logrus.Error(err) - return nil, err - } - } - logrus.Infof("Retrieved Resource of type: %s and name: %s", data.GetKind(), data.GetName()) - return data1, nil -} - -func (iClient *Client) updateResource(ctx context.Context, res schema.GroupVersionResource, data *unstructured.Unstructured) error { - if _, err := iClient.k8sDynamicClient.Resource(res).Namespace(data.GetNamespace()).Update(data, metav1.UpdateOptions{}); err != nil { - err = errors.Wrap(err, "unable to update resource with the given name, attempting operation without namespace") - logrus.Warn(err) - - if _, err = iClient.k8sDynamicClient.Resource(res).Update(data, metav1.UpdateOptions{}); err != nil { - err = errors.Wrap(err, "unable to update resource with the given name, while attempting to apply the config") - logrus.Error(err) - return err - } - } - logrus.Infof("Updated Resource of type: %s and name: %s", data.GetKind(), data.GetName()) - return nil -} - -func (iClient *Client) applyConfigChange(ctx context.Context, yamlFileContents, namespace string, delete, isCustomOp bool) error { - yamls, err := iClient.splitYAML(yamlFileContents) - if err != nil { - err = errors.Wrap(err, "error while splitting yaml") - logrus.Error(err) - return err - } - for _, yml := range yamls { - if strings.TrimSpace(yml) != "" { - if err := iClient.applyRulePayload(ctx, namespace, []byte(yml), delete, isCustomOp); err != nil { - errStr := strings.TrimSpace(err.Error()) - if delete { - if strings.HasSuffix(errStr, "not found") || - strings.HasSuffix(errStr, "the server could not find the requested resource") { - // logrus.Debugf("skipping error. . .") - continue - } - } else { - if strings.HasSuffix(errStr, "already exists") { - continue - } - } - // logrus.Debugf("returning error: %v", err) - return err - } - } - } - return nil -} - -func (iClient *Client) applyRulePayload(ctx context.Context, namespace string, newBytes []byte, delete, isCustomOp bool) error { - if iClient.k8sDynamicClient == nil { - return errors.New("mesh client has not been created") - } - // logrus.Debugf("received yaml bytes: %s", newBytes) - jsonBytes, err := yaml.YAMLToJSON(newBytes) - if err != nil { - err = errors.Wrapf(err, "unable to convert yaml to json") - logrus.Error(err) - return err - } - // logrus.Debugf("created json: %s, length: %d", jsonBytes, len(jsonBytes)) - if len(jsonBytes) > 5 { // attempting to skip 'null' json - data := &unstructured.Unstructured{} - err = data.UnmarshalJSON(jsonBytes) - if err != nil { - err = errors.Wrapf(err, "unable to unmarshal json created from yaml") - logrus.Error(err) - return err - } - if data.IsList() { - err = data.EachListItem(func(r runtime.Object) error { - dataL, _ := r.(*unstructured.Unstructured) - return iClient.executeRule(ctx, dataL, namespace, delete, isCustomOp) - }) - return err - } - return iClient.executeRule(ctx, data, namespace, delete, isCustomOp) - } - return nil -} - -func (iClient *Client) executeRule(ctx context.Context, data *unstructured.Unstructured, namespace string, delete, isCustomOp bool) error { - // logrus.Debug("========================================================") - // logrus.Debugf("Received data: %+#v", data) - if namespace != "" { - data.SetNamespace(namespace) - } - groupVersion := strings.Split(data.GetAPIVersion(), "/") - logrus.Debugf("groupVersion: %v", groupVersion) - var group, version string - if len(groupVersion) == 2 { - group = groupVersion[0] - version = groupVersion[1] - } else if len(groupVersion) == 1 { - version = groupVersion[0] - } - - kind := strings.ToLower(data.GetKind()) - switch kind { - case "logentry": - kind = "logentries" - case "kubernetes": - kind = "kuberneteses" - default: - kind += "s" - } - - res := schema.GroupVersionResource{ - Group: group, - Version: version, - Resource: kind, - } - logrus.Debugf("Computed Resource: %+#v", res) - - if delete { - return iClient.deleteResource(ctx, res, data) - } - - if err := iClient.createResource(ctx, res, data); err != nil { - if isCustomOp { - if err := iClient.deleteResource(ctx, res, data); err != nil { - return err - } - time.Sleep(time.Second) - if err := iClient.createResource(ctx, res, data); err != nil { - return err - } - // data1, err := iClient.getResource(ctx, res, data) - // if err != nil { - // return err - // } - // if err = iClient.updateResource(ctx, res, data1); err != nil { - // return err - // } - } else { - return err - } - } - return nil -} - -func (iClient *Client) executeTemplate(ctx context.Context, username, namespace, templateName string) (string, error) { - tmpl, err := template.ParseFiles(path.Join("consul", "config_templates", templateName)) - if err != nil { - err = errors.Wrapf(err, "unable to parse template") - logrus.Error(err) - return "", err - } - buf := bytes.NewBufferString("") - err = tmpl.Execute(buf, map[string]string{ - "user_name": username, - "namespace": namespace, - }) - if err != nil { - err = errors.Wrapf(err, "unable to execute template") - logrus.Error(err) - return "", err - } - return buf.String(), nil -} - -func (iClient *Client) createNamespace(ctx context.Context, namespace string) error { - logrus.Debugf("creating namespace: %s", namespace) - yamlFileContents, err := iClient.executeTemplate(ctx, "", namespace, "namespace.yml") - if err != nil { - return err - } - if err := iClient.applyConfigChange(ctx, yamlFileContents, namespace, false, false); err != nil { - return err - } - return nil -} - -// ApplyOperation is a method invoked to apply a particular operation on the mesh in a namespace -func (iClient *Client) ApplyOperation(ctx context.Context, arReq *meshes.ApplyRuleRequest) (*meshes.ApplyRuleResponse, error) { - if arReq == nil { - return nil, errors.New("mesh client has not been created") - } - - op, ok := supportedOps[arReq.OpName] - if !ok { - return nil, fmt.Errorf("operation id: %s, error: %s is not a valid operation name", arReq.OperationId, arReq.OpName) - } - - if arReq.OpName == customOpCommand && arReq.CustomBody == "" { - return nil, fmt.Errorf("operation id: %s, error: yaml body is empty for %s operation", arReq.OperationId, arReq.OpName) - } - - var yamlFileContents string - var err error - isCustomOp := false - - if !arReq.DeleteOp && arReq.Namespace != "default" { - if err := iClient.createNamespace(ctx, arReq.Namespace); err != nil { - logrus.Error(err) - return nil, err - } - } - - var svcName, appName string - - switch arReq.OpName { - case customOpCommand: - yamlFileContents = arReq.CustomBody - isCustomOp = true - - case installBookInfoCommand: - svcName = "productpage" - appName = "Book info" - fallthrough - case installHTTPBinCommand: - if svcName == "" { - svcName = "httpbin" - appName = "HTTP Bin" - } - yamlFileContents, err = iClient.executeTemplate(ctx, arReq.Username, arReq.Namespace, op.templateName) - if err != nil { - return nil, err - } - go func() { - opName1 := "deploying" - if arReq.DeleteOp { - opName1 = "removing" - } - - if err := iClient.applyConfigChange(ctx, yamlFileContents, arReq.Namespace, arReq.DeleteOp, isCustomOp); err != nil { - iClient.eventChan <- &meshes.EventsResponse{ - OperationId: arReq.OperationId, - EventType: meshes.EventType_ERROR, - Summary: fmt.Sprintf("Error while %s %s app", opName1, appName), - Details: err.Error(), - } - return - } - - opName := "deployed" - ports := []int64{} - if arReq.DeleteOp { - opName = "removed" - } else { - var err error - ports, err = iClient.getSVCPort(ctx, svcName, arReq.Namespace) - if err != nil { - iClient.eventChan <- &meshes.EventsResponse{ - OperationId: arReq.OperationId, - EventType: meshes.EventType_WARN, - Summary: fmt.Sprintf("%s app is deployed but unable to retrieve the port info for the service at the moment", appName), - Details: err.Error(), - } - return - } - } - var portMsg string - if len(ports) == 1 { - portMsg = fmt.Sprintf("The service is possibly available on port: %v", ports) - } else if len(ports) > 1 { - portMsg = fmt.Sprintf("The service is possibly available on one of the following ports: %v", ports) - } - msg := fmt.Sprintf("%s app is now %s. %s", appName, opName, portMsg) - - iClient.eventChan <- &meshes.EventsResponse{ - OperationId: arReq.OperationId, - EventType: meshes.EventType_INFO, - Summary: fmt.Sprintf("%s %s successfully", appName, opName), - Details: msg, - } - }() - return &meshes.ApplyRuleResponse{ - OperationId: arReq.OperationId, - }, nil - case installImageHubCommand: - if svcName == "" { - svcName = "ingess" - appName = "Image Hub" - } - yamlFileContents, err = iClient.executeTemplate(ctx, arReq.Username, arReq.Namespace, op.templateName) - if err != nil { - return nil, err - } - go func() { - opName1 := "deploying" - if arReq.DeleteOp { - opName1 = "removing" - } - - if err := iClient.applyConfigChange(ctx, yamlFileContents, arReq.Namespace, arReq.DeleteOp, isCustomOp); err != nil { - iClient.eventChan <- &meshes.EventsResponse{ - OperationId: arReq.OperationId, - EventType: meshes.EventType_ERROR, - Summary: fmt.Sprintf("Error while %s %s app", opName1, appName), - Details: err.Error(), - } - return - } - - opName := "deployed" - ports := []int64{} - if arReq.DeleteOp { - opName = "removed" - } else { - var err error - ports, err = iClient.getSVCPort(ctx, svcName, arReq.Namespace) - if err != nil { - iClient.eventChan <- &meshes.EventsResponse{ - OperationId: arReq.OperationId, - EventType: meshes.EventType_WARN, - Summary: fmt.Sprintf("%s app is deployed but unable to retrieve the port info for the service at the moment", appName), - Details: err.Error(), - } - return - } - } - var portMsg string - if len(ports) == 1 { - portMsg = fmt.Sprintf("The service is possibly available on port: %v", ports) - } else if len(ports) > 1 { - portMsg = fmt.Sprintf("The service is possibly available on one of the following ports: %v", ports) - } - msg := fmt.Sprintf("%s app is now %s. %s", appName, opName, portMsg) - - iClient.eventChan <- &meshes.EventsResponse{ - OperationId: arReq.OperationId, - EventType: meshes.EventType_INFO, - Summary: fmt.Sprintf("%s %s successfully", appName, opName), - Details: msg, - } - }() - return &meshes.ApplyRuleResponse{ - OperationId: arReq.OperationId, - }, nil - // case installConsulCommand: - // yamlFileContents = op.templateName - // fallthrough - default: - yamlFileContents, err = iClient.executeTemplate(ctx, arReq.Username, arReq.Namespace, op.templateName) - if err != nil { - return nil, err - } - } - - if err := iClient.applyConfigChange(ctx, yamlFileContents, arReq.Namespace, arReq.DeleteOp, isCustomOp); err != nil { - return nil, err - } - - return &meshes.ApplyRuleResponse{ - OperationId: arReq.OperationId, - }, nil -} - -// SupportedOperations - returns a list of supported operations on the mesh -func (iClient *Client) SupportedOperations(context.Context, *meshes.SupportedOperationsRequest) (*meshes.SupportedOperationsResponse, error) { - supportedOpsCount := len(supportedOps) - result := make([]*meshes.SupportedOperation, supportedOpsCount) - i := 0 - for k, sp := range supportedOps { - result[i] = &meshes.SupportedOperation{ - Key: k, - Value: sp.name, - Category: sp.opType, - } - i++ - } - return &meshes.SupportedOperationsResponse{ - Ops: result, - }, nil -} - -// StreamEvents - streams generated/collected events to the client -func (iClient *Client) StreamEvents(in *meshes.EventsRequest, stream meshes.MeshService_StreamEventsServer) error { - for { - select { - case event := <-iClient.eventChan: - logrus.Debugf("sending event: %+#v", event) - if err := stream.Send(event); err != nil { - err = errors.Wrapf(err, "unable to send event") - - // to prevent loosing the event, will re-add to the channel - go func() { - iClient.eventChan <- event - }() - logrus.Error(err) - return err - } - default: - } - time.Sleep(500 * time.Millisecond) - } -} - -func (iClient *Client) splitYAML(yamlContents string) ([]string, error) { - yamlDecoder, ok := NewDocumentDecoder(ioutil.NopCloser(bytes.NewReader([]byte(yamlContents)))).(*YAMLDecoder) - if !ok { - err := fmt.Errorf("unable to create a yaml decoder") - logrus.Error(err) - return nil, err - } - defer func() { - if err := yamlDecoder.Close(); err != nil { - logrus.Error(err) - } - }() - var err error - n := 0 - data := [][]byte{} - ind := 0 - for err == io.ErrShortBuffer || err == nil { - // for { - d := make([]byte, 1000) - n, err = yamlDecoder.Read(d) - // logrus.Debugf("Read this: %s, count: %d, err: %v", d, n, err) - if len(data) == 0 || len(data) <= ind { - data = append(data, []byte{}) - } - if n > 0 { - data[ind] = append(data[ind], d...) - } - if err == nil { - logrus.Debugf("..............BOUNDARY................") - ind++ - } - } - result := make([]string, len(data)) - for i, row := range data { - r := string(row) - r = strings.Trim(r, "\x00") - logrus.Debugf("ind: %d, data: %s", i, r) - result[i] = r - } - return result, nil -} - -func (iClient *Client) getSVCPort(ctx context.Context, svc, namespace string) ([]int64, error) { - ns := &unstructured.Unstructured{} - res := schema.GroupVersionResource{ - Version: "v1", - Resource: "services", - } - ns.SetName(svc) - ns.SetNamespace(namespace) - ns, err := iClient.getResource(ctx, res, ns) - if err != nil { - err = errors.Wrapf(err, "unable to get service details") - logrus.Error(err) - return nil, err - } - svcInst := ns.UnstructuredContent() - spec := svcInst["spec"].(map[string]interface{}) - ports, _ := spec["ports"].([]interface{}) - nodePorts := []int64{} - for _, port := range ports { - p, _ := port.(map[string]interface{}) - np, ok := p["nodePort"] - if ok { - npi, _ := np.(int64) - nodePorts = append(nodePorts, npi) - } - } - logrus.Debugf("retrieved svc: %+#v", ns) - return nodePorts, nil -} diff --git a/consul/consul2.go b/consul/consul2.go new file mode 100644 index 00000000..74071376 --- /dev/null +++ b/consul/consul2.go @@ -0,0 +1,17 @@ +package consul + +import ( + "github.com/layer5io/gokit/logger" + "github.com/mgfeller/common-adapter-library/adapter" + "github.com/mgfeller/common-adapter-library/config" +) + +type ConsulAdapter struct { + adapter.BaseAdapter +} + +func New(config config.Handler, log logger.Handler) adapter.Handler { + return &ConsulAdapter{ + adapter.BaseAdapter{Config: config, Log: log}, + } +} diff --git a/consul/consul_orig.go b/consul/consul_orig.go new file mode 100644 index 00000000..60d40672 --- /dev/null +++ b/consul/consul_orig.go @@ -0,0 +1,597 @@ +// Copyright 2019 Layer5.io +// +// Licensed 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 consul ... +package consul + +//import ( +// "bytes" +// "context" +// "fmt" +// "html/template" +// "io" +// "io/ioutil" +// "path" +// "time" +// +// "strings" +// +// "github.com/ghodss/yaml" +// "github.com/layer5io/meshery-consul/meshes" +// "github.com/pkg/errors" +// "github.com/sirupsen/logrus" +// metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +// "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +// "k8s.io/apimachinery/pkg/runtime" +// "k8s.io/apimachinery/pkg/runtime/schema" +//) +// +////CreateMeshInstance instantiates a new instance of Consul in a Kubernetes cluster. +//func (iClient *Client) CreateMeshInstance(_ context.Context, k8sReq *meshes.CreateMeshInstanceRequest) (*meshes.CreateMeshInstanceResponse, error) { +// var k8sConfig []byte +// contextName := "" +// if k8sReq != nil { +// k8sConfig = k8sReq.K8SConfig +// contextName = k8sReq.ContextName +// } +// logrus.Debugf("received contextName: %s", contextName) +// +// ic, err := newClient(k8sConfig, contextName) +// if err != nil { +// err = errors.Wrapf(err, "unable to create a new istio client") +// logrus.Error(err) +// return nil, err +// } +// iClient.k8sClientset = ic.k8sClientset +// iClient.k8sDynamicClient = ic.k8sDynamicClient +// iClient.eventChan = make(chan *meshes.EventsResponse, 100) +// iClient.config = ic.config +// +// return &meshes.CreateMeshInstanceResponse{}, nil +//} +// +//// MeshName just returns the name of the mesh the client is representing +//func (iClient *Client) MeshName(context.Context, *meshes.MeshNameRequest) (*meshes.MeshNameResponse, error) { +// return &meshes.MeshNameResponse{Name: "Consul"}, nil +//} +// +//func (iClient *Client) createResource(ctx context.Context, res schema.GroupVersionResource, data *unstructured.Unstructured) error { +// _, err := iClient.k8sDynamicClient.Resource(res).Namespace(data.GetNamespace()).Create(data, metav1.CreateOptions{}) +// if err != nil { +// err = errors.Wrapf(err, "unable to create the requested resource, attempting operation without namespace") +// logrus.Warn(err) +// _, err = iClient.k8sDynamicClient.Resource(res).Create(data, metav1.CreateOptions{}) +// if err != nil { +// err = errors.Wrapf(err, "unable to create the requested resource, attempting to update") +// logrus.Error(err) +// return err +// } +// } +// logrus.Infof("Created Resource of type: %s and name: %s", data.GetKind(), data.GetName()) +// return nil +//} +// +//func (iClient *Client) deleteResource(ctx context.Context, res schema.GroupVersionResource, data *unstructured.Unstructured) error { +// if iClient.k8sDynamicClient == nil { +// return errors.New("mesh client has not been created") +// } +// +// if res.Resource == "namespaces" && data.GetName() == "default" { // skipping deletion of default namespace +// return nil +// } +// +// // in the case with deployments, have to scale it down to 0 first and then delete. . . or else RS and pods will be left behind +// if res.Resource == "deployments" { +// data1, err := iClient.getResource(ctx, res, data) +// if err != nil { +// return err +// } +// depl := data1.UnstructuredContent() +// spec1 := depl["spec"].(map[string]interface{}) +// spec1["replicas"] = 0 +// data1.SetUnstructuredContent(depl) +// if err = iClient.updateResource(ctx, res, data1); err != nil { +// return err +// } +// } +// +// err := iClient.k8sDynamicClient.Resource(res).Namespace(data.GetNamespace()).Delete(data.GetName(), &metav1.DeleteOptions{}) +// if err != nil { +// err = errors.Wrapf(err, "unable to delete the requested resource, attempting operation without namespace") +// logrus.Warn(err) +// +// err := iClient.k8sDynamicClient.Resource(res).Delete(data.GetName(), &metav1.DeleteOptions{}) +// if err != nil { +// err = errors.Wrapf(err, "unable to delete the requested resource") +// logrus.Error(err) +// return err +// } +// } +// logrus.Infof("Deleted Resource of type: %s and name: %s", data.GetKind(), data.GetName()) +// return nil +//} +// +//func (iClient *Client) getResource(ctx context.Context, res schema.GroupVersionResource, data *unstructured.Unstructured) (*unstructured.Unstructured, error) { +// data1, err := iClient.k8sDynamicClient.Resource(res).Namespace(data.GetNamespace()).Get(data.GetName(), metav1.GetOptions{}) +// if err != nil { +// err = errors.Wrap(err, "unable to retrieve the resource with a matching name, attempting operation without namespace") +// logrus.Warn(err) +// +// data1, err = iClient.k8sDynamicClient.Resource(res).Get(data.GetName(), metav1.GetOptions{}) +// if err != nil { +// err = errors.Wrap(err, "unable to retrieve the resource with a matching name, while attempting to apply the config") +// logrus.Error(err) +// return nil, err +// } +// } +// logrus.Infof("Retrieved Resource of type: %s and name: %s", data.GetKind(), data.GetName()) +// return data1, nil +//} +// +//func (iClient *Client) updateResource(ctx context.Context, res schema.GroupVersionResource, data *unstructured.Unstructured) error { +// if _, err := iClient.k8sDynamicClient.Resource(res).Namespace(data.GetNamespace()).Update(data, metav1.UpdateOptions{}); err != nil { +// err = errors.Wrap(err, "unable to update resource with the given name, attempting operation without namespace") +// logrus.Warn(err) +// +// if _, err = iClient.k8sDynamicClient.Resource(res).Update(data, metav1.UpdateOptions{}); err != nil { +// err = errors.Wrap(err, "unable to update resource with the given name, while attempting to apply the config") +// logrus.Error(err) +// return err +// } +// } +// logrus.Infof("Updated Resource of type: %s and name: %s", data.GetKind(), data.GetName()) +// return nil +//} +// +//func (iClient *Client) applyConfigChange(ctx context.Context, yamlFileContents, namespace string, delete, isCustomOp bool) error { +// yamls, err := iClient.splitYAML(yamlFileContents) +// if err != nil { +// err = errors.Wrap(err, "error while splitting yaml") +// logrus.Error(err) +// return err +// } +// for _, yml := range yamls { +// if strings.TrimSpace(yml) != "" { +// if err := iClient.applyRulePayload(ctx, namespace, []byte(yml), delete, isCustomOp); err != nil { +// errStr := strings.TrimSpace(err.Error()) +// if delete { +// if strings.HasSuffix(errStr, "not found") || +// strings.HasSuffix(errStr, "the server could not find the requested resource") { +// // logrus.Debugf("skipping error. . .") +// continue +// } +// } else { +// if strings.HasSuffix(errStr, "already exists") { +// continue +// } +// } +// // logrus.Debugf("returning error: %v", err) +// return err +// } +// } +// } +// return nil +//} +// +//func (iClient *Client) applyRulePayload(ctx context.Context, namespace string, newBytes []byte, delete, isCustomOp bool) error { +// if iClient.k8sDynamicClient == nil { +// return errors.New("mesh client has not been created") +// } +// // logrus.Debugf("received yaml bytes: %s", newBytes) +// jsonBytes, err := yaml.YAMLToJSON(newBytes) +// if err != nil { +// err = errors.Wrapf(err, "unable to convert yaml to json") +// logrus.Error(err) +// return err +// } +// // logrus.Debugf("created json: %s, length: %d", jsonBytes, len(jsonBytes)) +// if len(jsonBytes) > 5 { // attempting to skip 'null' json +// data := &unstructured.Unstructured{} +// err = data.UnmarshalJSON(jsonBytes) +// if err != nil { +// err = errors.Wrapf(err, "unable to unmarshal json created from yaml") +// logrus.Error(err) +// return err +// } +// if data.IsList() { +// err = data.EachListItem(func(r runtime.Object) error { +// dataL, _ := r.(*unstructured.Unstructured) +// return iClient.executeRule(ctx, dataL, namespace, delete, isCustomOp) +// }) +// return err +// } +// return iClient.executeRule(ctx, data, namespace, delete, isCustomOp) +// } +// return nil +//} +// +//func (iClient *Client) executeRule(ctx context.Context, data *unstructured.Unstructured, namespace string, delete, isCustomOp bool) error { +// // logrus.Debug("========================================================") +// // logrus.Debugf("Received data: %+#v", data) +// if namespace != "" { +// data.SetNamespace(namespace) +// } +// groupVersion := strings.Split(data.GetAPIVersion(), "/") +// logrus.Debugf("groupVersion: %v", groupVersion) +// var group, version string +// if len(groupVersion) == 2 { +// group = groupVersion[0] +// version = groupVersion[1] +// } else if len(groupVersion) == 1 { +// version = groupVersion[0] +// } +// +// kind := strings.ToLower(data.GetKind()) +// switch kind { +// case "logentry": +// kind = "logentries" +// case "kubernetes": +// kind = "kuberneteses" +// default: +// kind += "s" +// } +// +// res := schema.GroupVersionResource{ +// Group: group, +// Version: version, +// Resource: kind, +// } +// logrus.Debugf("Computed Resource: %+#v", res) +// +// if delete { +// return iClient.deleteResource(ctx, res, data) +// } +// +// if err := iClient.createResource(ctx, res, data); err != nil { +// if isCustomOp { +// if err := iClient.deleteResource(ctx, res, data); err != nil { +// return err +// } +// time.Sleep(time.Second) +// if err := iClient.createResource(ctx, res, data); err != nil { +// return err +// } +// // data1, err := iClient.getResource(ctx, res, data) +// // if err != nil { +// // return err +// // } +// // if err = iClient.updateResource(ctx, res, data1); err != nil { +// // return err +// // } +// } else { +// return err +// } +// } +// return nil +//} +// +//func (iClient *Client) executeTemplate(ctx context.Context, username, namespace, templateName string) (string, error) { +// tmpl, err := template.ParseFiles(path.Join("consul", "config_templates", templateName)) +// if err != nil { +// err = errors.Wrapf(err, "unable to parse template") +// logrus.Error(err) +// return "", err +// } +// buf := bytes.NewBufferString("") +// err = tmpl.Execute(buf, map[string]string{ +// "user_name": username, +// "namespace": namespace, +// }) +// if err != nil { +// err = errors.Wrapf(err, "unable to execute template") +// logrus.Error(err) +// return "", err +// } +// return buf.String(), nil +//} +// +//func (iClient *Client) createNamespace(ctx context.Context, namespace string) error { +// logrus.Debugf("creating namespace: %s", namespace) +// yamlFileContents, err := iClient.executeTemplate(ctx, "", namespace, "namespace.yml") +// if err != nil { +// return err +// } +// if err := iClient.applyConfigChange(ctx, yamlFileContents, namespace, false, false); err != nil { +// return err +// } +// return nil +//} +// +//// ApplyOperation is a method invoked to apply a particular operation on the mesh in a namespace +//func (iClient *Client) ApplyOperation(ctx context.Context, arReq *meshes.ApplyRuleRequest) (*meshes.ApplyRuleResponse, error) { +// if arReq == nil { +// return nil, errors.New("mesh client has not been created") +// } +// +// op, ok := supportedOps[arReq.OpName] +// if !ok { +// return nil, fmt.Errorf("operation id: %s, error: %s is not a valid operation name", arReq.OperationId, arReq.OpName) +// } +// +// if arReq.OpName == customOpCommand && arReq.CustomBody == "" { +// return nil, fmt.Errorf("operation id: %s, error: yaml body is empty for %s operation", arReq.OperationId, arReq.OpName) +// } +// +// var yamlFileContents string +// var err error +// isCustomOp := false +// +// if !arReq.DeleteOp && arReq.Namespace != "default" { +// if err := iClient.createNamespace(ctx, arReq.Namespace); err != nil { +// logrus.Error(err) +// return nil, err +// } +// } +// +// var svcName, appName string +// +// switch arReq.OpName { +// case customOpCommand: +// yamlFileContents = arReq.CustomBody +// isCustomOp = true +// +// case installBookInfoCommand: +// svcName = "productpage" +// appName = "Book info" +// fallthrough +// case installHTTPBinCommand: +// if svcName == "" { +// svcName = "httpbin" +// appName = "HTTP Bin" +// } +// yamlFileContents, err = iClient.executeTemplate(ctx, arReq.Username, arReq.Namespace, op.templateName) +// if err != nil { +// return nil, err +// } +// go func() { +// opName1 := "deploying" +// if arReq.DeleteOp { +// opName1 = "removing" +// } +// +// if err := iClient.applyConfigChange(ctx, yamlFileContents, arReq.Namespace, arReq.DeleteOp, isCustomOp); err != nil { +// iClient.eventChan <- &meshes.EventsResponse{ +// OperationId: arReq.OperationId, +// EventType: meshes.EventType_ERROR, +// Summary: fmt.Sprintf("Error while %s %s app", opName1, appName), +// Details: err.Error(), +// } +// return +// } +// +// opName := "deployed" +// ports := []int64{} +// if arReq.DeleteOp { +// opName = "removed" +// } else { +// var err error +// ports, err = iClient.getSVCPort(ctx, svcName, arReq.Namespace) +// if err != nil { +// iClient.eventChan <- &meshes.EventsResponse{ +// OperationId: arReq.OperationId, +// EventType: meshes.EventType_WARN, +// Summary: fmt.Sprintf("%s app is deployed but unable to retrieve the port info for the service at the moment", appName), +// Details: err.Error(), +// } +// return +// } +// } +// var portMsg string +// if len(ports) == 1 { +// portMsg = fmt.Sprintf("The service is possibly available on port: %v", ports) +// } else if len(ports) > 1 { +// portMsg = fmt.Sprintf("The service is possibly available on one of the following ports: %v", ports) +// } +// msg := fmt.Sprintf("%s app is now %s. %s", appName, opName, portMsg) +// +// iClient.eventChan <- &meshes.EventsResponse{ +// OperationId: arReq.OperationId, +// EventType: meshes.EventType_INFO, +// Summary: fmt.Sprintf("%s %s successfully", appName, opName), +// Details: msg, +// } +// }() +// return &meshes.ApplyRuleResponse{ +// OperationId: arReq.OperationId, +// }, nil +// case installImageHubCommand: +// if svcName == "" { +// svcName = "ingess" +// appName = "Image Hub" +// } +// yamlFileContents, err = iClient.executeTemplate(ctx, arReq.Username, arReq.Namespace, op.templateName) +// if err != nil { +// return nil, err +// } +// go func() { +// opName1 := "deploying" +// if arReq.DeleteOp { +// opName1 = "removing" +// } +// +// if err := iClient.applyConfigChange(ctx, yamlFileContents, arReq.Namespace, arReq.DeleteOp, isCustomOp); err != nil { +// iClient.eventChan <- &meshes.EventsResponse{ +// OperationId: arReq.OperationId, +// EventType: meshes.EventType_ERROR, +// Summary: fmt.Sprintf("Error while %s %s app", opName1, appName), +// Details: err.Error(), +// } +// return +// } +// +// opName := "deployed" +// ports := []int64{} +// if arReq.DeleteOp { +// opName = "removed" +// } else { +// var err error +// ports, err = iClient.getSVCPort(ctx, svcName, arReq.Namespace) +// if err != nil { +// iClient.eventChan <- &meshes.EventsResponse{ +// OperationId: arReq.OperationId, +// EventType: meshes.EventType_WARN, +// Summary: fmt.Sprintf("%s app is deployed but unable to retrieve the port info for the service at the moment", appName), +// Details: err.Error(), +// } +// return +// } +// } +// var portMsg string +// if len(ports) == 1 { +// portMsg = fmt.Sprintf("The service is possibly available on port: %v", ports) +// } else if len(ports) > 1 { +// portMsg = fmt.Sprintf("The service is possibly available on one of the following ports: %v", ports) +// } +// msg := fmt.Sprintf("%s app is now %s. %s", appName, opName, portMsg) +// +// iClient.eventChan <- &meshes.EventsResponse{ +// OperationId: arReq.OperationId, +// EventType: meshes.EventType_INFO, +// Summary: fmt.Sprintf("%s %s successfully", appName, opName), +// Details: msg, +// } +// }() +// return &meshes.ApplyRuleResponse{ +// OperationId: arReq.OperationId, +// }, nil +// // case installConsulCommand: +// // yamlFileContents = op.templateName +// // fallthrough +// default: +// yamlFileContents, err = iClient.executeTemplate(ctx, arReq.Username, arReq.Namespace, op.templateName) +// if err != nil { +// return nil, err +// } +// } +// +// if err := iClient.applyConfigChange(ctx, yamlFileContents, arReq.Namespace, arReq.DeleteOp, isCustomOp); err != nil { +// return nil, err +// } +// +// return &meshes.ApplyRuleResponse{ +// OperationId: arReq.OperationId, +// }, nil +//} +// +//// SupportedOperations - returns a list of supported operations on the mesh +//func (iClient *Client) SupportedOperations(context.Context, *meshes.SupportedOperationsRequest) (*meshes.SupportedOperationsResponse, error) { +// supportedOpsCount := len(supportedOps) +// result := make([]*meshes.SupportedOperation, supportedOpsCount) +// i := 0 +// for k, sp := range supportedOps { +// result[i] = &meshes.SupportedOperation{ +// Key: k, +// Value: sp.name, +// Category: sp.opType, +// } +// i++ +// } +// return &meshes.SupportedOperationsResponse{ +// Ops: result, +// }, nil +//} +// +//// StreamEvents - streams generated/collected events to the client +//func (iClient *Client) StreamEvents(in *meshes.EventsRequest, stream meshes.MeshService_StreamEventsServer) error { +// for { +// select { +// case event := <-iClient.eventChan: +// logrus.Debugf("sending event: %+#v", event) +// if err := stream.Send(event); err != nil { +// err = errors.Wrapf(err, "unable to send event") +// +// // to prevent loosing the event, will re-add to the channel +// go func() { +// iClient.eventChan <- event +// }() +// logrus.Error(err) +// return err +// } +// default: +// } +// time.Sleep(500 * time.Millisecond) +// } +//} +// +//func (iClient *Client) splitYAML(yamlContents string) ([]string, error) { +// yamlDecoder, ok := NewDocumentDecoder(ioutil.NopCloser(bytes.NewReader([]byte(yamlContents)))).(*YAMLDecoder) +// if !ok { +// err := fmt.Errorf("unable to create a yaml decoder") +// logrus.Error(err) +// return nil, err +// } +// defer func() { +// if err := yamlDecoder.Close(); err != nil { +// logrus.Error(err) +// } +// }() +// var err error +// n := 0 +// data := [][]byte{} +// ind := 0 +// for err == io.ErrShortBuffer || err == nil { +// // for { +// d := make([]byte, 1000) +// n, err = yamlDecoder.Read(d) +// // logrus.Debugf("Read this: %s, count: %d, err: %v", d, n, err) +// if len(data) == 0 || len(data) <= ind { +// data = append(data, []byte{}) +// } +// if n > 0 { +// data[ind] = append(data[ind], d...) +// } +// if err == nil { +// logrus.Debugf("..............BOUNDARY................") +// ind++ +// } +// } +// result := make([]string, len(data)) +// for i, row := range data { +// r := string(row) +// r = strings.Trim(r, "\x00") +// logrus.Debugf("ind: %d, data: %s", i, r) +// result[i] = r +// } +// return result, nil +//} +// +//func (iClient *Client) getSVCPort(ctx context.Context, svc, namespace string) ([]int64, error) { +// ns := &unstructured.Unstructured{} +// res := schema.GroupVersionResource{ +// Version: "v1", +// Resource: "services", +// } +// ns.SetName(svc) +// ns.SetNamespace(namespace) +// ns, err := iClient.getResource(ctx, res, ns) +// if err != nil { +// err = errors.Wrapf(err, "unable to get service details") +// logrus.Error(err) +// return nil, err +// } +// svcInst := ns.UnstructuredContent() +// spec := svcInst["spec"].(map[string]interface{}) +// ports, _ := spec["ports"].([]interface{}) +// nodePorts := []int64{} +// for _, port := range ports { +// p, _ := port.(map[string]interface{}) +// np, ok := p["nodePort"] +// if ok { +// npi, _ := np.(int64) +// nodePorts = append(nodePorts, npi) +// } +// } +// logrus.Debugf("retrieved svc: %+#v", ns) +// return nodePorts, nil +//} diff --git a/consul/install.go b/consul/install.go new file mode 100644 index 00000000..f3a8beb9 --- /dev/null +++ b/consul/install.go @@ -0,0 +1,34 @@ +package consul + +import "github.com/mgfeller/common-adapter-library/adapter" + +type MeshInstance struct{} + +func (m *MeshInstance) applyConsulUsingManifest(doDelete bool) error { + + return nil +} + +func (h *ConsulAdapter) installConsul(doDelete bool) (string, error) { + status := "installing" + + if doDelete { + status = "removing" + } + + meshInstance := &MeshInstance{} + + err := h.Config.MeshInstance(meshInstance) + if err != nil { + return status, adapter.ErrMeshConfig(err) + } + + h.Log.Info("Installing Consul") + err = meshInstance.applyConsulUsingManifest(doDelete) + if err != nil { + h.Log.Err("Consul installation failed", adapter.ErrInstallMesh(err).Error()) + return status, adapter.ErrInstallMesh(err) + } + + return "deployed", nil +} diff --git a/consul/operations.go b/consul/operations.go new file mode 100644 index 00000000..62ed7ff6 --- /dev/null +++ b/consul/operations.go @@ -0,0 +1,56 @@ +package consul + +import ( + "context" + "fmt" + "github.com/layer5io/meshery-consul/internal/config" + "github.com/mgfeller/common-adapter-library/adapter" +) + +func (h *ConsulAdapter) ApplyOperation(ctx context.Context, op string, id string, doDelete bool) error { + + operations := make(adapter.Operations, 0) + err := h.Config.Operations(&operations) + if err != nil { + return err + } + + status := "deploying" + e := &adapter.Event{ + Operationid: id, + Summary: "Deploying", + Details: "None", + } + + if doDelete { + status = "removing" + e.Summary = "Removing" + } + + switch op { + case config.CustomOpCommand: + h.StreamErr(e, adapter.ErrOpInvalid) + case config.InstallConsulCommand: + go func(hh *ConsulAdapter, ee *adapter.Event) { + if status, err := hh.installConsul(doDelete); err != nil { + ee.Summary = fmt.Sprintf("Error while %s Consul service mesh", status) + ee.Details = err.Error() + hh.StreamErr(ee, err) + return + } + ee.Summary = fmt.Sprintf("Consul service mesh %s successfully", status) + ee.Details = fmt.Sprintf("The Consul service mesh is now %s.", status) + hh.StreamInfo(ee) + }(h, e) + h.StreamErr(e, adapter.ErrOpInvalid) + case config.InstallHTTPBinCommand: + h.StreamErr(e, adapter.ErrOpInvalid) + case config.InstallImageHubCommand: + h.StreamErr(e, adapter.ErrOpInvalid) + case config.InstallBookInfoCommand: + h.StreamErr(e, adapter.ErrOpInvalid) + default: + h.StreamErr(e, adapter.ErrOpInvalid) + } + return nil +} diff --git a/consul/supported_ops.go b/consul/supported_ops.go index 080fa12b..77a6c629 100644 --- a/consul/supported_ops.go +++ b/consul/supported_ops.go @@ -15,48 +15,49 @@ //Package consul ... package consul -import "github.com/layer5io/meshery-consul/meshes" - -type supportedOperation struct { - // a friendly name - name string - // the template file name - templateName string - - opType meshes.OpCategory -} - -const ( - customOpCommand = "custom" - installConsulCommand = "consul_install" - installBookInfoCommand = "install_book_info" - installHTTPBinCommand = "install_http_bin" - installImageHubCommand = "install_image_hub" -) - -var supportedOps = map[string]supportedOperation{ - customOpCommand: { - name: "Custom YAML", - opType: meshes.OpCategory_CUSTOM, - }, - installConsulCommand: { - name: "Consul Connect: unsecured, 1 server, suitable for local exploration", - templateName: "consul.yaml", - opType: meshes.OpCategory_INSTALL, - }, - installBookInfoCommand: { - name: "Istio Book Info Application", - templateName: "bookinfo.yaml", - opType: meshes.OpCategory_SAMPLE_APPLICATION, - }, - installHTTPBinCommand: { - name: "HTTPbin Application", - templateName: "httpbin-consul.yaml", - opType: meshes.OpCategory_SAMPLE_APPLICATION, - }, - installImageHubCommand: { - name: "Image Hub Application", - templateName: "image-hub.yaml", - opType: meshes.OpCategory_SAMPLE_APPLICATION, - }, -} +// +//import "github.com/layer5io/meshery-consul/meshes" +// +//type supportedOperation struct { +// // a friendly name +// name string +// // the template file name +// templateName string +// +// opType meshes.OpCategory +//} +// +//const ( +// customOpCommand = "custom" +// installConsulCommand = "consul_install" +// installBookInfoCommand = "install_book_info" +// installHTTPBinCommand = "install_http_bin" +// installImageHubCommand = "install_image_hub" +//) +// +//var supportedOps = map[string]supportedOperation{ +// customOpCommand: { +// name: "Custom YAML", +// opType: meshes.OpCategory_CUSTOM, +// }, +// installConsulCommand: { +// name: "Consul Connect: unsecured, 1 server, suitable for local exploration", +// templateName: "consul.yaml", +// opType: meshes.OpCategory_INSTALL, +// }, +// installBookInfoCommand: { +// name: "Istio Book Info Application", +// templateName: "bookinfo.yaml", +// opType: meshes.OpCategory_SAMPLE_APPLICATION, +// }, +// installHTTPBinCommand: { +// name: "HTTPbin Application", +// templateName: "httpbin-consul.yaml", +// opType: meshes.OpCategory_SAMPLE_APPLICATION, +// }, +// installImageHubCommand: { +// name: "Image Hub Application", +// templateName: "image-hub.yaml", +// opType: meshes.OpCategory_SAMPLE_APPLICATION, +// }, +//} diff --git a/go.mod b/go.mod index 18e7b34a..07ec1dea 100644 --- a/go.mod +++ b/go.mod @@ -2,29 +2,12 @@ module github.com/layer5io/meshery-consul go 1.13 +replace github.com/mgfeller/common-adapter-library => ../common-adapter-library + require ( - github.com/Azure/go-autorest/autorest/adal v0.6.0 // indirect - github.com/ghodss/yaml v1.0.0 - github.com/gogo/protobuf v1.3.0 // indirect - github.com/golang/protobuf v1.4.2 github.com/googleapis/gnostic v0.3.1 // indirect - github.com/gophercloud/gophercloud v0.4.0 // indirect - github.com/imdario/mergo v0.3.7 // indirect - github.com/json-iterator/go v1.1.7 // indirect - github.com/modern-go/reflect2 v1.0.1 // indirect - github.com/pkg/errors v0.9.1 - github.com/sirupsen/logrus v1.6.0 - github.com/spf13/pflag v1.0.3 // indirect - golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 // indirect - golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 - golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect - golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect - google.golang.org/grpc v1.32.0 - gopkg.in/inf.v0 v0.9.1 // indirect - k8s.io/api v0.0.0-20190313235455-40a48860b5ab // indirect - k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1 - k8s.io/client-go v11.0.0+incompatible - k8s.io/klog v0.4.0 // indirect - k8s.io/utils v0.0.0-20190829053155-3a4a5477acf8 // indirect - sigs.k8s.io/yaml v1.1.0 // indirect + github.com/layer5io/gokit v0.1.12 + github.com/mgfeller/common-adapter-library v0.0.0-20200922065641-284f3e2e9db4 + github.com/spf13/viper v1.7.1 + google.golang.org/grpc v1.32.0 // indirect ) diff --git a/go.sum b/go.sum index ae0abc2a..de333bf8 100644 --- a/go.sum +++ b/go.sum @@ -1,46 +1,137 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/Azure/go-autorest v13.0.0+incompatible h1:56c11ykhsFSPNNQuS73Ri8h/ezqVhr2h6t9LJIEKVO0= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0 h1:RmDygqvj27Zf3fCQjQRtLyC7KwFcHkeJitcO0OoGOcA= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs= github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.6.0 h1:UCTq22yE3RPgbU/8u4scfnnzuCW6pwQ9n+uBtV78ouo= -github.com/Azure/go-autorest/autorest/adal v0.6.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM= -github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1GnWeHDdaNKY= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k= github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/sketches-go v0.0.1/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/apache/thrift v0.13.0 h1:5hryIiq9gtn+MiLVn0wP37kb/uTeRZgN08WoCsAhIhI= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +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 v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/gogo/protobuf v1.3.0 h1:G8O7TerXerS4F6sx9OV7/nRfJdnXgHZu/S/7F2SN+UE= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -53,109 +144,469 @@ github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0 github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= -github.com/gophercloud/gophercloud v0.4.0 h1:4iXQnHF7LKOl7ncQsRibnUmfx/unxT3rLAniYRB8kQQ= -github.com/gophercloud/gophercloud v0.4.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= -github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.0 h1:0IKlLyQ3Hs9nDaiK5cSHAGmcQEIC8l2Ts1u6x5Dfrqg= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.0/go.mod h1:mJzapYve32yjrKlk9GbyCZHuPgZsrbyIbyKhSzOpg6s= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= +github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/layer5io/gokit v0.1.12 h1:QGfoOHfiOpvPaCg1sGFM8ZuatXsgCkWGPD7GVVVQMyY= +github.com/layer5io/gokit v0.1.12/go.mod h1:kqwXJ5JZqHv74UCH1pVyDdpLT8muaUyRVu58WWu6wcY= +github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +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/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.5.0 h1:1N5EYkVAPEywqZRJd7cwnRtCb6xJx7NH3T3WUTF980Q= -github.com/sirupsen/logrus v1.5.0/go.mod h1:+F7Ogzej0PZc/94MaYx/nvG9jOFMD2osvC3s+Squfpo= github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk= +github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc v0.11.0 h1:jx+6CPh/uE5xW4uCm5gCb5B36+/c/k58mH+8YQ1glZo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc v0.11.0/go.mod h1:+6Kxsolxctkb7k57eHfR2T1EF7ukt5btjo8s/92wk4M= +go.opentelemetry.io/otel v0.11.0 h1:IN2tzQa9Gc4ZVKnTaMbPVcHjvzOdg5n9QfnmlqiET7E= +go.opentelemetry.io/otel v0.11.0/go.mod h1:G8UCk+KooF2HLkgo8RHX9epABH/aRGYET7gQOqBVdB0= +go.opentelemetry.io/otel/exporters/trace/jaeger v0.11.0 h1:m4ClXOtALIuL9j8gbDA1lIiKOqNNkGrX3Y2FucsufAw= +go.opentelemetry.io/otel/exporters/trace/jaeger v0.11.0/go.mod h1:bGil2p2ze3OaFpkXKbwIOPNFX0DvbFgqcxuEsrGHCd0= +go.opentelemetry.io/otel/sdk v0.11.0 h1:bkDMymVj6gIkPfgC5ci5atq0OYbfUHSn8NvsmyfyMq4= +go.opentelemetry.io/otel/sdk v0.11.0/go.mod h1:XbZ6MrzIZ+d+qr7pH0FwHIbCnANMvXYgkq4afL/IUMQ= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM= -golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297 h1:k7pJ2yAPLPgbskkFdhRCsA77k2fySZ1zf2zCjvQCiIM= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642 h1:B6caxRw+hozq68X2MY7jEpZh/cr4/aHLv9xU8Kkadrw= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 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/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c h1:Lq4llNryJoaVFRmvrIwC/ZHH7tNt4tUYIu8+se2aayY= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.28.1 h1:C1QC6KzgSiLyBabDi87BbjaGreoRgGUF5nOyvfrAZ1k= -google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.0 h1:2pJjwYOdkZ9HlN4sWRYBg9ttH5bCOlsueaM+b/oYjwo= -google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1 h1:SfXqXS5hkufcdZ/mHtYCh53P2b+92WQq/DZcKLgsFRs= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.32.0 h1:zWTV+LMdc3kaiJMSTOFz2UgSBgx8RNQoTGiZu3fR9S0= google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -168,23 +619,61 @@ google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2M google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.0.0-20190313235455-40a48860b5ab h1:DG9A67baNpoeweOy2spF1OWHhnVY5KR7/Ek/+U1lVZc= -k8s.io/api v0.0.0-20190313235455-40a48860b5ab/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA= -k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1 h1:IS7K02iBkQXpCeieSiyJjGoLSdVOv2DbPaWHJ+ZtgKg= -k8s.io/apimachinery v0.0.0-20190313205120-d7deff9243b1/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0= -k8s.io/client-go v11.0.0+incompatible h1:LBbX2+lOwY9flffWlJM7f1Ct8V2SRNiMRDFeiwnJo9o= -k8s.io/client-go v11.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.18.8 h1:aIKUzJPb96f3fKec2lxtY7acZC9gQNDLVhfSGpxBAC4= +k8s.io/api v0.18.8/go.mod h1:d/CXqwWv+Z2XEG1LgceeDmHQwpUJhROPx16SlxJgERY= +k8s.io/apimachinery v0.18.8 h1:jimPrycCqgx2QPearX3to1JePz7wSbVLq+7PdBTTwQ0= +k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= +k8s.io/client-go v0.18.8 h1:SdbLpIxk5j5YbFr1b7fq8S7mDgDjYmUxSbszyoesoDM= +k8s.io/client-go v0.18.8/go.mod h1:HqFqMllQ5NnQJNwjro9k5zMyfhZlOwpuTLVrxjkYSxU= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v0.4.0 h1:lCJCxf/LIowc2IGS9TPjWDyXY4nOmdGdfcwwDQCOURQ= -k8s.io/klog v0.4.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/utils v0.0.0-20190829053155-3a4a5477acf8 h1:khtxGxwSe3nyReEEggzTwQigMT3g40enrlivMlMeaGY= -k8s.io/utils v0.0.0-20190829053155-3a4a5477acf8/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89 h1:d4vVOjXm687F1iLSP2q3lyPPuyvTUt3aVoBpi2DqRsU= +k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 00000000..bde18463 --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,13 @@ +package config + +import ( + "github.com/mgfeller/common-adapter-library/config" +) + +func New(name string, serverConfig map[string]string, meshConfig map[string]string, providerConfig map[string]string) (config.Handler, error) { + switch name { + case "viper": + return NewViper(serverConfig, meshConfig, providerConfig) + } + return nil, config.ErrEmptyConfig +} diff --git a/internal/config/defaults.go b/internal/config/defaults.go new file mode 100644 index 00000000..4cd7f001 --- /dev/null +++ b/internal/config/defaults.go @@ -0,0 +1,22 @@ +package config + +var ( + ServerDefaults = map[string]string{ + "name": "consul-adapter", + "port": "10002", + "traceurl": "none", + "version": "v0.1.0", + } + + MeshDefaults = map[string]string{ + "name": "consul", + "status": "not installed", // TODO: status should be a type / an enum + "version": "1.8.2", + } + + ViperDefaults = map[string]string{ + "filepath": "~/.meshery-consul", + "filename": "config.yml", + "filetype": "yaml", + } +) diff --git a/internal/config/keys.go b/internal/config/keys.go new file mode 100644 index 00000000..318eec55 --- /dev/null +++ b/internal/config/keys.go @@ -0,0 +1,9 @@ +package config + +const ( + CustomOpCommand = "custom" + InstallConsulCommand = "consul_install" + InstallBookInfoCommand = "install_book_info" + InstallHTTPBinCommand = "install_http_bin" + InstallImageHubCommand = "install_image_hub" +) diff --git a/internal/config/viper.go b/internal/config/viper.go new file mode 100644 index 00000000..2295aab1 --- /dev/null +++ b/internal/config/viper.go @@ -0,0 +1,69 @@ +package config + +import ( + "errors" + "github.com/mgfeller/common-adapter-library/config" + "github.com/spf13/viper" +) + +const ( + ServerKey = "server" + MeshSpecKey = "mesh" + MeshInstanceKey = "instance" +) + +type Viper struct { + instance *viper.Viper +} + +func NewViper(serverConfig map[string]string, meshConfig map[string]string, providerConfig map[string]string) (config.Handler, error) { + v := viper.New() + v.AddConfigPath(providerConfig["filepath"]) + v.SetConfigType(providerConfig["filetype"]) + v.SetConfigName(providerConfig["filename"]) + v.AutomaticEnv() + + for key, value := range serverConfig { + v.SetDefault(ServerKey+"."+key, value) + } + + for key, value := range meshConfig { + v.SetDefault(MeshSpecKey+"."+key, value) + } + + if err := viper.ReadInConfig(); err != nil { + if _, ok := err.(viper.ConfigFileNotFoundError); ok { + // Config file not found; ignore error + } else { + // Config file was found but another error was produced + return nil, config.ErrViper(err) + } + } + return &Viper{ + instance: v, + }, nil +} + +func (v *Viper) SetKey(key string, value string) { + v.instance.Set(key, value) +} + +func (v *Viper) GetKey(key string) string { + return v.instance.Get(key).(string) +} + +func (v *Viper) Server(result interface{}) error { + return v.instance.Sub(ServerKey).Unmarshal(result) +} + +func (v *Viper) MeshSpec(result interface{}) error { + return v.instance.Sub(MeshSpecKey).Unmarshal(result) +} + +func (v *Viper) MeshInstance(result interface{}) error { + return v.instance.Sub(MeshInstanceKey).Unmarshal(result) +} + +func (v *Viper) Operations(result interface{}) error { + return errors.New("config 'operations' not implemented") +} diff --git a/main.go b/main.go index 8efd109f..c5831fd3 100644 --- a/main.go +++ b/main.go @@ -15,54 +15,47 @@ package main import ( - "flag" "fmt" - "net" - "os" - - "github.com/sirupsen/logrus" - "google.golang.org/grpc" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/reflection" - + "github.com/layer5io/gokit/errors" + "github.com/layer5io/gokit/logger" + "github.com/layer5io/gokit/utils" "github.com/layer5io/meshery-consul/consul" - mesh "github.com/layer5io/meshery-consul/meshes" + "github.com/layer5io/meshery-consul/internal/config" + "github.com/mgfeller/common-adapter-library/api/grpc" + "os" + "time" ) var ( - gRPCPort = flag.Int("grpc-port", 10002, "The gRPC server port") + serviceName = "consul-adaptor" + configProvider = "viper" + kubeConfigPath = fmt.Sprintf("%s/.kube/meshery.config", utils.GetHome()) ) -var log grpclog.LoggerV2 - -func init() { - log = grpclog.NewLoggerV2(os.Stdout, os.Stdout, os.Stdout) - grpclog.SetLoggerV2(log) -} - func main() { - flag.Parse() - - if os.Getenv("DEBUG") == "true" { - logrus.SetLevel(logrus.DebugLevel) + log, err := logger.New(serviceName) + if err != nil { + fmt.Println("Logger Init Failed", err.Error()) + os.Exit(1) } - addr := fmt.Sprintf(":%d", *gRPCPort) - lis, err := net.Listen("tcp", addr) + config, err := config.New(configProvider, config.ServerDefaults, config.MeshDefaults, config.ViperDefaults) if err != nil { - logrus.Fatalln("Failed to listen:", err) + log.Err("Config Init Failed", err.Error()) + os.Exit(1) } - s := grpc.NewServer( - // grpc.Creds(credentials.NewServerTLSFromCert(&insecure.Cert)), - ) - // Reflection is enabled to simplify accessing the gRPC service using gRPCurl, e.g. - // grpcurl --plaintext localhost:10002 meshes.MeshService.SupportedOperations - // If the use of reflection is not desirable, the parameters '-import-path ./meshes/ -proto meshops.proto' have - // to be added to each grpcurl request, with the appropriate import path. - reflection.Register(s) - mesh.RegisterMeshServiceServer(s, &consul.Client{}) + config.SetKey("kube-config-path", kubeConfigPath) - // Serve gRPC Server - logrus.Infof("Serving gRPC on %s", addr) - logrus.Fatal(s.Serve(lis)) + service := &grpc.Service{} + _ = config.Server(&service) + + service.Handler = consul.New(config, log) + service.Channel = make(chan interface{}, 100) + service.StartedAt = time.Now() + log.Info(fmt.Sprintf("%s starting on port: %s", service.Name, service.Port)) + err = grpc.Start(service, nil) + if err != nil { + log.Err(errors.ErrGrpcServer, "adapter crashed on startup") + os.Exit(1) + } } diff --git a/meshes/meshops.pb.go b/meshes/meshops.pb.go deleted file mode 100644 index 19e223de..00000000 --- a/meshes/meshops.pb.go +++ /dev/null @@ -1,872 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: meshops.proto - -package meshes - -import ( - fmt "fmt" - - proto "github.com/golang/protobuf/proto" - - math "math" - - context "golang.org/x/net/context" - - grpc "google.golang.org/grpc" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -type OpCategory int32 - -const ( - OpCategory_INSTALL OpCategory = 0 - OpCategory_SAMPLE_APPLICATION OpCategory = 1 - OpCategory_CONFIGURE OpCategory = 2 - OpCategory_VALIDATE OpCategory = 3 - OpCategory_CUSTOM OpCategory = 4 -) - -var OpCategory_name = map[int32]string{ - 0: "INSTALL", - 1: "SAMPLE_APPLICATION", - 2: "CONFIGURE", - 3: "VALIDATE", - 4: "CUSTOM", -} -var OpCategory_value = map[string]int32{ - "INSTALL": 0, - "SAMPLE_APPLICATION": 1, - "CONFIGURE": 2, - "VALIDATE": 3, - "CUSTOM": 4, -} - -func (x OpCategory) String() string { - return proto.EnumName(OpCategory_name, int32(x)) -} -func (OpCategory) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_meshops_70742207f69c0a34, []int{0} -} - -type EventType int32 - -const ( - EventType_INFO EventType = 0 - EventType_WARN EventType = 1 - EventType_ERROR EventType = 2 -) - -var EventType_name = map[int32]string{ - 0: "INFO", - 1: "WARN", - 2: "ERROR", -} -var EventType_value = map[string]int32{ - "INFO": 0, - "WARN": 1, - "ERROR": 2, -} - -func (x EventType) String() string { - return proto.EnumName(EventType_name, int32(x)) -} -func (EventType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_meshops_70742207f69c0a34, []int{1} -} - -type CreateMeshInstanceRequest struct { - K8SConfig []byte `protobuf:"bytes,1,opt,name=k8sConfig,proto3" json:"k8sConfig,omitempty"` - ContextName string `protobuf:"bytes,2,opt,name=contextName,proto3" json:"contextName,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CreateMeshInstanceRequest) Reset() { *m = CreateMeshInstanceRequest{} } -func (m *CreateMeshInstanceRequest) String() string { return proto.CompactTextString(m) } -func (*CreateMeshInstanceRequest) ProtoMessage() {} -func (*CreateMeshInstanceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_meshops_70742207f69c0a34, []int{0} -} -func (m *CreateMeshInstanceRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CreateMeshInstanceRequest.Unmarshal(m, b) -} -func (m *CreateMeshInstanceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CreateMeshInstanceRequest.Marshal(b, m, deterministic) -} -func (dst *CreateMeshInstanceRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_CreateMeshInstanceRequest.Merge(dst, src) -} -func (m *CreateMeshInstanceRequest) XXX_Size() int { - return xxx_messageInfo_CreateMeshInstanceRequest.Size(m) -} -func (m *CreateMeshInstanceRequest) XXX_DiscardUnknown() { - xxx_messageInfo_CreateMeshInstanceRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_CreateMeshInstanceRequest proto.InternalMessageInfo - -func (m *CreateMeshInstanceRequest) GetK8SConfig() []byte { - if m != nil { - return m.K8SConfig - } - return nil -} - -func (m *CreateMeshInstanceRequest) GetContextName() string { - if m != nil { - return m.ContextName - } - return "" -} - -type CreateMeshInstanceResponse struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *CreateMeshInstanceResponse) Reset() { *m = CreateMeshInstanceResponse{} } -func (m *CreateMeshInstanceResponse) String() string { return proto.CompactTextString(m) } -func (*CreateMeshInstanceResponse) ProtoMessage() {} -func (*CreateMeshInstanceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_meshops_70742207f69c0a34, []int{1} -} -func (m *CreateMeshInstanceResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_CreateMeshInstanceResponse.Unmarshal(m, b) -} -func (m *CreateMeshInstanceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_CreateMeshInstanceResponse.Marshal(b, m, deterministic) -} -func (dst *CreateMeshInstanceResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_CreateMeshInstanceResponse.Merge(dst, src) -} -func (m *CreateMeshInstanceResponse) XXX_Size() int { - return xxx_messageInfo_CreateMeshInstanceResponse.Size(m) -} -func (m *CreateMeshInstanceResponse) XXX_DiscardUnknown() { - xxx_messageInfo_CreateMeshInstanceResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_CreateMeshInstanceResponse proto.InternalMessageInfo - -type MeshNameRequest struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *MeshNameRequest) Reset() { *m = MeshNameRequest{} } -func (m *MeshNameRequest) String() string { return proto.CompactTextString(m) } -func (*MeshNameRequest) ProtoMessage() {} -func (*MeshNameRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_meshops_70742207f69c0a34, []int{2} -} -func (m *MeshNameRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_MeshNameRequest.Unmarshal(m, b) -} -func (m *MeshNameRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_MeshNameRequest.Marshal(b, m, deterministic) -} -func (dst *MeshNameRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_MeshNameRequest.Merge(dst, src) -} -func (m *MeshNameRequest) XXX_Size() int { - return xxx_messageInfo_MeshNameRequest.Size(m) -} -func (m *MeshNameRequest) XXX_DiscardUnknown() { - xxx_messageInfo_MeshNameRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_MeshNameRequest proto.InternalMessageInfo - -type MeshNameResponse struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *MeshNameResponse) Reset() { *m = MeshNameResponse{} } -func (m *MeshNameResponse) String() string { return proto.CompactTextString(m) } -func (*MeshNameResponse) ProtoMessage() {} -func (*MeshNameResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_meshops_70742207f69c0a34, []int{3} -} -func (m *MeshNameResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_MeshNameResponse.Unmarshal(m, b) -} -func (m *MeshNameResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_MeshNameResponse.Marshal(b, m, deterministic) -} -func (dst *MeshNameResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_MeshNameResponse.Merge(dst, src) -} -func (m *MeshNameResponse) XXX_Size() int { - return xxx_messageInfo_MeshNameResponse.Size(m) -} -func (m *MeshNameResponse) XXX_DiscardUnknown() { - xxx_messageInfo_MeshNameResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_MeshNameResponse proto.InternalMessageInfo - -func (m *MeshNameResponse) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -type ApplyRuleRequest struct { - OpName string `protobuf:"bytes,1,opt,name=opName,proto3" json:"opName,omitempty"` - Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` - Username string `protobuf:"bytes,3,opt,name=username,proto3" json:"username,omitempty"` - CustomBody string `protobuf:"bytes,4,opt,name=custom_body,json=customBody,proto3" json:"custom_body,omitempty"` - DeleteOp bool `protobuf:"varint,5,opt,name=delete_op,json=deleteOp,proto3" json:"delete_op,omitempty"` - OperationId string `protobuf:"bytes,6,opt,name=operation_id,json=operationId,proto3" json:"operation_id,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ApplyRuleRequest) Reset() { *m = ApplyRuleRequest{} } -func (m *ApplyRuleRequest) String() string { return proto.CompactTextString(m) } -func (*ApplyRuleRequest) ProtoMessage() {} -func (*ApplyRuleRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_meshops_70742207f69c0a34, []int{4} -} -func (m *ApplyRuleRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ApplyRuleRequest.Unmarshal(m, b) -} -func (m *ApplyRuleRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ApplyRuleRequest.Marshal(b, m, deterministic) -} -func (dst *ApplyRuleRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplyRuleRequest.Merge(dst, src) -} -func (m *ApplyRuleRequest) XXX_Size() int { - return xxx_messageInfo_ApplyRuleRequest.Size(m) -} -func (m *ApplyRuleRequest) XXX_DiscardUnknown() { - xxx_messageInfo_ApplyRuleRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplyRuleRequest proto.InternalMessageInfo - -func (m *ApplyRuleRequest) GetOpName() string { - if m != nil { - return m.OpName - } - return "" -} - -func (m *ApplyRuleRequest) GetNamespace() string { - if m != nil { - return m.Namespace - } - return "" -} - -func (m *ApplyRuleRequest) GetUsername() string { - if m != nil { - return m.Username - } - return "" -} - -func (m *ApplyRuleRequest) GetCustomBody() string { - if m != nil { - return m.CustomBody - } - return "" -} - -func (m *ApplyRuleRequest) GetDeleteOp() bool { - if m != nil { - return m.DeleteOp - } - return false -} - -func (m *ApplyRuleRequest) GetOperationId() string { - if m != nil { - return m.OperationId - } - return "" -} - -type ApplyRuleResponse struct { - Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` - OperationId string `protobuf:"bytes,2,opt,name=operation_id,json=operationId,proto3" json:"operation_id,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ApplyRuleResponse) Reset() { *m = ApplyRuleResponse{} } -func (m *ApplyRuleResponse) String() string { return proto.CompactTextString(m) } -func (*ApplyRuleResponse) ProtoMessage() {} -func (*ApplyRuleResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_meshops_70742207f69c0a34, []int{5} -} -func (m *ApplyRuleResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ApplyRuleResponse.Unmarshal(m, b) -} -func (m *ApplyRuleResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ApplyRuleResponse.Marshal(b, m, deterministic) -} -func (dst *ApplyRuleResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_ApplyRuleResponse.Merge(dst, src) -} -func (m *ApplyRuleResponse) XXX_Size() int { - return xxx_messageInfo_ApplyRuleResponse.Size(m) -} -func (m *ApplyRuleResponse) XXX_DiscardUnknown() { - xxx_messageInfo_ApplyRuleResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_ApplyRuleResponse proto.InternalMessageInfo - -func (m *ApplyRuleResponse) GetError() string { - if m != nil { - return m.Error - } - return "" -} - -func (m *ApplyRuleResponse) GetOperationId() string { - if m != nil { - return m.OperationId - } - return "" -} - -type SupportedOperationsRequest struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SupportedOperationsRequest) Reset() { *m = SupportedOperationsRequest{} } -func (m *SupportedOperationsRequest) String() string { return proto.CompactTextString(m) } -func (*SupportedOperationsRequest) ProtoMessage() {} -func (*SupportedOperationsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_meshops_70742207f69c0a34, []int{6} -} -func (m *SupportedOperationsRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SupportedOperationsRequest.Unmarshal(m, b) -} -func (m *SupportedOperationsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SupportedOperationsRequest.Marshal(b, m, deterministic) -} -func (dst *SupportedOperationsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_SupportedOperationsRequest.Merge(dst, src) -} -func (m *SupportedOperationsRequest) XXX_Size() int { - return xxx_messageInfo_SupportedOperationsRequest.Size(m) -} -func (m *SupportedOperationsRequest) XXX_DiscardUnknown() { - xxx_messageInfo_SupportedOperationsRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_SupportedOperationsRequest proto.InternalMessageInfo - -type SupportedOperationsResponse struct { - Ops []*SupportedOperation `protobuf:"bytes,1,rep,name=ops,proto3" json:"ops,omitempty"` - Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SupportedOperationsResponse) Reset() { *m = SupportedOperationsResponse{} } -func (m *SupportedOperationsResponse) String() string { return proto.CompactTextString(m) } -func (*SupportedOperationsResponse) ProtoMessage() {} -func (*SupportedOperationsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_meshops_70742207f69c0a34, []int{7} -} -func (m *SupportedOperationsResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SupportedOperationsResponse.Unmarshal(m, b) -} -func (m *SupportedOperationsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SupportedOperationsResponse.Marshal(b, m, deterministic) -} -func (dst *SupportedOperationsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_SupportedOperationsResponse.Merge(dst, src) -} -func (m *SupportedOperationsResponse) XXX_Size() int { - return xxx_messageInfo_SupportedOperationsResponse.Size(m) -} -func (m *SupportedOperationsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_SupportedOperationsResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_SupportedOperationsResponse proto.InternalMessageInfo - -func (m *SupportedOperationsResponse) GetOps() []*SupportedOperation { - if m != nil { - return m.Ops - } - return nil -} - -func (m *SupportedOperationsResponse) GetError() string { - if m != nil { - return m.Error - } - return "" -} - -type SupportedOperation struct { - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` - Category OpCategory `protobuf:"varint,3,opt,name=category,proto3,enum=meshes.OpCategory" json:"category,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *SupportedOperation) Reset() { *m = SupportedOperation{} } -func (m *SupportedOperation) String() string { return proto.CompactTextString(m) } -func (*SupportedOperation) ProtoMessage() {} -func (*SupportedOperation) Descriptor() ([]byte, []int) { - return fileDescriptor_meshops_70742207f69c0a34, []int{8} -} -func (m *SupportedOperation) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SupportedOperation.Unmarshal(m, b) -} -func (m *SupportedOperation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SupportedOperation.Marshal(b, m, deterministic) -} -func (dst *SupportedOperation) XXX_Merge(src proto.Message) { - xxx_messageInfo_SupportedOperation.Merge(dst, src) -} -func (m *SupportedOperation) XXX_Size() int { - return xxx_messageInfo_SupportedOperation.Size(m) -} -func (m *SupportedOperation) XXX_DiscardUnknown() { - xxx_messageInfo_SupportedOperation.DiscardUnknown(m) -} - -var xxx_messageInfo_SupportedOperation proto.InternalMessageInfo - -func (m *SupportedOperation) GetKey() string { - if m != nil { - return m.Key - } - return "" -} - -func (m *SupportedOperation) GetValue() string { - if m != nil { - return m.Value - } - return "" -} - -func (m *SupportedOperation) GetCategory() OpCategory { - if m != nil { - return m.Category - } - return OpCategory_INSTALL -} - -type EventsRequest struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EventsRequest) Reset() { *m = EventsRequest{} } -func (m *EventsRequest) String() string { return proto.CompactTextString(m) } -func (*EventsRequest) ProtoMessage() {} -func (*EventsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_meshops_70742207f69c0a34, []int{9} -} -func (m *EventsRequest) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EventsRequest.Unmarshal(m, b) -} -func (m *EventsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EventsRequest.Marshal(b, m, deterministic) -} -func (dst *EventsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_EventsRequest.Merge(dst, src) -} -func (m *EventsRequest) XXX_Size() int { - return xxx_messageInfo_EventsRequest.Size(m) -} -func (m *EventsRequest) XXX_DiscardUnknown() { - xxx_messageInfo_EventsRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_EventsRequest proto.InternalMessageInfo - -type EventsResponse struct { - EventType EventType `protobuf:"varint,1,opt,name=event_type,json=eventType,proto3,enum=meshes.EventType" json:"event_type,omitempty"` - Summary string `protobuf:"bytes,2,opt,name=summary,proto3" json:"summary,omitempty"` - Details string `protobuf:"bytes,3,opt,name=details,proto3" json:"details,omitempty"` - OperationId string `protobuf:"bytes,4,opt,name=operation_id,json=operationId,proto3" json:"operation_id,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *EventsResponse) Reset() { *m = EventsResponse{} } -func (m *EventsResponse) String() string { return proto.CompactTextString(m) } -func (*EventsResponse) ProtoMessage() {} -func (*EventsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_meshops_70742207f69c0a34, []int{10} -} -func (m *EventsResponse) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_EventsResponse.Unmarshal(m, b) -} -func (m *EventsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_EventsResponse.Marshal(b, m, deterministic) -} -func (dst *EventsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_EventsResponse.Merge(dst, src) -} -func (m *EventsResponse) XXX_Size() int { - return xxx_messageInfo_EventsResponse.Size(m) -} -func (m *EventsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_EventsResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_EventsResponse proto.InternalMessageInfo - -func (m *EventsResponse) GetEventType() EventType { - if m != nil { - return m.EventType - } - return EventType_INFO -} - -func (m *EventsResponse) GetSummary() string { - if m != nil { - return m.Summary - } - return "" -} - -func (m *EventsResponse) GetDetails() string { - if m != nil { - return m.Details - } - return "" -} - -func (m *EventsResponse) GetOperationId() string { - if m != nil { - return m.OperationId - } - return "" -} - -func init() { - proto.RegisterType((*CreateMeshInstanceRequest)(nil), "meshes.CreateMeshInstanceRequest") - proto.RegisterType((*CreateMeshInstanceResponse)(nil), "meshes.CreateMeshInstanceResponse") - proto.RegisterType((*MeshNameRequest)(nil), "meshes.MeshNameRequest") - proto.RegisterType((*MeshNameResponse)(nil), "meshes.MeshNameResponse") - proto.RegisterType((*ApplyRuleRequest)(nil), "meshes.ApplyRuleRequest") - proto.RegisterType((*ApplyRuleResponse)(nil), "meshes.ApplyRuleResponse") - proto.RegisterType((*SupportedOperationsRequest)(nil), "meshes.SupportedOperationsRequest") - proto.RegisterType((*SupportedOperationsResponse)(nil), "meshes.SupportedOperationsResponse") - proto.RegisterType((*SupportedOperation)(nil), "meshes.SupportedOperation") - proto.RegisterType((*EventsRequest)(nil), "meshes.EventsRequest") - proto.RegisterType((*EventsResponse)(nil), "meshes.EventsResponse") - proto.RegisterEnum("meshes.OpCategory", OpCategory_name, OpCategory_value) - proto.RegisterEnum("meshes.EventType", EventType_name, EventType_value) -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// MeshServiceClient is the client API for MeshService service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type MeshServiceClient interface { - CreateMeshInstance(ctx context.Context, in *CreateMeshInstanceRequest, opts ...grpc.CallOption) (*CreateMeshInstanceResponse, error) - MeshName(ctx context.Context, in *MeshNameRequest, opts ...grpc.CallOption) (*MeshNameResponse, error) - ApplyOperation(ctx context.Context, in *ApplyRuleRequest, opts ...grpc.CallOption) (*ApplyRuleResponse, error) - SupportedOperations(ctx context.Context, in *SupportedOperationsRequest, opts ...grpc.CallOption) (*SupportedOperationsResponse, error) - StreamEvents(ctx context.Context, in *EventsRequest, opts ...grpc.CallOption) (MeshService_StreamEventsClient, error) -} - -type meshServiceClient struct { - cc *grpc.ClientConn -} - -func NewMeshServiceClient(cc *grpc.ClientConn) MeshServiceClient { - return &meshServiceClient{cc} -} - -func (c *meshServiceClient) CreateMeshInstance(ctx context.Context, in *CreateMeshInstanceRequest, opts ...grpc.CallOption) (*CreateMeshInstanceResponse, error) { - out := new(CreateMeshInstanceResponse) - err := c.cc.Invoke(ctx, "/meshes.MeshService/CreateMeshInstance", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *meshServiceClient) MeshName(ctx context.Context, in *MeshNameRequest, opts ...grpc.CallOption) (*MeshNameResponse, error) { - out := new(MeshNameResponse) - err := c.cc.Invoke(ctx, "/meshes.MeshService/MeshName", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *meshServiceClient) ApplyOperation(ctx context.Context, in *ApplyRuleRequest, opts ...grpc.CallOption) (*ApplyRuleResponse, error) { - out := new(ApplyRuleResponse) - err := c.cc.Invoke(ctx, "/meshes.MeshService/ApplyOperation", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *meshServiceClient) SupportedOperations(ctx context.Context, in *SupportedOperationsRequest, opts ...grpc.CallOption) (*SupportedOperationsResponse, error) { - out := new(SupportedOperationsResponse) - err := c.cc.Invoke(ctx, "/meshes.MeshService/SupportedOperations", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *meshServiceClient) StreamEvents(ctx context.Context, in *EventsRequest, opts ...grpc.CallOption) (MeshService_StreamEventsClient, error) { - stream, err := c.cc.NewStream(ctx, &_MeshService_serviceDesc.Streams[0], "/meshes.MeshService/StreamEvents", opts...) - if err != nil { - return nil, err - } - x := &meshServiceStreamEventsClient{stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err - } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type MeshService_StreamEventsClient interface { - Recv() (*EventsResponse, error) - grpc.ClientStream -} - -type meshServiceStreamEventsClient struct { - grpc.ClientStream -} - -func (x *meshServiceStreamEventsClient) Recv() (*EventsResponse, error) { - m := new(EventsResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -// MeshServiceServer is the server API for MeshService service. -type MeshServiceServer interface { - CreateMeshInstance(context.Context, *CreateMeshInstanceRequest) (*CreateMeshInstanceResponse, error) - MeshName(context.Context, *MeshNameRequest) (*MeshNameResponse, error) - ApplyOperation(context.Context, *ApplyRuleRequest) (*ApplyRuleResponse, error) - SupportedOperations(context.Context, *SupportedOperationsRequest) (*SupportedOperationsResponse, error) - StreamEvents(*EventsRequest, MeshService_StreamEventsServer) error -} - -func RegisterMeshServiceServer(s *grpc.Server, srv MeshServiceServer) { - s.RegisterService(&_MeshService_serviceDesc, srv) -} - -func _MeshService_CreateMeshInstance_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CreateMeshInstanceRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MeshServiceServer).CreateMeshInstance(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/meshes.MeshService/CreateMeshInstance", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MeshServiceServer).CreateMeshInstance(ctx, req.(*CreateMeshInstanceRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _MeshService_MeshName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MeshNameRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MeshServiceServer).MeshName(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/meshes.MeshService/MeshName", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MeshServiceServer).MeshName(ctx, req.(*MeshNameRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _MeshService_ApplyOperation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ApplyRuleRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MeshServiceServer).ApplyOperation(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/meshes.MeshService/ApplyOperation", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MeshServiceServer).ApplyOperation(ctx, req.(*ApplyRuleRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _MeshService_SupportedOperations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(SupportedOperationsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(MeshServiceServer).SupportedOperations(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/meshes.MeshService/SupportedOperations", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MeshServiceServer).SupportedOperations(ctx, req.(*SupportedOperationsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _MeshService_StreamEvents_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(EventsRequest) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(MeshServiceServer).StreamEvents(m, &meshServiceStreamEventsServer{stream}) -} - -type MeshService_StreamEventsServer interface { - Send(*EventsResponse) error - grpc.ServerStream -} - -type meshServiceStreamEventsServer struct { - grpc.ServerStream -} - -func (x *meshServiceStreamEventsServer) Send(m *EventsResponse) error { - return x.ServerStream.SendMsg(m) -} - -var _MeshService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "meshes.MeshService", - HandlerType: (*MeshServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "CreateMeshInstance", - Handler: _MeshService_CreateMeshInstance_Handler, - }, - { - MethodName: "MeshName", - Handler: _MeshService_MeshName_Handler, - }, - { - MethodName: "ApplyOperation", - Handler: _MeshService_ApplyOperation_Handler, - }, - { - MethodName: "SupportedOperations", - Handler: _MeshService_SupportedOperations_Handler, - }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "StreamEvents", - Handler: _MeshService_StreamEvents_Handler, - ServerStreams: true, - }, - }, - Metadata: "meshops.proto", -} - -func init() { proto.RegisterFile("meshops.proto", fileDescriptor_meshops_70742207f69c0a34) } - -var fileDescriptor_meshops_70742207f69c0a34 = []byte{ - // 676 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x54, 0x61, 0x6f, 0xda, 0x3c, - 0x10, 0x6e, 0x80, 0x52, 0x38, 0x28, 0x4d, 0xfd, 0xbe, 0xeb, 0xd2, 0xb4, 0xd2, 0x68, 0x26, 0x4d, - 0xa8, 0x9a, 0x50, 0xc5, 0xbe, 0xec, 0xdb, 0x94, 0x31, 0x5a, 0x45, 0xa2, 0xa4, 0x0a, 0x74, 0x93, - 0x36, 0x4d, 0x2c, 0x85, 0x5b, 0x8b, 0x0a, 0xb1, 0x17, 0x9b, 0x6a, 0xf9, 0x29, 0xd3, 0x7e, 0xcf, - 0xfe, 0xd7, 0xe4, 0x24, 0x0e, 0x5d, 0x43, 0xfb, 0xcd, 0xf7, 0xdc, 0xf9, 0xf1, 0x3d, 0xf6, 0x73, - 0x86, 0xed, 0x05, 0xf2, 0x1b, 0xca, 0x78, 0x9b, 0x85, 0x54, 0x50, 0x52, 0x96, 0x21, 0x72, 0xeb, - 0x0b, 0xec, 0x77, 0x43, 0xf4, 0x05, 0x9e, 0x23, 0xbf, 0x71, 0x02, 0x2e, 0xfc, 0x60, 0x82, 0x1e, - 0xfe, 0x58, 0x22, 0x17, 0xe4, 0x10, 0xaa, 0xb7, 0x6f, 0x79, 0x97, 0x06, 0xdf, 0x67, 0xd7, 0x86, - 0xd6, 0xd4, 0x5a, 0x75, 0x6f, 0x05, 0x90, 0x26, 0xd4, 0x26, 0x34, 0x10, 0xf8, 0x53, 0x0c, 0xfc, - 0x05, 0x1a, 0x85, 0xa6, 0xd6, 0xaa, 0x7a, 0xf7, 0x21, 0xeb, 0x10, 0xcc, 0x75, 0xe4, 0x9c, 0xd1, - 0x80, 0xa3, 0xb5, 0x0b, 0x3b, 0x12, 0x97, 0x95, 0xe9, 0x81, 0xd6, 0x2b, 0xd0, 0x57, 0x50, 0x52, - 0x46, 0x08, 0x94, 0x02, 0xc9, 0xaf, 0xc5, 0xfc, 0xf1, 0xda, 0xfa, 0xa3, 0x81, 0x6e, 0x33, 0x36, - 0x8f, 0xbc, 0xe5, 0x3c, 0xeb, 0x76, 0x0f, 0xca, 0x94, 0x0d, 0x56, 0xa5, 0x69, 0x24, 0x55, 0xc8, - 0x4d, 0x9c, 0xf9, 0x13, 0xd5, 0xe5, 0x0a, 0x20, 0x26, 0x54, 0x96, 0x1c, 0xc3, 0xf8, 0x88, 0x62, - 0x9c, 0xcc, 0x62, 0xf2, 0x02, 0x6a, 0x93, 0x25, 0x17, 0x74, 0x31, 0xbe, 0xa2, 0xd3, 0xc8, 0x28, - 0xc5, 0x69, 0x48, 0xa0, 0xf7, 0x74, 0x1a, 0x91, 0x03, 0xa8, 0x4e, 0x71, 0x8e, 0x02, 0xc7, 0x94, - 0x19, 0x9b, 0x4d, 0xad, 0x55, 0xf1, 0x2a, 0x09, 0xe0, 0x32, 0x72, 0x04, 0x75, 0xca, 0x30, 0xf4, - 0xc5, 0x8c, 0x06, 0xe3, 0xd9, 0xd4, 0x28, 0x27, 0x17, 0x94, 0x61, 0xce, 0xd4, 0xea, 0xc3, 0xee, - 0x3d, 0x19, 0xa9, 0xe0, 0xff, 0x61, 0x13, 0xc3, 0x90, 0x86, 0xa9, 0x8c, 0x24, 0xc8, 0xb1, 0x15, - 0xf2, 0x6c, 0x87, 0x60, 0x0e, 0x97, 0x8c, 0xd1, 0x50, 0xe0, 0xd4, 0x55, 0x38, 0x57, 0x77, 0xeb, - 0xc3, 0xc1, 0xda, 0x6c, 0x7a, 0xea, 0x6b, 0x28, 0x52, 0xc6, 0x0d, 0xad, 0x59, 0x6c, 0xd5, 0x3a, - 0x66, 0x3b, 0xb1, 0x47, 0x3b, 0xbf, 0xc3, 0x93, 0x65, 0xab, 0x1e, 0x0b, 0xf7, 0x7a, 0xb4, 0xe6, - 0x40, 0xf2, 0x1b, 0x88, 0x0e, 0xc5, 0x5b, 0x8c, 0x52, 0x35, 0x72, 0x29, 0x77, 0xdf, 0xf9, 0xf3, - 0xa5, 0x7a, 0x8d, 0x24, 0x20, 0x6d, 0xa8, 0x4c, 0x7c, 0x81, 0xd7, 0x34, 0x8c, 0xe2, 0x97, 0x68, - 0x74, 0x88, 0x6a, 0xc3, 0x65, 0xdd, 0x34, 0xe3, 0x65, 0x35, 0xd6, 0x0e, 0x6c, 0xf7, 0xee, 0x30, - 0x10, 0x99, 0xc2, 0x5f, 0x1a, 0x34, 0x14, 0x92, 0xaa, 0x3a, 0x01, 0x40, 0x89, 0x8c, 0x45, 0xc4, - 0x12, 0x5f, 0x34, 0x3a, 0xbb, 0x8a, 0x35, 0xae, 0x1d, 0x45, 0x0c, 0xbd, 0x2a, 0xaa, 0x25, 0x31, - 0x60, 0x8b, 0x2f, 0x17, 0x0b, 0x3f, 0x8c, 0xd2, 0xee, 0x54, 0x28, 0x33, 0x53, 0x14, 0xfe, 0x6c, - 0xce, 0x53, 0xa3, 0xa8, 0x30, 0xf7, 0x36, 0xa5, 0xdc, 0xdb, 0x1c, 0x7f, 0x06, 0x58, 0x89, 0x20, - 0x35, 0xd8, 0x72, 0x06, 0xc3, 0x91, 0xdd, 0xef, 0xeb, 0x1b, 0x64, 0x0f, 0xc8, 0xd0, 0x3e, 0xbf, - 0xe8, 0xf7, 0xc6, 0xf6, 0xc5, 0x45, 0xdf, 0xe9, 0xda, 0x23, 0xc7, 0x1d, 0xe8, 0x1a, 0xd9, 0x86, - 0x6a, 0xd7, 0x1d, 0x9c, 0x3a, 0x67, 0x97, 0x5e, 0x4f, 0x2f, 0x90, 0x3a, 0x54, 0x3e, 0xda, 0x7d, - 0xe7, 0x83, 0x3d, 0xea, 0xe9, 0x45, 0x02, 0x50, 0xee, 0x5e, 0x0e, 0x47, 0xee, 0xb9, 0x5e, 0x3a, - 0x3e, 0x86, 0x6a, 0x26, 0x85, 0x54, 0xa0, 0xe4, 0x0c, 0x4e, 0x5d, 0x7d, 0x43, 0xae, 0x3e, 0xd9, - 0x9e, 0x64, 0xaa, 0xc2, 0x66, 0xcf, 0xf3, 0x5c, 0x4f, 0x2f, 0x74, 0x7e, 0x17, 0xa1, 0x26, 0x47, - 0x6c, 0x88, 0xe1, 0xdd, 0x6c, 0x82, 0xe4, 0x2b, 0x90, 0xfc, 0x88, 0x92, 0x23, 0x75, 0x45, 0x8f, - 0xfe, 0x0d, 0xa6, 0xf5, 0x54, 0x49, 0x3a, 0xe1, 0x1b, 0xe4, 0x1d, 0x54, 0xd4, 0x40, 0x93, 0xe7, - 0x6a, 0xc7, 0x83, 0xa9, 0x37, 0x8d, 0x7c, 0x22, 0x23, 0x38, 0x83, 0x46, 0x3c, 0x21, 0x2b, 0x3b, - 0x65, 0xd5, 0x0f, 0x3f, 0x00, 0x73, 0x7f, 0x4d, 0x26, 0x23, 0xfa, 0x06, 0xff, 0xad, 0xb1, 0x3f, - 0xb1, 0x1e, 0x77, 0xba, 0xf2, 0x95, 0xf9, 0xf2, 0xc9, 0x9a, 0xec, 0x04, 0x1b, 0xea, 0x43, 0x11, - 0xa2, 0xbf, 0x48, 0x3c, 0x48, 0x9e, 0xfd, 0xe3, 0xb3, 0x8c, 0x6d, 0xef, 0x21, 0xac, 0x08, 0x4e, - 0xb4, 0xab, 0x72, 0xfc, 0x39, 0xbf, 0xf9, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x27, 0xa3, 0x6e, 0x5a, - 0xad, 0x05, 0x00, 0x00, -} From 931aac465432e305a9d575a3788adf7d779aa609 Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Sat, 26 Sep 2020 23:47:42 +0200 Subject: [PATCH 02/16] adding supported operations Signed-off-by: Michael Gfeller --- internal/config/config.go | 5 +-- internal/config/viper.go | 11 +++++-- internal/operations/operations.go | 52 +++++++++++++++++++++++++++++++ main.go | 3 +- 4 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 internal/operations/operations.go diff --git a/internal/config/config.go b/internal/config/config.go index bde18463..3240438f 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1,13 +1,14 @@ package config import ( + "github.com/mgfeller/common-adapter-library/adapter" "github.com/mgfeller/common-adapter-library/config" ) -func New(name string, serverConfig map[string]string, meshConfig map[string]string, providerConfig map[string]string) (config.Handler, error) { +func New(name string, serverConfig map[string]string, meshConfig map[string]string, providerConfig map[string]string, operations adapter.Operations) (config.Handler, error) { switch name { case "viper": - return NewViper(serverConfig, meshConfig, providerConfig) + return NewViper(serverConfig, meshConfig, providerConfig, operations) } return nil, config.ErrEmptyConfig } diff --git a/internal/config/viper.go b/internal/config/viper.go index 2295aab1..b090b724 100644 --- a/internal/config/viper.go +++ b/internal/config/viper.go @@ -1,7 +1,7 @@ package config import ( - "errors" + "github.com/mgfeller/common-adapter-library/adapter" "github.com/mgfeller/common-adapter-library/config" "github.com/spf13/viper" ) @@ -10,13 +10,14 @@ const ( ServerKey = "server" MeshSpecKey = "mesh" MeshInstanceKey = "instance" + OperationsKey = "operations" ) type Viper struct { instance *viper.Viper } -func NewViper(serverConfig map[string]string, meshConfig map[string]string, providerConfig map[string]string) (config.Handler, error) { +func NewViper(serverConfig map[string]string, meshConfig map[string]string, providerConfig map[string]string, operations adapter.Operations) (config.Handler, error) { v := viper.New() v.AddConfigPath(providerConfig["filepath"]) v.SetConfigType(providerConfig["filetype"]) @@ -31,6 +32,10 @@ func NewViper(serverConfig map[string]string, meshConfig map[string]string, prov v.SetDefault(MeshSpecKey+"."+key, value) } + for key, value := range operations { + v.Set(OperationsKey+"."+key, value) + } + if err := viper.ReadInConfig(); err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); ok { // Config file not found; ignore error @@ -65,5 +70,5 @@ func (v *Viper) MeshInstance(result interface{}) error { } func (v *Viper) Operations(result interface{}) error { - return errors.New("config 'operations' not implemented") + return v.instance.Sub(OperationsKey).Unmarshal(result) } diff --git a/internal/operations/operations.go b/internal/operations/operations.go new file mode 100644 index 00000000..0324f1ee --- /dev/null +++ b/internal/operations/operations.go @@ -0,0 +1,52 @@ +package operations + +import ( + "github.com/layer5io/meshery-consul/internal/config" + "github.com/mgfeller/common-adapter-library/adapter" + "github.com/mgfeller/common-adapter-library/meshes" +) + +var ( + Operations = adapter.Operations{ + config.InstallConsulCommand: &adapter.Operation{ + Type: int32(meshes.OpCategory_INSTALL), + Properties: map[string]string{ + "description": "Consul Connect: unsecured, 1 server, suitable for local exploration", + "version": "1.8.2", + "templateName": "consul.yaml", + }, + }, + config.InstallBookInfoCommand: &adapter.Operation{ + Type: int32(meshes.OpCategory_SAMPLE_APPLICATION), + Properties: map[string]string{ + "description": "Istio Book Info Application", + "version": "", + "templateName": "bookinfo.yaml", + }, + }, + config.InstallHTTPBinCommand: &adapter.Operation{ + Type: int32(meshes.OpCategory_SAMPLE_APPLICATION), + Properties: map[string]string{ + "description": "HTTPbin Application", + "version": "", + "templateName": "httpbin-consul.yaml", + }, + }, + config.InstallImageHubCommand: &adapter.Operation{ + Type: int32(meshes.OpCategory_SAMPLE_APPLICATION), + Properties: map[string]string{ + "description": "Image Hub Application", + "version": "", + "templateName": "image-hub.yaml", + }, + }, + config.CustomOpCommand: &adapter.Operation{ + Type: int32(meshes.OpCategory_CUSTOM), + Properties: map[string]string{ + "description": "Custom YAML", + "version": "", + "templateName": "image-hub.yaml", + }, + }, + } +) diff --git a/main.go b/main.go index c5831fd3..d66e7853 100644 --- a/main.go +++ b/main.go @@ -21,6 +21,7 @@ import ( "github.com/layer5io/gokit/utils" "github.com/layer5io/meshery-consul/consul" "github.com/layer5io/meshery-consul/internal/config" + "github.com/layer5io/meshery-consul/internal/operations" "github.com/mgfeller/common-adapter-library/api/grpc" "os" "time" @@ -39,7 +40,7 @@ func main() { os.Exit(1) } - config, err := config.New(configProvider, config.ServerDefaults, config.MeshDefaults, config.ViperDefaults) + config, err := config.New(configProvider, config.ServerDefaults, config.MeshDefaults, config.ViperDefaults, operations.Operations) if err != nil { log.Err("Config Init Failed", err.Error()) os.Exit(1) From 2c8b30b1160129586e8439d7f6cd76bb62d8b4c7 Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Sun, 27 Sep 2020 00:00:16 +0200 Subject: [PATCH 03/16] moved Viper config provider to common library Signed-off-by: Michael Gfeller --- internal/config/config.go | 3 +- internal/config/viper.go | 74 --------------------------------------- 2 files changed, 2 insertions(+), 75 deletions(-) delete mode 100644 internal/config/viper.go diff --git a/internal/config/config.go b/internal/config/config.go index 3240438f..fb912d58 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -3,12 +3,13 @@ package config import ( "github.com/mgfeller/common-adapter-library/adapter" "github.com/mgfeller/common-adapter-library/config" + "github.com/mgfeller/common-adapter-library/config_provider" ) func New(name string, serverConfig map[string]string, meshConfig map[string]string, providerConfig map[string]string, operations adapter.Operations) (config.Handler, error) { switch name { case "viper": - return NewViper(serverConfig, meshConfig, providerConfig, operations) + return config_provider.NewViper(serverConfig, meshConfig, providerConfig, operations) } return nil, config.ErrEmptyConfig } diff --git a/internal/config/viper.go b/internal/config/viper.go deleted file mode 100644 index b090b724..00000000 --- a/internal/config/viper.go +++ /dev/null @@ -1,74 +0,0 @@ -package config - -import ( - "github.com/mgfeller/common-adapter-library/adapter" - "github.com/mgfeller/common-adapter-library/config" - "github.com/spf13/viper" -) - -const ( - ServerKey = "server" - MeshSpecKey = "mesh" - MeshInstanceKey = "instance" - OperationsKey = "operations" -) - -type Viper struct { - instance *viper.Viper -} - -func NewViper(serverConfig map[string]string, meshConfig map[string]string, providerConfig map[string]string, operations adapter.Operations) (config.Handler, error) { - v := viper.New() - v.AddConfigPath(providerConfig["filepath"]) - v.SetConfigType(providerConfig["filetype"]) - v.SetConfigName(providerConfig["filename"]) - v.AutomaticEnv() - - for key, value := range serverConfig { - v.SetDefault(ServerKey+"."+key, value) - } - - for key, value := range meshConfig { - v.SetDefault(MeshSpecKey+"."+key, value) - } - - for key, value := range operations { - v.Set(OperationsKey+"."+key, value) - } - - if err := viper.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - // Config file not found; ignore error - } else { - // Config file was found but another error was produced - return nil, config.ErrViper(err) - } - } - return &Viper{ - instance: v, - }, nil -} - -func (v *Viper) SetKey(key string, value string) { - v.instance.Set(key, value) -} - -func (v *Viper) GetKey(key string) string { - return v.instance.Get(key).(string) -} - -func (v *Viper) Server(result interface{}) error { - return v.instance.Sub(ServerKey).Unmarshal(result) -} - -func (v *Viper) MeshSpec(result interface{}) error { - return v.instance.Sub(MeshSpecKey).Unmarshal(result) -} - -func (v *Viper) MeshInstance(result interface{}) error { - return v.instance.Sub(MeshInstanceKey).Unmarshal(result) -} - -func (v *Viper) Operations(result interface{}) error { - return v.instance.Sub(OperationsKey).Unmarshal(result) -} From d11dc17ce9dd9aa5a6632836cbab4b63484c3fc0 Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Sun, 27 Sep 2020 13:18:14 +0200 Subject: [PATCH 04/16] adding mesh instance config, improving some tests, no goroutine for operation not using goroutine for operation so that error is propagated to the request response. Signed-off-by: Michael Gfeller --- consul/{consul2.go => consul.go} | 0 consul/install.go | 10 ++++++---- consul/operations.go | 21 +++++++++------------ internal/config/config.go | 4 ++-- internal/config/defaults.go | 10 ++++++++-- main.go | 2 +- tests/e2e/ca_install_mesh_tests.bats | 9 +++++++-- 7 files changed, 33 insertions(+), 23 deletions(-) rename consul/{consul2.go => consul.go} (100%) diff --git a/consul/consul2.go b/consul/consul.go similarity index 100% rename from consul/consul2.go rename to consul/consul.go diff --git a/consul/install.go b/consul/install.go index f3a8beb9..8f955d9d 100644 --- a/consul/install.go +++ b/consul/install.go @@ -1,16 +1,18 @@ package consul -import "github.com/mgfeller/common-adapter-library/adapter" +import ( + "errors" + "github.com/mgfeller/common-adapter-library/adapter" +) type MeshInstance struct{} func (m *MeshInstance) applyConsulUsingManifest(doDelete bool) error { - - return nil + return errors.New("not implemented yet") } func (h *ConsulAdapter) installConsul(doDelete bool) (string, error) { - status := "installing" + status := "installing" // TODO: should be type/enum defined in the common adapter library if doDelete { status = "removing" diff --git a/consul/operations.go b/consul/operations.go index 62ed7ff6..60fb8a33 100644 --- a/consul/operations.go +++ b/consul/operations.go @@ -31,18 +31,15 @@ func (h *ConsulAdapter) ApplyOperation(ctx context.Context, op string, id string case config.CustomOpCommand: h.StreamErr(e, adapter.ErrOpInvalid) case config.InstallConsulCommand: - go func(hh *ConsulAdapter, ee *adapter.Event) { - if status, err := hh.installConsul(doDelete); err != nil { - ee.Summary = fmt.Sprintf("Error while %s Consul service mesh", status) - ee.Details = err.Error() - hh.StreamErr(ee, err) - return - } - ee.Summary = fmt.Sprintf("Consul service mesh %s successfully", status) - ee.Details = fmt.Sprintf("The Consul service mesh is now %s.", status) - hh.StreamInfo(ee) - }(h, e) - h.StreamErr(e, adapter.ErrOpInvalid) + if status, err := h.installConsul(doDelete); err != nil { + e.Summary = fmt.Sprintf("Error while %s Consul service mesh", status) + e.Details = err.Error() + h.StreamErr(e, err) + return err + } + e.Summary = fmt.Sprintf("Consul service mesh %s successfully", status) + e.Details = fmt.Sprintf("The Consul service mesh is now %s.", status) + h.StreamInfo(e) case config.InstallHTTPBinCommand: h.StreamErr(e, adapter.ErrOpInvalid) case config.InstallImageHubCommand: diff --git a/internal/config/config.go b/internal/config/config.go index fb912d58..30330b37 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -6,10 +6,10 @@ import ( "github.com/mgfeller/common-adapter-library/config_provider" ) -func New(name string, serverConfig map[string]string, meshConfig map[string]string, providerConfig map[string]string, operations adapter.Operations) (config.Handler, error) { +func New(name string, serverConfig map[string]string, meshSpec map[string]string, meshInstance map[string]string, providerConfig map[string]string, operations adapter.Operations) (config.Handler, error) { switch name { case "viper": - return config_provider.NewViper(serverConfig, meshConfig, providerConfig, operations) + return config_provider.NewViper(serverConfig, meshSpec, meshInstance, providerConfig, operations) } return nil, config.ErrEmptyConfig } diff --git a/internal/config/defaults.go b/internal/config/defaults.go index 4cd7f001..8ce66dac 100644 --- a/internal/config/defaults.go +++ b/internal/config/defaults.go @@ -8,8 +8,14 @@ var ( "version": "v0.1.0", } - MeshDefaults = map[string]string{ - "name": "consul", + MeshSpecDefaults = map[string]string{ + "name": "Consul", + "status": "not installed", // TODO: status should be a type / an enum + "version": "1.8.2", + } + + MeshInstanceDefaults = map[string]string{ + "name": "Consul", "status": "not installed", // TODO: status should be a type / an enum "version": "1.8.2", } diff --git a/main.go b/main.go index d66e7853..16d45305 100644 --- a/main.go +++ b/main.go @@ -40,7 +40,7 @@ func main() { os.Exit(1) } - config, err := config.New(configProvider, config.ServerDefaults, config.MeshDefaults, config.ViperDefaults, operations.Operations) + config, err := config.New(configProvider, config.ServerDefaults, config.MeshSpecDefaults, config.MeshInstanceDefaults, config.ViperDefaults, operations.Operations) if err != nil { log.Err("Config Init Failed", err.Error()) os.Exit(1) diff --git a/tests/e2e/ca_install_mesh_tests.bats b/tests/e2e/ca_install_mesh_tests.bats index 77090f49..c2f24401 100644 --- a/tests/e2e/ca_install_mesh_tests.bats +++ b/tests/e2e/ca_install_mesh_tests.bats @@ -14,8 +14,10 @@ EOT } @test "client instance should be created" { - run bash -c "echo '$CREATE_MESH_REQ_MSG' | grpcurl --plaintext -d @ $MESHERY_ADAPTER_ADDR:10002 meshes.MeshService.CreateMeshInstance" + run bash -c "echo '$CREATE_MESH_REQ_MSG' | grpcurl --plaintext -d @ $MESHERY_ADAPTER_ADDR:10002 meshes.MeshService.CreateMeshInstance | jq ." [ "$status" -eq 0 ] + # this operation returns an empty JSON map. an error will not return a JSON object. + [[ $(echo $output | jq length ) = "0" ]] } @test "consul_install should be successful" { @@ -26,12 +28,15 @@ EOT "username": "", "customBody": "", "deleteOp": false, - "operationId": "" + "operationId": "testid" } EOT ) run bash -c "echo '$INSTALL_CONSUL' | grpcurl --plaintext -d @ $MESHERY_ADAPTER_ADDR:10002 meshes.MeshService.ApplyOperation" [ "$status" -eq 0 ] + # This operation returns a JSON map if successful. An error doesn't return a JSON object, unless the the implementation in + # api/grpc/handlers.go:ApplyOperation is changed (see TODO there). + [[ $(echo $output | jq -j ".operationId") = "testid" ]] } @test "deployment/consul-consul-connect-injector-webhook-deployment should be ready" { From fc6c0818a38e58f9839e4ead482cee73355478c8 Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Tue, 29 Sep 2020 22:47:50 +0200 Subject: [PATCH 05/16] adjusted config provider package name Signed-off-by: Michael Gfeller --- internal/config/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index 30330b37..ec0ce124 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -3,13 +3,13 @@ package config import ( "github.com/mgfeller/common-adapter-library/adapter" "github.com/mgfeller/common-adapter-library/config" - "github.com/mgfeller/common-adapter-library/config_provider" + "github.com/mgfeller/common-adapter-library/configprovider" ) func New(name string, serverConfig map[string]string, meshSpec map[string]string, meshInstance map[string]string, providerConfig map[string]string, operations adapter.Operations) (config.Handler, error) { switch name { case "viper": - return config_provider.NewViper(serverConfig, meshSpec, meshInstance, providerConfig, operations) + return configprovider.NewViper(serverConfig, meshSpec, meshInstance, providerConfig, operations) } return nil, config.ErrEmptyConfig } From f1a34f1f37037e72f1b0fc03479342e589c9e2a7 Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Sat, 3 Oct 2020 18:15:08 +0200 Subject: [PATCH 06/16] change BaseAdapter to Handler; added namespace creation Signed-off-by: Michael Gfeller --- consul/consul.go | 8 ++++---- consul/install.go | 3 ++- consul/operations.go | 21 ++++++++++++++------- main.go | 5 +++-- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/consul/consul.go b/consul/consul.go index 74071376..daa9dd25 100644 --- a/consul/consul.go +++ b/consul/consul.go @@ -6,12 +6,12 @@ import ( "github.com/mgfeller/common-adapter-library/config" ) -type ConsulAdapter struct { - adapter.BaseAdapter +type Handler struct { + adapter.BaseHandler } func New(config config.Handler, log logger.Handler) adapter.Handler { - return &ConsulAdapter{ - adapter.BaseAdapter{Config: config, Log: log}, + return &Handler{ + adapter.BaseHandler{Config: config, Log: log}, } } diff --git a/consul/install.go b/consul/install.go index 8f955d9d..3f1e949c 100644 --- a/consul/install.go +++ b/consul/install.go @@ -2,6 +2,7 @@ package consul import ( "errors" + "github.com/mgfeller/common-adapter-library/adapter" ) @@ -11,7 +12,7 @@ func (m *MeshInstance) applyConsulUsingManifest(doDelete bool) error { return errors.New("not implemented yet") } -func (h *ConsulAdapter) installConsul(doDelete bool) (string, error) { +func (h *Handler) installConsul(doDelete bool) (string, error) { status := "installing" // TODO: should be type/enum defined in the common adapter library if doDelete { diff --git a/consul/operations.go b/consul/operations.go index 60fb8a33..614106c3 100644 --- a/consul/operations.go +++ b/consul/operations.go @@ -3,13 +3,13 @@ package consul import ( "context" "fmt" + "github.com/layer5io/meshery-consul/internal/config" "github.com/mgfeller/common-adapter-library/adapter" ) -func (h *ConsulAdapter) ApplyOperation(ctx context.Context, op string, id string, doDelete bool) error { - - operations := make(adapter.Operations, 0) +func (h *Handler) ApplyOperation(ctx context.Context, request adapter.OperationRequest) error { + operations := make(adapter.Operations) err := h.Config.Operations(&operations) if err != nil { return err @@ -17,21 +17,28 @@ func (h *ConsulAdapter) ApplyOperation(ctx context.Context, op string, id string status := "deploying" e := &adapter.Event{ - Operationid: id, + Operationid: request.OperationID, Summary: "Deploying", Details: "None", } - if doDelete { + if request.IsDeleteOperation { status = "removing" e.Summary = "Removing" } - switch op { + if err := h.CreateNamespace(request.IsDeleteOperation, request.Namespace); err != nil { + e.Summary = "Error while creating namespace" + e.Details = err.Error() + h.StreamErr(e, err) + return err + } + + switch request.OperationName { case config.CustomOpCommand: h.StreamErr(e, adapter.ErrOpInvalid) case config.InstallConsulCommand: - if status, err := h.installConsul(doDelete); err != nil { + if status, err := h.installConsul(request.IsDeleteOperation); err != nil { e.Summary = fmt.Sprintf("Error while %s Consul service mesh", status) e.Details = err.Error() h.StreamErr(e, err) diff --git a/main.go b/main.go index 16d45305..b650e4c6 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,9 @@ package main import ( "fmt" + "os" + "time" + "github.com/layer5io/gokit/errors" "github.com/layer5io/gokit/logger" "github.com/layer5io/gokit/utils" @@ -23,8 +26,6 @@ import ( "github.com/layer5io/meshery-consul/internal/config" "github.com/layer5io/meshery-consul/internal/operations" "github.com/mgfeller/common-adapter-library/api/grpc" - "os" - "time" ) var ( From 12fef408c1fcf725a87debec56b01d77185cb4c3 Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Sat, 3 Oct 2020 18:22:26 +0200 Subject: [PATCH 07/16] deleted unused files - code moved to common library Signed-off-by: Michael Gfeller --- consul/client.go | 116 -------------------------- consul/config_templates/namespace.yml | 5 -- consul/supported_ops.go | 63 -------------- consul/yaml.go | 101 ---------------------- 4 files changed, 285 deletions(-) delete mode 100644 consul/client.go delete mode 100644 consul/config_templates/namespace.yml delete mode 100644 consul/supported_ops.go delete mode 100644 consul/yaml.go diff --git a/consul/client.go b/consul/client.go deleted file mode 100644 index ab04dcf5..00000000 --- a/consul/client.go +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2019 Layer5.io -// -// Licensed 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 consul ... -package consul - -// -//import ( -// "github.com/ghodss/yaml" -// "github.com/layer5io/meshery-consul/meshes" -// "github.com/sirupsen/logrus" -// "k8s.io/client-go/dynamic" -// "k8s.io/client-go/kubernetes" -// -// // auth is needed for initialization only -// _ "k8s.io/client-go/plugin/pkg/client/auth" -// "k8s.io/client-go/rest" -// "k8s.io/client-go/tools/clientcmd" -//) -// -//// Client represents an consul client in Meshery -//type Client struct { -// config *rest.Config -// k8sClientset *kubernetes.Clientset -// k8sDynamicClient dynamic.Interface -// -// eventChan chan *meshes.EventsResponse -//} -// -//func configClient(kubeconfig []byte, contextName string) (*rest.Config, error) { -// if len(kubeconfig) > 0 { -// ccfg, err := clientcmd.Load(kubeconfig) -// if err != nil { -// return nil, err -// } -// if contextName != "" { -// ccfg.CurrentContext = contextName -// } -// -// return clientcmd.NewDefaultClientConfig(*ccfg, &clientcmd.ConfigOverrides{}).ClientConfig() -// } -// return rest.InClusterConfig() -//} -// -//func newClient(kubeconfig []byte, contextName string) (*Client, error) { -// kubeconfig = monkeyPatchingToSupportInsecureConn(kubeconfig) -// client := Client{} -// config, err := configClient(kubeconfig, contextName) -// if err != nil { -// return nil, err -// } -// config.QPS = 100 -// config.Burst = 200 -// -// dynamicClient, err := dynamic.NewForConfig(config) -// if err != nil { -// return nil, err -// } -// client.k8sDynamicClient = dynamicClient -// -// k8sClientset, err := kubernetes.NewForConfig(config) -// if err != nil { -// return nil, err -// } -// client.k8sClientset = k8sClientset -// client.config = config -// -// return &client, nil -//} -// -//func monkeyPatchingToSupportInsecureConn(data []byte) []byte { -// config := map[string]interface{}{} -// if err := yaml.Unmarshal(data, &config); err != nil { -// logrus.Warn(err) -// return data // we will skip this process -// } -// // logrus.Infof("unmarshalled config: %+#v", config) -// clusters, ok := config["clusters"].([]interface{}) -// if !ok { -// logrus.Warn("unable to type cast clusters to a map array") -// return data -// } -// for _, clusterI := range clusters { -// cluster, ok := clusterI.(map[string]interface{}) -// if !ok { -// logrus.Warn("unable to type case individual cluster to a map") -// continue -// } -// indCluster, ok := cluster["cluster"].(map[string]interface{}) -// if !ok { -// logrus.Warn("unable to type case clusters.cluster to a map") -// continue -// } -// indCluster["insecure-skip-tls-verify"] = true // TODO: should we persist this back? -// delete(indCluster, "certificate-authority-data") -// delete(indCluster, "certificate-authority") -// } -// // logrus.Debugf("New config: %+#v", config) -// data1, err := yaml.Marshal(config) -// if err != nil { -// logrus.Warn(err) -// return data -// } -// return data1 -//} diff --git a/consul/config_templates/namespace.yml b/consul/config_templates/namespace.yml deleted file mode 100644 index d510de95..00000000 --- a/consul/config_templates/namespace.yml +++ /dev/null @@ -1,5 +0,0 @@ ---- -apiVersion: v1 -kind: Namespace -metadata: - name: {{.namespace}} diff --git a/consul/supported_ops.go b/consul/supported_ops.go deleted file mode 100644 index 77a6c629..00000000 --- a/consul/supported_ops.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2019 Layer5.io -// -// Licensed 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 consul ... -package consul - -// -//import "github.com/layer5io/meshery-consul/meshes" -// -//type supportedOperation struct { -// // a friendly name -// name string -// // the template file name -// templateName string -// -// opType meshes.OpCategory -//} -// -//const ( -// customOpCommand = "custom" -// installConsulCommand = "consul_install" -// installBookInfoCommand = "install_book_info" -// installHTTPBinCommand = "install_http_bin" -// installImageHubCommand = "install_image_hub" -//) -// -//var supportedOps = map[string]supportedOperation{ -// customOpCommand: { -// name: "Custom YAML", -// opType: meshes.OpCategory_CUSTOM, -// }, -// installConsulCommand: { -// name: "Consul Connect: unsecured, 1 server, suitable for local exploration", -// templateName: "consul.yaml", -// opType: meshes.OpCategory_INSTALL, -// }, -// installBookInfoCommand: { -// name: "Istio Book Info Application", -// templateName: "bookinfo.yaml", -// opType: meshes.OpCategory_SAMPLE_APPLICATION, -// }, -// installHTTPBinCommand: { -// name: "HTTPbin Application", -// templateName: "httpbin-consul.yaml", -// opType: meshes.OpCategory_SAMPLE_APPLICATION, -// }, -// installImageHubCommand: { -// name: "Image Hub Application", -// templateName: "image-hub.yaml", -// opType: meshes.OpCategory_SAMPLE_APPLICATION, -// }, -//} diff --git a/consul/yaml.go b/consul/yaml.go deleted file mode 100644 index 47c51d3a..00000000 --- a/consul/yaml.go +++ /dev/null @@ -1,101 +0,0 @@ -//Package consul ... -package consul - -import ( - "bufio" - "bytes" - "io" -) - -// YAMLDecoder reads chunks of objects and returns ErrShortBuffer if -// the data is not sufficient. -// borrowed from APIMachinery -type YAMLDecoder struct { - r io.ReadCloser - scanner *bufio.Scanner - remaining []byte -} - -// NewDocumentDecoder decodes YAML documents from the provided -// stream in chunks by converting each document (as defined by -// the YAML spec) into its own chunk. io.ErrShortBuffer will be -// returned if the entire buffer could not be read to assist -// the caller in framing the chunk. -func NewDocumentDecoder(r io.ReadCloser) io.ReadCloser { - b := make([]byte, 4096) - scanner := bufio.NewScanner(r) - scanner.Buffer(b, 256*1024) // overriding: the size of the buffer used was small when loading large sections from istio deployment yaml - scanner.Split(splitYAMLDocument) - return &YAMLDecoder{ - r: r, - scanner: scanner, - } -} - -// Read reads the previous slice into the buffer, or attempts to read -// the next chunk. -func (d *YAMLDecoder) Read(data []byte) (n int, err error) { - left := len(d.remaining) - if left == 0 { - // return the next chunk from the stream - if !d.scanner.Scan() { - err := d.scanner.Err() - if err == nil { - err = io.EOF - } - return 0, err - } - out := d.scanner.Bytes() - d.remaining = out - left = len(out) - } - - // fits within data - if left <= len(data) { - copy(data, d.remaining) - d.remaining = nil - return left, nil - } - - // caller will need to reread - copy(data, d.remaining[:len(data)]) - d.remaining = d.remaining[len(data):] - return len(data), io.ErrShortBuffer -} - -// Close closes the decoder -func (d *YAMLDecoder) Close() error { - return d.r.Close() -} - -const yamlSeparator = "\n---" - -// splitYAMLDocument is a bufio.SplitFunc for splitting YAML streams into individual documents. -func splitYAMLDocument(data []byte, atEOF bool) (advance int, token []byte, err error) { - if atEOF && len(data) == 0 { - return 0, nil, nil - } - sep := len([]byte(yamlSeparator)) - if i := bytes.Index(data, []byte(yamlSeparator)); i >= 0 { - // We have a potential document terminator - i += sep - after := data[i:] - if len(after) == 0 { - // we can't read any more characters - if atEOF { - return len(data), data[:len(data)-sep], nil - } - return 0, nil, nil - } - if j := bytes.IndexByte(after, '\n'); j >= 0 { - return i + j + 1, data[0 : i-sep], nil - } - return 0, nil, nil - } - // If we're at EOF, we have a final, non-terminated line. Return it. - if atEOF { - return len(data), data, nil - } - // Request more data. - return 0, nil, nil -} From ee9621d358892eb5bfaf4fe2de98171dff7fd0c6 Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Sun, 4 Oct 2020 12:56:12 +0200 Subject: [PATCH 08/16] implemented installing (and removing) consul using manifest Signed-off-by: Michael Gfeller --- consul/install.go | 16 ++++++++++------ consul/operations.go | 12 +++++++++++- internal/config/keys.go | 4 ++++ internal/operations/operations.go | 30 +++++++++++++++--------------- 4 files changed, 40 insertions(+), 22 deletions(-) diff --git a/consul/install.go b/consul/install.go index 3f1e949c..7346b990 100644 --- a/consul/install.go +++ b/consul/install.go @@ -1,21 +1,25 @@ package consul import ( - "errors" + "path" + + "github.com/layer5io/meshery-consul/internal/config" "github.com/mgfeller/common-adapter-library/adapter" ) type MeshInstance struct{} -func (m *MeshInstance) applyConsulUsingManifest(doDelete bool) error { - return errors.New("not implemented yet") +func (m *MeshInstance) applyConsulUsingManifest(request adapter.OperationRequest, operation *adapter.Operation, h *Handler) error { + err := h.ApplyKubernetesManifest(request, *operation, map[string]string{}, + path.Join("consul", "config_templates", operation.Properties[config.OperationTemplateNameKey])) + return err } -func (h *Handler) installConsul(doDelete bool) (string, error) { +func (h *Handler) applyConsulUsingManifest(request adapter.OperationRequest, operation *adapter.Operation) (string, error) { status := "installing" // TODO: should be type/enum defined in the common adapter library - if doDelete { + if request.IsDeleteOperation { status = "removing" } @@ -27,7 +31,7 @@ func (h *Handler) installConsul(doDelete bool) (string, error) { } h.Log.Info("Installing Consul") - err = meshInstance.applyConsulUsingManifest(doDelete) + err = meshInstance.applyConsulUsingManifest(request, operation, h) if err != nil { h.Log.Err("Consul installation failed", adapter.ErrInstallMesh(err).Error()) return status, adapter.ErrInstallMesh(err) diff --git a/consul/operations.go b/consul/operations.go index 614106c3..023b07ec 100644 --- a/consul/operations.go +++ b/consul/operations.go @@ -2,6 +2,7 @@ package consul import ( "context" + "errors" "fmt" "github.com/layer5io/meshery-consul/internal/config" @@ -34,11 +35,20 @@ func (h *Handler) ApplyOperation(ctx context.Context, request adapter.OperationR return err } + operation, ok := operations[request.OperationName] + if !ok { + e.Summary = "Error unknown operation name" + err = errors.New(e.Summary) + e.Details = err.Error() + h.StreamErr(e, err) + return err + } + switch request.OperationName { case config.CustomOpCommand: h.StreamErr(e, adapter.ErrOpInvalid) case config.InstallConsulCommand: - if status, err := h.installConsul(request.IsDeleteOperation); err != nil { + if status, err := h.applyConsulUsingManifest(request, operation); err != nil { e.Summary = fmt.Sprintf("Error while %s Consul service mesh", status) e.Details = err.Error() h.StreamErr(e, err) diff --git a/internal/config/keys.go b/internal/config/keys.go index 318eec55..0d1423c0 100644 --- a/internal/config/keys.go +++ b/internal/config/keys.go @@ -6,4 +6,8 @@ const ( InstallBookInfoCommand = "install_book_info" InstallHTTPBinCommand = "install_http_bin" InstallImageHubCommand = "install_image_hub" + + OperationDescriptionKey = "description" + OperationVersionKey = "version" + OperationTemplateNameKey = "templateName" ) diff --git a/internal/operations/operations.go b/internal/operations/operations.go index 0324f1ee..00382397 100644 --- a/internal/operations/operations.go +++ b/internal/operations/operations.go @@ -11,41 +11,41 @@ var ( config.InstallConsulCommand: &adapter.Operation{ Type: int32(meshes.OpCategory_INSTALL), Properties: map[string]string{ - "description": "Consul Connect: unsecured, 1 server, suitable for local exploration", - "version": "1.8.2", - "templateName": "consul.yaml", + config.OperationDescriptionKey: "Consul Connect: unsecured, 1 server, suitable for local exploration", + config.OperationVersionKey: "1.8.2", + config.OperationTemplateNameKey: "consul.yaml", }, }, config.InstallBookInfoCommand: &adapter.Operation{ Type: int32(meshes.OpCategory_SAMPLE_APPLICATION), Properties: map[string]string{ - "description": "Istio Book Info Application", - "version": "", - "templateName": "bookinfo.yaml", + config.OperationDescriptionKey: "Istio Book Info Application", + config.OperationVersionKey: "", + config.OperationTemplateNameKey: "bookinfo.yaml", }, }, config.InstallHTTPBinCommand: &adapter.Operation{ Type: int32(meshes.OpCategory_SAMPLE_APPLICATION), Properties: map[string]string{ - "description": "HTTPbin Application", - "version": "", - "templateName": "httpbin-consul.yaml", + config.OperationDescriptionKey: "HTTPbin Application", + config.OperationVersionKey: "", + config.OperationTemplateNameKey: "httpbin-consul.yaml", }, }, config.InstallImageHubCommand: &adapter.Operation{ Type: int32(meshes.OpCategory_SAMPLE_APPLICATION), Properties: map[string]string{ - "description": "Image Hub Application", - "version": "", - "templateName": "image-hub.yaml", + config.OperationDescriptionKey: "Image Hub Application", + config.OperationVersionKey: "", + config.OperationTemplateNameKey: "image-hub.yaml", }, }, config.CustomOpCommand: &adapter.Operation{ Type: int32(meshes.OpCategory_CUSTOM), Properties: map[string]string{ - "description": "Custom YAML", - "version": "", - "templateName": "image-hub.yaml", + config.OperationDescriptionKey: "Custom YAML", + config.OperationVersionKey: "", + config.OperationTemplateNameKey: "image-hub.yaml", }, }, } From f79404c4029d53bca18faecc3c021003c58b63b4 Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Sun, 4 Oct 2020 21:26:40 +0200 Subject: [PATCH 09/16] implemented all existing operations; all BATS tests pass no custom operation yet, and no test Signed-off-by: Michael Gfeller --- consul/install.go | 15 ++++++++------- consul/operations.go | 25 ++++++++++--------------- internal/config/defaults.go | 4 ++-- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/consul/install.go b/consul/install.go index 7346b990..af90645d 100644 --- a/consul/install.go +++ b/consul/install.go @@ -1,6 +1,7 @@ package consul import ( + "fmt" "path" "github.com/layer5io/meshery-consul/internal/config" @@ -10,14 +11,14 @@ import ( type MeshInstance struct{} -func (m *MeshInstance) applyConsulUsingManifest(request adapter.OperationRequest, operation *adapter.Operation, h *Handler) error { - err := h.ApplyKubernetesManifest(request, *operation, map[string]string{}, +func (m *MeshInstance) applyUsingManifest(request adapter.OperationRequest, operation *adapter.Operation, h *Handler) error { + err := h.ApplyKubernetesManifest(request, *operation, map[string]string{"namespace": request.Namespace}, path.Join("consul", "config_templates", operation.Properties[config.OperationTemplateNameKey])) return err } -func (h *Handler) applyConsulUsingManifest(request adapter.OperationRequest, operation *adapter.Operation) (string, error) { - status := "installing" // TODO: should be type/enum defined in the common adapter library +func (h *Handler) applyUsingManifest(request adapter.OperationRequest, operation *adapter.Operation) (string, error) { + status := "installing" // TODO: should be enum defined in the common adapter library if request.IsDeleteOperation { status = "removing" @@ -30,10 +31,10 @@ func (h *Handler) applyConsulUsingManifest(request adapter.OperationRequest, ope return status, adapter.ErrMeshConfig(err) } - h.Log.Info("Installing Consul") - err = meshInstance.applyConsulUsingManifest(request, operation, h) + h.Log.Info(fmt.Sprintf("%s %s", status, operation.Properties[config.OperationDescriptionKey])) + err = meshInstance.applyUsingManifest(request, operation, h) if err != nil { - h.Log.Err("Consul installation failed", adapter.ErrInstallMesh(err).Error()) + h.Log.Err(fmt.Sprintf("Error: %s %s failed", status, operation.Properties[config.OperationDescriptionKey]), adapter.ErrInstallMesh(err).Error()) return status, adapter.ErrInstallMesh(err) } diff --git a/consul/operations.go b/consul/operations.go index 023b07ec..7400418d 100644 --- a/consul/operations.go +++ b/consul/operations.go @@ -2,7 +2,6 @@ package consul import ( "context" - "errors" "fmt" "github.com/layer5io/meshery-consul/internal/config" @@ -38,31 +37,27 @@ func (h *Handler) ApplyOperation(ctx context.Context, request adapter.OperationR operation, ok := operations[request.OperationName] if !ok { e.Summary = "Error unknown operation name" - err = errors.New(e.Summary) + err = adapter.ErrOpInvalid e.Details = err.Error() h.StreamErr(e, err) return err } switch request.OperationName { - case config.CustomOpCommand: - h.StreamErr(e, adapter.ErrOpInvalid) - case config.InstallConsulCommand: - if status, err := h.applyConsulUsingManifest(request, operation); err != nil { - e.Summary = fmt.Sprintf("Error while %s Consul service mesh", status) + case config.CustomOpCommand, // TODO: implement custom op and test for it + config.InstallConsulCommand, + config.InstallHTTPBinCommand, + config.InstallImageHubCommand, + config.InstallBookInfoCommand: + if status, err := h.applyUsingManifest(request, operation); err != nil { + e.Summary = fmt.Sprintf("Error while %s %s", status, operation.Properties[config.OperationDescriptionKey]) e.Details = err.Error() h.StreamErr(e, err) return err } - e.Summary = fmt.Sprintf("Consul service mesh %s successfully", status) - e.Details = fmt.Sprintf("The Consul service mesh is now %s.", status) + e.Summary = fmt.Sprintf("%s %s successfully", operation.Properties[config.OperationDescriptionKey], status) + e.Details = fmt.Sprintf("%s is now %s.", operation.Properties[config.OperationDescriptionKey], status) h.StreamInfo(e) - case config.InstallHTTPBinCommand: - h.StreamErr(e, adapter.ErrOpInvalid) - case config.InstallImageHubCommand: - h.StreamErr(e, adapter.ErrOpInvalid) - case config.InstallBookInfoCommand: - h.StreamErr(e, adapter.ErrOpInvalid) default: h.StreamErr(e, adapter.ErrOpInvalid) } diff --git a/internal/config/defaults.go b/internal/config/defaults.go index 8ce66dac..87c1305d 100644 --- a/internal/config/defaults.go +++ b/internal/config/defaults.go @@ -10,13 +10,13 @@ var ( MeshSpecDefaults = map[string]string{ "name": "Consul", - "status": "not installed", // TODO: status should be a type / an enum + "status": "not installed", // TODO: status should be an enum "version": "1.8.2", } MeshInstanceDefaults = map[string]string{ "name": "Consul", - "status": "not installed", // TODO: status should be a type / an enum + "status": "not installed", // TODO: status should be an enum "version": "1.8.2", } From 92a49cecae2b1d41b247e50639c4b09f02b3c619 Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Tue, 6 Oct 2020 22:21:24 +0200 Subject: [PATCH 10/16] changing to layer5io/meshery-adapter-library Signed-off-by: Michael Gfeller --- consul/consul.go | 4 +- consul/consul_orig.go | 597 ------------------------------ consul/install.go | 2 +- consul/operations.go | 2 +- go.mod | 5 +- go.sum | 2 + internal/config/config.go | 6 +- internal/operations/operations.go | 4 +- main.go | 2 +- 9 files changed, 14 insertions(+), 610 deletions(-) delete mode 100644 consul/consul_orig.go diff --git a/consul/consul.go b/consul/consul.go index daa9dd25..6bed60e7 100644 --- a/consul/consul.go +++ b/consul/consul.go @@ -2,8 +2,8 @@ package consul import ( "github.com/layer5io/gokit/logger" - "github.com/mgfeller/common-adapter-library/adapter" - "github.com/mgfeller/common-adapter-library/config" + "github.com/layer5io/meshery-adapter-library/adapter" + "github.com/layer5io/meshery-adapter-library/config" ) type Handler struct { diff --git a/consul/consul_orig.go b/consul/consul_orig.go deleted file mode 100644 index 60d40672..00000000 --- a/consul/consul_orig.go +++ /dev/null @@ -1,597 +0,0 @@ -// Copyright 2019 Layer5.io -// -// Licensed 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 consul ... -package consul - -//import ( -// "bytes" -// "context" -// "fmt" -// "html/template" -// "io" -// "io/ioutil" -// "path" -// "time" -// -// "strings" -// -// "github.com/ghodss/yaml" -// "github.com/layer5io/meshery-consul/meshes" -// "github.com/pkg/errors" -// "github.com/sirupsen/logrus" -// metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -// "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" -// "k8s.io/apimachinery/pkg/runtime" -// "k8s.io/apimachinery/pkg/runtime/schema" -//) -// -////CreateMeshInstance instantiates a new instance of Consul in a Kubernetes cluster. -//func (iClient *Client) CreateMeshInstance(_ context.Context, k8sReq *meshes.CreateMeshInstanceRequest) (*meshes.CreateMeshInstanceResponse, error) { -// var k8sConfig []byte -// contextName := "" -// if k8sReq != nil { -// k8sConfig = k8sReq.K8SConfig -// contextName = k8sReq.ContextName -// } -// logrus.Debugf("received contextName: %s", contextName) -// -// ic, err := newClient(k8sConfig, contextName) -// if err != nil { -// err = errors.Wrapf(err, "unable to create a new istio client") -// logrus.Error(err) -// return nil, err -// } -// iClient.k8sClientset = ic.k8sClientset -// iClient.k8sDynamicClient = ic.k8sDynamicClient -// iClient.eventChan = make(chan *meshes.EventsResponse, 100) -// iClient.config = ic.config -// -// return &meshes.CreateMeshInstanceResponse{}, nil -//} -// -//// MeshName just returns the name of the mesh the client is representing -//func (iClient *Client) MeshName(context.Context, *meshes.MeshNameRequest) (*meshes.MeshNameResponse, error) { -// return &meshes.MeshNameResponse{Name: "Consul"}, nil -//} -// -//func (iClient *Client) createResource(ctx context.Context, res schema.GroupVersionResource, data *unstructured.Unstructured) error { -// _, err := iClient.k8sDynamicClient.Resource(res).Namespace(data.GetNamespace()).Create(data, metav1.CreateOptions{}) -// if err != nil { -// err = errors.Wrapf(err, "unable to create the requested resource, attempting operation without namespace") -// logrus.Warn(err) -// _, err = iClient.k8sDynamicClient.Resource(res).Create(data, metav1.CreateOptions{}) -// if err != nil { -// err = errors.Wrapf(err, "unable to create the requested resource, attempting to update") -// logrus.Error(err) -// return err -// } -// } -// logrus.Infof("Created Resource of type: %s and name: %s", data.GetKind(), data.GetName()) -// return nil -//} -// -//func (iClient *Client) deleteResource(ctx context.Context, res schema.GroupVersionResource, data *unstructured.Unstructured) error { -// if iClient.k8sDynamicClient == nil { -// return errors.New("mesh client has not been created") -// } -// -// if res.Resource == "namespaces" && data.GetName() == "default" { // skipping deletion of default namespace -// return nil -// } -// -// // in the case with deployments, have to scale it down to 0 first and then delete. . . or else RS and pods will be left behind -// if res.Resource == "deployments" { -// data1, err := iClient.getResource(ctx, res, data) -// if err != nil { -// return err -// } -// depl := data1.UnstructuredContent() -// spec1 := depl["spec"].(map[string]interface{}) -// spec1["replicas"] = 0 -// data1.SetUnstructuredContent(depl) -// if err = iClient.updateResource(ctx, res, data1); err != nil { -// return err -// } -// } -// -// err := iClient.k8sDynamicClient.Resource(res).Namespace(data.GetNamespace()).Delete(data.GetName(), &metav1.DeleteOptions{}) -// if err != nil { -// err = errors.Wrapf(err, "unable to delete the requested resource, attempting operation without namespace") -// logrus.Warn(err) -// -// err := iClient.k8sDynamicClient.Resource(res).Delete(data.GetName(), &metav1.DeleteOptions{}) -// if err != nil { -// err = errors.Wrapf(err, "unable to delete the requested resource") -// logrus.Error(err) -// return err -// } -// } -// logrus.Infof("Deleted Resource of type: %s and name: %s", data.GetKind(), data.GetName()) -// return nil -//} -// -//func (iClient *Client) getResource(ctx context.Context, res schema.GroupVersionResource, data *unstructured.Unstructured) (*unstructured.Unstructured, error) { -// data1, err := iClient.k8sDynamicClient.Resource(res).Namespace(data.GetNamespace()).Get(data.GetName(), metav1.GetOptions{}) -// if err != nil { -// err = errors.Wrap(err, "unable to retrieve the resource with a matching name, attempting operation without namespace") -// logrus.Warn(err) -// -// data1, err = iClient.k8sDynamicClient.Resource(res).Get(data.GetName(), metav1.GetOptions{}) -// if err != nil { -// err = errors.Wrap(err, "unable to retrieve the resource with a matching name, while attempting to apply the config") -// logrus.Error(err) -// return nil, err -// } -// } -// logrus.Infof("Retrieved Resource of type: %s and name: %s", data.GetKind(), data.GetName()) -// return data1, nil -//} -// -//func (iClient *Client) updateResource(ctx context.Context, res schema.GroupVersionResource, data *unstructured.Unstructured) error { -// if _, err := iClient.k8sDynamicClient.Resource(res).Namespace(data.GetNamespace()).Update(data, metav1.UpdateOptions{}); err != nil { -// err = errors.Wrap(err, "unable to update resource with the given name, attempting operation without namespace") -// logrus.Warn(err) -// -// if _, err = iClient.k8sDynamicClient.Resource(res).Update(data, metav1.UpdateOptions{}); err != nil { -// err = errors.Wrap(err, "unable to update resource with the given name, while attempting to apply the config") -// logrus.Error(err) -// return err -// } -// } -// logrus.Infof("Updated Resource of type: %s and name: %s", data.GetKind(), data.GetName()) -// return nil -//} -// -//func (iClient *Client) applyConfigChange(ctx context.Context, yamlFileContents, namespace string, delete, isCustomOp bool) error { -// yamls, err := iClient.splitYAML(yamlFileContents) -// if err != nil { -// err = errors.Wrap(err, "error while splitting yaml") -// logrus.Error(err) -// return err -// } -// for _, yml := range yamls { -// if strings.TrimSpace(yml) != "" { -// if err := iClient.applyRulePayload(ctx, namespace, []byte(yml), delete, isCustomOp); err != nil { -// errStr := strings.TrimSpace(err.Error()) -// if delete { -// if strings.HasSuffix(errStr, "not found") || -// strings.HasSuffix(errStr, "the server could not find the requested resource") { -// // logrus.Debugf("skipping error. . .") -// continue -// } -// } else { -// if strings.HasSuffix(errStr, "already exists") { -// continue -// } -// } -// // logrus.Debugf("returning error: %v", err) -// return err -// } -// } -// } -// return nil -//} -// -//func (iClient *Client) applyRulePayload(ctx context.Context, namespace string, newBytes []byte, delete, isCustomOp bool) error { -// if iClient.k8sDynamicClient == nil { -// return errors.New("mesh client has not been created") -// } -// // logrus.Debugf("received yaml bytes: %s", newBytes) -// jsonBytes, err := yaml.YAMLToJSON(newBytes) -// if err != nil { -// err = errors.Wrapf(err, "unable to convert yaml to json") -// logrus.Error(err) -// return err -// } -// // logrus.Debugf("created json: %s, length: %d", jsonBytes, len(jsonBytes)) -// if len(jsonBytes) > 5 { // attempting to skip 'null' json -// data := &unstructured.Unstructured{} -// err = data.UnmarshalJSON(jsonBytes) -// if err != nil { -// err = errors.Wrapf(err, "unable to unmarshal json created from yaml") -// logrus.Error(err) -// return err -// } -// if data.IsList() { -// err = data.EachListItem(func(r runtime.Object) error { -// dataL, _ := r.(*unstructured.Unstructured) -// return iClient.executeRule(ctx, dataL, namespace, delete, isCustomOp) -// }) -// return err -// } -// return iClient.executeRule(ctx, data, namespace, delete, isCustomOp) -// } -// return nil -//} -// -//func (iClient *Client) executeRule(ctx context.Context, data *unstructured.Unstructured, namespace string, delete, isCustomOp bool) error { -// // logrus.Debug("========================================================") -// // logrus.Debugf("Received data: %+#v", data) -// if namespace != "" { -// data.SetNamespace(namespace) -// } -// groupVersion := strings.Split(data.GetAPIVersion(), "/") -// logrus.Debugf("groupVersion: %v", groupVersion) -// var group, version string -// if len(groupVersion) == 2 { -// group = groupVersion[0] -// version = groupVersion[1] -// } else if len(groupVersion) == 1 { -// version = groupVersion[0] -// } -// -// kind := strings.ToLower(data.GetKind()) -// switch kind { -// case "logentry": -// kind = "logentries" -// case "kubernetes": -// kind = "kuberneteses" -// default: -// kind += "s" -// } -// -// res := schema.GroupVersionResource{ -// Group: group, -// Version: version, -// Resource: kind, -// } -// logrus.Debugf("Computed Resource: %+#v", res) -// -// if delete { -// return iClient.deleteResource(ctx, res, data) -// } -// -// if err := iClient.createResource(ctx, res, data); err != nil { -// if isCustomOp { -// if err := iClient.deleteResource(ctx, res, data); err != nil { -// return err -// } -// time.Sleep(time.Second) -// if err := iClient.createResource(ctx, res, data); err != nil { -// return err -// } -// // data1, err := iClient.getResource(ctx, res, data) -// // if err != nil { -// // return err -// // } -// // if err = iClient.updateResource(ctx, res, data1); err != nil { -// // return err -// // } -// } else { -// return err -// } -// } -// return nil -//} -// -//func (iClient *Client) executeTemplate(ctx context.Context, username, namespace, templateName string) (string, error) { -// tmpl, err := template.ParseFiles(path.Join("consul", "config_templates", templateName)) -// if err != nil { -// err = errors.Wrapf(err, "unable to parse template") -// logrus.Error(err) -// return "", err -// } -// buf := bytes.NewBufferString("") -// err = tmpl.Execute(buf, map[string]string{ -// "user_name": username, -// "namespace": namespace, -// }) -// if err != nil { -// err = errors.Wrapf(err, "unable to execute template") -// logrus.Error(err) -// return "", err -// } -// return buf.String(), nil -//} -// -//func (iClient *Client) createNamespace(ctx context.Context, namespace string) error { -// logrus.Debugf("creating namespace: %s", namespace) -// yamlFileContents, err := iClient.executeTemplate(ctx, "", namespace, "namespace.yml") -// if err != nil { -// return err -// } -// if err := iClient.applyConfigChange(ctx, yamlFileContents, namespace, false, false); err != nil { -// return err -// } -// return nil -//} -// -//// ApplyOperation is a method invoked to apply a particular operation on the mesh in a namespace -//func (iClient *Client) ApplyOperation(ctx context.Context, arReq *meshes.ApplyRuleRequest) (*meshes.ApplyRuleResponse, error) { -// if arReq == nil { -// return nil, errors.New("mesh client has not been created") -// } -// -// op, ok := supportedOps[arReq.OpName] -// if !ok { -// return nil, fmt.Errorf("operation id: %s, error: %s is not a valid operation name", arReq.OperationId, arReq.OpName) -// } -// -// if arReq.OpName == customOpCommand && arReq.CustomBody == "" { -// return nil, fmt.Errorf("operation id: %s, error: yaml body is empty for %s operation", arReq.OperationId, arReq.OpName) -// } -// -// var yamlFileContents string -// var err error -// isCustomOp := false -// -// if !arReq.DeleteOp && arReq.Namespace != "default" { -// if err := iClient.createNamespace(ctx, arReq.Namespace); err != nil { -// logrus.Error(err) -// return nil, err -// } -// } -// -// var svcName, appName string -// -// switch arReq.OpName { -// case customOpCommand: -// yamlFileContents = arReq.CustomBody -// isCustomOp = true -// -// case installBookInfoCommand: -// svcName = "productpage" -// appName = "Book info" -// fallthrough -// case installHTTPBinCommand: -// if svcName == "" { -// svcName = "httpbin" -// appName = "HTTP Bin" -// } -// yamlFileContents, err = iClient.executeTemplate(ctx, arReq.Username, arReq.Namespace, op.templateName) -// if err != nil { -// return nil, err -// } -// go func() { -// opName1 := "deploying" -// if arReq.DeleteOp { -// opName1 = "removing" -// } -// -// if err := iClient.applyConfigChange(ctx, yamlFileContents, arReq.Namespace, arReq.DeleteOp, isCustomOp); err != nil { -// iClient.eventChan <- &meshes.EventsResponse{ -// OperationId: arReq.OperationId, -// EventType: meshes.EventType_ERROR, -// Summary: fmt.Sprintf("Error while %s %s app", opName1, appName), -// Details: err.Error(), -// } -// return -// } -// -// opName := "deployed" -// ports := []int64{} -// if arReq.DeleteOp { -// opName = "removed" -// } else { -// var err error -// ports, err = iClient.getSVCPort(ctx, svcName, arReq.Namespace) -// if err != nil { -// iClient.eventChan <- &meshes.EventsResponse{ -// OperationId: arReq.OperationId, -// EventType: meshes.EventType_WARN, -// Summary: fmt.Sprintf("%s app is deployed but unable to retrieve the port info for the service at the moment", appName), -// Details: err.Error(), -// } -// return -// } -// } -// var portMsg string -// if len(ports) == 1 { -// portMsg = fmt.Sprintf("The service is possibly available on port: %v", ports) -// } else if len(ports) > 1 { -// portMsg = fmt.Sprintf("The service is possibly available on one of the following ports: %v", ports) -// } -// msg := fmt.Sprintf("%s app is now %s. %s", appName, opName, portMsg) -// -// iClient.eventChan <- &meshes.EventsResponse{ -// OperationId: arReq.OperationId, -// EventType: meshes.EventType_INFO, -// Summary: fmt.Sprintf("%s %s successfully", appName, opName), -// Details: msg, -// } -// }() -// return &meshes.ApplyRuleResponse{ -// OperationId: arReq.OperationId, -// }, nil -// case installImageHubCommand: -// if svcName == "" { -// svcName = "ingess" -// appName = "Image Hub" -// } -// yamlFileContents, err = iClient.executeTemplate(ctx, arReq.Username, arReq.Namespace, op.templateName) -// if err != nil { -// return nil, err -// } -// go func() { -// opName1 := "deploying" -// if arReq.DeleteOp { -// opName1 = "removing" -// } -// -// if err := iClient.applyConfigChange(ctx, yamlFileContents, arReq.Namespace, arReq.DeleteOp, isCustomOp); err != nil { -// iClient.eventChan <- &meshes.EventsResponse{ -// OperationId: arReq.OperationId, -// EventType: meshes.EventType_ERROR, -// Summary: fmt.Sprintf("Error while %s %s app", opName1, appName), -// Details: err.Error(), -// } -// return -// } -// -// opName := "deployed" -// ports := []int64{} -// if arReq.DeleteOp { -// opName = "removed" -// } else { -// var err error -// ports, err = iClient.getSVCPort(ctx, svcName, arReq.Namespace) -// if err != nil { -// iClient.eventChan <- &meshes.EventsResponse{ -// OperationId: arReq.OperationId, -// EventType: meshes.EventType_WARN, -// Summary: fmt.Sprintf("%s app is deployed but unable to retrieve the port info for the service at the moment", appName), -// Details: err.Error(), -// } -// return -// } -// } -// var portMsg string -// if len(ports) == 1 { -// portMsg = fmt.Sprintf("The service is possibly available on port: %v", ports) -// } else if len(ports) > 1 { -// portMsg = fmt.Sprintf("The service is possibly available on one of the following ports: %v", ports) -// } -// msg := fmt.Sprintf("%s app is now %s. %s", appName, opName, portMsg) -// -// iClient.eventChan <- &meshes.EventsResponse{ -// OperationId: arReq.OperationId, -// EventType: meshes.EventType_INFO, -// Summary: fmt.Sprintf("%s %s successfully", appName, opName), -// Details: msg, -// } -// }() -// return &meshes.ApplyRuleResponse{ -// OperationId: arReq.OperationId, -// }, nil -// // case installConsulCommand: -// // yamlFileContents = op.templateName -// // fallthrough -// default: -// yamlFileContents, err = iClient.executeTemplate(ctx, arReq.Username, arReq.Namespace, op.templateName) -// if err != nil { -// return nil, err -// } -// } -// -// if err := iClient.applyConfigChange(ctx, yamlFileContents, arReq.Namespace, arReq.DeleteOp, isCustomOp); err != nil { -// return nil, err -// } -// -// return &meshes.ApplyRuleResponse{ -// OperationId: arReq.OperationId, -// }, nil -//} -// -//// SupportedOperations - returns a list of supported operations on the mesh -//func (iClient *Client) SupportedOperations(context.Context, *meshes.SupportedOperationsRequest) (*meshes.SupportedOperationsResponse, error) { -// supportedOpsCount := len(supportedOps) -// result := make([]*meshes.SupportedOperation, supportedOpsCount) -// i := 0 -// for k, sp := range supportedOps { -// result[i] = &meshes.SupportedOperation{ -// Key: k, -// Value: sp.name, -// Category: sp.opType, -// } -// i++ -// } -// return &meshes.SupportedOperationsResponse{ -// Ops: result, -// }, nil -//} -// -//// StreamEvents - streams generated/collected events to the client -//func (iClient *Client) StreamEvents(in *meshes.EventsRequest, stream meshes.MeshService_StreamEventsServer) error { -// for { -// select { -// case event := <-iClient.eventChan: -// logrus.Debugf("sending event: %+#v", event) -// if err := stream.Send(event); err != nil { -// err = errors.Wrapf(err, "unable to send event") -// -// // to prevent loosing the event, will re-add to the channel -// go func() { -// iClient.eventChan <- event -// }() -// logrus.Error(err) -// return err -// } -// default: -// } -// time.Sleep(500 * time.Millisecond) -// } -//} -// -//func (iClient *Client) splitYAML(yamlContents string) ([]string, error) { -// yamlDecoder, ok := NewDocumentDecoder(ioutil.NopCloser(bytes.NewReader([]byte(yamlContents)))).(*YAMLDecoder) -// if !ok { -// err := fmt.Errorf("unable to create a yaml decoder") -// logrus.Error(err) -// return nil, err -// } -// defer func() { -// if err := yamlDecoder.Close(); err != nil { -// logrus.Error(err) -// } -// }() -// var err error -// n := 0 -// data := [][]byte{} -// ind := 0 -// for err == io.ErrShortBuffer || err == nil { -// // for { -// d := make([]byte, 1000) -// n, err = yamlDecoder.Read(d) -// // logrus.Debugf("Read this: %s, count: %d, err: %v", d, n, err) -// if len(data) == 0 || len(data) <= ind { -// data = append(data, []byte{}) -// } -// if n > 0 { -// data[ind] = append(data[ind], d...) -// } -// if err == nil { -// logrus.Debugf("..............BOUNDARY................") -// ind++ -// } -// } -// result := make([]string, len(data)) -// for i, row := range data { -// r := string(row) -// r = strings.Trim(r, "\x00") -// logrus.Debugf("ind: %d, data: %s", i, r) -// result[i] = r -// } -// return result, nil -//} -// -//func (iClient *Client) getSVCPort(ctx context.Context, svc, namespace string) ([]int64, error) { -// ns := &unstructured.Unstructured{} -// res := schema.GroupVersionResource{ -// Version: "v1", -// Resource: "services", -// } -// ns.SetName(svc) -// ns.SetNamespace(namespace) -// ns, err := iClient.getResource(ctx, res, ns) -// if err != nil { -// err = errors.Wrapf(err, "unable to get service details") -// logrus.Error(err) -// return nil, err -// } -// svcInst := ns.UnstructuredContent() -// spec := svcInst["spec"].(map[string]interface{}) -// ports, _ := spec["ports"].([]interface{}) -// nodePorts := []int64{} -// for _, port := range ports { -// p, _ := port.(map[string]interface{}) -// np, ok := p["nodePort"] -// if ok { -// npi, _ := np.(int64) -// nodePorts = append(nodePorts, npi) -// } -// } -// logrus.Debugf("retrieved svc: %+#v", ns) -// return nodePorts, nil -//} diff --git a/consul/install.go b/consul/install.go index af90645d..c1dbe129 100644 --- a/consul/install.go +++ b/consul/install.go @@ -6,7 +6,7 @@ import ( "github.com/layer5io/meshery-consul/internal/config" - "github.com/mgfeller/common-adapter-library/adapter" + "github.com/layer5io/meshery-adapter-library/adapter" ) type MeshInstance struct{} diff --git a/consul/operations.go b/consul/operations.go index 7400418d..34b0a73d 100644 --- a/consul/operations.go +++ b/consul/operations.go @@ -4,8 +4,8 @@ import ( "context" "fmt" + "github.com/layer5io/meshery-adapter-library/adapter" "github.com/layer5io/meshery-consul/internal/config" - "github.com/mgfeller/common-adapter-library/adapter" ) func (h *Handler) ApplyOperation(ctx context.Context, request adapter.OperationRequest) error { diff --git a/go.mod b/go.mod index 07ec1dea..b9fbe428 100644 --- a/go.mod +++ b/go.mod @@ -2,12 +2,11 @@ module github.com/layer5io/meshery-consul go 1.13 -replace github.com/mgfeller/common-adapter-library => ../common-adapter-library +replace github.com/layer5io/meshery-adapter-library => ../meshery-adapter-library require ( github.com/googleapis/gnostic v0.3.1 // indirect github.com/layer5io/gokit v0.1.12 - github.com/mgfeller/common-adapter-library v0.0.0-20200922065641-284f3e2e9db4 - github.com/spf13/viper v1.7.1 + github.com/layer5io/meshery-adapter-library v0.0.0-20201005203405-4c01118f7bcc google.golang.org/grpc v1.32.0 // indirect ) diff --git a/go.sum b/go.sum index de333bf8..edaff5e1 100644 --- a/go.sum +++ b/go.sum @@ -244,6 +244,8 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mgfeller/meshery-adapter-library v0.0.0-20201005203405-4c01118f7bcc h1:a/aK/mRMOJiSdABqHvco45xCjPT1s6IU0X7qKU3R9UE= +github.com/mgfeller/meshery-adapter-library v0.0.0-20201005203405-4c01118f7bcc/go.mod h1:kPQnsVgE0YwEo+JQKRYJGA+VAbzpc0IiAdXvBGQ6pSI= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= diff --git a/internal/config/config.go b/internal/config/config.go index ec0ce124..9c20f7f2 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1,9 +1,9 @@ package config import ( - "github.com/mgfeller/common-adapter-library/adapter" - "github.com/mgfeller/common-adapter-library/config" - "github.com/mgfeller/common-adapter-library/configprovider" + "github.com/layer5io/meshery-adapter-library/adapter" + "github.com/layer5io/meshery-adapter-library/config" + "github.com/layer5io/meshery-adapter-library/configprovider" ) func New(name string, serverConfig map[string]string, meshSpec map[string]string, meshInstance map[string]string, providerConfig map[string]string, operations adapter.Operations) (config.Handler, error) { diff --git a/internal/operations/operations.go b/internal/operations/operations.go index 00382397..3868e18d 100644 --- a/internal/operations/operations.go +++ b/internal/operations/operations.go @@ -1,9 +1,9 @@ package operations import ( + "github.com/layer5io/meshery-adapter-library/adapter" + "github.com/layer5io/meshery-adapter-library/meshes" "github.com/layer5io/meshery-consul/internal/config" - "github.com/mgfeller/common-adapter-library/adapter" - "github.com/mgfeller/common-adapter-library/meshes" ) var ( diff --git a/main.go b/main.go index b650e4c6..4c393ea4 100644 --- a/main.go +++ b/main.go @@ -22,10 +22,10 @@ import ( "github.com/layer5io/gokit/errors" "github.com/layer5io/gokit/logger" "github.com/layer5io/gokit/utils" + "github.com/layer5io/meshery-adapter-library/api/grpc" "github.com/layer5io/meshery-consul/consul" "github.com/layer5io/meshery-consul/internal/config" "github.com/layer5io/meshery-consul/internal/operations" - "github.com/mgfeller/common-adapter-library/api/grpc" ) var ( From 69ca72ff2ee8f792697a2c077e8aa11dbbd7b9ae Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Fri, 9 Oct 2020 19:53:38 +0200 Subject: [PATCH 11/16] using layer5io/meshery-adapter-library v0.1.0-alpha.1 Signed-off-by: Michael Gfeller --- go.mod | 4 +--- go.sum | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b9fbe428..20e1737f 100644 --- a/go.mod +++ b/go.mod @@ -2,11 +2,9 @@ module github.com/layer5io/meshery-consul go 1.13 -replace github.com/layer5io/meshery-adapter-library => ../meshery-adapter-library - require ( github.com/googleapis/gnostic v0.3.1 // indirect github.com/layer5io/gokit v0.1.12 - github.com/layer5io/meshery-adapter-library v0.0.0-20201005203405-4c01118f7bcc + github.com/layer5io/meshery-adapter-library v0.1.0-alpha.1 google.golang.org/grpc v1.32.0 // indirect ) diff --git a/go.sum b/go.sum index edaff5e1..aba4d512 100644 --- a/go.sum +++ b/go.sum @@ -238,6 +238,8 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/layer5io/gokit v0.1.12 h1:QGfoOHfiOpvPaCg1sGFM8ZuatXsgCkWGPD7GVVVQMyY= github.com/layer5io/gokit v0.1.12/go.mod h1:kqwXJ5JZqHv74UCH1pVyDdpLT8muaUyRVu58WWu6wcY= +github.com/layer5io/meshery-adapter-library v0.1.0-alpha.1 h1:DlmSQ3GE3fT7vFYQ7LoQCKiIz3A6LGjpUDtfj2OD9Kc= +github.com/layer5io/meshery-adapter-library v0.1.0-alpha.1/go.mod h1:kKO9OmVc0+iXSYBVC7bG80hMdUPQwGv+3zUj/jT0VR8= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= From 933892d63ed807aa2761e70f2346bbafb2bfa18e Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Tue, 13 Oct 2020 21:29:15 +0200 Subject: [PATCH 12/16] functionality to get service ports; removed some todos Signed-off-by: Michael Gfeller --- consul/install.go | 40 +++++++++++++++++++++++++++++-- consul/operations.go | 27 +++++++++++++++++---- go.mod | 2 ++ go.sum | 6 ++--- internal/config/defaults.go | 4 ++-- internal/config/keys.go | 1 + internal/operations/operations.go | 3 +++ 7 files changed, 71 insertions(+), 12 deletions(-) diff --git a/consul/install.go b/consul/install.go index c1dbe129..10760416 100644 --- a/consul/install.go +++ b/consul/install.go @@ -4,6 +4,8 @@ import ( "fmt" "path" + "github.com/layer5io/gokit/errors" + "github.com/layer5io/meshery-consul/internal/config" "github.com/layer5io/meshery-adapter-library/adapter" @@ -17,8 +19,12 @@ func (m *MeshInstance) applyUsingManifest(request adapter.OperationRequest, oper return err } +func (m *MeshInstance) getServicePorts(request adapter.OperationRequest, operation *adapter.Operation, h *Handler) ([]int64, error) { + return h.GetServicePorts(operation.Properties[config.OperationServiceNameKey], request.Namespace) +} + func (h *Handler) applyUsingManifest(request adapter.OperationRequest, operation *adapter.Operation) (string, error) { - status := "installing" // TODO: should be enum defined in the common adapter library + status := "installing" if request.IsDeleteOperation { status = "removing" @@ -34,9 +40,39 @@ func (h *Handler) applyUsingManifest(request adapter.OperationRequest, operation h.Log.Info(fmt.Sprintf("%s %s", status, operation.Properties[config.OperationDescriptionKey])) err = meshInstance.applyUsingManifest(request, operation, h) if err != nil { - h.Log.Err(fmt.Sprintf("Error: %s %s failed", status, operation.Properties[config.OperationDescriptionKey]), adapter.ErrInstallMesh(err).Error()) + h.Log.Err(fmt.Sprintf("%s %s failed", status, operation.Properties[config.OperationDescriptionKey]), adapter.ErrInstallMesh(err).Error()) return status, adapter.ErrInstallMesh(err) } return "deployed", nil } + +func (h *Handler) getServicePorts(request adapter.OperationRequest, operation *adapter.Operation) (string, []int64, error) { + meshInstance := &MeshInstance{} + + err := h.Config.MeshInstance(meshInstance) + if err != nil { + return "", nil, adapter.ErrMeshConfig(err) + } + + svc := operation.Properties[config.OperationServiceNameKey] + + h.Log.Info(fmt.Sprintf("Retreiving service ports for service %s.", svc)) + + var ports []int64 + ports, err = meshInstance.getServicePorts(request, operation, h) + if err != nil { + error := errors.New("0000", fmt.Sprintf("Unable to retrieve information from the mesh: %s.", err.Error())) + h.Log.Err(fmt.Sprintf("Retreiving port(s) for service %s failed.", svc), error.Error()) + return "", nil, error + } + + var portMsg string + if len(ports) == 1 { + portMsg = fmt.Sprintf("The service %s is possibly available on port: %v.", svc, ports) + } else if len(ports) > 1 { + portMsg = fmt.Sprintf("The service %s is possibly available on one of the following ports: %v.", svc, ports) + } + + return portMsg, ports, nil +} diff --git a/consul/operations.go b/consul/operations.go index 34b0a73d..3f6522be 100644 --- a/consul/operations.go +++ b/consul/operations.go @@ -44,19 +44,38 @@ func (h *Handler) ApplyOperation(ctx context.Context, request adapter.OperationR } switch request.OperationName { - case config.CustomOpCommand, // TODO: implement custom op and test for it + case config.CustomOpCommand, config.InstallConsulCommand, config.InstallHTTPBinCommand, config.InstallImageHubCommand, config.InstallBookInfoCommand: + + opDesc := operation.Properties[config.OperationDescriptionKey] if status, err := h.applyUsingManifest(request, operation); err != nil { - e.Summary = fmt.Sprintf("Error while %s %s", status, operation.Properties[config.OperationDescriptionKey]) + e.Summary = fmt.Sprintf("Error while %s %s", status, opDesc) e.Details = err.Error() h.StreamErr(e, err) return err } - e.Summary = fmt.Sprintf("%s %s successfully", operation.Properties[config.OperationDescriptionKey], status) - e.Details = fmt.Sprintf("%s is now %s.", operation.Properties[config.OperationDescriptionKey], status) + + e.Summary = fmt.Sprintf("%s %s successfully.", opDesc, status) + e.Details = fmt.Sprintf("%s is now %s.", opDesc, status) + + if !request.IsDeleteOperation { + if svc, ok := operation.Properties[config.OperationServiceNameKey]; ok && svc != "" { + portMsg, _, err1 := h.getServicePorts(request, operation) + if err1 != nil { + h.StreamErr(&adapter.Event{ + Operationid: request.OperationID, + Summary: fmt.Sprintf("Unable to retrieve port(s) info for the service %s.", operation.Properties[config.OperationServiceNameKey]), + Details: err1.Error(), + }, err1) + } else { + e.Summary = fmt.Sprintf("%s %s", e.Summary, portMsg) + e.Details = fmt.Sprintf("%s %s", e.Details, portMsg) + } + } + } h.StreamInfo(e) default: h.StreamErr(e, adapter.ErrOpInvalid) diff --git a/go.mod b/go.mod index 20e1737f..4b5c838c 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/layer5io/meshery-consul go 1.13 +replace github.com/layer5io/meshery-adapter-library => github.com/mgfeller/meshery-adapter-library v0.1.0-alpha.2 + require ( github.com/googleapis/gnostic v0.3.1 // indirect github.com/layer5io/gokit v0.1.12 diff --git a/go.sum b/go.sum index aba4d512..ef70eb8d 100644 --- a/go.sum +++ b/go.sum @@ -238,16 +238,14 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/layer5io/gokit v0.1.12 h1:QGfoOHfiOpvPaCg1sGFM8ZuatXsgCkWGPD7GVVVQMyY= github.com/layer5io/gokit v0.1.12/go.mod h1:kqwXJ5JZqHv74UCH1pVyDdpLT8muaUyRVu58WWu6wcY= -github.com/layer5io/meshery-adapter-library v0.1.0-alpha.1 h1:DlmSQ3GE3fT7vFYQ7LoQCKiIz3A6LGjpUDtfj2OD9Kc= -github.com/layer5io/meshery-adapter-library v0.1.0-alpha.1/go.mod h1:kKO9OmVc0+iXSYBVC7bG80hMdUPQwGv+3zUj/jT0VR8= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mgfeller/meshery-adapter-library v0.0.0-20201005203405-4c01118f7bcc h1:a/aK/mRMOJiSdABqHvco45xCjPT1s6IU0X7qKU3R9UE= -github.com/mgfeller/meshery-adapter-library v0.0.0-20201005203405-4c01118f7bcc/go.mod h1:kPQnsVgE0YwEo+JQKRYJGA+VAbzpc0IiAdXvBGQ6pSI= +github.com/mgfeller/meshery-adapter-library v0.1.0-alpha.2 h1:/zFLHaCQt2PNE0UWWs8SFvQcDT0TId+sCerhfMOZsQ0= +github.com/mgfeller/meshery-adapter-library v0.1.0-alpha.2/go.mod h1:kKO9OmVc0+iXSYBVC7bG80hMdUPQwGv+3zUj/jT0VR8= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= diff --git a/internal/config/defaults.go b/internal/config/defaults.go index 87c1305d..9c94336d 100644 --- a/internal/config/defaults.go +++ b/internal/config/defaults.go @@ -10,13 +10,13 @@ var ( MeshSpecDefaults = map[string]string{ "name": "Consul", - "status": "not installed", // TODO: status should be an enum + "status": "not installed", "version": "1.8.2", } MeshInstanceDefaults = map[string]string{ "name": "Consul", - "status": "not installed", // TODO: status should be an enum + "status": "not installed", "version": "1.8.2", } diff --git a/internal/config/keys.go b/internal/config/keys.go index 0d1423c0..b015ce05 100644 --- a/internal/config/keys.go +++ b/internal/config/keys.go @@ -10,4 +10,5 @@ const ( OperationDescriptionKey = "description" OperationVersionKey = "version" OperationTemplateNameKey = "templateName" + OperationServiceNameKey = "serviceName" ) diff --git a/internal/operations/operations.go b/internal/operations/operations.go index 3868e18d..7bd1fcb0 100644 --- a/internal/operations/operations.go +++ b/internal/operations/operations.go @@ -22,6 +22,7 @@ var ( config.OperationDescriptionKey: "Istio Book Info Application", config.OperationVersionKey: "", config.OperationTemplateNameKey: "bookinfo.yaml", + config.OperationServiceNameKey: "productpage", }, }, config.InstallHTTPBinCommand: &adapter.Operation{ @@ -30,6 +31,7 @@ var ( config.OperationDescriptionKey: "HTTPbin Application", config.OperationVersionKey: "", config.OperationTemplateNameKey: "httpbin-consul.yaml", + config.OperationServiceNameKey: "httpbin", }, }, config.InstallImageHubCommand: &adapter.Operation{ @@ -38,6 +40,7 @@ var ( config.OperationDescriptionKey: "Image Hub Application", config.OperationVersionKey: "", config.OperationTemplateNameKey: "image-hub.yaml", + config.OperationServiceNameKey: "ingess", }, }, config.CustomOpCommand: &adapter.Operation{ From 78ba7e4529c01049c3c8c165ef030d6f9c56eaf5 Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Mon, 19 Oct 2020 21:02:15 +0200 Subject: [PATCH 13/16] update after review; using latest version of meshery-adapter-library Signed-off-by: Michael Gfeller --- consul/operations.go | 2 +- go.mod | 4 +--- go.sum | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/consul/operations.go b/consul/operations.go index 3f6522be..035927f6 100644 --- a/consul/operations.go +++ b/consul/operations.go @@ -62,7 +62,7 @@ func (h *Handler) ApplyOperation(ctx context.Context, request adapter.OperationR e.Details = fmt.Sprintf("%s is now %s.", opDesc, status) if !request.IsDeleteOperation { - if svc, ok := operation.Properties[config.OperationServiceNameKey]; ok && svc != "" { + if svc, ok := operation.Properties[config.OperationServiceNameKey]; ok && len(svc) > 0 { portMsg, _, err1 := h.getServicePorts(request, operation) if err1 != nil { h.StreamErr(&adapter.Event{ diff --git a/go.mod b/go.mod index 4b5c838c..5f84ba29 100644 --- a/go.mod +++ b/go.mod @@ -2,11 +2,9 @@ module github.com/layer5io/meshery-consul go 1.13 -replace github.com/layer5io/meshery-adapter-library => github.com/mgfeller/meshery-adapter-library v0.1.0-alpha.2 - require ( github.com/googleapis/gnostic v0.3.1 // indirect github.com/layer5io/gokit v0.1.12 - github.com/layer5io/meshery-adapter-library v0.1.0-alpha.1 + github.com/layer5io/meshery-adapter-library v0.1.0-beta google.golang.org/grpc v1.32.0 // indirect ) diff --git a/go.sum b/go.sum index ef70eb8d..20971919 100644 --- a/go.sum +++ b/go.sum @@ -238,14 +238,14 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/layer5io/gokit v0.1.12 h1:QGfoOHfiOpvPaCg1sGFM8ZuatXsgCkWGPD7GVVVQMyY= github.com/layer5io/gokit v0.1.12/go.mod h1:kqwXJ5JZqHv74UCH1pVyDdpLT8muaUyRVu58WWu6wcY= +github.com/layer5io/meshery-adapter-library v0.1.0-beta h1:p8OtzUg/pjueVLrqVKRoT9IgnTj3PHoUad+Y6pSaxMM= +github.com/layer5io/meshery-adapter-library v0.1.0-beta/go.mod h1:kKO9OmVc0+iXSYBVC7bG80hMdUPQwGv+3zUj/jT0VR8= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/mgfeller/meshery-adapter-library v0.1.0-alpha.2 h1:/zFLHaCQt2PNE0UWWs8SFvQcDT0TId+sCerhfMOZsQ0= -github.com/mgfeller/meshery-adapter-library v0.1.0-alpha.2/go.mod h1:kKO9OmVc0+iXSYBVC7bG80hMdUPQwGv+3zUj/jT0VR8= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= From 579ffa57ccb3c385cc8e22e6892dbf9108cb76fe Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Tue, 20 Oct 2020 20:16:06 +0200 Subject: [PATCH 14/16] updated Dockerfile to set up appuser's home directory Signed-off-by: Michael Gfeller --- Dockerfile | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2554d572..86be28a0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,18 @@ FROM golang:1.13 as bd -RUN adduser --disabled-login appuser WORKDIR /github.com/layer5io/meshery-consul ADD . . RUN GOPROXY=direct GOSUMDB=off go build -ldflags="-w -s" -a -o /meshery-consul . RUN find . -name "*.go" -type f -delete; mv consul / FROM alpine -RUN apk --update add ca-certificates -RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 -COPY --from=bd /meshery-consul /app/ -COPY --from=bd /consul /app/consul -COPY --from=bd /etc/passwd /etc/passwd +RUN addgroup -S appgroup && adduser -S appuser -G appgroup +RUN apk --update add ca-certificates && \ + mkdir /lib64 && \ + ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2 + USER appuser -WORKDIR /app +RUN mkdir -p /home/appuser/.kube +WORKDIR /home/appuser +COPY --from=bd /meshery-consul /home/appuser +COPY --from=bd /consul /home/appuser/consul CMD ./meshery-consul From f441139c84729a35ca74d02dab9aab7e90911d49 Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Sun, 25 Oct 2020 22:05:23 +0100 Subject: [PATCH 15/16] updates based on code review, and IDE checks Signed-off-by: Michael Gfeller --- consul/error.go | 31 +++++++++++++++++++++++++++++++ consul/install.go | 28 +++++++++++++--------------- consul/operations.go | 9 +++++---- internal/config/defaults.go | 8 ++++++-- internal/status/status.go | 24 ++++++++++++++++++++++++ main.go | 13 ++++++++----- 6 files changed, 87 insertions(+), 26 deletions(-) create mode 100644 consul/error.go create mode 100644 internal/status/status.go diff --git a/consul/error.go b/consul/error.go new file mode 100644 index 00000000..78caa36b --- /dev/null +++ b/consul/error.go @@ -0,0 +1,31 @@ +// Copyright 2020 Layer5, Inc. +// +// Licensed 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 consul + +import ( + "fmt" + + "github.com/layer5io/gokit/errors" +) + +// This error code should probably be moved to https://github.com/layer5io/meshkit/blob/master/errors/codes.go. +const ( + ErrGetInfoCode = "1015" +) + +// This function should probably be moved to https://github.com/layer5io/meshery-adapter-library/blob/master/adapter/error.go. +func ErrGetInfo(err error) error { + return errors.New(ErrGetInfoCode, fmt.Sprintf("Unable to retrieve information from the mesh: %s", err.Error())) +} diff --git a/consul/install.go b/consul/install.go index 10760416..9fe8ee66 100644 --- a/consul/install.go +++ b/consul/install.go @@ -4,30 +4,28 @@ import ( "fmt" "path" - "github.com/layer5io/gokit/errors" - - "github.com/layer5io/meshery-consul/internal/config" - "github.com/layer5io/meshery-adapter-library/adapter" + "github.com/layer5io/meshery-consul/internal/config" + opstatus "github.com/layer5io/meshery-consul/internal/status" ) type MeshInstance struct{} -func (m *MeshInstance) applyUsingManifest(request adapter.OperationRequest, operation *adapter.Operation, h *Handler) error { - err := h.ApplyKubernetesManifest(request, *operation, map[string]string{"namespace": request.Namespace}, +func (m *MeshInstance) applyUsingManifest(request adapter.OperationRequest, operation adapter.Operation, h *Handler) error { + err := h.ApplyKubernetesManifest(request, operation, map[string]string{"namespace": request.Namespace}, path.Join("consul", "config_templates", operation.Properties[config.OperationTemplateNameKey])) return err } -func (m *MeshInstance) getServicePorts(request adapter.OperationRequest, operation *adapter.Operation, h *Handler) ([]int64, error) { +func (m *MeshInstance) getServicePorts(request adapter.OperationRequest, operation adapter.Operation, h *Handler) ([]int64, error) { return h.GetServicePorts(operation.Properties[config.OperationServiceNameKey], request.Namespace) } -func (h *Handler) applyUsingManifest(request adapter.OperationRequest, operation *adapter.Operation) (string, error) { - status := "installing" +func (h *Handler) applyUsingManifest(request adapter.OperationRequest, operation adapter.Operation) (string, error) { + status := opstatus.Installing if request.IsDeleteOperation { - status = "removing" + status = opstatus.Removing } meshInstance := &MeshInstance{} @@ -44,10 +42,10 @@ func (h *Handler) applyUsingManifest(request adapter.OperationRequest, operation return status, adapter.ErrInstallMesh(err) } - return "deployed", nil + return opstatus.Deployed, nil } -func (h *Handler) getServicePorts(request adapter.OperationRequest, operation *adapter.Operation) (string, []int64, error) { +func (h *Handler) getServicePorts(request adapter.OperationRequest, operation adapter.Operation) (string, []int64, error) { meshInstance := &MeshInstance{} err := h.Config.MeshInstance(meshInstance) @@ -62,9 +60,9 @@ func (h *Handler) getServicePorts(request adapter.OperationRequest, operation *a var ports []int64 ports, err = meshInstance.getServicePorts(request, operation, h) if err != nil { - error := errors.New("0000", fmt.Sprintf("Unable to retrieve information from the mesh: %s.", err.Error())) - h.Log.Err(fmt.Sprintf("Retreiving port(s) for service %s failed.", svc), error.Error()) - return "", nil, error + err2 := ErrGetInfo(err) + h.Log.Err(fmt.Sprintf("Retreiving port(s) for service %s failed.", svc), err2.Error()) + return "", nil, err2 } var portMsg string diff --git a/consul/operations.go b/consul/operations.go index 035927f6..e7170460 100644 --- a/consul/operations.go +++ b/consul/operations.go @@ -6,6 +6,7 @@ import ( "github.com/layer5io/meshery-adapter-library/adapter" "github.com/layer5io/meshery-consul/internal/config" + opstatus "github.com/layer5io/meshery-consul/internal/status" ) func (h *Handler) ApplyOperation(ctx context.Context, request adapter.OperationRequest) error { @@ -15,7 +16,7 @@ func (h *Handler) ApplyOperation(ctx context.Context, request adapter.OperationR return err } - status := "deploying" + status := opstatus.Deploying e := &adapter.Event{ Operationid: request.OperationID, Summary: "Deploying", @@ -23,7 +24,7 @@ func (h *Handler) ApplyOperation(ctx context.Context, request adapter.OperationR } if request.IsDeleteOperation { - status = "removing" + status = opstatus.Removing e.Summary = "Removing" } @@ -51,7 +52,7 @@ func (h *Handler) ApplyOperation(ctx context.Context, request adapter.OperationR config.InstallBookInfoCommand: opDesc := operation.Properties[config.OperationDescriptionKey] - if status, err := h.applyUsingManifest(request, operation); err != nil { + if status, err := h.applyUsingManifest(request, *operation); err != nil { e.Summary = fmt.Sprintf("Error while %s %s", status, opDesc) e.Details = err.Error() h.StreamErr(e, err) @@ -63,7 +64,7 @@ func (h *Handler) ApplyOperation(ctx context.Context, request adapter.OperationR if !request.IsDeleteOperation { if svc, ok := operation.Properties[config.OperationServiceNameKey]; ok && len(svc) > 0 { - portMsg, _, err1 := h.getServicePorts(request, operation) + portMsg, _, err1 := h.getServicePorts(request, *operation) if err1 != nil { h.StreamErr(&adapter.Event{ Operationid: request.OperationID, diff --git a/internal/config/defaults.go b/internal/config/defaults.go index 9c94336d..e481f5ec 100644 --- a/internal/config/defaults.go +++ b/internal/config/defaults.go @@ -1,5 +1,9 @@ package config +import ( + "github.com/layer5io/meshery-consul/internal/status" +) + var ( ServerDefaults = map[string]string{ "name": "consul-adapter", @@ -10,13 +14,13 @@ var ( MeshSpecDefaults = map[string]string{ "name": "Consul", - "status": "not installed", + "status": status.NotInstalled, "version": "1.8.2", } MeshInstanceDefaults = map[string]string{ "name": "Consul", - "status": "not installed", + "status": status.NotInstalled, "version": "1.8.2", } diff --git a/internal/status/status.go b/internal/status/status.go new file mode 100644 index 00000000..2abcf495 --- /dev/null +++ b/internal/status/status.go @@ -0,0 +1,24 @@ +// Copyright 2020 Layer5, Inc. +// +// Licensed 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 status + +// Mesh status should probably be moved to https://github.com/layer5io/meshery-adapter-library +const ( + NotInstalled = "not installed" + Installing = "installing" + Deploying = "deploying" + Deployed = "deployed" + Removing = "removing" +) diff --git a/main.go b/main.go index 4c393ea4..3b842e28 100644 --- a/main.go +++ b/main.go @@ -28,9 +28,12 @@ import ( "github.com/layer5io/meshery-consul/internal/operations" ) -var ( +const ( serviceName = "consul-adaptor" configProvider = "viper" +) + +var ( kubeConfigPath = fmt.Sprintf("%s/.kube/meshery.config", utils.GetHome()) ) @@ -41,17 +44,17 @@ func main() { os.Exit(1) } - config, err := config.New(configProvider, config.ServerDefaults, config.MeshSpecDefaults, config.MeshInstanceDefaults, config.ViperDefaults, operations.Operations) + cfg, err := config.New(configProvider, config.ServerDefaults, config.MeshSpecDefaults, config.MeshInstanceDefaults, config.ViperDefaults, operations.Operations) if err != nil { log.Err("Config Init Failed", err.Error()) os.Exit(1) } - config.SetKey("kube-config-path", kubeConfigPath) + cfg.SetKey("kube-config-path", kubeConfigPath) service := &grpc.Service{} - _ = config.Server(&service) + _ = cfg.Server(&service) - service.Handler = consul.New(config, log) + service.Handler = consul.New(cfg, log) service.Channel = make(chan interface{}, 100) service.StartedAt = time.Now() log.Info(fmt.Sprintf("%s starting on port: %s", service.Name, service.Port)) From ffa1ffa7cac4a5f48d6d66c6c3beb041c32d20f7 Mon Sep 17 00:00:00 2001 From: Michael Gfeller Date: Mon, 26 Oct 2020 17:52:47 +0100 Subject: [PATCH 16/16] adaptor -> adapter Signed-off-by: Michael Gfeller --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index 3b842e28..7e983aa0 100644 --- a/main.go +++ b/main.go @@ -29,7 +29,7 @@ import ( ) const ( - serviceName = "consul-adaptor" + serviceName = "consul-adapter" configProvider = "viper" )