From f3b7ccf72a28787e578bf4d64f8a40dec800a38e Mon Sep 17 00:00:00 2001 From: xmcqueen Date: Thu, 12 Dec 2019 15:24:40 -0800 Subject: [PATCH 01/65] [script] remove DS_PROMETHEUS variable interpolation syntax in Dockerfile --- docker/grafana/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/grafana/Dockerfile b/docker/grafana/Dockerfile index e454d54567..1eeb6de1f4 100644 --- a/docker/grafana/Dockerfile +++ b/docker/grafana/Dockerfile @@ -13,5 +13,5 @@ COPY ./integrations/grafana/temporal_function_comparison.json /tmp/grafana_dashb # JustWorksTM. Use a temporary directory to host the dashboards since the default # directory is owned by root. COPY ./integrations/grafana/m3db_overlaid_dashboard.json /tmp/m3db_overlaid_dashboard.json -RUN awk '{gsub(/\${DS_PROMETHEUS}/,"Prometheus");print}' /tmp/m3db_overlaid_dashboard.json \ - | awk '{gsub(/\${DS_M3QUERY}/,"M3Query - Prometheus");print}' > /tmp/grafana_dashboards/m3db_overlaid_dashboard.json +RUN awk '{gsub(/DS_PROMETHEUS/,"Prometheus");print}' /tmp/m3db_overlaid_dashboard.json \ + | awk '{gsub(/DS_M3QUERY/,"M3Query - Prometheus");print}' > /tmp/grafana_dashboards/m3db_overlaid_dashboard.json From 96f2d6e23053b9f1085faf70904e2b4b641d0f11 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 5 Jan 2020 13:18:19 -0800 Subject: [PATCH 02/65] start of tool for some operational tasks --- src/cmd/tools/q/main/README.md | 45 +++++++++++ src/cmd/tools/q/main/main.go | 80 +++++++++++++++++++ src/cmd/tools/q/main/namespaces/get.go | 102 +++++++++++++++++++++++++ 3 files changed, 227 insertions(+) create mode 100644 src/cmd/tools/q/main/README.md create mode 100644 src/cmd/tools/q/main/main.go create mode 100644 src/cmd/tools/q/main/namespaces/get.go diff --git a/src/cmd/tools/q/main/README.md b/src/cmd/tools/q/main/README.md new file mode 100644 index 0000000000..81f6a1ee90 --- /dev/null +++ b/src/cmd/tools/q/main/README.md @@ -0,0 +1,45 @@ +#https://www.m3db.io/openapi/ + +per rob https://m3db.slack.com/archives/CKARJDKT2/p1577442957085600 +make it like https://www.vskills.in/certification/tutorial/big-data/apache-cassandra/nodetool/ + +try to get the curl's and operational tasks from this page into a tool +https://m3db.github.io/m3/how_to/kubernetes/ + +^Cbmcqueen-mn2:m3db bmcqueen$ kubectl port-forward svc/m3dbnode-persistent-cluster 9003 + +bmcqueen-mn2:m3db bmcqueen$ curl -v localhost:9003/health +* Trying 127.0.0.1... +* TCP_NODELAY set +* Connected to localhost (127.0.0.1) port 9003 (#0) +> GET /health HTTP/1.1 +> Host: localhost:9003 +> User-Agent: curl/7.64.1 +> Accept: */* +> +< HTTP/1.1 200 OK +< Content-Type: application/json +< Date: Sat, 04 Jan 2020 03:42:30 GMT +< Content-Length: 26 +< +{"ok":true,"status":"up"} +* Connection #0 to host localhost left intact +* Closing connection 0 +bmcqueen-mn2:m3db bmcqueen$ curl -v localhost:9003/health + + +initialize placement +list placements + +#https://m3db.github.io/m3/operational_guide/namespace_configuration/ +#https://www.m3db.io/openapi/#tag/M3DB-Namespace +list namespaces +creating a namespace +delete namespace + +db placements +#https://m3db.github.io/m3/operational_guide/placement_configuration/#removing-a-node +#https://www.m3db.io/openapi/#tag/M3DB-Placement +adding a node +removing a node +replacing a node diff --git a/src/cmd/tools/q/main/main.go b/src/cmd/tools/q/main/main.go new file mode 100644 index 0000000000..c1907b839b --- /dev/null +++ b/src/cmd/tools/q/main/main.go @@ -0,0 +1,80 @@ +// Copyright (c) 2018 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package main + +import ( + "flag" + "fmt" + "os" + "strings" + + "github.com/m3db/m3/src/cmd/tools/q/main/namespaces" + //"github.com/m3db/m3/src/dbnode/persist/fs" + //"github.com/m3db/m3/src/x/ident" + + //"github.com/pborman/getopt" + "go.uber.org/zap" +) + +func main() { + + flag.Usage = func() { + fmt.Fprintf(flag.CommandLine.Output(), ` +Usage of %s: + + Specify one of the following subcommands: + + %s + + +`, os.Args[0], strings.Join([]string{ + namespaces.GetFlags.Name(), + }, ", ")) + + flag.PrintDefaults() + } + + if len(os.Args) < 2 { + flag.Usage() + os.Exit(1) + } + + flag.Parse() + + rawLogger, err := zap.NewDevelopment() + if err != nil { + fmt.Fprintf(os.Stderr, "unable to create logger: %+v", err) + os.Exit(1) + } + log := rawLogger.Sugar() + + switch flag.Arg(0) { + case namespaces.GetFlags.Name(): + + namespaces.Get(log) + + default: + flag.Usage() + os.Exit(1) + + } + +} diff --git a/src/cmd/tools/q/main/namespaces/get.go b/src/cmd/tools/q/main/namespaces/get.go new file mode 100644 index 0000000000..d71ec917c2 --- /dev/null +++ b/src/cmd/tools/q/main/namespaces/get.go @@ -0,0 +1,102 @@ +package namespaces + +import ( + "flag" + "fmt" + "go.uber.org/zap" + "io/ioutil" + "net/http" + "os" + + "github.com/gogo/protobuf/jsonpb" + "github.com/m3db/m3/src/query/generated/proto/admin" +) + +var ( + GetFlags *flag.FlagSet + endpoint *string + showAll *bool + defaultPath = "/api/v1/namespace?debug=true" +) + +//curl -s -k -v 'http://localhost:7201/api/v1/namespace?debug=true' | jq .registry.namespaces\|keys + +func init() { + GetFlags = flag.NewFlagSet("namespaces", flag.ExitOnError) + endpoint = GetFlags.String("endpoint", "http://localhost:7201", "url for endpoint") + showAll = GetFlags.Bool("all", false, "show standard info for namespaces (default is to list only the names)") + GetFlags.Usage = func() { + fmt.Fprintf(GetFlags.Output(), ` +Description: + +blah blah + + +Usage of %s: + +`, GetFlags.Name()) + GetFlags.PrintDefaults() + } +} + +func Get(log *zap.SugaredLogger) { + + if err := GetFlags.Parse(flag.Args()[1:]); err != nil { + GetFlags.Usage() + os.Exit(1) + } + + //if GetFlags.NFlag() > 4 { + // GetFlags.Usage() + // os.Exit(1) + //} + + registry := admin.NamespaceGetResponse{} + + url := fmt.Sprintf("%s%s", *endpoint, defaultPath) + + log.Debugf("url:%s:\n", url) + + resp, err := http.Get(url) + if err != nil { + panic(err) + } + + defer func() { + ioutil.ReadAll(resp.Body) + resp.Body.Close() + }() + + if err != nil { + panic(err) + } + + // printout the json + // no need to unmarshal it + if *showAll { + dat, err := ioutil.ReadAll(resp.Body) + if err != nil { + panic(err) + } + + fmt.Println(string(dat)) + + return + } + + unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} + + err = unmarshaller.Unmarshal(resp.Body, ®istry) + if err != nil { + panic(err) + } + + log.Debug(registry) + log.Debugf("%#v\n", *showAll) + + for k, _ := range registry.Registry.Namespaces { + fmt.Println(k) + } + + return +} From d01a4738cc96962efa89e30db9a1bdbef6635958 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Tue, 7 Jan 2020 09:15:14 -0800 Subject: [PATCH 03/65] looks like yaml inputs works nicely --- src/cmd/tools/q/main/database/cmd.go | 157 ++++++++++++++++++ .../q/main/database/examples/create.yaml | 26 +++ .../tools/q/main/database/examples/devel.yaml | 15 ++ src/cmd/tools/q/main/flagvar/file.go | 52 ++++++ src/cmd/tools/q/main/main.go | 12 ++ src/cmd/tools/q/main/namespaces/get.go | 13 +- src/cmd/tools/q/main/placements/get.go | 103 ++++++++++++ 7 files changed, 374 insertions(+), 4 deletions(-) create mode 100644 src/cmd/tools/q/main/database/cmd.go create mode 100644 src/cmd/tools/q/main/database/examples/create.yaml create mode 100644 src/cmd/tools/q/main/database/examples/devel.yaml create mode 100644 src/cmd/tools/q/main/flagvar/file.go create mode 100644 src/cmd/tools/q/main/placements/get.go diff --git a/src/cmd/tools/q/main/database/cmd.go b/src/cmd/tools/q/main/database/cmd.go new file mode 100644 index 0000000000..a0486f21aa --- /dev/null +++ b/src/cmd/tools/q/main/database/cmd.go @@ -0,0 +1,157 @@ +package database + +import ( + "bytes" + "net/http" + + //"bytes" + //"encoding/json" + "flag" + "fmt" + "go.uber.org/zap" + "io/ioutil" + + //"io/ioutil" + //"net/http" + + //"k8s.io/gengo/testdata/a/b" + + "github.com/ghodss/yaml" + + //"io/ioutil" + //"net/http" + "os" + + "github.com/gogo/protobuf/jsonpb" + //"gopkg.in/yaml.v2" + "github.com/m3db/m3/src/query/generated/proto/admin" + "github.com/m3db/m3/src/cmd/tools/q/main/flagvar" +) + +var ( + DatabaseFlags *flag.FlagSet + endpoint *string + createYaml = flagvar.File{} + + defaultPath = "/api/v1/database" + debugQS = "debug=true" +) + +//curl -X POST http://localhost:7201/api/v1/database/create -d + +func init() { + DatabaseFlags = flag.NewFlagSet("database", flag.ExitOnError) + endpoint = DatabaseFlags.String("endpoint", "http://bmcqueen-ld1:7201", "url for endpoint") + DatabaseFlags.Var(&createYaml, "create", "Path to yaml for simplified db creation with sane defaults.") + DatabaseFlags.Usage = func() { + fmt.Fprintf(DatabaseFlags.Output(), ` +Description: + +blah blah + + +Usage of %s: + +`, DatabaseFlags.Name()) + DatabaseFlags.PrintDefaults() + } +} + +func Cmd(log *zap.SugaredLogger) { + + if err := DatabaseFlags.Parse(flag.Args()[1:]); err != nil { + DatabaseFlags.Usage() + os.Exit(1) + } + + //if DatabaseFlags.NFlag() > 4 { + // DatabaseFlags.Usage() + // os.Exit(1) + //} + + if len(createYaml.Value) < 1 { + DatabaseFlags.Usage() + os.Exit(1) + } + + registry := admin.DatabaseCreateRequest{} + + content, err := ioutil.ReadFile(createYaml.Value) + //content, err := os.Open(createYaml.Value) + if err != nil { + log.Fatal(err) + } + + //fmt.Printf("File contents: %s\n\n", content) + + if err = yaml.Unmarshal([]byte(content), ®istry); err != nil { + log.Fatalf("cannot unmarshal data: %v", err) + } + + //unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} + + //if err = unmarshaller.Unmarshal(content, ®istry); err != nil { + // panic(err) + //} + + //fmt.Printf("%+v:\n", registry) + + var data *bytes.Buffer + data = bytes.NewBuffer(nil) + + marshaller := &jsonpb.Marshaler{} + if err = marshaller.Marshal(data, ®istry); err != nil { + log.Fatal(err) + } + + url := fmt.Sprintf("%s%s/create", *endpoint, defaultPath) + + log.Debugf("url:%s:\n", url) + + client := &http.Client{} + + req, err := http.NewRequest(http.MethodPost, url, data) + req.Header.Add("Content-Type", "application/json") + + resp, err := client.Do(req) + if err != nil { + panic(err) + + } + defer func() { + ioutil.ReadAll(resp.Body) + resp.Body.Close() + }() + + //// printout the json + //// no need to unmarshal it + //if *showAll { + dat, err := ioutil.ReadAll(resp.Body) + if err != nil { + panic(err) + } + + fmt.Println(string(dat)) + + return + //} + + + //old stuff + // + //unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} + // + //err = unmarshaller.Unmarshal(resp.Body, ®istry) + //if err != nil { + // panic(err) + //} + // + //log.Debug(registry) + //log.Debugf("%#v\n", *showAll) + // + //for k, _ := range registry.Registry.Namespaces { + // fmt.Println(k) + //} + + return +} diff --git a/src/cmd/tools/q/main/database/examples/create.yaml b/src/cmd/tools/q/main/database/examples/create.yaml new file mode 100644 index 0000000000..a9ac280f30 --- /dev/null +++ b/src/cmd/tools/q/main/database/examples/create.yaml @@ -0,0 +1,26 @@ +--- +type: cluster +namespace_name: 1week_namespace +retention_time: 168h +num_shards: 1024 +replication_factor: 3 +hosts: +- id: m3db001 + isolationGroup: us-east1-a + zone: embedded + weight: 100 + address: 10.142.0.1 + port: 9000 +- id: m3db002 + isolationGroup: us-east1-b + zone: embedded + weight: 100 + address: 10.142.0.2 + port: 9000 +- id: m3db003 + isolationGroup: us-east1-c + zone: embedded + weight: 100 + address: 10.142.0.3 + port: 9000 + diff --git a/src/cmd/tools/q/main/database/examples/devel.yaml b/src/cmd/tools/q/main/database/examples/devel.yaml new file mode 100644 index 0000000000..5359c9500b --- /dev/null +++ b/src/cmd/tools/q/main/database/examples/devel.yaml @@ -0,0 +1,15 @@ +--- +type: cluster +namespace_name: default +retention_time: 168h +num_shards: 64 +replication_factor: 1 +hosts: +- id: m3db_seed + isolation_group: rack-a + zone: embedded + weight: 1024 + endpoint: m3db_seed:9000 + hostname: m3db_seed + port: 9000 + diff --git a/src/cmd/tools/q/main/flagvar/file.go b/src/cmd/tools/q/main/flagvar/file.go new file mode 100644 index 0000000000..43bb190d5a --- /dev/null +++ b/src/cmd/tools/q/main/flagvar/file.go @@ -0,0 +1,52 @@ +package flagvar + +import ( + "os" + "strings" +) + +// File is a `flag.Value` for file path arguments. +// By default, any errors from os.Stat are returned. +// Alternatively, the value of the `Validate` field is used as a validator when specified. +type File struct { + Validate func(os.FileInfo, error) error + + Value string +} + +// Set is flag.Value.Set +func (fv *File) Set(v string) error { + info, err := os.Stat(v) + fv.Value = v + if fv.Validate != nil { + return fv.Validate(info, err) + } + return err +} + +func (fv *File) String() string { + return fv.Value +} + +// Files is a `flag.Value` for file path arguments. +// By default, any errors from os.Stat are returned. +// Alternatively, the value of the `Validate` field is used as a validator when specified. +type Files struct { + Validate func(os.FileInfo, error) error + + Values []string +} + +// Set is flag.Value.Set +func (fv *Files) Set(v string) error { + info, err := os.Stat(v) + fv.Values = append(fv.Values, v) + if fv.Validate != nil { + return fv.Validate(info, err) + } + return err +} + +func (fv *Files) String() string { + return strings.Join(fv.Values, ",") +} diff --git a/src/cmd/tools/q/main/main.go b/src/cmd/tools/q/main/main.go index c1907b839b..80447a8322 100644 --- a/src/cmd/tools/q/main/main.go +++ b/src/cmd/tools/q/main/main.go @@ -26,7 +26,9 @@ import ( "os" "strings" + "github.com/m3db/m3/src/cmd/tools/q/main/database" "github.com/m3db/m3/src/cmd/tools/q/main/namespaces" + "github.com/m3db/m3/src/cmd/tools/q/main/placements" //"github.com/m3db/m3/src/dbnode/persist/fs" //"github.com/m3db/m3/src/x/ident" @@ -46,6 +48,8 @@ Usage of %s: `, os.Args[0], strings.Join([]string{ + database.DatabaseFlags.Name(), + placements.GetFlags.Name(), namespaces.GetFlags.Name(), }, ", ")) @@ -67,10 +71,18 @@ Usage of %s: log := rawLogger.Sugar() switch flag.Arg(0) { + case database.DatabaseFlags.Name(): + + database.Cmd(log) + case namespaces.GetFlags.Name(): namespaces.Get(log) + case placements.GetFlags.Name(): + + placements.Get(log) + default: flag.Usage() os.Exit(1) diff --git a/src/cmd/tools/q/main/namespaces/get.go b/src/cmd/tools/q/main/namespaces/get.go index d71ec917c2..855bf6a5d7 100644 --- a/src/cmd/tools/q/main/namespaces/get.go +++ b/src/cmd/tools/q/main/namespaces/get.go @@ -16,15 +16,20 @@ var ( GetFlags *flag.FlagSet endpoint *string showAll *bool - defaultPath = "/api/v1/namespace?debug=true" + defaultPath = "/api/v1/namespace" + debugQS = "debug=true" + delete *string ) //curl -s -k -v 'http://localhost:7201/api/v1/namespace?debug=true' | jq .registry.namespaces\|keys +//curl -v -X DELETE bmcqueen-ld1:7201/api/v1/services/m3db/namespace/metrics_10s_48h + func init() { GetFlags = flag.NewFlagSet("namespaces", flag.ExitOnError) - endpoint = GetFlags.String("endpoint", "http://localhost:7201", "url for endpoint") - showAll = GetFlags.Bool("all", false, "show standard info for namespaces (default is to list only the names)") + endpoint = GetFlags.String("endpoint", "http://bmcqueen-ld1:7201", "url for endpoint") + endpoint = GetFlags.String("delete", "", "name of namespace to delete") + showAll = GetFlags.Bool("all", false, "show all the standard info for namespaces (otherwise default behaviour lists only the names)") GetFlags.Usage = func() { fmt.Fprintf(GetFlags.Output(), ` Description: @@ -53,7 +58,7 @@ func Get(log *zap.SugaredLogger) { registry := admin.NamespaceGetResponse{} - url := fmt.Sprintf("%s%s", *endpoint, defaultPath) + url := fmt.Sprintf("%s%s?%s", *endpoint, defaultPath, debugQS) log.Debugf("url:%s:\n", url) diff --git a/src/cmd/tools/q/main/placements/get.go b/src/cmd/tools/q/main/placements/get.go new file mode 100644 index 0000000000..af7b647dbc --- /dev/null +++ b/src/cmd/tools/q/main/placements/get.go @@ -0,0 +1,103 @@ +package placements + +import ( + "flag" + "fmt" + "go.uber.org/zap" + "io/ioutil" + "net/http" + "os" + + //"github.com/gogo/protobuf/jsonpb" + //"github.com/m3db/m3/src/query/generated/proto/admin" +) + +var ( + GetFlags *flag.FlagSet + endpoint *string + defaultPath = "/api/v1/placement" +) + +//curl -s -k -v 'http://localhost:7201/api/v1/placement' + +//curl -v -X DELETE bmcqueen-ld1:7201/api/v1/services/m3db/placement + +func init() { + GetFlags = flag.NewFlagSet("placements", flag.ExitOnError) + endpoint = GetFlags.String("endpoint", "http://bmcqueen-ld1:7201", "url for endpoint") + //showAll = GetFlags.Bool("all", false, "show standard info for namespaces (default is to list only the names)") + GetFlags.Usage = func() { + fmt.Fprintf(GetFlags.Output(), ` +Description: + +blah blah + + +Usage of %s: + +`, GetFlags.Name()) + GetFlags.PrintDefaults() + } +} + +func Get(log *zap.SugaredLogger) { + + if err := GetFlags.Parse(flag.Args()[1:]); err != nil { + GetFlags.Usage() + os.Exit(1) + } + + //if GetFlags.NFlag() > 4 { + // GetFlags.Usage() + // os.Exit(1) + //} + + //registry := admin.PlacementGetResponse{} + + url := fmt.Sprintf("%s%s", *endpoint, defaultPath) + + log.Debugf("url:%s:\n", url) + + resp, err := http.Get(url) + if err != nil { + panic(err) + } + + defer func() { + ioutil.ReadAll(resp.Body) + resp.Body.Close() + }() + + if err != nil { + panic(err) + } + + // printout the json + // no need to unmarshal it + //if *showAll { + dat, err := ioutil.ReadAll(resp.Body) + if err != nil { + panic(err) + } + + fmt.Println(string(dat)) + + return + //} + + //unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} + // + //err = unmarshaller.Unmarshal(resp.Body, ®istry) + //if err != nil { + // panic(err) + //} + // + //log.Debug(registry) + //log.Debugf("%#v\n", *showAll) + // + //for k, _ := range registry.Registry.Namespaces { + // fmt.Println(k) + //} + + return +} From 30fd1a58e2404287c79b4fd9b6b5cc6680301d81 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Tue, 7 Jan 2020 15:53:00 -0800 Subject: [PATCH 04/65] cleaned up a lot and added many api calls --- src/cmd/tools/q/main/common/http.go | 83 ++++++++++++ src/cmd/tools/q/main/database/cmd.go | 114 +++++------------ src/cmd/tools/q/main/main.go | 16 +-- src/cmd/tools/q/main/namespaces/cmd.go | 116 +++++++++++++++++ src/cmd/tools/q/main/namespaces/get.go | 107 ---------------- src/cmd/tools/q/main/placements/cmd.go | 120 ++++++++++++++++++ .../q/main/placements/examples/newNode.yaml | 10 ++ src/cmd/tools/q/main/placements/get.go | 103 --------------- 8 files changed, 371 insertions(+), 298 deletions(-) create mode 100644 src/cmd/tools/q/main/common/http.go create mode 100644 src/cmd/tools/q/main/namespaces/cmd.go delete mode 100644 src/cmd/tools/q/main/namespaces/get.go create mode 100644 src/cmd/tools/q/main/placements/cmd.go create mode 100644 src/cmd/tools/q/main/placements/examples/newNode.yaml delete mode 100644 src/cmd/tools/q/main/placements/get.go diff --git a/src/cmd/tools/q/main/common/http.go b/src/cmd/tools/q/main/common/http.go new file mode 100644 index 0000000000..3b60cfa672 --- /dev/null +++ b/src/cmd/tools/q/main/common/http.go @@ -0,0 +1,83 @@ +package common + +import ( + "flag" + "go.uber.org/zap" + "io" + "io/ioutil" + "net/http" +) + +var ( + EndPoint *string +) + +// This is used across the commands +func init() { + EndPoint = flag.String("endpoint", "http://bmcqueen-ld1:7201", "url for endpoint") +} + +func DoGet(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { + + logger.Debugf("url:%s:\n", url) + + resp, err := http.Get(url) + if err != nil { + panic(err) + } + + defer func() { + ioutil.ReadAll(resp.Body) + resp.Body.Close() + }() + + getter(resp.Body, logger) + +} + +func DoPost(url string, data io.Reader, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { + + logger.Debugf("url:%s:\n", url) + + client := &http.Client{} + + req, err := http.NewRequest(http.MethodPost, url, data) + req.Header.Add("Content-Type", "application/json") + + resp, err := client.Do(req) + if err != nil { + panic(err) + + } + defer func() { + ioutil.ReadAll(resp.Body) + resp.Body.Close() + }() + + getter(resp.Body, logger) + +} + +func DoDelete(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { + + logger.Debugf("url:%s:\n", url) + + client := &http.Client{} + + req, err := http.NewRequest(http.MethodDelete, url, nil) + req.Header.Add("Content-Type", "application/json") + + resp, err := client.Do(req) + if err != nil { + panic(err) + + } + defer func() { + ioutil.ReadAll(resp.Body) + resp.Body.Close() + }() + + getter(resp.Body, logger) + +} + diff --git a/src/cmd/tools/q/main/database/cmd.go b/src/cmd/tools/q/main/database/cmd.go index a0486f21aa..b1846fe908 100644 --- a/src/cmd/tools/q/main/database/cmd.go +++ b/src/cmd/tools/q/main/database/cmd.go @@ -2,8 +2,7 @@ package database import ( "bytes" - "net/http" - + "io" //"bytes" //"encoding/json" "flag" @@ -23,79 +22,79 @@ import ( "os" "github.com/gogo/protobuf/jsonpb" + "github.com/m3db/m3/src/cmd/tools/q/main/common" //"gopkg.in/yaml.v2" - "github.com/m3db/m3/src/query/generated/proto/admin" "github.com/m3db/m3/src/cmd/tools/q/main/flagvar" + "github.com/m3db/m3/src/query/generated/proto/admin" ) var ( - DatabaseFlags *flag.FlagSet - endpoint *string - createYaml = flagvar.File{} + CmdFlags *flag.FlagSet + createYaml = flagvar.File{} - defaultPath = "/api/v1/database" - debugQS = "debug=true" + defaultPath = "/api/v1/database" + debugQS = "debug=true" ) //curl -X POST http://localhost:7201/api/v1/database/create -d func init() { - DatabaseFlags = flag.NewFlagSet("database", flag.ExitOnError) - endpoint = DatabaseFlags.String("endpoint", "http://bmcqueen-ld1:7201", "url for endpoint") - DatabaseFlags.Var(&createYaml, "create", "Path to yaml for simplified db creation with sane defaults.") - DatabaseFlags.Usage = func() { - fmt.Fprintf(DatabaseFlags.Output(), ` + CmdFlags = flag.NewFlagSet("db", flag.ExitOnError) + CmdFlags.Var(&createYaml, "create", "Path to yaml for simplified db creation with sane defaults.") + CmdFlags.Usage = func() { + fmt.Fprintf(CmdFlags.Output(), ` Description: -blah blah +database tasks Usage of %s: -`, DatabaseFlags.Name()) - DatabaseFlags.PrintDefaults() +`, CmdFlags.Name()) + CmdFlags.PrintDefaults() } } +func doShow (reader io.Reader, logger *zap.SugaredLogger) { + + dat, err := ioutil.ReadAll(reader) + if err != nil { + panic(err) + } + + fmt.Println(string(dat)) + + return +} + func Cmd(log *zap.SugaredLogger) { - if err := DatabaseFlags.Parse(flag.Args()[1:]); err != nil { - DatabaseFlags.Usage() + if err := CmdFlags.Parse(flag.Args()[1:]); err != nil { + CmdFlags.Usage() os.Exit(1) } - //if DatabaseFlags.NFlag() > 4 { - // DatabaseFlags.Usage() + //if CmdFlags.NFlag() > 4 { + // CmdFlags.Usage() // os.Exit(1) //} if len(createYaml.Value) < 1 { - DatabaseFlags.Usage() + CmdFlags.Usage() os.Exit(1) } registry := admin.DatabaseCreateRequest{} content, err := ioutil.ReadFile(createYaml.Value) - //content, err := os.Open(createYaml.Value) if err != nil { log.Fatal(err) } - //fmt.Printf("File contents: %s\n\n", content) - - if err = yaml.Unmarshal([]byte(content), ®istry); err != nil { + if err = yaml.Unmarshal(content, ®istry); err != nil { log.Fatalf("cannot unmarshal data: %v", err) } - //unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} - - //if err = unmarshaller.Unmarshal(content, ®istry); err != nil { - // panic(err) - //} - - //fmt.Printf("%+v:\n", registry) - var data *bytes.Buffer data = bytes.NewBuffer(nil) @@ -104,54 +103,9 @@ func Cmd(log *zap.SugaredLogger) { log.Fatal(err) } - url := fmt.Sprintf("%s%s/create", *endpoint, defaultPath) - - log.Debugf("url:%s:\n", url) - - client := &http.Client{} - - req, err := http.NewRequest(http.MethodPost, url, data) - req.Header.Add("Content-Type", "application/json") - - resp, err := client.Do(req) - if err != nil { - panic(err) - - } - defer func() { - ioutil.ReadAll(resp.Body) - resp.Body.Close() - }() - - //// printout the json - //// no need to unmarshal it - //if *showAll { - dat, err := ioutil.ReadAll(resp.Body) - if err != nil { - panic(err) - } - - fmt.Println(string(dat)) - - return - //} - + url := fmt.Sprintf("%s%s/create", *common.EndPoint, defaultPath) - //old stuff - // - //unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} - // - //err = unmarshaller.Unmarshal(resp.Body, ®istry) - //if err != nil { - // panic(err) - //} - // - //log.Debug(registry) - //log.Debugf("%#v\n", *showAll) - // - //for k, _ := range registry.Registry.Namespaces { - // fmt.Println(k) - //} + common.DoPost(url, data, log, doShow) return } diff --git a/src/cmd/tools/q/main/main.go b/src/cmd/tools/q/main/main.go index 80447a8322..bd18635efe 100644 --- a/src/cmd/tools/q/main/main.go +++ b/src/cmd/tools/q/main/main.go @@ -48,9 +48,9 @@ Usage of %s: `, os.Args[0], strings.Join([]string{ - database.DatabaseFlags.Name(), - placements.GetFlags.Name(), - namespaces.GetFlags.Name(), + database.CmdFlags.Name(), + placements.CmdFlags.Name(), + namespaces.CmdFlags.Name(), }, ", ")) flag.PrintDefaults() @@ -71,17 +71,17 @@ Usage of %s: log := rawLogger.Sugar() switch flag.Arg(0) { - case database.DatabaseFlags.Name(): + case database.CmdFlags.Name(): database.Cmd(log) - case namespaces.GetFlags.Name(): + case namespaces.CmdFlags.Name(): - namespaces.Get(log) + namespaces.Cmd(log) - case placements.GetFlags.Name(): + case placements.CmdFlags.Name(): - placements.Get(log) + placements.Cmd(log) default: flag.Usage() diff --git a/src/cmd/tools/q/main/namespaces/cmd.go b/src/cmd/tools/q/main/namespaces/cmd.go new file mode 100644 index 0000000000..7d65e31655 --- /dev/null +++ b/src/cmd/tools/q/main/namespaces/cmd.go @@ -0,0 +1,116 @@ +package namespaces + +import ( + "flag" + "fmt" + "go.uber.org/zap" + "io" + "io/ioutil" + "os" + + "github.com/gogo/protobuf/jsonpb" + "github.com/m3db/m3/src/cmd/tools/q/main/common" + "github.com/m3db/m3/src/query/generated/proto/admin" +) + +var ( + CmdFlags *flag.FlagSet + //endpoint *string + showAll *bool + defaultPath = "/api/v1/namespace" + debugQS = "debug=true" + delete *string +) + +func init() { + CmdFlags = flag.NewFlagSet("ns", flag.ExitOnError) + delete = CmdFlags.String("delete", "", "name of namespace to delete") + showAll = CmdFlags.Bool("all", false, "show all the standard info for namespaces (otherwise default behaviour lists only the names)") + CmdFlags.Usage = func() { + fmt.Fprintf(CmdFlags.Output(), ` +Description: + +namespace tasks + +Usage of %s: + +`, CmdFlags.Name()) + CmdFlags.PrintDefaults() + } +} + + +func doShowAll(in io.Reader, log *zap.SugaredLogger) { + + dat, err := ioutil.ReadAll(in) + if err != nil { + panic(err) + } + + fmt.Println(string(dat)) +} + +//curl -s -k -v 'http://localhost:7201/api/v1/namespace?debug=true' | jq .registry.namespaces\|keys +func doShowNames(in io.Reader, log *zap.SugaredLogger) { + + registry := admin.NamespaceGetResponse{} + + unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} + + if err := unmarshaller.Unmarshal(in, ®istry); err != nil { + panic(err) + } + + log.Debug(registry) + + for k, _ := range registry.Registry.Namespaces { + fmt.Println(k) + } +} + +//curl -v -X DELETE bmcqueen-ld1:7201/api/v1/services/m3db/namespace/metrics_10s_48h +func doDelete(reader io.Reader, logger *zap.SugaredLogger) { + + dat, err := ioutil.ReadAll(reader) + if err != nil { + panic(err) + } + + fmt.Println(string(dat)) + + return +} + +func Cmd(log *zap.SugaredLogger) { + + if err := CmdFlags.Parse(flag.Args()[1:]); err != nil { + CmdFlags.Usage() + os.Exit(1) + } + + //if CmdFlags.NFlag() > 4 { + // CmdFlags.Usage() + // os.Exit(1) + //} + + url := fmt.Sprintf("%s%s?%s", *common.EndPoint, defaultPath, debugQS) + + if *showAll { + + common.DoGet(url, log, doShowAll) + + } else if len(*delete) > 0 { + + url = fmt.Sprintf("%s%s/%s", *common.EndPoint, "/api/v1/services/m3db/namespace", *delete) + + common.DoDelete(url, log, doDelete) + + } else { + + common.DoGet(url, log, doShowNames) + + } + + + return +} diff --git a/src/cmd/tools/q/main/namespaces/get.go b/src/cmd/tools/q/main/namespaces/get.go deleted file mode 100644 index 855bf6a5d7..0000000000 --- a/src/cmd/tools/q/main/namespaces/get.go +++ /dev/null @@ -1,107 +0,0 @@ -package namespaces - -import ( - "flag" - "fmt" - "go.uber.org/zap" - "io/ioutil" - "net/http" - "os" - - "github.com/gogo/protobuf/jsonpb" - "github.com/m3db/m3/src/query/generated/proto/admin" -) - -var ( - GetFlags *flag.FlagSet - endpoint *string - showAll *bool - defaultPath = "/api/v1/namespace" - debugQS = "debug=true" - delete *string -) - -//curl -s -k -v 'http://localhost:7201/api/v1/namespace?debug=true' | jq .registry.namespaces\|keys - -//curl -v -X DELETE bmcqueen-ld1:7201/api/v1/services/m3db/namespace/metrics_10s_48h - -func init() { - GetFlags = flag.NewFlagSet("namespaces", flag.ExitOnError) - endpoint = GetFlags.String("endpoint", "http://bmcqueen-ld1:7201", "url for endpoint") - endpoint = GetFlags.String("delete", "", "name of namespace to delete") - showAll = GetFlags.Bool("all", false, "show all the standard info for namespaces (otherwise default behaviour lists only the names)") - GetFlags.Usage = func() { - fmt.Fprintf(GetFlags.Output(), ` -Description: - -blah blah - - -Usage of %s: - -`, GetFlags.Name()) - GetFlags.PrintDefaults() - } -} - -func Get(log *zap.SugaredLogger) { - - if err := GetFlags.Parse(flag.Args()[1:]); err != nil { - GetFlags.Usage() - os.Exit(1) - } - - //if GetFlags.NFlag() > 4 { - // GetFlags.Usage() - // os.Exit(1) - //} - - registry := admin.NamespaceGetResponse{} - - url := fmt.Sprintf("%s%s?%s", *endpoint, defaultPath, debugQS) - - log.Debugf("url:%s:\n", url) - - resp, err := http.Get(url) - if err != nil { - panic(err) - } - - defer func() { - ioutil.ReadAll(resp.Body) - resp.Body.Close() - }() - - if err != nil { - panic(err) - } - - // printout the json - // no need to unmarshal it - if *showAll { - dat, err := ioutil.ReadAll(resp.Body) - if err != nil { - panic(err) - } - - fmt.Println(string(dat)) - - return - } - - unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} - - err = unmarshaller.Unmarshal(resp.Body, ®istry) - if err != nil { - panic(err) - } - - log.Debug(registry) - log.Debugf("%#v\n", *showAll) - - for k, _ := range registry.Registry.Namespaces { - fmt.Println(k) - } - - return -} diff --git a/src/cmd/tools/q/main/placements/cmd.go b/src/cmd/tools/q/main/placements/cmd.go new file mode 100644 index 0000000000..8d528a682a --- /dev/null +++ b/src/cmd/tools/q/main/placements/cmd.go @@ -0,0 +1,120 @@ +package placements + +import ( + "bytes" + "flag" + "fmt" + "go.uber.org/zap" + "io" + "io/ioutil" + "os" + + "github.com/gogo/protobuf/jsonpb" + "github.com/m3db/m3/src/query/generated/proto/admin" + "github.com/m3db/m3/src/cmd/tools/q/main/common" + "github.com/m3db/m3/src/cmd/tools/q/main/flagvar" + "github.com/ghodss/yaml" + +) + +var ( + CmdFlags *flag.FlagSet + defaultPath = "/api/v1/services/m3db/placement" + delete *bool + deleteNode *string + newNode = flagvar.File{} +) + +//curl -s -k -v 'http://localhost:7201/api/v1/placement' + +//curl -v -X DELETE bmcqueen-ld1:7201/api/v1/services/m3db/placement + +func init() { + CmdFlags = flag.NewFlagSet("pl", flag.ExitOnError) + delete = CmdFlags.Bool("deleteAll", false, "delete all instances in the placement") + deleteNode = CmdFlags.String("deleteNode", "", "delete the specified node in the placement") + CmdFlags.Var(&newNode, "newNode", "add a new node to the placement. Specify the filename of the yaml.") + //CmdFlags.Var(&createYaml, "create", "Path to yaml for simplified db creation with sane defaults.") + + CmdFlags.Usage = func() { + fmt.Fprintf(CmdFlags.Output(), ` +Description: + +placement tasks + +Usage of %s: + +`, CmdFlags.Name()) + CmdFlags.PrintDefaults() + } +} + +func doShowAll(in io.Reader, log *zap.SugaredLogger) { + + dat, err := ioutil.ReadAll(in) + if err != nil { + panic(err) + } + + fmt.Println(string(dat)) +} + +func Cmd(log *zap.SugaredLogger) { + + if err := CmdFlags.Parse(flag.Args()[1:]); err != nil { + CmdFlags.Usage() + os.Exit(1) + } + + //if CmdFlags.NFlag() > 4 { + // CmdFlags.Usage() + // os.Exit(1) + //} + + if len(*deleteNode) > 0 { + + url := fmt.Sprintf("%s%s/%s", *common.EndPoint, defaultPath, *deleteNode) + + common.DoDelete(url, log, doShowAll) + + } else if len(newNode.Value) > 0 { + + registry := admin.PlacementInitRequest{} + + content, err := ioutil.ReadFile(newNode.Value) + if err != nil { + log.Fatal(err) + } + + if err = yaml.Unmarshal(content, ®istry); err != nil { + log.Fatalf("cannot unmarshal data: %v", err) + } + + var data *bytes.Buffer + data = bytes.NewBuffer(nil) + + marshaller := &jsonpb.Marshaler{} + if err = marshaller.Marshal(data, ®istry); err != nil { + log.Fatal(err) + } + + url := fmt.Sprintf("%s%s", *common.EndPoint, defaultPath) + + common.DoPost(url, data, log, doShowAll) + + } else if *delete { + + url := fmt.Sprintf("%s%s", *common.EndPoint, defaultPath) + + common.DoDelete(url, log, doShowAll) + + } else { + + url := fmt.Sprintf("%s%s", *common.EndPoint, defaultPath) + + common.DoGet(url, log, doShowAll) + + } + + return +} diff --git a/src/cmd/tools/q/main/placements/examples/newNode.yaml b/src/cmd/tools/q/main/placements/examples/newNode.yaml new file mode 100644 index 0000000000..a8308ba9d8 --- /dev/null +++ b/src/cmd/tools/q/main/placements/examples/newNode.yaml @@ -0,0 +1,10 @@ +--- +instances: + - id: node1 + isolationGroup: isoGroup1 + zone: etcdZone1 + weight: 100 + endpoint: targetHostname1:9000 + hostname: newNodeHostname1 + port: 9000 + diff --git a/src/cmd/tools/q/main/placements/get.go b/src/cmd/tools/q/main/placements/get.go deleted file mode 100644 index af7b647dbc..0000000000 --- a/src/cmd/tools/q/main/placements/get.go +++ /dev/null @@ -1,103 +0,0 @@ -package placements - -import ( - "flag" - "fmt" - "go.uber.org/zap" - "io/ioutil" - "net/http" - "os" - - //"github.com/gogo/protobuf/jsonpb" - //"github.com/m3db/m3/src/query/generated/proto/admin" -) - -var ( - GetFlags *flag.FlagSet - endpoint *string - defaultPath = "/api/v1/placement" -) - -//curl -s -k -v 'http://localhost:7201/api/v1/placement' - -//curl -v -X DELETE bmcqueen-ld1:7201/api/v1/services/m3db/placement - -func init() { - GetFlags = flag.NewFlagSet("placements", flag.ExitOnError) - endpoint = GetFlags.String("endpoint", "http://bmcqueen-ld1:7201", "url for endpoint") - //showAll = GetFlags.Bool("all", false, "show standard info for namespaces (default is to list only the names)") - GetFlags.Usage = func() { - fmt.Fprintf(GetFlags.Output(), ` -Description: - -blah blah - - -Usage of %s: - -`, GetFlags.Name()) - GetFlags.PrintDefaults() - } -} - -func Get(log *zap.SugaredLogger) { - - if err := GetFlags.Parse(flag.Args()[1:]); err != nil { - GetFlags.Usage() - os.Exit(1) - } - - //if GetFlags.NFlag() > 4 { - // GetFlags.Usage() - // os.Exit(1) - //} - - //registry := admin.PlacementGetResponse{} - - url := fmt.Sprintf("%s%s", *endpoint, defaultPath) - - log.Debugf("url:%s:\n", url) - - resp, err := http.Get(url) - if err != nil { - panic(err) - } - - defer func() { - ioutil.ReadAll(resp.Body) - resp.Body.Close() - }() - - if err != nil { - panic(err) - } - - // printout the json - // no need to unmarshal it - //if *showAll { - dat, err := ioutil.ReadAll(resp.Body) - if err != nil { - panic(err) - } - - fmt.Println(string(dat)) - - return - //} - - //unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} - // - //err = unmarshaller.Unmarshal(resp.Body, ®istry) - //if err != nil { - // panic(err) - //} - // - //log.Debug(registry) - //log.Debugf("%#v\n", *showAll) - // - //for k, _ := range registry.Registry.Namespaces { - // fmt.Println(k) - //} - - return -} From 040a2b4b1f865db7772390b61fd1dc471bdbca97 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Tue, 7 Jan 2020 20:33:38 -0800 Subject: [PATCH 05/65] added placement init --- src/cmd/tools/q/main/common/http.go | 2 ++ src/cmd/tools/q/main/placements/cmd.go | 27 +++++++++++++++++++ .../q/main/placements/examples/init.yaml | 25 +++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 src/cmd/tools/q/main/placements/examples/init.yaml diff --git a/src/cmd/tools/q/main/common/http.go b/src/cmd/tools/q/main/common/http.go index 3b60cfa672..2be8029f09 100644 --- a/src/cmd/tools/q/main/common/http.go +++ b/src/cmd/tools/q/main/common/http.go @@ -54,6 +54,8 @@ func DoPost(url string, data io.Reader, logger *zap.SugaredLogger, getter func(r resp.Body.Close() }() + logger.Debugf("resp:%d:\n", resp.StatusCode) + getter(resp.Body, logger) } diff --git a/src/cmd/tools/q/main/placements/cmd.go b/src/cmd/tools/q/main/placements/cmd.go index 8d528a682a..590aacfb01 100644 --- a/src/cmd/tools/q/main/placements/cmd.go +++ b/src/cmd/tools/q/main/placements/cmd.go @@ -22,6 +22,7 @@ var ( defaultPath = "/api/v1/services/m3db/placement" delete *bool deleteNode *string + initFlag = flagvar.File{} newNode = flagvar.File{} ) @@ -33,6 +34,7 @@ func init() { CmdFlags = flag.NewFlagSet("pl", flag.ExitOnError) delete = CmdFlags.Bool("deleteAll", false, "delete all instances in the placement") deleteNode = CmdFlags.String("deleteNode", "", "delete the specified node in the placement") + CmdFlags.Var( &initFlag, "init", "initialize a placement. Specify a yaml file.") CmdFlags.Var(&newNode, "newNode", "add a new node to the placement. Specify the filename of the yaml.") //CmdFlags.Var(&createYaml, "create", "Path to yaml for simplified db creation with sane defaults.") @@ -102,6 +104,31 @@ func Cmd(log *zap.SugaredLogger) { common.DoPost(url, data, log, doShowAll) + } else if len(initFlag.Value) > 0 { + + registry := admin.PlacementInitRequest{} + + content, err := ioutil.ReadFile(initFlag.Value) + if err != nil { + log.Fatal(err) + } + + if err = yaml.Unmarshal(content, ®istry); err != nil { + log.Fatalf("cannot unmarshal data: %v", err) + } + + var data *bytes.Buffer + data = bytes.NewBuffer(nil) + + marshaller := &jsonpb.Marshaler{} + if err = marshaller.Marshal(data, ®istry); err != nil { + log.Fatal(err) + } + + url := fmt.Sprintf("%s%s%s", *common.EndPoint, defaultPath, "/init") + + common.DoPost(url, data, log, doShowAll) + } else if *delete { url := fmt.Sprintf("%s%s", *common.EndPoint, defaultPath) diff --git a/src/cmd/tools/q/main/placements/examples/init.yaml b/src/cmd/tools/q/main/placements/examples/init.yaml new file mode 100644 index 0000000000..9f9f1f2e40 --- /dev/null +++ b/src/cmd/tools/q/main/placements/examples/init.yaml @@ -0,0 +1,25 @@ +--- +num_shards: 64 +replication_factor: 1 +instances: + - id: nodeid1 + isolation_group: isogroup1 + zone: etcd1 + weight: 100 + endpoint: node1:9000 + hostname: node1 + port: 9000 + - id: nodeid2 + isolation_group: isogroup2 + zone: etcd1 + weight: 100 + endpoint: node2:9000 + hostname: node2 + port: 9000 + - id: nodeid3 + isolation_group: isogroup3 + zone: etcd1 + weight: 100 + endpoint: node3:9000 + hostname: node3 + port: 9000 From 8e86a943129205bab1e23b88a2c4957e5db72410 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Wed, 8 Jan 2020 10:14:16 -0800 Subject: [PATCH 06/65] factored --- src/cmd/tools/q/main/common/http.go | 9 ++- src/cmd/tools/q/main/common/yaml.go | 35 ++++++++++++ src/cmd/tools/q/main/database/cmd.go | 37 +----------- src/cmd/tools/q/main/namespaces/cmd.go | 8 +-- src/cmd/tools/q/main/placements/cmd.go | 56 +++---------------- .../q/main/placements/examples/newNode.yaml | 2 +- .../main/placements/examples/replaceNode.yaml | 12 ++++ 7 files changed, 67 insertions(+), 92 deletions(-) create mode 100644 src/cmd/tools/q/main/common/yaml.go create mode 100644 src/cmd/tools/q/main/placements/examples/replaceNode.yaml diff --git a/src/cmd/tools/q/main/common/http.go b/src/cmd/tools/q/main/common/http.go index 2be8029f09..88cb168ba3 100644 --- a/src/cmd/tools/q/main/common/http.go +++ b/src/cmd/tools/q/main/common/http.go @@ -19,7 +19,7 @@ func init() { func DoGet(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { - logger.Debugf("url:%s:\n", url) + logger.Debugf("DoGet:url:%s:\n", url) resp, err := http.Get(url) if err != nil { @@ -37,7 +37,7 @@ func DoGet(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, func DoPost(url string, data io.Reader, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { - logger.Debugf("url:%s:\n", url) + logger.Debugf("DoPost:url:%s:\n", url) client := &http.Client{} @@ -54,7 +54,7 @@ func DoPost(url string, data io.Reader, logger *zap.SugaredLogger, getter func(r resp.Body.Close() }() - logger.Debugf("resp:%d:\n", resp.StatusCode) + logger.Debugf("resp.StatusCode:%d:\n", resp.StatusCode) getter(resp.Body, logger) @@ -62,7 +62,7 @@ func DoPost(url string, data io.Reader, logger *zap.SugaredLogger, getter func(r func DoDelete(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { - logger.Debugf("url:%s:\n", url) + logger.Debugf("DoDelete:url:%s:\n", url) client := &http.Client{} @@ -82,4 +82,3 @@ func DoDelete(url string, logger *zap.SugaredLogger, getter func(reader io.Reade getter(resp.Body, logger) } - diff --git a/src/cmd/tools/q/main/common/yaml.go b/src/cmd/tools/q/main/common/yaml.go new file mode 100644 index 0000000000..35a0669a1a --- /dev/null +++ b/src/cmd/tools/q/main/common/yaml.go @@ -0,0 +1,35 @@ +package common + +import ( + "bytes" + "github.com/ghodss/yaml" + "github.com/gogo/protobuf/jsonpb" + "github.com/gogo/protobuf/proto" + "go.uber.org/zap" + "io" + "io/ioutil" +) + +func LoadYaml(path string, target proto.Message, log *zap.SugaredLogger) io.Reader { + + log.Debugf("path:%s:\n", path) + + content, err := ioutil.ReadFile(path) + if err != nil { + log.Fatal(err) + } + + if err = yaml.Unmarshal(content, target); err != nil { + log.Fatalf("cannot unmarshal data: %v", err) + } + + var data *bytes.Buffer + data = bytes.NewBuffer(nil) + + marshaller := &jsonpb.Marshaler{} + if err = marshaller.Marshal(data, target); err != nil { + log.Fatal(err) + } + + return data +} diff --git a/src/cmd/tools/q/main/database/cmd.go b/src/cmd/tools/q/main/database/cmd.go index b1846fe908..d965ab81af 100644 --- a/src/cmd/tools/q/main/database/cmd.go +++ b/src/cmd/tools/q/main/database/cmd.go @@ -1,29 +1,15 @@ package database import ( - "bytes" - "io" - //"bytes" - //"encoding/json" "flag" "fmt" "go.uber.org/zap" + "io" "io/ioutil" - //"io/ioutil" - //"net/http" - - //"k8s.io/gengo/testdata/a/b" - - "github.com/ghodss/yaml" - - //"io/ioutil" - //"net/http" "os" - "github.com/gogo/protobuf/jsonpb" "github.com/m3db/m3/src/cmd/tools/q/main/common" - //"gopkg.in/yaml.v2" "github.com/m3db/m3/src/cmd/tools/q/main/flagvar" "github.com/m3db/m3/src/query/generated/proto/admin" ) @@ -55,7 +41,7 @@ Usage of %s: } } -func doShow (reader io.Reader, logger *zap.SugaredLogger) { +func doShow(reader io.Reader, logger *zap.SugaredLogger) { dat, err := ioutil.ReadAll(reader) if err != nil { @@ -84,24 +70,7 @@ func Cmd(log *zap.SugaredLogger) { os.Exit(1) } - registry := admin.DatabaseCreateRequest{} - - content, err := ioutil.ReadFile(createYaml.Value) - if err != nil { - log.Fatal(err) - } - - if err = yaml.Unmarshal(content, ®istry); err != nil { - log.Fatalf("cannot unmarshal data: %v", err) - } - - var data *bytes.Buffer - data = bytes.NewBuffer(nil) - - marshaller := &jsonpb.Marshaler{} - if err = marshaller.Marshal(data, ®istry); err != nil { - log.Fatal(err) - } + data := common.LoadYaml(createYaml.Value, &admin.DatabaseCreateRequest{}, log) url := fmt.Sprintf("%s%s/create", *common.EndPoint, defaultPath) diff --git a/src/cmd/tools/q/main/namespaces/cmd.go b/src/cmd/tools/q/main/namespaces/cmd.go index 7d65e31655..14a94ea31e 100644 --- a/src/cmd/tools/q/main/namespaces/cmd.go +++ b/src/cmd/tools/q/main/namespaces/cmd.go @@ -14,11 +14,11 @@ import ( ) var ( - CmdFlags *flag.FlagSet + CmdFlags *flag.FlagSet //endpoint *string showAll *bool - defaultPath = "/api/v1/namespace" - debugQS = "debug=true" + defaultPath = "/api/v1/namespace" + debugQS = "debug=true" delete *string ) @@ -39,7 +39,6 @@ Usage of %s: } } - func doShowAll(in io.Reader, log *zap.SugaredLogger) { dat, err := ioutil.ReadAll(in) @@ -111,6 +110,5 @@ func Cmd(log *zap.SugaredLogger) { } - return } diff --git a/src/cmd/tools/q/main/placements/cmd.go b/src/cmd/tools/q/main/placements/cmd.go index 590aacfb01..69eb1ab1ba 100644 --- a/src/cmd/tools/q/main/placements/cmd.go +++ b/src/cmd/tools/q/main/placements/cmd.go @@ -1,7 +1,6 @@ package placements import ( - "bytes" "flag" "fmt" "go.uber.org/zap" @@ -9,21 +8,18 @@ import ( "io/ioutil" "os" - "github.com/gogo/protobuf/jsonpb" - "github.com/m3db/m3/src/query/generated/proto/admin" "github.com/m3db/m3/src/cmd/tools/q/main/common" "github.com/m3db/m3/src/cmd/tools/q/main/flagvar" - "github.com/ghodss/yaml" - + "github.com/m3db/m3/src/query/generated/proto/admin" ) var ( CmdFlags *flag.FlagSet - defaultPath = "/api/v1/services/m3db/placement" - delete *bool - deleteNode *string - initFlag = flagvar.File{} - newNode = flagvar.File{} + defaultPath = "/api/v1/services/m3db/placement" + delete *bool + deleteNode *string + initFlag = flagvar.File{} + newNode = flagvar.File{} ) //curl -s -k -v 'http://localhost:7201/api/v1/placement' @@ -34,7 +30,7 @@ func init() { CmdFlags = flag.NewFlagSet("pl", flag.ExitOnError) delete = CmdFlags.Bool("deleteAll", false, "delete all instances in the placement") deleteNode = CmdFlags.String("deleteNode", "", "delete the specified node in the placement") - CmdFlags.Var( &initFlag, "init", "initialize a placement. Specify a yaml file.") + CmdFlags.Var(&initFlag, "init", "initialize a placement. Specify a yaml file.") CmdFlags.Var(&newNode, "newNode", "add a new node to the placement. Specify the filename of the yaml.") //CmdFlags.Var(&createYaml, "create", "Path to yaml for simplified db creation with sane defaults.") @@ -81,24 +77,7 @@ func Cmd(log *zap.SugaredLogger) { } else if len(newNode.Value) > 0 { - registry := admin.PlacementInitRequest{} - - content, err := ioutil.ReadFile(newNode.Value) - if err != nil { - log.Fatal(err) - } - - if err = yaml.Unmarshal(content, ®istry); err != nil { - log.Fatalf("cannot unmarshal data: %v", err) - } - - var data *bytes.Buffer - data = bytes.NewBuffer(nil) - - marshaller := &jsonpb.Marshaler{} - if err = marshaller.Marshal(data, ®istry); err != nil { - log.Fatal(err) - } + data := common.LoadYaml(newNode.Value, &admin.PlacementInitRequest{}, log) url := fmt.Sprintf("%s%s", *common.EndPoint, defaultPath) @@ -106,24 +85,7 @@ func Cmd(log *zap.SugaredLogger) { } else if len(initFlag.Value) > 0 { - registry := admin.PlacementInitRequest{} - - content, err := ioutil.ReadFile(initFlag.Value) - if err != nil { - log.Fatal(err) - } - - if err = yaml.Unmarshal(content, ®istry); err != nil { - log.Fatalf("cannot unmarshal data: %v", err) - } - - var data *bytes.Buffer - data = bytes.NewBuffer(nil) - - marshaller := &jsonpb.Marshaler{} - if err = marshaller.Marshal(data, ®istry); err != nil { - log.Fatal(err) - } + data := common.LoadYaml(initFlag.Value, &admin.PlacementInitRequest{}, log) url := fmt.Sprintf("%s%s%s", *common.EndPoint, defaultPath, "/init") diff --git a/src/cmd/tools/q/main/placements/examples/newNode.yaml b/src/cmd/tools/q/main/placements/examples/newNode.yaml index a8308ba9d8..d1a3af2d23 100644 --- a/src/cmd/tools/q/main/placements/examples/newNode.yaml +++ b/src/cmd/tools/q/main/placements/examples/newNode.yaml @@ -2,7 +2,7 @@ instances: - id: node1 isolationGroup: isoGroup1 - zone: etcdZone1 + zone: embedded weight: 100 endpoint: targetHostname1:9000 hostname: newNodeHostname1 diff --git a/src/cmd/tools/q/main/placements/examples/replaceNode.yaml b/src/cmd/tools/q/main/placements/examples/replaceNode.yaml new file mode 100644 index 0000000000..f16eaaae84 --- /dev/null +++ b/src/cmd/tools/q/main/placements/examples/replaceNode.yaml @@ -0,0 +1,12 @@ +--- +leavingInstanceIDs: +- oldnodeid1 +candidates: +- id: newnodeid1 + isolationGroup: newnodeisogroup1 + zone: etcdzone1 + weight: 100 + endpoint: node11:9000 + hostname: node11 + port: 9000 + From f8579641f30482f4f909c11646d347b82b7acafe Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Wed, 8 Jan 2020 10:29:30 -0800 Subject: [PATCH 07/65] factoring --- src/cmd/tools/q/main/common/http.go | 11 +++++++ src/cmd/tools/q/main/database/cmd.go | 17 +---------- src/cmd/tools/q/main/namespaces/cmd.go | 31 ++----------------- src/cmd/tools/q/main/placements/cmd.go | 41 ++++++++++++-------------- 4 files changed, 34 insertions(+), 66 deletions(-) diff --git a/src/cmd/tools/q/main/common/http.go b/src/cmd/tools/q/main/common/http.go index 88cb168ba3..748c22e6bd 100644 --- a/src/cmd/tools/q/main/common/http.go +++ b/src/cmd/tools/q/main/common/http.go @@ -2,6 +2,7 @@ package common import ( "flag" + "fmt" "go.uber.org/zap" "io" "io/ioutil" @@ -82,3 +83,13 @@ func DoDelete(url string, logger *zap.SugaredLogger, getter func(reader io.Reade getter(resp.Body, logger) } + +func DoDump(in io.Reader, log *zap.SugaredLogger) { + + dat, err := ioutil.ReadAll(in) + if err != nil { + panic(err) + } + + fmt.Println(string(dat)) +} diff --git a/src/cmd/tools/q/main/database/cmd.go b/src/cmd/tools/q/main/database/cmd.go index d965ab81af..0971fc0239 100644 --- a/src/cmd/tools/q/main/database/cmd.go +++ b/src/cmd/tools/q/main/database/cmd.go @@ -4,9 +4,6 @@ import ( "flag" "fmt" "go.uber.org/zap" - "io" - "io/ioutil" - "os" "github.com/m3db/m3/src/cmd/tools/q/main/common" @@ -41,18 +38,6 @@ Usage of %s: } } -func doShow(reader io.Reader, logger *zap.SugaredLogger) { - - dat, err := ioutil.ReadAll(reader) - if err != nil { - panic(err) - } - - fmt.Println(string(dat)) - - return -} - func Cmd(log *zap.SugaredLogger) { if err := CmdFlags.Parse(flag.Args()[1:]); err != nil { @@ -74,7 +59,7 @@ func Cmd(log *zap.SugaredLogger) { url := fmt.Sprintf("%s%s/create", *common.EndPoint, defaultPath) - common.DoPost(url, data, log, doShow) + common.DoPost(url, data, log, common.DoDump) return } diff --git a/src/cmd/tools/q/main/namespaces/cmd.go b/src/cmd/tools/q/main/namespaces/cmd.go index 14a94ea31e..ac9edb19fb 100644 --- a/src/cmd/tools/q/main/namespaces/cmd.go +++ b/src/cmd/tools/q/main/namespaces/cmd.go @@ -5,7 +5,6 @@ import ( "fmt" "go.uber.org/zap" "io" - "io/ioutil" "os" "github.com/gogo/protobuf/jsonpb" @@ -14,8 +13,7 @@ import ( ) var ( - CmdFlags *flag.FlagSet - //endpoint *string + CmdFlags *flag.FlagSet showAll *bool defaultPath = "/api/v1/namespace" debugQS = "debug=true" @@ -39,16 +37,6 @@ Usage of %s: } } -func doShowAll(in io.Reader, log *zap.SugaredLogger) { - - dat, err := ioutil.ReadAll(in) - if err != nil { - panic(err) - } - - fmt.Println(string(dat)) -} - //curl -s -k -v 'http://localhost:7201/api/v1/namespace?debug=true' | jq .registry.namespaces\|keys func doShowNames(in io.Reader, log *zap.SugaredLogger) { @@ -67,19 +55,6 @@ func doShowNames(in io.Reader, log *zap.SugaredLogger) { } } -//curl -v -X DELETE bmcqueen-ld1:7201/api/v1/services/m3db/namespace/metrics_10s_48h -func doDelete(reader io.Reader, logger *zap.SugaredLogger) { - - dat, err := ioutil.ReadAll(reader) - if err != nil { - panic(err) - } - - fmt.Println(string(dat)) - - return -} - func Cmd(log *zap.SugaredLogger) { if err := CmdFlags.Parse(flag.Args()[1:]); err != nil { @@ -96,13 +71,13 @@ func Cmd(log *zap.SugaredLogger) { if *showAll { - common.DoGet(url, log, doShowAll) + common.DoGet(url, log, common.DoDump) } else if len(*delete) > 0 { url = fmt.Sprintf("%s%s/%s", *common.EndPoint, "/api/v1/services/m3db/namespace", *delete) - common.DoDelete(url, log, doDelete) + common.DoDelete(url, log, common.DoDump) } else { diff --git a/src/cmd/tools/q/main/placements/cmd.go b/src/cmd/tools/q/main/placements/cmd.go index 69eb1ab1ba..1702422d90 100644 --- a/src/cmd/tools/q/main/placements/cmd.go +++ b/src/cmd/tools/q/main/placements/cmd.go @@ -4,8 +4,6 @@ import ( "flag" "fmt" "go.uber.org/zap" - "io" - "io/ioutil" "os" "github.com/m3db/m3/src/cmd/tools/q/main/common" @@ -19,7 +17,8 @@ var ( delete *bool deleteNode *string initFlag = flagvar.File{} - newNode = flagvar.File{} + newNodeFlag = flagvar.File{} + replaceFlag = flagvar.File{} ) //curl -s -k -v 'http://localhost:7201/api/v1/placement' @@ -31,8 +30,8 @@ func init() { delete = CmdFlags.Bool("deleteAll", false, "delete all instances in the placement") deleteNode = CmdFlags.String("deleteNode", "", "delete the specified node in the placement") CmdFlags.Var(&initFlag, "init", "initialize a placement. Specify a yaml file.") - CmdFlags.Var(&newNode, "newNode", "add a new node to the placement. Specify the filename of the yaml.") - //CmdFlags.Var(&createYaml, "create", "Path to yaml for simplified db creation with sane defaults.") + CmdFlags.Var(&newNodeFlag, "newNode", "add a new node to the placement. Specify the filename of the yaml.") + CmdFlags.Var(&replaceFlag, "replaceNode", "add a new node to the placement. Specify the filename of the yaml.") CmdFlags.Usage = func() { fmt.Fprintf(CmdFlags.Output(), ` @@ -47,16 +46,6 @@ Usage of %s: } } -func doShowAll(in io.Reader, log *zap.SugaredLogger) { - - dat, err := ioutil.ReadAll(in) - if err != nil { - panic(err) - } - - fmt.Println(string(dat)) -} - func Cmd(log *zap.SugaredLogger) { if err := CmdFlags.Parse(flag.Args()[1:]); err != nil { @@ -73,15 +62,15 @@ func Cmd(log *zap.SugaredLogger) { url := fmt.Sprintf("%s%s/%s", *common.EndPoint, defaultPath, *deleteNode) - common.DoDelete(url, log, doShowAll) + common.DoDelete(url, log, common.DoDump) - } else if len(newNode.Value) > 0 { + } else if len(newNodeFlag.Value) > 0 { - data := common.LoadYaml(newNode.Value, &admin.PlacementInitRequest{}, log) + data := common.LoadYaml(newNodeFlag.Value, &admin.PlacementInitRequest{}, log) url := fmt.Sprintf("%s%s", *common.EndPoint, defaultPath) - common.DoPost(url, data, log, doShowAll) + common.DoPost(url, data, log, common.DoDump) } else if len(initFlag.Value) > 0 { @@ -89,19 +78,27 @@ func Cmd(log *zap.SugaredLogger) { url := fmt.Sprintf("%s%s%s", *common.EndPoint, defaultPath, "/init") - common.DoPost(url, data, log, doShowAll) + common.DoPost(url, data, log, common.DoDump) + + } else if len(replaceFlag.Value) > 0 { + + data := common.LoadYaml(replaceFlag.Value, &admin.PlacementReplaceRequest{}, log) + + url := fmt.Sprintf("%s%s%s", *common.EndPoint, defaultPath, "/replace") + + common.DoPost(url, data, log, common.DoDump) } else if *delete { url := fmt.Sprintf("%s%s", *common.EndPoint, defaultPath) - common.DoDelete(url, log, doShowAll) + common.DoDelete(url, log, common.DoDump) } else { url := fmt.Sprintf("%s%s", *common.EndPoint, defaultPath) - common.DoGet(url, log, doShowAll) + common.DoGet(url, log, common.DoDump) } From 4330b01283ff398291881cd809140e94e972c89a Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Wed, 8 Jan 2020 10:46:35 -0800 Subject: [PATCH 08/65] cleanup --- src/cmd/tools/q/main/common/http.go | 22 +++++++++++++++++----- src/cmd/tools/q/main/namespaces/cmd.go | 4 +--- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/cmd/tools/q/main/common/http.go b/src/cmd/tools/q/main/common/http.go index 748c22e6bd..1af105d264 100644 --- a/src/cmd/tools/q/main/common/http.go +++ b/src/cmd/tools/q/main/common/http.go @@ -13,7 +13,7 @@ var ( EndPoint *string ) -// This is used across the commands +// This is used across all the commands func init() { EndPoint = flag.String("endpoint", "http://bmcqueen-ld1:7201", "url for endpoint") } @@ -24,7 +24,7 @@ func DoGet(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, resp, err := http.Get(url) if err != nil { - panic(err) + logger.Fatal(err) } defer func() { @@ -32,6 +32,10 @@ func DoGet(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, resp.Body.Close() }() + if resp.StatusCode > 299 { + logger.Fatal("error from m3db:%s:url:%s:", resp.Status, url) + } + getter(resp.Body, logger) } @@ -47,7 +51,7 @@ func DoPost(url string, data io.Reader, logger *zap.SugaredLogger, getter func(r resp, err := client.Do(req) if err != nil { - panic(err) + logger.Fatal(err) } defer func() { @@ -57,6 +61,10 @@ func DoPost(url string, data io.Reader, logger *zap.SugaredLogger, getter func(r logger.Debugf("resp.StatusCode:%d:\n", resp.StatusCode) + if resp.StatusCode > 299 { + logger.Fatal("error from m3db:%s:url:%s:", resp.Status, url) + } + getter(resp.Body, logger) } @@ -72,7 +80,7 @@ func DoDelete(url string, logger *zap.SugaredLogger, getter func(reader io.Reade resp, err := client.Do(req) if err != nil { - panic(err) + logger.Fatal(err) } defer func() { @@ -80,6 +88,10 @@ func DoDelete(url string, logger *zap.SugaredLogger, getter func(reader io.Reade resp.Body.Close() }() + if resp.StatusCode > 299 { + logger.Fatal("error from m3db:%s:url:%s:", resp.Status, url) + } + getter(resp.Body, logger) } @@ -88,7 +100,7 @@ func DoDump(in io.Reader, log *zap.SugaredLogger) { dat, err := ioutil.ReadAll(in) if err != nil { - panic(err) + log.Fatal(err) } fmt.Println(string(dat)) diff --git a/src/cmd/tools/q/main/namespaces/cmd.go b/src/cmd/tools/q/main/namespaces/cmd.go index ac9edb19fb..d9def755a0 100644 --- a/src/cmd/tools/q/main/namespaces/cmd.go +++ b/src/cmd/tools/q/main/namespaces/cmd.go @@ -45,11 +45,9 @@ func doShowNames(in io.Reader, log *zap.SugaredLogger) { unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} if err := unmarshaller.Unmarshal(in, ®istry); err != nil { - panic(err) + log.Fatal(err) } - log.Debug(registry) - for k, _ := range registry.Registry.Namespaces { fmt.Println(k) } From 9038a0a048e58c12ba2ff4e2e52573f37e49e039 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Wed, 8 Jan 2020 13:04:10 -0800 Subject: [PATCH 09/65] docs --- src/cmd/tools/q/main/README.md | 107 ++++++++++++++----------- src/cmd/tools/q/main/common/http.go | 32 +++++--- src/cmd/tools/q/main/common/yaml.go | 2 +- src/cmd/tools/q/main/database/cmd.go | 18 ++--- src/cmd/tools/q/main/main.go | 3 +- src/cmd/tools/q/main/namespaces/cmd.go | 24 ++++-- src/cmd/tools/q/main/placements/cmd.go | 33 +++++--- 7 files changed, 134 insertions(+), 85 deletions(-) diff --git a/src/cmd/tools/q/main/README.md b/src/cmd/tools/q/main/README.md index 81f6a1ee90..1ef11f0961 100644 --- a/src/cmd/tools/q/main/README.md +++ b/src/cmd/tools/q/main/README.md @@ -1,45 +1,62 @@ -#https://www.m3db.io/openapi/ - -per rob https://m3db.slack.com/archives/CKARJDKT2/p1577442957085600 -make it like https://www.vskills.in/certification/tutorial/big-data/apache-cassandra/nodetool/ - -try to get the curl's and operational tasks from this page into a tool -https://m3db.github.io/m3/how_to/kubernetes/ - -^Cbmcqueen-mn2:m3db bmcqueen$ kubectl port-forward svc/m3dbnode-persistent-cluster 9003 - -bmcqueen-mn2:m3db bmcqueen$ curl -v localhost:9003/health -* Trying 127.0.0.1... -* TCP_NODELAY set -* Connected to localhost (127.0.0.1) port 9003 (#0) -> GET /health HTTP/1.1 -> Host: localhost:9003 -> User-Agent: curl/7.64.1 -> Accept: */* -> -< HTTP/1.1 200 OK -< Content-Type: application/json -< Date: Sat, 04 Jan 2020 03:42:30 GMT -< Content-Length: 26 -< -{"ok":true,"status":"up"} -* Connection #0 to host localhost left intact -* Closing connection 0 -bmcqueen-mn2:m3db bmcqueen$ curl -v localhost:9003/health - - -initialize placement -list placements - -#https://m3db.github.io/m3/operational_guide/namespace_configuration/ -#https://www.m3db.io/openapi/#tag/M3DB-Namespace -list namespaces -creating a namespace -delete namespace - -db placements -#https://m3db.github.io/m3/operational_guide/placement_configuration/#removing-a-node -#https://www.m3db.io/openapi/#tag/M3DB-Placement -adding a node -removing a node -replacing a node +M3DB Tool +======== + +This is a CLI tool to do some things that may be desirable for cluster introspection, or for operational purposes. + +Where configuration data is required its provided via YAML. + +You can: + +* create a database per the simplified database create API +* list namespaces +* delete namespaces +* list placements +* delete placements +* add nodes +* remove nodes + +NOTE: This tool can delete namespaces and placements. It can be quite hazardous if used without adequate understanding of your m3db cluster's topology, or without a decent understanding of how m3db works. + +Examples +------- + + # show help + m3db-tool -h + # create a database + m3db-tool db -create ./database/examples/devel.yaml + # list namespaces + m3db-tool ns + # delete a namespace + m3db-tool ns -delete default + # list placements + m3db-tool pl + # point to some remote and list namespaces + m3db-tool -endpoint http://localhost:7201 ns + # list the ids of the placements + m3db-tool -endpoint http://localhost:7201 pl | jq .placement.instances[].id + +Some example yaml files are provided in the examples directories. Here's one for database creation: + + --- + type: cluster + namespace_name: default + retention_time: 168h + num_shards: 64 + replication_factor: 1 + hosts: + - id: m3db_seed + isolation_group: rack-a + zone: embedded + weight: 1024 + endpoint: m3db_seed:9000 + hostname: m3db_seed + port: 9000 + + +See the examples directories below. + +References +========== + +[https://m3db.github.io/m3/operational_guide](operational guide) +[api docs](https://www.m3db.io/openapi/) diff --git a/src/cmd/tools/q/main/common/http.go b/src/cmd/tools/q/main/common/http.go index 1af105d264..bb035d351f 100644 --- a/src/cmd/tools/q/main/common/http.go +++ b/src/cmd/tools/q/main/common/http.go @@ -15,7 +15,7 @@ var ( // This is used across all the commands func init() { - EndPoint = flag.String("endpoint", "http://bmcqueen-ld1:7201", "url for endpoint") + EndPoint = flag.String("endpoint", "http://localhost:7201", "The url for target m3db backend.") } func DoGet(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { @@ -32,9 +32,7 @@ func DoGet(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, resp.Body.Close() }() - if resp.StatusCode > 299 { - logger.Fatal("error from m3db:%s:url:%s:", resp.Status, url) - } + checkForAndHandleError(url, resp, logger) getter(resp.Body, logger) @@ -59,11 +57,7 @@ func DoPost(url string, data io.Reader, logger *zap.SugaredLogger, getter func(r resp.Body.Close() }() - logger.Debugf("resp.StatusCode:%d:\n", resp.StatusCode) - - if resp.StatusCode > 299 { - logger.Fatal("error from m3db:%s:url:%s:", resp.Status, url) - } + checkForAndHandleError(url, resp, logger) getter(resp.Body, logger) @@ -85,12 +79,11 @@ func DoDelete(url string, logger *zap.SugaredLogger, getter func(reader io.Reade } defer func() { ioutil.ReadAll(resp.Body) + resp.Body.Close() }() - if resp.StatusCode > 299 { - logger.Fatal("error from m3db:%s:url:%s:", resp.Status, url) - } + checkForAndHandleError(url, resp, logger) getter(resp.Body, logger) @@ -105,3 +98,18 @@ func DoDump(in io.Reader, log *zap.SugaredLogger) { fmt.Println(string(dat)) } + +func checkForAndHandleError(url string, resp *http.Response, log *zap.SugaredLogger) { + + log.Debugf("resp.StatusCode:%d:\n", resp.StatusCode) + + if resp.StatusCode > 299 { + dat, _ := ioutil.ReadAll(resp.Body) + + if dat != nil { + fmt.Println(string(dat)) + } + + log.Fatalf("error from m3db:%s:url:%s:", resp.Status, url) + } +} diff --git a/src/cmd/tools/q/main/common/yaml.go b/src/cmd/tools/q/main/common/yaml.go index 35a0669a1a..6599d7eddc 100644 --- a/src/cmd/tools/q/main/common/yaml.go +++ b/src/cmd/tools/q/main/common/yaml.go @@ -20,7 +20,7 @@ func LoadYaml(path string, target proto.Message, log *zap.SugaredLogger) io.Read } if err = yaml.Unmarshal(content, target); err != nil { - log.Fatalf("cannot unmarshal data: %v", err) + log.Fatalf("cannot unmarshal data:%v:from yaml file:%s:", err, path) } var data *bytes.Buffer diff --git a/src/cmd/tools/q/main/database/cmd.go b/src/cmd/tools/q/main/database/cmd.go index 0971fc0239..d533b752f5 100644 --- a/src/cmd/tools/q/main/database/cmd.go +++ b/src/cmd/tools/q/main/database/cmd.go @@ -19,21 +19,20 @@ var ( debugQS = "debug=true" ) -//curl -X POST http://localhost:7201/api/v1/database/create -d - func init() { CmdFlags = flag.NewFlagSet("db", flag.ExitOnError) CmdFlags.Var(&createYaml, "create", "Path to yaml for simplified db creation with sane defaults.") CmdFlags.Usage = func() { fmt.Fprintf(CmdFlags.Output(), ` -Description: +This is the "%s" subcommand for database scoped operations. -database tasks +Description: +This subcommand allows the creation of a new database from a yaml specification. Usage of %s: -`, CmdFlags.Name()) +`, CmdFlags.Name(), CmdFlags.Name()) CmdFlags.PrintDefaults() } } @@ -45,10 +44,11 @@ func Cmd(log *zap.SugaredLogger) { os.Exit(1) } - //if CmdFlags.NFlag() > 4 { - // CmdFlags.Usage() - // os.Exit(1) - //} + if CmdFlags.NFlag() > 1 { + fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") + CmdFlags.Usage() + os.Exit(1) + } if len(createYaml.Value) < 1 { CmdFlags.Usage() diff --git a/src/cmd/tools/q/main/main.go b/src/cmd/tools/q/main/main.go index bd18635efe..697268a78a 100644 --- a/src/cmd/tools/q/main/main.go +++ b/src/cmd/tools/q/main/main.go @@ -42,10 +42,11 @@ func main() { fmt.Fprintf(flag.CommandLine.Output(), ` Usage of %s: - Specify one of the following subcommands: + Specify one of the following subcommands, which are shorthand for database, placement, and namespace: %s +Each subcommand has its own built-in help provided via "-h". `, os.Args[0], strings.Join([]string{ database.CmdFlags.Name(), diff --git a/src/cmd/tools/q/main/namespaces/cmd.go b/src/cmd/tools/q/main/namespaces/cmd.go index d9def755a0..12495871eb 100644 --- a/src/cmd/tools/q/main/namespaces/cmd.go +++ b/src/cmd/tools/q/main/namespaces/cmd.go @@ -26,18 +26,27 @@ func init() { showAll = CmdFlags.Bool("all", false, "show all the standard info for namespaces (otherwise default behaviour lists only the names)") CmdFlags.Usage = func() { fmt.Fprintf(CmdFlags.Output(), ` +This is the subcommand for acting on placements. + Description: -namespace tasks +The subcommand "%s"" provides the ability to: + +* list all namespaces +* verbosely list all the available information about the namespaces +* delete a specific namespace + +Default behaviour (no arguments) is to print out the names of the namespaces. + +Specify only one action at a time. Usage of %s: -`, CmdFlags.Name()) +`, CmdFlags.Name(), CmdFlags.Name()) CmdFlags.PrintDefaults() } } -//curl -s -k -v 'http://localhost:7201/api/v1/namespace?debug=true' | jq .registry.namespaces\|keys func doShowNames(in io.Reader, log *zap.SugaredLogger) { registry := admin.NamespaceGetResponse{} @@ -60,10 +69,11 @@ func Cmd(log *zap.SugaredLogger) { os.Exit(1) } - //if CmdFlags.NFlag() > 4 { - // CmdFlags.Usage() - // os.Exit(1) - //} + if CmdFlags.NFlag() > 1 { + fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") + CmdFlags.Usage() + os.Exit(1) + } url := fmt.Sprintf("%s%s?%s", *common.EndPoint, defaultPath, debugQS) diff --git a/src/cmd/tools/q/main/placements/cmd.go b/src/cmd/tools/q/main/placements/cmd.go index 1702422d90..047b4381aa 100644 --- a/src/cmd/tools/q/main/placements/cmd.go +++ b/src/cmd/tools/q/main/placements/cmd.go @@ -21,10 +21,6 @@ var ( replaceFlag = flagvar.File{} ) -//curl -s -k -v 'http://localhost:7201/api/v1/placement' - -//curl -v -X DELETE bmcqueen-ld1:7201/api/v1/services/m3db/placement - func init() { CmdFlags = flag.NewFlagSet("pl", flag.ExitOnError) delete = CmdFlags.Bool("deleteAll", false, "delete all instances in the placement") @@ -35,13 +31,29 @@ func init() { CmdFlags.Usage = func() { fmt.Fprintf(CmdFlags.Output(), ` +This is the subcommand for acting on placements. + Description: -placement tasks +The subcommand "%s"" provides the ability to: + +* delete an entire placement from a node +* remove a node from a placement +* add a new node to as existing placement +* replace a node within an existing placement +* initialize a placement + +Default behaviour (no arguments) is to provide a json dump of the existing placement. + +New node creation and node replacement require specification of +the desired placement parameters, which you are to provide via a yaml +file, the pathname of which is the argument for the cli option. + +Specify only one action at a time. Usage of %s: -`, CmdFlags.Name()) +`, CmdFlags.Name(), CmdFlags.Name()) CmdFlags.PrintDefaults() } } @@ -53,10 +65,11 @@ func Cmd(log *zap.SugaredLogger) { os.Exit(1) } - //if CmdFlags.NFlag() > 4 { - // CmdFlags.Usage() - // os.Exit(1) - //} + if CmdFlags.NFlag() > 1 { + fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") + CmdFlags.Usage() + os.Exit(1) + } if len(*deleteNode) > 0 { From e32ba1d1b950d8e44ecf6fbe97e0da46814355ea Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Wed, 8 Jan 2020 13:20:05 -0800 Subject: [PATCH 10/65] rename and add to Makefilf --- Makefile | 1 + docs/operational_guide/placement_configuration.md | 2 +- src/cmd/tools/{q/main => m3db_tool}/README.md | 0 src/cmd/tools/{q => m3db_tool}/main/common/http.go | 0 src/cmd/tools/{q => m3db_tool}/main/common/yaml.go | 0 src/cmd/tools/{q => m3db_tool}/main/database/cmd.go | 4 ++-- .../main/database/examples/create.yaml | 0 .../{q => m3db_tool}/main/database/examples/devel.yaml | 0 src/cmd/tools/{q => m3db_tool}/main/flagvar/file.go | 0 src/cmd/tools/{q => m3db_tool}/main/main.go | 10 +++------- src/cmd/tools/{q => m3db_tool}/main/namespaces/cmd.go | 2 +- src/cmd/tools/{q => m3db_tool}/main/placements/cmd.go | 4 ++-- .../main/placements/examples/init.yaml | 0 .../main/placements/examples/newNode.yaml | 0 .../main/placements/examples/replaceNode.yaml | 0 15 files changed, 10 insertions(+), 13 deletions(-) rename src/cmd/tools/{q/main => m3db_tool}/README.md (100%) rename src/cmd/tools/{q => m3db_tool}/main/common/http.go (100%) rename src/cmd/tools/{q => m3db_tool}/main/common/yaml.go (100%) rename src/cmd/tools/{q => m3db_tool}/main/database/cmd.go (91%) rename src/cmd/tools/{q => m3db_tool}/main/database/examples/create.yaml (100%) rename src/cmd/tools/{q => m3db_tool}/main/database/examples/devel.yaml (100%) rename src/cmd/tools/{q => m3db_tool}/main/flagvar/file.go (100%) rename src/cmd/tools/{q => m3db_tool}/main/main.go (88%) rename src/cmd/tools/{q => m3db_tool}/main/namespaces/cmd.go (97%) rename src/cmd/tools/{q => m3db_tool}/main/placements/cmd.go (96%) rename src/cmd/tools/{q => m3db_tool}/main/placements/examples/init.yaml (100%) rename src/cmd/tools/{q => m3db_tool}/main/placements/examples/newNode.yaml (100%) rename src/cmd/tools/{q => m3db_tool}/main/placements/examples/replaceNode.yaml (100%) diff --git a/Makefile b/Makefile index 440e7caf89..ab0776582b 100644 --- a/Makefile +++ b/Makefile @@ -92,6 +92,7 @@ TOOLS := \ verify_index_files \ carbon_load \ docs_test \ + m3db_tool \ .PHONY: setup setup: diff --git a/docs/operational_guide/placement_configuration.md b/docs/operational_guide/placement_configuration.md index 52ecb48802..fd994d3cfe 100644 --- a/docs/operational_guide/placement_configuration.md +++ b/docs/operational_guide/placement_configuration.md @@ -118,7 +118,7 @@ curl -X POST localhost:7201/api/v1/services/m3db/placement/init -d '{ "endpoint": ":", "hostname": "", "port": - }, + } ] }' ``` diff --git a/src/cmd/tools/q/main/README.md b/src/cmd/tools/m3db_tool/README.md similarity index 100% rename from src/cmd/tools/q/main/README.md rename to src/cmd/tools/m3db_tool/README.md diff --git a/src/cmd/tools/q/main/common/http.go b/src/cmd/tools/m3db_tool/main/common/http.go similarity index 100% rename from src/cmd/tools/q/main/common/http.go rename to src/cmd/tools/m3db_tool/main/common/http.go diff --git a/src/cmd/tools/q/main/common/yaml.go b/src/cmd/tools/m3db_tool/main/common/yaml.go similarity index 100% rename from src/cmd/tools/q/main/common/yaml.go rename to src/cmd/tools/m3db_tool/main/common/yaml.go diff --git a/src/cmd/tools/q/main/database/cmd.go b/src/cmd/tools/m3db_tool/main/database/cmd.go similarity index 91% rename from src/cmd/tools/q/main/database/cmd.go rename to src/cmd/tools/m3db_tool/main/database/cmd.go index d533b752f5..dba501182c 100644 --- a/src/cmd/tools/q/main/database/cmd.go +++ b/src/cmd/tools/m3db_tool/main/database/cmd.go @@ -6,8 +6,8 @@ import ( "go.uber.org/zap" "os" - "github.com/m3db/m3/src/cmd/tools/q/main/common" - "github.com/m3db/m3/src/cmd/tools/q/main/flagvar" + "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/common" + "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/flagvar" "github.com/m3db/m3/src/query/generated/proto/admin" ) diff --git a/src/cmd/tools/q/main/database/examples/create.yaml b/src/cmd/tools/m3db_tool/main/database/examples/create.yaml similarity index 100% rename from src/cmd/tools/q/main/database/examples/create.yaml rename to src/cmd/tools/m3db_tool/main/database/examples/create.yaml diff --git a/src/cmd/tools/q/main/database/examples/devel.yaml b/src/cmd/tools/m3db_tool/main/database/examples/devel.yaml similarity index 100% rename from src/cmd/tools/q/main/database/examples/devel.yaml rename to src/cmd/tools/m3db_tool/main/database/examples/devel.yaml diff --git a/src/cmd/tools/q/main/flagvar/file.go b/src/cmd/tools/m3db_tool/main/flagvar/file.go similarity index 100% rename from src/cmd/tools/q/main/flagvar/file.go rename to src/cmd/tools/m3db_tool/main/flagvar/file.go diff --git a/src/cmd/tools/q/main/main.go b/src/cmd/tools/m3db_tool/main/main.go similarity index 88% rename from src/cmd/tools/q/main/main.go rename to src/cmd/tools/m3db_tool/main/main.go index 697268a78a..da6cfc7ab0 100644 --- a/src/cmd/tools/q/main/main.go +++ b/src/cmd/tools/m3db_tool/main/main.go @@ -26,13 +26,9 @@ import ( "os" "strings" - "github.com/m3db/m3/src/cmd/tools/q/main/database" - "github.com/m3db/m3/src/cmd/tools/q/main/namespaces" - "github.com/m3db/m3/src/cmd/tools/q/main/placements" - //"github.com/m3db/m3/src/dbnode/persist/fs" - //"github.com/m3db/m3/src/x/ident" - - //"github.com/pborman/getopt" + "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/database" + "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/namespaces" + "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/placements" "go.uber.org/zap" ) diff --git a/src/cmd/tools/q/main/namespaces/cmd.go b/src/cmd/tools/m3db_tool/main/namespaces/cmd.go similarity index 97% rename from src/cmd/tools/q/main/namespaces/cmd.go rename to src/cmd/tools/m3db_tool/main/namespaces/cmd.go index 12495871eb..52ed7db7c1 100644 --- a/src/cmd/tools/q/main/namespaces/cmd.go +++ b/src/cmd/tools/m3db_tool/main/namespaces/cmd.go @@ -8,7 +8,7 @@ import ( "os" "github.com/gogo/protobuf/jsonpb" - "github.com/m3db/m3/src/cmd/tools/q/main/common" + "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/common" "github.com/m3db/m3/src/query/generated/proto/admin" ) diff --git a/src/cmd/tools/q/main/placements/cmd.go b/src/cmd/tools/m3db_tool/main/placements/cmd.go similarity index 96% rename from src/cmd/tools/q/main/placements/cmd.go rename to src/cmd/tools/m3db_tool/main/placements/cmd.go index 047b4381aa..e78be6bef8 100644 --- a/src/cmd/tools/q/main/placements/cmd.go +++ b/src/cmd/tools/m3db_tool/main/placements/cmd.go @@ -6,8 +6,8 @@ import ( "go.uber.org/zap" "os" - "github.com/m3db/m3/src/cmd/tools/q/main/common" - "github.com/m3db/m3/src/cmd/tools/q/main/flagvar" + "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/common" + "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/flagvar" "github.com/m3db/m3/src/query/generated/proto/admin" ) diff --git a/src/cmd/tools/q/main/placements/examples/init.yaml b/src/cmd/tools/m3db_tool/main/placements/examples/init.yaml similarity index 100% rename from src/cmd/tools/q/main/placements/examples/init.yaml rename to src/cmd/tools/m3db_tool/main/placements/examples/init.yaml diff --git a/src/cmd/tools/q/main/placements/examples/newNode.yaml b/src/cmd/tools/m3db_tool/main/placements/examples/newNode.yaml similarity index 100% rename from src/cmd/tools/q/main/placements/examples/newNode.yaml rename to src/cmd/tools/m3db_tool/main/placements/examples/newNode.yaml diff --git a/src/cmd/tools/q/main/placements/examples/replaceNode.yaml b/src/cmd/tools/m3db_tool/main/placements/examples/replaceNode.yaml similarity index 100% rename from src/cmd/tools/q/main/placements/examples/replaceNode.yaml rename to src/cmd/tools/m3db_tool/main/placements/examples/replaceNode.yaml From 971442488881ef65eb33e31c2cdc943a5f16163e Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Wed, 8 Jan 2020 19:24:21 -0800 Subject: [PATCH 11/65] factor flags into main per PR comment --- src/cmd/tools/m3db_tool/main/common/http.go | 10 -- src/cmd/tools/m3db_tool/main/database/cmd.go | 72 +++++----- src/cmd/tools/m3db_tool/main/main.go | 86 ++++++++---- .../tools/m3db_tool/main/namespaces/cmd.go | 85 ++++++------ .../tools/m3db_tool/main/placements/cmd.go | 130 ++++++++---------- 5 files changed, 197 insertions(+), 186 deletions(-) diff --git a/src/cmd/tools/m3db_tool/main/common/http.go b/src/cmd/tools/m3db_tool/main/common/http.go index bb035d351f..a15c2859ea 100644 --- a/src/cmd/tools/m3db_tool/main/common/http.go +++ b/src/cmd/tools/m3db_tool/main/common/http.go @@ -1,7 +1,6 @@ package common import ( - "flag" "fmt" "go.uber.org/zap" "io" @@ -9,15 +8,6 @@ import ( "net/http" ) -var ( - EndPoint *string -) - -// This is used across all the commands -func init() { - EndPoint = flag.String("endpoint", "http://localhost:7201", "The url for target m3db backend.") -} - func DoGet(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { logger.Debugf("DoGet:url:%s:\n", url) diff --git a/src/cmd/tools/m3db_tool/main/database/cmd.go b/src/cmd/tools/m3db_tool/main/database/cmd.go index dba501182c..0c1baaf130 100644 --- a/src/cmd/tools/m3db_tool/main/database/cmd.go +++ b/src/cmd/tools/m3db_tool/main/database/cmd.go @@ -3,27 +3,35 @@ package database import ( "flag" "fmt" - "go.uber.org/zap" - "os" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/common" "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/flagvar" "github.com/m3db/m3/src/query/generated/proto/admin" + "go.uber.org/zap" + "os" + "strings" ) -var ( - CmdFlags *flag.FlagSet - createYaml = flagvar.File{} - +const ( defaultPath = "/api/v1/database" - debugQS = "debug=true" ) -func init() { - CmdFlags = flag.NewFlagSet("db", flag.ExitOnError) - CmdFlags.Var(&createYaml, "create", "Path to yaml for simplified db creation with sane defaults.") - CmdFlags.Usage = func() { - fmt.Fprintf(CmdFlags.Output(), ` +func Cmd(createYaml string, endpoint string, log *zap.SugaredLogger) { + + data := common.LoadYaml(createYaml, &admin.DatabaseCreateRequest{}, log) + + url := fmt.Sprintf("%s%s/create", endpoint, defaultPath) + + common.DoPost(url, data, log, common.DoDump) + + return +} + +func SetupDatabaseFlags(createDatabaseYaml *flagvar.File) *flag.FlagSet { + + databaseCmdFlags := flag.NewFlagSet("db", flag.ExitOnError) + databaseCmdFlags.Var(createDatabaseYaml, "create", "Path to yaml for simplified db creation with sane defaults.") + databaseCmdFlags.Usage = func() { + fmt.Fprintf(databaseCmdFlags.Output(), ` This is the "%s" subcommand for database scoped operations. Description: @@ -32,34 +40,28 @@ This subcommand allows the creation of a new database from a yaml specification. Usage of %s: -`, CmdFlags.Name(), CmdFlags.Name()) - CmdFlags.PrintDefaults() +`, databaseCmdFlags.Name(), databaseCmdFlags.Name()) + databaseCmdFlags.PrintDefaults() } -} - -func Cmd(log *zap.SugaredLogger) { - if err := CmdFlags.Parse(flag.Args()[1:]); err != nil { - CmdFlags.Usage() - os.Exit(1) - } + flag.Usage = func() { + fmt.Fprintf(flag.CommandLine.Output(), ` +Usage of %s: - if CmdFlags.NFlag() > 1 { - fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") - CmdFlags.Usage() - os.Exit(1) - } + Specify one of the following subcommands, which are shorthand for database, placement, and namespace: - if len(createYaml.Value) < 1 { - CmdFlags.Usage() - os.Exit(1) - } + %s - data := common.LoadYaml(createYaml.Value, &admin.DatabaseCreateRequest{}, log) +Each subcommand has its own built-in help provided via "-h". - url := fmt.Sprintf("%s%s/create", *common.EndPoint, defaultPath) +`, os.Args[0], strings.Join([]string{ + databaseCmdFlags.Name(), + databaseCmdFlags.Name(), + databaseCmdFlags.Name(), + }, ", ")) - common.DoPost(url, data, log, common.DoDump) + flag.PrintDefaults() + } - return + return databaseCmdFlags } diff --git a/src/cmd/tools/m3db_tool/main/main.go b/src/cmd/tools/m3db_tool/main/main.go index da6cfc7ab0..1f014fc989 100644 --- a/src/cmd/tools/m3db_tool/main/main.go +++ b/src/cmd/tools/m3db_tool/main/main.go @@ -23,8 +23,8 @@ package main import ( "flag" "fmt" + "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/flagvar" "os" - "strings" "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/database" "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/namespaces" @@ -32,32 +32,28 @@ import ( "go.uber.org/zap" ) -func main() { - - flag.Usage = func() { - fmt.Fprintf(flag.CommandLine.Output(), ` -Usage of %s: - - Specify one of the following subcommands, which are shorthand for database, placement, and namespace: - - %s - -Each subcommand has its own built-in help provided via "-h". - -`, os.Args[0], strings.Join([]string{ - database.CmdFlags.Name(), - placements.CmdFlags.Name(), - namespaces.CmdFlags.Name(), - }, ", ")) +const ( + defaultEndpoint = "http://localhost:7201" +) - flag.PrintDefaults() - } +func main() { if len(os.Args) < 2 { flag.Usage() os.Exit(1) } + endPoint := flag.String("endpoint", defaultEndpoint, "The url for target m3db backend.") + + createDatabaseYaml := flagvar.File{} + databaseCmdFlags := database.SetupDatabaseFlags(&createDatabaseYaml) + + namespaceArgs := namespaces.NamespaceArgs{} + namespaceCmdFlags := namespaces.SetupNamespaceFlags(&namespaceArgs) + + placementArgs := placements.PlacementArgs{} + placementCmdFlags := placements.SetupPlacementFlags(&placementArgs) + flag.Parse() rawLogger, err := zap.NewDevelopment() @@ -68,17 +64,55 @@ Each subcommand has its own built-in help provided via "-h". log := rawLogger.Sugar() switch flag.Arg(0) { - case database.CmdFlags.Name(): + case databaseCmdFlags.Name(): + + if err := databaseCmdFlags.Parse(flag.Args()[1:]); err != nil { + databaseCmdFlags.Usage() + os.Exit(1) + } + + if databaseCmdFlags.NFlag() > 1 { + fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") + databaseCmdFlags.Usage() + os.Exit(1) + } + + if len(createDatabaseYaml.Value) < 1 { + databaseCmdFlags.Usage() + os.Exit(1) + } + + database.Cmd(createDatabaseYaml.Value, *endPoint, log) + + case namespaceCmdFlags.Name(): + + if err := namespaceCmdFlags.Parse(flag.Args()[1:]); err != nil { + namespaceCmdFlags.Usage() + os.Exit(1) + } + + if namespaceCmdFlags.NFlag() > 1 { + fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") + namespaceCmdFlags.Usage() + os.Exit(1) + } - database.Cmd(log) + namespaces.Cmd(&namespaceArgs, *endPoint, log) - case namespaces.CmdFlags.Name(): + case placementCmdFlags.Name(): - namespaces.Cmd(log) + if err := placementCmdFlags.Parse(flag.Args()[1:]); err != nil { + placementCmdFlags.Usage() + os.Exit(1) + } - case placements.CmdFlags.Name(): + if placementCmdFlags.NFlag() > 1 { + fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") + placementCmdFlags.Usage() + os.Exit(1) + } - placements.Cmd(log) + placements.Cmd(&placementArgs, *endPoint, log) default: flag.Usage() diff --git a/src/cmd/tools/m3db_tool/main/namespaces/cmd.go b/src/cmd/tools/m3db_tool/main/namespaces/cmd.go index 52ed7db7c1..45944f68b6 100644 --- a/src/cmd/tools/m3db_tool/main/namespaces/cmd.go +++ b/src/cmd/tools/m3db_tool/main/namespaces/cmd.go @@ -5,46 +5,20 @@ import ( "fmt" "go.uber.org/zap" "io" - "os" "github.com/gogo/protobuf/jsonpb" "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/common" "github.com/m3db/m3/src/query/generated/proto/admin" ) -var ( - CmdFlags *flag.FlagSet - showAll *bool +const ( defaultPath = "/api/v1/namespace" debugQS = "debug=true" - delete *string ) -func init() { - CmdFlags = flag.NewFlagSet("ns", flag.ExitOnError) - delete = CmdFlags.String("delete", "", "name of namespace to delete") - showAll = CmdFlags.Bool("all", false, "show all the standard info for namespaces (otherwise default behaviour lists only the names)") - CmdFlags.Usage = func() { - fmt.Fprintf(CmdFlags.Output(), ` -This is the subcommand for acting on placements. - -Description: - -The subcommand "%s"" provides the ability to: - -* list all namespaces -* verbosely list all the available information about the namespaces -* delete a specific namespace - -Default behaviour (no arguments) is to print out the names of the namespaces. - -Specify only one action at a time. - -Usage of %s: - -`, CmdFlags.Name(), CmdFlags.Name()) - CmdFlags.PrintDefaults() - } +type NamespaceArgs struct { + showAll *bool + delete *string } func doShowNames(in io.Reader, log *zap.SugaredLogger) { @@ -62,28 +36,17 @@ func doShowNames(in io.Reader, log *zap.SugaredLogger) { } } -func Cmd(log *zap.SugaredLogger) { - - if err := CmdFlags.Parse(flag.Args()[1:]); err != nil { - CmdFlags.Usage() - os.Exit(1) - } - - if CmdFlags.NFlag() > 1 { - fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") - CmdFlags.Usage() - os.Exit(1) - } +func Cmd(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { - url := fmt.Sprintf("%s%s?%s", *common.EndPoint, defaultPath, debugQS) + url := fmt.Sprintf("%s%s?%s", endpoint, defaultPath, debugQS) - if *showAll { + if *flags.showAll { common.DoGet(url, log, common.DoDump) - } else if len(*delete) > 0 { + } else if len(*flags.delete) > 0 { - url = fmt.Sprintf("%s%s/%s", *common.EndPoint, "/api/v1/services/m3db/namespace", *delete) + url = fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", *flags.delete) common.DoDelete(url, log, common.DoDump) @@ -95,3 +58,33 @@ func Cmd(log *zap.SugaredLogger) { return } + +func SetupNamespaceFlags(flags *NamespaceArgs) *flag.FlagSet { + + namespaceCmdFlags := flag.NewFlagSet("ns", flag.ExitOnError) + flags.delete = namespaceCmdFlags.String("delete", "", "name of namespace to delete") + flags.showAll = namespaceCmdFlags.Bool("all", false, "show all the standard info for namespaces (otherwise default behaviour lists only the names)") + namespaceCmdFlags.Usage = func() { + fmt.Fprintf(namespaceCmdFlags.Output(), ` +This is the subcommand for acting on placements. + +Description: + +The subcommand "%s"" provides the ability to: + +* list all namespaces +* verbosely list all the available information about the namespaces +* delete a specific namespace + +Default behaviour (no arguments) is to print out the names of the namespaces. + +Specify only one action at a time. + +Usage of %s: + +`, namespaceCmdFlags.Name(), namespaceCmdFlags.Name()) + namespaceCmdFlags.PrintDefaults() + } + + return namespaceCmdFlags +} diff --git a/src/cmd/tools/m3db_tool/main/placements/cmd.go b/src/cmd/tools/m3db_tool/main/placements/cmd.go index e78be6bef8..0773d423c5 100644 --- a/src/cmd/tools/m3db_tool/main/placements/cmd.go +++ b/src/cmd/tools/m3db_tool/main/placements/cmd.go @@ -3,117 +3,109 @@ package placements import ( "flag" "fmt" - "go.uber.org/zap" - "os" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/common" "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/flagvar" "github.com/m3db/m3/src/query/generated/proto/admin" + "go.uber.org/zap" ) -var ( - CmdFlags *flag.FlagSet +const ( defaultPath = "/api/v1/services/m3db/placement" - delete *bool - deleteNode *string - initFlag = flagvar.File{} - newNodeFlag = flagvar.File{} - replaceFlag = flagvar.File{} ) -func init() { - CmdFlags = flag.NewFlagSet("pl", flag.ExitOnError) - delete = CmdFlags.Bool("deleteAll", false, "delete all instances in the placement") - deleteNode = CmdFlags.String("deleteNode", "", "delete the specified node in the placement") - CmdFlags.Var(&initFlag, "init", "initialize a placement. Specify a yaml file.") - CmdFlags.Var(&newNodeFlag, "newNode", "add a new node to the placement. Specify the filename of the yaml.") - CmdFlags.Var(&replaceFlag, "replaceNode", "add a new node to the placement. Specify the filename of the yaml.") +type PlacementArgs struct { + deletePlacement *bool + deleteNode *string + initFlag flagvar.File + newNodeFlag flagvar.File + replaceFlag flagvar.File +} - CmdFlags.Usage = func() { - fmt.Fprintf(CmdFlags.Output(), ` -This is the subcommand for acting on placements. +func Cmd(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { -Description: + if len(*flags.deleteNode) > 0 { -The subcommand "%s"" provides the ability to: + url := fmt.Sprintf("%s%s/%s", endpoint, defaultPath, *flags.deleteNode) -* delete an entire placement from a node -* remove a node from a placement -* add a new node to as existing placement -* replace a node within an existing placement -* initialize a placement + common.DoDelete(url, log, common.DoDump) -Default behaviour (no arguments) is to provide a json dump of the existing placement. + } else if len(flags.newNodeFlag.Value) > 0 { -New node creation and node replacement require specification of -the desired placement parameters, which you are to provide via a yaml -file, the pathname of which is the argument for the cli option. + data := common.LoadYaml(flags.newNodeFlag.Value, &admin.PlacementInitRequest{}, log) -Specify only one action at a time. + url := fmt.Sprintf("%s%s", endpoint, defaultPath) -Usage of %s: + common.DoPost(url, data, log, common.DoDump) -`, CmdFlags.Name(), CmdFlags.Name()) - CmdFlags.PrintDefaults() - } -} + } else if len(flags.initFlag.Value) > 0 { -func Cmd(log *zap.SugaredLogger) { + data := common.LoadYaml(flags.initFlag.Value, &admin.PlacementInitRequest{}, log) - if err := CmdFlags.Parse(flag.Args()[1:]); err != nil { - CmdFlags.Usage() - os.Exit(1) - } + url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/init") - if CmdFlags.NFlag() > 1 { - fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") - CmdFlags.Usage() - os.Exit(1) - } + common.DoPost(url, data, log, common.DoDump) - if len(*deleteNode) > 0 { + } else if len(flags.replaceFlag.Value) > 0 { - url := fmt.Sprintf("%s%s/%s", *common.EndPoint, defaultPath, *deleteNode) + data := common.LoadYaml(flags.replaceFlag.Value, &admin.PlacementReplaceRequest{}, log) - common.DoDelete(url, log, common.DoDump) + url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/replace") - } else if len(newNodeFlag.Value) > 0 { + common.DoPost(url, data, log, common.DoDump) - data := common.LoadYaml(newNodeFlag.Value, &admin.PlacementInitRequest{}, log) + } else if *flags.deletePlacement { - url := fmt.Sprintf("%s%s", *common.EndPoint, defaultPath) + url := fmt.Sprintf("%s%s", endpoint, defaultPath) - common.DoPost(url, data, log, common.DoDump) + common.DoDelete(url, log, common.DoDump) - } else if len(initFlag.Value) > 0 { + } else { - data := common.LoadYaml(initFlag.Value, &admin.PlacementInitRequest{}, log) + url := fmt.Sprintf("%s%s", endpoint, defaultPath) - url := fmt.Sprintf("%s%s%s", *common.EndPoint, defaultPath, "/init") + common.DoGet(url, log, common.DoDump) - common.DoPost(url, data, log, common.DoDump) + } - } else if len(replaceFlag.Value) > 0 { + return +} - data := common.LoadYaml(replaceFlag.Value, &admin.PlacementReplaceRequest{}, log) +func SetupPlacementFlags(flags *PlacementArgs) *flag.FlagSet { - url := fmt.Sprintf("%s%s%s", *common.EndPoint, defaultPath, "/replace") + placementCmdFlags := flag.NewFlagSet("pl", flag.ExitOnError) + flags.deletePlacement = placementCmdFlags.Bool("deleteAll", false, "delete all instances in the placement") + flags.deleteNode = placementCmdFlags.String("deleteNode", "", "delete the specified node in the placement") + placementCmdFlags.Var(&flags.initFlag, "init", "initialize a placement. Specify a yaml file.") + placementCmdFlags.Var(&flags.newNodeFlag, "newNode", "add a new node to the placement. Specify the filename of the yaml.") + placementCmdFlags.Var(&flags.replaceFlag, "replaceNode", "add a new node to the placement. Specify the filename of the yaml.") - common.DoPost(url, data, log, common.DoDump) + placementCmdFlags.Usage = func() { + fmt.Fprintf(placementCmdFlags.Output(), ` +This is the subcommand for acting on placements. - } else if *delete { +Description: - url := fmt.Sprintf("%s%s", *common.EndPoint, defaultPath) +The subcommand "%s"" provides the ability to: - common.DoDelete(url, log, common.DoDump) +* delete an entire placement from a node +* remove a node from a placement +* add a new node to as existing placement +* replace a node within an existing placement +* initialize a placement - } else { +Default behaviour (no arguments) is to provide a json dump of the existing placement. - url := fmt.Sprintf("%s%s", *common.EndPoint, defaultPath) +New node creation and node replacement require specification of +the desired placement parameters, which you are to provide via a yaml +file, the pathname of which is the argument for the cli option. - common.DoGet(url, log, common.DoDump) +Specify only one action at a time. +Usage of %s: + +`, placementCmdFlags.Name(), placementCmdFlags.Name()) + placementCmdFlags.PrintDefaults() } - return + return placementCmdFlags } From b2af08e00a30140e9fa464f8fbb3ba93dc1142c9 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Thu, 9 Jan 2020 14:15:55 -0800 Subject: [PATCH 12/65] many of the PR comments are done --- src/cmd/tools/m3db_tool/main/common/http.go | 28 ---- src/cmd/tools/m3db_tool/main/common/yaml.go | 8 +- src/cmd/tools/m3db_tool/main/database/cmd.go | 36 +++-- src/cmd/tools/m3db_tool/main/flagvar/file.go | 52 -------- src/cmd/tools/m3db_tool/main/main.go | 123 +++++++++++------- .../tools/m3db_tool/main/namespaces/cmd.go | 35 ++--- .../tools/m3db_tool/main/placements/cmd.go | 86 +++++------- 7 files changed, 136 insertions(+), 232 deletions(-) delete mode 100644 src/cmd/tools/m3db_tool/main/flagvar/file.go diff --git a/src/cmd/tools/m3db_tool/main/common/http.go b/src/cmd/tools/m3db_tool/main/common/http.go index a15c2859ea..5f583081d8 100644 --- a/src/cmd/tools/m3db_tool/main/common/http.go +++ b/src/cmd/tools/m3db_tool/main/common/http.go @@ -9,34 +9,24 @@ import ( ) func DoGet(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { - logger.Debugf("DoGet:url:%s:\n", url) - resp, err := http.Get(url) if err != nil { logger.Fatal(err) } - defer func() { ioutil.ReadAll(resp.Body) resp.Body.Close() }() - checkForAndHandleError(url, resp, logger) - getter(resp.Body, logger) - } func DoPost(url string, data io.Reader, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { - logger.Debugf("DoPost:url:%s:\n", url) - client := &http.Client{} - req, err := http.NewRequest(http.MethodPost, url, data) req.Header.Add("Content-Type", "application/json") - resp, err := client.Do(req) if err != nil { logger.Fatal(err) @@ -46,60 +36,42 @@ func DoPost(url string, data io.Reader, logger *zap.SugaredLogger, getter func(r ioutil.ReadAll(resp.Body) resp.Body.Close() }() - checkForAndHandleError(url, resp, logger) - getter(resp.Body, logger) - } func DoDelete(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { - logger.Debugf("DoDelete:url:%s:\n", url) - client := &http.Client{} - req, err := http.NewRequest(http.MethodDelete, url, nil) req.Header.Add("Content-Type", "application/json") - resp, err := client.Do(req) if err != nil { logger.Fatal(err) - } defer func() { ioutil.ReadAll(resp.Body) - resp.Body.Close() }() - checkForAndHandleError(url, resp, logger) - getter(resp.Body, logger) - } func DoDump(in io.Reader, log *zap.SugaredLogger) { - dat, err := ioutil.ReadAll(in) if err != nil { log.Fatal(err) } - fmt.Println(string(dat)) } func checkForAndHandleError(url string, resp *http.Response, log *zap.SugaredLogger) { - log.Debugf("resp.StatusCode:%d:\n", resp.StatusCode) - if resp.StatusCode > 299 { dat, _ := ioutil.ReadAll(resp.Body) - if dat != nil { fmt.Println(string(dat)) } - log.Fatalf("error from m3db:%s:url:%s:", resp.Status, url) } } diff --git a/src/cmd/tools/m3db_tool/main/common/yaml.go b/src/cmd/tools/m3db_tool/main/common/yaml.go index 6599d7eddc..b5bcd024fd 100644 --- a/src/cmd/tools/m3db_tool/main/common/yaml.go +++ b/src/cmd/tools/m3db_tool/main/common/yaml.go @@ -10,26 +10,20 @@ import ( "io/ioutil" ) -func LoadYaml(path string, target proto.Message, log *zap.SugaredLogger) io.Reader { - +func LoadYAML(path string, target proto.Message, log *zap.SugaredLogger) io.Reader { log.Debugf("path:%s:\n", path) - content, err := ioutil.ReadFile(path) if err != nil { log.Fatal(err) } - if err = yaml.Unmarshal(content, target); err != nil { log.Fatalf("cannot unmarshal data:%v:from yaml file:%s:", err, path) } - var data *bytes.Buffer data = bytes.NewBuffer(nil) - marshaller := &jsonpb.Marshaler{} if err = marshaller.Marshal(data, target); err != nil { log.Fatal(err) } - return data } diff --git a/src/cmd/tools/m3db_tool/main/database/cmd.go b/src/cmd/tools/m3db_tool/main/database/cmd.go index 0c1baaf130..c5bd5074cb 100644 --- a/src/cmd/tools/m3db_tool/main/database/cmd.go +++ b/src/cmd/tools/m3db_tool/main/database/cmd.go @@ -4,8 +4,8 @@ import ( "flag" "fmt" "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/common" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/flagvar" "github.com/m3db/m3/src/query/generated/proto/admin" + "github.com/m3db/m3/src/x/config/configflag" "go.uber.org/zap" "os" "strings" @@ -15,23 +15,19 @@ const ( defaultPath = "/api/v1/database" ) -func Cmd(createYaml string, endpoint string, log *zap.SugaredLogger) { - - data := common.LoadYaml(createYaml, &admin.DatabaseCreateRequest{}, log) - +func Command(createYAML string, endpoint string, log *zap.SugaredLogger) { + log.Debugf("createYAML:%s:\n", createYAML) + data := common.LoadYAML(createYAML, &admin.DatabaseCreateRequest{}, log) url := fmt.Sprintf("%s%s/create", endpoint, defaultPath) - common.DoPost(url, data, log, common.DoDump) - return } -func SetupDatabaseFlags(createDatabaseYaml *flagvar.File) *flag.FlagSet { - - databaseCmdFlags := flag.NewFlagSet("db", flag.ExitOnError) - databaseCmdFlags.Var(createDatabaseYaml, "create", "Path to yaml for simplified db creation with sane defaults.") - databaseCmdFlags.Usage = func() { - fmt.Fprintf(databaseCmdFlags.Output(), ` +func SetupDatabaseFlags(createDatabaseYAML *configflag.FlagStringSlice) *flag.FlagSet { + databaseFlags := flag.NewFlagSet("db", flag.ExitOnError) + databaseFlags.Var(createDatabaseYAML, "create", "Path to yaml for simplified db creation with sane defaults.") + databaseFlags.Usage = func() { + fmt.Fprintf(databaseFlags.Output(), ` This is the "%s" subcommand for database scoped operations. Description: @@ -40,10 +36,9 @@ This subcommand allows the creation of a new database from a yaml specification. Usage of %s: -`, databaseCmdFlags.Name(), databaseCmdFlags.Name()) - databaseCmdFlags.PrintDefaults() +`, databaseFlags.Name(), databaseFlags.Name()) + databaseFlags.PrintDefaults() } - flag.Usage = func() { fmt.Fprintf(flag.CommandLine.Output(), ` Usage of %s: @@ -55,13 +50,12 @@ Usage of %s: Each subcommand has its own built-in help provided via "-h". `, os.Args[0], strings.Join([]string{ - databaseCmdFlags.Name(), - databaseCmdFlags.Name(), - databaseCmdFlags.Name(), + databaseFlags.Name(), + databaseFlags.Name(), + databaseFlags.Name(), }, ", ")) flag.PrintDefaults() } - - return databaseCmdFlags + return databaseFlags } diff --git a/src/cmd/tools/m3db_tool/main/flagvar/file.go b/src/cmd/tools/m3db_tool/main/flagvar/file.go deleted file mode 100644 index 43bb190d5a..0000000000 --- a/src/cmd/tools/m3db_tool/main/flagvar/file.go +++ /dev/null @@ -1,52 +0,0 @@ -package flagvar - -import ( - "os" - "strings" -) - -// File is a `flag.Value` for file path arguments. -// By default, any errors from os.Stat are returned. -// Alternatively, the value of the `Validate` field is used as a validator when specified. -type File struct { - Validate func(os.FileInfo, error) error - - Value string -} - -// Set is flag.Value.Set -func (fv *File) Set(v string) error { - info, err := os.Stat(v) - fv.Value = v - if fv.Validate != nil { - return fv.Validate(info, err) - } - return err -} - -func (fv *File) String() string { - return fv.Value -} - -// Files is a `flag.Value` for file path arguments. -// By default, any errors from os.Stat are returned. -// Alternatively, the value of the `Validate` field is used as a validator when specified. -type Files struct { - Validate func(os.FileInfo, error) error - - Values []string -} - -// Set is flag.Value.Set -func (fv *Files) Set(v string) error { - info, err := os.Stat(v) - fv.Values = append(fv.Values, v) - if fv.Validate != nil { - return fv.Validate(info, err) - } - return err -} - -func (fv *Files) String() string { - return strings.Join(fv.Values, ",") -} diff --git a/src/cmd/tools/m3db_tool/main/main.go b/src/cmd/tools/m3db_tool/main/main.go index 1f014fc989..2b8039a554 100644 --- a/src/cmd/tools/m3db_tool/main/main.go +++ b/src/cmd/tools/m3db_tool/main/main.go @@ -23,12 +23,12 @@ package main import ( "flag" "fmt" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/flagvar" "os" "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/database" "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/namespaces" "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/placements" + "github.com/m3db/m3/src/x/config/configflag" "go.uber.org/zap" ) @@ -38,24 +38,28 @@ const ( func main() { - if len(os.Args) < 2 { - flag.Usage() - os.Exit(1) - } - + // top-level option endPoint := flag.String("endpoint", defaultEndpoint, "The url for target m3db backend.") - createDatabaseYaml := flagvar.File{} - databaseCmdFlags := database.SetupDatabaseFlags(&createDatabaseYaml) + // the database-related subcommand + createDatabaseYAML := configflag.FlagStringSlice{} + databaseFlags := database.SetupDatabaseFlags(&createDatabaseYAML) + // the namespace-relateed subcommand namespaceArgs := namespaces.NamespaceArgs{} - namespaceCmdFlags := namespaces.SetupNamespaceFlags(&namespaceArgs) + namespaceFlags := namespaces.SetupNamespaceFlags(&namespaceArgs) + // the placement-related subcommand placementArgs := placements.PlacementArgs{} - placementCmdFlags := placements.SetupPlacementFlags(&placementArgs) + placementFlags := placements.SetupPlacementFlags(&placementArgs) flag.Parse() + if len(os.Args) < 2 { + flag.Usage() + os.Exit(1) + } + rawLogger, err := zap.NewDevelopment() if err != nil { fmt.Fprintf(os.Stderr, "unable to create logger: %+v", err) @@ -64,60 +68,83 @@ func main() { log := rawLogger.Sugar() switch flag.Arg(0) { - case databaseCmdFlags.Name(): - - if err := databaseCmdFlags.Parse(flag.Args()[1:]); err != nil { - databaseCmdFlags.Usage() - os.Exit(1) - } - - if databaseCmdFlags.NFlag() > 1 { - fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") - databaseCmdFlags.Usage() + case databaseFlags.Name(): + if err := databaseFlags.Parse(flag.Args()[1:]); err != nil { + databaseFlags.Usage() os.Exit(1) } - - if len(createDatabaseYaml.Value) < 1 { - databaseCmdFlags.Usage() + databaseFlags.Visit(func(f *flag.Flag) { + vals := f.Value.(*configflag.FlagStringSlice) + for _, val := range vals.Value { + if len(val) == 0 { + fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + databaseFlags.Usage() + os.Exit(1) + } + } + }) + if len(createDatabaseYAML.Value) != 1 { + databaseFlags.Usage() os.Exit(1) } - - database.Cmd(createDatabaseYaml.Value, *endPoint, log) - - case namespaceCmdFlags.Name(): - - if err := namespaceCmdFlags.Parse(flag.Args()[1:]); err != nil { - namespaceCmdFlags.Usage() + database.Command(createDatabaseYAML.Value[0], *endPoint, log) + case namespaceFlags.Name(): + if err := namespaceFlags.Parse(flag.Args()[1:]); err != nil { + namespaceFlags.Usage() os.Exit(1) } - - if namespaceCmdFlags.NFlag() > 1 { + if namespaceFlags.NFlag() > 1 { fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") - namespaceCmdFlags.Usage() + namespaceFlags.Usage() os.Exit(1) } - - namespaces.Cmd(&namespaceArgs, *endPoint, log) - - case placementCmdFlags.Name(): - - if err := placementCmdFlags.Parse(flag.Args()[1:]); err != nil { - placementCmdFlags.Usage() + namespaceFlags.Visit(func(f *flag.Flag) { + vals := f.Value.(*configflag.FlagStringSlice) + for _, val := range vals.Value { + if len(val) == 0 { + fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + namespaceFlags.Usage() + os.Exit(1) + } + } + }) + namespaces.Command(&namespaceArgs, *endPoint, log) + case placementFlags.Name(): + if err := placementFlags.Parse(flag.Args()[1:]); err != nil { + placementFlags.Usage() os.Exit(1) } - - if placementCmdFlags.NFlag() > 1 { + // all are mutually exclusive + // only one can be specified + if placementFlags.NFlag() > 1 { fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") - placementCmdFlags.Usage() + placementFlags.Usage() os.Exit(1) } - - placements.Cmd(&placementArgs, *endPoint, log) - + placementFlags.Visit(func(f *flag.Flag) { + switch f.Name { + case placements.DeleteNodeName: + if len(f.Value.String()) == 0 { + fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + placementFlags.Usage() + os.Exit(1) + } + case placements.InitName, placements.NewNodeName, placements.ReplaceNodeName: + vals := f.Value.(*configflag.FlagStringSlice) + for _, val := range vals.Value { + if len(val) == 0 { + fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + placementFlags.Usage() + os.Exit(1) + } + } + default: + return + } + }) + placements.Command(&placementArgs, *endPoint, log) default: flag.Usage() os.Exit(1) - } - } diff --git a/src/cmd/tools/m3db_tool/main/namespaces/cmd.go b/src/cmd/tools/m3db_tool/main/namespaces/cmd.go index 45944f68b6..d8a5706340 100644 --- a/src/cmd/tools/m3db_tool/main/namespaces/cmd.go +++ b/src/cmd/tools/m3db_tool/main/namespaces/cmd.go @@ -22,50 +22,36 @@ type NamespaceArgs struct { } func doShowNames(in io.Reader, log *zap.SugaredLogger) { - registry := admin.NamespaceGetResponse{} - unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} - if err := unmarshaller.Unmarshal(in, ®istry); err != nil { log.Fatal(err) } - for k, _ := range registry.Registry.Namespaces { fmt.Println(k) } } -func Cmd(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { - +func Command(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { + log.Debugf("NamespaceArgs:%+v:\n", flags) url := fmt.Sprintf("%s%s?%s", endpoint, defaultPath, debugQS) - if *flags.showAll { - common.DoGet(url, log, common.DoDump) - } else if len(*flags.delete) > 0 { - url = fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", *flags.delete) - common.DoDelete(url, log, common.DoDump) - } else { - common.DoGet(url, log, doShowNames) - } - return } func SetupNamespaceFlags(flags *NamespaceArgs) *flag.FlagSet { - - namespaceCmdFlags := flag.NewFlagSet("ns", flag.ExitOnError) - flags.delete = namespaceCmdFlags.String("delete", "", "name of namespace to delete") - flags.showAll = namespaceCmdFlags.Bool("all", false, "show all the standard info for namespaces (otherwise default behaviour lists only the names)") - namespaceCmdFlags.Usage = func() { - fmt.Fprintf(namespaceCmdFlags.Output(), ` + namespaceFlags := flag.NewFlagSet("ns", flag.ExitOnError) + flags.delete = namespaceFlags.String("delete", "", "name of namespace to delete") + flags.showAll = namespaceFlags.Bool("all", false, "show all the standard info for namespaces (otherwise default behaviour lists only the names)") + namespaceFlags.Usage = func() { + fmt.Fprintf(namespaceFlags.Output(), ` This is the subcommand for acting on placements. Description: @@ -82,9 +68,8 @@ Specify only one action at a time. Usage of %s: -`, namespaceCmdFlags.Name(), namespaceCmdFlags.Name()) - namespaceCmdFlags.PrintDefaults() +`, namespaceFlags.Name(), namespaceFlags.Name()) + namespaceFlags.PrintDefaults() } - - return namespaceCmdFlags + return namespaceFlags } diff --git a/src/cmd/tools/m3db_tool/main/placements/cmd.go b/src/cmd/tools/m3db_tool/main/placements/cmd.go index 0773d423c5..00fa4bf08f 100644 --- a/src/cmd/tools/m3db_tool/main/placements/cmd.go +++ b/src/cmd/tools/m3db_tool/main/placements/cmd.go @@ -4,88 +4,73 @@ import ( "flag" "fmt" "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/common" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/flagvar" "github.com/m3db/m3/src/query/generated/proto/admin" + "github.com/m3db/m3/src/x/config/configflag" "go.uber.org/zap" + "os" ) const ( - defaultPath = "/api/v1/services/m3db/placement" + placementCommandName = "pl" + defaultPath = "/api/v1/services/m3db/placement" + + // flag names + DeleteAllName = "deleteAll" + DeleteNodeName = "deleteNode" + InitName = "init" + NewNodeName = "newNode" + ReplaceNodeName = "replaceNode" ) type PlacementArgs struct { deletePlacement *bool deleteNode *string - initFlag flagvar.File - newNodeFlag flagvar.File - replaceFlag flagvar.File + initFlag configflag.FlagStringSlice + newNodeFlag configflag.FlagStringSlice + replaceFlag configflag.FlagStringSlice } -func Cmd(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { - +func Command(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { + log.Debugf("PlacementArgs:%+v:\n", flags) if len(*flags.deleteNode) > 0 { - url := fmt.Sprintf("%s%s/%s", endpoint, defaultPath, *flags.deleteNode) - common.DoDelete(url, log, common.DoDump) - - } else if len(flags.newNodeFlag.Value) > 0 { - - data := common.LoadYaml(flags.newNodeFlag.Value, &admin.PlacementInitRequest{}, log) - + } else if len(flags.newNodeFlag.Value) > 0 && len(flags.newNodeFlag.Value) > 0 { + data := common.LoadYAML(flags.newNodeFlag.Value[0], &admin.PlacementInitRequest{}, log) url := fmt.Sprintf("%s%s", endpoint, defaultPath) - common.DoPost(url, data, log, common.DoDump) - - } else if len(flags.initFlag.Value) > 0 { - - data := common.LoadYaml(flags.initFlag.Value, &admin.PlacementInitRequest{}, log) - + } else if len(flags.initFlag.Value) > 0 && len(flags.initFlag.Value[0]) > 0 { + data := common.LoadYAML(flags.initFlag.Value[0], &admin.PlacementInitRequest{}, log) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/init") - common.DoPost(url, data, log, common.DoDump) - - } else if len(flags.replaceFlag.Value) > 0 { - - data := common.LoadYaml(flags.replaceFlag.Value, &admin.PlacementReplaceRequest{}, log) - + } else if len(flags.replaceFlag.Value) > 0 && len(flags.replaceFlag.Value[0]) > 0 { + data := common.LoadYAML(flags.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}, log) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/replace") - common.DoPost(url, data, log, common.DoDump) - } else if *flags.deletePlacement { - url := fmt.Sprintf("%s%s", endpoint, defaultPath) - common.DoDelete(url, log, common.DoDump) - } else { - url := fmt.Sprintf("%s%s", endpoint, defaultPath) - common.DoGet(url, log, common.DoDump) - } - return } func SetupPlacementFlags(flags *PlacementArgs) *flag.FlagSet { - - placementCmdFlags := flag.NewFlagSet("pl", flag.ExitOnError) - flags.deletePlacement = placementCmdFlags.Bool("deleteAll", false, "delete all instances in the placement") - flags.deleteNode = placementCmdFlags.String("deleteNode", "", "delete the specified node in the placement") - placementCmdFlags.Var(&flags.initFlag, "init", "initialize a placement. Specify a yaml file.") - placementCmdFlags.Var(&flags.newNodeFlag, "newNode", "add a new node to the placement. Specify the filename of the yaml.") - placementCmdFlags.Var(&flags.replaceFlag, "replaceNode", "add a new node to the placement. Specify the filename of the yaml.") - - placementCmdFlags.Usage = func() { - fmt.Fprintf(placementCmdFlags.Output(), ` -This is the subcommand for acting on placements. + placementFlags := flag.NewFlagSet(placementCommandName, flag.ExitOnError) + flags.deletePlacement = placementFlags.Bool(DeleteAllName, false, "delete all instances in the placement") + flags.deleteNode = placementFlags.String(DeleteNodeName, "", "delete the specified node in the placement") + placementFlags.Var(&flags.initFlag, InitName, "initialize a placement. Specify a yaml file.") + placementFlags.Var(&flags.newNodeFlag, NewNodeName, "add a new node to the placement. Specify the filename of the yaml.") + placementFlags.Var(&flags.replaceFlag, ReplaceNodeName, "add a new node to the placement. Specify the filename of the yaml.") + placementFlags.Usage = func() { + fmt.Fprintf(os.Stderr, ` +"%s" is for acting on placements. Description: -The subcommand "%s"" provides the ability to: +The subcommand "%s" provides the ability to: * delete an entire placement from a node * remove a node from a placement @@ -103,9 +88,8 @@ Specify only one action at a time. Usage of %s: -`, placementCmdFlags.Name(), placementCmdFlags.Name()) - placementCmdFlags.PrintDefaults() +`, placementFlags.Name(), placementFlags.Name(), placementFlags.Name()) + placementFlags.PrintDefaults() } - - return placementCmdFlags + return placementFlags } From 66c577ac9f9d9d4fc0acbc9112e552c94b1904b0 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Thu, 9 Jan 2020 14:40:47 -0800 Subject: [PATCH 13/65] more PR comments --- src/cmd/tools/m3db_tool/main/database/cmd.go | 7 ++++--- .../m3db_tool/main/{common => http}/http.go | 18 ++++++++++++---- src/cmd/tools/m3db_tool/main/main.go | 12 +++++------ .../tools/m3db_tool/main/namespaces/cmd.go | 10 ++++----- .../tools/m3db_tool/main/placements/cmd.go | 21 ++++++++++--------- .../main/{common/yaml.go => yaml/load.go} | 4 ++-- 6 files changed, 41 insertions(+), 31 deletions(-) rename src/cmd/tools/m3db_tool/main/{common => http}/http.go (88%) rename src/cmd/tools/m3db_tool/main/{common/yaml.go => yaml/load.go} (85%) diff --git a/src/cmd/tools/m3db_tool/main/database/cmd.go b/src/cmd/tools/m3db_tool/main/database/cmd.go index c5bd5074cb..54ba906d35 100644 --- a/src/cmd/tools/m3db_tool/main/database/cmd.go +++ b/src/cmd/tools/m3db_tool/main/database/cmd.go @@ -3,7 +3,8 @@ package database import ( "flag" "fmt" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/common" + "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/http" + "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/yaml" "github.com/m3db/m3/src/query/generated/proto/admin" "github.com/m3db/m3/src/x/config/configflag" "go.uber.org/zap" @@ -17,9 +18,9 @@ const ( func Command(createYAML string, endpoint string, log *zap.SugaredLogger) { log.Debugf("createYAML:%s:\n", createYAML) - data := common.LoadYAML(createYAML, &admin.DatabaseCreateRequest{}, log) + data := yaml.Load(createYAML, &admin.DatabaseCreateRequest{}, log) url := fmt.Sprintf("%s%s/create", endpoint, defaultPath) - common.DoPost(url, data, log, common.DoDump) + http.DoPost(url, data, log, http.DoDump) return } diff --git a/src/cmd/tools/m3db_tool/main/common/http.go b/src/cmd/tools/m3db_tool/main/http/http.go similarity index 88% rename from src/cmd/tools/m3db_tool/main/common/http.go rename to src/cmd/tools/m3db_tool/main/http/http.go index 5f583081d8..4596156246 100644 --- a/src/cmd/tools/m3db_tool/main/common/http.go +++ b/src/cmd/tools/m3db_tool/main/http/http.go @@ -1,4 +1,4 @@ -package common +package http import ( "fmt" @@ -6,11 +6,17 @@ import ( "io" "io/ioutil" "net/http" + "time" ) +const timeout = time.Duration(5 * time.Second) + func DoGet(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { logger.Debugf("DoGet:url:%s:\n", url) - resp, err := http.Get(url) + client := http.Client{ + Timeout: timeout, + } + resp, err := client.Get(url) if err != nil { logger.Fatal(err) } @@ -24,7 +30,9 @@ func DoGet(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, func DoPost(url string, data io.Reader, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { logger.Debugf("DoPost:url:%s:\n", url) - client := &http.Client{} + client := &http.Client{ + Timeout: timeout, + } req, err := http.NewRequest(http.MethodPost, url, data) req.Header.Add("Content-Type", "application/json") resp, err := client.Do(req) @@ -42,7 +50,9 @@ func DoPost(url string, data io.Reader, logger *zap.SugaredLogger, getter func(r func DoDelete(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { logger.Debugf("DoDelete:url:%s:\n", url) - client := &http.Client{} + client := &http.Client{ + Timeout: timeout, + } req, err := http.NewRequest(http.MethodDelete, url, nil) req.Header.Add("Content-Type", "application/json") resp, err := client.Do(req) diff --git a/src/cmd/tools/m3db_tool/main/main.go b/src/cmd/tools/m3db_tool/main/main.go index 2b8039a554..7979b25e2c 100644 --- a/src/cmd/tools/m3db_tool/main/main.go +++ b/src/cmd/tools/m3db_tool/main/main.go @@ -73,6 +73,10 @@ func main() { databaseFlags.Usage() os.Exit(1) } + if databaseFlags.NFlag() == 0 { + databaseFlags.Usage() + os.Exit(1) + } databaseFlags.Visit(func(f *flag.Flag) { vals := f.Value.(*configflag.FlagStringSlice) for _, val := range vals.Value { @@ -83,11 +87,7 @@ func main() { } } }) - if len(createDatabaseYAML.Value) != 1 { - databaseFlags.Usage() - os.Exit(1) - } - database.Command(createDatabaseYAML.Value[0], *endPoint, log) + database.Command(createDatabaseYAML.Value[len(createDatabaseYAML.Value)-1], *endPoint, log) case namespaceFlags.Name(): if err := namespaceFlags.Parse(flag.Args()[1:]); err != nil { namespaceFlags.Usage() @@ -114,8 +114,6 @@ func main() { placementFlags.Usage() os.Exit(1) } - // all are mutually exclusive - // only one can be specified if placementFlags.NFlag() > 1 { fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") placementFlags.Usage() diff --git a/src/cmd/tools/m3db_tool/main/namespaces/cmd.go b/src/cmd/tools/m3db_tool/main/namespaces/cmd.go index d8a5706340..65977ebd0f 100644 --- a/src/cmd/tools/m3db_tool/main/namespaces/cmd.go +++ b/src/cmd/tools/m3db_tool/main/namespaces/cmd.go @@ -7,7 +7,7 @@ import ( "io" "github.com/gogo/protobuf/jsonpb" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/common" + "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/http" "github.com/m3db/m3/src/query/generated/proto/admin" ) @@ -21,7 +21,7 @@ type NamespaceArgs struct { delete *string } -func doShowNames(in io.Reader, log *zap.SugaredLogger) { +func showNames(in io.Reader, log *zap.SugaredLogger) { registry := admin.NamespaceGetResponse{} unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} if err := unmarshaller.Unmarshal(in, ®istry); err != nil { @@ -36,12 +36,12 @@ func Command(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { log.Debugf("NamespaceArgs:%+v:\n", flags) url := fmt.Sprintf("%s%s?%s", endpoint, defaultPath, debugQS) if *flags.showAll { - common.DoGet(url, log, common.DoDump) + http.DoGet(url, log, http.DoDump) } else if len(*flags.delete) > 0 { url = fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", *flags.delete) - common.DoDelete(url, log, common.DoDump) + http.DoDelete(url, log, http.DoDump) } else { - common.DoGet(url, log, doShowNames) + http.DoGet(url, log, showNames) } return } diff --git a/src/cmd/tools/m3db_tool/main/placements/cmd.go b/src/cmd/tools/m3db_tool/main/placements/cmd.go index 00fa4bf08f..aa684d9150 100644 --- a/src/cmd/tools/m3db_tool/main/placements/cmd.go +++ b/src/cmd/tools/m3db_tool/main/placements/cmd.go @@ -3,7 +3,8 @@ package placements import ( "flag" "fmt" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/common" + "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/http" + "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/yaml" "github.com/m3db/m3/src/query/generated/proto/admin" "github.com/m3db/m3/src/x/config/configflag" "go.uber.org/zap" @@ -34,25 +35,25 @@ func Command(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { log.Debugf("PlacementArgs:%+v:\n", flags) if len(*flags.deleteNode) > 0 { url := fmt.Sprintf("%s%s/%s", endpoint, defaultPath, *flags.deleteNode) - common.DoDelete(url, log, common.DoDump) + http.DoDelete(url, log, http.DoDump) } else if len(flags.newNodeFlag.Value) > 0 && len(flags.newNodeFlag.Value) > 0 { - data := common.LoadYAML(flags.newNodeFlag.Value[0], &admin.PlacementInitRequest{}, log) + data := yaml.Load(flags.newNodeFlag.Value[0], &admin.PlacementInitRequest{}, log) url := fmt.Sprintf("%s%s", endpoint, defaultPath) - common.DoPost(url, data, log, common.DoDump) + http.DoPost(url, data, log, http.DoDump) } else if len(flags.initFlag.Value) > 0 && len(flags.initFlag.Value[0]) > 0 { - data := common.LoadYAML(flags.initFlag.Value[0], &admin.PlacementInitRequest{}, log) + data := yaml.Load(flags.initFlag.Value[0], &admin.PlacementInitRequest{}, log) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/init") - common.DoPost(url, data, log, common.DoDump) + http.DoPost(url, data, log, http.DoDump) } else if len(flags.replaceFlag.Value) > 0 && len(flags.replaceFlag.Value[0]) > 0 { - data := common.LoadYAML(flags.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}, log) + data := yaml.Load(flags.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}, log) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/replace") - common.DoPost(url, data, log, common.DoDump) + http.DoPost(url, data, log, http.DoDump) } else if *flags.deletePlacement { url := fmt.Sprintf("%s%s", endpoint, defaultPath) - common.DoDelete(url, log, common.DoDump) + http.DoDelete(url, log, http.DoDump) } else { url := fmt.Sprintf("%s%s", endpoint, defaultPath) - common.DoGet(url, log, common.DoDump) + http.DoGet(url, log, http.DoDump) } return } diff --git a/src/cmd/tools/m3db_tool/main/common/yaml.go b/src/cmd/tools/m3db_tool/main/yaml/load.go similarity index 85% rename from src/cmd/tools/m3db_tool/main/common/yaml.go rename to src/cmd/tools/m3db_tool/main/yaml/load.go index b5bcd024fd..8f657fb222 100644 --- a/src/cmd/tools/m3db_tool/main/common/yaml.go +++ b/src/cmd/tools/m3db_tool/main/yaml/load.go @@ -1,4 +1,4 @@ -package common +package yaml import ( "bytes" @@ -10,7 +10,7 @@ import ( "io/ioutil" ) -func LoadYAML(path string, target proto.Message, log *zap.SugaredLogger) io.Reader { +func Load(path string, target proto.Message, log *zap.SugaredLogger) io.Reader { log.Debugf("path:%s:\n", path) content, err := ioutil.ReadFile(path) if err != nil { From 9c73f0ff5074735eb892de88ef597455e1f4446b Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Thu, 9 Jan 2020 14:57:26 -0800 Subject: [PATCH 14/65] last code comments, next add some tests --- Makefile | 4 +- src/cmd/tools/{m3db_tool => m3ctl}/README.md | 14 +++---- .../{m3db_tool => m3ctl}/main/database/cmd.go | 42 +++++++++---------- .../main/database/examples/create.yaml | 0 .../main/database/examples/devel.yaml | 0 .../{m3db_tool => m3ctl}/main/http/http.go | 0 .../tools/{m3db_tool => m3ctl}/main/main.go | 27 ++++++++++-- .../main/namespaces/cmd.go | 2 +- .../main/placements/cmd.go | 4 +- .../main/placements/examples/init.yaml | 0 .../main/placements/examples/newNode.yaml | 0 .../main/placements/examples/replaceNode.yaml | 0 .../{m3db_tool => m3ctl}/main/yaml/load.go | 0 13 files changed, 55 insertions(+), 38 deletions(-) rename src/cmd/tools/{m3db_tool => m3ctl}/README.md (83%) rename src/cmd/tools/{m3db_tool => m3ctl}/main/database/cmd.go (66%) rename src/cmd/tools/{m3db_tool => m3ctl}/main/database/examples/create.yaml (100%) rename src/cmd/tools/{m3db_tool => m3ctl}/main/database/examples/devel.yaml (100%) rename src/cmd/tools/{m3db_tool => m3ctl}/main/http/http.go (100%) rename src/cmd/tools/{m3db_tool => m3ctl}/main/main.go (87%) rename src/cmd/tools/{m3db_tool => m3ctl}/main/namespaces/cmd.go (97%) rename src/cmd/tools/{m3db_tool => m3ctl}/main/placements/cmd.go (96%) rename src/cmd/tools/{m3db_tool => m3ctl}/main/placements/examples/init.yaml (100%) rename src/cmd/tools/{m3db_tool => m3ctl}/main/placements/examples/newNode.yaml (100%) rename src/cmd/tools/{m3db_tool => m3ctl}/main/placements/examples/replaceNode.yaml (100%) rename src/cmd/tools/{m3db_tool => m3ctl}/main/yaml/load.go (100%) diff --git a/Makefile b/Makefile index 3c44278481..2273f044eb 100644 --- a/Makefile +++ b/Makefile @@ -93,7 +93,7 @@ TOOLS := \ verify_index_files \ carbon_load \ docs_test \ - m3db_tool \ + m3ctl \ .PHONY: setup setup: @@ -118,7 +118,7 @@ $(SERVICE)-linux-amd64: .PHONY: $(SERVICE)-docker-dev $(SERVICE)-docker-dev: clean-build $(SERVICE)-linux-amd64 mkdir -p ./bin/config - + # Hacky way to find all configs and put into ./bin/config/ find ./src | fgrep config | fgrep ".yml" | xargs -I{} cp {} ./bin/config/ find ./src | fgrep config | fgrep ".yaml" | xargs -I{} cp {} ./bin/config/ diff --git a/src/cmd/tools/m3db_tool/README.md b/src/cmd/tools/m3ctl/README.md similarity index 83% rename from src/cmd/tools/m3db_tool/README.md rename to src/cmd/tools/m3ctl/README.md index 1ef11f0961..56923c941d 100644 --- a/src/cmd/tools/m3db_tool/README.md +++ b/src/cmd/tools/m3ctl/README.md @@ -21,19 +21,19 @@ Examples ------- # show help - m3db-tool -h + m3ctl -h # create a database - m3db-tool db -create ./database/examples/devel.yaml + m3ctl db -create ./database/examples/devel.yaml # list namespaces - m3db-tool ns + m3ctl ns # delete a namespace - m3db-tool ns -delete default + m3ctl ns -delete default # list placements - m3db-tool pl + m3ctl pl # point to some remote and list namespaces - m3db-tool -endpoint http://localhost:7201 ns + m3ctl -endpoint http://localhost:7201 ns # list the ids of the placements - m3db-tool -endpoint http://localhost:7201 pl | jq .placement.instances[].id + m3ctl -endpoint http://localhost:7201 pl | jq .placement.instances[].id Some example yaml files are provided in the examples directories. Here's one for database creation: diff --git a/src/cmd/tools/m3db_tool/main/database/cmd.go b/src/cmd/tools/m3ctl/main/database/cmd.go similarity index 66% rename from src/cmd/tools/m3db_tool/main/database/cmd.go rename to src/cmd/tools/m3ctl/main/database/cmd.go index 54ba906d35..10e6a065b3 100644 --- a/src/cmd/tools/m3db_tool/main/database/cmd.go +++ b/src/cmd/tools/m3ctl/main/database/cmd.go @@ -3,13 +3,11 @@ package database import ( "flag" "fmt" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/http" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/yaml" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" "github.com/m3db/m3/src/query/generated/proto/admin" "github.com/m3db/m3/src/x/config/configflag" "go.uber.org/zap" - "os" - "strings" ) const ( @@ -40,23 +38,23 @@ Usage of %s: `, databaseFlags.Name(), databaseFlags.Name()) databaseFlags.PrintDefaults() } - flag.Usage = func() { - fmt.Fprintf(flag.CommandLine.Output(), ` -Usage of %s: - - Specify one of the following subcommands, which are shorthand for database, placement, and namespace: - - %s - -Each subcommand has its own built-in help provided via "-h". - -`, os.Args[0], strings.Join([]string{ - databaseFlags.Name(), - databaseFlags.Name(), - databaseFlags.Name(), - }, ", ")) - - flag.PrintDefaults() - } + // flag.Usage = func() { + // fmt.Fprintf(flag.CommandLine.Output(), ` + //Usage of %s: + // + // Specify one of the following subcommands, which are shorthand for database, placement, and namespace: + // + // %s + // + //Each subcommand has its own built-in help provided via "-h". + // + //`, os.Args[0], strings.Join([]string{ + // databaseFlags.Name(), + // databaseFlags.Name(), + // databaseFlags.Name(), + // }, ", ")) + // + // flag.PrintDefaults() + // } return databaseFlags } diff --git a/src/cmd/tools/m3db_tool/main/database/examples/create.yaml b/src/cmd/tools/m3ctl/main/database/examples/create.yaml similarity index 100% rename from src/cmd/tools/m3db_tool/main/database/examples/create.yaml rename to src/cmd/tools/m3ctl/main/database/examples/create.yaml diff --git a/src/cmd/tools/m3db_tool/main/database/examples/devel.yaml b/src/cmd/tools/m3ctl/main/database/examples/devel.yaml similarity index 100% rename from src/cmd/tools/m3db_tool/main/database/examples/devel.yaml rename to src/cmd/tools/m3ctl/main/database/examples/devel.yaml diff --git a/src/cmd/tools/m3db_tool/main/http/http.go b/src/cmd/tools/m3ctl/main/http/http.go similarity index 100% rename from src/cmd/tools/m3db_tool/main/http/http.go rename to src/cmd/tools/m3ctl/main/http/http.go diff --git a/src/cmd/tools/m3db_tool/main/main.go b/src/cmd/tools/m3ctl/main/main.go similarity index 87% rename from src/cmd/tools/m3db_tool/main/main.go rename to src/cmd/tools/m3ctl/main/main.go index 7979b25e2c..25be7b233c 100644 --- a/src/cmd/tools/m3db_tool/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -24,10 +24,11 @@ import ( "flag" "fmt" "os" + "strings" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/database" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/namespaces" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/placements" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/database" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/namespaces" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" "github.com/m3db/m3/src/x/config/configflag" "go.uber.org/zap" ) @@ -45,13 +46,31 @@ func main() { createDatabaseYAML := configflag.FlagStringSlice{} databaseFlags := database.SetupDatabaseFlags(&createDatabaseYAML) - // the namespace-relateed subcommand + // the namespace-related subcommand namespaceArgs := namespaces.NamespaceArgs{} namespaceFlags := namespaces.SetupNamespaceFlags(&namespaceArgs) // the placement-related subcommand placementArgs := placements.PlacementArgs{} placementFlags := placements.SetupPlacementFlags(&placementArgs) + flag.Usage = func() { + fmt.Fprintf(flag.CommandLine.Output(), ` +Usage of %s: + + Specify one of the following subcommands, which are shorthand for database, placement, and namespace: + + %s + +Each subcommand has its own built-in help provided via "-h". + +`, os.Args[0], strings.Join([]string{ + databaseFlags.Name(), + placementFlags.Name(), + namespaceFlags.Name(), + }, ", ")) + + flag.PrintDefaults() + } flag.Parse() diff --git a/src/cmd/tools/m3db_tool/main/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/namespaces/cmd.go similarity index 97% rename from src/cmd/tools/m3db_tool/main/namespaces/cmd.go rename to src/cmd/tools/m3ctl/main/namespaces/cmd.go index 65977ebd0f..490f137b41 100644 --- a/src/cmd/tools/m3db_tool/main/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/namespaces/cmd.go @@ -7,7 +7,7 @@ import ( "io" "github.com/gogo/protobuf/jsonpb" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/http" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" "github.com/m3db/m3/src/query/generated/proto/admin" ) diff --git a/src/cmd/tools/m3db_tool/main/placements/cmd.go b/src/cmd/tools/m3ctl/main/placements/cmd.go similarity index 96% rename from src/cmd/tools/m3db_tool/main/placements/cmd.go rename to src/cmd/tools/m3ctl/main/placements/cmd.go index aa684d9150..41cbc09e62 100644 --- a/src/cmd/tools/m3db_tool/main/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd.go @@ -3,8 +3,8 @@ package placements import ( "flag" "fmt" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/http" - "github.com/m3db/m3/src/cmd/tools/m3db_tool/main/yaml" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" "github.com/m3db/m3/src/query/generated/proto/admin" "github.com/m3db/m3/src/x/config/configflag" "go.uber.org/zap" diff --git a/src/cmd/tools/m3db_tool/main/placements/examples/init.yaml b/src/cmd/tools/m3ctl/main/placements/examples/init.yaml similarity index 100% rename from src/cmd/tools/m3db_tool/main/placements/examples/init.yaml rename to src/cmd/tools/m3ctl/main/placements/examples/init.yaml diff --git a/src/cmd/tools/m3db_tool/main/placements/examples/newNode.yaml b/src/cmd/tools/m3ctl/main/placements/examples/newNode.yaml similarity index 100% rename from src/cmd/tools/m3db_tool/main/placements/examples/newNode.yaml rename to src/cmd/tools/m3ctl/main/placements/examples/newNode.yaml diff --git a/src/cmd/tools/m3db_tool/main/placements/examples/replaceNode.yaml b/src/cmd/tools/m3ctl/main/placements/examples/replaceNode.yaml similarity index 100% rename from src/cmd/tools/m3db_tool/main/placements/examples/replaceNode.yaml rename to src/cmd/tools/m3ctl/main/placements/examples/replaceNode.yaml diff --git a/src/cmd/tools/m3db_tool/main/yaml/load.go b/src/cmd/tools/m3ctl/main/yaml/load.go similarity index 100% rename from src/cmd/tools/m3db_tool/main/yaml/load.go rename to src/cmd/tools/m3ctl/main/yaml/load.go From a70df4d77558e3b24b4b144c6280d578b63870c0 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Thu, 9 Jan 2020 15:22:13 -0800 Subject: [PATCH 15/65] factoring --- src/cmd/tools/m3ctl/main/database/cmd.go | 39 ----------- .../tools/m3ctl/main/database/setupFlags.go | 26 ++++++++ src/cmd/tools/m3ctl/main/main.go | 7 +- src/cmd/tools/m3ctl/main/namespaces/cmd.go | 29 --------- .../tools/m3ctl/main/namespaces/setupFlags.go | 34 ++++++++++ src/cmd/tools/m3ctl/main/placements/cmd.go | 58 +---------------- .../tools/m3ctl/main/placements/setupFlags.go | 64 +++++++++++++++++++ 7 files changed, 129 insertions(+), 128 deletions(-) create mode 100644 src/cmd/tools/m3ctl/main/database/setupFlags.go create mode 100644 src/cmd/tools/m3ctl/main/namespaces/setupFlags.go create mode 100644 src/cmd/tools/m3ctl/main/placements/setupFlags.go diff --git a/src/cmd/tools/m3ctl/main/database/cmd.go b/src/cmd/tools/m3ctl/main/database/cmd.go index 10e6a065b3..f281866e0b 100644 --- a/src/cmd/tools/m3ctl/main/database/cmd.go +++ b/src/cmd/tools/m3ctl/main/database/cmd.go @@ -1,12 +1,10 @@ package database import ( - "flag" "fmt" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" "github.com/m3db/m3/src/query/generated/proto/admin" - "github.com/m3db/m3/src/x/config/configflag" "go.uber.org/zap" ) @@ -21,40 +19,3 @@ func Command(createYAML string, endpoint string, log *zap.SugaredLogger) { http.DoPost(url, data, log, http.DoDump) return } - -func SetupDatabaseFlags(createDatabaseYAML *configflag.FlagStringSlice) *flag.FlagSet { - databaseFlags := flag.NewFlagSet("db", flag.ExitOnError) - databaseFlags.Var(createDatabaseYAML, "create", "Path to yaml for simplified db creation with sane defaults.") - databaseFlags.Usage = func() { - fmt.Fprintf(databaseFlags.Output(), ` -This is the "%s" subcommand for database scoped operations. - -Description: - -This subcommand allows the creation of a new database from a yaml specification. - -Usage of %s: - -`, databaseFlags.Name(), databaseFlags.Name()) - databaseFlags.PrintDefaults() - } - // flag.Usage = func() { - // fmt.Fprintf(flag.CommandLine.Output(), ` - //Usage of %s: - // - // Specify one of the following subcommands, which are shorthand for database, placement, and namespace: - // - // %s - // - //Each subcommand has its own built-in help provided via "-h". - // - //`, os.Args[0], strings.Join([]string{ - // databaseFlags.Name(), - // databaseFlags.Name(), - // databaseFlags.Name(), - // }, ", ")) - // - // flag.PrintDefaults() - // } - return databaseFlags -} diff --git a/src/cmd/tools/m3ctl/main/database/setupFlags.go b/src/cmd/tools/m3ctl/main/database/setupFlags.go new file mode 100644 index 0000000000..2eaa206335 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/database/setupFlags.go @@ -0,0 +1,26 @@ +package database + +import ( + "flag" + "fmt" + "github.com/m3db/m3/src/x/config/configflag" +) + +func SetupFlags(createDatabaseYAML *configflag.FlagStringSlice) *flag.FlagSet { + databaseFlags := flag.NewFlagSet("db", flag.ExitOnError) + databaseFlags.Var(createDatabaseYAML, "create", "Path to yaml for simplified db creation with sane defaults.") + databaseFlags.Usage = func() { + fmt.Fprintf(databaseFlags.Output(), ` +This is the "%s" subcommand for database scoped operations. + +Description: + +This subcommand allows the creation of a new database from a yaml specification. + +Usage of %s: + +`, databaseFlags.Name(), databaseFlags.Name()) + databaseFlags.PrintDefaults() + } + return databaseFlags +} diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 25be7b233c..b30ec61a3c 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -44,15 +44,15 @@ func main() { // the database-related subcommand createDatabaseYAML := configflag.FlagStringSlice{} - databaseFlags := database.SetupDatabaseFlags(&createDatabaseYAML) + databaseFlags := database.SetupFlags(&createDatabaseYAML) // the namespace-related subcommand namespaceArgs := namespaces.NamespaceArgs{} - namespaceFlags := namespaces.SetupNamespaceFlags(&namespaceArgs) + namespaceFlags := namespaces.SetupFlags(&namespaceArgs) // the placement-related subcommand placementArgs := placements.PlacementArgs{} - placementFlags := placements.SetupPlacementFlags(&placementArgs) + placementFlags := placements.SetupFlags(&placementArgs) flag.Usage = func() { fmt.Fprintf(flag.CommandLine.Output(), ` Usage of %s: @@ -106,6 +106,7 @@ Each subcommand has its own built-in help provided via "-h". } } }) + // the below createDatabaseYAML.Value has at least one by this time per the arg parser database.Command(createDatabaseYAML.Value[len(createDatabaseYAML.Value)-1], *endPoint, log) case namespaceFlags.Name(): if err := namespaceFlags.Parse(flag.Args()[1:]); err != nil { diff --git a/src/cmd/tools/m3ctl/main/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/namespaces/cmd.go index 490f137b41..3b241df387 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/namespaces/cmd.go @@ -1,7 +1,6 @@ package namespaces import ( - "flag" "fmt" "go.uber.org/zap" "io" @@ -45,31 +44,3 @@ func Command(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { } return } - -func SetupNamespaceFlags(flags *NamespaceArgs) *flag.FlagSet { - namespaceFlags := flag.NewFlagSet("ns", flag.ExitOnError) - flags.delete = namespaceFlags.String("delete", "", "name of namespace to delete") - flags.showAll = namespaceFlags.Bool("all", false, "show all the standard info for namespaces (otherwise default behaviour lists only the names)") - namespaceFlags.Usage = func() { - fmt.Fprintf(namespaceFlags.Output(), ` -This is the subcommand for acting on placements. - -Description: - -The subcommand "%s"" provides the ability to: - -* list all namespaces -* verbosely list all the available information about the namespaces -* delete a specific namespace - -Default behaviour (no arguments) is to print out the names of the namespaces. - -Specify only one action at a time. - -Usage of %s: - -`, namespaceFlags.Name(), namespaceFlags.Name()) - namespaceFlags.PrintDefaults() - } - return namespaceFlags -} diff --git a/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go b/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go new file mode 100644 index 0000000000..b9bf30972a --- /dev/null +++ b/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go @@ -0,0 +1,34 @@ +package namespaces + +import ( + "flag" + "fmt" +) + +func SetupFlags(flags *NamespaceArgs) *flag.FlagSet { + namespaceFlags := flag.NewFlagSet("ns", flag.ExitOnError) + flags.delete = namespaceFlags.String("delete", "", "name of namespace to delete") + flags.showAll = namespaceFlags.Bool("all", false, "show all the standard info for namespaces (otherwise default behaviour lists only the names)") + namespaceFlags.Usage = func() { + fmt.Fprintf(namespaceFlags.Output(), ` +This is the subcommand for acting on placements. + +Description: + +The subcommand "%s"" provides the ability to: + +* list all namespaces +* verbosely list all the available information about the namespaces +* delete a specific namespace + +Default behaviour (no arguments) is to print out the names of the namespaces. + +Specify only one action at a time. + +Usage of %s: + +`, namespaceFlags.Name(), namespaceFlags.Name()) + namespaceFlags.PrintDefaults() + } + return namespaceFlags +} diff --git a/src/cmd/tools/m3ctl/main/placements/cmd.go b/src/cmd/tools/m3ctl/main/placements/cmd.go index 41cbc09e62..cd0c654a71 100644 --- a/src/cmd/tools/m3ctl/main/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd.go @@ -1,36 +1,17 @@ package placements import ( - "flag" "fmt" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" "github.com/m3db/m3/src/query/generated/proto/admin" - "github.com/m3db/m3/src/x/config/configflag" "go.uber.org/zap" - "os" ) const ( - placementCommandName = "pl" - defaultPath = "/api/v1/services/m3db/placement" - - // flag names - DeleteAllName = "deleteAll" - DeleteNodeName = "deleteNode" - InitName = "init" - NewNodeName = "newNode" - ReplaceNodeName = "replaceNode" + defaultPath = "/api/v1/services/m3db/placement" ) -type PlacementArgs struct { - deletePlacement *bool - deleteNode *string - initFlag configflag.FlagStringSlice - newNodeFlag configflag.FlagStringSlice - replaceFlag configflag.FlagStringSlice -} - func Command(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { log.Debugf("PlacementArgs:%+v:\n", flags) if len(*flags.deleteNode) > 0 { @@ -57,40 +38,3 @@ func Command(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { } return } - -func SetupPlacementFlags(flags *PlacementArgs) *flag.FlagSet { - placementFlags := flag.NewFlagSet(placementCommandName, flag.ExitOnError) - flags.deletePlacement = placementFlags.Bool(DeleteAllName, false, "delete all instances in the placement") - flags.deleteNode = placementFlags.String(DeleteNodeName, "", "delete the specified node in the placement") - placementFlags.Var(&flags.initFlag, InitName, "initialize a placement. Specify a yaml file.") - placementFlags.Var(&flags.newNodeFlag, NewNodeName, "add a new node to the placement. Specify the filename of the yaml.") - placementFlags.Var(&flags.replaceFlag, ReplaceNodeName, "add a new node to the placement. Specify the filename of the yaml.") - placementFlags.Usage = func() { - fmt.Fprintf(os.Stderr, ` -"%s" is for acting on placements. - -Description: - -The subcommand "%s" provides the ability to: - -* delete an entire placement from a node -* remove a node from a placement -* add a new node to as existing placement -* replace a node within an existing placement -* initialize a placement - -Default behaviour (no arguments) is to provide a json dump of the existing placement. - -New node creation and node replacement require specification of -the desired placement parameters, which you are to provide via a yaml -file, the pathname of which is the argument for the cli option. - -Specify only one action at a time. - -Usage of %s: - -`, placementFlags.Name(), placementFlags.Name(), placementFlags.Name()) - placementFlags.PrintDefaults() - } - return placementFlags -} diff --git a/src/cmd/tools/m3ctl/main/placements/setupFlags.go b/src/cmd/tools/m3ctl/main/placements/setupFlags.go new file mode 100644 index 0000000000..3d6834875d --- /dev/null +++ b/src/cmd/tools/m3ctl/main/placements/setupFlags.go @@ -0,0 +1,64 @@ +package placements + +import ( + "flag" + "fmt" + "github.com/m3db/m3/src/x/config/configflag" + "os" +) + +const ( + placementCommandName = "pl" + + // flag names + DeleteAllName = "deleteAll" + DeleteNodeName = "deleteNode" + InitName = "init" + NewNodeName = "newNode" + ReplaceNodeName = "replaceNode" +) + +type PlacementArgs struct { + deletePlacement *bool + deleteNode *string + initFlag configflag.FlagStringSlice + newNodeFlag configflag.FlagStringSlice + replaceFlag configflag.FlagStringSlice +} + +func SetupFlags(flags *PlacementArgs) *flag.FlagSet { + placementFlags := flag.NewFlagSet(placementCommandName, flag.ExitOnError) + flags.deletePlacement = placementFlags.Bool(DeleteAllName, false, "delete all instances in the placement") + flags.deleteNode = placementFlags.String(DeleteNodeName, "", "delete the specified node in the placement") + placementFlags.Var(&flags.initFlag, InitName, "initialize a placement. Specify a yaml file.") + placementFlags.Var(&flags.newNodeFlag, NewNodeName, "add a new node to the placement. Specify the filename of the yaml.") + placementFlags.Var(&flags.replaceFlag, ReplaceNodeName, "add a new node to the placement. Specify the filename of the yaml.") + placementFlags.Usage = func() { + fmt.Fprintf(os.Stderr, ` +"%s" is for acting on placements. + +Description: + +The subcommand "%s" provides the ability to: + +* delete an entire placement from a node +* remove a node from a placement +* add a new node to as existing placement +* replace a node within an existing placement +* initialize a placement + +Default behaviour (no arguments) is to provide a json dump of the existing placement. + +New node creation and node replacement require specification of +the desired placement parameters, which you are to provide via a yaml +file, the pathname of which is the argument for the cli option. + +Specify only one action at a time. + +Usage of %s: + +`, placementFlags.Name(), placementFlags.Name(), placementFlags.Name()) + placementFlags.PrintDefaults() + } + return placementFlags +} From 3685e07560aca6db0b7745ffcd2e5440a8333eb0 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Thu, 9 Jan 2020 19:48:59 -0800 Subject: [PATCH 16/65] add yaml loader test --- src/cmd/tools/m3ctl/main/http/checker.go | 19 +++++++++ src/cmd/tools/m3ctl/main/http/http.go | 10 ----- src/cmd/tools/m3ctl/main/yaml/load.go | 16 ++++++-- src/cmd/tools/m3ctl/main/yaml/load_test.go | 40 +++++++++++++++++++ .../m3ctl/main/yaml/testdata/basicCreate.yaml | 15 +++++++ 5 files changed, 86 insertions(+), 14 deletions(-) create mode 100644 src/cmd/tools/m3ctl/main/http/checker.go create mode 100644 src/cmd/tools/m3ctl/main/yaml/load_test.go create mode 100644 src/cmd/tools/m3ctl/main/yaml/testdata/basicCreate.yaml diff --git a/src/cmd/tools/m3ctl/main/http/checker.go b/src/cmd/tools/m3ctl/main/http/checker.go new file mode 100644 index 0000000000..3e50b47268 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/http/checker.go @@ -0,0 +1,19 @@ +package http + +import ( + "fmt" + "go.uber.org/zap" + "io/ioutil" + "net/http" +) + +func checkForAndHandleError(url string, resp *http.Response, log *zap.SugaredLogger) { + log.Debugf("resp.StatusCode:%d:\n", resp.StatusCode) + if resp.StatusCode > 299 { + dat, _ := ioutil.ReadAll(resp.Body) + if dat != nil { + fmt.Println(string(dat)) + } + log.Fatalf("error from m3db:%s:url:%s:", resp.Status, url) + } +} diff --git a/src/cmd/tools/m3ctl/main/http/http.go b/src/cmd/tools/m3ctl/main/http/http.go index 4596156246..ece01177b2 100644 --- a/src/cmd/tools/m3ctl/main/http/http.go +++ b/src/cmd/tools/m3ctl/main/http/http.go @@ -75,13 +75,3 @@ func DoDump(in io.Reader, log *zap.SugaredLogger) { fmt.Println(string(dat)) } -func checkForAndHandleError(url string, resp *http.Response, log *zap.SugaredLogger) { - log.Debugf("resp.StatusCode:%d:\n", resp.StatusCode) - if resp.StatusCode > 299 { - dat, _ := ioutil.ReadAll(resp.Body) - if dat != nil { - fmt.Println(string(dat)) - } - log.Fatalf("error from m3db:%s:url:%s:", resp.Status, url) - } -} diff --git a/src/cmd/tools/m3ctl/main/yaml/load.go b/src/cmd/tools/m3ctl/main/yaml/load.go index 8f657fb222..3b62fd909c 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load.go +++ b/src/cmd/tools/m3ctl/main/yaml/load.go @@ -16,14 +16,22 @@ func Load(path string, target proto.Message, log *zap.SugaredLogger) io.Reader { if err != nil { log.Fatal(err) } - if err = yaml.Unmarshal(content, target); err != nil { + rv, err := _load(content, target) + if err != nil { log.Fatalf("cannot unmarshal data:%v:from yaml file:%s:", err, path) } + return rv +} +// more easily testable version +func _load(content []byte, target proto.Message) (io.Reader, error) { + if err := yaml.Unmarshal(content, target); err != nil { + return nil, err + } var data *bytes.Buffer data = bytes.NewBuffer(nil) marshaller := &jsonpb.Marshaler{} - if err = marshaller.Marshal(data, target); err != nil { - log.Fatal(err) + if err := marshaller.Marshal(data, target); err != nil { + return nil, err } - return data + return data, nil } diff --git a/src/cmd/tools/m3ctl/main/yaml/load_test.go b/src/cmd/tools/m3ctl/main/yaml/load_test.go new file mode 100644 index 0000000000..8fffc8f736 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/yaml/load_test.go @@ -0,0 +1,40 @@ +package yaml + +import ( + "io/ioutil" + "testing" + "github.com/gogo/protobuf/jsonpb" + "github.com/m3db/m3/src/query/generated/proto/admin" +) + +func TestLoadBasic(t *testing.T) { + content, err := ioutil.ReadFile("./testdata/basicCreate.yaml") + if err != nil { + t.Fatalf("failed to read yaml test data:%v:\n", err) + } + + source := admin.DatabaseCreateRequest{} + data, err := _load(content, &source) + + dest := admin.DatabaseCreateRequest{} + unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} + if err := unmarshaller.Unmarshal(data, &dest); err != nil { + t.Fatalf("failed to unmarshal basic test data:%v:\n", err) + } + if dest.ReplicationFactor != 327 { + t.Errorf("in and out ReplicationFactor did not match:expected:%d:got:%d:\n", source.ReplicationFactor, dest.ReplicationFactor) + } + if dest.ReplicationFactor != source.ReplicationFactor { + t.Errorf("in and out ReplicationFactor did not match:expected:%d:got:%d:\n", source.ReplicationFactor, dest.ReplicationFactor) + } + if dest.NamespaceName != "default" { + t.Errorf("namespace is wrong:expected:%s:got:%s:\n", "default", dest.NamespaceName) + } + if len(dest.Hosts) != 1 { + t.Errorf("number of hosts is wrong:expected:%d:got:%d:\n", 1, len(dest.Hosts)) + } + if dest.Hosts[0].Id != "m3db_seed" { + t.Errorf("hostname is wrong:expected:%s:got:%s:\n", "m3db_seed", dest.Hosts[0]) + } + +} diff --git a/src/cmd/tools/m3ctl/main/yaml/testdata/basicCreate.yaml b/src/cmd/tools/m3ctl/main/yaml/testdata/basicCreate.yaml new file mode 100644 index 0000000000..899de1cc8d --- /dev/null +++ b/src/cmd/tools/m3ctl/main/yaml/testdata/basicCreate.yaml @@ -0,0 +1,15 @@ +--- +type: cluster +namespace_name: default +retention_time: 168h +num_shards: 64 +replication_factor: 327 +hosts: +- id: m3db_seed + isolation_group: rack-a + zone: embedded + weight: 1024 + endpoint: m3db_seed:9000 + hostname: m3db_seed + port: 9000 + From 62a73685990c166259e9d925f36728bb3a603879 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Fri, 10 Jan 2020 12:43:33 -0800 Subject: [PATCH 17/65] checkpoint refactor to redo the cli syntax --- .../tools/m3ctl/main/database/setupFlags.go | 29 +++- src/cmd/tools/m3ctl/main/main.go | 133 +++++++++++++----- src/cmd/tools/m3ctl/main/namespaces/cmd.go | 47 ++----- src/cmd/tools/m3ctl/main/namespaces/delete.go | 12 ++ .../tools/m3ctl/main/namespaces/setupFlags.go | 42 ++++-- src/cmd/tools/m3ctl/main/namespaces/show.go | 37 +++++ .../tools/m3ctl/main/namespaces/showNames.go | 26 ++++ 7 files changed, 242 insertions(+), 84 deletions(-) create mode 100644 src/cmd/tools/m3ctl/main/namespaces/delete.go create mode 100644 src/cmd/tools/m3ctl/main/namespaces/show.go create mode 100644 src/cmd/tools/m3ctl/main/namespaces/showNames.go diff --git a/src/cmd/tools/m3ctl/main/database/setupFlags.go b/src/cmd/tools/m3ctl/main/database/setupFlags.go index 2eaa206335..fb1bc67198 100644 --- a/src/cmd/tools/m3ctl/main/database/setupFlags.go +++ b/src/cmd/tools/m3ctl/main/database/setupFlags.go @@ -6,21 +6,40 @@ import ( "github.com/m3db/m3/src/x/config/configflag" ) -func SetupFlags(createDatabaseYAML *configflag.FlagStringSlice) *flag.FlagSet { +type DatabaseFlagSets struct { + Database *flag.FlagSet + Create * flag.FlagSet +} +func SetupFlags(createDatabaseYAML *configflag.FlagStringSlice) DatabaseFlagSets { databaseFlags := flag.NewFlagSet("db", flag.ExitOnError) - databaseFlags.Var(createDatabaseYAML, "create", "Path to yaml for simplified db creation with sane defaults.") + createFlags := flag.NewFlagSet("create", flag.ExitOnError) + databaseFlags.Usage = func() { fmt.Fprintf(databaseFlags.Output(), ` This is the "%s" subcommand for database scoped operations. +It has the following subcommands: + + %s + +`, databaseFlags.Name(), createFlags.Name()) + databaseFlags.PrintDefaults() + } + + createFlags.Var(createDatabaseYAML, "f", "Path to yaml for simplified db creation with sane defaults.") + createFlags.Usage = func() { + fmt.Fprintf(databaseFlags.Output(), ` +This is the "%s" subcommand for %s scoped operations. + Description: This subcommand allows the creation of a new database from a yaml specification. Usage of %s: -`, databaseFlags.Name(), databaseFlags.Name()) - databaseFlags.PrintDefaults() +`, createFlags.Name(), databaseFlags.Name(), createFlags.Name()) + createFlags.PrintDefaults() } - return databaseFlags + + return DatabaseFlagSets{Database:databaseFlags, Create:createFlags} } diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index b30ec61a3c..1b72ab44c6 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -44,11 +44,11 @@ func main() { // the database-related subcommand createDatabaseYAML := configflag.FlagStringSlice{} - databaseFlags := database.SetupFlags(&createDatabaseYAML) + databaseFlagSets := database.SetupFlags(&createDatabaseYAML) // the namespace-related subcommand namespaceArgs := namespaces.NamespaceArgs{} - namespaceFlags := namespaces.SetupFlags(&namespaceArgs) + namespaceFlagSets := namespaces.SetupFlags(&namespaceArgs) // the placement-related subcommand placementArgs := placements.PlacementArgs{} @@ -64,9 +64,9 @@ Usage of %s: Each subcommand has its own built-in help provided via "-h". `, os.Args[0], strings.Join([]string{ - databaseFlags.Name(), + databaseFlagSets.Database.Name(), placementFlags.Name(), - namespaceFlags.Name(), + namespaceFlagSets.Namespace.Name(), }, ", ")) flag.PrintDefaults() @@ -87,48 +87,109 @@ Each subcommand has its own built-in help provided via "-h". log := rawLogger.Sugar() switch flag.Arg(0) { - case databaseFlags.Name(): - if err := databaseFlags.Parse(flag.Args()[1:]); err != nil { - databaseFlags.Usage() + case databaseFlagSets.Database.Name(): + if err := databaseFlagSets.Database.Parse(flag.Args()[1:]); err != nil { + databaseFlagSets.Database.Usage() os.Exit(1) } - if databaseFlags.NFlag() == 0 { - databaseFlags.Usage() + if databaseFlagSets.Database.NArg() == 0 { + databaseFlagSets.Database.Usage() os.Exit(1) } - databaseFlags.Visit(func(f *flag.Flag) { - vals := f.Value.(*configflag.FlagStringSlice) - for _, val := range vals.Value { - if len(val) == 0 { - fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - databaseFlags.Usage() - os.Exit(1) - } + //databaseFlags.Visit(func(f *flag.Flag) { + // vals := f.Value.(*configflag.FlagStringSlice) + // for _, val := range vals.Value { + // if len(val) == 0 { + // fmt.Println("QQQQ3") + // fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + // databaseFlags.Usage() + // os.Exit(1) + // } + // } + //}) + + //database.Command(createDatabaseYAML.Value[len(createDatabaseYAML.Value)-1], *endPoint, log) + switch flag.Arg(1) { + case databaseFlagSets.Create.Name(): + if err := databaseFlagSets.Create.Parse(flag.Args()[2:]); err != nil { + databaseFlagSets.Create.Usage() + os.Exit(1) } - }) - // the below createDatabaseYAML.Value has at least one by this time per the arg parser - database.Command(createDatabaseYAML.Value[len(createDatabaseYAML.Value)-1], *endPoint, log) - case namespaceFlags.Name(): - if err := namespaceFlags.Parse(flag.Args()[1:]); err != nil { - namespaceFlags.Usage() + if databaseFlagSets.Create.NFlag() == 0 { + //fmt.Println("QQQQ5") + databaseFlagSets.Create.Usage() + os.Exit(1) + } + databaseFlagSets.Create.Visit(func(f *flag.Flag) { + vals := f.Value.(*configflag.FlagStringSlice) + for _, val := range vals.Value { + if len(val) == 0 { + //fmt.Println("QQQQ5.5") + fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + databaseFlagSets.Create.Usage() + os.Exit(1) + } + } + }) + // the below createDatabaseYAML.Value has at least one by this time per the arg parser + database.Command(createDatabaseYAML.Value[len(createDatabaseYAML.Value)-1], *endPoint, log) + default: + //fmt.Println("QQQQ6") + databaseFlagSets.Database.Usage() os.Exit(1) } - if namespaceFlags.NFlag() > 1 { - fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") - namespaceFlags.Usage() + case namespaceFlagSets.Namespace.Name(): + if err := namespaceFlagSets.Namespace.Parse(flag.Args()[1:]); err != nil { + namespaceFlagSets.Namespace.Usage() os.Exit(1) } - namespaceFlags.Visit(func(f *flag.Flag) { - vals := f.Value.(*configflag.FlagStringSlice) - for _, val := range vals.Value { - if len(val) == 0 { - fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - namespaceFlags.Usage() - os.Exit(1) - } + // maybe do the default action which is listing the names + if namespaceFlagSets.Namespace.NArg() == 0 { + namespaces.Show(&namespaceArgs, *endPoint, log) + os.Exit(0) + } + + //if namespaceFlagSets.NFlag() > 1 { + // fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") + // namespaceFlagSets.Usage() + // os.Exit(1) + //} + //namespaceFlagSets.Namespace.Visit(func(f *flag.Flag) { + // vals := f.Value.(*configflag.FlagStringSlice) + // for _, val := range vals.Value { + // if len(val) == 0 { + // fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + // namespaceFlagSets.Namespace.Usage() + // os.Exit(1) + // } + // } + //}) + //namespaces.Command(&namespaceArgs, *endPoint, log) + switch flag.Arg(1) { + case namespaceFlagSets.Delete.Name(): + if err := namespaceFlagSets.Delete.Parse(flag.Args()[2:]); err != nil { + namespaceFlagSets.Delete.Usage() + os.Exit(1) } - }) - namespaces.Command(&namespaceArgs, *endPoint, log) + if namespaceFlagSets.Delete.NFlag() == 0 { + //fmt.Println("QQQQ5") + namespaceFlagSets.Delete.Usage() + os.Exit(1) + } + namespaceFlagSets.Delete.Visit(func(f *flag.Flag) { + if len(f.Value.String()) == 0 { + //fmt.Println("QQQQ5.5") + fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + namespaceFlagSets.Delete.Usage() + os.Exit(1) + } + }) + namespaces.Delete(&namespaceArgs, *endPoint, log) + + default: + namespaceFlagSets.Namespace.Usage() + os.Exit(1) + } case placementFlags.Name(): if err := placementFlags.Parse(flag.Args()[1:]); err != nil { placementFlags.Usage() diff --git a/src/cmd/tools/m3ctl/main/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/namespaces/cmd.go index 3b241df387..8ef99013ac 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/namespaces/cmd.go @@ -1,15 +1,5 @@ package namespaces -import ( - "fmt" - "go.uber.org/zap" - "io" - - "github.com/gogo/protobuf/jsonpb" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" - "github.com/m3db/m3/src/query/generated/proto/admin" -) - const ( defaultPath = "/api/v1/namespace" debugQS = "debug=true" @@ -20,27 +10,16 @@ type NamespaceArgs struct { delete *string } -func showNames(in io.Reader, log *zap.SugaredLogger) { - registry := admin.NamespaceGetResponse{} - unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} - if err := unmarshaller.Unmarshal(in, ®istry); err != nil { - log.Fatal(err) - } - for k, _ := range registry.Registry.Namespaces { - fmt.Println(k) - } -} - -func Command(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { - log.Debugf("NamespaceArgs:%+v:\n", flags) - url := fmt.Sprintf("%s%s?%s", endpoint, defaultPath, debugQS) - if *flags.showAll { - http.DoGet(url, log, http.DoDump) - } else if len(*flags.delete) > 0 { - url = fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", *flags.delete) - http.DoDelete(url, log, http.DoDump) - } else { - http.DoGet(url, log, showNames) - } - return -} +//func xCommand(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { +// log.Debugf("NamespaceArgs:%+v:\n", flags) +// url := fmt.Sprintf("%s%s?%s", endpoint, defaultPath, debugQS) +// if *flags.showAll { +// http.DoGet(url, log, http.DoDump) +// } else if len(*flags.delete) > 0 { +// url = fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", *flags.delete) +// http.DoDelete(url, log, http.DoDump) +// } else { +// http.DoGet(url, log, showNames) +// } +// return +//} diff --git a/src/cmd/tools/m3ctl/main/namespaces/delete.go b/src/cmd/tools/m3ctl/main/namespaces/delete.go new file mode 100644 index 0000000000..d34f676f9c --- /dev/null +++ b/src/cmd/tools/m3ctl/main/namespaces/delete.go @@ -0,0 +1,12 @@ +package namespaces + +import ( + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + "go.uber.org/zap" +) + +func Delete(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { + url := fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", *flags.delete) + http.DoDelete(url, log, http.DoDump) +} diff --git a/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go b/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go index b9bf30972a..ecab96dfc9 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go +++ b/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go @@ -5,30 +5,54 @@ import ( "fmt" ) -func SetupFlags(flags *NamespaceArgs) *flag.FlagSet { +type NamespaceFlags struct { + Namespace *flag.FlagSet + Delete *flag.FlagSet +} + +func SetupFlags(flags *NamespaceArgs) NamespaceFlags { namespaceFlags := flag.NewFlagSet("ns", flag.ExitOnError) - flags.delete = namespaceFlags.String("delete", "", "name of namespace to delete") + deleteFlags := flag.NewFlagSet("delete", flag.ExitOnError) + flags.delete = deleteFlags.String("name", "", "name of namespace to delete") + flags.showAll = namespaceFlags.Bool("all", false, "show all the standard info for namespaces (otherwise default behaviour lists only the names)") namespaceFlags.Usage = func() { fmt.Fprintf(namespaceFlags.Output(), ` -This is the subcommand for acting on placements. +This is the subcommand for acting on namespaces. Description: The subcommand "%s"" provides the ability to: -* list all namespaces -* verbosely list all the available information about the namespaces -* delete a specific namespace +* list all namespaces (default) +* verbosely list all the available information about the namespaces (-all) +* delete a specific namespace (see the delete subcommand) Default behaviour (no arguments) is to print out the names of the namespaces. Specify only one action at a time. -Usage of %s: +It has the following subcommands: -`, namespaceFlags.Name(), namespaceFlags.Name()) + %s + +Usage: + +`, namespaceFlags.Name(), deleteFlags.Name()) namespaceFlags.PrintDefaults() } - return namespaceFlags + deleteFlags.Usage = func() { + fmt.Fprintf(deleteFlags.Output(), ` +This is the "%s" subcommand for %s scoped operations. + +Description: + +This subcommand allows the creation of a new database from a yaml specification. + +Usage of %s: + +`, deleteFlags.Name(), namespaceFlags.Name(), deleteFlags.Name()) + deleteFlags.PrintDefaults() + } + return NamespaceFlags{Namespace: namespaceFlags, Delete: deleteFlags} } diff --git a/src/cmd/tools/m3ctl/main/namespaces/show.go b/src/cmd/tools/m3ctl/main/namespaces/show.go new file mode 100644 index 0000000000..1504fa3896 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/namespaces/show.go @@ -0,0 +1,37 @@ +package namespaces + +import ( + "fmt" + "github.com/gogo/protobuf/jsonpb" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + "github.com/m3db/m3/src/query/generated/proto/admin" + "go.uber.org/zap" + "io" +) + +func Show(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { + url := fmt.Sprintf("%s%s?%s", endpoint, defaultPath, debugQS) + if *flags.showAll { + http.DoGet(url, log, http.DoDump) + } else { + http.DoGet(url, log, showNames) + } +} + + +func showNames(in io.Reader, log *zap.SugaredLogger) { + registry := admin.NamespaceGetResponse{} + unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} + if err := unmarshaller.Unmarshal(in, ®istry); err != nil { + log.Fatal(err) + } + for k, _ := range registry.Registry.Namespaces { + fmt.Println(k) + } +} + +//func ShowNames(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { +// url := fmt.Sprintf("%s%s?%s", endpoint, defaultPath, debugQS) +// http.DoGet(url, log, showNames) +//} + diff --git a/src/cmd/tools/m3ctl/main/namespaces/showNames.go b/src/cmd/tools/m3ctl/main/namespaces/showNames.go new file mode 100644 index 0000000000..db0babd577 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/namespaces/showNames.go @@ -0,0 +1,26 @@ +package namespaces + +//import ( +// "fmt" +// "github.com/gogo/protobuf/jsonpb" +// "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" +// "github.com/m3db/m3/src/query/generated/proto/admin" +// "go.uber.org/zap" +// "io" +//) + +//func showNames(in io.Reader, log *zap.SugaredLogger) { +// registry := admin.NamespaceGetResponse{} +// unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} +// if err := unmarshaller.Unmarshal(in, ®istry); err != nil { +// log.Fatal(err) +// } +// for k, _ := range registry.Registry.Namespaces { +// fmt.Println(k) +// } +//} +// +//func ShowNames(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { +// url := fmt.Sprintf("%s%s?%s", endpoint, defaultPath, debugQS) +// http.DoGet(url, log, showNames) +//} From bc8682824888808b353c159ca2b993440884d002 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Fri, 10 Jan 2020 19:01:08 -0800 Subject: [PATCH 18/65] finished putting in new cli syntax --- .../m3ctl/main/database/{cmd.go => create.go} | 2 +- .../tools/m3ctl/main/database/setupFlags.go | 5 +- src/cmd/tools/m3ctl/main/http/http.go | 1 - src/cmd/tools/m3ctl/main/main.go | 156 ++++++++++-------- src/cmd/tools/m3ctl/main/namespaces/cmd.go | 19 --- .../tools/m3ctl/main/namespaces/setupFlags.go | 9 +- src/cmd/tools/m3ctl/main/namespaces/show.go | 7 - .../tools/m3ctl/main/namespaces/showNames.go | 26 --- src/cmd/tools/m3ctl/main/placements/add.go | 17 ++ src/cmd/tools/m3ctl/main/placements/cmd.go | 35 ---- src/cmd/tools/m3ctl/main/placements/delete.go | 18 ++ src/cmd/tools/m3ctl/main/placements/get.go | 13 ++ src/cmd/tools/m3ctl/main/placements/init.go | 17 ++ .../tools/m3ctl/main/placements/replace.go | 16 ++ .../tools/m3ctl/main/placements/setupFlags.go | 51 +++--- src/cmd/tools/m3ctl/main/yaml/load.go | 3 +- src/cmd/tools/m3ctl/main/yaml/load_test.go | 4 +- 17 files changed, 214 insertions(+), 185 deletions(-) rename src/cmd/tools/m3ctl/main/database/{cmd.go => create.go} (86%) delete mode 100644 src/cmd/tools/m3ctl/main/namespaces/showNames.go create mode 100644 src/cmd/tools/m3ctl/main/placements/add.go create mode 100644 src/cmd/tools/m3ctl/main/placements/delete.go create mode 100644 src/cmd/tools/m3ctl/main/placements/get.go create mode 100644 src/cmd/tools/m3ctl/main/placements/init.go create mode 100644 src/cmd/tools/m3ctl/main/placements/replace.go diff --git a/src/cmd/tools/m3ctl/main/database/cmd.go b/src/cmd/tools/m3ctl/main/database/create.go similarity index 86% rename from src/cmd/tools/m3ctl/main/database/cmd.go rename to src/cmd/tools/m3ctl/main/database/create.go index f281866e0b..d6b91688b3 100644 --- a/src/cmd/tools/m3ctl/main/database/cmd.go +++ b/src/cmd/tools/m3ctl/main/database/create.go @@ -12,7 +12,7 @@ const ( defaultPath = "/api/v1/database" ) -func Command(createYAML string, endpoint string, log *zap.SugaredLogger) { +func Create(createYAML string, endpoint string, log *zap.SugaredLogger) { log.Debugf("createYAML:%s:\n", createYAML) data := yaml.Load(createYAML, &admin.DatabaseCreateRequest{}, log) url := fmt.Sprintf("%s%s/create", endpoint, defaultPath) diff --git a/src/cmd/tools/m3ctl/main/database/setupFlags.go b/src/cmd/tools/m3ctl/main/database/setupFlags.go index fb1bc67198..f940179cc7 100644 --- a/src/cmd/tools/m3ctl/main/database/setupFlags.go +++ b/src/cmd/tools/m3ctl/main/database/setupFlags.go @@ -8,8 +8,9 @@ import ( type DatabaseFlagSets struct { Database *flag.FlagSet - Create * flag.FlagSet + Create *flag.FlagSet } + func SetupFlags(createDatabaseYAML *configflag.FlagStringSlice) DatabaseFlagSets { databaseFlags := flag.NewFlagSet("db", flag.ExitOnError) createFlags := flag.NewFlagSet("create", flag.ExitOnError) @@ -41,5 +42,5 @@ Usage of %s: createFlags.PrintDefaults() } - return DatabaseFlagSets{Database:databaseFlags, Create:createFlags} + return DatabaseFlagSets{Database: databaseFlags, Create: createFlags} } diff --git a/src/cmd/tools/m3ctl/main/http/http.go b/src/cmd/tools/m3ctl/main/http/http.go index ece01177b2..41bf936bb5 100644 --- a/src/cmd/tools/m3ctl/main/http/http.go +++ b/src/cmd/tools/m3ctl/main/http/http.go @@ -74,4 +74,3 @@ func DoDump(in io.Reader, log *zap.SugaredLogger) { } fmt.Println(string(dat)) } - diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 1b72ab44c6..39ab3ec369 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -23,14 +23,12 @@ package main import ( "flag" "fmt" - "os" - "strings" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/database" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/namespaces" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" "github.com/m3db/m3/src/x/config/configflag" "go.uber.org/zap" + "os" ) const ( @@ -52,7 +50,7 @@ func main() { // the placement-related subcommand placementArgs := placements.PlacementArgs{} - placementFlags := placements.SetupFlags(&placementArgs) + placementFlagSets := placements.SetupFlags(&placementArgs) flag.Usage = func() { fmt.Fprintf(flag.CommandLine.Output(), ` Usage of %s: @@ -60,14 +58,14 @@ Usage of %s: Specify one of the following subcommands, which are shorthand for database, placement, and namespace: %s + %s + %s Each subcommand has its own built-in help provided via "-h". -`, os.Args[0], strings.Join([]string{ - databaseFlagSets.Database.Name(), - placementFlags.Name(), - namespaceFlagSets.Namespace.Name(), - }, ", ")) +`, os.Args[0], databaseFlagSets.Database.Name(), + placementFlagSets.Placement.Name(), + namespaceFlagSets.Namespace.Name()) flag.PrintDefaults() } @@ -96,19 +94,6 @@ Each subcommand has its own built-in help provided via "-h". databaseFlagSets.Database.Usage() os.Exit(1) } - //databaseFlags.Visit(func(f *flag.Flag) { - // vals := f.Value.(*configflag.FlagStringSlice) - // for _, val := range vals.Value { - // if len(val) == 0 { - // fmt.Println("QQQQ3") - // fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - // databaseFlags.Usage() - // os.Exit(1) - // } - // } - //}) - - //database.Command(createDatabaseYAML.Value[len(createDatabaseYAML.Value)-1], *endPoint, log) switch flag.Arg(1) { case databaseFlagSets.Create.Name(): if err := databaseFlagSets.Create.Parse(flag.Args()[2:]); err != nil { @@ -116,7 +101,6 @@ Each subcommand has its own built-in help provided via "-h". os.Exit(1) } if databaseFlagSets.Create.NFlag() == 0 { - //fmt.Println("QQQQ5") databaseFlagSets.Create.Usage() os.Exit(1) } @@ -124,7 +108,6 @@ Each subcommand has its own built-in help provided via "-h". vals := f.Value.(*configflag.FlagStringSlice) for _, val := range vals.Value { if len(val) == 0 { - //fmt.Println("QQQQ5.5") fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) databaseFlagSets.Create.Usage() os.Exit(1) @@ -132,9 +115,8 @@ Each subcommand has its own built-in help provided via "-h". } }) // the below createDatabaseYAML.Value has at least one by this time per the arg parser - database.Command(createDatabaseYAML.Value[len(createDatabaseYAML.Value)-1], *endPoint, log) + database.Create(createDatabaseYAML.Value[len(createDatabaseYAML.Value)-1], *endPoint, log) default: - //fmt.Println("QQQQ6") databaseFlagSets.Database.Usage() os.Exit(1) } @@ -148,23 +130,6 @@ Each subcommand has its own built-in help provided via "-h". namespaces.Show(&namespaceArgs, *endPoint, log) os.Exit(0) } - - //if namespaceFlagSets.NFlag() > 1 { - // fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") - // namespaceFlagSets.Usage() - // os.Exit(1) - //} - //namespaceFlagSets.Namespace.Visit(func(f *flag.Flag) { - // vals := f.Value.(*configflag.FlagStringSlice) - // for _, val := range vals.Value { - // if len(val) == 0 { - // fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - // namespaceFlagSets.Namespace.Usage() - // os.Exit(1) - // } - // } - //}) - //namespaces.Command(&namespaceArgs, *endPoint, log) switch flag.Arg(1) { case namespaceFlagSets.Delete.Name(): if err := namespaceFlagSets.Delete.Parse(flag.Args()[2:]); err != nil { @@ -172,56 +137,111 @@ Each subcommand has its own built-in help provided via "-h". os.Exit(1) } if namespaceFlagSets.Delete.NFlag() == 0 { - //fmt.Println("QQQQ5") namespaceFlagSets.Delete.Usage() os.Exit(1) } namespaceFlagSets.Delete.Visit(func(f *flag.Flag) { - if len(f.Value.String()) == 0 { - //fmt.Println("QQQQ5.5") - fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - namespaceFlagSets.Delete.Usage() - os.Exit(1) - } + if len(f.Value.String()) == 0 { + fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + namespaceFlagSets.Delete.Usage() + os.Exit(1) + } }) namespaces.Delete(&namespaceArgs, *endPoint, log) - default: namespaceFlagSets.Namespace.Usage() os.Exit(1) } - case placementFlags.Name(): - if err := placementFlags.Parse(flag.Args()[1:]); err != nil { - placementFlags.Usage() + case placementFlagSets.Placement.Name(): + if err := placementFlagSets.Placement.Parse(flag.Args()[1:]); err != nil { + placementFlagSets.Placement.Usage() os.Exit(1) } - if placementFlags.NFlag() > 1 { - fmt.Fprintf(os.Stderr, "Please specify only one action. There were too many cli arguments provided.\n") - placementFlags.Usage() - os.Exit(1) + if placementFlagSets.Placement.NArg() == 0 { + placements.Get(&placementArgs, *endPoint, log) + os.Exit(0) } - placementFlags.Visit(func(f *flag.Flag) { - switch f.Name { - case placements.DeleteNodeName: + switch flag.Arg(1) { + case placementFlagSets.Add.Name(): + if err := placementFlagSets.Add.Parse(flag.Args()[2:]); err != nil { + placementFlagSets.Add.Usage() + os.Exit(1) + } + if placementFlagSets.Add.NFlag() == 0 { + placementFlagSets.Add.Usage() + os.Exit(1) + } + placementFlagSets.Add.Visit(func(f *flag.Flag) { + vals := f.Value.(*configflag.FlagStringSlice) + for _, val := range vals.Value { + if len(val) == 0 { + fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + placementFlagSets.Add.Usage() + os.Exit(1) + } + } + }) + placements.Add(&placementArgs, *endPoint, log) + case placementFlagSets.Delete.Name(): + if err := placementFlagSets.Delete.Parse(flag.Args()[2:]); err != nil { + placementFlagSets.Delete.Usage() + os.Exit(1) + } + if placementFlagSets.Delete.NFlag() == 0 { + placementFlagSets.Delete.Usage() + os.Exit(1) + } + placementFlagSets.Delete.Visit(func(f *flag.Flag) { if len(f.Value.String()) == 0 { fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - placementFlags.Usage() + placementFlagSets.Delete.Usage() os.Exit(1) } - case placements.InitName, placements.NewNodeName, placements.ReplaceNodeName: + }) + placements.Delete(&placementArgs, *endPoint, log) + case placementFlagSets.Init.Name(): + if err := placementFlagSets.Init.Parse(flag.Args()[2:]); err != nil { + placementFlagSets.Init.Usage() + os.Exit(1) + } + if placementFlagSets.Init.NFlag() == 0 { + placementFlagSets.Init.Usage() + os.Exit(1) + } + placementFlagSets.Init.Visit(func(f *flag.Flag) { vals := f.Value.(*configflag.FlagStringSlice) for _, val := range vals.Value { if len(val) == 0 { fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - placementFlags.Usage() + placementFlagSets.Init.Usage() os.Exit(1) } } - default: - return + }) + placements.Init(&placementArgs, *endPoint, log) + case placementFlagSets.Replace.Name(): + if err := placementFlagSets.Replace.Parse(flag.Args()[2:]); err != nil { + placementFlagSets.Replace.Usage() + os.Exit(1) + } + if placementFlagSets.Replace.NFlag() == 0 { + placementFlagSets.Replace.Usage() + os.Exit(1) } - }) - placements.Command(&placementArgs, *endPoint, log) + placementFlagSets.Replace.Visit(func(f *flag.Flag) { + vals := f.Value.(*configflag.FlagStringSlice) + for _, val := range vals.Value { + if len(val) == 0 { + fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + placementFlagSets.Replace.Usage() + os.Exit(1) + } + } + }) + placements.Replace(&placementArgs, *endPoint, log) + default: + placements.Get(&placementArgs, *endPoint, log) + } default: flag.Usage() os.Exit(1) diff --git a/src/cmd/tools/m3ctl/main/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/namespaces/cmd.go index 8ef99013ac..1a760a2f63 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/namespaces/cmd.go @@ -4,22 +4,3 @@ const ( defaultPath = "/api/v1/namespace" debugQS = "debug=true" ) - -type NamespaceArgs struct { - showAll *bool - delete *string -} - -//func xCommand(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { -// log.Debugf("NamespaceArgs:%+v:\n", flags) -// url := fmt.Sprintf("%s%s?%s", endpoint, defaultPath, debugQS) -// if *flags.showAll { -// http.DoGet(url, log, http.DoDump) -// } else if len(*flags.delete) > 0 { -// url = fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", *flags.delete) -// http.DoDelete(url, log, http.DoDump) -// } else { -// http.DoGet(url, log, showNames) -// } -// return -//} diff --git a/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go b/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go index ecab96dfc9..07cc207c62 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go +++ b/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go @@ -7,7 +7,7 @@ import ( type NamespaceFlags struct { Namespace *flag.FlagSet - Delete *flag.FlagSet + Delete *flag.FlagSet } func SetupFlags(flags *NamespaceArgs) NamespaceFlags { @@ -22,7 +22,7 @@ This is the subcommand for acting on namespaces. Description: -The subcommand "%s"" provides the ability to: +The namespaces subcommand "%s"" provides the ability to: * list all namespaces (default) * verbosely list all the available information about the namespaces (-all) @@ -56,3 +56,8 @@ Usage of %s: } return NamespaceFlags{Namespace: namespaceFlags, Delete: deleteFlags} } + +type NamespaceArgs struct { + showAll *bool + delete *string +} diff --git a/src/cmd/tools/m3ctl/main/namespaces/show.go b/src/cmd/tools/m3ctl/main/namespaces/show.go index 1504fa3896..c39008c0b0 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/show.go +++ b/src/cmd/tools/m3ctl/main/namespaces/show.go @@ -18,7 +18,6 @@ func Show(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { } } - func showNames(in io.Reader, log *zap.SugaredLogger) { registry := admin.NamespaceGetResponse{} unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} @@ -29,9 +28,3 @@ func showNames(in io.Reader, log *zap.SugaredLogger) { fmt.Println(k) } } - -//func ShowNames(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { -// url := fmt.Sprintf("%s%s?%s", endpoint, defaultPath, debugQS) -// http.DoGet(url, log, showNames) -//} - diff --git a/src/cmd/tools/m3ctl/main/namespaces/showNames.go b/src/cmd/tools/m3ctl/main/namespaces/showNames.go deleted file mode 100644 index db0babd577..0000000000 --- a/src/cmd/tools/m3ctl/main/namespaces/showNames.go +++ /dev/null @@ -1,26 +0,0 @@ -package namespaces - -//import ( -// "fmt" -// "github.com/gogo/protobuf/jsonpb" -// "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" -// "github.com/m3db/m3/src/query/generated/proto/admin" -// "go.uber.org/zap" -// "io" -//) - -//func showNames(in io.Reader, log *zap.SugaredLogger) { -// registry := admin.NamespaceGetResponse{} -// unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} -// if err := unmarshaller.Unmarshal(in, ®istry); err != nil { -// log.Fatal(err) -// } -// for k, _ := range registry.Registry.Namespaces { -// fmt.Println(k) -// } -//} -// -//func ShowNames(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { -// url := fmt.Sprintf("%s%s?%s", endpoint, defaultPath, debugQS) -// http.DoGet(url, log, showNames) -//} diff --git a/src/cmd/tools/m3ctl/main/placements/add.go b/src/cmd/tools/m3ctl/main/placements/add.go new file mode 100644 index 0000000000..fe186513e0 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/placements/add.go @@ -0,0 +1,17 @@ +package placements + +import ( + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" + "github.com/m3db/m3/src/query/generated/proto/admin" + "go.uber.org/zap" +) + +func Add(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { + log.Debugf("PlacementArgs:%+v:\n", flags) + data := yaml.Load(flags.newNodeFlag.Value[0], &admin.PlacementInitRequest{}, log) + url := fmt.Sprintf("%s%s", endpoint, defaultPath) + http.DoPost(url, data, log, http.DoDump) + return +} diff --git a/src/cmd/tools/m3ctl/main/placements/cmd.go b/src/cmd/tools/m3ctl/main/placements/cmd.go index cd0c654a71..83ebfc48e2 100644 --- a/src/cmd/tools/m3ctl/main/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd.go @@ -1,40 +1,5 @@ package placements -import ( - "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" - "github.com/m3db/m3/src/query/generated/proto/admin" - "go.uber.org/zap" -) - const ( defaultPath = "/api/v1/services/m3db/placement" ) - -func Command(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { - log.Debugf("PlacementArgs:%+v:\n", flags) - if len(*flags.deleteNode) > 0 { - url := fmt.Sprintf("%s%s/%s", endpoint, defaultPath, *flags.deleteNode) - http.DoDelete(url, log, http.DoDump) - } else if len(flags.newNodeFlag.Value) > 0 && len(flags.newNodeFlag.Value) > 0 { - data := yaml.Load(flags.newNodeFlag.Value[0], &admin.PlacementInitRequest{}, log) - url := fmt.Sprintf("%s%s", endpoint, defaultPath) - http.DoPost(url, data, log, http.DoDump) - } else if len(flags.initFlag.Value) > 0 && len(flags.initFlag.Value[0]) > 0 { - data := yaml.Load(flags.initFlag.Value[0], &admin.PlacementInitRequest{}, log) - url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/init") - http.DoPost(url, data, log, http.DoDump) - } else if len(flags.replaceFlag.Value) > 0 && len(flags.replaceFlag.Value[0]) > 0 { - data := yaml.Load(flags.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}, log) - url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/replace") - http.DoPost(url, data, log, http.DoDump) - } else if *flags.deletePlacement { - url := fmt.Sprintf("%s%s", endpoint, defaultPath) - http.DoDelete(url, log, http.DoDump) - } else { - url := fmt.Sprintf("%s%s", endpoint, defaultPath) - http.DoGet(url, log, http.DoDump) - } - return -} diff --git a/src/cmd/tools/m3ctl/main/placements/delete.go b/src/cmd/tools/m3ctl/main/placements/delete.go new file mode 100644 index 0000000000..97b7447bf7 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/placements/delete.go @@ -0,0 +1,18 @@ +package placements + +import ( + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + "go.uber.org/zap" +) + +func Delete(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { + if *flags.deletePlacement { + url := fmt.Sprintf("%s%s", endpoint, defaultPath) + http.DoDelete(url, log, http.DoDump) + return + } + url := fmt.Sprintf("%s%s/%s", endpoint, defaultPath, *flags.deleteNode) + http.DoDelete(url, log, http.DoDump) + return +} diff --git a/src/cmd/tools/m3ctl/main/placements/get.go b/src/cmd/tools/m3ctl/main/placements/get.go new file mode 100644 index 0000000000..0de2c68f20 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/placements/get.go @@ -0,0 +1,13 @@ +package placements + +import ( + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + "go.uber.org/zap" +) + +func Get(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { + url := fmt.Sprintf("%s%s", endpoint, defaultPath) + http.DoGet(url, log, http.DoDump) + return +} diff --git a/src/cmd/tools/m3ctl/main/placements/init.go b/src/cmd/tools/m3ctl/main/placements/init.go new file mode 100644 index 0000000000..0f0efef2e1 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/placements/init.go @@ -0,0 +1,17 @@ +package placements + +import ( + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" + "github.com/m3db/m3/src/query/generated/proto/admin" + "go.uber.org/zap" +) + +func Init(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { + log.Debugf("PlacementArgs:%+v:\n", flags) + data := yaml.Load(flags.initFlag.Value[0], &admin.PlacementInitRequest{}, log) + url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/init") + http.DoPost(url, data, log, http.DoDump) + return +} diff --git a/src/cmd/tools/m3ctl/main/placements/replace.go b/src/cmd/tools/m3ctl/main/placements/replace.go new file mode 100644 index 0000000000..8a2c00bcf9 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/placements/replace.go @@ -0,0 +1,16 @@ +package placements + +import ( + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" + "github.com/m3db/m3/src/query/generated/proto/admin" + "go.uber.org/zap" +) + +func Replace(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { + data := yaml.Load(flags.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}, log) + url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/replace") + http.DoPost(url, data, log, http.DoDump) + return +} diff --git a/src/cmd/tools/m3ctl/main/placements/setupFlags.go b/src/cmd/tools/m3ctl/main/placements/setupFlags.go index 3d6834875d..7abedaabfc 100644 --- a/src/cmd/tools/m3ctl/main/placements/setupFlags.go +++ b/src/cmd/tools/m3ctl/main/placements/setupFlags.go @@ -7,17 +7,6 @@ import ( "os" ) -const ( - placementCommandName = "pl" - - // flag names - DeleteAllName = "deleteAll" - DeleteNodeName = "deleteNode" - InitName = "init" - NewNodeName = "newNode" - ReplaceNodeName = "replaceNode" -) - type PlacementArgs struct { deletePlacement *bool deleteNode *string @@ -26,21 +15,35 @@ type PlacementArgs struct { replaceFlag configflag.FlagStringSlice } -func SetupFlags(flags *PlacementArgs) *flag.FlagSet { - placementFlags := flag.NewFlagSet(placementCommandName, flag.ExitOnError) - flags.deletePlacement = placementFlags.Bool(DeleteAllName, false, "delete all instances in the placement") - flags.deleteNode = placementFlags.String(DeleteNodeName, "", "delete the specified node in the placement") - placementFlags.Var(&flags.initFlag, InitName, "initialize a placement. Specify a yaml file.") - placementFlags.Var(&flags.newNodeFlag, NewNodeName, "add a new node to the placement. Specify the filename of the yaml.") - placementFlags.Var(&flags.replaceFlag, ReplaceNodeName, "add a new node to the placement. Specify the filename of the yaml.") +type PlacementFlags struct { + Placement *flag.FlagSet + Delete *flag.FlagSet + Add *flag.FlagSet + Init *flag.FlagSet + Replace *flag.FlagSet +} + +func SetupFlags(flags *PlacementArgs) PlacementFlags { + placementFlags := flag.NewFlagSet("pl", flag.ExitOnError) + deleteFlags := flag.NewFlagSet("delete", flag.ExitOnError) + addFlags := flag.NewFlagSet("add", flag.ExitOnError) + initFlags := flag.NewFlagSet("init", flag.ExitOnError) + replaceFlags := flag.NewFlagSet("replace", flag.ExitOnError) + + flags.deletePlacement = deleteFlags.Bool("all", false, "delete the entire placement") + flags.deleteNode = deleteFlags.String("node", "", "delete the specified node in the placement") + initFlags.Var(&flags.initFlag, "f", "initialize a placement. Specify a yaml file.") + addFlags.Var(&flags.newNodeFlag, "f", "add a new node to the placement. Specify the filename of the yaml.") + replaceFlags.Var(&flags.replaceFlag, "f", "add a new node to the placement. Specify the filename of the yaml.") placementFlags.Usage = func() { fmt.Fprintf(os.Stderr, ` "%s" is for acting on placements. Description: -The subcommand "%s" provides the ability to: +The placements subcommand "%s" provides the ability to: +* list the info for the placement * delete an entire placement from a node * remove a node from a placement * add a new node to as existing placement @@ -55,10 +58,16 @@ file, the pathname of which is the argument for the cli option. Specify only one action at a time. +It has the following subcommands: + %s + %s + %s + %s + Usage of %s: -`, placementFlags.Name(), placementFlags.Name(), placementFlags.Name()) +`, placementFlags.Name(), placementFlags.Name(), deleteFlags.Name(), addFlags.Name(), initFlags.Name(), replaceFlags.Name(), placementFlags.Name()) placementFlags.PrintDefaults() } - return placementFlags + return PlacementFlags{Placement: placementFlags, Delete: deleteFlags, Add: addFlags, Init: initFlags, Replace: replaceFlags} } diff --git a/src/cmd/tools/m3ctl/main/yaml/load.go b/src/cmd/tools/m3ctl/main/yaml/load.go index 3b62fd909c..91b7012e2c 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load.go +++ b/src/cmd/tools/m3ctl/main/yaml/load.go @@ -16,12 +16,13 @@ func Load(path string, target proto.Message, log *zap.SugaredLogger) io.Reader { if err != nil { log.Fatal(err) } - rv, err := _load(content, target) + rv, err := _load(content, target) if err != nil { log.Fatalf("cannot unmarshal data:%v:from yaml file:%s:", err, path) } return rv } + // more easily testable version func _load(content []byte, target proto.Message) (io.Reader, error) { if err := yaml.Unmarshal(content, target); err != nil { diff --git a/src/cmd/tools/m3ctl/main/yaml/load_test.go b/src/cmd/tools/m3ctl/main/yaml/load_test.go index 8fffc8f736..c4c71dc381 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load_test.go +++ b/src/cmd/tools/m3ctl/main/yaml/load_test.go @@ -1,10 +1,10 @@ package yaml import ( - "io/ioutil" - "testing" "github.com/gogo/protobuf/jsonpb" "github.com/m3db/m3/src/query/generated/proto/admin" + "io/ioutil" + "testing" ) func TestLoadBasic(t *testing.T) { From 9e7f3fb7748f8a0c02b365d40c9088a862cc6479 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Fri, 10 Jan 2020 19:55:07 -0800 Subject: [PATCH 19/65] factoring --- .../tools/m3ctl/main/database/setupFlags.go | 38 +++++ src/cmd/tools/m3ctl/main/main.go | 157 +----------------- src/cmd/tools/m3ctl/main/namespaces/cmd.go | 6 - .../tools/m3ctl/main/namespaces/setupFlags.go | 41 +++++ src/cmd/tools/m3ctl/main/placements/cmd.go | 5 - .../tools/m3ctl/main/placements/setupFlags.go | 98 +++++++++++ 6 files changed, 180 insertions(+), 165 deletions(-) delete mode 100644 src/cmd/tools/m3ctl/main/namespaces/cmd.go delete mode 100644 src/cmd/tools/m3ctl/main/placements/cmd.go diff --git a/src/cmd/tools/m3ctl/main/database/setupFlags.go b/src/cmd/tools/m3ctl/main/database/setupFlags.go index f940179cc7..2290bccf8e 100644 --- a/src/cmd/tools/m3ctl/main/database/setupFlags.go +++ b/src/cmd/tools/m3ctl/main/database/setupFlags.go @@ -4,6 +4,8 @@ import ( "flag" "fmt" "github.com/m3db/m3/src/x/config/configflag" + "go.uber.org/zap" + "os" ) type DatabaseFlagSets struct { @@ -44,3 +46,39 @@ Usage of %s: return DatabaseFlagSets{Database: databaseFlags, Create: createFlags} } +func ParseAndDo(arg string, flags *DatabaseFlagSets, ep string, log *zap.SugaredLogger) { + if err := flags.Database.Parse(flag.Args()[1:]); err != nil { + flags.Database.Usage() + os.Exit(1) + } + if flags.Database.NArg() == 0 { + flags.Database.Usage() + os.Exit(1) + } + switch flag.Arg(1) { + case flags.Create.Name(): + if err := flags.Create.Parse(flag.Args()[2:]); err != nil { + flags.Create.Usage() + os.Exit(1) + } + if flags.Create.NFlag() == 0 { + flags.Create.Usage() + os.Exit(1) + } + flags.Create.Visit(func(f *flag.Flag) { + vals := f.Value.(*configflag.FlagStringSlice) + for _, val := range vals.Value { + if len(val) == 0 { + fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + flags.Create.Usage() + os.Exit(1) + } + } + }) + // the below createDatabaseYAML.Value has at least one by this time per the arg parser + Create(arg, ep, log) + default: + flags.Database.Usage() + os.Exit(1) + } +} \ No newline at end of file diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 39ab3ec369..2811dc6a5e 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -86,162 +86,11 @@ Each subcommand has its own built-in help provided via "-h". switch flag.Arg(0) { case databaseFlagSets.Database.Name(): - if err := databaseFlagSets.Database.Parse(flag.Args()[1:]); err != nil { - databaseFlagSets.Database.Usage() - os.Exit(1) - } - if databaseFlagSets.Database.NArg() == 0 { - databaseFlagSets.Database.Usage() - os.Exit(1) - } - switch flag.Arg(1) { - case databaseFlagSets.Create.Name(): - if err := databaseFlagSets.Create.Parse(flag.Args()[2:]); err != nil { - databaseFlagSets.Create.Usage() - os.Exit(1) - } - if databaseFlagSets.Create.NFlag() == 0 { - databaseFlagSets.Create.Usage() - os.Exit(1) - } - databaseFlagSets.Create.Visit(func(f *flag.Flag) { - vals := f.Value.(*configflag.FlagStringSlice) - for _, val := range vals.Value { - if len(val) == 0 { - fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - databaseFlagSets.Create.Usage() - os.Exit(1) - } - } - }) - // the below createDatabaseYAML.Value has at least one by this time per the arg parser - database.Create(createDatabaseYAML.Value[len(createDatabaseYAML.Value)-1], *endPoint, log) - default: - databaseFlagSets.Database.Usage() - os.Exit(1) - } + database.ParseAndDo(createDatabaseYAML.Value[len(createDatabaseYAML.Value)-1], &databaseFlagSets, *endPoint, log) case namespaceFlagSets.Namespace.Name(): - if err := namespaceFlagSets.Namespace.Parse(flag.Args()[1:]); err != nil { - namespaceFlagSets.Namespace.Usage() - os.Exit(1) - } - // maybe do the default action which is listing the names - if namespaceFlagSets.Namespace.NArg() == 0 { - namespaces.Show(&namespaceArgs, *endPoint, log) - os.Exit(0) - } - switch flag.Arg(1) { - case namespaceFlagSets.Delete.Name(): - if err := namespaceFlagSets.Delete.Parse(flag.Args()[2:]); err != nil { - namespaceFlagSets.Delete.Usage() - os.Exit(1) - } - if namespaceFlagSets.Delete.NFlag() == 0 { - namespaceFlagSets.Delete.Usage() - os.Exit(1) - } - namespaceFlagSets.Delete.Visit(func(f *flag.Flag) { - if len(f.Value.String()) == 0 { - fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - namespaceFlagSets.Delete.Usage() - os.Exit(1) - } - }) - namespaces.Delete(&namespaceArgs, *endPoint, log) - default: - namespaceFlagSets.Namespace.Usage() - os.Exit(1) - } + namespaces.ParseAndDo(&namespaceArgs, &namespaceFlagSets, *endPoint, log) case placementFlagSets.Placement.Name(): - if err := placementFlagSets.Placement.Parse(flag.Args()[1:]); err != nil { - placementFlagSets.Placement.Usage() - os.Exit(1) - } - if placementFlagSets.Placement.NArg() == 0 { - placements.Get(&placementArgs, *endPoint, log) - os.Exit(0) - } - switch flag.Arg(1) { - case placementFlagSets.Add.Name(): - if err := placementFlagSets.Add.Parse(flag.Args()[2:]); err != nil { - placementFlagSets.Add.Usage() - os.Exit(1) - } - if placementFlagSets.Add.NFlag() == 0 { - placementFlagSets.Add.Usage() - os.Exit(1) - } - placementFlagSets.Add.Visit(func(f *flag.Flag) { - vals := f.Value.(*configflag.FlagStringSlice) - for _, val := range vals.Value { - if len(val) == 0 { - fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - placementFlagSets.Add.Usage() - os.Exit(1) - } - } - }) - placements.Add(&placementArgs, *endPoint, log) - case placementFlagSets.Delete.Name(): - if err := placementFlagSets.Delete.Parse(flag.Args()[2:]); err != nil { - placementFlagSets.Delete.Usage() - os.Exit(1) - } - if placementFlagSets.Delete.NFlag() == 0 { - placementFlagSets.Delete.Usage() - os.Exit(1) - } - placementFlagSets.Delete.Visit(func(f *flag.Flag) { - if len(f.Value.String()) == 0 { - fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - placementFlagSets.Delete.Usage() - os.Exit(1) - } - }) - placements.Delete(&placementArgs, *endPoint, log) - case placementFlagSets.Init.Name(): - if err := placementFlagSets.Init.Parse(flag.Args()[2:]); err != nil { - placementFlagSets.Init.Usage() - os.Exit(1) - } - if placementFlagSets.Init.NFlag() == 0 { - placementFlagSets.Init.Usage() - os.Exit(1) - } - placementFlagSets.Init.Visit(func(f *flag.Flag) { - vals := f.Value.(*configflag.FlagStringSlice) - for _, val := range vals.Value { - if len(val) == 0 { - fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - placementFlagSets.Init.Usage() - os.Exit(1) - } - } - }) - placements.Init(&placementArgs, *endPoint, log) - case placementFlagSets.Replace.Name(): - if err := placementFlagSets.Replace.Parse(flag.Args()[2:]); err != nil { - placementFlagSets.Replace.Usage() - os.Exit(1) - } - if placementFlagSets.Replace.NFlag() == 0 { - placementFlagSets.Replace.Usage() - os.Exit(1) - } - placementFlagSets.Replace.Visit(func(f *flag.Flag) { - vals := f.Value.(*configflag.FlagStringSlice) - for _, val := range vals.Value { - if len(val) == 0 { - fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - placementFlagSets.Replace.Usage() - os.Exit(1) - } - } - }) - placements.Replace(&placementArgs, *endPoint, log) - default: - placements.Get(&placementArgs, *endPoint, log) - } + placements.ParseAndDo(&placementArgs, &placementFlagSets, *endPoint, log) default: flag.Usage() os.Exit(1) diff --git a/src/cmd/tools/m3ctl/main/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/namespaces/cmd.go deleted file mode 100644 index 1a760a2f63..0000000000 --- a/src/cmd/tools/m3ctl/main/namespaces/cmd.go +++ /dev/null @@ -1,6 +0,0 @@ -package namespaces - -const ( - defaultPath = "/api/v1/namespace" - debugQS = "debug=true" -) diff --git a/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go b/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go index 07cc207c62..00ab1000b0 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go +++ b/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go @@ -3,6 +3,13 @@ package namespaces import ( "flag" "fmt" + "go.uber.org/zap" + "os" +) + +const ( + defaultPath = "/api/v1/namespace" + debugQS = "debug=true" ) type NamespaceFlags struct { @@ -61,3 +68,37 @@ type NamespaceArgs struct { showAll *bool delete *string } + +func ParseAndDo(args *NamespaceArgs, flags *NamespaceFlags, ep string, log *zap.SugaredLogger) { + if err := flags.Namespace.Parse(flag.Args()[1:]); err != nil { + flags.Namespace.Usage() + os.Exit(1) + } + // maybe do the default action which is listing the names + if flags.Namespace.NArg() == 0 { + Show(args, ep, log) + os.Exit(0) + } + switch flag.Arg(1) { + case flags.Delete.Name(): + if err := flags.Delete.Parse(flag.Args()[2:]); err != nil { + flags.Delete.Usage() + os.Exit(1) + } + if flags.Delete.NFlag() == 0 { + flags.Delete.Usage() + os.Exit(1) + } + flags.Delete.Visit(func(f *flag.Flag) { + if len(f.Value.String()) == 0 { + fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + flags.Delete.Usage() + os.Exit(1) + } + }) + Delete(args, ep, log) + default: + flags.Namespace.Usage() + os.Exit(1) + } +} diff --git a/src/cmd/tools/m3ctl/main/placements/cmd.go b/src/cmd/tools/m3ctl/main/placements/cmd.go deleted file mode 100644 index 83ebfc48e2..0000000000 --- a/src/cmd/tools/m3ctl/main/placements/cmd.go +++ /dev/null @@ -1,5 +0,0 @@ -package placements - -const ( - defaultPath = "/api/v1/services/m3db/placement" -) diff --git a/src/cmd/tools/m3ctl/main/placements/setupFlags.go b/src/cmd/tools/m3ctl/main/placements/setupFlags.go index 7abedaabfc..8ea8cad874 100644 --- a/src/cmd/tools/m3ctl/main/placements/setupFlags.go +++ b/src/cmd/tools/m3ctl/main/placements/setupFlags.go @@ -4,9 +4,14 @@ import ( "flag" "fmt" "github.com/m3db/m3/src/x/config/configflag" + "go.uber.org/zap" "os" ) +const ( + defaultPath = "/api/v1/services/m3db/placement" +) + type PlacementArgs struct { deletePlacement *bool deleteNode *string @@ -71,3 +76,96 @@ Usage of %s: } return PlacementFlags{Placement: placementFlags, Delete: deleteFlags, Add: addFlags, Init: initFlags, Replace: replaceFlags} } + +func ParseAndDo(args *PlacementArgs, flags *PlacementFlags, ep string, log *zap.SugaredLogger) { + if err := flags.Placement.Parse(flag.Args()[1:]); err != nil { + flags.Placement.Usage() + os.Exit(1) + } + if flags.Placement.NArg() == 0 { + Get(args, ep, log) + os.Exit(0) + } + switch flag.Arg(1) { + case flags.Add.Name(): + if err := flags.Add.Parse(flag.Args()[2:]); err != nil { + flags.Add.Usage() + os.Exit(1) + } + if flags.Add.NFlag() == 0 { + flags.Add.Usage() + os.Exit(1) + } + flags.Add.Visit(func(f *flag.Flag) { + vals := f.Value.(*configflag.FlagStringSlice) + for _, val := range vals.Value { + if len(val) == 0 { + fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + flags.Add.Usage() + os.Exit(1) + } + } + }) + Add(args, ep, log) + case flags.Delete.Name(): + if err := flags.Delete.Parse(flag.Args()[2:]); err != nil { + flags.Delete.Usage() + os.Exit(1) + } + if flags.Delete.NFlag() == 0 { + flags.Delete.Usage() + os.Exit(1) + } + flags.Delete.Visit(func(f *flag.Flag) { + if len(f.Value.String()) == 0 { + fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + flags.Delete.Usage() + os.Exit(1) + } + }) + Delete(args, ep, log) + case flags.Init.Name(): + if err := flags.Init.Parse(flag.Args()[2:]); err != nil { + flags.Init.Usage() + os.Exit(1) + } + if flags.Init.NFlag() == 0 { + flags.Init.Usage() + os.Exit(1) + } + flags.Init.Visit(func(f *flag.Flag) { + vals := f.Value.(*configflag.FlagStringSlice) + for _, val := range vals.Value { + if len(val) == 0 { + fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + flags.Init.Usage() + os.Exit(1) + } + } + }) + Init(args, ep, log) + case flags.Replace.Name(): + if err := flags.Replace.Parse(flag.Args()[2:]); err != nil { + flags.Replace.Usage() + os.Exit(1) + } + if flags.Replace.NFlag() == 0 { + flags.Replace.Usage() + os.Exit(1) + } + flags.Replace.Visit(func(f *flag.Flag) { + vals := f.Value.(*configflag.FlagStringSlice) + for _, val := range vals.Value { + if len(val) == 0 { + fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) + flags.Replace.Usage() + os.Exit(1) + } + } + }) + Replace(args, ep, log) + default: + Get(args, ep, log) + } + +} From f9981ff76bf4d77ca84ead21577cbaa553a283dc Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Fri, 10 Jan 2020 20:20:29 -0800 Subject: [PATCH 20/65] renaming and README --- src/cmd/tools/m3ctl/README.md | 19 ++++++++++++++----- .../main/database/{setupFlags.go => cmd.go} | 10 +++++++--- src/cmd/tools/m3ctl/main/database/create.go | 4 ---- src/cmd/tools/m3ctl/main/main.go | 2 +- .../main/namespaces/{setupFlags.go => cmd.go} | 11 +++++------ .../main/placements/{setupFlags.go => cmd.go} | 0 6 files changed, 27 insertions(+), 19 deletions(-) rename src/cmd/tools/m3ctl/main/database/{setupFlags.go => cmd.go} (87%) rename src/cmd/tools/m3ctl/main/namespaces/{setupFlags.go => cmd.go} (99%) rename src/cmd/tools/m3ctl/main/placements/{setupFlags.go => cmd.go} (100%) diff --git a/src/cmd/tools/m3ctl/README.md b/src/cmd/tools/m3ctl/README.md index 56923c941d..b59b6a7ed7 100644 --- a/src/cmd/tools/m3ctl/README.md +++ b/src/cmd/tools/m3ctl/README.md @@ -1,7 +1,9 @@ M3DB Tool ======== -This is a CLI tool to do some things that may be desirable for cluster introspection, or for operational purposes. +This is a CLI tool to do some things that may be desirable for +cluster introspection, or for operational purposes. + Where configuration data is required its provided via YAML. @@ -15,7 +17,10 @@ You can: * add nodes * remove nodes -NOTE: This tool can delete namespaces and placements. It can be quite hazardous if used without adequate understanding of your m3db cluster's topology, or without a decent understanding of how m3db works. +NOTE: This tool can delete namespaces and placements. It can be +quite hazardous if used without adequate understanding of your m3db +cluster's topology, or without a decent understanding of how m3db +works. Examples ------- @@ -23,19 +28,23 @@ Examples # show help m3ctl -h # create a database - m3ctl db -create ./database/examples/devel.yaml + m3ctl db create -f ./database/examples/devel.yaml # list namespaces m3ctl ns # delete a namespace - m3ctl ns -delete default + m3ctl ns delete -name default # list placements m3ctl pl # point to some remote and list namespaces m3ctl -endpoint http://localhost:7201 ns + # check the namespaces in a kubernetes cluster + # first setup a tunnel via kubectl port-forward ... 7201 + m3ctl -endpoint http://localhost:7201 ns # list the ids of the placements m3ctl -endpoint http://localhost:7201 pl | jq .placement.instances[].id -Some example yaml files are provided in the examples directories. Here's one for database creation: +Some example yaml files are provided in the examples directories. +Here's one for database creation: --- type: cluster diff --git a/src/cmd/tools/m3ctl/main/database/setupFlags.go b/src/cmd/tools/m3ctl/main/database/cmd.go similarity index 87% rename from src/cmd/tools/m3ctl/main/database/setupFlags.go rename to src/cmd/tools/m3ctl/main/database/cmd.go index 2290bccf8e..37c4119817 100644 --- a/src/cmd/tools/m3ctl/main/database/setupFlags.go +++ b/src/cmd/tools/m3ctl/main/database/cmd.go @@ -8,6 +8,10 @@ import ( "os" ) +const ( + defaultPath = "/api/v1/database" +) + type DatabaseFlagSets struct { Database *flag.FlagSet Create *flag.FlagSet @@ -46,7 +50,7 @@ Usage of %s: return DatabaseFlagSets{Database: databaseFlags, Create: createFlags} } -func ParseAndDo(arg string, flags *DatabaseFlagSets, ep string, log *zap.SugaredLogger) { +func ParseAndDo(arg *configflag.FlagStringSlice, flags *DatabaseFlagSets, ep string, log *zap.SugaredLogger) { if err := flags.Database.Parse(flag.Args()[1:]); err != nil { flags.Database.Usage() os.Exit(1) @@ -75,8 +79,8 @@ func ParseAndDo(arg string, flags *DatabaseFlagSets, ep string, log *zap.Sugared } } }) - // the below createDatabaseYAML.Value has at least one by this time per the arg parser - Create(arg, ep, log) + // the below arg.Value has at least one value by this time per the arg parser + Create(arg.Value[len(arg.Value)-1], ep, log) default: flags.Database.Usage() os.Exit(1) diff --git a/src/cmd/tools/m3ctl/main/database/create.go b/src/cmd/tools/m3ctl/main/database/create.go index d6b91688b3..96872af0c4 100644 --- a/src/cmd/tools/m3ctl/main/database/create.go +++ b/src/cmd/tools/m3ctl/main/database/create.go @@ -8,10 +8,6 @@ import ( "go.uber.org/zap" ) -const ( - defaultPath = "/api/v1/database" -) - func Create(createYAML string, endpoint string, log *zap.SugaredLogger) { log.Debugf("createYAML:%s:\n", createYAML) data := yaml.Load(createYAML, &admin.DatabaseCreateRequest{}, log) diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 2811dc6a5e..ed77cabdb1 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -86,7 +86,7 @@ Each subcommand has its own built-in help provided via "-h". switch flag.Arg(0) { case databaseFlagSets.Database.Name(): - database.ParseAndDo(createDatabaseYAML.Value[len(createDatabaseYAML.Value)-1], &databaseFlagSets, *endPoint, log) + database.ParseAndDo(&createDatabaseYAML, &databaseFlagSets, *endPoint, log) case namespaceFlagSets.Namespace.Name(): namespaces.ParseAndDo(&namespaceArgs, &namespaceFlagSets, *endPoint, log) case placementFlagSets.Placement.Name(): diff --git a/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go b/src/cmd/tools/m3ctl/main/namespaces/cmd.go similarity index 99% rename from src/cmd/tools/m3ctl/main/namespaces/setupFlags.go rename to src/cmd/tools/m3ctl/main/namespaces/cmd.go index 00ab1000b0..85a091d01b 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/setupFlags.go +++ b/src/cmd/tools/m3ctl/main/namespaces/cmd.go @@ -12,11 +12,15 @@ const ( debugQS = "debug=true" ) +type NamespaceArgs struct { + showAll *bool + delete *string +} + type NamespaceFlags struct { Namespace *flag.FlagSet Delete *flag.FlagSet } - func SetupFlags(flags *NamespaceArgs) NamespaceFlags { namespaceFlags := flag.NewFlagSet("ns", flag.ExitOnError) deleteFlags := flag.NewFlagSet("delete", flag.ExitOnError) @@ -64,11 +68,6 @@ Usage of %s: return NamespaceFlags{Namespace: namespaceFlags, Delete: deleteFlags} } -type NamespaceArgs struct { - showAll *bool - delete *string -} - func ParseAndDo(args *NamespaceArgs, flags *NamespaceFlags, ep string, log *zap.SugaredLogger) { if err := flags.Namespace.Parse(flag.Args()[1:]); err != nil { flags.Namespace.Usage() diff --git a/src/cmd/tools/m3ctl/main/placements/setupFlags.go b/src/cmd/tools/m3ctl/main/placements/cmd.go similarity index 100% rename from src/cmd/tools/m3ctl/main/placements/setupFlags.go rename to src/cmd/tools/m3ctl/main/placements/cmd.go From 385ddf077f43a6c0feebfb1a287ec724eadd0c9a Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 12 Jan 2020 11:24:07 -0800 Subject: [PATCH 21/65] working test for arg processing --- src/cmd/tools/m3ctl/main/database/cmd.go | 60 +++++++++++-------- src/cmd/tools/m3ctl/main/database/cmd_test.go | 23 +++++++ src/cmd/tools/m3ctl/main/database/create.go | 10 ++-- src/cmd/tools/m3ctl/main/http/checker.go | 6 +- src/cmd/tools/m3ctl/main/http/http.go | 34 +++++------ src/cmd/tools/m3ctl/main/main.go | 14 +---- src/cmd/tools/m3ctl/main/namespaces/cmd.go | 8 +-- src/cmd/tools/m3ctl/main/namespaces/delete.go | 5 +- src/cmd/tools/m3ctl/main/namespaces/show.go | 10 ++-- src/cmd/tools/m3ctl/main/placements/add.go | 10 ++-- src/cmd/tools/m3ctl/main/placements/cmd.go | 52 +++------------- src/cmd/tools/m3ctl/main/placements/delete.go | 7 +-- src/cmd/tools/m3ctl/main/placements/get.go | 5 +- src/cmd/tools/m3ctl/main/placements/init.go | 10 ++-- .../tools/m3ctl/main/placements/replace.go | 7 +-- src/cmd/tools/m3ctl/main/yaml/load.go | 6 +- 16 files changed, 126 insertions(+), 141 deletions(-) create mode 100644 src/cmd/tools/m3ctl/main/database/cmd_test.go diff --git a/src/cmd/tools/m3ctl/main/database/cmd.go b/src/cmd/tools/m3ctl/main/database/cmd.go index 37c4119817..611ec018cc 100644 --- a/src/cmd/tools/m3ctl/main/database/cmd.go +++ b/src/cmd/tools/m3ctl/main/database/cmd.go @@ -4,7 +4,6 @@ import ( "flag" "fmt" "github.com/m3db/m3/src/x/config/configflag" - "go.uber.org/zap" "os" ) @@ -50,39 +49,52 @@ Usage of %s: return DatabaseFlagSets{Database: databaseFlags, Create: createFlags} } -func ParseAndDo(arg *configflag.FlagStringSlice, flags *DatabaseFlagSets, ep string, log *zap.SugaredLogger) { - if err := flags.Database.Parse(flag.Args()[1:]); err != nil { - flags.Database.Usage() + +type flagsError struct { + Message string +} + +func (e *flagsError) Error() string { + if e == nil { + return "" + } + return e.Message +} +func ParseAndDo(arg *configflag.FlagStringSlice, flags *DatabaseFlagSets, ep string) { + if err := _parseAndDo(flag.Args(), arg, flags, ep, Create); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } +} +func _parseAndDo(args []string, finalArgs *configflag.FlagStringSlice, flags *DatabaseFlagSets, ep string, doer func(string, string)) error { + if len(args) == 0 { + // if it gets here i want to see how it got here + panic("parser called with no args") + } + if err := flags.Database.Parse(args[1:]); err != nil { + flags.Database.Usage() + return err + } if flags.Database.NArg() == 0 { flags.Database.Usage() - os.Exit(1) + return &flagsError{} } - switch flag.Arg(1) { + switch flags.Database.Arg(0) { case flags.Create.Name(): - if err := flags.Create.Parse(flag.Args()[2:]); err != nil { + // pop and parse + createArgs := flags.Database.Args()[1:] + if err := flags.Create.Parse(createArgs); err != nil { flags.Create.Usage() - os.Exit(1) + return err } if flags.Create.NFlag() == 0 { flags.Create.Usage() - os.Exit(1) + return &flagsError{} } - flags.Create.Visit(func(f *flag.Flag) { - vals := f.Value.(*configflag.FlagStringSlice) - for _, val := range vals.Value { - if len(val) == 0 { - fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - flags.Create.Usage() - os.Exit(1) - } - } - }) - // the below arg.Value has at least one value by this time per the arg parser - Create(arg.Value[len(arg.Value)-1], ep, log) + // the below finalArgs.Value has at least one value by this time per the finalArgs parser + doer(finalArgs.Value[len(finalArgs.Value)-1], ep) + return nil default: - flags.Database.Usage() - os.Exit(1) + return &flagsError{} } -} \ No newline at end of file +} diff --git a/src/cmd/tools/m3ctl/main/database/cmd_test.go b/src/cmd/tools/m3ctl/main/database/cmd_test.go new file mode 100644 index 0000000000..7226fdac98 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/database/cmd_test.go @@ -0,0 +1,23 @@ +package database + +import ( + "github.com/m3db/m3/src/x/config/configflag" + "testing" +) + +func TestBasic(t *testing.T) { + + createDatabaseYAML := configflag.FlagStringSlice{} + databaseFlagSets := SetupFlags(&createDatabaseYAML) + + if e := _parseAndDo([]string{""}, &createDatabaseYAML, &databaseFlagSets, "", func(string, string) { return }); e == nil { + t.Error("It should return error on no args") + } + + createDatabaseYAML = configflag.FlagStringSlice{} + databaseFlagSets = SetupFlags(&createDatabaseYAML) + + if e := _parseAndDo([]string{"db", "create", "-f", "somefile"}, &createDatabaseYAML, &databaseFlagSets, "", func(string, string) { return }); e != nil { + t.Error("It should NOT return error on sane args") + } +} diff --git a/src/cmd/tools/m3ctl/main/database/create.go b/src/cmd/tools/m3ctl/main/database/create.go index 96872af0c4..4ec1b9b059 100644 --- a/src/cmd/tools/m3ctl/main/database/create.go +++ b/src/cmd/tools/m3ctl/main/database/create.go @@ -5,13 +5,13 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" "github.com/m3db/m3/src/query/generated/proto/admin" - "go.uber.org/zap" + "log" ) -func Create(createYAML string, endpoint string, log *zap.SugaredLogger) { - log.Debugf("createYAML:%s:\n", createYAML) - data := yaml.Load(createYAML, &admin.DatabaseCreateRequest{}, log) +func Create(createYAML string, endpoint string) { + log.Printf("createYAML:%s:\n", createYAML) + data := yaml.Load(createYAML, &admin.DatabaseCreateRequest{}) url := fmt.Sprintf("%s%s/create", endpoint, defaultPath) - http.DoPost(url, data, log, http.DoDump) + http.DoPost(url, data, http.DoDump) return } diff --git a/src/cmd/tools/m3ctl/main/http/checker.go b/src/cmd/tools/m3ctl/main/http/checker.go index 3e50b47268..12a41147fd 100644 --- a/src/cmd/tools/m3ctl/main/http/checker.go +++ b/src/cmd/tools/m3ctl/main/http/checker.go @@ -2,13 +2,13 @@ package http import ( "fmt" - "go.uber.org/zap" "io/ioutil" + "log" "net/http" ) -func checkForAndHandleError(url string, resp *http.Response, log *zap.SugaredLogger) { - log.Debugf("resp.StatusCode:%d:\n", resp.StatusCode) +func checkForAndHandleError(url string, resp *http.Response) { + log.Printf("resp.StatusCode:%d:\n", resp.StatusCode) if resp.StatusCode > 299 { dat, _ := ioutil.ReadAll(resp.Body) if dat != nil { diff --git a/src/cmd/tools/m3ctl/main/http/http.go b/src/cmd/tools/m3ctl/main/http/http.go index 41bf936bb5..debdb90890 100644 --- a/src/cmd/tools/m3ctl/main/http/http.go +++ b/src/cmd/tools/m3ctl/main/http/http.go @@ -2,34 +2,34 @@ package http import ( "fmt" - "go.uber.org/zap" "io" "io/ioutil" + "log" "net/http" "time" ) const timeout = time.Duration(5 * time.Second) -func DoGet(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { - logger.Debugf("DoGet:url:%s:\n", url) +func DoGet(url string, getter func(reader io.Reader)) { + log.Printf("DoGet:url:%s:\n", url) client := http.Client{ Timeout: timeout, } resp, err := client.Get(url) if err != nil { - logger.Fatal(err) + log.Fatal(err) } defer func() { ioutil.ReadAll(resp.Body) resp.Body.Close() }() - checkForAndHandleError(url, resp, logger) - getter(resp.Body, logger) + checkForAndHandleError(url, resp) + getter(resp.Body) } -func DoPost(url string, data io.Reader, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { - logger.Debugf("DoPost:url:%s:\n", url) +func DoPost(url string, data io.Reader, getter func(reader io.Reader)) { + log.Printf("DoPost:url:%s:\n", url) client := &http.Client{ Timeout: timeout, } @@ -37,19 +37,19 @@ func DoPost(url string, data io.Reader, logger *zap.SugaredLogger, getter func(r req.Header.Add("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { - logger.Fatal(err) + log.Fatal(err) } defer func() { ioutil.ReadAll(resp.Body) resp.Body.Close() }() - checkForAndHandleError(url, resp, logger) - getter(resp.Body, logger) + checkForAndHandleError(url, resp) + getter(resp.Body) } -func DoDelete(url string, logger *zap.SugaredLogger, getter func(reader io.Reader, logger *zap.SugaredLogger)) { - logger.Debugf("DoDelete:url:%s:\n", url) +func DoDelete(url string, getter func(reader io.Reader)) { + log.Printf("DoDelete:url:%s:\n", url) client := &http.Client{ Timeout: timeout, } @@ -57,17 +57,17 @@ func DoDelete(url string, logger *zap.SugaredLogger, getter func(reader io.Reade req.Header.Add("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { - logger.Fatal(err) + log.Fatal(err) } defer func() { ioutil.ReadAll(resp.Body) resp.Body.Close() }() - checkForAndHandleError(url, resp, logger) - getter(resp.Body, logger) + checkForAndHandleError(url, resp) + getter(resp.Body) } -func DoDump(in io.Reader, log *zap.SugaredLogger) { +func DoDump(in io.Reader) { dat, err := ioutil.ReadAll(in) if err != nil { log.Fatal(err) diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index ed77cabdb1..a9d0876836 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -27,7 +27,6 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/namespaces" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" "github.com/m3db/m3/src/x/config/configflag" - "go.uber.org/zap" "os" ) @@ -77,20 +76,13 @@ Each subcommand has its own built-in help provided via "-h". os.Exit(1) } - rawLogger, err := zap.NewDevelopment() - if err != nil { - fmt.Fprintf(os.Stderr, "unable to create logger: %+v", err) - os.Exit(1) - } - log := rawLogger.Sugar() - switch flag.Arg(0) { case databaseFlagSets.Database.Name(): - database.ParseAndDo(&createDatabaseYAML, &databaseFlagSets, *endPoint, log) + database.ParseAndDo(&createDatabaseYAML, &databaseFlagSets, *endPoint) case namespaceFlagSets.Namespace.Name(): - namespaces.ParseAndDo(&namespaceArgs, &namespaceFlagSets, *endPoint, log) + namespaces.ParseAndDo(&namespaceArgs, &namespaceFlagSets, *endPoint) case placementFlagSets.Placement.Name(): - placements.ParseAndDo(&placementArgs, &placementFlagSets, *endPoint, log) + placements.ParseAndDo(&placementArgs, &placementFlagSets, *endPoint) default: flag.Usage() os.Exit(1) diff --git a/src/cmd/tools/m3ctl/main/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/namespaces/cmd.go index 85a091d01b..55b9cc3bbe 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/namespaces/cmd.go @@ -3,7 +3,6 @@ package namespaces import ( "flag" "fmt" - "go.uber.org/zap" "os" ) @@ -21,6 +20,7 @@ type NamespaceFlags struct { Namespace *flag.FlagSet Delete *flag.FlagSet } + func SetupFlags(flags *NamespaceArgs) NamespaceFlags { namespaceFlags := flag.NewFlagSet("ns", flag.ExitOnError) deleteFlags := flag.NewFlagSet("delete", flag.ExitOnError) @@ -68,14 +68,14 @@ Usage of %s: return NamespaceFlags{Namespace: namespaceFlags, Delete: deleteFlags} } -func ParseAndDo(args *NamespaceArgs, flags *NamespaceFlags, ep string, log *zap.SugaredLogger) { +func ParseAndDo(args *NamespaceArgs, flags *NamespaceFlags, ep string) { if err := flags.Namespace.Parse(flag.Args()[1:]); err != nil { flags.Namespace.Usage() os.Exit(1) } // maybe do the default action which is listing the names if flags.Namespace.NArg() == 0 { - Show(args, ep, log) + Show(args, ep) os.Exit(0) } switch flag.Arg(1) { @@ -95,7 +95,7 @@ func ParseAndDo(args *NamespaceArgs, flags *NamespaceFlags, ep string, log *zap. os.Exit(1) } }) - Delete(args, ep, log) + Delete(args, ep) default: flags.Namespace.Usage() os.Exit(1) diff --git a/src/cmd/tools/m3ctl/main/namespaces/delete.go b/src/cmd/tools/m3ctl/main/namespaces/delete.go index d34f676f9c..dbbbdd5630 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/delete.go +++ b/src/cmd/tools/m3ctl/main/namespaces/delete.go @@ -3,10 +3,9 @@ package namespaces import ( "fmt" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" - "go.uber.org/zap" ) -func Delete(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { +func Delete(flags *NamespaceArgs, endpoint string) { url := fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", *flags.delete) - http.DoDelete(url, log, http.DoDump) + http.DoDelete(url, http.DoDump) } diff --git a/src/cmd/tools/m3ctl/main/namespaces/show.go b/src/cmd/tools/m3ctl/main/namespaces/show.go index c39008c0b0..3f34a593b7 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/show.go +++ b/src/cmd/tools/m3ctl/main/namespaces/show.go @@ -5,20 +5,20 @@ import ( "github.com/gogo/protobuf/jsonpb" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" "github.com/m3db/m3/src/query/generated/proto/admin" - "go.uber.org/zap" "io" + "log" ) -func Show(flags *NamespaceArgs, endpoint string, log *zap.SugaredLogger) { +func Show(flags *NamespaceArgs, endpoint string) { url := fmt.Sprintf("%s%s?%s", endpoint, defaultPath, debugQS) if *flags.showAll { - http.DoGet(url, log, http.DoDump) + http.DoGet(url, http.DoDump) } else { - http.DoGet(url, log, showNames) + http.DoGet(url, showNames) } } -func showNames(in io.Reader, log *zap.SugaredLogger) { +func showNames(in io.Reader) { registry := admin.NamespaceGetResponse{} unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} if err := unmarshaller.Unmarshal(in, ®istry); err != nil { diff --git a/src/cmd/tools/m3ctl/main/placements/add.go b/src/cmd/tools/m3ctl/main/placements/add.go index fe186513e0..be3f9bb1ad 100644 --- a/src/cmd/tools/m3ctl/main/placements/add.go +++ b/src/cmd/tools/m3ctl/main/placements/add.go @@ -5,13 +5,13 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" "github.com/m3db/m3/src/query/generated/proto/admin" - "go.uber.org/zap" + "log" ) -func Add(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { - log.Debugf("PlacementArgs:%+v:\n", flags) - data := yaml.Load(flags.newNodeFlag.Value[0], &admin.PlacementInitRequest{}, log) +func Add(flags *PlacementArgs, endpoint string) { + log.Printf("PlacementArgs:%+v:\n", flags) + data := yaml.Load(flags.newNodeFlag.Value[0], &admin.PlacementInitRequest{}) url := fmt.Sprintf("%s%s", endpoint, defaultPath) - http.DoPost(url, data, log, http.DoDump) + http.DoPost(url, data, http.DoDump) return } diff --git a/src/cmd/tools/m3ctl/main/placements/cmd.go b/src/cmd/tools/m3ctl/main/placements/cmd.go index 8ea8cad874..a54d49ea20 100644 --- a/src/cmd/tools/m3ctl/main/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd.go @@ -4,7 +4,6 @@ import ( "flag" "fmt" "github.com/m3db/m3/src/x/config/configflag" - "go.uber.org/zap" "os" ) @@ -77,13 +76,13 @@ Usage of %s: return PlacementFlags{Placement: placementFlags, Delete: deleteFlags, Add: addFlags, Init: initFlags, Replace: replaceFlags} } -func ParseAndDo(args *PlacementArgs, flags *PlacementFlags, ep string, log *zap.SugaredLogger) { +func ParseAndDo(args *PlacementArgs, flags *PlacementFlags, ep string) { if err := flags.Placement.Parse(flag.Args()[1:]); err != nil { flags.Placement.Usage() os.Exit(1) } if flags.Placement.NArg() == 0 { - Get(args, ep, log) + Get(args, ep) os.Exit(0) } switch flag.Arg(1) { @@ -96,17 +95,7 @@ func ParseAndDo(args *PlacementArgs, flags *PlacementFlags, ep string, log *zap. flags.Add.Usage() os.Exit(1) } - flags.Add.Visit(func(f *flag.Flag) { - vals := f.Value.(*configflag.FlagStringSlice) - for _, val := range vals.Value { - if len(val) == 0 { - fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - flags.Add.Usage() - os.Exit(1) - } - } - }) - Add(args, ep, log) + Add(args, ep) case flags.Delete.Name(): if err := flags.Delete.Parse(flag.Args()[2:]); err != nil { flags.Delete.Usage() @@ -116,14 +105,7 @@ func ParseAndDo(args *PlacementArgs, flags *PlacementFlags, ep string, log *zap. flags.Delete.Usage() os.Exit(1) } - flags.Delete.Visit(func(f *flag.Flag) { - if len(f.Value.String()) == 0 { - fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - flags.Delete.Usage() - os.Exit(1) - } - }) - Delete(args, ep, log) + Delete(args, ep) case flags.Init.Name(): if err := flags.Init.Parse(flag.Args()[2:]); err != nil { flags.Init.Usage() @@ -133,17 +115,7 @@ func ParseAndDo(args *PlacementArgs, flags *PlacementFlags, ep string, log *zap. flags.Init.Usage() os.Exit(1) } - flags.Init.Visit(func(f *flag.Flag) { - vals := f.Value.(*configflag.FlagStringSlice) - for _, val := range vals.Value { - if len(val) == 0 { - fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - flags.Init.Usage() - os.Exit(1) - } - } - }) - Init(args, ep, log) + Init(args, ep) case flags.Replace.Name(): if err := flags.Replace.Parse(flag.Args()[2:]); err != nil { flags.Replace.Usage() @@ -153,19 +125,9 @@ func ParseAndDo(args *PlacementArgs, flags *PlacementFlags, ep string, log *zap. flags.Replace.Usage() os.Exit(1) } - flags.Replace.Visit(func(f *flag.Flag) { - vals := f.Value.(*configflag.FlagStringSlice) - for _, val := range vals.Value { - if len(val) == 0 { - fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - flags.Replace.Usage() - os.Exit(1) - } - } - }) - Replace(args, ep, log) + Replace(args, ep) default: - Get(args, ep, log) + Get(args, ep) } } diff --git a/src/cmd/tools/m3ctl/main/placements/delete.go b/src/cmd/tools/m3ctl/main/placements/delete.go index 97b7447bf7..63b16434f6 100644 --- a/src/cmd/tools/m3ctl/main/placements/delete.go +++ b/src/cmd/tools/m3ctl/main/placements/delete.go @@ -3,16 +3,15 @@ package placements import ( "fmt" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" - "go.uber.org/zap" ) -func Delete(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { +func Delete(flags *PlacementArgs, endpoint string) { if *flags.deletePlacement { url := fmt.Sprintf("%s%s", endpoint, defaultPath) - http.DoDelete(url, log, http.DoDump) + http.DoDelete(url, http.DoDump) return } url := fmt.Sprintf("%s%s/%s", endpoint, defaultPath, *flags.deleteNode) - http.DoDelete(url, log, http.DoDump) + http.DoDelete(url, http.DoDump) return } diff --git a/src/cmd/tools/m3ctl/main/placements/get.go b/src/cmd/tools/m3ctl/main/placements/get.go index 0de2c68f20..58474fc053 100644 --- a/src/cmd/tools/m3ctl/main/placements/get.go +++ b/src/cmd/tools/m3ctl/main/placements/get.go @@ -3,11 +3,10 @@ package placements import ( "fmt" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" - "go.uber.org/zap" ) -func Get(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { +func Get(flags *PlacementArgs, endpoint string) { url := fmt.Sprintf("%s%s", endpoint, defaultPath) - http.DoGet(url, log, http.DoDump) + http.DoGet(url, http.DoDump) return } diff --git a/src/cmd/tools/m3ctl/main/placements/init.go b/src/cmd/tools/m3ctl/main/placements/init.go index 0f0efef2e1..f1da33211c 100644 --- a/src/cmd/tools/m3ctl/main/placements/init.go +++ b/src/cmd/tools/m3ctl/main/placements/init.go @@ -5,13 +5,13 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" "github.com/m3db/m3/src/query/generated/proto/admin" - "go.uber.org/zap" + "log" ) -func Init(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { - log.Debugf("PlacementArgs:%+v:\n", flags) - data := yaml.Load(flags.initFlag.Value[0], &admin.PlacementInitRequest{}, log) +func Init(flags *PlacementArgs, endpoint string) { + log.Printf("PlacementArgs:%+v:\n", flags) + data := yaml.Load(flags.initFlag.Value[0], &admin.PlacementInitRequest{}) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/init") - http.DoPost(url, data, log, http.DoDump) + http.DoPost(url, data, http.DoDump) return } diff --git a/src/cmd/tools/m3ctl/main/placements/replace.go b/src/cmd/tools/m3ctl/main/placements/replace.go index 8a2c00bcf9..d64fa37a70 100644 --- a/src/cmd/tools/m3ctl/main/placements/replace.go +++ b/src/cmd/tools/m3ctl/main/placements/replace.go @@ -5,12 +5,11 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" "github.com/m3db/m3/src/query/generated/proto/admin" - "go.uber.org/zap" ) -func Replace(flags *PlacementArgs, endpoint string, log *zap.SugaredLogger) { - data := yaml.Load(flags.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}, log) +func Replace(flags *PlacementArgs, endpoint string) { + data := yaml.Load(flags.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/replace") - http.DoPost(url, data, log, http.DoDump) + http.DoPost(url, data, http.DoDump) return } diff --git a/src/cmd/tools/m3ctl/main/yaml/load.go b/src/cmd/tools/m3ctl/main/yaml/load.go index 91b7012e2c..ee367370fa 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load.go +++ b/src/cmd/tools/m3ctl/main/yaml/load.go @@ -5,13 +5,13 @@ import ( "github.com/ghodss/yaml" "github.com/gogo/protobuf/jsonpb" "github.com/gogo/protobuf/proto" - "go.uber.org/zap" "io" "io/ioutil" + "log" ) -func Load(path string, target proto.Message, log *zap.SugaredLogger) io.Reader { - log.Debugf("path:%s:\n", path) +func Load(path string, target proto.Message) io.Reader { + log.Printf("path:%s:\n", path) content, err := ioutil.ReadFile(path) if err != nil { log.Fatal(err) From 024e500b0f445d6fa79221c6b41a43f09ddcff4e Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 12 Jan 2020 14:06:38 -0800 Subject: [PATCH 22/65] added test for namespaces command line parsing --- src/cmd/tools/m3ctl/main/database/cmd.go | 35 ++++++------- src/cmd/tools/m3ctl/main/database/cmd_test.go | 4 +- src/cmd/tools/m3ctl/main/errors/types.go | 12 +++++ src/cmd/tools/m3ctl/main/namespaces/cmd.go | 52 ++++++++++++------- .../tools/m3ctl/main/namespaces/cmd_test.go | 32 ++++++++++++ 5 files changed, 93 insertions(+), 42 deletions(-) create mode 100644 src/cmd/tools/m3ctl/main/errors/types.go create mode 100644 src/cmd/tools/m3ctl/main/namespaces/cmd_test.go diff --git a/src/cmd/tools/m3ctl/main/database/cmd.go b/src/cmd/tools/m3ctl/main/database/cmd.go index 611ec018cc..85c36c44a2 100644 --- a/src/cmd/tools/m3ctl/main/database/cmd.go +++ b/src/cmd/tools/m3ctl/main/database/cmd.go @@ -3,6 +3,7 @@ package database import ( "flag" "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" "github.com/m3db/m3/src/x/config/configflag" "os" ) @@ -50,34 +51,27 @@ Usage of %s: return DatabaseFlagSets{Database: databaseFlags, Create: createFlags} } -type flagsError struct { - Message string -} - -func (e *flagsError) Error() string { - if e == nil { - return "" - } - return e.Message -} func ParseAndDo(arg *configflag.FlagStringSlice, flags *DatabaseFlagSets, ep string) { - if err := _parseAndDo(flag.Args(), arg, flags, ep, Create); err != nil { + args := flag.Args() + // right here args should be like "db create -f somefile" + if len(args) < 2 { + flags.Database.Usage() + os.Exit(1) + } + // pop and parse + if err := parseAndDoCreate(args[1:], arg, flags, ep, Create); err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } } -func _parseAndDo(args []string, finalArgs *configflag.FlagStringSlice, flags *DatabaseFlagSets, ep string, doer func(string, string)) error { - if len(args) == 0 { - // if it gets here i want to see how it got here - panic("parser called with no args") - } - if err := flags.Database.Parse(args[1:]); err != nil { +func parseAndDoCreate(args []string, finalArgs *configflag.FlagStringSlice, flags *DatabaseFlagSets, ep string, doer func(string, string)) error { + if err := flags.Database.Parse(args); err != nil { flags.Database.Usage() return err } if flags.Database.NArg() == 0 { flags.Database.Usage() - return &flagsError{} + return &errors.FlagsError{} } switch flags.Database.Arg(0) { case flags.Create.Name(): @@ -89,12 +83,13 @@ func _parseAndDo(args []string, finalArgs *configflag.FlagStringSlice, flags *Da } if flags.Create.NFlag() == 0 { flags.Create.Usage() - return &flagsError{} + return &errors.FlagsError{} } // the below finalArgs.Value has at least one value by this time per the finalArgs parser doer(finalArgs.Value[len(finalArgs.Value)-1], ep) return nil default: - return &flagsError{} + flags.Database.Usage() + return &errors.FlagsError{} } } diff --git a/src/cmd/tools/m3ctl/main/database/cmd_test.go b/src/cmd/tools/m3ctl/main/database/cmd_test.go index 7226fdac98..86e59f6a66 100644 --- a/src/cmd/tools/m3ctl/main/database/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/database/cmd_test.go @@ -10,14 +10,14 @@ func TestBasic(t *testing.T) { createDatabaseYAML := configflag.FlagStringSlice{} databaseFlagSets := SetupFlags(&createDatabaseYAML) - if e := _parseAndDo([]string{""}, &createDatabaseYAML, &databaseFlagSets, "", func(string, string) { return }); e == nil { + if e := parseAndDoCreate([]string{""}, &createDatabaseYAML, &databaseFlagSets, "", func(string, string) { return }); e == nil { t.Error("It should return error on no args") } createDatabaseYAML = configflag.FlagStringSlice{} databaseFlagSets = SetupFlags(&createDatabaseYAML) - if e := _parseAndDo([]string{"db", "create", "-f", "somefile"}, &createDatabaseYAML, &databaseFlagSets, "", func(string, string) { return }); e != nil { + if e := parseAndDoCreate([]string{"create", "-f", "somefile"}, &createDatabaseYAML, &databaseFlagSets, "", func(string, string) { return }); e != nil { t.Error("It should NOT return error on sane args") } } diff --git a/src/cmd/tools/m3ctl/main/errors/types.go b/src/cmd/tools/m3ctl/main/errors/types.go new file mode 100644 index 0000000000..f2eaba018b --- /dev/null +++ b/src/cmd/tools/m3ctl/main/errors/types.go @@ -0,0 +1,12 @@ +package errors + +type FlagsError struct { + Message string +} + +func (e *FlagsError) Error() string { + if e == nil { + return "" + } + return e.Message +} diff --git a/src/cmd/tools/m3ctl/main/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/namespaces/cmd.go index 55b9cc3bbe..9ff2e2b6e1 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/namespaces/cmd.go @@ -3,6 +3,7 @@ package namespaces import ( "flag" "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" "os" ) @@ -17,8 +18,10 @@ type NamespaceArgs struct { } type NamespaceFlags struct { - Namespace *flag.FlagSet - Delete *flag.FlagSet + Namespace *flag.FlagSet + NamespaceDoer func(*NamespaceArgs, string) + Delete *flag.FlagSet + DeleteDoer func(*NamespaceArgs, string) } func SetupFlags(flags *NamespaceArgs) NamespaceFlags { @@ -65,39 +68,48 @@ Usage of %s: `, deleteFlags.Name(), namespaceFlags.Name(), deleteFlags.Name()) deleteFlags.PrintDefaults() } - return NamespaceFlags{Namespace: namespaceFlags, Delete: deleteFlags} + return NamespaceFlags{Namespace: namespaceFlags, NamespaceDoer: Show, Delete: deleteFlags, DeleteDoer: Delete} } func ParseAndDo(args *NamespaceArgs, flags *NamespaceFlags, ep string) { - if err := flags.Namespace.Parse(flag.Args()[1:]); err != nil { + osArgs := flag.Args() + // right here args should be like "ns delete -name someName" + if len(osArgs) < 1 { flags.Namespace.Usage() os.Exit(1) } - // maybe do the default action which is listing the names + // pop and parse + if err := parseAndDo(osArgs[1:], args, flags, ep); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } +} + +func parseAndDo(args []string, finalArgs *NamespaceArgs, flags *NamespaceFlags, ep string) error { + if err := flags.Namespace.Parse(args); err != nil { + flags.Namespace.Usage() + return &errors.FlagsError{} + } + // maybe do "ns -all" if flags.Namespace.NArg() == 0 { - Show(args, ep) - os.Exit(0) + flags.NamespaceDoer(finalArgs, ep) + return nil } - switch flag.Arg(1) { + nextArgs := flags.Namespace.Args() + switch nextArgs[0] { case flags.Delete.Name(): - if err := flags.Delete.Parse(flag.Args()[2:]); err != nil { + if err := flags.Delete.Parse(nextArgs[1:]); err != nil { flags.Delete.Usage() - os.Exit(1) + return &errors.FlagsError{} } if flags.Delete.NFlag() == 0 { flags.Delete.Usage() - os.Exit(1) + return &errors.FlagsError{} } - flags.Delete.Visit(func(f *flag.Flag) { - if len(f.Value.String()) == 0 { - fmt.Fprintf(os.Stderr, "%s requires a value.\n", f.Name) - flags.Delete.Usage() - os.Exit(1) - } - }) - Delete(args, ep) + flags.DeleteDoer(finalArgs, ep) + return nil default: flags.Namespace.Usage() - os.Exit(1) + return &errors.FlagsError{} } } diff --git a/src/cmd/tools/m3ctl/main/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/main/namespaces/cmd_test.go new file mode 100644 index 0000000000..924b1ba41d --- /dev/null +++ b/src/cmd/tools/m3ctl/main/namespaces/cmd_test.go @@ -0,0 +1,32 @@ +package namespaces + +import ( + "testing" +) + +func makeStub() (NamespaceArgs, NamespaceFlags) { + namespaceArgs := NamespaceArgs{} + namespaceFlagSets := SetupFlags(&namespaceArgs) + + namespaceFlagSets.NamespaceDoer = func(*NamespaceArgs, string) { return } + namespaceFlagSets.DeleteDoer = func(*NamespaceArgs, string) { return } + + return namespaceArgs, namespaceFlagSets +} +func TestBasic(t *testing.T) { + + args, flags := makeStub() + if e := parseAndDo([]string{""}, &args, &flags, ""); e == nil { + t.Error("It should return error on no args") + } + + args, flags = makeStub() + if e := parseAndDo([]string{"delete", "-name", "www"}, &args, &flags, ""); e != nil { + t.Error("It should not return error no sane args") + } + + args, flags = makeStub() + if e := parseAndDo([]string{"-all"}, &args, &flags, ""); e != nil { + t.Error("It should not return error no sane args") + } +} From 75e49d24d889547fbcf518f06542aad42420acfe Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 12 Jan 2020 17:54:00 -0800 Subject: [PATCH 23/65] add placements cli args test --- src/cmd/tools/m3ctl/main/database/cmd_test.go | 9 ++ src/cmd/tools/m3ctl/main/namespaces/cmd.go | 10 +- .../tools/m3ctl/main/namespaces/cmd_test.go | 4 +- src/cmd/tools/m3ctl/main/placements/cmd.go | 94 +++++++++++++------ .../tools/m3ctl/main/placements/cmd_test.go | 58 ++++++++++++ 5 files changed, 142 insertions(+), 33 deletions(-) create mode 100644 src/cmd/tools/m3ctl/main/placements/cmd_test.go diff --git a/src/cmd/tools/m3ctl/main/database/cmd_test.go b/src/cmd/tools/m3ctl/main/database/cmd_test.go index 86e59f6a66..3e5fdd49b2 100644 --- a/src/cmd/tools/m3ctl/main/database/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/database/cmd_test.go @@ -20,4 +20,13 @@ func TestBasic(t *testing.T) { if e := parseAndDoCreate([]string{"create", "-f", "somefile"}, &createDatabaseYAML, &databaseFlagSets, "", func(string, string) { return }); e != nil { t.Error("It should NOT return error on sane args") } + + if len(createDatabaseYAML.Value) != 1 { + t.Fatalf("db create filename len is wrong:expected:1:but got:%d:\n", len(createDatabaseYAML.Value)) + } + + if createDatabaseYAML.Value[0] != "somefile" { + t.Errorf("db create filename value is wrong:expected:%s:but got:%s:\n", createDatabaseYAML.Value[0], "somefile") + } + } diff --git a/src/cmd/tools/m3ctl/main/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/namespaces/cmd.go index 9ff2e2b6e1..6ad04dcb7b 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/namespaces/cmd.go @@ -28,7 +28,6 @@ func SetupFlags(flags *NamespaceArgs) NamespaceFlags { namespaceFlags := flag.NewFlagSet("ns", flag.ExitOnError) deleteFlags := flag.NewFlagSet("delete", flag.ExitOnError) flags.delete = deleteFlags.String("name", "", "name of namespace to delete") - flags.showAll = namespaceFlags.Bool("all", false, "show all the standard info for namespaces (otherwise default behaviour lists only the names)") namespaceFlags.Usage = func() { fmt.Fprintf(namespaceFlags.Output(), ` @@ -72,14 +71,14 @@ Usage of %s: } func ParseAndDo(args *NamespaceArgs, flags *NamespaceFlags, ep string) { - osArgs := flag.Args() + originalArgs := flag.Args() // right here args should be like "ns delete -name someName" - if len(osArgs) < 1 { + if len(originalArgs) < 1 { flags.Namespace.Usage() os.Exit(1) } // pop and parse - if err := parseAndDo(osArgs[1:], args, flags, ep); err != nil { + if err := parseAndDo(originalArgs[1:], args, flags, ep); err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } @@ -108,6 +107,9 @@ func parseAndDo(args []string, finalArgs *NamespaceArgs, flags *NamespaceFlags, } flags.DeleteDoer(finalArgs, ep) return nil + case "": + flags.NamespaceDoer(finalArgs, ep) + return nil default: flags.Namespace.Usage() return &errors.FlagsError{} diff --git a/src/cmd/tools/m3ctl/main/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/main/namespaces/cmd_test.go index 924b1ba41d..9c911d8ce8 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/namespaces/cmd_test.go @@ -16,8 +16,8 @@ func makeStub() (NamespaceArgs, NamespaceFlags) { func TestBasic(t *testing.T) { args, flags := makeStub() - if e := parseAndDo([]string{""}, &args, &flags, ""); e == nil { - t.Error("It should return error on no args") + if e := parseAndDo([]string{""}, &args, &flags, ""); e != nil { + t.Error("It should not return an error on no args") } args, flags = makeStub() diff --git a/src/cmd/tools/m3ctl/main/placements/cmd.go b/src/cmd/tools/m3ctl/main/placements/cmd.go index a54d49ea20..c3fec95d04 100644 --- a/src/cmd/tools/m3ctl/main/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd.go @@ -3,6 +3,7 @@ package placements import ( "flag" "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" "github.com/m3db/m3/src/x/config/configflag" "os" ) @@ -20,11 +21,16 @@ type PlacementArgs struct { } type PlacementFlags struct { - Placement *flag.FlagSet - Delete *flag.FlagSet - Add *flag.FlagSet - Init *flag.FlagSet - Replace *flag.FlagSet + Placement *flag.FlagSet + PlacementDoer func(*PlacementArgs, string) + Delete *flag.FlagSet + DeleteDoer func(*PlacementArgs, string) + Add *flag.FlagSet + AddDoer func(*PlacementArgs, string) + Init *flag.FlagSet + InitDoer func(*PlacementArgs, string) + Replace *flag.FlagSet + ReplaceDoer func(*PlacementArgs, string) } func SetupFlags(flags *PlacementArgs) PlacementFlags { @@ -73,61 +79,95 @@ Usage of %s: `, placementFlags.Name(), placementFlags.Name(), deleteFlags.Name(), addFlags.Name(), initFlags.Name(), replaceFlags.Name(), placementFlags.Name()) placementFlags.PrintDefaults() } - return PlacementFlags{Placement: placementFlags, Delete: deleteFlags, Add: addFlags, Init: initFlags, Replace: replaceFlags} + return PlacementFlags{ + Placement: placementFlags, + PlacementDoer: Get, + Delete: deleteFlags, + DeleteDoer: Delete, + Add: addFlags, + AddDoer: Add, + Init: initFlags, + InitDoer: Init, + Replace: replaceFlags, + ReplaceDoer: Replace, + } } func ParseAndDo(args *PlacementArgs, flags *PlacementFlags, ep string) { - if err := flags.Placement.Parse(flag.Args()[1:]); err != nil { + originalArgs := flag.Args() + // right here args should be like "ns delete -name someName" + if len(originalArgs) < 1 { flags.Placement.Usage() os.Exit(1) } + // pop and parse + if err := parseAndDo(originalArgs[1:], args, flags, ep); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + +} + +func parseAndDo(args []string, finalArgs *PlacementArgs, flags *PlacementFlags, ep string) error { + if err := flags.Placement.Parse(args); err != nil { + flags.Placement.Usage() + return &errors.FlagsError{} + } if flags.Placement.NArg() == 0 { - Get(args, ep) - os.Exit(0) + flags.PlacementDoer(finalArgs, ep) + return nil } - switch flag.Arg(1) { + nextArgs := flags.Placement.Args() + switch nextArgs[0] { case flags.Add.Name(): - if err := flags.Add.Parse(flag.Args()[2:]); err != nil { + if err := flags.Add.Parse(nextArgs[1:]); err != nil { flags.Add.Usage() - os.Exit(1) + return &errors.FlagsError{} } if flags.Add.NFlag() == 0 { flags.Add.Usage() - os.Exit(1) + return &errors.FlagsError{} } - Add(args, ep) + flags.AddDoer(finalArgs, ep) + return nil case flags.Delete.Name(): - if err := flags.Delete.Parse(flag.Args()[2:]); err != nil { + if err := flags.Delete.Parse(nextArgs[1:]); err != nil { flags.Delete.Usage() - os.Exit(1) + return &errors.FlagsError{} } if flags.Delete.NFlag() == 0 { flags.Delete.Usage() - os.Exit(1) + return &errors.FlagsError{} } - Delete(args, ep) + flags.DeleteDoer(finalArgs, ep) + return nil case flags.Init.Name(): - if err := flags.Init.Parse(flag.Args()[2:]); err != nil { + if err := flags.Init.Parse(nextArgs[1:]); err != nil { flags.Init.Usage() - os.Exit(1) + return &errors.FlagsError{} } if flags.Init.NFlag() == 0 { flags.Init.Usage() - os.Exit(1) + return &errors.FlagsError{} } - Init(args, ep) + flags.InitDoer(finalArgs, ep) + return nil case flags.Replace.Name(): - if err := flags.Replace.Parse(flag.Args()[2:]); err != nil { + if err := flags.Replace.Parse(nextArgs[1:]); err != nil { flags.Replace.Usage() - os.Exit(1) + return &errors.FlagsError{} } if flags.Replace.NFlag() == 0 { flags.Replace.Usage() - os.Exit(1) + return &errors.FlagsError{} } - Replace(args, ep) + flags.ReplaceDoer(finalArgs, ep) + return nil + case "": + flags.PlacementDoer(finalArgs, ep) + return nil default: - Get(args, ep) + return &errors.FlagsError{} } } diff --git a/src/cmd/tools/m3ctl/main/placements/cmd_test.go b/src/cmd/tools/m3ctl/main/placements/cmd_test.go new file mode 100644 index 0000000000..8c0c319f11 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/placements/cmd_test.go @@ -0,0 +1,58 @@ +package placements + +import ( + "testing" +) + +func makeStub() (PlacementArgs, PlacementFlags) { + placementArgs := PlacementArgs{} + placementFlagSets := SetupFlags(&placementArgs) + + placementFlagSets.PlacementDoer = func(*PlacementArgs, string) { return } + placementFlagSets.AddDoer = func(*PlacementArgs, string) { return } + placementFlagSets.DeleteDoer = func(*PlacementArgs, string) { return } + placementFlagSets.InitDoer = func(*PlacementArgs, string) { return } + placementFlagSets.ReplaceDoer = func(*PlacementArgs, string) { return } + + return placementArgs, placementFlagSets +} +func TestBasic(t *testing.T) { + + // default is to list placements + // so no args is OK + args, flags := makeStub() + if err := parseAndDo([]string{""}, &args, &flags, ""); err != nil { + t.Error("It should not return error no args") + } + + args, flags = makeStub() + if err := parseAndDo([]string{"junk"}, &args, &flags, ""); err == nil { + t.Error("It should return an error on junk") + } + + args, flags = makeStub() + if err := parseAndDo([]string{"delete", "-all"}, &args, &flags, ""); err != nil { + t.Error("It should not return error no sane args") + } + + args, flags = makeStub() + if err := parseAndDo([]string{"delete", "-node", "nodeName"}, &args, &flags, ""); err != nil { + t.Error("It should not return error no sane args") + } + + args, flags = makeStub() + if err := parseAndDo([]string{"add", "-f", "somefile"}, &args, &flags, ""); err != nil { + t.Error("It should not return error no sane args") + } + + args, flags = makeStub() + if err := parseAndDo([]string{"init", "-f", "somefile"}, &args, &flags, ""); err != nil { + t.Error("It should not return error no sane args") + } + + args, flags = makeStub() + if err := parseAndDo([]string{"replace", "-f", "somefile"}, &args, &flags, ""); err != nil { + t.Error("It should not return error no sane args") + } + +} From 0e13026c2dac29f365f2dcf644de7ac97299a90b Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 12 Jan 2020 18:06:54 -0800 Subject: [PATCH 24/65] cleaning up --- src/cmd/tools/m3ctl/main/database/cmd.go | 2 +- src/cmd/tools/m3ctl/main/database/cmd_test.go | 2 +- src/cmd/tools/m3ctl/main/namespaces/cmd.go | 12 +++---- .../tools/m3ctl/main/namespaces/cmd_test.go | 6 ++-- src/cmd/tools/m3ctl/main/placements/cmd.go | 32 +++++++++---------- .../tools/m3ctl/main/placements/cmd_test.go | 12 +++---- src/cmd/tools/m3ctl/main/yaml/load.go | 1 - 7 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/cmd/tools/m3ctl/main/database/cmd.go b/src/cmd/tools/m3ctl/main/database/cmd.go index 85c36c44a2..16d2198d22 100644 --- a/src/cmd/tools/m3ctl/main/database/cmd.go +++ b/src/cmd/tools/m3ctl/main/database/cmd.go @@ -85,7 +85,7 @@ func parseAndDoCreate(args []string, finalArgs *configflag.FlagStringSlice, flag flags.Create.Usage() return &errors.FlagsError{} } - // the below finalArgs.Value has at least one value by this time per the finalArgs parser + // the below finalArgs.Value has at least one value by this time per the parser doer(finalArgs.Value[len(finalArgs.Value)-1], ep) return nil default: diff --git a/src/cmd/tools/m3ctl/main/database/cmd_test.go b/src/cmd/tools/m3ctl/main/database/cmd_test.go index 3e5fdd49b2..41b8969251 100644 --- a/src/cmd/tools/m3ctl/main/database/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/database/cmd_test.go @@ -10,7 +10,7 @@ func TestBasic(t *testing.T) { createDatabaseYAML := configflag.FlagStringSlice{} databaseFlagSets := SetupFlags(&createDatabaseYAML) - if e := parseAndDoCreate([]string{""}, &createDatabaseYAML, &databaseFlagSets, "", func(string, string) { return }); e == nil { + if e := parseAndDoCreate([]string{}, &createDatabaseYAML, &databaseFlagSets, "", func(string, string) { return }); e == nil { t.Error("It should return error on no args") } diff --git a/src/cmd/tools/m3ctl/main/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/namespaces/cmd.go index 6ad04dcb7b..3600ce6d63 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/namespaces/cmd.go @@ -19,9 +19,9 @@ type NamespaceArgs struct { type NamespaceFlags struct { Namespace *flag.FlagSet - NamespaceDoer func(*NamespaceArgs, string) + namespaceDoer func(*NamespaceArgs, string) Delete *flag.FlagSet - DeleteDoer func(*NamespaceArgs, string) + deleteDoer func(*NamespaceArgs, string) } func SetupFlags(flags *NamespaceArgs) NamespaceFlags { @@ -67,7 +67,7 @@ Usage of %s: `, deleteFlags.Name(), namespaceFlags.Name(), deleteFlags.Name()) deleteFlags.PrintDefaults() } - return NamespaceFlags{Namespace: namespaceFlags, NamespaceDoer: Show, Delete: deleteFlags, DeleteDoer: Delete} + return NamespaceFlags{Namespace: namespaceFlags, namespaceDoer: Show, Delete: deleteFlags, deleteDoer: Delete} } func ParseAndDo(args *NamespaceArgs, flags *NamespaceFlags, ep string) { @@ -91,7 +91,7 @@ func parseAndDo(args []string, finalArgs *NamespaceArgs, flags *NamespaceFlags, } // maybe do "ns -all" if flags.Namespace.NArg() == 0 { - flags.NamespaceDoer(finalArgs, ep) + flags.namespaceDoer(finalArgs, ep) return nil } nextArgs := flags.Namespace.Args() @@ -105,10 +105,10 @@ func parseAndDo(args []string, finalArgs *NamespaceArgs, flags *NamespaceFlags, flags.Delete.Usage() return &errors.FlagsError{} } - flags.DeleteDoer(finalArgs, ep) + flags.deleteDoer(finalArgs, ep) return nil case "": - flags.NamespaceDoer(finalArgs, ep) + flags.namespaceDoer(finalArgs, ep) return nil default: flags.Namespace.Usage() diff --git a/src/cmd/tools/m3ctl/main/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/main/namespaces/cmd_test.go index 9c911d8ce8..f87becdbd1 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/namespaces/cmd_test.go @@ -8,15 +8,15 @@ func makeStub() (NamespaceArgs, NamespaceFlags) { namespaceArgs := NamespaceArgs{} namespaceFlagSets := SetupFlags(&namespaceArgs) - namespaceFlagSets.NamespaceDoer = func(*NamespaceArgs, string) { return } - namespaceFlagSets.DeleteDoer = func(*NamespaceArgs, string) { return } + namespaceFlagSets.namespaceDoer = func(*NamespaceArgs, string) { return } + namespaceFlagSets.deleteDoer = func(*NamespaceArgs, string) { return } return namespaceArgs, namespaceFlagSets } func TestBasic(t *testing.T) { args, flags := makeStub() - if e := parseAndDo([]string{""}, &args, &flags, ""); e != nil { + if e := parseAndDo([]string{}, &args, &flags, ""); e != nil { t.Error("It should not return an error on no args") } diff --git a/src/cmd/tools/m3ctl/main/placements/cmd.go b/src/cmd/tools/m3ctl/main/placements/cmd.go index c3fec95d04..03b5dd99fb 100644 --- a/src/cmd/tools/m3ctl/main/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd.go @@ -22,15 +22,15 @@ type PlacementArgs struct { type PlacementFlags struct { Placement *flag.FlagSet - PlacementDoer func(*PlacementArgs, string) + placementDoer func(*PlacementArgs, string) Delete *flag.FlagSet - DeleteDoer func(*PlacementArgs, string) + deleteDoer func(*PlacementArgs, string) Add *flag.FlagSet - AddDoer func(*PlacementArgs, string) + addDoer func(*PlacementArgs, string) Init *flag.FlagSet - InitDoer func(*PlacementArgs, string) + initDoer func(*PlacementArgs, string) Replace *flag.FlagSet - ReplaceDoer func(*PlacementArgs, string) + replaceDoer func(*PlacementArgs, string) } func SetupFlags(flags *PlacementArgs) PlacementFlags { @@ -81,15 +81,15 @@ Usage of %s: } return PlacementFlags{ Placement: placementFlags, - PlacementDoer: Get, + placementDoer: Get, Delete: deleteFlags, - DeleteDoer: Delete, + deleteDoer: Delete, Add: addFlags, - AddDoer: Add, + addDoer: Add, Init: initFlags, - InitDoer: Init, + initDoer: Init, Replace: replaceFlags, - ReplaceDoer: Replace, + replaceDoer: Replace, } } @@ -114,7 +114,7 @@ func parseAndDo(args []string, finalArgs *PlacementArgs, flags *PlacementFlags, return &errors.FlagsError{} } if flags.Placement.NArg() == 0 { - flags.PlacementDoer(finalArgs, ep) + flags.placementDoer(finalArgs, ep) return nil } nextArgs := flags.Placement.Args() @@ -128,7 +128,7 @@ func parseAndDo(args []string, finalArgs *PlacementArgs, flags *PlacementFlags, flags.Add.Usage() return &errors.FlagsError{} } - flags.AddDoer(finalArgs, ep) + flags.addDoer(finalArgs, ep) return nil case flags.Delete.Name(): if err := flags.Delete.Parse(nextArgs[1:]); err != nil { @@ -139,7 +139,7 @@ func parseAndDo(args []string, finalArgs *PlacementArgs, flags *PlacementFlags, flags.Delete.Usage() return &errors.FlagsError{} } - flags.DeleteDoer(finalArgs, ep) + flags.deleteDoer(finalArgs, ep) return nil case flags.Init.Name(): if err := flags.Init.Parse(nextArgs[1:]); err != nil { @@ -150,7 +150,7 @@ func parseAndDo(args []string, finalArgs *PlacementArgs, flags *PlacementFlags, flags.Init.Usage() return &errors.FlagsError{} } - flags.InitDoer(finalArgs, ep) + flags.initDoer(finalArgs, ep) return nil case flags.Replace.Name(): if err := flags.Replace.Parse(nextArgs[1:]); err != nil { @@ -161,10 +161,10 @@ func parseAndDo(args []string, finalArgs *PlacementArgs, flags *PlacementFlags, flags.Replace.Usage() return &errors.FlagsError{} } - flags.ReplaceDoer(finalArgs, ep) + flags.replaceDoer(finalArgs, ep) return nil case "": - flags.PlacementDoer(finalArgs, ep) + flags.placementDoer(finalArgs, ep) return nil default: return &errors.FlagsError{} diff --git a/src/cmd/tools/m3ctl/main/placements/cmd_test.go b/src/cmd/tools/m3ctl/main/placements/cmd_test.go index 8c0c319f11..af4674ac13 100644 --- a/src/cmd/tools/m3ctl/main/placements/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd_test.go @@ -8,11 +8,11 @@ func makeStub() (PlacementArgs, PlacementFlags) { placementArgs := PlacementArgs{} placementFlagSets := SetupFlags(&placementArgs) - placementFlagSets.PlacementDoer = func(*PlacementArgs, string) { return } - placementFlagSets.AddDoer = func(*PlacementArgs, string) { return } - placementFlagSets.DeleteDoer = func(*PlacementArgs, string) { return } - placementFlagSets.InitDoer = func(*PlacementArgs, string) { return } - placementFlagSets.ReplaceDoer = func(*PlacementArgs, string) { return } + placementFlagSets.placementDoer = func(*PlacementArgs, string) { return } + placementFlagSets.addDoer = func(*PlacementArgs, string) { return } + placementFlagSets.deleteDoer = func(*PlacementArgs, string) { return } + placementFlagSets.initDoer = func(*PlacementArgs, string) { return } + placementFlagSets.replaceDoer = func(*PlacementArgs, string) { return } return placementArgs, placementFlagSets } @@ -21,7 +21,7 @@ func TestBasic(t *testing.T) { // default is to list placements // so no args is OK args, flags := makeStub() - if err := parseAndDo([]string{""}, &args, &flags, ""); err != nil { + if err := parseAndDo([]string{}, &args, &flags, ""); err != nil { t.Error("It should not return error no args") } diff --git a/src/cmd/tools/m3ctl/main/yaml/load.go b/src/cmd/tools/m3ctl/main/yaml/load.go index ee367370fa..6975d31180 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load.go +++ b/src/cmd/tools/m3ctl/main/yaml/load.go @@ -11,7 +11,6 @@ import ( ) func Load(path string, target proto.Message) io.Reader { - log.Printf("path:%s:\n", path) content, err := ioutil.ReadFile(path) if err != nil { log.Fatal(err) From 099d24d29088edd137bf924897e141857f5e83aa Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Mon, 13 Jan 2020 09:34:46 -0800 Subject: [PATCH 25/65] address more PR comments --- src/cmd/tools/m3ctl/main/{http => client}/checker.go | 2 +- src/cmd/tools/m3ctl/main/{http => client}/http.go | 2 +- src/cmd/tools/m3ctl/main/database/cmd.go | 3 ++- src/cmd/tools/m3ctl/main/database/cmd_test.go | 3 ++- src/cmd/tools/m3ctl/main/database/create.go | 7 ++++--- src/cmd/tools/m3ctl/main/main.go | 3 ++- src/cmd/tools/m3ctl/main/namespaces/cmd.go | 3 ++- src/cmd/tools/m3ctl/main/namespaces/delete.go | 5 +++-- src/cmd/tools/m3ctl/main/namespaces/show.go | 12 +++++++----- src/cmd/tools/m3ctl/main/placements/add.go | 7 ++++--- src/cmd/tools/m3ctl/main/placements/cmd.go | 3 ++- src/cmd/tools/m3ctl/main/placements/delete.go | 7 ++++--- src/cmd/tools/m3ctl/main/placements/get.go | 5 +++-- src/cmd/tools/m3ctl/main/placements/init.go | 7 ++++--- src/cmd/tools/m3ctl/main/placements/replace.go | 5 +++-- src/cmd/tools/m3ctl/main/yaml/load.go | 7 ++++--- src/cmd/tools/m3ctl/main/yaml/load_test.go | 6 ++++-- 17 files changed, 52 insertions(+), 35 deletions(-) rename src/cmd/tools/m3ctl/main/{http => client}/checker.go (95%) rename src/cmd/tools/m3ctl/main/{http => client}/http.go (98%) diff --git a/src/cmd/tools/m3ctl/main/http/checker.go b/src/cmd/tools/m3ctl/main/client/checker.go similarity index 95% rename from src/cmd/tools/m3ctl/main/http/checker.go rename to src/cmd/tools/m3ctl/main/client/checker.go index 12a41147fd..c03843bab4 100644 --- a/src/cmd/tools/m3ctl/main/http/checker.go +++ b/src/cmd/tools/m3ctl/main/client/checker.go @@ -1,4 +1,4 @@ -package http +package client import ( "fmt" diff --git a/src/cmd/tools/m3ctl/main/http/http.go b/src/cmd/tools/m3ctl/main/client/http.go similarity index 98% rename from src/cmd/tools/m3ctl/main/http/http.go rename to src/cmd/tools/m3ctl/main/client/http.go index debdb90890..7a642e64cd 100644 --- a/src/cmd/tools/m3ctl/main/http/http.go +++ b/src/cmd/tools/m3ctl/main/client/http.go @@ -1,4 +1,4 @@ -package http +package client import ( "fmt" diff --git a/src/cmd/tools/m3ctl/main/database/cmd.go b/src/cmd/tools/m3ctl/main/database/cmd.go index 16d2198d22..63ff8770ef 100644 --- a/src/cmd/tools/m3ctl/main/database/cmd.go +++ b/src/cmd/tools/m3ctl/main/database/cmd.go @@ -3,9 +3,10 @@ package database import ( "flag" "fmt" + "os" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" "github.com/m3db/m3/src/x/config/configflag" - "os" ) const ( diff --git a/src/cmd/tools/m3ctl/main/database/cmd_test.go b/src/cmd/tools/m3ctl/main/database/cmd_test.go index 41b8969251..962d2707de 100644 --- a/src/cmd/tools/m3ctl/main/database/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/database/cmd_test.go @@ -1,8 +1,9 @@ package database import ( - "github.com/m3db/m3/src/x/config/configflag" "testing" + + "github.com/m3db/m3/src/x/config/configflag" ) func TestBasic(t *testing.T) { diff --git a/src/cmd/tools/m3ctl/main/database/create.go b/src/cmd/tools/m3ctl/main/database/create.go index 4ec1b9b059..b71ece2171 100644 --- a/src/cmd/tools/m3ctl/main/database/create.go +++ b/src/cmd/tools/m3ctl/main/database/create.go @@ -2,16 +2,17 @@ package database import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + "log" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" "github.com/m3db/m3/src/query/generated/proto/admin" - "log" ) func Create(createYAML string, endpoint string) { log.Printf("createYAML:%s:\n", createYAML) data := yaml.Load(createYAML, &admin.DatabaseCreateRequest{}) url := fmt.Sprintf("%s%s/create", endpoint, defaultPath) - http.DoPost(url, data, http.DoDump) + client.DoPost(url, data, client.DoDump) return } diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index a9d0876836..97f3595cc5 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -23,11 +23,12 @@ package main import ( "flag" "fmt" + "os" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/database" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/namespaces" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" "github.com/m3db/m3/src/x/config/configflag" - "os" ) const ( diff --git a/src/cmd/tools/m3ctl/main/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/namespaces/cmd.go index 3600ce6d63..626fc28f64 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/namespaces/cmd.go @@ -3,8 +3,9 @@ package namespaces import ( "flag" "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" "os" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" ) const ( diff --git a/src/cmd/tools/m3ctl/main/namespaces/delete.go b/src/cmd/tools/m3ctl/main/namespaces/delete.go index dbbbdd5630..3ab4b0a148 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/delete.go +++ b/src/cmd/tools/m3ctl/main/namespaces/delete.go @@ -2,10 +2,11 @@ package namespaces import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" ) func Delete(flags *NamespaceArgs, endpoint string) { url := fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", *flags.delete) - http.DoDelete(url, http.DoDump) + client.DoDelete(url, client.DoDump) } diff --git a/src/cmd/tools/m3ctl/main/namespaces/show.go b/src/cmd/tools/m3ctl/main/namespaces/show.go index 3f34a593b7..8a40107b7a 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/show.go +++ b/src/cmd/tools/m3ctl/main/namespaces/show.go @@ -2,19 +2,21 @@ package namespaces import ( "fmt" - "github.com/gogo/protobuf/jsonpb" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" - "github.com/m3db/m3/src/query/generated/proto/admin" "io" "log" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" + "github.com/m3db/m3/src/query/generated/proto/admin" + + "github.com/gogo/protobuf/jsonpb" ) func Show(flags *NamespaceArgs, endpoint string) { url := fmt.Sprintf("%s%s?%s", endpoint, defaultPath, debugQS) if *flags.showAll { - http.DoGet(url, http.DoDump) + client.DoGet(url, client.DoDump) } else { - http.DoGet(url, showNames) + client.DoGet(url, showNames) } } diff --git a/src/cmd/tools/m3ctl/main/placements/add.go b/src/cmd/tools/m3ctl/main/placements/add.go index be3f9bb1ad..e2541e823f 100644 --- a/src/cmd/tools/m3ctl/main/placements/add.go +++ b/src/cmd/tools/m3ctl/main/placements/add.go @@ -2,16 +2,17 @@ package placements import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + "log" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" "github.com/m3db/m3/src/query/generated/proto/admin" - "log" ) func Add(flags *PlacementArgs, endpoint string) { log.Printf("PlacementArgs:%+v:\n", flags) data := yaml.Load(flags.newNodeFlag.Value[0], &admin.PlacementInitRequest{}) url := fmt.Sprintf("%s%s", endpoint, defaultPath) - http.DoPost(url, data, http.DoDump) + client.DoPost(url, data, client.DoDump) return } diff --git a/src/cmd/tools/m3ctl/main/placements/cmd.go b/src/cmd/tools/m3ctl/main/placements/cmd.go index 03b5dd99fb..a3908244fc 100644 --- a/src/cmd/tools/m3ctl/main/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd.go @@ -3,9 +3,10 @@ package placements import ( "flag" "fmt" + "os" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" "github.com/m3db/m3/src/x/config/configflag" - "os" ) const ( diff --git a/src/cmd/tools/m3ctl/main/placements/delete.go b/src/cmd/tools/m3ctl/main/placements/delete.go index 63b16434f6..a5188b285b 100644 --- a/src/cmd/tools/m3ctl/main/placements/delete.go +++ b/src/cmd/tools/m3ctl/main/placements/delete.go @@ -2,16 +2,17 @@ package placements import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" ) func Delete(flags *PlacementArgs, endpoint string) { if *flags.deletePlacement { url := fmt.Sprintf("%s%s", endpoint, defaultPath) - http.DoDelete(url, http.DoDump) + client.DoDelete(url, client.DoDump) return } url := fmt.Sprintf("%s%s/%s", endpoint, defaultPath, *flags.deleteNode) - http.DoDelete(url, http.DoDump) + client.DoDelete(url, client.DoDump) return } diff --git a/src/cmd/tools/m3ctl/main/placements/get.go b/src/cmd/tools/m3ctl/main/placements/get.go index 58474fc053..cae4018324 100644 --- a/src/cmd/tools/m3ctl/main/placements/get.go +++ b/src/cmd/tools/m3ctl/main/placements/get.go @@ -2,11 +2,12 @@ package placements import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" ) func Get(flags *PlacementArgs, endpoint string) { url := fmt.Sprintf("%s%s", endpoint, defaultPath) - http.DoGet(url, http.DoDump) + client.DoGet(url, client.DoDump) return } diff --git a/src/cmd/tools/m3ctl/main/placements/init.go b/src/cmd/tools/m3ctl/main/placements/init.go index f1da33211c..50a5d0ca76 100644 --- a/src/cmd/tools/m3ctl/main/placements/init.go +++ b/src/cmd/tools/m3ctl/main/placements/init.go @@ -2,16 +2,17 @@ package placements import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + "log" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" "github.com/m3db/m3/src/query/generated/proto/admin" - "log" ) func Init(flags *PlacementArgs, endpoint string) { log.Printf("PlacementArgs:%+v:\n", flags) data := yaml.Load(flags.initFlag.Value[0], &admin.PlacementInitRequest{}) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/init") - http.DoPost(url, data, http.DoDump) + client.DoPost(url, data, client.DoDump) return } diff --git a/src/cmd/tools/m3ctl/main/placements/replace.go b/src/cmd/tools/m3ctl/main/placements/replace.go index d64fa37a70..829ce1bb55 100644 --- a/src/cmd/tools/m3ctl/main/placements/replace.go +++ b/src/cmd/tools/m3ctl/main/placements/replace.go @@ -2,7 +2,8 @@ package placements import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/http" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" "github.com/m3db/m3/src/query/generated/proto/admin" ) @@ -10,6 +11,6 @@ import ( func Replace(flags *PlacementArgs, endpoint string) { data := yaml.Load(flags.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/replace") - http.DoPost(url, data, http.DoDump) + client.DoPost(url, data, client.DoDump) return } diff --git a/src/cmd/tools/m3ctl/main/yaml/load.go b/src/cmd/tools/m3ctl/main/yaml/load.go index 6975d31180..f9544b34cf 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load.go +++ b/src/cmd/tools/m3ctl/main/yaml/load.go @@ -2,12 +2,13 @@ package yaml import ( "bytes" - "github.com/ghodss/yaml" - "github.com/gogo/protobuf/jsonpb" - "github.com/gogo/protobuf/proto" "io" "io/ioutil" "log" + + "github.com/ghodss/yaml" + "github.com/gogo/protobuf/jsonpb" + "github.com/gogo/protobuf/proto" ) func Load(path string, target proto.Message) io.Reader { diff --git a/src/cmd/tools/m3ctl/main/yaml/load_test.go b/src/cmd/tools/m3ctl/main/yaml/load_test.go index c4c71dc381..eafc160fe6 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load_test.go +++ b/src/cmd/tools/m3ctl/main/yaml/load_test.go @@ -1,10 +1,12 @@ package yaml import ( - "github.com/gogo/protobuf/jsonpb" - "github.com/m3db/m3/src/query/generated/proto/admin" "io/ioutil" "testing" + + "github.com/m3db/m3/src/query/generated/proto/admin" + + "github.com/gogo/protobuf/jsonpb" ) func TestLoadBasic(t *testing.T) { From 2ef92979dbf7f4c6a80e58cc2d31e57b70fa9062 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Tue, 28 Jan 2020 07:13:31 -0800 Subject: [PATCH 26/65] checkpoint --- src/cmd/tools/m3ctl/main/checkArgs/perCase.go | 20 +++ src/cmd/tools/m3ctl/main/main.go | 3 +- src/cmd/tools/m3ctl/main/placements/add.go | 6 +- src/cmd/tools/m3ctl/main/placements/cmd.go | 162 +++++++++--------- src/cmd/tools/m3ctl/main/placements/delete.go | 6 +- src/cmd/tools/m3ctl/main/placements/get.go | 2 +- src/cmd/tools/m3ctl/main/placements/init.go | 6 +- .../tools/m3ctl/main/placements/replace.go | 4 +- 8 files changed, 119 insertions(+), 90 deletions(-) create mode 100644 src/cmd/tools/m3ctl/main/checkArgs/perCase.go diff --git a/src/cmd/tools/m3ctl/main/checkArgs/perCase.go b/src/cmd/tools/m3ctl/main/checkArgs/perCase.go new file mode 100644 index 0000000000..ed99cf2b78 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/checkArgs/perCase.go @@ -0,0 +1,20 @@ +package checkArgs + +import ( + "flag" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" +) + +func CheckPerCase(args []string, fs *flag.FlagSet) *errors.FlagsError { + if err := fs.Parse(args); err != nil { + fs.Usage() + return &errors.FlagsError{} + } + if fs.NFlag() == 0 { + fs.Usage() + return &errors.FlagsError{} + } + + return nil +} + diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 97f3595cc5..462ad01b71 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -64,6 +64,7 @@ Usage of %s: Each subcommand has its own built-in help provided via "-h". `, os.Args[0], databaseFlagSets.Database.Name(), + //placementFlagSets.Placement.Name(), placementFlagSets.Placement.Name(), namespaceFlagSets.Namespace.Name()) @@ -83,7 +84,7 @@ Each subcommand has its own built-in help provided via "-h". case namespaceFlagSets.Namespace.Name(): namespaces.ParseAndDo(&namespaceArgs, &namespaceFlagSets, *endPoint) case placementFlagSets.Placement.Name(): - placements.ParseAndDo(&placementArgs, &placementFlagSets, *endPoint) + placementFlagSets.ParseAndDo(flag.Args(), &placementArgs, *endPoint) default: flag.Usage() os.Exit(1) diff --git a/src/cmd/tools/m3ctl/main/placements/add.go b/src/cmd/tools/m3ctl/main/placements/add.go index e2541e823f..1419fb542a 100644 --- a/src/cmd/tools/m3ctl/main/placements/add.go +++ b/src/cmd/tools/m3ctl/main/placements/add.go @@ -9,9 +9,9 @@ import ( "github.com/m3db/m3/src/query/generated/proto/admin" ) -func Add(flags *PlacementArgs, endpoint string) { - log.Printf("PlacementArgs:%+v:\n", flags) - data := yaml.Load(flags.newNodeFlag.Value[0], &admin.PlacementInitRequest{}) +func (s XPlacementFlags) add(endpoint string) { + log.Printf("PlacementArgs:%+v:\n", s.finalArgs) + data := yaml.Load(s.finalArgs.newNodeFlag.Value[0], &admin.PlacementInitRequest{}) url := fmt.Sprintf("%s%s", endpoint, defaultPath) client.DoPost(url, data, client.DoDump) return diff --git a/src/cmd/tools/m3ctl/main/placements/cmd.go b/src/cmd/tools/m3ctl/main/placements/cmd.go index a3908244fc..7a0dedcc6c 100644 --- a/src/cmd/tools/m3ctl/main/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd.go @@ -3,6 +3,7 @@ package placements import ( "flag" "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "os" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" @@ -21,31 +22,45 @@ type PlacementArgs struct { replaceFlag configflag.FlagStringSlice } -type PlacementFlags struct { - Placement *flag.FlagSet - placementDoer func(*PlacementArgs, string) - Delete *flag.FlagSet - deleteDoer func(*PlacementArgs, string) - Add *flag.FlagSet - addDoer func(*PlacementArgs, string) - Init *flag.FlagSet - initDoer func(*PlacementArgs, string) - Replace *flag.FlagSet - replaceDoer func(*PlacementArgs, string) +type XFlagSet struct { + Flagset *flag.FlagSet } - -func SetupFlags(flags *PlacementArgs) PlacementFlags { +type XPlacementFlags struct { + //Args *PlacementArgs + finalArgs *PlacementArgs + Globals []string + Placement *flag.FlagSet + Add *flag.FlagSet + Delete *flag.FlagSet + Init *flag.FlagSet + Replace *flag.FlagSet +} +//type PlacementFlags struct { +// Placement *flag.FlagSet +// placementDoer func(*PlacementArgs, string) +// Delete *flag.FlagSet +// deleteDoer func(*PlacementArgs, string) +// Add *flag.FlagSet +// addDoer func(*PlacementArgs, string) +// Init *flag.FlagSet +// initDoer func(*PlacementArgs, string) +// Replace *flag.FlagSet +// replaceDoer func(*PlacementArgs, string) +//} + +//func SetupFlags(flags *PlacementArgs) PlacementFlags { +func SetupFlags(finalArgs *PlacementArgs) XPlacementFlags { placementFlags := flag.NewFlagSet("pl", flag.ExitOnError) deleteFlags := flag.NewFlagSet("delete", flag.ExitOnError) addFlags := flag.NewFlagSet("add", flag.ExitOnError) initFlags := flag.NewFlagSet("init", flag.ExitOnError) replaceFlags := flag.NewFlagSet("replace", flag.ExitOnError) - flags.deletePlacement = deleteFlags.Bool("all", false, "delete the entire placement") - flags.deleteNode = deleteFlags.String("node", "", "delete the specified node in the placement") - initFlags.Var(&flags.initFlag, "f", "initialize a placement. Specify a yaml file.") - addFlags.Var(&flags.newNodeFlag, "f", "add a new node to the placement. Specify the filename of the yaml.") - replaceFlags.Var(&flags.replaceFlag, "f", "add a new node to the placement. Specify the filename of the yaml.") + finalArgs.deletePlacement = deleteFlags.Bool("all", false, "delete the entire placement") + finalArgs.deleteNode = deleteFlags.String("node", "", "delete the specified node in the placement") + initFlags.Var(&finalArgs.initFlag, "f", "initialize a placement. Specify a yaml file.") + addFlags.Var(&finalArgs.newNodeFlag, "f", "add a new node to the placement. Specify the filename of the yaml.") + replaceFlags.Var(&finalArgs.replaceFlag, "f", "add a new node to the placement. Specify the filename of the yaml.") placementFlags.Usage = func() { fmt.Fprintf(os.Stderr, ` "%s" is for acting on placements. @@ -80,92 +95,85 @@ Usage of %s: `, placementFlags.Name(), placementFlags.Name(), deleteFlags.Name(), addFlags.Name(), initFlags.Name(), replaceFlags.Name(), placementFlags.Name()) placementFlags.PrintDefaults() } - return PlacementFlags{ - Placement: placementFlags, - placementDoer: Get, - Delete: deleteFlags, - deleteDoer: Delete, - Add: addFlags, - addDoer: Add, - Init: initFlags, - initDoer: Init, - Replace: replaceFlags, - replaceDoer: Replace, + //return PlacementFlags{ + // Placement: placementFlags, + // placementDoer: Get, + // Delete: deleteFlags, + // deleteDoer: Delete, + // Add: addFlags, + // addDoer: Add, + // Init: initFlags, + // initDoer: Init, + // Replace: replaceFlags, + // replaceDoer: Replace, + //} + return XPlacementFlags{ + //Args: nil, + finalArgs: finalArgs, + Globals: nil, + Placement: placementFlags, + Add: addFlags, + Delete: deleteFlags, + Init: initFlags, + Replace: replaceFlags, } } -func ParseAndDo(args *PlacementArgs, flags *PlacementFlags, ep string) { - originalArgs := flag.Args() +func (xflags XPlacementFlags) ParseAndDo(cli []string, args *PlacementArgs, ep string) { + //originalArgs := flag.Args() // right here args should be like "ns delete -name someName" - if len(originalArgs) < 1 { - flags.Placement.Usage() + if len(cli) < 1 { + xflags.Placement.Usage() os.Exit(1) } // pop and parse - if err := parseAndDo(originalArgs[1:], args, flags, ep); err != nil { + if err := dispatcher(cli[1:], xflags, ep); err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } } -func parseAndDo(args []string, finalArgs *PlacementArgs, flags *PlacementFlags, ep string) error { - if err := flags.Placement.Parse(args); err != nil { - flags.Placement.Usage() +func dispatcher(inArgs []string, xflags XPlacementFlags, ep string) error { + if err := xflags.Placement.Parse(inArgs); err != nil { + xflags.Placement.Usage() return &errors.FlagsError{} } - if flags.Placement.NArg() == 0 { - flags.placementDoer(finalArgs, ep) + if xflags.Placement.NArg() == 0 { + xflags.xget(ep) return nil } - nextArgs := flags.Placement.Args() + //if err := checkArgs.CheckPerCase(inArgs, xflags.Placement); err != nil { + // return err + //} + nextArgs := xflags.Placement.Args() switch nextArgs[0] { - case flags.Add.Name(): - if err := flags.Add.Parse(nextArgs[1:]); err != nil { - flags.Add.Usage() - return &errors.FlagsError{} - } - if flags.Add.NFlag() == 0 { - flags.Add.Usage() - return &errors.FlagsError{} + case xflags.Add.Name(): + if err := checkArgs.CheckPerCase(nextArgs[1:], xflags.Add); err != nil { + return err } - flags.addDoer(finalArgs, ep) + xflags.add(ep) return nil - case flags.Delete.Name(): - if err := flags.Delete.Parse(nextArgs[1:]); err != nil { - flags.Delete.Usage() - return &errors.FlagsError{} + case xflags.Delete.Name(): + if err := checkArgs.CheckPerCase(nextArgs[1:], xflags.Delete); err != nil { + return err } - if flags.Delete.NFlag() == 0 { - flags.Delete.Usage() - return &errors.FlagsError{} - } - flags.deleteDoer(finalArgs, ep) + xflags.delete(ep) return nil - case flags.Init.Name(): - if err := flags.Init.Parse(nextArgs[1:]); err != nil { - flags.Init.Usage() - return &errors.FlagsError{} - } - if flags.Init.NFlag() == 0 { - flags.Init.Usage() - return &errors.FlagsError{} + case xflags.Init.Name(): + if err := checkArgs.CheckPerCase(nextArgs[1:], xflags.Init); err != nil { + return err } - flags.initDoer(finalArgs, ep) + xflags.xinit(ep) return nil - case flags.Replace.Name(): - if err := flags.Replace.Parse(nextArgs[1:]); err != nil { - flags.Replace.Usage() - return &errors.FlagsError{} - } - if flags.Replace.NFlag() == 0 { - flags.Replace.Usage() - return &errors.FlagsError{} + case xflags.Replace.Name(): + if err := checkArgs.CheckPerCase(nextArgs[1:], xflags.Replace); err != nil { + return err } - flags.replaceDoer(finalArgs, ep) + xflags.replace(ep) return nil case "": - flags.placementDoer(finalArgs, ep) + xflags.xget(ep) return nil default: return &errors.FlagsError{} diff --git a/src/cmd/tools/m3ctl/main/placements/delete.go b/src/cmd/tools/m3ctl/main/placements/delete.go index a5188b285b..3af922197f 100644 --- a/src/cmd/tools/m3ctl/main/placements/delete.go +++ b/src/cmd/tools/m3ctl/main/placements/delete.go @@ -6,13 +6,13 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" ) -func Delete(flags *PlacementArgs, endpoint string) { - if *flags.deletePlacement { +func (s XPlacementFlags) delete(endpoint string) { + if *s.finalArgs.deletePlacement { url := fmt.Sprintf("%s%s", endpoint, defaultPath) client.DoDelete(url, client.DoDump) return } - url := fmt.Sprintf("%s%s/%s", endpoint, defaultPath, *flags.deleteNode) + url := fmt.Sprintf("%s%s/%s", endpoint, defaultPath, *s.finalArgs.deleteNode) client.DoDelete(url, client.DoDump) return } diff --git a/src/cmd/tools/m3ctl/main/placements/get.go b/src/cmd/tools/m3ctl/main/placements/get.go index cae4018324..f4c925022a 100644 --- a/src/cmd/tools/m3ctl/main/placements/get.go +++ b/src/cmd/tools/m3ctl/main/placements/get.go @@ -6,7 +6,7 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" ) -func Get(flags *PlacementArgs, endpoint string) { +func (s XPlacementFlags) xget(endpoint string) { url := fmt.Sprintf("%s%s", endpoint, defaultPath) client.DoGet(url, client.DoDump) return diff --git a/src/cmd/tools/m3ctl/main/placements/init.go b/src/cmd/tools/m3ctl/main/placements/init.go index 50a5d0ca76..605b8fdebf 100644 --- a/src/cmd/tools/m3ctl/main/placements/init.go +++ b/src/cmd/tools/m3ctl/main/placements/init.go @@ -9,9 +9,9 @@ import ( "github.com/m3db/m3/src/query/generated/proto/admin" ) -func Init(flags *PlacementArgs, endpoint string) { - log.Printf("PlacementArgs:%+v:\n", flags) - data := yaml.Load(flags.initFlag.Value[0], &admin.PlacementInitRequest{}) +func (s XPlacementFlags) xinit(endpoint string) { + log.Printf("PlacementArgs:%+v:\n", s.finalArgs) + data := yaml.Load(s.finalArgs.initFlag.Value[0], &admin.PlacementInitRequest{}) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/init") client.DoPost(url, data, client.DoDump) return diff --git a/src/cmd/tools/m3ctl/main/placements/replace.go b/src/cmd/tools/m3ctl/main/placements/replace.go index 829ce1bb55..d89f071599 100644 --- a/src/cmd/tools/m3ctl/main/placements/replace.go +++ b/src/cmd/tools/m3ctl/main/placements/replace.go @@ -8,8 +8,8 @@ import ( "github.com/m3db/m3/src/query/generated/proto/admin" ) -func Replace(flags *PlacementArgs, endpoint string) { - data := yaml.Load(flags.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}) +func (s XPlacementFlags) replace(endpoint string) { + data := yaml.Load(s.finalArgs.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/replace") client.DoPost(url, data, client.DoDump) return From 8a6a7936c0f373bb9852008383681b71951471c4 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Tue, 28 Jan 2020 20:17:10 -0800 Subject: [PATCH 27/65] better arg handling started and test passes --- src/cmd/tools/m3ctl/main/main.go | 8 +- src/cmd/tools/m3ctl/main/placements/add.go | 6 +- src/cmd/tools/m3ctl/main/placements/cmd.go | 85 ++++++++----------- .../tools/m3ctl/main/placements/cmd_test.go | 52 ++++++------ src/cmd/tools/m3ctl/main/placements/delete.go | 6 +- src/cmd/tools/m3ctl/main/placements/get.go | 2 +- src/cmd/tools/m3ctl/main/placements/init.go | 6 +- .../tools/m3ctl/main/placements/replace.go | 4 +- 8 files changed, 81 insertions(+), 88 deletions(-) diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 462ad01b71..52ec3c7e21 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -49,8 +49,9 @@ func main() { namespaceFlagSets := namespaces.SetupFlags(&namespaceArgs) // the placement-related subcommand - placementArgs := placements.PlacementArgs{} - placementFlagSets := placements.SetupFlags(&placementArgs) + //placementArgs := placements.PlacementArgs{} + //placementFlagSets := placements.SetupFlags(&placementArgs) + placementFlagSets := placements.SetupFlags() flag.Usage = func() { fmt.Fprintf(flag.CommandLine.Output(), ` Usage of %s: @@ -84,7 +85,8 @@ Each subcommand has its own built-in help provided via "-h". case namespaceFlagSets.Namespace.Name(): namespaces.ParseAndDo(&namespaceArgs, &namespaceFlagSets, *endPoint) case placementFlagSets.Placement.Name(): - placementFlagSets.ParseAndDo(flag.Args(), &placementArgs, *endPoint) + //placementFlagSets.ParseAndDo(flag.Args(), &placementArgs, *endPoint) + placementFlagSets.ParseAndDo(flag.Args(), *endPoint) default: flag.Usage() os.Exit(1) diff --git a/src/cmd/tools/m3ctl/main/placements/add.go b/src/cmd/tools/m3ctl/main/placements/add.go index 1419fb542a..fd3b8e1ff5 100644 --- a/src/cmd/tools/m3ctl/main/placements/add.go +++ b/src/cmd/tools/m3ctl/main/placements/add.go @@ -9,9 +9,9 @@ import ( "github.com/m3db/m3/src/query/generated/proto/admin" ) -func (s XPlacementFlags) add(endpoint string) { - log.Printf("PlacementArgs:%+v:\n", s.finalArgs) - data := yaml.Load(s.finalArgs.newNodeFlag.Value[0], &admin.PlacementInitRequest{}) +func xadd(s PlacementArgs, endpoint string) { + log.Printf("PlacementArgs:%+v:\n", s) + data := yaml.Load(s.newNodeFlag.Value[0], &admin.PlacementInitRequest{}) url := fmt.Sprintf("%s%s", endpoint, defaultPath) client.DoPost(url, data, client.DoDump) return diff --git a/src/cmd/tools/m3ctl/main/placements/cmd.go b/src/cmd/tools/m3ctl/main/placements/cmd.go index 7a0dedcc6c..df32452736 100644 --- a/src/cmd/tools/m3ctl/main/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd.go @@ -26,30 +26,37 @@ type XFlagSet struct { Flagset *flag.FlagSet } type XPlacementFlags struct { - //Args *PlacementArgs - finalArgs *PlacementArgs - Globals []string + Args *PlacementArgs + finalArgs placementHandler + //Globals []string Placement *flag.FlagSet Add *flag.FlagSet Delete *flag.FlagSet Init *flag.FlagSet Replace *flag.FlagSet } -//type PlacementFlags struct { -// Placement *flag.FlagSet -// placementDoer func(*PlacementArgs, string) -// Delete *flag.FlagSet -// deleteDoer func(*PlacementArgs, string) -// Add *flag.FlagSet -// addDoer func(*PlacementArgs, string) -// Init *flag.FlagSet -// initDoer func(*PlacementArgs, string) -// Replace *flag.FlagSet -// replaceDoer func(*PlacementArgs, string) -//} - -//func SetupFlags(flags *PlacementArgs) PlacementFlags { -func SetupFlags(finalArgs *PlacementArgs) XPlacementFlags { +type placementHandler struct { + add func(PlacementArgs, string) + delete func(PlacementArgs, string) + xget func(PlacementArgs, string) + xinit func(PlacementArgs, string) + replace func(PlacementArgs, string) +} + +func SetupFlags() XPlacementFlags { + return _setupFlags( + &PlacementArgs{}, + placementHandler{ + add: xadd, + delete: xdelete, + xget: xget, + xinit: xinit, + replace: xreplace, + }, + ) +} +func _setupFlags(finalArgs *PlacementArgs, handler placementHandler) XPlacementFlags { + placementFlags := flag.NewFlagSet("pl", flag.ExitOnError) deleteFlags := flag.NewFlagSet("delete", flag.ExitOnError) addFlags := flag.NewFlagSet("add", flag.ExitOnError) @@ -90,27 +97,13 @@ It has the following subcommands: %s %s -Usage of %s: - -`, placementFlags.Name(), placementFlags.Name(), deleteFlags.Name(), addFlags.Name(), initFlags.Name(), replaceFlags.Name(), placementFlags.Name()) +`, placementFlags.Name(), placementFlags.Name(), deleteFlags.Name(), addFlags.Name(), initFlags.Name(), replaceFlags.Name()) placementFlags.PrintDefaults() } - //return PlacementFlags{ - // Placement: placementFlags, - // placementDoer: Get, - // Delete: deleteFlags, - // deleteDoer: Delete, - // Add: addFlags, - // addDoer: Add, - // Init: initFlags, - // initDoer: Init, - // Replace: replaceFlags, - // replaceDoer: Replace, - //} return XPlacementFlags{ - //Args: nil, - finalArgs: finalArgs, - Globals: nil, + Args: finalArgs, + finalArgs: handler, + //Globals: nil, Placement: placementFlags, Add: addFlags, Delete: deleteFlags, @@ -119,9 +112,8 @@ Usage of %s: } } -func (xflags XPlacementFlags) ParseAndDo(cli []string, args *PlacementArgs, ep string) { - //originalArgs := flag.Args() - // right here args should be like "ns delete -name someName" +func (xflags XPlacementFlags) ParseAndDo(cli []string, ep string) { + // right here args should be like "pl delete -node someName" if len(cli) < 1 { xflags.Placement.Usage() os.Exit(1) @@ -140,40 +132,37 @@ func dispatcher(inArgs []string, xflags XPlacementFlags, ep string) error { return &errors.FlagsError{} } if xflags.Placement.NArg() == 0 { - xflags.xget(ep) + xflags.finalArgs.xget(*xflags.Args, ep) return nil } - //if err := checkArgs.CheckPerCase(inArgs, xflags.Placement); err != nil { - // return err - //} nextArgs := xflags.Placement.Args() switch nextArgs[0] { case xflags.Add.Name(): if err := checkArgs.CheckPerCase(nextArgs[1:], xflags.Add); err != nil { return err } - xflags.add(ep) + xflags.finalArgs.add(*xflags.Args, ep) return nil case xflags.Delete.Name(): if err := checkArgs.CheckPerCase(nextArgs[1:], xflags.Delete); err != nil { return err } - xflags.delete(ep) + xflags.finalArgs.delete(*xflags.Args, ep) return nil case xflags.Init.Name(): if err := checkArgs.CheckPerCase(nextArgs[1:], xflags.Init); err != nil { return err } - xflags.xinit(ep) + xflags.finalArgs.xinit(*xflags.Args, ep) return nil case xflags.Replace.Name(): if err := checkArgs.CheckPerCase(nextArgs[1:], xflags.Replace); err != nil { return err } - xflags.replace(ep) + xflags.finalArgs.replace(*xflags.Args, ep) return nil case "": - xflags.xget(ep) + xflags.finalArgs.xget(*xflags.Args, ep) return nil default: return &errors.FlagsError{} diff --git a/src/cmd/tools/m3ctl/main/placements/cmd_test.go b/src/cmd/tools/m3ctl/main/placements/cmd_test.go index af4674ac13..358cd79dfa 100644 --- a/src/cmd/tools/m3ctl/main/placements/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd_test.go @@ -4,54 +4,56 @@ import ( "testing" ) -func makeStub() (PlacementArgs, PlacementFlags) { - placementArgs := PlacementArgs{} - placementFlagSets := SetupFlags(&placementArgs) - - placementFlagSets.placementDoer = func(*PlacementArgs, string) { return } - placementFlagSets.addDoer = func(*PlacementArgs, string) { return } - placementFlagSets.deleteDoer = func(*PlacementArgs, string) { return } - placementFlagSets.initDoer = func(*PlacementArgs, string) { return } - placementFlagSets.replaceDoer = func(*PlacementArgs, string) { return } - - return placementArgs, placementFlagSets +func stub1(s PlacementArgs, endpoint string) { return } + +func makeStub() XPlacementFlags { + return _setupFlags( + &PlacementArgs{}, + placementHandler{ + add: stub1, + delete: stub1, + xget: stub1, + xinit: stub1, + replace: stub1, + }, + ) } func TestBasic(t *testing.T) { // default is to list placements // so no args is OK - args, flags := makeStub() - if err := parseAndDo([]string{}, &args, &flags, ""); err != nil { + flags := makeStub() + if err := dispatcher([]string{}, flags, "http://localhost:13013"); err != nil { t.Error("It should not return error no args") } - args, flags = makeStub() - if err := parseAndDo([]string{"junk"}, &args, &flags, ""); err == nil { + flags = makeStub() + if err := dispatcher([]string{"junk"}, flags, ""); err == nil { t.Error("It should return an error on junk") } - args, flags = makeStub() - if err := parseAndDo([]string{"delete", "-all"}, &args, &flags, ""); err != nil { + flags = makeStub() + if err := dispatcher([]string{"delete", "-all"},flags, ""); err != nil { t.Error("It should not return error no sane args") } - args, flags = makeStub() - if err := parseAndDo([]string{"delete", "-node", "nodeName"}, &args, &flags, ""); err != nil { + flags = makeStub() + if err := dispatcher([]string{"delete", "-node", "nodeName"}, flags, ""); err != nil { t.Error("It should not return error no sane args") } - args, flags = makeStub() - if err := parseAndDo([]string{"add", "-f", "somefile"}, &args, &flags, ""); err != nil { + flags = makeStub() + if err := dispatcher([]string{"add", "-f", "somefile"}, flags, ""); err != nil { t.Error("It should not return error no sane args") } - args, flags = makeStub() - if err := parseAndDo([]string{"init", "-f", "somefile"}, &args, &flags, ""); err != nil { + flags = makeStub() + if err := dispatcher([]string{"init", "-f", "somefile"}, flags, ""); err != nil { t.Error("It should not return error no sane args") } - args, flags = makeStub() - if err := parseAndDo([]string{"replace", "-f", "somefile"}, &args, &flags, ""); err != nil { + flags = makeStub() + if err := dispatcher([]string{"replace", "-f", "somefile"}, flags, ""); err != nil { t.Error("It should not return error no sane args") } diff --git a/src/cmd/tools/m3ctl/main/placements/delete.go b/src/cmd/tools/m3ctl/main/placements/delete.go index 3af922197f..02c8a5701b 100644 --- a/src/cmd/tools/m3ctl/main/placements/delete.go +++ b/src/cmd/tools/m3ctl/main/placements/delete.go @@ -6,13 +6,13 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" ) -func (s XPlacementFlags) delete(endpoint string) { - if *s.finalArgs.deletePlacement { +func xdelete(s PlacementArgs, endpoint string) { + if *s.deletePlacement { url := fmt.Sprintf("%s%s", endpoint, defaultPath) client.DoDelete(url, client.DoDump) return } - url := fmt.Sprintf("%s%s/%s", endpoint, defaultPath, *s.finalArgs.deleteNode) + url := fmt.Sprintf("%s%s/%s", endpoint, defaultPath, *s.deleteNode) client.DoDelete(url, client.DoDump) return } diff --git a/src/cmd/tools/m3ctl/main/placements/get.go b/src/cmd/tools/m3ctl/main/placements/get.go index f4c925022a..09644ddeaf 100644 --- a/src/cmd/tools/m3ctl/main/placements/get.go +++ b/src/cmd/tools/m3ctl/main/placements/get.go @@ -6,7 +6,7 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" ) -func (s XPlacementFlags) xget(endpoint string) { +func xget(s PlacementArgs, endpoint string) { url := fmt.Sprintf("%s%s", endpoint, defaultPath) client.DoGet(url, client.DoDump) return diff --git a/src/cmd/tools/m3ctl/main/placements/init.go b/src/cmd/tools/m3ctl/main/placements/init.go index 605b8fdebf..ff3d43a8f3 100644 --- a/src/cmd/tools/m3ctl/main/placements/init.go +++ b/src/cmd/tools/m3ctl/main/placements/init.go @@ -9,9 +9,9 @@ import ( "github.com/m3db/m3/src/query/generated/proto/admin" ) -func (s XPlacementFlags) xinit(endpoint string) { - log.Printf("PlacementArgs:%+v:\n", s.finalArgs) - data := yaml.Load(s.finalArgs.initFlag.Value[0], &admin.PlacementInitRequest{}) +func xinit(s PlacementArgs, endpoint string) { + log.Printf("PlacementArgs:%+v:\n", s) + data := yaml.Load(s.initFlag.Value[0], &admin.PlacementInitRequest{}) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/init") client.DoPost(url, data, client.DoDump) return diff --git a/src/cmd/tools/m3ctl/main/placements/replace.go b/src/cmd/tools/m3ctl/main/placements/replace.go index d89f071599..be1fbbbdeb 100644 --- a/src/cmd/tools/m3ctl/main/placements/replace.go +++ b/src/cmd/tools/m3ctl/main/placements/replace.go @@ -8,8 +8,8 @@ import ( "github.com/m3db/m3/src/query/generated/proto/admin" ) -func (s XPlacementFlags) replace(endpoint string) { - data := yaml.Load(s.finalArgs.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}) +func xreplace(s PlacementArgs, endpoint string) { + data := yaml.Load(s.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/replace") client.DoPost(url, data, client.DoDump) return From e7651f59ebb90c36d3abef221f009d7165d86945 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Thu, 30 Jan 2020 10:56:45 -0800 Subject: [PATCH 28/65] make it more test-friendly and make the test less sucky --- src/cmd/tools/m3ctl/main/main.go | 10 +- src/cmd/tools/m3ctl/main/placements/add.go | 4 +- src/cmd/tools/m3ctl/main/placements/cmd.go | 95 +++++++++-------- .../tools/m3ctl/main/placements/cmd_test.go | 100 +++++++++++------- src/cmd/tools/m3ctl/main/placements/delete.go | 2 +- src/cmd/tools/m3ctl/main/placements/get.go | 2 +- src/cmd/tools/m3ctl/main/placements/init.go | 4 +- .../tools/m3ctl/main/placements/replace.go | 2 +- 8 files changed, 125 insertions(+), 94 deletions(-) diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 52ec3c7e21..045491ceb0 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -49,9 +49,7 @@ func main() { namespaceFlagSets := namespaces.SetupFlags(&namespaceArgs) // the placement-related subcommand - //placementArgs := placements.PlacementArgs{} - //placementFlagSets := placements.SetupFlags(&placementArgs) - placementFlagSets := placements.SetupFlags() + placementFlagSets := placements.InitializeFlags() flag.Usage = func() { fmt.Fprintf(flag.CommandLine.Output(), ` Usage of %s: @@ -65,7 +63,6 @@ Usage of %s: Each subcommand has its own built-in help provided via "-h". `, os.Args[0], databaseFlagSets.Database.Name(), - //placementFlagSets.Placement.Name(), placementFlagSets.Placement.Name(), namespaceFlagSets.Namespace.Name()) @@ -85,8 +82,9 @@ Each subcommand has its own built-in help provided via "-h". case namespaceFlagSets.Namespace.Name(): namespaces.ParseAndDo(&namespaceArgs, &namespaceFlagSets, *endPoint) case placementFlagSets.Placement.Name(): - //placementFlagSets.ParseAndDo(flag.Args(), &placementArgs, *endPoint) - placementFlagSets.ParseAndDo(flag.Args(), *endPoint) + if err := placementFlagSets.ParseAndDo(flag.Args(), *endPoint); err != nil { + os.Exit(1) + } default: flag.Usage() os.Exit(1) diff --git a/src/cmd/tools/m3ctl/main/placements/add.go b/src/cmd/tools/m3ctl/main/placements/add.go index fd3b8e1ff5..7534779006 100644 --- a/src/cmd/tools/m3ctl/main/placements/add.go +++ b/src/cmd/tools/m3ctl/main/placements/add.go @@ -9,8 +9,8 @@ import ( "github.com/m3db/m3/src/query/generated/proto/admin" ) -func xadd(s PlacementArgs, endpoint string) { - log.Printf("PlacementArgs:%+v:\n", s) +func xadd(s placementArgs, endpoint string) { + log.Printf("placementArgs:%+v:\n", s) data := yaml.Load(s.newNodeFlag.Value[0], &admin.PlacementInitRequest{}) url := fmt.Sprintf("%s%s", endpoint, defaultPath) client.DoPost(url, data, client.DoDump) diff --git a/src/cmd/tools/m3ctl/main/placements/cmd.go b/src/cmd/tools/m3ctl/main/placements/cmd.go index df32452736..2cf956fe4c 100644 --- a/src/cmd/tools/m3ctl/main/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd.go @@ -14,7 +14,9 @@ const ( defaultPath = "/api/v1/services/m3db/placement" ) -type PlacementArgs struct { +// all the values from the cli args are stored in here +// for all the placement-related commands +type placementArgs struct { deletePlacement *bool deleteNode *string initFlag configflag.FlagStringSlice @@ -22,11 +24,9 @@ type PlacementArgs struct { replaceFlag configflag.FlagStringSlice } -type XFlagSet struct { - Flagset *flag.FlagSet -} -type XPlacementFlags struct { - Args *PlacementArgs +// this has all that the dispatcher needs to parse the cli +type Context struct { + args *placementArgs finalArgs placementHandler //Globals []string Placement *flag.FlagSet @@ -36,16 +36,16 @@ type XPlacementFlags struct { Replace *flag.FlagSet } type placementHandler struct { - add func(PlacementArgs, string) - delete func(PlacementArgs, string) - xget func(PlacementArgs, string) - xinit func(PlacementArgs, string) - replace func(PlacementArgs, string) + add func(placementArgs, string) + delete func(placementArgs, string) + xget func(placementArgs, string) + xinit func(placementArgs, string) + replace func(placementArgs, string) } -func SetupFlags() XPlacementFlags { +func InitializeFlags() Context { return _setupFlags( - &PlacementArgs{}, + &placementArgs{}, placementHandler{ add: xadd, delete: xdelete, @@ -55,7 +55,7 @@ func SetupFlags() XPlacementFlags { }, ) } -func _setupFlags(finalArgs *PlacementArgs, handler placementHandler) XPlacementFlags { +func _setupFlags(finalArgs *placementArgs, handler placementHandler) Context { placementFlags := flag.NewFlagSet("pl", flag.ExitOnError) deleteFlags := flag.NewFlagSet("delete", flag.ExitOnError) @@ -100,8 +100,8 @@ It has the following subcommands: `, placementFlags.Name(), placementFlags.Name(), deleteFlags.Name(), addFlags.Name(), initFlags.Name(), replaceFlags.Name()) placementFlags.PrintDefaults() } - return XPlacementFlags{ - Args: finalArgs, + return Context{ + args: finalArgs, finalArgs: handler, //Globals: nil, Placement: placementFlags, @@ -112,57 +112,62 @@ It has the following subcommands: } } -func (xflags XPlacementFlags) ParseAndDo(cli []string, ep string) { +func (ctx Context) ParseAndDo(cli []string, ep string) error { // right here args should be like "pl delete -node someName" if len(cli) < 1 { - xflags.Placement.Usage() - os.Exit(1) + ctx.Placement.Usage() + return &errors.FlagsError{} + } + + inArgs := cli[1:] + if err := ctx.Placement.Parse(inArgs); err != nil { + ctx.Placement.Usage() + return &errors.FlagsError{} + } + if ctx.Placement.NArg() == 0 { + ctx.finalArgs.xget(*ctx.args, ep) + return nil } - // pop and parse - if err := dispatcher(cli[1:], xflags, ep); err != nil { + + // pop and dispatch + if err := dispatcher(ctx, ep); err != nil { fmt.Fprintf(os.Stderr, err.Error()) - os.Exit(1) + return err } + return nil + } -func dispatcher(inArgs []string, xflags XPlacementFlags, ep string) error { - if err := xflags.Placement.Parse(inArgs); err != nil { - xflags.Placement.Usage() - return &errors.FlagsError{} - } - if xflags.Placement.NArg() == 0 { - xflags.finalArgs.xget(*xflags.Args, ep) - return nil - } - nextArgs := xflags.Placement.Args() +func dispatcher(ctx Context, ep string) error { + nextArgs := ctx.Placement.Args() switch nextArgs[0] { - case xflags.Add.Name(): - if err := checkArgs.CheckPerCase(nextArgs[1:], xflags.Add); err != nil { + case ctx.Add.Name(): + if err := checkArgs.CheckPerCase(nextArgs[1:], ctx.Add); err != nil { return err } - xflags.finalArgs.add(*xflags.Args, ep) + ctx.finalArgs.add(*ctx.args, ep) return nil - case xflags.Delete.Name(): - if err := checkArgs.CheckPerCase(nextArgs[1:], xflags.Delete); err != nil { + case ctx.Delete.Name(): + if err := checkArgs.CheckPerCase(nextArgs[1:], ctx.Delete); err != nil { return err } - xflags.finalArgs.delete(*xflags.Args, ep) + ctx.finalArgs.delete(*ctx.args, ep) return nil - case xflags.Init.Name(): - if err := checkArgs.CheckPerCase(nextArgs[1:], xflags.Init); err != nil { + case ctx.Init.Name(): + if err := checkArgs.CheckPerCase(nextArgs[1:], ctx.Init); err != nil { return err } - xflags.finalArgs.xinit(*xflags.Args, ep) + ctx.finalArgs.xinit(*ctx.args, ep) return nil - case xflags.Replace.Name(): - if err := checkArgs.CheckPerCase(nextArgs[1:], xflags.Replace); err != nil { + case ctx.Replace.Name(): + if err := checkArgs.CheckPerCase(nextArgs[1:], ctx.Replace); err != nil { return err } - xflags.finalArgs.replace(*xflags.Args, ep) + ctx.finalArgs.replace(*ctx.args, ep) return nil case "": - xflags.finalArgs.xget(*xflags.Args, ep) + ctx.finalArgs.xget(*ctx.args, ep) return nil default: return &errors.FlagsError{} diff --git a/src/cmd/tools/m3ctl/main/placements/cmd_test.go b/src/cmd/tools/m3ctl/main/placements/cmd_test.go index 358cd79dfa..0bae5a2b5c 100644 --- a/src/cmd/tools/m3ctl/main/placements/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd_test.go @@ -4,11 +4,11 @@ import ( "testing" ) -func stub1(s PlacementArgs, endpoint string) { return } +func stub1(placementArgs, string) { return } -func makeStub() XPlacementFlags { +func makeStub() Context { return _setupFlags( - &PlacementArgs{}, + &placementArgs{}, placementHandler{ add: stub1, delete: stub1, @@ -20,41 +20,69 @@ func makeStub() XPlacementFlags { } func TestBasic(t *testing.T) { - // default is to list placements - // so no args is OK - flags := makeStub() - if err := dispatcher([]string{}, flags, "http://localhost:13013"); err != nil { - t.Error("It should not return error no args") - } - - flags = makeStub() - if err := dispatcher([]string{"junk"}, flags, ""); err == nil { - t.Error("It should return an error on junk") - } - - flags = makeStub() - if err := dispatcher([]string{"delete", "-all"},flags, ""); err != nil { - t.Error("It should not return error no sane args") - } - - flags = makeStub() - if err := dispatcher([]string{"delete", "-node", "nodeName"}, flags, ""); err != nil { - t.Error("It should not return error no sane args") - } - - flags = makeStub() - if err := dispatcher([]string{"add", "-f", "somefile"}, flags, ""); err != nil { - t.Error("It should not return error no sane args") - } - - flags = makeStub() - if err := dispatcher([]string{"init", "-f", "somefile"}, flags, ""); err != nil { - t.Error("It should not return error no sane args") + testData := []struct { + args []string + ep string + msg string + successCondition func(error) bool + }{ + { + // no args not even pl + args: []string{}, + ep: "", + msg: "It should return error because we got here without pl", + successCondition: func(err error) bool {return err != nil}, + }, + { + // no args except pl + args: []string{"pl"}, + ep: "", + msg: "It should not return error no args", + successCondition: func(err error) bool {return err == nil}, + }, + { + args: []string{"pl", "junk"}, + ep: "", + msg: "It should return error when given junk", + successCondition: func(err error) bool {return err != nil}, + }, + { + args: []string{"pl", "delete", "-all"}, + ep: "", + msg: "It should not return error on sane delete all args", + successCondition: func(err error) bool {return err == nil}, + }, + { + args: []string{"pl", "delete", "-node", "nodeName"}, + ep: "", + msg: "It should not return error on sane delete args", + successCondition: func(err error) bool {return err == nil}, + }, + { + args: []string{"pl", "add", "-f", "someFile"}, + ep: "", + msg: "It should not return error on sane add args", + successCondition: func(err error) bool {return err == nil}, + }, + { + args: []string{"pl", "init", "-f", "someFile"}, + ep: "", + msg: "It should not return error on sane init args", + successCondition: func(err error) bool {return err == nil}, + }, + { + args: []string{"pl", "replace", "-f", "someFile"}, + ep: "", + msg: "It should not return error on sane replace args", + successCondition: func(err error) bool {return err == nil}, + }, } - flags = makeStub() - if err := dispatcher([]string{"replace", "-f", "somefile"}, flags, ""); err != nil { - t.Error("It should not return error no sane args") + for _, v := range testData { + ctx := makeStub() + if ! v.successCondition(ctx.ParseAndDo(v.args, v.ep)) { + t.Error(v.msg) + } } } diff --git a/src/cmd/tools/m3ctl/main/placements/delete.go b/src/cmd/tools/m3ctl/main/placements/delete.go index 02c8a5701b..11069c8b97 100644 --- a/src/cmd/tools/m3ctl/main/placements/delete.go +++ b/src/cmd/tools/m3ctl/main/placements/delete.go @@ -6,7 +6,7 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" ) -func xdelete(s PlacementArgs, endpoint string) { +func xdelete(s placementArgs, endpoint string) { if *s.deletePlacement { url := fmt.Sprintf("%s%s", endpoint, defaultPath) client.DoDelete(url, client.DoDump) diff --git a/src/cmd/tools/m3ctl/main/placements/get.go b/src/cmd/tools/m3ctl/main/placements/get.go index 09644ddeaf..11cdcd99ad 100644 --- a/src/cmd/tools/m3ctl/main/placements/get.go +++ b/src/cmd/tools/m3ctl/main/placements/get.go @@ -6,7 +6,7 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" ) -func xget(s PlacementArgs, endpoint string) { +func xget(s placementArgs, endpoint string) { url := fmt.Sprintf("%s%s", endpoint, defaultPath) client.DoGet(url, client.DoDump) return diff --git a/src/cmd/tools/m3ctl/main/placements/init.go b/src/cmd/tools/m3ctl/main/placements/init.go index ff3d43a8f3..853da95c0a 100644 --- a/src/cmd/tools/m3ctl/main/placements/init.go +++ b/src/cmd/tools/m3ctl/main/placements/init.go @@ -9,8 +9,8 @@ import ( "github.com/m3db/m3/src/query/generated/proto/admin" ) -func xinit(s PlacementArgs, endpoint string) { - log.Printf("PlacementArgs:%+v:\n", s) +func xinit(s placementArgs, endpoint string) { + log.Printf("placementArgs:%+v:\n", s) data := yaml.Load(s.initFlag.Value[0], &admin.PlacementInitRequest{}) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/init") client.DoPost(url, data, client.DoDump) diff --git a/src/cmd/tools/m3ctl/main/placements/replace.go b/src/cmd/tools/m3ctl/main/placements/replace.go index be1fbbbdeb..9e267c2852 100644 --- a/src/cmd/tools/m3ctl/main/placements/replace.go +++ b/src/cmd/tools/m3ctl/main/placements/replace.go @@ -8,7 +8,7 @@ import ( "github.com/m3db/m3/src/query/generated/proto/admin" ) -func xreplace(s PlacementArgs, endpoint string) { +func xreplace(s placementArgs, endpoint string) { data := yaml.Load(s.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/replace") client.DoPost(url, data, client.DoDump) From becd2237d7b44c8760e46289da24cce52f19b840 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Thu, 30 Jan 2020 20:32:32 -0800 Subject: [PATCH 29/65] rename some items --- src/cmd/tools/m3ctl/main/client/http.go | 2 +- src/cmd/tools/m3ctl/main/database/create.go | 2 +- src/cmd/tools/m3ctl/main/namespaces/delete.go | 2 +- src/cmd/tools/m3ctl/main/namespaces/show.go | 2 +- src/cmd/tools/m3ctl/main/placements/add.go | 4 +-- src/cmd/tools/m3ctl/main/placements/cmd.go | 30 +++++++++---------- src/cmd/tools/m3ctl/main/placements/delete.go | 6 ++-- src/cmd/tools/m3ctl/main/placements/get.go | 4 +-- src/cmd/tools/m3ctl/main/placements/init.go | 4 +-- .../tools/m3ctl/main/placements/replace.go | 4 +-- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/cmd/tools/m3ctl/main/client/http.go b/src/cmd/tools/m3ctl/main/client/http.go index 7a642e64cd..666db698c0 100644 --- a/src/cmd/tools/m3ctl/main/client/http.go +++ b/src/cmd/tools/m3ctl/main/client/http.go @@ -67,7 +67,7 @@ func DoDelete(url string, getter func(reader io.Reader)) { getter(resp.Body) } -func DoDump(in io.Reader) { +func Dumper(in io.Reader) { dat, err := ioutil.ReadAll(in) if err != nil { log.Fatal(err) diff --git a/src/cmd/tools/m3ctl/main/database/create.go b/src/cmd/tools/m3ctl/main/database/create.go index b71ece2171..b63c427056 100644 --- a/src/cmd/tools/m3ctl/main/database/create.go +++ b/src/cmd/tools/m3ctl/main/database/create.go @@ -13,6 +13,6 @@ func Create(createYAML string, endpoint string) { log.Printf("createYAML:%s:\n", createYAML) data := yaml.Load(createYAML, &admin.DatabaseCreateRequest{}) url := fmt.Sprintf("%s%s/create", endpoint, defaultPath) - client.DoPost(url, data, client.DoDump) + client.DoPost(url, data, client.Dumper) return } diff --git a/src/cmd/tools/m3ctl/main/namespaces/delete.go b/src/cmd/tools/m3ctl/main/namespaces/delete.go index 3ab4b0a148..737386a35a 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/delete.go +++ b/src/cmd/tools/m3ctl/main/namespaces/delete.go @@ -8,5 +8,5 @@ import ( func Delete(flags *NamespaceArgs, endpoint string) { url := fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", *flags.delete) - client.DoDelete(url, client.DoDump) + client.DoDelete(url, client.Dumper) } diff --git a/src/cmd/tools/m3ctl/main/namespaces/show.go b/src/cmd/tools/m3ctl/main/namespaces/show.go index 8a40107b7a..a247d1ee85 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/show.go +++ b/src/cmd/tools/m3ctl/main/namespaces/show.go @@ -14,7 +14,7 @@ import ( func Show(flags *NamespaceArgs, endpoint string) { url := fmt.Sprintf("%s%s?%s", endpoint, defaultPath, debugQS) if *flags.showAll { - client.DoGet(url, client.DoDump) + client.DoGet(url, client.Dumper) } else { client.DoGet(url, showNames) } diff --git a/src/cmd/tools/m3ctl/main/placements/add.go b/src/cmd/tools/m3ctl/main/placements/add.go index 7534779006..d30ba344d3 100644 --- a/src/cmd/tools/m3ctl/main/placements/add.go +++ b/src/cmd/tools/m3ctl/main/placements/add.go @@ -9,10 +9,10 @@ import ( "github.com/m3db/m3/src/query/generated/proto/admin" ) -func xadd(s placementArgs, endpoint string) { +func doAdd(s placementArgs, endpoint string) { log.Printf("placementArgs:%+v:\n", s) data := yaml.Load(s.newNodeFlag.Value[0], &admin.PlacementInitRequest{}) url := fmt.Sprintf("%s%s", endpoint, defaultPath) - client.DoPost(url, data, client.DoDump) + client.DoPost(url, data, client.Dumper) return } diff --git a/src/cmd/tools/m3ctl/main/placements/cmd.go b/src/cmd/tools/m3ctl/main/placements/cmd.go index 2cf956fe4c..10dd65fabb 100644 --- a/src/cmd/tools/m3ctl/main/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd.go @@ -26,8 +26,8 @@ type placementArgs struct { // this has all that the dispatcher needs to parse the cli type Context struct { - args *placementArgs - finalArgs placementHandler + vals *placementArgs + handlers placementHandler //Globals []string Placement *flag.FlagSet Add *flag.FlagSet @@ -47,11 +47,11 @@ func InitializeFlags() Context { return _setupFlags( &placementArgs{}, placementHandler{ - add: xadd, - delete: xdelete, - xget: xget, - xinit: xinit, - replace: xreplace, + add: doAdd, + delete: doDelete, + xget: doGet, + xinit: doInit, + replace: doReplace, }, ) } @@ -101,8 +101,8 @@ It has the following subcommands: placementFlags.PrintDefaults() } return Context{ - args: finalArgs, - finalArgs: handler, + vals: finalArgs, + handlers: handler, //Globals: nil, Placement: placementFlags, Add: addFlags, @@ -125,7 +125,7 @@ func (ctx Context) ParseAndDo(cli []string, ep string) error { return &errors.FlagsError{} } if ctx.Placement.NArg() == 0 { - ctx.finalArgs.xget(*ctx.args, ep) + ctx.handlers.xget(*ctx.vals, ep) return nil } @@ -146,28 +146,28 @@ func dispatcher(ctx Context, ep string) error { if err := checkArgs.CheckPerCase(nextArgs[1:], ctx.Add); err != nil { return err } - ctx.finalArgs.add(*ctx.args, ep) + ctx.handlers.add(*ctx.vals, ep) return nil case ctx.Delete.Name(): if err := checkArgs.CheckPerCase(nextArgs[1:], ctx.Delete); err != nil { return err } - ctx.finalArgs.delete(*ctx.args, ep) + ctx.handlers.delete(*ctx.vals, ep) return nil case ctx.Init.Name(): if err := checkArgs.CheckPerCase(nextArgs[1:], ctx.Init); err != nil { return err } - ctx.finalArgs.xinit(*ctx.args, ep) + ctx.handlers.xinit(*ctx.vals, ep) return nil case ctx.Replace.Name(): if err := checkArgs.CheckPerCase(nextArgs[1:], ctx.Replace); err != nil { return err } - ctx.finalArgs.replace(*ctx.args, ep) + ctx.handlers.replace(*ctx.vals, ep) return nil case "": - ctx.finalArgs.xget(*ctx.args, ep) + ctx.handlers.xget(*ctx.vals, ep) return nil default: return &errors.FlagsError{} diff --git a/src/cmd/tools/m3ctl/main/placements/delete.go b/src/cmd/tools/m3ctl/main/placements/delete.go index 11069c8b97..6a790eff39 100644 --- a/src/cmd/tools/m3ctl/main/placements/delete.go +++ b/src/cmd/tools/m3ctl/main/placements/delete.go @@ -6,13 +6,13 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" ) -func xdelete(s placementArgs, endpoint string) { +func doDelete(s placementArgs, endpoint string) { if *s.deletePlacement { url := fmt.Sprintf("%s%s", endpoint, defaultPath) - client.DoDelete(url, client.DoDump) + client.DoDelete(url, client.Dumper) return } url := fmt.Sprintf("%s%s/%s", endpoint, defaultPath, *s.deleteNode) - client.DoDelete(url, client.DoDump) + client.DoDelete(url, client.Dumper) return } diff --git a/src/cmd/tools/m3ctl/main/placements/get.go b/src/cmd/tools/m3ctl/main/placements/get.go index 11cdcd99ad..66e553ffa9 100644 --- a/src/cmd/tools/m3ctl/main/placements/get.go +++ b/src/cmd/tools/m3ctl/main/placements/get.go @@ -6,8 +6,8 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" ) -func xget(s placementArgs, endpoint string) { +func doGet(s placementArgs, endpoint string) { url := fmt.Sprintf("%s%s", endpoint, defaultPath) - client.DoGet(url, client.DoDump) + client.DoGet(url, client.Dumper) return } diff --git a/src/cmd/tools/m3ctl/main/placements/init.go b/src/cmd/tools/m3ctl/main/placements/init.go index 853da95c0a..3739dabf0b 100644 --- a/src/cmd/tools/m3ctl/main/placements/init.go +++ b/src/cmd/tools/m3ctl/main/placements/init.go @@ -9,10 +9,10 @@ import ( "github.com/m3db/m3/src/query/generated/proto/admin" ) -func xinit(s placementArgs, endpoint string) { +func doInit(s placementArgs, endpoint string) { log.Printf("placementArgs:%+v:\n", s) data := yaml.Load(s.initFlag.Value[0], &admin.PlacementInitRequest{}) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/init") - client.DoPost(url, data, client.DoDump) + client.DoPost(url, data, client.Dumper) return } diff --git a/src/cmd/tools/m3ctl/main/placements/replace.go b/src/cmd/tools/m3ctl/main/placements/replace.go index 9e267c2852..d1dfadc0ba 100644 --- a/src/cmd/tools/m3ctl/main/placements/replace.go +++ b/src/cmd/tools/m3ctl/main/placements/replace.go @@ -8,9 +8,9 @@ import ( "github.com/m3db/m3/src/query/generated/proto/admin" ) -func xreplace(s placementArgs, endpoint string) { +func doReplace(s placementArgs, endpoint string) { data := yaml.Load(s.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}) url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/replace") - client.DoPost(url, data, client.DoDump) + client.DoPost(url, data, client.Dumper) return } From 0fc035f06cdf6693c219bcca3a77160fbd921259 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sat, 1 Feb 2020 11:47:50 -0800 Subject: [PATCH 30/65] checkpoint --- .../{perCase.go => popParseCheck.go} | 6 +- src/cmd/tools/m3ctl/main/get/cmd.go | 128 ++++++++++++++++ .../tools/m3ctl/main/get/placements/cmd.go | 142 ++++++++++++++++++ .../tools/m3ctl/main/get/placements/get.go | 14 ++ src/cmd/tools/m3ctl/main/main.go | 22 ++- src/cmd/tools/m3ctl/main/placements/add.go | 2 +- src/cmd/tools/m3ctl/main/placements/cmd.go | 25 ++- .../tools/m3ctl/main/placements/cmd_test.go | 2 +- .../tools/m3ctl/main/placements/constants.go | 6 + src/cmd/tools/m3ctl/main/placements/delete.go | 4 +- src/cmd/tools/m3ctl/main/placements/get.go | 2 +- src/cmd/tools/m3ctl/main/placements/init.go | 2 +- .../tools/m3ctl/main/placements/replace.go | 2 +- 13 files changed, 328 insertions(+), 29 deletions(-) rename src/cmd/tools/m3ctl/main/checkArgs/{perCase.go => popParseCheck.go} (60%) create mode 100644 src/cmd/tools/m3ctl/main/get/cmd.go create mode 100644 src/cmd/tools/m3ctl/main/get/placements/cmd.go create mode 100644 src/cmd/tools/m3ctl/main/get/placements/get.go create mode 100644 src/cmd/tools/m3ctl/main/placements/constants.go diff --git a/src/cmd/tools/m3ctl/main/checkArgs/perCase.go b/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go similarity index 60% rename from src/cmd/tools/m3ctl/main/checkArgs/perCase.go rename to src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go index ed99cf2b78..bbec4c8f7a 100644 --- a/src/cmd/tools/m3ctl/main/checkArgs/perCase.go +++ b/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go @@ -5,8 +5,10 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" ) -func CheckPerCase(args []string, fs *flag.FlagSet) *errors.FlagsError { - if err := fs.Parse(args); err != nil { +func PopParseAndCheck(args []string, fs *flag.FlagSet) *errors.FlagsError { + + thisArgs := args[1:] + if err := fs.Parse(thisArgs); err != nil { fs.Usage() return &errors.FlagsError{} } diff --git a/src/cmd/tools/m3ctl/main/get/cmd.go b/src/cmd/tools/m3ctl/main/get/cmd.go new file mode 100644 index 0000000000..6a7e27238f --- /dev/null +++ b/src/cmd/tools/m3ctl/main/get/cmd.go @@ -0,0 +1,128 @@ +package get + +import ( + "flag" + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/get/placements" + + //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" + "os" + + //"github.com/m3db/m3/src/x/config/configflag" +) + +// all the values from the cli args are stored in here +// for all the placement-related commands +//type getArgs struct { +// deletePlacement *bool +// deleteNode *string +// initFlag configflag.FlagStringSlice +// newNodeFlag configflag.FlagStringSlice +// replaceFlag configflag.FlagStringSlice +//} + +type GlobalOpts struct { + Get placements.Globals +} +// this has all that the upper level needs to dispatch to here +type Context struct { + //vals *placementArgs + //handlers placementHandler + GlobalOpts + Get *flag.FlagSet + //Add *flag.FlagSet + //Delete *flag.FlagSet + //Init *flag.FlagSet + //Replace *flag.FlagSet +} +//type placementHandler struct { +// add func(placementArgs, string) +// delete func(placementArgs, string) +// xget func(placementArgs, string) +// xinit func(placementArgs, string) +// replace func(placementArgs, string) +//} + +// setup hooks and context for this level +// everything needed to prep for this get command leve +// nothing that's needed below it +// just the stuff for parsing at the get level +func InitializeFlags() Context { + //return _setupFlags( + //&placementArgs{}, + //placementHandler{ + // add: doAdd, + // delete: doDelete, + // xget: doGet, + // xinit: doInit, + // replace: doReplace, + // }, + //) + + return _setupFlags() +} +func _setupFlags() Context { + + getFlags := flag.NewFlagSet("get", flag.ExitOnError) + getFlags.Usage = func() { + fmt.Fprintf(os.Stderr, "help msg here\n") + getFlags.PrintDefaults() + } + + return Context{Get:getFlags} +} + +// parse this level +// get hooks for the next level +// dispatch +func (ctx Context) PopParseDispatch(cli []string) error { + + thisFlagset := ctx.Get + // right here args should be like "get ns -all" + if len(cli) < 1 { + thisFlagset.Usage() + return &errors.FlagsError{} + } + + // pop and parse + inArgs := cli[1:] + if err := thisFlagset.Parse(inArgs); err != nil { + thisFlagset.Usage() + return &errors.FlagsError{} + } + if thisFlagset.NArg() == 0 { + //ctx.handlers.xget(*ctx.vals, ep) + thisFlagset.Usage() + //fmt.Print("stub get default action or error whatever is appropriate\n") + return &errors.FlagsError{} + } + + // contexts for next level + //plctx := placements.InitializeFlags() + plctx := placements.InitializeFlags() + + nextArgs := thisFlagset.Args() + fmt.Print(nextArgs) + switch nextArgs[0] { + case plctx.Placement.Name(): + fmt.Print("pl case") + plctx.Globals = ctx.GlobalOpts.Get + if err := plctx.PopParseDispatch(nextArgs); err != nil { + return err + } + //case plctx.Placement.Name(): + // fmt.Print("pl case") + // if err := plctx.PopParseDispatch(nextArgs, "fake endpoint"); err != nil { + // return err + // } + default: + fmt.Print("default case") + thisFlagset.Usage() + return &errors.FlagsError{} + } + + fmt.Print("done with case") + return nil + +} \ No newline at end of file diff --git a/src/cmd/tools/m3ctl/main/get/placements/cmd.go b/src/cmd/tools/m3ctl/main/get/placements/cmd.go new file mode 100644 index 0000000000..2d260396ff --- /dev/null +++ b/src/cmd/tools/m3ctl/main/get/placements/cmd.go @@ -0,0 +1,142 @@ +package placements + +import ( + "flag" + "fmt" + "go.uber.org/zap" + + //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" + "os" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" + //"github.com/m3db/m3/src/x/config/configflag" +) + +//const ( +// defaultPath = "/api/v1/services/m3db/placement" +//) + +// all the values from the cli args are stored in here +// for all the placement-related commands +type placementArgs struct { + //deletePlacement *bool + //deleteNode *string + //initFlag configflag.FlagStringSlice + //newNodeFlag configflag.FlagStringSlice + //replaceFlag configflag.FlagStringSlice +} + +type Globals struct { +Endpoint string +zap *zap.SugaredLogger +} + +// this has all that the dispatcher needs to parse the cli +type Context struct { + vals *placementArgs + handlers placementHandlers + Globals struct { + Endpoint string + zap *zap.SugaredLogger + } + Placement *flag.FlagSet + //Add *flag.FlagSet + //Delete *flag.FlagSet + //Init *flag.FlagSet + //Replace *flag.FlagSet +} +type placementHandlers struct { + xget func(*placementArgs, Globals) +} + +// everything needed to prep for this pl command level +// nothing that's needed below it +// just the stuff for parsing at the pl level +func InitializeFlags() Context { + return _setupFlags( + &placementArgs{}, + placementHandlers{ + //add: doAdd, + //delete: doDelete, + //xget: func(c *placementArgs, s string) {fmt.Print("deeper fake pl get handler")}, + xget: doGet, + //xget: placements., + //xinit: doInit, + //replace: doReplace, + }, + ) +} +func _setupFlags(finalArgs *placementArgs, handler placementHandlers) Context { + + placementFlags := flag.NewFlagSet("pl", flag.ExitOnError) + //deleteFlags := flag.NewFlagSet("delete", flag.ExitOnError) + //addFlags := flag.NewFlagSet("add", flag.ExitOnError) + //initFlags := flag.NewFlagSet("init", flag.ExitOnError) + //replaceFlags := flag.NewFlagSet("replace", flag.ExitOnError) + + //finalArgs.deletePlacement = deleteFlags.Bool("all", false, "delete the entire placement") + //finalArgs.deleteNode = deleteFlags.String("node", "", "delete the specified node in the placement") + //initFlags.Var(&finalArgs.initFlag, "f", "initialize a placement. Specify a yaml file.") + //addFlags.Var(&finalArgs.newNodeFlag, "f", "add a new node to the placement. Specify the filename of the yaml.") + //replaceFlags.Var(&finalArgs.replaceFlag, "f", "add a new node to the placement. Specify the filename of the yaml.") + placementFlags.Usage = func() { + fmt.Fprintf(os.Stderr, ` +"%s" is for acting on placements. + +Description: + +Default behaviour (no arguments) is to provide a json dump of the existing placement. + + +`, placementFlags.Name()) + placementFlags.PrintDefaults() + } + return Context{ + vals: finalArgs, + handlers: handler, + //GlobalOpts: nil, + Placement: placementFlags, + //Add: addFlags, + //Delete: deleteFlags, + //Init: initFlags, + //Replace: replaceFlags, + } +} + +func (ctx Context) PopParseDispatch(cli []string) error { + // right here args should be like "pl delete -node someName" + if len(cli) < 1 { + ctx.Placement.Usage() + return &errors.FlagsError{} + } + + inArgs := cli[1:] + if err := ctx.Placement.Parse(inArgs); err != nil { + ctx.Placement.Usage() + return &errors.FlagsError{} + } + if ctx.Placement.NArg() == 0 { + ctx.handlers.xget(ctx.vals, ctx.Globals) + return nil + } + + if err := dispatcher(ctx); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + return err + } + + return nil + +} + +func dispatcher(ctx Context) error { + nextArgs := ctx.Placement.Args() + switch nextArgs[0] { + case "": + ctx.handlers.xget(ctx.vals, ctx.Globals) + return nil + default: + return &errors.FlagsError{} + } + +} diff --git a/src/cmd/tools/m3ctl/main/get/placements/get.go b/src/cmd/tools/m3ctl/main/get/placements/get.go new file mode 100644 index 0000000000..97fe4527c8 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/get/placements/get.go @@ -0,0 +1,14 @@ +package placements + +import ( + "fmt" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" + common "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" +) + +func doGet(s *placementArgs, globals Globals) { + url := fmt.Sprintf("%s%s", globals.Endpoint, common.DefaultPath) + client.DoGet(url, client.Dumper) + return +} diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 045491ceb0..f92a03ca99 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -23,11 +23,11 @@ package main import ( "flag" "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/get" "os" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/database" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/namespaces" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" "github.com/m3db/m3/src/x/config/configflag" ) @@ -40,6 +40,7 @@ func main() { // top-level option endPoint := flag.String("endpoint", defaultEndpoint, "The url for target m3db backend.") + // hooks and context for the next level // the database-related subcommand createDatabaseYAML := configflag.FlagStringSlice{} databaseFlagSets := database.SetupFlags(&createDatabaseYAML) @@ -48,8 +49,9 @@ func main() { namespaceArgs := namespaces.NamespaceArgs{} namespaceFlagSets := namespaces.SetupFlags(&namespaceArgs) - // the placement-related subcommand - placementFlagSets := placements.InitializeFlags() + //placementFlagSets := placements.InitializeFlags() + getFlagSets := get.InitializeFlags() + flag.Usage = func() { fmt.Fprintf(flag.CommandLine.Output(), ` Usage of %s: @@ -63,12 +65,14 @@ Usage of %s: Each subcommand has its own built-in help provided via "-h". `, os.Args[0], databaseFlagSets.Database.Name(), - placementFlagSets.Placement.Name(), + //placementFlagSets.Placement.Name(), + "was pl", namespaceFlagSets.Namespace.Name()) flag.PrintDefaults() } + // parse this level flag.Parse() if len(os.Args) < 2 { @@ -76,13 +80,19 @@ Each subcommand has its own built-in help provided via "-h". os.Exit(1) } + // dispatch to the next level switch flag.Arg(0) { case databaseFlagSets.Database.Name(): database.ParseAndDo(&createDatabaseYAML, &databaseFlagSets, *endPoint) case namespaceFlagSets.Namespace.Name(): namespaces.ParseAndDo(&namespaceArgs, &namespaceFlagSets, *endPoint) - case placementFlagSets.Placement.Name(): - if err := placementFlagSets.ParseAndDo(flag.Args(), *endPoint); err != nil { + //case placementFlagSets.Placement.Name(): + // if err := placementFlagSets.PopParseDispatch(flag.Args(), *endPoint); err != nil { + // os.Exit(1) + // } + case getFlagSets.Get.Name(): + getFlagSets.GlobalOpts.Get.Endpoint = *endPoint + if err := getFlagSets.PopParseDispatch(flag.Args()); err != nil { os.Exit(1) } default: diff --git a/src/cmd/tools/m3ctl/main/placements/add.go b/src/cmd/tools/m3ctl/main/placements/add.go index d30ba344d3..c77418fbaa 100644 --- a/src/cmd/tools/m3ctl/main/placements/add.go +++ b/src/cmd/tools/m3ctl/main/placements/add.go @@ -12,7 +12,7 @@ import ( func doAdd(s placementArgs, endpoint string) { log.Printf("placementArgs:%+v:\n", s) data := yaml.Load(s.newNodeFlag.Value[0], &admin.PlacementInitRequest{}) - url := fmt.Sprintf("%s%s", endpoint, defaultPath) + url := fmt.Sprintf("%s%s", endpoint, DefaultPath) client.DoPost(url, data, client.Dumper) return } diff --git a/src/cmd/tools/m3ctl/main/placements/cmd.go b/src/cmd/tools/m3ctl/main/placements/cmd.go index 10dd65fabb..bebdb27b66 100644 --- a/src/cmd/tools/m3ctl/main/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd.go @@ -10,10 +10,6 @@ import ( "github.com/m3db/m3/src/x/config/configflag" ) -const ( - defaultPath = "/api/v1/services/m3db/placement" -) - // all the values from the cli args are stored in here // for all the placement-related commands type placementArgs struct { @@ -28,7 +24,7 @@ type placementArgs struct { type Context struct { vals *placementArgs handlers placementHandler - //Globals []string + //GlobalOpts []string Placement *flag.FlagSet Add *flag.FlagSet Delete *flag.FlagSet @@ -103,7 +99,7 @@ It has the following subcommands: return Context{ vals: finalArgs, handlers: handler, - //Globals: nil, + //GlobalOpts: nil, Placement: placementFlags, Add: addFlags, Delete: deleteFlags, @@ -112,13 +108,15 @@ It has the following subcommands: } } -func (ctx Context) ParseAndDo(cli []string, ep string) error { +func (ctx Context) PopParseAndDo(cli []string, ep string) error { + fmt.Printf("pl parse and do:args:%v:\n", cli) // right here args should be like "pl delete -node someName" if len(cli) < 1 { ctx.Placement.Usage() return &errors.FlagsError{} } + // pop and parse inArgs := cli[1:] if err := ctx.Placement.Parse(inArgs); err != nil { ctx.Placement.Usage() @@ -129,7 +127,6 @@ func (ctx Context) ParseAndDo(cli []string, ep string) error { return nil } - // pop and dispatch if err := dispatcher(ctx, ep); err != nil { fmt.Fprintf(os.Stderr, err.Error()) return err @@ -140,28 +137,28 @@ func (ctx Context) ParseAndDo(cli []string, ep string) error { } func dispatcher(ctx Context, ep string) error { - nextArgs := ctx.Placement.Args() - switch nextArgs[0] { + thisArgs := ctx.Placement.Args() + switch thisArgs[0] { case ctx.Add.Name(): - if err := checkArgs.CheckPerCase(nextArgs[1:], ctx.Add); err != nil { + if err := checkArgs.PopParseAndCheck(thisArgs, ctx.Add); err != nil { return err } ctx.handlers.add(*ctx.vals, ep) return nil case ctx.Delete.Name(): - if err := checkArgs.CheckPerCase(nextArgs[1:], ctx.Delete); err != nil { + if err := checkArgs.PopParseAndCheck(thisArgs, ctx.Delete); err != nil { return err } ctx.handlers.delete(*ctx.vals, ep) return nil case ctx.Init.Name(): - if err := checkArgs.CheckPerCase(nextArgs[1:], ctx.Init); err != nil { + if err := checkArgs.PopParseAndCheck(thisArgs, ctx.Init); err != nil { return err } ctx.handlers.xinit(*ctx.vals, ep) return nil case ctx.Replace.Name(): - if err := checkArgs.CheckPerCase(nextArgs[1:], ctx.Replace); err != nil { + if err := checkArgs.PopParseAndCheck(thisArgs, ctx.Replace); err != nil { return err } ctx.handlers.replace(*ctx.vals, ep) diff --git a/src/cmd/tools/m3ctl/main/placements/cmd_test.go b/src/cmd/tools/m3ctl/main/placements/cmd_test.go index 0bae5a2b5c..977dd61329 100644 --- a/src/cmd/tools/m3ctl/main/placements/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/placements/cmd_test.go @@ -80,7 +80,7 @@ func TestBasic(t *testing.T) { for _, v := range testData { ctx := makeStub() - if ! v.successCondition(ctx.ParseAndDo(v.args, v.ep)) { + if ! v.successCondition(ctx.PopParseAndDo(v.args, v.ep)) { t.Error(v.msg) } } diff --git a/src/cmd/tools/m3ctl/main/placements/constants.go b/src/cmd/tools/m3ctl/main/placements/constants.go new file mode 100644 index 0000000000..7c9ac71081 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/placements/constants.go @@ -0,0 +1,6 @@ +package placements + +const ( + DefaultPath = "/api/v1/services/m3db/placement" +) + diff --git a/src/cmd/tools/m3ctl/main/placements/delete.go b/src/cmd/tools/m3ctl/main/placements/delete.go index 6a790eff39..22b371443c 100644 --- a/src/cmd/tools/m3ctl/main/placements/delete.go +++ b/src/cmd/tools/m3ctl/main/placements/delete.go @@ -8,11 +8,11 @@ import ( func doDelete(s placementArgs, endpoint string) { if *s.deletePlacement { - url := fmt.Sprintf("%s%s", endpoint, defaultPath) + url := fmt.Sprintf("%s%s", endpoint, DefaultPath) client.DoDelete(url, client.Dumper) return } - url := fmt.Sprintf("%s%s/%s", endpoint, defaultPath, *s.deleteNode) + url := fmt.Sprintf("%s%s/%s", endpoint, DefaultPath, *s.deleteNode) client.DoDelete(url, client.Dumper) return } diff --git a/src/cmd/tools/m3ctl/main/placements/get.go b/src/cmd/tools/m3ctl/main/placements/get.go index 66e553ffa9..8101c17742 100644 --- a/src/cmd/tools/m3ctl/main/placements/get.go +++ b/src/cmd/tools/m3ctl/main/placements/get.go @@ -7,7 +7,7 @@ import ( ) func doGet(s placementArgs, endpoint string) { - url := fmt.Sprintf("%s%s", endpoint, defaultPath) + url := fmt.Sprintf("%s%s", endpoint, DefaultPath) client.DoGet(url, client.Dumper) return } diff --git a/src/cmd/tools/m3ctl/main/placements/init.go b/src/cmd/tools/m3ctl/main/placements/init.go index 3739dabf0b..24da13a2fe 100644 --- a/src/cmd/tools/m3ctl/main/placements/init.go +++ b/src/cmd/tools/m3ctl/main/placements/init.go @@ -12,7 +12,7 @@ import ( func doInit(s placementArgs, endpoint string) { log.Printf("placementArgs:%+v:\n", s) data := yaml.Load(s.initFlag.Value[0], &admin.PlacementInitRequest{}) - url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/init") + url := fmt.Sprintf("%s%s%s", endpoint, DefaultPath, "/init") client.DoPost(url, data, client.Dumper) return } diff --git a/src/cmd/tools/m3ctl/main/placements/replace.go b/src/cmd/tools/m3ctl/main/placements/replace.go index d1dfadc0ba..3da9eec105 100644 --- a/src/cmd/tools/m3ctl/main/placements/replace.go +++ b/src/cmd/tools/m3ctl/main/placements/replace.go @@ -10,7 +10,7 @@ import ( func doReplace(s placementArgs, endpoint string) { data := yaml.Load(s.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}) - url := fmt.Sprintf("%s%s%s", endpoint, defaultPath, "/replace") + url := fmt.Sprintf("%s%s%s", endpoint, DefaultPath, "/replace") client.DoPost(url, data, client.Dumper) return } From e77f0bab2aec742b47c71605e4cd352fb05ad071 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sat, 1 Feb 2020 18:59:57 -0800 Subject: [PATCH 31/65] checkpoint --- src/cmd/tools/m3ctl/main/checkArgs/types.go | 8 ++ src/cmd/tools/m3ctl/main/delete/cmd.go | 108 +++++++++++++++++ .../tools/m3ctl/main/delete/namespaces/cmd.go | 103 ++++++++++++++++ .../m3ctl/main/delete/namespaces/cmd_test.go | 73 ++++++++++++ .../m3ctl/main/delete/namespaces/delete.go | 12 ++ .../tools/m3ctl/main/delete/placements/cmd.go | 97 +++++++++++++++ .../m3ctl/main/delete/placements/cmd_test.go | 79 +++++++++++++ .../m3ctl/main/delete/placements/delete.go | 19 +++ src/cmd/tools/m3ctl/main/get/cmd.go | 18 ++- .../tools/m3ctl/main/get/namespaces/cmd.go | 111 ++++++++++++++++++ .../tools/m3ctl/main/get/namespaces/get.go | 34 ++++++ .../tools/m3ctl/main/get/placements/cmd.go | 39 +++--- .../tools/m3ctl/main/get/placements/get.go | 3 +- src/cmd/tools/m3ctl/main/main.go | 29 +++-- src/cmd/tools/m3ctl/main/namespaces/cmd.go | 5 - .../tools/m3ctl/main/namespaces/constants.go | 6 + src/cmd/tools/m3ctl/main/namespaces/show.go | 2 +- .../placements/{constants.go => types.go} | 0 18 files changed, 699 insertions(+), 47 deletions(-) create mode 100644 src/cmd/tools/m3ctl/main/checkArgs/types.go create mode 100644 src/cmd/tools/m3ctl/main/delete/cmd.go create mode 100644 src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go create mode 100644 src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go create mode 100644 src/cmd/tools/m3ctl/main/delete/namespaces/delete.go create mode 100644 src/cmd/tools/m3ctl/main/delete/placements/cmd.go create mode 100644 src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go create mode 100644 src/cmd/tools/m3ctl/main/delete/placements/delete.go create mode 100644 src/cmd/tools/m3ctl/main/get/namespaces/cmd.go create mode 100644 src/cmd/tools/m3ctl/main/get/namespaces/get.go create mode 100644 src/cmd/tools/m3ctl/main/namespaces/constants.go rename src/cmd/tools/m3ctl/main/placements/{constants.go => types.go} (100%) diff --git a/src/cmd/tools/m3ctl/main/checkArgs/types.go b/src/cmd/tools/m3ctl/main/checkArgs/types.go new file mode 100644 index 0000000000..0ccdbbfa5f --- /dev/null +++ b/src/cmd/tools/m3ctl/main/checkArgs/types.go @@ -0,0 +1,8 @@ +package checkArgs + +import "go.uber.org/zap" + +type GlobalOpts struct { + Endpoint string + zap *zap.SugaredLogger +} diff --git a/src/cmd/tools/m3ctl/main/delete/cmd.go b/src/cmd/tools/m3ctl/main/delete/cmd.go new file mode 100644 index 0000000000..b2934fd8e7 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/delete/cmd.go @@ -0,0 +1,108 @@ +package delete + +import ( + "flag" + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/delete/namespaces" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/delete/placements" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" + "os" +) + +// this has all that the upper level needs to dispatch to here +type Context struct { + //vals *placementArgs + //handlers placementHandler + GlobalOpts checkArgs.GlobalOpts + Delete *flag.FlagSet + //Add *flag.FlagSet + //Delete *flag.FlagSet + //Init *flag.FlagSet + //Replace *flag.FlagSet +} +//type placementHandler struct { +// add func(placementArgs, string) +// delete func(placementArgs, string) +// xget func(placementArgs, string) +// xinit func(placementArgs, string) +// replace func(placementArgs, string) +//} + +// setup hooks and context for this level +// everything needed to prep for this get command leve +// nothing that's needed below it +// just the stuff for parsing at the get level +func InitializeFlags() Context { + //return _setupFlags( + //&placementArgs{}, + //placementHandler{ + // add: doAdd, + // delete: doDelete, + // xget: doGet, + // xinit: doInit, + // replace: doReplace, + // }, + //) + + return _setupFlags() +} +func _setupFlags() Context { + + deleteFlags := flag.NewFlagSet("delete", flag.ContinueOnError) + deleteFlags.Usage = func() { + fmt.Fprintf(os.Stderr, "delete help msg here\n") + deleteFlags.PrintDefaults() + } + + return Context{Delete:deleteFlags} +} + +func (ctx Context) PopParseDispatch(cli []string) error { + + thisFlagset := ctx.Delete + if len(cli) < 1 { + thisFlagset.Usage() + return &errors.FlagsError{} + } + + // pop and parse + inArgs := cli[1:] + //if err := thisFlagset.Parse(inArgs); err != nil { + // thisFlagset.Usage() + // return err + //} + thisFlagset.Parse(inArgs) + if thisFlagset.NArg() == 0 { + thisFlagset.Usage() + return &errors.FlagsError{} + } + + plctx := placements.InitializeFlags() + nsctx := namespaces.InitializeFlags() + + nextArgs := thisFlagset.Args() + fmt.Print(nextArgs) + switch nextArgs[0] { + case plctx.Placement.Name(): + fmt.Print("delete pl case") + plctx.Globals = ctx.GlobalOpts + if err := plctx.PopParseDispatch(nextArgs); err != nil { + return err + } + case nsctx.Namespaces.Name(): + fmt.Print("delete ns case") + nsctx.Globals = ctx.GlobalOpts + if err := nsctx.PopParseDispatch(nextArgs); err != nil { + return err + } + default: + fmt.Print("delete default case") + thisFlagset.Usage() + return &errors.FlagsError{} + } + + fmt.Print("done delete with case") + return nil + +} \ No newline at end of file diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go new file mode 100644 index 0000000000..e6f95d3ea2 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go @@ -0,0 +1,103 @@ +package namespaces + +import ( + "flag" + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" + "os" +) + +// all the values from the cli args are stored in here +// for all the placement-related commands +type namespacesArgs struct { + nodeName *string +} + +// this has all that the upper dispatcher needs to parse the cli +type Context struct { + vals *namespacesArgs + handlers namespacesHandlers + Globals checkArgs.GlobalOpts + Namespaces *flag.FlagSet +} +type namespacesHandlers struct { + xdel func(*namespacesArgs, checkArgs.GlobalOpts) +} + +func InitializeFlags() Context { + return _setupFlags( + &namespacesArgs{}, + namespacesHandlers{ + xdel: doDelete, + }, + ) +} +func _setupFlags(finalArgs *namespacesArgs, handler namespacesHandlers) Context { + + nsFlags := flag.NewFlagSet("ns", flag.ContinueOnError) + + finalArgs.nodeName = nsFlags.String("node", "", "delete the specified node in the placement") + nsFlags.Usage = func() { + fmt.Fprintf(os.Stderr, ` +"%s" is for acting on placements. + +Description: + +qqq + +`, nsFlags.Name()) + nsFlags.PrintDefaults() + } + + return Context{ + vals: finalArgs, + handlers: handler, + Namespaces: nsFlags, + } +} +func (ctx Context) PopParseDispatch(cli []string) error { + if len(cli) < 1 { + fmt.Printf("1:%v:\n", cli) + ctx.Namespaces.Usage() + return &errors.FlagsError{} + } + + inArgs := cli[1:] + if err := ctx.Namespaces.Parse(inArgs); err != nil { + fmt.Printf("2:%v:\n", cli) + + ctx.Namespaces.Usage() + return err + } + if ctx.Namespaces.NFlag() == 0 { + fmt.Printf("3:%v:%v:\n", cli, ctx.Namespaces.NArg()) + + ctx.Namespaces.Usage() + return &errors.FlagsError{} + } + + if err := dispatcher(ctx); err != nil { + fmt.Printf("4:%v:\n", cli) + + return err + } + + return nil + +} + +func dispatcher(ctx Context) error { + nextArgs := ctx.Namespaces.Args() + + fmt.Printf("nextArgs:%v:%v:\n", nextArgs, len(nextArgs)) + + if len(nextArgs) != 0 { + ctx.Namespaces.Usage() + return &errors.FlagsError{"\nextra args supplied. See usage.\n"} + } + + ctx.handlers.xdel(ctx.vals, ctx.Globals) + return nil + +} diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go new file mode 100644 index 0000000000..855cb8b411 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go @@ -0,0 +1,73 @@ +package namespaces + +import ( + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "testing" +) + +func makeStub() Context { + ctx := _setupFlags( + &namespacesArgs{}, + namespacesHandlers{ + xdel: func(*namespacesArgs, checkArgs.GlobalOpts) { return }, + }, + ) + + ctx.Globals.Endpoint = "fakeEndpoint" + + return ctx +} +func TestBasic(t *testing.T) { + + testData := []struct { + args []string + msg string + successCondition func(error) bool + }{ + { + args: []string{"ns", "-node", "eee"}, + msg: "It should return no error for sane args", + successCondition: func(err error) bool { return err == nil }, + }, + { + args: []string{}, + msg: "It should return error because we got here without ns", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"ns"}, + msg: "It should return error because we got no args", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"ns", "-h"}, + msg: "It should return error because we ran with -h", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"ns", "-node"}, + msg: "It should return error because we ran with -node but no args", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"ns", "-node", "eee", "errr"}, + msg: "It should return error because we got extra args", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"ns", "-node", ""}, + msg: "It should return an error because we got an empty val", + successCondition: func(err error) bool { return err == nil }, + }, + + } + + for _, v := range testData { + ctx := makeStub() + rv := ctx.PopParseDispatch(v.args) + if ! v.successCondition(rv) { + t.Error(v.msg) + } + } + +} diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/delete.go b/src/cmd/tools/m3ctl/main/delete/namespaces/delete.go new file mode 100644 index 0000000000..127a61497d --- /dev/null +++ b/src/cmd/tools/m3ctl/main/delete/namespaces/delete.go @@ -0,0 +1,12 @@ +package namespaces + +import ( + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" +) + +func doDelete(flags *namespacesArgs, globals checkArgs.GlobalOpts) { + url := fmt.Sprintf("%s%s/%s", globals.Endpoint, "/api/v1/services/m3db/namespace", *flags.nodeName) + client.DoDelete(url, client.Dumper) +} diff --git a/src/cmd/tools/m3ctl/main/delete/placements/cmd.go b/src/cmd/tools/m3ctl/main/delete/placements/cmd.go new file mode 100644 index 0000000000..01ca22c8ea --- /dev/null +++ b/src/cmd/tools/m3ctl/main/delete/placements/cmd.go @@ -0,0 +1,97 @@ +package placements + +import ( + "flag" + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" + "os" +) + +// all the values from the cli args are stored in here +// for all the placement-related commands +type placementArgs struct { + deleteEntire *bool + nodeName *string +} + +// this has all that the upper dispatcher needs to parse the cli +type Context struct { + vals *placementArgs + handlers placementHandlers + Globals checkArgs.GlobalOpts + Placement *flag.FlagSet +} +type placementHandlers struct { + xdel func(*placementArgs, checkArgs.GlobalOpts) +} + +func InitializeFlags() Context { + return _setupFlags( + &placementArgs{}, + placementHandlers{ + xdel: doDelete, + }, + ) +} +func _setupFlags(finalArgs *placementArgs, handler placementHandlers) Context { + + placementFlags := flag.NewFlagSet("pl", flag.ContinueOnError) + + finalArgs.deleteEntire = placementFlags.Bool("all", false, "delete the entire placement") + finalArgs.nodeName = placementFlags.String("node", "", "delete the specified node in the placement") + placementFlags.Usage = func() { + fmt.Fprintf(os.Stderr, ` +"%s" is for acting on placements. + +Description: + +qqq + +`, placementFlags.Name()) + placementFlags.PrintDefaults() + } + + return Context{ + vals: finalArgs, + handlers: handler, + Placement: placementFlags, + } +} +func (ctx Context) PopParseDispatch(cli []string) error { + if len(cli) < 1 { + ctx.Placement.Usage() + return &errors.FlagsError{} + } + + inArgs := cli[1:] + if err := ctx.Placement.Parse(inArgs); err != nil { + ctx.Placement.Usage() + return &errors.FlagsError{} + } + if ctx.Placement.NFlag() == 0 { + fmt.Printf("3:%v:%v:\n", cli, ctx.Placement.NArg()) + + ctx.Placement.Usage() + return &errors.FlagsError{} + } + + if err := dispatcher(ctx); err != nil { + return err + } + + return nil + +} + +func dispatcher(ctx Context) error { + nextArgs := ctx.Placement.Args() + + if len(nextArgs) != 0 { + ctx.Placement.Usage() + return &errors.FlagsError{"\nextra args supplied. See usage\n"} + } + ctx.handlers.xdel(ctx.vals, ctx.Globals) + return nil + +} diff --git a/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go b/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go new file mode 100644 index 0000000000..517b86bf11 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go @@ -0,0 +1,79 @@ +package placements + +import ( + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "testing" +) + +func makeStub() Context { + ctx := _setupFlags( + &placementArgs{}, + placementHandlers{ + xdel: func(*placementArgs, checkArgs.GlobalOpts) { return }, + }, + ) + + ctx.Globals.Endpoint = "nuch" + + return ctx +} +func TestBasic(t *testing.T) { + + testData := []struct { + args []string + msg string + successCondition func(error) bool + }{ + { + args: []string{"pl", "-all"}, + msg: "It should return no error for sane args for -all", + successCondition: func(err error) bool { return err == nil }, + }, + { + args: []string{"pl", "-node", "eee"}, + msg: "It should return no error for sane args for -node", + successCondition: func(err error) bool { return err == nil }, + }, + { + args: []string{}, + msg: "It should return error because we got here without pl", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"pl"}, + msg: "It should return error because we got no args", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"pl", "-h"}, + msg: "It should return error because we ran with -h", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"pl", "-node"}, + msg: "It should return error because we ran with -node but no args", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"pl", "-node", "eee", "errr"}, + msg: "It should return error because we got extra args", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"pl", "-node", ""}, + msg: "It should return an error because we got an empty val", + successCondition: func(err error) bool { return err == nil }, + }, + + } + + for _, v := range testData { + ctx := makeStub() + rv := ctx.PopParseDispatch(v.args) + if ! v.successCondition(rv) { + t.Error(v.msg) + } + } + +} + diff --git a/src/cmd/tools/m3ctl/main/delete/placements/delete.go b/src/cmd/tools/m3ctl/main/delete/placements/delete.go new file mode 100644 index 0000000000..ed4bf2d08b --- /dev/null +++ b/src/cmd/tools/m3ctl/main/delete/placements/delete.go @@ -0,0 +1,19 @@ +package placements + +import ( + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + common "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" +) + +func doDelete(s *placementArgs, globals checkArgs.GlobalOpts) { + if *s.deleteEntire { + url := fmt.Sprintf("%s%s", globals.Endpoint, common.DefaultPath) + client.DoDelete(url, client.Dumper) + return + } + url := fmt.Sprintf("%s%s/%s", globals.Endpoint, common.DefaultPath, *s.nodeName) + client.DoDelete(url, client.Dumper) + return +} diff --git a/src/cmd/tools/m3ctl/main/get/cmd.go b/src/cmd/tools/m3ctl/main/get/cmd.go index 6a7e27238f..0b88d5d302 100644 --- a/src/cmd/tools/m3ctl/main/get/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/cmd.go @@ -3,7 +3,9 @@ package get import ( "flag" "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/get/namespaces" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/get/placements" //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" @@ -22,14 +24,11 @@ import ( // replaceFlag configflag.FlagStringSlice //} -type GlobalOpts struct { - Get placements.Globals -} // this has all that the upper level needs to dispatch to here type Context struct { //vals *placementArgs //handlers placementHandler - GlobalOpts + GlobalOpts checkArgs.GlobalOpts Get *flag.FlagSet //Add *flag.FlagSet //Delete *flag.FlagSet @@ -64,7 +63,7 @@ func InitializeFlags() Context { } func _setupFlags() Context { - getFlags := flag.NewFlagSet("get", flag.ExitOnError) + getFlags := flag.NewFlagSet("get", flag.ContinueOnError) getFlags.Usage = func() { fmt.Fprintf(os.Stderr, "help msg here\n") getFlags.PrintDefaults() @@ -101,16 +100,23 @@ func (ctx Context) PopParseDispatch(cli []string) error { // contexts for next level //plctx := placements.InitializeFlags() plctx := placements.InitializeFlags() + nsctx := namespaces.InitializeFlags() nextArgs := thisFlagset.Args() fmt.Print(nextArgs) switch nextArgs[0] { case plctx.Placement.Name(): fmt.Print("pl case") - plctx.Globals = ctx.GlobalOpts.Get + plctx.Globals = ctx.GlobalOpts if err := plctx.PopParseDispatch(nextArgs); err != nil { return err } + case nsctx.Namespaces.Name(): + fmt.Print("pl case") + nsctx.Globals = ctx.GlobalOpts + if err := nsctx.PopParseDispatch(nextArgs); err != nil { + return err + } //case plctx.Placement.Name(): // fmt.Print("pl case") // if err := plctx.PopParseDispatch(nextArgs, "fake endpoint"); err != nil { diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go new file mode 100644 index 0000000000..9c133a8670 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go @@ -0,0 +1,111 @@ +package namespaces + +import ( + "flag" + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" + "os" +) + +type namespacesArgs struct { + showAll *bool +} + +type context struct { + vals *namespacesArgs + handlers namespacesHandlers + Globals checkArgs.GlobalOpts + Namespaces *flag.FlagSet + //Add *flag.FlagSet + //Delete *flag.FlagSet + //Init *flag.FlagSet + //Replace *flag.FlagSet +} +type namespacesHandlers struct { + xget func(*namespacesArgs, checkArgs.GlobalOpts) +} + +// everything needed to prep for this pl command level +// nothing that's needed below it +// just the stuff for parsing at the pl level +func InitializeFlags() context { + return _setupFlags( + &namespacesArgs{}, + namespacesHandlers{ + //add: doAdd, + //delete: doDelete, + //xget: func(c *placementArgs, s string) {fmt.Print("deeper fake pl get handler")}, + xget: get, + //xget: placements., + //xinit: doInit, + //replace: doReplace, + }, + ) +} +func _setupFlags(finalArgs *namespacesArgs, handler namespacesHandlers) context { + namespaceFlags := flag.NewFlagSet("ns", flag.ContinueOnError) + finalArgs.showAll = namespaceFlags.Bool("all", false, "get all the standard info for namespaces (otherwise default behaviour lists only the names)") + + namespaceFlags.Usage = func() { + fmt.Fprintf(os.Stderr, ` +"%s" is for acting on placements. + +Description: + +Default behaviour (no arguments) is to provide a json dump of the existing placement. + + +`, namespaceFlags.Name()) + namespaceFlags.PrintDefaults() + } + return context{ + vals: finalArgs, + handlers: handler, + //GlobalOpts: nil, + Namespaces: namespaceFlags, + //Add: addFlags, + //Delete: deleteFlags, + //Init: initFlags, + //Replace: replaceFlags, + } +} + +func (ctx context) PopParseDispatch(cli []string) error { + // right here args should be like "pl delete -node someName" + if len(cli) < 1 { + ctx.Namespaces.Usage() + return &errors.FlagsError{} + } + + inArgs := cli[1:] + if err := ctx.Namespaces.Parse(inArgs); err != nil { + ctx.Namespaces.Usage() + return &errors.FlagsError{} + } + if ctx.Namespaces.NArg() == 0 { + ctx.handlers.xget(ctx.vals, ctx.Globals) + return nil + } + + if err := dispatcher(ctx); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + return err + } + + return nil + +} + +func dispatcher(ctx context) error { + + nextArgs := ctx.Namespaces.Args() + switch nextArgs[0] { + case "": + ctx.handlers.xget(ctx.vals, ctx.Globals) + return nil + default: + ctx.Namespaces.Usage() + return &errors.FlagsError{} + } +} \ No newline at end of file diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/get.go b/src/cmd/tools/m3ctl/main/get/namespaces/get.go new file mode 100644 index 0000000000..7aa09953da --- /dev/null +++ b/src/cmd/tools/m3ctl/main/get/namespaces/get.go @@ -0,0 +1,34 @@ +package namespaces + +import ( + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "io" + "log" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" + "github.com/m3db/m3/src/query/generated/proto/admin" + common "github.com/m3db/m3/src/cmd/tools/m3ctl/main/namespaces" + + "github.com/gogo/protobuf/jsonpb" +) + +func get(flags *namespacesArgs, globals checkArgs.GlobalOpts) { + url := fmt.Sprintf("%s%s?%s", globals.Endpoint, common.DefaultPath, common.DebugQS) + if *flags.showAll { + client.DoGet(url, client.Dumper) + } else { + client.DoGet(url, showNames) + } +} + +func showNames(in io.Reader) { + registry := admin.NamespaceGetResponse{} + unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} + if err := unmarshaller.Unmarshal(in, ®istry); err != nil { + log.Fatal(err) + } + for k, _ := range registry.Registry.Namespaces { + fmt.Println(k) + } +} diff --git a/src/cmd/tools/m3ctl/main/get/placements/cmd.go b/src/cmd/tools/m3ctl/main/get/placements/cmd.go index 2d260396ff..ac74a682cc 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/placements/cmd.go @@ -3,8 +3,7 @@ package placements import ( "flag" "fmt" - "go.uber.org/zap" - + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" "os" @@ -26,19 +25,11 @@ type placementArgs struct { //replaceFlag configflag.FlagStringSlice } -type Globals struct { -Endpoint string -zap *zap.SugaredLogger -} - -// this has all that the dispatcher needs to parse the cli -type Context struct { - vals *placementArgs - handlers placementHandlers - Globals struct { - Endpoint string - zap *zap.SugaredLogger - } +// this has all that the upper dispatcher needs to parse the cli +type context struct { + vals *placementArgs + handlers placementHandlers + Globals checkArgs.GlobalOpts Placement *flag.FlagSet //Add *flag.FlagSet //Delete *flag.FlagSet @@ -46,29 +37,29 @@ type Context struct { //Replace *flag.FlagSet } type placementHandlers struct { - xget func(*placementArgs, Globals) + xget func(*placementArgs, checkArgs.GlobalOpts) } // everything needed to prep for this pl command level // nothing that's needed below it // just the stuff for parsing at the pl level -func InitializeFlags() Context { +func InitializeFlags() context { return _setupFlags( &placementArgs{}, placementHandlers{ //add: doAdd, //delete: doDelete, //xget: func(c *placementArgs, s string) {fmt.Print("deeper fake pl get handler")}, - xget: doGet, + xget: doGet, //xget: placements., //xinit: doInit, //replace: doReplace, }, ) } -func _setupFlags(finalArgs *placementArgs, handler placementHandlers) Context { +func _setupFlags(finalArgs *placementArgs, handler placementHandlers) context { - placementFlags := flag.NewFlagSet("pl", flag.ExitOnError) + placementFlags := flag.NewFlagSet("pl", flag.ContinueOnError) //deleteFlags := flag.NewFlagSet("delete", flag.ExitOnError) //addFlags := flag.NewFlagSet("add", flag.ExitOnError) //initFlags := flag.NewFlagSet("init", flag.ExitOnError) @@ -91,7 +82,7 @@ Default behaviour (no arguments) is to provide a json dump of the existing place `, placementFlags.Name()) placementFlags.PrintDefaults() } - return Context{ + return context{ vals: finalArgs, handlers: handler, //GlobalOpts: nil, @@ -103,7 +94,7 @@ Default behaviour (no arguments) is to provide a json dump of the existing place } } -func (ctx Context) PopParseDispatch(cli []string) error { +func (ctx context) PopParseDispatch(cli []string) error { // right here args should be like "pl delete -node someName" if len(cli) < 1 { ctx.Placement.Usage() @@ -113,7 +104,7 @@ func (ctx Context) PopParseDispatch(cli []string) error { inArgs := cli[1:] if err := ctx.Placement.Parse(inArgs); err != nil { ctx.Placement.Usage() - return &errors.FlagsError{} + return &errors.FlagsError{} } if ctx.Placement.NArg() == 0 { ctx.handlers.xget(ctx.vals, ctx.Globals) @@ -129,7 +120,7 @@ func (ctx Context) PopParseDispatch(cli []string) error { } -func dispatcher(ctx Context) error { +func dispatcher(ctx context) error { nextArgs := ctx.Placement.Args() switch nextArgs[0] { case "": diff --git a/src/cmd/tools/m3ctl/main/get/placements/get.go b/src/cmd/tools/m3ctl/main/get/placements/get.go index 97fe4527c8..6a8f97a64b 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/get.go +++ b/src/cmd/tools/m3ctl/main/get/placements/get.go @@ -2,12 +2,13 @@ package placements import ( "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" common "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" ) -func doGet(s *placementArgs, globals Globals) { +func doGet(s *placementArgs, globals checkArgs.GlobalOpts) { url := fmt.Sprintf("%s%s", globals.Endpoint, common.DefaultPath) client.DoGet(url, client.Dumper) return diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index f92a03ca99..5c46cc3275 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -24,10 +24,11 @@ import ( "flag" "fmt" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/get" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/delete" "os" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/database" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/namespaces" + //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/namespaces" "github.com/m3db/m3/src/x/config/configflag" ) @@ -46,11 +47,12 @@ func main() { databaseFlagSets := database.SetupFlags(&createDatabaseYAML) // the namespace-related subcommand - namespaceArgs := namespaces.NamespaceArgs{} - namespaceFlagSets := namespaces.SetupFlags(&namespaceArgs) + //namespaceArgs := namespaces.NamespaceArgs{} + //namespaceFlagSets := namespaces.SetupFlags(&namespaceArgs) //placementFlagSets := placements.InitializeFlags() getFlagSets := get.InitializeFlags() + deleteFlagSets := delete.InitializeFlags() flag.Usage = func() { fmt.Fprintf(flag.CommandLine.Output(), ` @@ -66,8 +68,8 @@ Each subcommand has its own built-in help provided via "-h". `, os.Args[0], databaseFlagSets.Database.Name(), //placementFlagSets.Placement.Name(), - "was pl", - namespaceFlagSets.Namespace.Name()) + getFlagSets.Get.Name(), + deleteFlagSets.Delete.Name()) flag.PrintDefaults() } @@ -82,17 +84,24 @@ Each subcommand has its own built-in help provided via "-h". // dispatch to the next level switch flag.Arg(0) { - case databaseFlagSets.Database.Name(): - database.ParseAndDo(&createDatabaseYAML, &databaseFlagSets, *endPoint) - case namespaceFlagSets.Namespace.Name(): - namespaces.ParseAndDo(&namespaceArgs, &namespaceFlagSets, *endPoint) + //case databaseFlagSets.Database.Name(): + // database.ParseAndDo(&createDatabaseYAML, &databaseFlagSets, *endPoint) + //case namespaceFlagSets.Namespace.Name(): + // namespaces.ParseAndDo(&namespaceArgs, &namespaceFlagSets, *endPoint) //case placementFlagSets.Placement.Name(): // if err := placementFlagSets.PopParseDispatch(flag.Args(), *endPoint); err != nil { // os.Exit(1) // } case getFlagSets.Get.Name(): - getFlagSets.GlobalOpts.Get.Endpoint = *endPoint + getFlagSets.GlobalOpts.Endpoint = *endPoint if err := getFlagSets.PopParseDispatch(flag.Args()); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + case deleteFlagSets.Delete.Name(): + deleteFlagSets.GlobalOpts.Endpoint = *endPoint + if err := deleteFlagSets.PopParseDispatch(flag.Args()); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } default: diff --git a/src/cmd/tools/m3ctl/main/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/namespaces/cmd.go index 626fc28f64..347a85226c 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/namespaces/cmd.go @@ -8,11 +8,6 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" ) -const ( - defaultPath = "/api/v1/namespace" - debugQS = "debug=true" -) - type NamespaceArgs struct { showAll *bool delete *string diff --git a/src/cmd/tools/m3ctl/main/namespaces/constants.go b/src/cmd/tools/m3ctl/main/namespaces/constants.go new file mode 100644 index 0000000000..485bd1178c --- /dev/null +++ b/src/cmd/tools/m3ctl/main/namespaces/constants.go @@ -0,0 +1,6 @@ +package namespaces + +const ( + DefaultPath = "/api/v1/namespace" + DebugQS = "debug=true" +) diff --git a/src/cmd/tools/m3ctl/main/namespaces/show.go b/src/cmd/tools/m3ctl/main/namespaces/show.go index a247d1ee85..6c657ce6d0 100644 --- a/src/cmd/tools/m3ctl/main/namespaces/show.go +++ b/src/cmd/tools/m3ctl/main/namespaces/show.go @@ -12,7 +12,7 @@ import ( ) func Show(flags *NamespaceArgs, endpoint string) { - url := fmt.Sprintf("%s%s?%s", endpoint, defaultPath, debugQS) + url := fmt.Sprintf("%s%s?%s", endpoint, DefaultPath, DebugQS) if *flags.showAll { client.DoGet(url, client.Dumper) } else { diff --git a/src/cmd/tools/m3ctl/main/placements/constants.go b/src/cmd/tools/m3ctl/main/placements/types.go similarity index 100% rename from src/cmd/tools/m3ctl/main/placements/constants.go rename to src/cmd/tools/m3ctl/main/placements/types.go From 51f92ddbe690de80c3a26f5a73daf75be14365ec Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 2 Feb 2020 14:47:33 -0800 Subject: [PATCH 32/65] add an operation type to the yaml and wrap the existing pb --- src/cmd/tools/m3ctl/main/apply/cmd.go | 3 + .../tools/m3ctl/main/get/namespaces/cmd.go | 12 +- .../m3ctl/main/get/namespaces/cmd_test.go | 70 +++++++++++ .../tools/m3ctl/main/get/placements/cmd.go | 12 +- .../m3ctl/main/get/placements/cmd_test.go | 64 ++++++++++ .../namespaces/{constants.go => types.go} | 0 src/cmd/tools/m3ctl/main/yaml/dbCreate.proto | 13 ++ .../m3ctl/main/yaml/generated/dbCreate.pb.go | 119 ++++++++++++++++++ src/cmd/tools/m3ctl/main/yaml/load_test.go | 33 ++--- .../m3ctl/main/yaml/testdata/basicCreate.yaml | 28 +++-- src/cmd/tools/m3ctl/main/yaml/types.go | 13 ++ 11 files changed, 327 insertions(+), 40 deletions(-) create mode 100644 src/cmd/tools/m3ctl/main/apply/cmd.go create mode 100644 src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go create mode 100644 src/cmd/tools/m3ctl/main/get/placements/cmd_test.go rename src/cmd/tools/m3ctl/main/namespaces/{constants.go => types.go} (100%) create mode 100644 src/cmd/tools/m3ctl/main/yaml/dbCreate.proto create mode 100644 src/cmd/tools/m3ctl/main/yaml/generated/dbCreate.pb.go create mode 100644 src/cmd/tools/m3ctl/main/yaml/types.go diff --git a/src/cmd/tools/m3ctl/main/apply/cmd.go b/src/cmd/tools/m3ctl/main/apply/cmd.go new file mode 100644 index 0000000000..5e189fa9f5 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/apply/cmd.go @@ -0,0 +1,3 @@ +package apply + + diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go index 9c133a8670..c067e643d5 100644 --- a/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go @@ -12,7 +12,7 @@ type namespacesArgs struct { showAll *bool } -type context struct { +type Context struct { vals *namespacesArgs handlers namespacesHandlers Globals checkArgs.GlobalOpts @@ -29,7 +29,7 @@ type namespacesHandlers struct { // everything needed to prep for this pl command level // nothing that's needed below it // just the stuff for parsing at the pl level -func InitializeFlags() context { +func InitializeFlags() Context { return _setupFlags( &namespacesArgs{}, namespacesHandlers{ @@ -43,7 +43,7 @@ func InitializeFlags() context { }, ) } -func _setupFlags(finalArgs *namespacesArgs, handler namespacesHandlers) context { +func _setupFlags(finalArgs *namespacesArgs, handler namespacesHandlers) Context { namespaceFlags := flag.NewFlagSet("ns", flag.ContinueOnError) finalArgs.showAll = namespaceFlags.Bool("all", false, "get all the standard info for namespaces (otherwise default behaviour lists only the names)") @@ -59,7 +59,7 @@ Default behaviour (no arguments) is to provide a json dump of the existing place `, namespaceFlags.Name()) namespaceFlags.PrintDefaults() } - return context{ + return Context{ vals: finalArgs, handlers: handler, //GlobalOpts: nil, @@ -71,7 +71,7 @@ Default behaviour (no arguments) is to provide a json dump of the existing place } } -func (ctx context) PopParseDispatch(cli []string) error { +func (ctx Context) PopParseDispatch(cli []string) error { // right here args should be like "pl delete -node someName" if len(cli) < 1 { ctx.Namespaces.Usage() @@ -97,7 +97,7 @@ func (ctx context) PopParseDispatch(cli []string) error { } -func dispatcher(ctx context) error { +func dispatcher(ctx Context) error { nextArgs := ctx.Namespaces.Args() switch nextArgs[0] { diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go new file mode 100644 index 0000000000..9856aa5d1d --- /dev/null +++ b/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go @@ -0,0 +1,70 @@ +package namespaces + +import ( + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "testing" +) + +func makeStub() Context { + ctx := _setupFlags( + &namespacesArgs{}, + namespacesHandlers{ + xget: func(*namespacesArgs, checkArgs.GlobalOpts) { return }, + }, + ) + + ctx.Globals.Endpoint = "nuch" + + return ctx +} +func TestBasic(t *testing.T) { + + testData := []struct { + args []string + msg string + successCondition func(error) bool + }{ + { + args: []string{"ns"}, + msg: "It should return no error for sane args", + successCondition: func(err error) bool { return err == nil }, + }, + { + args: []string{"ns", "-all"}, + msg: "It should return no error for sane args for -all", + successCondition: func(err error) bool { return err == nil }, + }, + { + args: []string{}, + msg: "It should return error because we got here without pl", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"ns", "-h"}, + msg: "It should return error because we ran with -h", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"ns", "-all", "eee", "errr"}, + msg: "It should return error because we got extra args", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"ns", ""}, + msg: "It should return an error because we got an empty val", + successCondition: func(err error) bool { return err == nil }, + }, + + } + + for _, v := range testData { + ctx := makeStub() + rv := ctx.PopParseDispatch(v.args) + if ! v.successCondition(rv) { + t.Error(v.msg) + } + } + +} + + diff --git a/src/cmd/tools/m3ctl/main/get/placements/cmd.go b/src/cmd/tools/m3ctl/main/get/placements/cmd.go index ac74a682cc..b46f43f317 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/placements/cmd.go @@ -26,7 +26,7 @@ type placementArgs struct { } // this has all that the upper dispatcher needs to parse the cli -type context struct { +type Context struct { vals *placementArgs handlers placementHandlers Globals checkArgs.GlobalOpts @@ -43,7 +43,7 @@ type placementHandlers struct { // everything needed to prep for this pl command level // nothing that's needed below it // just the stuff for parsing at the pl level -func InitializeFlags() context { +func InitializeFlags() Context { return _setupFlags( &placementArgs{}, placementHandlers{ @@ -57,7 +57,7 @@ func InitializeFlags() context { }, ) } -func _setupFlags(finalArgs *placementArgs, handler placementHandlers) context { +func _setupFlags(finalArgs *placementArgs, handler placementHandlers) Context { placementFlags := flag.NewFlagSet("pl", flag.ContinueOnError) //deleteFlags := flag.NewFlagSet("delete", flag.ExitOnError) @@ -82,7 +82,7 @@ Default behaviour (no arguments) is to provide a json dump of the existing place `, placementFlags.Name()) placementFlags.PrintDefaults() } - return context{ + return Context{ vals: finalArgs, handlers: handler, //GlobalOpts: nil, @@ -94,7 +94,7 @@ Default behaviour (no arguments) is to provide a json dump of the existing place } } -func (ctx context) PopParseDispatch(cli []string) error { +func (ctx Context) PopParseDispatch(cli []string) error { // right here args should be like "pl delete -node someName" if len(cli) < 1 { ctx.Placement.Usage() @@ -120,7 +120,7 @@ func (ctx context) PopParseDispatch(cli []string) error { } -func dispatcher(ctx context) error { +func dispatcher(ctx Context) error { nextArgs := ctx.Placement.Args() switch nextArgs[0] { case "": diff --git a/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go b/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go new file mode 100644 index 0000000000..7a817c4b01 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go @@ -0,0 +1,64 @@ +package placements + +import ( + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "testing" +) + +func makeStub() Context { + ctx := _setupFlags( + &placementArgs{}, + placementHandlers{ + xget: func(*placementArgs, checkArgs.GlobalOpts) { return }, + }, + ) + + ctx.Globals.Endpoint = "nuch" + + return ctx +} +func TestBasic(t *testing.T) { + + testData := []struct { + args []string + msg string + successCondition func(error) bool + }{ + { + args: []string{"pl"}, + msg: "It should return no error for sane args", + successCondition: func(err error) bool { return err == nil }, + }, + { + args: []string{}, + msg: "It should return error because we got here without pl", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"pl", "-h"}, + msg: "It should return error because we ran with -h", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"pl", "-node", "eee", "errr"}, + msg: "It should return error because we got extra args", + successCondition: func(err error) bool { return err != nil }, + }, + { + args: []string{"pl", ""}, + msg: "It should return an error because we got an empty val", + successCondition: func(err error) bool { return err == nil }, + }, + + } + + for _, v := range testData { + ctx := makeStub() + rv := ctx.PopParseDispatch(v.args) + if ! v.successCondition(rv) { + t.Error(v.msg) + } + } + +} + diff --git a/src/cmd/tools/m3ctl/main/namespaces/constants.go b/src/cmd/tools/m3ctl/main/namespaces/types.go similarity index 100% rename from src/cmd/tools/m3ctl/main/namespaces/constants.go rename to src/cmd/tools/m3ctl/main/namespaces/types.go diff --git a/src/cmd/tools/m3ctl/main/yaml/dbCreate.proto b/src/cmd/tools/m3ctl/main/yaml/dbCreate.proto new file mode 100644 index 0000000000..d33f4c04fe --- /dev/null +++ b/src/cmd/tools/m3ctl/main/yaml/dbCreate.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; +package yaml; + +import "github.com/m3db/m3/src/query/generated/proto/admin/database.proto"; + +message DatabaseCreateRequestYaml { + enum OperationType { + CREATE = 0; + INIT = 1; + } + OperationType type = 7; + admin.DatabaseCreateRequest Request = 15; +} \ No newline at end of file diff --git a/src/cmd/tools/m3ctl/main/yaml/generated/dbCreate.pb.go b/src/cmd/tools/m3ctl/main/yaml/generated/dbCreate.pb.go new file mode 100644 index 0000000000..81a5bc3d95 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/yaml/generated/dbCreate.pb.go @@ -0,0 +1,119 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: dbCreate.proto + +package yaml + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + admin "github.com/m3db/m3/src/query/generated/proto/admin" + math "math" +) + +// 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 DatabaseCreateRequestYaml_OperationType int32 + +const ( + DatabaseCreateRequestYaml_CREATE DatabaseCreateRequestYaml_OperationType = 0 + DatabaseCreateRequestYaml_INIT DatabaseCreateRequestYaml_OperationType = 1 +) + +var DatabaseCreateRequestYaml_OperationType_name = map[int32]string{ + 0: "CREATE", + 1: "INIT", +} + +var DatabaseCreateRequestYaml_OperationType_value = map[string]int32{ + "CREATE": 0, + "INIT": 1, +} + +func (x DatabaseCreateRequestYaml_OperationType) String() string { + return proto.EnumName(DatabaseCreateRequestYaml_OperationType_name, int32(x)) +} + +func (DatabaseCreateRequestYaml_OperationType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_ac8e05fdfec588ce, []int{0, 0} +} + +type DatabaseCreateRequestYaml struct { + Type DatabaseCreateRequestYaml_OperationType `protobuf:"varint,7,opt,name=type,proto3,enum=yaml.DatabaseCreateRequestYaml_OperationType" json:"type,omitempty"` + Request *admin.DatabaseCreateRequest `protobuf:"bytes,15,opt,name=Request,proto3" json:"Request,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DatabaseCreateRequestYaml) Reset() { *m = DatabaseCreateRequestYaml{} } +func (m *DatabaseCreateRequestYaml) String() string { return proto.CompactTextString(m) } +func (*DatabaseCreateRequestYaml) ProtoMessage() {} +func (*DatabaseCreateRequestYaml) Descriptor() ([]byte, []int) { + return fileDescriptor_ac8e05fdfec588ce, []int{0} +} + +func (m *DatabaseCreateRequestYaml) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_DatabaseCreateRequestYaml.Unmarshal(m, b) +} +func (m *DatabaseCreateRequestYaml) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_DatabaseCreateRequestYaml.Marshal(b, m, deterministic) +} +func (m *DatabaseCreateRequestYaml) XXX_Merge(src proto.Message) { + xxx_messageInfo_DatabaseCreateRequestYaml.Merge(m, src) +} +func (m *DatabaseCreateRequestYaml) XXX_Size() int { + return xxx_messageInfo_DatabaseCreateRequestYaml.Size(m) +} +func (m *DatabaseCreateRequestYaml) XXX_DiscardUnknown() { + xxx_messageInfo_DatabaseCreateRequestYaml.DiscardUnknown(m) +} + +var xxx_messageInfo_DatabaseCreateRequestYaml proto.InternalMessageInfo + +func (m *DatabaseCreateRequestYaml) GetType() DatabaseCreateRequestYaml_OperationType { + if m != nil { + return m.Type + } + return DatabaseCreateRequestYaml_CREATE +} + +func (m *DatabaseCreateRequestYaml) GetRequest() *admin.DatabaseCreateRequest { + if m != nil { + return m.Request + } + return nil +} + +func init() { + proto.RegisterEnum("yaml.DatabaseCreateRequestYaml_OperationType", DatabaseCreateRequestYaml_OperationType_name, DatabaseCreateRequestYaml_OperationType_value) + proto.RegisterType((*DatabaseCreateRequestYaml)(nil), "yaml.DatabaseCreateRequestYaml") +} + +func init() { proto.RegisterFile("dbCreate.proto", fileDescriptor_ac8e05fdfec588ce) } + +var fileDescriptor_ac8e05fdfec588ce = []byte{ + // 220 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0x49, 0x72, 0x2e, + 0x4a, 0x4d, 0x2c, 0x49, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xa9, 0x4c, 0xcc, 0xcd, + 0x91, 0x72, 0x4c, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xcf, 0x35, 0x4e, + 0x49, 0xd2, 0xcf, 0x35, 0xd6, 0x2f, 0x2e, 0x4a, 0xd6, 0x2f, 0x2c, 0x4d, 0x2d, 0xaa, 0xd4, 0x4f, + 0x4f, 0xcd, 0x4b, 0x2d, 0x4a, 0x2c, 0x49, 0x4d, 0xd1, 0x07, 0xeb, 0xd1, 0x4f, 0x4c, 0xc9, 0xcd, + 0xcc, 0xd3, 0x4f, 0x49, 0x2c, 0x49, 0x4c, 0x4a, 0x2c, 0x86, 0x1a, 0xa4, 0xb4, 0x97, 0x91, 0x4b, + 0xd2, 0x05, 0x2a, 0x04, 0xb1, 0x21, 0x28, 0xb5, 0xb0, 0x34, 0xb5, 0xb8, 0x24, 0x32, 0x31, 0x37, + 0x47, 0xc8, 0x91, 0x8b, 0xa5, 0xa4, 0xb2, 0x20, 0x55, 0x82, 0x5d, 0x81, 0x51, 0x83, 0xcf, 0x48, + 0x57, 0x0f, 0x64, 0xab, 0x1e, 0x4e, 0xe5, 0x7a, 0xfe, 0x05, 0x20, 0x0b, 0x33, 0xf3, 0xf3, 0x42, + 0x2a, 0x0b, 0x52, 0x83, 0xc0, 0x5a, 0x85, 0xcc, 0xb8, 0xd8, 0xa1, 0x4a, 0x24, 0xf8, 0x15, 0x18, + 0x35, 0xb8, 0x8d, 0x64, 0xf4, 0xc0, 0x0e, 0xc1, 0x6e, 0x4c, 0x10, 0x4c, 0xb1, 0x92, 0x2a, 0x17, + 0x2f, 0x8a, 0x71, 0x42, 0x5c, 0x5c, 0x6c, 0xce, 0x41, 0xae, 0x8e, 0x21, 0xae, 0x02, 0x0c, 0x42, + 0x1c, 0x5c, 0x2c, 0x9e, 0x7e, 0x9e, 0x21, 0x02, 0x8c, 0x49, 0x6c, 0x60, 0x6f, 0x18, 0x03, 0x02, + 0x00, 0x00, 0xff, 0xff, 0xf6, 0x8f, 0x01, 0x1f, 0x21, 0x01, 0x00, 0x00, +} diff --git a/src/cmd/tools/m3ctl/main/yaml/load_test.go b/src/cmd/tools/m3ctl/main/yaml/load_test.go index eafc160fe6..537d68de6a 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load_test.go +++ b/src/cmd/tools/m3ctl/main/yaml/load_test.go @@ -3,9 +3,7 @@ package yaml import ( "io/ioutil" "testing" - - "github.com/m3db/m3/src/query/generated/proto/admin" - + pb "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" "github.com/gogo/protobuf/jsonpb" ) @@ -15,28 +13,33 @@ func TestLoadBasic(t *testing.T) { t.Fatalf("failed to read yaml test data:%v:\n", err) } - source := admin.DatabaseCreateRequest{} + source := pb.DatabaseCreateRequestYaml{} data, err := _load(content, &source) - dest := admin.DatabaseCreateRequest{} + dest := pb.DatabaseCreateRequestYaml{} unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} + if err := unmarshaller.Unmarshal(data, &dest); err != nil { t.Fatalf("failed to unmarshal basic test data:%v:\n", err) } - if dest.ReplicationFactor != 327 { - t.Errorf("in and out ReplicationFactor did not match:expected:%d:got:%d:\n", source.ReplicationFactor, dest.ReplicationFactor) + + if dest.Type != pb.DatabaseCreateRequestYaml_CREATE { + t.Errorf("dest type does not have the correct type:expected:%v:got:%v:", pb.DatabaseCreateRequestYaml_CREATE, dest.Type) + } + if dest.Request.ReplicationFactor != 327 { + t.Errorf("in and out ReplicationFactor did not match:expected:%d:got:%d:\n", source.Request.ReplicationFactor, dest.Request.ReplicationFactor) } - if dest.ReplicationFactor != source.ReplicationFactor { - t.Errorf("in and out ReplicationFactor did not match:expected:%d:got:%d:\n", source.ReplicationFactor, dest.ReplicationFactor) + if dest.Request.ReplicationFactor != source.Request.ReplicationFactor { + t.Errorf("in and out ReplicationFactor did not match:expected:%d:got:%d:\n", source.Request.ReplicationFactor, dest.Request.ReplicationFactor) } - if dest.NamespaceName != "default" { - t.Errorf("namespace is wrong:expected:%s:got:%s:\n", "default", dest.NamespaceName) + if dest.Request.NamespaceName != "default" { + t.Errorf("namespace is wrong:expected:%s:got:%s:\n", "default", dest.Request.NamespaceName) } - if len(dest.Hosts) != 1 { - t.Errorf("number of hosts is wrong:expected:%d:got:%d:\n", 1, len(dest.Hosts)) + if len(dest.Request.Hosts) != 1 { + t.Errorf("number of hosts is wrong:expected:%d:got:%d:\n", 1, len(dest.Request.Hosts)) } - if dest.Hosts[0].Id != "m3db_seed" { - t.Errorf("hostname is wrong:expected:%s:got:%s:\n", "m3db_seed", dest.Hosts[0]) + if dest.Request.Hosts[0].Id != "m3db_seed" { + t.Errorf("hostname is wrong:expected:%s:got:%s:\n", "m3db_seed", dest.Request.Hosts[0]) } } diff --git a/src/cmd/tools/m3ctl/main/yaml/testdata/basicCreate.yaml b/src/cmd/tools/m3ctl/main/yaml/testdata/basicCreate.yaml index 899de1cc8d..a5a513a481 100644 --- a/src/cmd/tools/m3ctl/main/yaml/testdata/basicCreate.yaml +++ b/src/cmd/tools/m3ctl/main/yaml/testdata/basicCreate.yaml @@ -1,15 +1,17 @@ --- -type: cluster -namespace_name: default -retention_time: 168h -num_shards: 64 -replication_factor: 327 -hosts: -- id: m3db_seed - isolation_group: rack-a - zone: embedded - weight: 1024 - endpoint: m3db_seed:9000 - hostname: m3db_seed - port: 9000 +operation: create +request: + type: cluster + namespace_name: default + retention_time: 168h + num_shards: 64 + replication_factor: 327 + hosts: + - id: m3db_seed + isolation_group: rack-a + zone: embedded + weight: 1024 + endpoint: m3db_seed:9000 + hostname: m3db_seed + port: 9000 diff --git a/src/cmd/tools/m3ctl/main/yaml/types.go b/src/cmd/tools/m3ctl/main/yaml/types.go new file mode 100644 index 0000000000..21e81c4392 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/yaml/types.go @@ -0,0 +1,13 @@ +package yaml + +import "github.com/m3db/m3/src/query/generated/proto/admin" + +type OP int +const ( + Create OP = iota +) + +type QQQ struct { + operation OP + admin.DatabaseCreateRequest +} From 95f239f28f5fe7a418cff69173e67d6a6ca7e092 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 2 Feb 2020 14:47:58 -0800 Subject: [PATCH 33/65] add an operation type to the yaml and wrap the existing pb --- src/cmd/tools/m3ctl/main/database/examples/create.yaml | 1 + src/cmd/tools/m3ctl/main/database/examples/devel.yaml | 1 + src/cmd/tools/m3ctl/main/delete/cmd.go | 9 ++++----- src/cmd/tools/m3ctl/main/placements/examples/init.yaml | 1 + .../tools/m3ctl/main/placements/examples/newNode.yaml | 1 + .../m3ctl/main/placements/examples/replaceNode.yaml | 1 + 6 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/cmd/tools/m3ctl/main/database/examples/create.yaml b/src/cmd/tools/m3ctl/main/database/examples/create.yaml index a9ac280f30..f4b33ceb18 100644 --- a/src/cmd/tools/m3ctl/main/database/examples/create.yaml +++ b/src/cmd/tools/m3ctl/main/database/examples/create.yaml @@ -1,4 +1,5 @@ --- +operation: create type: cluster namespace_name: 1week_namespace retention_time: 168h diff --git a/src/cmd/tools/m3ctl/main/database/examples/devel.yaml b/src/cmd/tools/m3ctl/main/database/examples/devel.yaml index 5359c9500b..c324320c12 100644 --- a/src/cmd/tools/m3ctl/main/database/examples/devel.yaml +++ b/src/cmd/tools/m3ctl/main/database/examples/devel.yaml @@ -1,4 +1,5 @@ --- +operation: create type: cluster namespace_name: default retention_time: 168h diff --git a/src/cmd/tools/m3ctl/main/delete/cmd.go b/src/cmd/tools/m3ctl/main/delete/cmd.go index b2934fd8e7..e0af109f5b 100644 --- a/src/cmd/tools/m3ctl/main/delete/cmd.go +++ b/src/cmd/tools/m3ctl/main/delete/cmd.go @@ -68,11 +68,10 @@ func (ctx Context) PopParseDispatch(cli []string) error { // pop and parse inArgs := cli[1:] - //if err := thisFlagset.Parse(inArgs); err != nil { - // thisFlagset.Usage() - // return err - //} - thisFlagset.Parse(inArgs) + if err := thisFlagset.Parse(inArgs); err != nil { + thisFlagset.Usage() + return err + } if thisFlagset.NArg() == 0 { thisFlagset.Usage() return &errors.FlagsError{} diff --git a/src/cmd/tools/m3ctl/main/placements/examples/init.yaml b/src/cmd/tools/m3ctl/main/placements/examples/init.yaml index 9f9f1f2e40..cff7140666 100644 --- a/src/cmd/tools/m3ctl/main/placements/examples/init.yaml +++ b/src/cmd/tools/m3ctl/main/placements/examples/init.yaml @@ -1,4 +1,5 @@ --- +operation: init num_shards: 64 replication_factor: 1 instances: diff --git a/src/cmd/tools/m3ctl/main/placements/examples/newNode.yaml b/src/cmd/tools/m3ctl/main/placements/examples/newNode.yaml index d1a3af2d23..c65bc50ef2 100644 --- a/src/cmd/tools/m3ctl/main/placements/examples/newNode.yaml +++ b/src/cmd/tools/m3ctl/main/placements/examples/newNode.yaml @@ -1,4 +1,5 @@ --- +operation: new_node instances: - id: node1 isolationGroup: isoGroup1 diff --git a/src/cmd/tools/m3ctl/main/placements/examples/replaceNode.yaml b/src/cmd/tools/m3ctl/main/placements/examples/replaceNode.yaml index f16eaaae84..d8d14893a4 100644 --- a/src/cmd/tools/m3ctl/main/placements/examples/replaceNode.yaml +++ b/src/cmd/tools/m3ctl/main/placements/examples/replaceNode.yaml @@ -1,4 +1,5 @@ --- +operation: replace_node leavingInstanceIDs: - oldnodeid1 candidates: From 383f9e8d4a667ed94ef0d0ec3f046d20f1499f0b Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 2 Feb 2020 17:45:40 -0800 Subject: [PATCH 34/65] checkpoint --- src/cmd/tools/m3ctl/main/yaml/load.go | 27 ++++++++++++++++++++++ src/cmd/tools/m3ctl/main/yaml/load_test.go | 6 +++++ 2 files changed, 33 insertions(+) diff --git a/src/cmd/tools/m3ctl/main/yaml/load.go b/src/cmd/tools/m3ctl/main/yaml/load.go index f9544b34cf..ca7620cb65 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load.go +++ b/src/cmd/tools/m3ctl/main/yaml/load.go @@ -6,11 +6,29 @@ import ( "io/ioutil" "log" + pb "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" + "github.com/ghodss/yaml" "github.com/gogo/protobuf/jsonpb" "github.com/gogo/protobuf/proto" ) +// this reads a yaml representation of an m3 structure +// and produces an io.Reader of it protocol buffer-encoded +// +// we don't know anything about what the user it trying to do +// but we only know how to do the things that are the keys of +// this map DatabaseCreateRequestYaml_OperationType_value +// so try to load each and take whatever works +// there's a "operation" field the user must specify to +// indicate the intent +// +// See the examples directories. +// +// the strategy is to loop over the keys of +// DatabaseCreateRequestYaml_OperationType_value +// and try to load for each +// checking the "operation" field func Load(path string, target proto.Message) io.Reader { content, err := ioutil.ReadFile(path) if err != nil { @@ -23,11 +41,20 @@ func Load(path string, target proto.Message) io.Reader { return rv } +func q() (io.Reader, error) { + + for k := range pb.DatabaseCreateRequestYaml_OperationType_value { + + } +} + // more easily testable version func _load(content []byte, target proto.Message) (io.Reader, error) { + // unmarshal it into json if err := yaml.Unmarshal(content, target); err != nil { return nil, err } + // marshal it into protocol buffers var data *bytes.Buffer data = bytes.NewBuffer(nil) marshaller := &jsonpb.Marshaler{} diff --git a/src/cmd/tools/m3ctl/main/yaml/load_test.go b/src/cmd/tools/m3ctl/main/yaml/load_test.go index 537d68de6a..c163c8a02e 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load_test.go +++ b/src/cmd/tools/m3ctl/main/yaml/load_test.go @@ -7,18 +7,24 @@ import ( "github.com/gogo/protobuf/jsonpb" ) +// this uses _load to get an encoded stream of the +// structure, then unmarshals it back into a struct +// and verifies the unmarshalled struct matches +// what was specified in the yaml func TestLoadBasic(t *testing.T) { content, err := ioutil.ReadFile("./testdata/basicCreate.yaml") if err != nil { t.Fatalf("failed to read yaml test data:%v:\n", err) } + // load the yaml and encode it source := pb.DatabaseCreateRequestYaml{} data, err := _load(content, &source) dest := pb.DatabaseCreateRequestYaml{} unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} + // unmarshal the stream back into a struct and verify it if err := unmarshaller.Unmarshal(data, &dest); err != nil { t.Fatalf("failed to unmarshal basic test data:%v:\n", err) } From d2bbeb45e15998efd5787007c4ed9add888068d6 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 2 Feb 2020 20:07:00 -0800 Subject: [PATCH 35/65] checkpoint --- src/cmd/tools/m3ctl/main/yaml/dbCreate.proto | 13 ++-- .../m3ctl/main/yaml/generated/dbCreate.pb.go | 63 ++++++------------- src/cmd/tools/m3ctl/main/yaml/load.go | 19 ++++-- src/cmd/tools/m3ctl/main/yaml/load_test.go | 39 +++++++++--- .../main/yaml/testdata/unknownOperation.yaml | 17 +++++ src/cmd/tools/m3ctl/main/yaml/types.go | 21 ++++--- 6 files changed, 101 insertions(+), 71 deletions(-) create mode 100644 src/cmd/tools/m3ctl/main/yaml/testdata/unknownOperation.yaml diff --git a/src/cmd/tools/m3ctl/main/yaml/dbCreate.proto b/src/cmd/tools/m3ctl/main/yaml/dbCreate.proto index d33f4c04fe..fb0d33d04d 100644 --- a/src/cmd/tools/m3ctl/main/yaml/dbCreate.proto +++ b/src/cmd/tools/m3ctl/main/yaml/dbCreate.proto @@ -2,12 +2,11 @@ syntax = "proto3"; package yaml; import "github.com/m3db/m3/src/query/generated/proto/admin/database.proto"; - +/* enum OperationType { + CREATE = 0; + INIT = 1; +} */ message DatabaseCreateRequestYaml { - enum OperationType { - CREATE = 0; - INIT = 1; - } - OperationType type = 7; - admin.DatabaseCreateRequest Request = 15; + string Operation = 1; + admin.DatabaseCreateRequest Request = 2; } \ No newline at end of file diff --git a/src/cmd/tools/m3ctl/main/yaml/generated/dbCreate.pb.go b/src/cmd/tools/m3ctl/main/yaml/generated/dbCreate.pb.go index 81a5bc3d95..358033c0d1 100644 --- a/src/cmd/tools/m3ctl/main/yaml/generated/dbCreate.pb.go +++ b/src/cmd/tools/m3ctl/main/yaml/generated/dbCreate.pb.go @@ -21,37 +21,16 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package -type DatabaseCreateRequestYaml_OperationType int32 - -const ( - DatabaseCreateRequestYaml_CREATE DatabaseCreateRequestYaml_OperationType = 0 - DatabaseCreateRequestYaml_INIT DatabaseCreateRequestYaml_OperationType = 1 -) - -var DatabaseCreateRequestYaml_OperationType_name = map[int32]string{ - 0: "CREATE", - 1: "INIT", -} - -var DatabaseCreateRequestYaml_OperationType_value = map[string]int32{ - "CREATE": 0, - "INIT": 1, -} - -func (x DatabaseCreateRequestYaml_OperationType) String() string { - return proto.EnumName(DatabaseCreateRequestYaml_OperationType_name, int32(x)) -} - -func (DatabaseCreateRequestYaml_OperationType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_ac8e05fdfec588ce, []int{0, 0} -} - +// enum OperationType { +//CREATE = 0; +//INIT = 1; +//} type DatabaseCreateRequestYaml struct { - Type DatabaseCreateRequestYaml_OperationType `protobuf:"varint,7,opt,name=type,proto3,enum=yaml.DatabaseCreateRequestYaml_OperationType" json:"type,omitempty"` - Request *admin.DatabaseCreateRequest `protobuf:"bytes,15,opt,name=Request,proto3" json:"Request,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Operation string `protobuf:"bytes,1,opt,name=Operation,proto3" json:"Operation,omitempty"` + Request *admin.DatabaseCreateRequest `protobuf:"bytes,2,opt,name=Request,proto3" json:"Request,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *DatabaseCreateRequestYaml) Reset() { *m = DatabaseCreateRequestYaml{} } @@ -79,11 +58,11 @@ func (m *DatabaseCreateRequestYaml) XXX_DiscardUnknown() { var xxx_messageInfo_DatabaseCreateRequestYaml proto.InternalMessageInfo -func (m *DatabaseCreateRequestYaml) GetType() DatabaseCreateRequestYaml_OperationType { +func (m *DatabaseCreateRequestYaml) GetOperation() string { if m != nil { - return m.Type + return m.Operation } - return DatabaseCreateRequestYaml_CREATE + return "" } func (m *DatabaseCreateRequestYaml) GetRequest() *admin.DatabaseCreateRequest { @@ -94,26 +73,22 @@ func (m *DatabaseCreateRequestYaml) GetRequest() *admin.DatabaseCreateRequest { } func init() { - proto.RegisterEnum("yaml.DatabaseCreateRequestYaml_OperationType", DatabaseCreateRequestYaml_OperationType_name, DatabaseCreateRequestYaml_OperationType_value) proto.RegisterType((*DatabaseCreateRequestYaml)(nil), "yaml.DatabaseCreateRequestYaml") } func init() { proto.RegisterFile("dbCreate.proto", fileDescriptor_ac8e05fdfec588ce) } var fileDescriptor_ac8e05fdfec588ce = []byte{ - // 220 bytes of a gzipped FileDescriptorProto + // 174 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0x49, 0x72, 0x2e, 0x4a, 0x4d, 0x2c, 0x49, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xa9, 0x4c, 0xcc, 0xcd, 0x91, 0x72, 0x4c, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xcf, 0x35, 0x4e, 0x49, 0xd2, 0xcf, 0x35, 0xd6, 0x2f, 0x2e, 0x4a, 0xd6, 0x2f, 0x2c, 0x4d, 0x2d, 0xaa, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0x4a, 0x2c, 0x49, 0x4d, 0xd1, 0x07, 0xeb, 0xd1, 0x4f, 0x4c, 0xc9, 0xcd, - 0xcc, 0xd3, 0x4f, 0x49, 0x2c, 0x49, 0x4c, 0x4a, 0x2c, 0x86, 0x1a, 0xa4, 0xb4, 0x97, 0x91, 0x4b, - 0xd2, 0x05, 0x2a, 0x04, 0xb1, 0x21, 0x28, 0xb5, 0xb0, 0x34, 0xb5, 0xb8, 0x24, 0x32, 0x31, 0x37, - 0x47, 0xc8, 0x91, 0x8b, 0xa5, 0xa4, 0xb2, 0x20, 0x55, 0x82, 0x5d, 0x81, 0x51, 0x83, 0xcf, 0x48, - 0x57, 0x0f, 0x64, 0xab, 0x1e, 0x4e, 0xe5, 0x7a, 0xfe, 0x05, 0x20, 0x0b, 0x33, 0xf3, 0xf3, 0x42, - 0x2a, 0x0b, 0x52, 0x83, 0xc0, 0x5a, 0x85, 0xcc, 0xb8, 0xd8, 0xa1, 0x4a, 0x24, 0xf8, 0x15, 0x18, - 0x35, 0xb8, 0x8d, 0x64, 0xf4, 0xc0, 0x0e, 0xc1, 0x6e, 0x4c, 0x10, 0x4c, 0xb1, 0x92, 0x2a, 0x17, - 0x2f, 0x8a, 0x71, 0x42, 0x5c, 0x5c, 0x6c, 0xce, 0x41, 0xae, 0x8e, 0x21, 0xae, 0x02, 0x0c, 0x42, - 0x1c, 0x5c, 0x2c, 0x9e, 0x7e, 0x9e, 0x21, 0x02, 0x8c, 0x49, 0x6c, 0x60, 0x6f, 0x18, 0x03, 0x02, - 0x00, 0x00, 0xff, 0xff, 0xf6, 0x8f, 0x01, 0x1f, 0x21, 0x01, 0x00, 0x00, + 0xcc, 0xd3, 0x4f, 0x49, 0x2c, 0x49, 0x4c, 0x4a, 0x2c, 0x86, 0x1a, 0xa4, 0x54, 0xc8, 0x25, 0xe9, + 0x02, 0x15, 0x81, 0x58, 0x10, 0x94, 0x5a, 0x58, 0x9a, 0x5a, 0x5c, 0x12, 0x99, 0x98, 0x9b, 0x23, + 0x24, 0xc3, 0xc5, 0xe9, 0x5f, 0x00, 0x32, 0x23, 0x33, 0x3f, 0x4f, 0x82, 0x51, 0x81, 0x51, 0x83, + 0x33, 0x08, 0x21, 0x20, 0x64, 0xc6, 0xc5, 0x0e, 0x55, 0x2c, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x6d, + 0x24, 0xa3, 0x07, 0xb6, 0x42, 0x0f, 0xab, 0x81, 0x41, 0x30, 0xc5, 0x49, 0x6c, 0x60, 0x9b, 0x8d, + 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x6d, 0xb1, 0x77, 0xc1, 0xd4, 0x00, 0x00, 0x00, } diff --git a/src/cmd/tools/m3ctl/main/yaml/load.go b/src/cmd/tools/m3ctl/main/yaml/load.go index ca7620cb65..89c07d09c7 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load.go +++ b/src/cmd/tools/m3ctl/main/yaml/load.go @@ -2,6 +2,7 @@ package yaml import ( "bytes" + "fmt" "io" "io/ioutil" "log" @@ -29,23 +30,31 @@ import ( // DatabaseCreateRequestYaml_OperationType_value // and try to load for each // checking the "operation" field -func Load(path string, target proto.Message) io.Reader { +//func Load(path string, target proto.Message) io.Reader { +func Load(path string) io.Reader { content, err := ioutil.ReadFile(path) if err != nil { log.Fatal(err) } - rv, err := _load(content, target) + //rv, err := _load(content, target) + rv, err := decodeKnownOps(content) if err != nil { log.Fatalf("cannot unmarshal data:%v:from yaml file:%s:", err, path) } return rv } -func q() (io.Reader, error) { - - for k := range pb.DatabaseCreateRequestYaml_OperationType_value { +func decodeKnownOps(data []byte) (io.Reader, error) { + createReq := &pb.DatabaseCreateRequestYaml{} + if rv, err := _load(data, createReq); err != nil { + return rv, err + } else if createReq.Operation == opCreate { + return rv, nil } + + return nil, fmt.Errorf("Unknown operation specified in the yaml\n") + } // more easily testable version diff --git a/src/cmd/tools/m3ctl/main/yaml/load_test.go b/src/cmd/tools/m3ctl/main/yaml/load_test.go index c163c8a02e..6494cbdae9 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load_test.go +++ b/src/cmd/tools/m3ctl/main/yaml/load_test.go @@ -16,21 +16,20 @@ func TestLoadBasic(t *testing.T) { if err != nil { t.Fatalf("failed to read yaml test data:%v:\n", err) } - // load the yaml and encode it source := pb.DatabaseCreateRequestYaml{} data, err := _load(content, &source) - + if err != nil { + t.Fatalf("failed to encode the basic test data:%v:\n", err) + } dest := pb.DatabaseCreateRequestYaml{} unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} - // unmarshal the stream back into a struct and verify it if err := unmarshaller.Unmarshal(data, &dest); err != nil { t.Fatalf("failed to unmarshal basic test data:%v:\n", err) } - - if dest.Type != pb.DatabaseCreateRequestYaml_CREATE { - t.Errorf("dest type does not have the correct type:expected:%v:got:%v:", pb.DatabaseCreateRequestYaml_CREATE, dest.Type) + if dest.Operation != opCreate { + t.Errorf("dest type does not have the correct type:expected:%v:got:%v:", opCreate, dest.Operation) } if dest.Request.ReplicationFactor != 327 { t.Errorf("in and out ReplicationFactor did not match:expected:%d:got:%d:\n", source.Request.ReplicationFactor, dest.Request.ReplicationFactor) @@ -47,5 +46,31 @@ func TestLoadBasic(t *testing.T) { if dest.Request.Hosts[0].Id != "m3db_seed" { t.Errorf("hostname is wrong:expected:%s:got:%s:\n", "m3db_seed", dest.Request.Hosts[0]) } - +} +func TestOperationSelectorPositive(t *testing.T) { + content, err := ioutil.ReadFile("./testdata/basicCreate.yaml") + if err != nil { + t.Fatalf("failed to read yaml test data:%v:\n", err) + } + data, err := decodeKnownOps(content) + if err != nil { + t.Fatalf("operation selector failed to encode the unknown operation yaml test data:%v:\n", err) + } + dest := pb.DatabaseCreateRequestYaml{} + unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} + if err := unmarshaller.Unmarshal(data, &dest); err != nil { + t.Fatalf("operation selector failed to unmarshal unknown operation data:%v:\n", err) + } + if dest.Operation != opCreate { + t.Errorf("dest type does not have the correct type via operation selector:expected:%v:got:%v:", opInit, dest.Operation) + } +} +func TestOperationSelectorNegative(t *testing.T) { + content, err := ioutil.ReadFile("./testdata/unknownOperation.yaml") + if err != nil { + t.Fatalf("failed to read yaml test data:%v:\n", err) + } + if _, err = decodeKnownOps(content); err == nil { + t.Fatalf("operation selector should have returned an error\n") + } } diff --git a/src/cmd/tools/m3ctl/main/yaml/testdata/unknownOperation.yaml b/src/cmd/tools/m3ctl/main/yaml/testdata/unknownOperation.yaml new file mode 100644 index 0000000000..2d2b3298b7 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/yaml/testdata/unknownOperation.yaml @@ -0,0 +1,17 @@ +--- +operation: nonesuch +request: + type: cluster + namespace_name: default + retention_time: 168h + num_shards: 64 + replication_factor: 327 + hosts: + - id: m3db_seed + isolation_group: rack-a + zone: embedded + weight: 1024 + endpoint: m3db_seed:9000 + hostname: m3db_seed + port: 9000 + diff --git a/src/cmd/tools/m3ctl/main/yaml/types.go b/src/cmd/tools/m3ctl/main/yaml/types.go index 21e81c4392..9c69ca71bd 100644 --- a/src/cmd/tools/m3ctl/main/yaml/types.go +++ b/src/cmd/tools/m3ctl/main/yaml/types.go @@ -1,13 +1,18 @@ package yaml -import "github.com/m3db/m3/src/query/generated/proto/admin" - -type OP int const ( - Create OP = iota + opCreate = "create" + opInit = "init" + opReplace = "replaceNode" + opNewNode = "newNode" ) -type QQQ struct { - operation OP - admin.DatabaseCreateRequest -} +//type OP int +//const ( +// Create OP = iota +//) +// +//type QQQ struct { +// operation OP +// admin.DatabaseCreateRequest +//} From be670f1774fb338d04b3d70c7a98c3151c4d9354 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Mon, 3 Feb 2020 15:38:28 -0800 Subject: [PATCH 36/65] loader is working and tests are passing --- src/cmd/tools/m3ctl/main/apply/apply.go | 15 ++++ src/cmd/tools/m3ctl/main/apply/cmd.go | 80 +++++++++++++++++++ src/cmd/tools/m3ctl/main/database/create.go | 22 ++--- src/cmd/tools/m3ctl/main/main.go | 20 +++-- src/cmd/tools/m3ctl/main/placements/add.go | 11 +-- src/cmd/tools/m3ctl/main/placements/init.go | 11 +-- .../tools/m3ctl/main/placements/replace.go | 14 ++-- src/cmd/tools/m3ctl/main/yaml/load.go | 39 ++++++--- src/cmd/tools/m3ctl/main/yaml/load_test.go | 17 +++- src/cmd/tools/m3ctl/main/yaml/types.go | 1 + 10 files changed, 172 insertions(+), 58 deletions(-) create mode 100644 src/cmd/tools/m3ctl/main/apply/apply.go diff --git a/src/cmd/tools/m3ctl/main/apply/apply.go b/src/cmd/tools/m3ctl/main/apply/apply.go new file mode 100644 index 0000000000..ea56a26ca2 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/apply/apply.go @@ -0,0 +1,15 @@ +package apply + +import ( + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" +) + +func Apply(vals *applyArgs, globals checkArgs.GlobalOpts) { + path, data := yaml.Load(vals.yamlFlag.Value[0]) + url := fmt.Sprintf("%s%s", globals.Endpoint, path) + client.DoPost(url, data, client.Dumper) + return +} diff --git a/src/cmd/tools/m3ctl/main/apply/cmd.go b/src/cmd/tools/m3ctl/main/apply/cmd.go index 5e189fa9f5..db20bd5ae7 100644 --- a/src/cmd/tools/m3ctl/main/apply/cmd.go +++ b/src/cmd/tools/m3ctl/main/apply/cmd.go @@ -1,3 +1,83 @@ package apply +import ( + "flag" + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" + "github.com/m3db/m3/src/x/config/configflag" + "os" +) + +type applyArgs struct { + yamlFlag *configflag.FlagStringSlice +} + +type Context struct { + vals *applyArgs + handlers applyHandlers + GlobalOpts checkArgs.GlobalOpts + Apply *flag.FlagSet +} +type applyHandlers struct { + xget func(*applyArgs, checkArgs.GlobalOpts) +} + +func InitializeFlags() Context { + return _setupFlags( + &applyArgs{ + yamlFlag: &configflag.FlagStringSlice{}, + }, + applyHandlers{ + xget: Apply, + }) +} +func _setupFlags(finalArgs *applyArgs, handlers applyHandlers) Context { + + applyFlags := flag.NewFlagSet("apply", flag.ContinueOnError) + applyFlags.Var(finalArgs.yamlFlag, "f", "Path to yaml.") + + applyFlags.Usage = func() { + fmt.Fprintf(os.Stderr, "help msg here for apply\n") + applyFlags.PrintDefaults() + } + + return Context{ + vals: finalArgs, + Apply: applyFlags, + handlers: handlers, + } +} + +func (ctx Context) PopParseDispatch(cli []string) error { + if len(cli) < 1 { + ctx.Apply.Usage() + return &errors.FlagsError{} + } + + inArgs := cli[1:] + if err := ctx.Apply.Parse(inArgs); err != nil { + ctx.Apply.Usage() + return &errors.FlagsError{} + } + if ctx.Apply.NFlag() != 1 { + ctx.Apply.Usage() + return &errors.FlagsError{} + } + + if err := dispatcher(ctx); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + return err + } + + return nil + +} + +// no dispatching here +// there are no subcommands +func dispatcher(ctx Context) error { + ctx.handlers.xget(ctx.vals, ctx.GlobalOpts) + return nil +} diff --git a/src/cmd/tools/m3ctl/main/database/create.go b/src/cmd/tools/m3ctl/main/database/create.go index b63c427056..9a339dfbda 100644 --- a/src/cmd/tools/m3ctl/main/database/create.go +++ b/src/cmd/tools/m3ctl/main/database/create.go @@ -1,18 +1,18 @@ package database import ( - "fmt" - "log" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" - "github.com/m3db/m3/src/query/generated/proto/admin" + //"fmt" + //"log" + // + //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" + //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" + //"github.com/m3db/m3/src/query/generated/proto/admin" ) func Create(createYAML string, endpoint string) { - log.Printf("createYAML:%s:\n", createYAML) - data := yaml.Load(createYAML, &admin.DatabaseCreateRequest{}) - url := fmt.Sprintf("%s%s/create", endpoint, defaultPath) - client.DoPost(url, data, client.Dumper) - return + //log.Printf("createYAML:%s:\n", createYAML) + //data := yaml.Load(createYAML, &admin.DatabaseCreateRequest{}) + //url := fmt.Sprintf("%s%s/create", endpoint, defaultPath) + //client.DoPost(url, data, client.Dumper) + //return } diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 5c46cc3275..d08ca3498d 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -23,13 +23,10 @@ package main import ( "flag" "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/get" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/apply" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/delete" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/get" "os" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/database" - //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/namespaces" - "github.com/m3db/m3/src/x/config/configflag" ) const ( @@ -43,8 +40,8 @@ func main() { // hooks and context for the next level // the database-related subcommand - createDatabaseYAML := configflag.FlagStringSlice{} - databaseFlagSets := database.SetupFlags(&createDatabaseYAML) + //createDatabaseYAML := configflag.FlagStringSlice{} + //databaseFlagSets := database.SetupFlags(&createDatabaseYAML) // the namespace-related subcommand //namespaceArgs := namespaces.NamespaceArgs{} @@ -53,6 +50,7 @@ func main() { //placementFlagSets := placements.InitializeFlags() getFlagSets := get.InitializeFlags() deleteFlagSets := delete.InitializeFlags() + applyFlagSets := apply.InitializeFlags() flag.Usage = func() { fmt.Fprintf(flag.CommandLine.Output(), ` @@ -66,7 +64,7 @@ Usage of %s: Each subcommand has its own built-in help provided via "-h". -`, os.Args[0], databaseFlagSets.Database.Name(), +`, os.Args[0], applyFlagSets.Apply.Name(), //placementFlagSets.Placement.Name(), getFlagSets.Get.Name(), deleteFlagSets.Delete.Name()) @@ -104,6 +102,12 @@ Each subcommand has its own built-in help provided via "-h". fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } + case applyFlagSets.Apply.Name(): + applyFlagSets.GlobalOpts.Endpoint = *endPoint + if err := applyFlagSets.PopParseDispatch(flag.Args()); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } default: flag.Usage() os.Exit(1) diff --git a/src/cmd/tools/m3ctl/main/placements/add.go b/src/cmd/tools/m3ctl/main/placements/add.go index c77418fbaa..4184a82004 100644 --- a/src/cmd/tools/m3ctl/main/placements/add.go +++ b/src/cmd/tools/m3ctl/main/placements/add.go @@ -1,18 +1,13 @@ package placements import ( - "fmt" "log" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" - "github.com/m3db/m3/src/query/generated/proto/admin" ) func doAdd(s placementArgs, endpoint string) { log.Printf("placementArgs:%+v:\n", s) - data := yaml.Load(s.newNodeFlag.Value[0], &admin.PlacementInitRequest{}) - url := fmt.Sprintf("%s%s", endpoint, DefaultPath) - client.DoPost(url, data, client.Dumper) + //data := yaml.Load(s.newNodeFlag.Value[0], &admin.PlacementInitRequest{}) + //url := fmt.Sprintf("%s%s", endpoint, DefaultPath) + //client.DoPost(url, data, client.Dumper) return } diff --git a/src/cmd/tools/m3ctl/main/placements/init.go b/src/cmd/tools/m3ctl/main/placements/init.go index 24da13a2fe..ff2cdeae0f 100644 --- a/src/cmd/tools/m3ctl/main/placements/init.go +++ b/src/cmd/tools/m3ctl/main/placements/init.go @@ -1,18 +1,13 @@ package placements import ( - "fmt" "log" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" - "github.com/m3db/m3/src/query/generated/proto/admin" ) func doInit(s placementArgs, endpoint string) { log.Printf("placementArgs:%+v:\n", s) - data := yaml.Load(s.initFlag.Value[0], &admin.PlacementInitRequest{}) - url := fmt.Sprintf("%s%s%s", endpoint, DefaultPath, "/init") - client.DoPost(url, data, client.Dumper) + //data := yaml.Load(s.initFlag.Value[0], &admin.PlacementInitRequest{}) + //url := fmt.Sprintf("%s%s%s", endpoint, DefaultPath, "/init") + //client.DoPost(url, data, client.Dumper) return } diff --git a/src/cmd/tools/m3ctl/main/placements/replace.go b/src/cmd/tools/m3ctl/main/placements/replace.go index 3da9eec105..30acdc83f4 100644 --- a/src/cmd/tools/m3ctl/main/placements/replace.go +++ b/src/cmd/tools/m3ctl/main/placements/replace.go @@ -1,16 +1,16 @@ package placements import ( - "fmt" + //"fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" - "github.com/m3db/m3/src/query/generated/proto/admin" + //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" + //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" + //"github.com/m3db/m3/src/query/generated/proto/admin" ) func doReplace(s placementArgs, endpoint string) { - data := yaml.Load(s.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}) - url := fmt.Sprintf("%s%s%s", endpoint, DefaultPath, "/replace") - client.DoPost(url, data, client.Dumper) + //data := yaml.Load(s.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}) + //url := fmt.Sprintf("%s%s%s", endpoint, DefaultPath, "/replace") + //client.DoPost(url, data, client.Dumper) return } diff --git a/src/cmd/tools/m3ctl/main/yaml/load.go b/src/cmd/tools/m3ctl/main/yaml/load.go index 89c07d09c7..15870b3d87 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load.go +++ b/src/cmd/tools/m3ctl/main/yaml/load.go @@ -30,34 +30,47 @@ import ( // DatabaseCreateRequestYaml_OperationType_value // and try to load for each // checking the "operation" field -//func Load(path string, target proto.Message) io.Reader { -func Load(path string) io.Reader { +func Load(path string) (string, io.Reader) { content, err := ioutil.ReadFile(path) if err != nil { log.Fatal(err) } - //rv, err := _load(content, target) - rv, err := decodeKnownOps(content) + url, pbmessage, err := decodeKnownOps(content) if err != nil { log.Fatalf("cannot unmarshal data:%v:from yaml file:%s:", err, path) } - return rv + + rv, err := _load(content, pbmessage) + + return url, rv } -func decodeKnownOps(data []byte) (io.Reader, error) { +// peek into the yaml to see what it is expected to be +// don't try to decode the entire thing since its +// going into something that's currently unknown +// so just grab the "operation" then dispatch +// +// returns the url path, proto.Message, and error +func decodeKnownOps(data []byte) (string, proto.Message, error) { + + type peeker struct { + Operation string + } - createReq := &pb.DatabaseCreateRequestYaml{} - if rv, err := _load(data, createReq); err != nil { - return rv, err - } else if createReq.Operation == opCreate { - return rv, nil + peek := &peeker{} + if err := yaml.Unmarshal(data, &peek); err != nil { + return "", nil, err } - return nil, fmt.Errorf("Unknown operation specified in the yaml\n") + switch peek.Operation { + case opCreate: + return dbcreatePath, &pb.DatabaseCreateRequestYaml{}, nil + default: + return "", nil, fmt.Errorf("Unknown operation specified in the yaml\n") + } } -// more easily testable version func _load(content []byte, target proto.Message) (io.Reader, error) { // unmarshal it into json if err := yaml.Unmarshal(content, target); err != nil { diff --git a/src/cmd/tools/m3ctl/main/yaml/load_test.go b/src/cmd/tools/m3ctl/main/yaml/load_test.go index 6494cbdae9..433650461f 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load_test.go +++ b/src/cmd/tools/m3ctl/main/yaml/load_test.go @@ -52,17 +52,28 @@ func TestOperationSelectorPositive(t *testing.T) { if err != nil { t.Fatalf("failed to read yaml test data:%v:\n", err) } - data, err := decodeKnownOps(content) + urlpath, pbmessage, err := decodeKnownOps(content) if err != nil { t.Fatalf("operation selector failed to encode the unknown operation yaml test data:%v:\n", err) } + + if urlpath != dbcreatePath { + t.Errorf("urlpath is wrong:expected:%s:got:%s:\n", dbcreatePath, urlpath) + } + + data, err := _load(content, pbmessage) + if err != nil { + t.Fatalf("failed to encode to protocol:%v:\n", err) + } + dest := pb.DatabaseCreateRequestYaml{} unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} if err := unmarshaller.Unmarshal(data, &dest); err != nil { t.Fatalf("operation selector failed to unmarshal unknown operation data:%v:\n", err) } + if dest.Operation != opCreate { - t.Errorf("dest type does not have the correct type via operation selector:expected:%v:got:%v:", opInit, dest.Operation) + t.Errorf("dest type does not have the correct type via operation selector:expected:%v:got:%v:", opCreate, dest.Operation) } } func TestOperationSelectorNegative(t *testing.T) { @@ -70,7 +81,7 @@ func TestOperationSelectorNegative(t *testing.T) { if err != nil { t.Fatalf("failed to read yaml test data:%v:\n", err) } - if _, err = decodeKnownOps(content); err == nil { + if _, _, err := decodeKnownOps(content); err == nil { t.Fatalf("operation selector should have returned an error\n") } } diff --git a/src/cmd/tools/m3ctl/main/yaml/types.go b/src/cmd/tools/m3ctl/main/yaml/types.go index 9c69ca71bd..ff8b9774c1 100644 --- a/src/cmd/tools/m3ctl/main/yaml/types.go +++ b/src/cmd/tools/m3ctl/main/yaml/types.go @@ -5,6 +5,7 @@ const ( opInit = "init" opReplace = "replaceNode" opNewNode = "newNode" + dbcreatePath = "/api/v1/database/create" ) //type OP int From 1f8bfe5e72e15acc2652a0c562bbc5c6a38014e6 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Mon, 3 Feb 2020 16:26:11 -0800 Subject: [PATCH 37/65] all commands work and tests pass. next add zap then cleanup --- .../main/placements/examples/newNode.yaml | 2 +- .../main/placements/examples/replaceNode.yaml | 2 +- .../tools/m3ctl/main/placements/replace.go | 2 + src/cmd/tools/m3ctl/main/yaml/dbCreate.proto | 4 - .../m3ctl/main/yaml/examples/create.yaml | 27 ++++ .../m3ctl/main/yaml/examples/develdb.yaml | 16 ++ .../tools/m3ctl/main/yaml/examples/init.yaml | 26 ++++ .../m3ctl/main/yaml/examples/newNode.yaml | 11 ++ .../m3ctl/main/yaml/examples/replaceNode.yaml | 13 ++ .../m3ctl/main/yaml/generated/placement.pb.go | 140 ++++++++++++++++++ src/cmd/tools/m3ctl/main/yaml/load.go | 43 +----- src/cmd/tools/m3ctl/main/yaml/load_test.go | 4 +- src/cmd/tools/m3ctl/main/yaml/peeker.go | 41 +++++ src/cmd/tools/m3ctl/main/yaml/placement.proto | 12 ++ src/cmd/tools/m3ctl/main/yaml/types.go | 1 + 15 files changed, 296 insertions(+), 48 deletions(-) create mode 100644 src/cmd/tools/m3ctl/main/yaml/examples/create.yaml create mode 100644 src/cmd/tools/m3ctl/main/yaml/examples/develdb.yaml create mode 100644 src/cmd/tools/m3ctl/main/yaml/examples/init.yaml create mode 100644 src/cmd/tools/m3ctl/main/yaml/examples/newNode.yaml create mode 100644 src/cmd/tools/m3ctl/main/yaml/examples/replaceNode.yaml create mode 100644 src/cmd/tools/m3ctl/main/yaml/generated/placement.pb.go create mode 100644 src/cmd/tools/m3ctl/main/yaml/peeker.go create mode 100644 src/cmd/tools/m3ctl/main/yaml/placement.proto diff --git a/src/cmd/tools/m3ctl/main/placements/examples/newNode.yaml b/src/cmd/tools/m3ctl/main/placements/examples/newNode.yaml index c65bc50ef2..8e735a4080 100644 --- a/src/cmd/tools/m3ctl/main/placements/examples/newNode.yaml +++ b/src/cmd/tools/m3ctl/main/placements/examples/newNode.yaml @@ -1,5 +1,5 @@ --- -operation: new_node +operation: newNode instances: - id: node1 isolationGroup: isoGroup1 diff --git a/src/cmd/tools/m3ctl/main/placements/examples/replaceNode.yaml b/src/cmd/tools/m3ctl/main/placements/examples/replaceNode.yaml index d8d14893a4..102b90f3ee 100644 --- a/src/cmd/tools/m3ctl/main/placements/examples/replaceNode.yaml +++ b/src/cmd/tools/m3ctl/main/placements/examples/replaceNode.yaml @@ -1,5 +1,5 @@ --- -operation: replace_node +operation: replaceNode leavingInstanceIDs: - oldnodeid1 candidates: diff --git a/src/cmd/tools/m3ctl/main/placements/replace.go b/src/cmd/tools/m3ctl/main/placements/replace.go index 30acdc83f4..40d23ae656 100644 --- a/src/cmd/tools/m3ctl/main/placements/replace.go +++ b/src/cmd/tools/m3ctl/main/placements/replace.go @@ -5,7 +5,9 @@ import ( //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" + //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" //"github.com/m3db/m3/src/query/generated/proto/admin" + //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" ) func doReplace(s placementArgs, endpoint string) { diff --git a/src/cmd/tools/m3ctl/main/yaml/dbCreate.proto b/src/cmd/tools/m3ctl/main/yaml/dbCreate.proto index fb0d33d04d..8c12db8072 100644 --- a/src/cmd/tools/m3ctl/main/yaml/dbCreate.proto +++ b/src/cmd/tools/m3ctl/main/yaml/dbCreate.proto @@ -2,10 +2,6 @@ syntax = "proto3"; package yaml; import "github.com/m3db/m3/src/query/generated/proto/admin/database.proto"; -/* enum OperationType { - CREATE = 0; - INIT = 1; -} */ message DatabaseCreateRequestYaml { string Operation = 1; admin.DatabaseCreateRequest Request = 2; diff --git a/src/cmd/tools/m3ctl/main/yaml/examples/create.yaml b/src/cmd/tools/m3ctl/main/yaml/examples/create.yaml new file mode 100644 index 0000000000..f4b33ceb18 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/yaml/examples/create.yaml @@ -0,0 +1,27 @@ +--- +operation: create +type: cluster +namespace_name: 1week_namespace +retention_time: 168h +num_shards: 1024 +replication_factor: 3 +hosts: +- id: m3db001 + isolationGroup: us-east1-a + zone: embedded + weight: 100 + address: 10.142.0.1 + port: 9000 +- id: m3db002 + isolationGroup: us-east1-b + zone: embedded + weight: 100 + address: 10.142.0.2 + port: 9000 +- id: m3db003 + isolationGroup: us-east1-c + zone: embedded + weight: 100 + address: 10.142.0.3 + port: 9000 + diff --git a/src/cmd/tools/m3ctl/main/yaml/examples/develdb.yaml b/src/cmd/tools/m3ctl/main/yaml/examples/develdb.yaml new file mode 100644 index 0000000000..c324320c12 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/yaml/examples/develdb.yaml @@ -0,0 +1,16 @@ +--- +operation: create +type: cluster +namespace_name: default +retention_time: 168h +num_shards: 64 +replication_factor: 1 +hosts: +- id: m3db_seed + isolation_group: rack-a + zone: embedded + weight: 1024 + endpoint: m3db_seed:9000 + hostname: m3db_seed + port: 9000 + diff --git a/src/cmd/tools/m3ctl/main/yaml/examples/init.yaml b/src/cmd/tools/m3ctl/main/yaml/examples/init.yaml new file mode 100644 index 0000000000..cff7140666 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/yaml/examples/init.yaml @@ -0,0 +1,26 @@ +--- +operation: init +num_shards: 64 +replication_factor: 1 +instances: + - id: nodeid1 + isolation_group: isogroup1 + zone: etcd1 + weight: 100 + endpoint: node1:9000 + hostname: node1 + port: 9000 + - id: nodeid2 + isolation_group: isogroup2 + zone: etcd1 + weight: 100 + endpoint: node2:9000 + hostname: node2 + port: 9000 + - id: nodeid3 + isolation_group: isogroup3 + zone: etcd1 + weight: 100 + endpoint: node3:9000 + hostname: node3 + port: 9000 diff --git a/src/cmd/tools/m3ctl/main/yaml/examples/newNode.yaml b/src/cmd/tools/m3ctl/main/yaml/examples/newNode.yaml new file mode 100644 index 0000000000..8e735a4080 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/yaml/examples/newNode.yaml @@ -0,0 +1,11 @@ +--- +operation: newNode +instances: + - id: node1 + isolationGroup: isoGroup1 + zone: embedded + weight: 100 + endpoint: targetHostname1:9000 + hostname: newNodeHostname1 + port: 9000 + diff --git a/src/cmd/tools/m3ctl/main/yaml/examples/replaceNode.yaml b/src/cmd/tools/m3ctl/main/yaml/examples/replaceNode.yaml new file mode 100644 index 0000000000..102b90f3ee --- /dev/null +++ b/src/cmd/tools/m3ctl/main/yaml/examples/replaceNode.yaml @@ -0,0 +1,13 @@ +--- +operation: replaceNode +leavingInstanceIDs: +- oldnodeid1 +candidates: +- id: newnodeid1 + isolationGroup: newnodeisogroup1 + zone: etcdzone1 + weight: 100 + endpoint: node11:9000 + hostname: node11 + port: 9000 + diff --git a/src/cmd/tools/m3ctl/main/yaml/generated/placement.pb.go b/src/cmd/tools/m3ctl/main/yaml/generated/placement.pb.go new file mode 100644 index 0000000000..dce3e3eeac --- /dev/null +++ b/src/cmd/tools/m3ctl/main/yaml/generated/placement.pb.go @@ -0,0 +1,140 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: placement.proto + +package yaml + +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + admin "github.com/m3db/m3/src/query/generated/proto/admin" + math "math" +) + +// 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 PlacementInitRequestYaml struct { + Operation string `protobuf:"bytes,1,opt,name=Operation,proto3" json:"Operation,omitempty"` + Request *admin.PlacementInitRequest `protobuf:"bytes,2,opt,name=Request,proto3" json:"Request,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PlacementInitRequestYaml) Reset() { *m = PlacementInitRequestYaml{} } +func (m *PlacementInitRequestYaml) String() string { return proto.CompactTextString(m) } +func (*PlacementInitRequestYaml) ProtoMessage() {} +func (*PlacementInitRequestYaml) Descriptor() ([]byte, []int) { + return fileDescriptor_ae0216eeb0d08e49, []int{0} +} + +func (m *PlacementInitRequestYaml) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PlacementInitRequestYaml.Unmarshal(m, b) +} +func (m *PlacementInitRequestYaml) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PlacementInitRequestYaml.Marshal(b, m, deterministic) +} +func (m *PlacementInitRequestYaml) XXX_Merge(src proto.Message) { + xxx_messageInfo_PlacementInitRequestYaml.Merge(m, src) +} +func (m *PlacementInitRequestYaml) XXX_Size() int { + return xxx_messageInfo_PlacementInitRequestYaml.Size(m) +} +func (m *PlacementInitRequestYaml) XXX_DiscardUnknown() { + xxx_messageInfo_PlacementInitRequestYaml.DiscardUnknown(m) +} + +var xxx_messageInfo_PlacementInitRequestYaml proto.InternalMessageInfo + +func (m *PlacementInitRequestYaml) GetOperation() string { + if m != nil { + return m.Operation + } + return "" +} + +func (m *PlacementInitRequestYaml) GetRequest() *admin.PlacementInitRequest { + if m != nil { + return m.Request + } + return nil +} + +type PlacementReplaceRequestYaml struct { + Operation string `protobuf:"bytes,3,opt,name=Operation,proto3" json:"Operation,omitempty"` + Request *admin.PlacementReplaceRequest `protobuf:"bytes,4,opt,name=Request,proto3" json:"Request,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PlacementReplaceRequestYaml) Reset() { *m = PlacementReplaceRequestYaml{} } +func (m *PlacementReplaceRequestYaml) String() string { return proto.CompactTextString(m) } +func (*PlacementReplaceRequestYaml) ProtoMessage() {} +func (*PlacementReplaceRequestYaml) Descriptor() ([]byte, []int) { + return fileDescriptor_ae0216eeb0d08e49, []int{1} +} + +func (m *PlacementReplaceRequestYaml) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_PlacementReplaceRequestYaml.Unmarshal(m, b) +} +func (m *PlacementReplaceRequestYaml) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_PlacementReplaceRequestYaml.Marshal(b, m, deterministic) +} +func (m *PlacementReplaceRequestYaml) XXX_Merge(src proto.Message) { + xxx_messageInfo_PlacementReplaceRequestYaml.Merge(m, src) +} +func (m *PlacementReplaceRequestYaml) XXX_Size() int { + return xxx_messageInfo_PlacementReplaceRequestYaml.Size(m) +} +func (m *PlacementReplaceRequestYaml) XXX_DiscardUnknown() { + xxx_messageInfo_PlacementReplaceRequestYaml.DiscardUnknown(m) +} + +var xxx_messageInfo_PlacementReplaceRequestYaml proto.InternalMessageInfo + +func (m *PlacementReplaceRequestYaml) GetOperation() string { + if m != nil { + return m.Operation + } + return "" +} + +func (m *PlacementReplaceRequestYaml) GetRequest() *admin.PlacementReplaceRequest { + if m != nil { + return m.Request + } + return nil +} + +func init() { + proto.RegisterType((*PlacementInitRequestYaml)(nil), "yaml.PlacementInitRequestYaml") + proto.RegisterType((*PlacementReplaceRequestYaml)(nil), "yaml.PlacementReplaceRequestYaml") +} + +func init() { proto.RegisterFile("placement.proto", fileDescriptor_ae0216eeb0d08e49) } + +var fileDescriptor_ae0216eeb0d08e49 = []byte{ + // 200 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2f, 0xc8, 0x49, 0x4c, + 0x4e, 0xcd, 0x4d, 0xcd, 0x2b, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xa9, 0x4c, 0xcc, + 0xcd, 0x91, 0x72, 0x4a, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xcf, 0x35, + 0x4e, 0x49, 0xd2, 0xcf, 0x35, 0xd6, 0x2f, 0x2e, 0x4a, 0xd6, 0x2f, 0x2c, 0x4d, 0x2d, 0xaa, 0xd4, + 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0x4a, 0x2c, 0x49, 0x4d, 0xd1, 0x07, 0xeb, 0xd1, 0x4f, 0x4c, 0xc9, + 0xcd, 0xcc, 0xd3, 0x47, 0x33, 0x49, 0x29, 0x9f, 0x4b, 0x22, 0x00, 0x26, 0xe4, 0x99, 0x97, 0x59, + 0x12, 0x94, 0x5a, 0x58, 0x9a, 0x5a, 0x5c, 0x12, 0x99, 0x98, 0x9b, 0x23, 0x24, 0xc3, 0xc5, 0xe9, + 0x5f, 0x00, 0x32, 0x23, 0x33, 0x3f, 0x4f, 0x82, 0x51, 0x81, 0x51, 0x83, 0x33, 0x08, 0x21, 0x20, + 0x64, 0xca, 0xc5, 0x0e, 0x55, 0x2c, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x6d, 0x24, 0xad, 0x07, 0xb6, + 0x42, 0x0f, 0x9b, 0x79, 0x41, 0x30, 0xb5, 0x4a, 0xa5, 0x5c, 0xd2, 0x70, 0x05, 0x41, 0xa9, 0x60, + 0xe7, 0xe0, 0xb4, 0x93, 0x19, 0xdd, 0x4e, 0x0b, 0x84, 0x9d, 0x2c, 0x60, 0x3b, 0xe5, 0xd0, 0xed, + 0x44, 0x35, 0x12, 0x6e, 0x6d, 0x12, 0x1b, 0xd8, 0xbb, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x34, 0x29, 0x78, 0x38, 0x4b, 0x01, 0x00, 0x00, +} diff --git a/src/cmd/tools/m3ctl/main/yaml/load.go b/src/cmd/tools/m3ctl/main/yaml/load.go index 15870b3d87..c52f6601a3 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load.go +++ b/src/cmd/tools/m3ctl/main/yaml/load.go @@ -2,13 +2,10 @@ package yaml import ( "bytes" - "fmt" "io" "io/ioutil" "log" - pb "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" - "github.com/ghodss/yaml" "github.com/gogo/protobuf/jsonpb" "github.com/gogo/protobuf/proto" @@ -18,26 +15,18 @@ import ( // and produces an io.Reader of it protocol buffer-encoded // // we don't know anything about what the user it trying to do -// but we only know how to do the things that are the keys of -// this map DatabaseCreateRequestYaml_OperationType_value -// so try to load each and take whatever works -// there's a "operation" field the user must specify to -// indicate the intent +// so peek at it to see what's the intended action then load it // // See the examples directories. // -// the strategy is to loop over the keys of -// DatabaseCreateRequestYaml_OperationType_value -// and try to load for each -// checking the "operation" field func Load(path string) (string, io.Reader) { content, err := ioutil.ReadFile(path) if err != nil { log.Fatal(err) } - url, pbmessage, err := decodeKnownOps(content) + url, pbmessage, err := peeker(content) if err != nil { - log.Fatalf("cannot unmarshal data:%v:from yaml file:%s:", err, path) + log.Fatalf("error inspecting the yaml:it might be bad yaml or it might be an unknown operation:%v:from yaml file:%s:", err, path) } rv, err := _load(content, pbmessage) @@ -45,32 +34,6 @@ func Load(path string) (string, io.Reader) { return url, rv } -// peek into the yaml to see what it is expected to be -// don't try to decode the entire thing since its -// going into something that's currently unknown -// so just grab the "operation" then dispatch -// -// returns the url path, proto.Message, and error -func decodeKnownOps(data []byte) (string, proto.Message, error) { - - type peeker struct { - Operation string - } - - peek := &peeker{} - if err := yaml.Unmarshal(data, &peek); err != nil { - return "", nil, err - } - - switch peek.Operation { - case opCreate: - return dbcreatePath, &pb.DatabaseCreateRequestYaml{}, nil - default: - return "", nil, fmt.Errorf("Unknown operation specified in the yaml\n") - } - -} - func _load(content []byte, target proto.Message) (io.Reader, error) { // unmarshal it into json if err := yaml.Unmarshal(content, target); err != nil { diff --git a/src/cmd/tools/m3ctl/main/yaml/load_test.go b/src/cmd/tools/m3ctl/main/yaml/load_test.go index 433650461f..5af6d42db9 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load_test.go +++ b/src/cmd/tools/m3ctl/main/yaml/load_test.go @@ -52,7 +52,7 @@ func TestOperationSelectorPositive(t *testing.T) { if err != nil { t.Fatalf("failed to read yaml test data:%v:\n", err) } - urlpath, pbmessage, err := decodeKnownOps(content) + urlpath, pbmessage, err := peeker(content) if err != nil { t.Fatalf("operation selector failed to encode the unknown operation yaml test data:%v:\n", err) } @@ -81,7 +81,7 @@ func TestOperationSelectorNegative(t *testing.T) { if err != nil { t.Fatalf("failed to read yaml test data:%v:\n", err) } - if _, _, err := decodeKnownOps(content); err == nil { + if _, _, err := peeker(content); err == nil { t.Fatalf("operation selector should have returned an error\n") } } diff --git a/src/cmd/tools/m3ctl/main/yaml/peeker.go b/src/cmd/tools/m3ctl/main/yaml/peeker.go new file mode 100644 index 0000000000..2f4525dfe1 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/yaml/peeker.go @@ -0,0 +1,41 @@ +package yaml + +import ( + "fmt" + "github.com/ghodss/yaml" + "github.com/gogo/protobuf/proto" + yaml2 "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" +) + +// peek into the yaml to see what it is expected to be +// don't try to decode the entire thing since its +// going into something that's currently unknown +// so just grab the "operation" then dispatch +// +// returns the url path, proto.Message, and error +func peeker(data []byte) (string, proto.Message, error) { + + type peeker struct { + Operation string + } + + peek := &peeker{} + if err := yaml.Unmarshal(data, &peek); err != nil { + return "", nil, err + } + + switch peek.Operation { + case opCreate: + return dbcreatePath, &yaml2.DatabaseCreateRequestYaml{}, nil + case opInit: + return fmt.Sprintf("%s/init", placementPath), &yaml2.PlacementInitRequestYaml{}, nil + case opReplace: + return fmt.Sprintf("%s/replace", placementPath), &yaml2.PlacementReplaceRequestYaml{}, nil + case opNewNode: + return fmt.Sprintf("%s", placementPath), &yaml2.PlacementInitRequestYaml{}, nil + default: + return "", nil, fmt.Errorf("Unknown operation specified in the yaml\n") + } + +} + diff --git a/src/cmd/tools/m3ctl/main/yaml/placement.proto b/src/cmd/tools/m3ctl/main/yaml/placement.proto new file mode 100644 index 0000000000..f4d4d9614b --- /dev/null +++ b/src/cmd/tools/m3ctl/main/yaml/placement.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; +package yaml; + +import "github.com/m3db/m3/src/query/generated/proto/admin/placement.proto"; +message PlacementInitRequestYaml { + string Operation = 1; + admin.PlacementInitRequest Request = 2; +} +message PlacementReplaceRequestYaml { + string Operation = 3; + admin.PlacementReplaceRequest Request = 4; +} \ No newline at end of file diff --git a/src/cmd/tools/m3ctl/main/yaml/types.go b/src/cmd/tools/m3ctl/main/yaml/types.go index ff8b9774c1..810462b0c0 100644 --- a/src/cmd/tools/m3ctl/main/yaml/types.go +++ b/src/cmd/tools/m3ctl/main/yaml/types.go @@ -6,6 +6,7 @@ const ( opReplace = "replaceNode" opNewNode = "newNode" dbcreatePath = "/api/v1/database/create" + placementPath = "/api/v1/services/m3db/placement" ) //type OP int From fa9dc7a7b0f458194260e42802c06e370df9c91c Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Mon, 3 Feb 2020 16:50:19 -0800 Subject: [PATCH 38/65] factor --- src/cmd/tools/m3ctl/main/yaml/load_test.go | 42 +---------------- src/cmd/tools/m3ctl/main/yaml/peeker_test.go | 47 ++++++++++++++++++++ 2 files changed, 49 insertions(+), 40 deletions(-) create mode 100644 src/cmd/tools/m3ctl/main/yaml/peeker_test.go diff --git a/src/cmd/tools/m3ctl/main/yaml/load_test.go b/src/cmd/tools/m3ctl/main/yaml/load_test.go index 5af6d42db9..c3974233ad 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load_test.go +++ b/src/cmd/tools/m3ctl/main/yaml/load_test.go @@ -1,10 +1,10 @@ package yaml import ( + "github.com/gogo/protobuf/jsonpb" + pb "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" "io/ioutil" "testing" - pb "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" - "github.com/gogo/protobuf/jsonpb" ) // this uses _load to get an encoded stream of the @@ -47,41 +47,3 @@ func TestLoadBasic(t *testing.T) { t.Errorf("hostname is wrong:expected:%s:got:%s:\n", "m3db_seed", dest.Request.Hosts[0]) } } -func TestOperationSelectorPositive(t *testing.T) { - content, err := ioutil.ReadFile("./testdata/basicCreate.yaml") - if err != nil { - t.Fatalf("failed to read yaml test data:%v:\n", err) - } - urlpath, pbmessage, err := peeker(content) - if err != nil { - t.Fatalf("operation selector failed to encode the unknown operation yaml test data:%v:\n", err) - } - - if urlpath != dbcreatePath { - t.Errorf("urlpath is wrong:expected:%s:got:%s:\n", dbcreatePath, urlpath) - } - - data, err := _load(content, pbmessage) - if err != nil { - t.Fatalf("failed to encode to protocol:%v:\n", err) - } - - dest := pb.DatabaseCreateRequestYaml{} - unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} - if err := unmarshaller.Unmarshal(data, &dest); err != nil { - t.Fatalf("operation selector failed to unmarshal unknown operation data:%v:\n", err) - } - - if dest.Operation != opCreate { - t.Errorf("dest type does not have the correct type via operation selector:expected:%v:got:%v:", opCreate, dest.Operation) - } -} -func TestOperationSelectorNegative(t *testing.T) { - content, err := ioutil.ReadFile("./testdata/unknownOperation.yaml") - if err != nil { - t.Fatalf("failed to read yaml test data:%v:\n", err) - } - if _, _, err := peeker(content); err == nil { - t.Fatalf("operation selector should have returned an error\n") - } -} diff --git a/src/cmd/tools/m3ctl/main/yaml/peeker_test.go b/src/cmd/tools/m3ctl/main/yaml/peeker_test.go new file mode 100644 index 0000000000..148941d833 --- /dev/null +++ b/src/cmd/tools/m3ctl/main/yaml/peeker_test.go @@ -0,0 +1,47 @@ +package yaml + +import ( + "github.com/gogo/protobuf/jsonpb" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" + "io/ioutil" + "testing" +) + +func TestPeekerPositive(t *testing.T) { + content, err := ioutil.ReadFile("./testdata/basicCreate.yaml") + if err != nil { + t.Fatalf("failed to read yaml test data:%v:\n", err) + } + urlpath, pbmessage, err := peeker(content) + if err != nil { + t.Fatalf("operation selector failed to encode the unknown operation yaml test data:%v:\n", err) + } + + if urlpath != dbcreatePath { + t.Errorf("urlpath is wrong:expected:%s:got:%s:\n", dbcreatePath, urlpath) + } + + data, err := _load(content, pbmessage) + if err != nil { + t.Fatalf("failed to encode to protocol:%v:\n", err) + } + + dest := yaml.DatabaseCreateRequestYaml{} + unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} + if err := unmarshaller.Unmarshal(data, &dest); err != nil { + t.Fatalf("operation selector failed to unmarshal unknown operation data:%v:\n", err) + } + + if dest.Operation != opCreate { + t.Errorf("dest type does not have the correct type via operation selector:expected:%v:got:%v:", opCreate, dest.Operation) + } +} +func TestPeekerNegative(t *testing.T) { + content, err := ioutil.ReadFile("./testdata/unknownOperation.yaml") + if err != nil { + t.Fatalf("failed to read yaml test data:%v:\n", err) + } + if _, _, err := peeker(content); err == nil { + t.Fatalf("operation selector should have returned an error\n") + } +} From f38dda5d00676b4a0924677772ddeda78a439eee Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Mon, 3 Feb 2020 20:21:05 -0800 Subject: [PATCH 39/65] remove the old code --- src/cmd/tools/m3ctl/main/database/cmd.go | 96 ---------- src/cmd/tools/m3ctl/main/database/cmd_test.go | 33 ---- src/cmd/tools/m3ctl/main/database/create.go | 18 -- .../m3ctl/main/database/examples/create.yaml | 27 --- .../m3ctl/main/database/examples/devel.yaml | 16 -- src/cmd/tools/m3ctl/main/namespaces/cmd.go | 113 ------------ .../tools/m3ctl/main/namespaces/cmd_test.go | 32 ---- src/cmd/tools/m3ctl/main/namespaces/delete.go | 12 -- src/cmd/tools/m3ctl/main/namespaces/show.go | 32 ---- src/cmd/tools/m3ctl/main/placements/add.go | 13 -- src/cmd/tools/m3ctl/main/placements/cmd.go | 173 ------------------ .../tools/m3ctl/main/placements/cmd_test.go | 88 --------- src/cmd/tools/m3ctl/main/placements/delete.go | 18 -- .../m3ctl/main/placements/examples/init.yaml | 26 --- .../main/placements/examples/newNode.yaml | 11 -- .../main/placements/examples/replaceNode.yaml | 13 -- src/cmd/tools/m3ctl/main/placements/get.go | 13 -- src/cmd/tools/m3ctl/main/placements/init.go | 13 -- .../tools/m3ctl/main/placements/replace.go | 18 -- 19 files changed, 765 deletions(-) delete mode 100644 src/cmd/tools/m3ctl/main/database/cmd.go delete mode 100644 src/cmd/tools/m3ctl/main/database/cmd_test.go delete mode 100644 src/cmd/tools/m3ctl/main/database/create.go delete mode 100644 src/cmd/tools/m3ctl/main/database/examples/create.yaml delete mode 100644 src/cmd/tools/m3ctl/main/database/examples/devel.yaml delete mode 100644 src/cmd/tools/m3ctl/main/namespaces/cmd.go delete mode 100644 src/cmd/tools/m3ctl/main/namespaces/cmd_test.go delete mode 100644 src/cmd/tools/m3ctl/main/namespaces/delete.go delete mode 100644 src/cmd/tools/m3ctl/main/namespaces/show.go delete mode 100644 src/cmd/tools/m3ctl/main/placements/add.go delete mode 100644 src/cmd/tools/m3ctl/main/placements/cmd.go delete mode 100644 src/cmd/tools/m3ctl/main/placements/cmd_test.go delete mode 100644 src/cmd/tools/m3ctl/main/placements/delete.go delete mode 100644 src/cmd/tools/m3ctl/main/placements/examples/init.yaml delete mode 100644 src/cmd/tools/m3ctl/main/placements/examples/newNode.yaml delete mode 100644 src/cmd/tools/m3ctl/main/placements/examples/replaceNode.yaml delete mode 100644 src/cmd/tools/m3ctl/main/placements/get.go delete mode 100644 src/cmd/tools/m3ctl/main/placements/init.go delete mode 100644 src/cmd/tools/m3ctl/main/placements/replace.go diff --git a/src/cmd/tools/m3ctl/main/database/cmd.go b/src/cmd/tools/m3ctl/main/database/cmd.go deleted file mode 100644 index 63ff8770ef..0000000000 --- a/src/cmd/tools/m3ctl/main/database/cmd.go +++ /dev/null @@ -1,96 +0,0 @@ -package database - -import ( - "flag" - "fmt" - "os" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" - "github.com/m3db/m3/src/x/config/configflag" -) - -const ( - defaultPath = "/api/v1/database" -) - -type DatabaseFlagSets struct { - Database *flag.FlagSet - Create *flag.FlagSet -} - -func SetupFlags(createDatabaseYAML *configflag.FlagStringSlice) DatabaseFlagSets { - databaseFlags := flag.NewFlagSet("db", flag.ExitOnError) - createFlags := flag.NewFlagSet("create", flag.ExitOnError) - - databaseFlags.Usage = func() { - fmt.Fprintf(databaseFlags.Output(), ` -This is the "%s" subcommand for database scoped operations. - -It has the following subcommands: - - %s - -`, databaseFlags.Name(), createFlags.Name()) - databaseFlags.PrintDefaults() - } - - createFlags.Var(createDatabaseYAML, "f", "Path to yaml for simplified db creation with sane defaults.") - createFlags.Usage = func() { - fmt.Fprintf(databaseFlags.Output(), ` -This is the "%s" subcommand for %s scoped operations. - -Description: - -This subcommand allows the creation of a new database from a yaml specification. - -Usage of %s: - -`, createFlags.Name(), databaseFlags.Name(), createFlags.Name()) - createFlags.PrintDefaults() - } - - return DatabaseFlagSets{Database: databaseFlags, Create: createFlags} -} - -func ParseAndDo(arg *configflag.FlagStringSlice, flags *DatabaseFlagSets, ep string) { - args := flag.Args() - // right here args should be like "db create -f somefile" - if len(args) < 2 { - flags.Database.Usage() - os.Exit(1) - } - // pop and parse - if err := parseAndDoCreate(args[1:], arg, flags, ep, Create); err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - os.Exit(1) - } -} -func parseAndDoCreate(args []string, finalArgs *configflag.FlagStringSlice, flags *DatabaseFlagSets, ep string, doer func(string, string)) error { - if err := flags.Database.Parse(args); err != nil { - flags.Database.Usage() - return err - } - if flags.Database.NArg() == 0 { - flags.Database.Usage() - return &errors.FlagsError{} - } - switch flags.Database.Arg(0) { - case flags.Create.Name(): - // pop and parse - createArgs := flags.Database.Args()[1:] - if err := flags.Create.Parse(createArgs); err != nil { - flags.Create.Usage() - return err - } - if flags.Create.NFlag() == 0 { - flags.Create.Usage() - return &errors.FlagsError{} - } - // the below finalArgs.Value has at least one value by this time per the parser - doer(finalArgs.Value[len(finalArgs.Value)-1], ep) - return nil - default: - flags.Database.Usage() - return &errors.FlagsError{} - } -} diff --git a/src/cmd/tools/m3ctl/main/database/cmd_test.go b/src/cmd/tools/m3ctl/main/database/cmd_test.go deleted file mode 100644 index 962d2707de..0000000000 --- a/src/cmd/tools/m3ctl/main/database/cmd_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package database - -import ( - "testing" - - "github.com/m3db/m3/src/x/config/configflag" -) - -func TestBasic(t *testing.T) { - - createDatabaseYAML := configflag.FlagStringSlice{} - databaseFlagSets := SetupFlags(&createDatabaseYAML) - - if e := parseAndDoCreate([]string{}, &createDatabaseYAML, &databaseFlagSets, "", func(string, string) { return }); e == nil { - t.Error("It should return error on no args") - } - - createDatabaseYAML = configflag.FlagStringSlice{} - databaseFlagSets = SetupFlags(&createDatabaseYAML) - - if e := parseAndDoCreate([]string{"create", "-f", "somefile"}, &createDatabaseYAML, &databaseFlagSets, "", func(string, string) { return }); e != nil { - t.Error("It should NOT return error on sane args") - } - - if len(createDatabaseYAML.Value) != 1 { - t.Fatalf("db create filename len is wrong:expected:1:but got:%d:\n", len(createDatabaseYAML.Value)) - } - - if createDatabaseYAML.Value[0] != "somefile" { - t.Errorf("db create filename value is wrong:expected:%s:but got:%s:\n", createDatabaseYAML.Value[0], "somefile") - } - -} diff --git a/src/cmd/tools/m3ctl/main/database/create.go b/src/cmd/tools/m3ctl/main/database/create.go deleted file mode 100644 index 9a339dfbda..0000000000 --- a/src/cmd/tools/m3ctl/main/database/create.go +++ /dev/null @@ -1,18 +0,0 @@ -package database - -import ( - //"fmt" - //"log" - // - //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" - //"github.com/m3db/m3/src/query/generated/proto/admin" -) - -func Create(createYAML string, endpoint string) { - //log.Printf("createYAML:%s:\n", createYAML) - //data := yaml.Load(createYAML, &admin.DatabaseCreateRequest{}) - //url := fmt.Sprintf("%s%s/create", endpoint, defaultPath) - //client.DoPost(url, data, client.Dumper) - //return -} diff --git a/src/cmd/tools/m3ctl/main/database/examples/create.yaml b/src/cmd/tools/m3ctl/main/database/examples/create.yaml deleted file mode 100644 index f4b33ceb18..0000000000 --- a/src/cmd/tools/m3ctl/main/database/examples/create.yaml +++ /dev/null @@ -1,27 +0,0 @@ ---- -operation: create -type: cluster -namespace_name: 1week_namespace -retention_time: 168h -num_shards: 1024 -replication_factor: 3 -hosts: -- id: m3db001 - isolationGroup: us-east1-a - zone: embedded - weight: 100 - address: 10.142.0.1 - port: 9000 -- id: m3db002 - isolationGroup: us-east1-b - zone: embedded - weight: 100 - address: 10.142.0.2 - port: 9000 -- id: m3db003 - isolationGroup: us-east1-c - zone: embedded - weight: 100 - address: 10.142.0.3 - port: 9000 - diff --git a/src/cmd/tools/m3ctl/main/database/examples/devel.yaml b/src/cmd/tools/m3ctl/main/database/examples/devel.yaml deleted file mode 100644 index c324320c12..0000000000 --- a/src/cmd/tools/m3ctl/main/database/examples/devel.yaml +++ /dev/null @@ -1,16 +0,0 @@ ---- -operation: create -type: cluster -namespace_name: default -retention_time: 168h -num_shards: 64 -replication_factor: 1 -hosts: -- id: m3db_seed - isolation_group: rack-a - zone: embedded - weight: 1024 - endpoint: m3db_seed:9000 - hostname: m3db_seed - port: 9000 - diff --git a/src/cmd/tools/m3ctl/main/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/namespaces/cmd.go deleted file mode 100644 index 347a85226c..0000000000 --- a/src/cmd/tools/m3ctl/main/namespaces/cmd.go +++ /dev/null @@ -1,113 +0,0 @@ -package namespaces - -import ( - "flag" - "fmt" - "os" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" -) - -type NamespaceArgs struct { - showAll *bool - delete *string -} - -type NamespaceFlags struct { - Namespace *flag.FlagSet - namespaceDoer func(*NamespaceArgs, string) - Delete *flag.FlagSet - deleteDoer func(*NamespaceArgs, string) -} - -func SetupFlags(flags *NamespaceArgs) NamespaceFlags { - namespaceFlags := flag.NewFlagSet("ns", flag.ExitOnError) - deleteFlags := flag.NewFlagSet("delete", flag.ExitOnError) - flags.delete = deleteFlags.String("name", "", "name of namespace to delete") - flags.showAll = namespaceFlags.Bool("all", false, "show all the standard info for namespaces (otherwise default behaviour lists only the names)") - namespaceFlags.Usage = func() { - fmt.Fprintf(namespaceFlags.Output(), ` -This is the subcommand for acting on namespaces. - -Description: - -The namespaces subcommand "%s"" provides the ability to: - -* list all namespaces (default) -* verbosely list all the available information about the namespaces (-all) -* delete a specific namespace (see the delete subcommand) - -Default behaviour (no arguments) is to print out the names of the namespaces. - -Specify only one action at a time. - -It has the following subcommands: - - %s - -Usage: - -`, namespaceFlags.Name(), deleteFlags.Name()) - namespaceFlags.PrintDefaults() - } - deleteFlags.Usage = func() { - fmt.Fprintf(deleteFlags.Output(), ` -This is the "%s" subcommand for %s scoped operations. - -Description: - -This subcommand allows the creation of a new database from a yaml specification. - -Usage of %s: - -`, deleteFlags.Name(), namespaceFlags.Name(), deleteFlags.Name()) - deleteFlags.PrintDefaults() - } - return NamespaceFlags{Namespace: namespaceFlags, namespaceDoer: Show, Delete: deleteFlags, deleteDoer: Delete} -} - -func ParseAndDo(args *NamespaceArgs, flags *NamespaceFlags, ep string) { - originalArgs := flag.Args() - // right here args should be like "ns delete -name someName" - if len(originalArgs) < 1 { - flags.Namespace.Usage() - os.Exit(1) - } - // pop and parse - if err := parseAndDo(originalArgs[1:], args, flags, ep); err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - os.Exit(1) - } -} - -func parseAndDo(args []string, finalArgs *NamespaceArgs, flags *NamespaceFlags, ep string) error { - if err := flags.Namespace.Parse(args); err != nil { - flags.Namespace.Usage() - return &errors.FlagsError{} - } - // maybe do "ns -all" - if flags.Namespace.NArg() == 0 { - flags.namespaceDoer(finalArgs, ep) - return nil - } - nextArgs := flags.Namespace.Args() - switch nextArgs[0] { - case flags.Delete.Name(): - if err := flags.Delete.Parse(nextArgs[1:]); err != nil { - flags.Delete.Usage() - return &errors.FlagsError{} - } - if flags.Delete.NFlag() == 0 { - flags.Delete.Usage() - return &errors.FlagsError{} - } - flags.deleteDoer(finalArgs, ep) - return nil - case "": - flags.namespaceDoer(finalArgs, ep) - return nil - default: - flags.Namespace.Usage() - return &errors.FlagsError{} - } -} diff --git a/src/cmd/tools/m3ctl/main/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/main/namespaces/cmd_test.go deleted file mode 100644 index f87becdbd1..0000000000 --- a/src/cmd/tools/m3ctl/main/namespaces/cmd_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package namespaces - -import ( - "testing" -) - -func makeStub() (NamespaceArgs, NamespaceFlags) { - namespaceArgs := NamespaceArgs{} - namespaceFlagSets := SetupFlags(&namespaceArgs) - - namespaceFlagSets.namespaceDoer = func(*NamespaceArgs, string) { return } - namespaceFlagSets.deleteDoer = func(*NamespaceArgs, string) { return } - - return namespaceArgs, namespaceFlagSets -} -func TestBasic(t *testing.T) { - - args, flags := makeStub() - if e := parseAndDo([]string{}, &args, &flags, ""); e != nil { - t.Error("It should not return an error on no args") - } - - args, flags = makeStub() - if e := parseAndDo([]string{"delete", "-name", "www"}, &args, &flags, ""); e != nil { - t.Error("It should not return error no sane args") - } - - args, flags = makeStub() - if e := parseAndDo([]string{"-all"}, &args, &flags, ""); e != nil { - t.Error("It should not return error no sane args") - } -} diff --git a/src/cmd/tools/m3ctl/main/namespaces/delete.go b/src/cmd/tools/m3ctl/main/namespaces/delete.go deleted file mode 100644 index 737386a35a..0000000000 --- a/src/cmd/tools/m3ctl/main/namespaces/delete.go +++ /dev/null @@ -1,12 +0,0 @@ -package namespaces - -import ( - "fmt" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" -) - -func Delete(flags *NamespaceArgs, endpoint string) { - url := fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", *flags.delete) - client.DoDelete(url, client.Dumper) -} diff --git a/src/cmd/tools/m3ctl/main/namespaces/show.go b/src/cmd/tools/m3ctl/main/namespaces/show.go deleted file mode 100644 index 6c657ce6d0..0000000000 --- a/src/cmd/tools/m3ctl/main/namespaces/show.go +++ /dev/null @@ -1,32 +0,0 @@ -package namespaces - -import ( - "fmt" - "io" - "log" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - "github.com/m3db/m3/src/query/generated/proto/admin" - - "github.com/gogo/protobuf/jsonpb" -) - -func Show(flags *NamespaceArgs, endpoint string) { - url := fmt.Sprintf("%s%s?%s", endpoint, DefaultPath, DebugQS) - if *flags.showAll { - client.DoGet(url, client.Dumper) - } else { - client.DoGet(url, showNames) - } -} - -func showNames(in io.Reader) { - registry := admin.NamespaceGetResponse{} - unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} - if err := unmarshaller.Unmarshal(in, ®istry); err != nil { - log.Fatal(err) - } - for k, _ := range registry.Registry.Namespaces { - fmt.Println(k) - } -} diff --git a/src/cmd/tools/m3ctl/main/placements/add.go b/src/cmd/tools/m3ctl/main/placements/add.go deleted file mode 100644 index 4184a82004..0000000000 --- a/src/cmd/tools/m3ctl/main/placements/add.go +++ /dev/null @@ -1,13 +0,0 @@ -package placements - -import ( - "log" -) - -func doAdd(s placementArgs, endpoint string) { - log.Printf("placementArgs:%+v:\n", s) - //data := yaml.Load(s.newNodeFlag.Value[0], &admin.PlacementInitRequest{}) - //url := fmt.Sprintf("%s%s", endpoint, DefaultPath) - //client.DoPost(url, data, client.Dumper) - return -} diff --git a/src/cmd/tools/m3ctl/main/placements/cmd.go b/src/cmd/tools/m3ctl/main/placements/cmd.go deleted file mode 100644 index bebdb27b66..0000000000 --- a/src/cmd/tools/m3ctl/main/placements/cmd.go +++ /dev/null @@ -1,173 +0,0 @@ -package placements - -import ( - "flag" - "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" - "os" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" - "github.com/m3db/m3/src/x/config/configflag" -) - -// all the values from the cli args are stored in here -// for all the placement-related commands -type placementArgs struct { - deletePlacement *bool - deleteNode *string - initFlag configflag.FlagStringSlice - newNodeFlag configflag.FlagStringSlice - replaceFlag configflag.FlagStringSlice -} - -// this has all that the dispatcher needs to parse the cli -type Context struct { - vals *placementArgs - handlers placementHandler - //GlobalOpts []string - Placement *flag.FlagSet - Add *flag.FlagSet - Delete *flag.FlagSet - Init *flag.FlagSet - Replace *flag.FlagSet -} -type placementHandler struct { - add func(placementArgs, string) - delete func(placementArgs, string) - xget func(placementArgs, string) - xinit func(placementArgs, string) - replace func(placementArgs, string) -} - -func InitializeFlags() Context { - return _setupFlags( - &placementArgs{}, - placementHandler{ - add: doAdd, - delete: doDelete, - xget: doGet, - xinit: doInit, - replace: doReplace, - }, - ) -} -func _setupFlags(finalArgs *placementArgs, handler placementHandler) Context { - - placementFlags := flag.NewFlagSet("pl", flag.ExitOnError) - deleteFlags := flag.NewFlagSet("delete", flag.ExitOnError) - addFlags := flag.NewFlagSet("add", flag.ExitOnError) - initFlags := flag.NewFlagSet("init", flag.ExitOnError) - replaceFlags := flag.NewFlagSet("replace", flag.ExitOnError) - - finalArgs.deletePlacement = deleteFlags.Bool("all", false, "delete the entire placement") - finalArgs.deleteNode = deleteFlags.String("node", "", "delete the specified node in the placement") - initFlags.Var(&finalArgs.initFlag, "f", "initialize a placement. Specify a yaml file.") - addFlags.Var(&finalArgs.newNodeFlag, "f", "add a new node to the placement. Specify the filename of the yaml.") - replaceFlags.Var(&finalArgs.replaceFlag, "f", "add a new node to the placement. Specify the filename of the yaml.") - placementFlags.Usage = func() { - fmt.Fprintf(os.Stderr, ` -"%s" is for acting on placements. - -Description: - -The placements subcommand "%s" provides the ability to: - -* list the info for the placement -* delete an entire placement from a node -* remove a node from a placement -* add a new node to as existing placement -* replace a node within an existing placement -* initialize a placement - -Default behaviour (no arguments) is to provide a json dump of the existing placement. - -New node creation and node replacement require specification of -the desired placement parameters, which you are to provide via a yaml -file, the pathname of which is the argument for the cli option. - -Specify only one action at a time. - -It has the following subcommands: - %s - %s - %s - %s - -`, placementFlags.Name(), placementFlags.Name(), deleteFlags.Name(), addFlags.Name(), initFlags.Name(), replaceFlags.Name()) - placementFlags.PrintDefaults() - } - return Context{ - vals: finalArgs, - handlers: handler, - //GlobalOpts: nil, - Placement: placementFlags, - Add: addFlags, - Delete: deleteFlags, - Init: initFlags, - Replace: replaceFlags, - } -} - -func (ctx Context) PopParseAndDo(cli []string, ep string) error { - fmt.Printf("pl parse and do:args:%v:\n", cli) - // right here args should be like "pl delete -node someName" - if len(cli) < 1 { - ctx.Placement.Usage() - return &errors.FlagsError{} - } - - // pop and parse - inArgs := cli[1:] - if err := ctx.Placement.Parse(inArgs); err != nil { - ctx.Placement.Usage() - return &errors.FlagsError{} - } - if ctx.Placement.NArg() == 0 { - ctx.handlers.xget(*ctx.vals, ep) - return nil - } - - if err := dispatcher(ctx, ep); err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - return err - } - - return nil - -} - -func dispatcher(ctx Context, ep string) error { - thisArgs := ctx.Placement.Args() - switch thisArgs[0] { - case ctx.Add.Name(): - if err := checkArgs.PopParseAndCheck(thisArgs, ctx.Add); err != nil { - return err - } - ctx.handlers.add(*ctx.vals, ep) - return nil - case ctx.Delete.Name(): - if err := checkArgs.PopParseAndCheck(thisArgs, ctx.Delete); err != nil { - return err - } - ctx.handlers.delete(*ctx.vals, ep) - return nil - case ctx.Init.Name(): - if err := checkArgs.PopParseAndCheck(thisArgs, ctx.Init); err != nil { - return err - } - ctx.handlers.xinit(*ctx.vals, ep) - return nil - case ctx.Replace.Name(): - if err := checkArgs.PopParseAndCheck(thisArgs, ctx.Replace); err != nil { - return err - } - ctx.handlers.replace(*ctx.vals, ep) - return nil - case "": - ctx.handlers.xget(*ctx.vals, ep) - return nil - default: - return &errors.FlagsError{} - } - -} diff --git a/src/cmd/tools/m3ctl/main/placements/cmd_test.go b/src/cmd/tools/m3ctl/main/placements/cmd_test.go deleted file mode 100644 index 977dd61329..0000000000 --- a/src/cmd/tools/m3ctl/main/placements/cmd_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package placements - -import ( - "testing" -) - -func stub1(placementArgs, string) { return } - -func makeStub() Context { - return _setupFlags( - &placementArgs{}, - placementHandler{ - add: stub1, - delete: stub1, - xget: stub1, - xinit: stub1, - replace: stub1, - }, - ) -} -func TestBasic(t *testing.T) { - - testData := []struct { - args []string - ep string - msg string - successCondition func(error) bool - }{ - { - // no args not even pl - args: []string{}, - ep: "", - msg: "It should return error because we got here without pl", - successCondition: func(err error) bool {return err != nil}, - }, - { - // no args except pl - args: []string{"pl"}, - ep: "", - msg: "It should not return error no args", - successCondition: func(err error) bool {return err == nil}, - }, - { - args: []string{"pl", "junk"}, - ep: "", - msg: "It should return error when given junk", - successCondition: func(err error) bool {return err != nil}, - }, - { - args: []string{"pl", "delete", "-all"}, - ep: "", - msg: "It should not return error on sane delete all args", - successCondition: func(err error) bool {return err == nil}, - }, - { - args: []string{"pl", "delete", "-node", "nodeName"}, - ep: "", - msg: "It should not return error on sane delete args", - successCondition: func(err error) bool {return err == nil}, - }, - { - args: []string{"pl", "add", "-f", "someFile"}, - ep: "", - msg: "It should not return error on sane add args", - successCondition: func(err error) bool {return err == nil}, - }, - { - args: []string{"pl", "init", "-f", "someFile"}, - ep: "", - msg: "It should not return error on sane init args", - successCondition: func(err error) bool {return err == nil}, - }, - { - args: []string{"pl", "replace", "-f", "someFile"}, - ep: "", - msg: "It should not return error on sane replace args", - successCondition: func(err error) bool {return err == nil}, - }, - } - - for _, v := range testData { - ctx := makeStub() - if ! v.successCondition(ctx.PopParseAndDo(v.args, v.ep)) { - t.Error(v.msg) - } - } - -} diff --git a/src/cmd/tools/m3ctl/main/placements/delete.go b/src/cmd/tools/m3ctl/main/placements/delete.go deleted file mode 100644 index 22b371443c..0000000000 --- a/src/cmd/tools/m3ctl/main/placements/delete.go +++ /dev/null @@ -1,18 +0,0 @@ -package placements - -import ( - "fmt" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" -) - -func doDelete(s placementArgs, endpoint string) { - if *s.deletePlacement { - url := fmt.Sprintf("%s%s", endpoint, DefaultPath) - client.DoDelete(url, client.Dumper) - return - } - url := fmt.Sprintf("%s%s/%s", endpoint, DefaultPath, *s.deleteNode) - client.DoDelete(url, client.Dumper) - return -} diff --git a/src/cmd/tools/m3ctl/main/placements/examples/init.yaml b/src/cmd/tools/m3ctl/main/placements/examples/init.yaml deleted file mode 100644 index cff7140666..0000000000 --- a/src/cmd/tools/m3ctl/main/placements/examples/init.yaml +++ /dev/null @@ -1,26 +0,0 @@ ---- -operation: init -num_shards: 64 -replication_factor: 1 -instances: - - id: nodeid1 - isolation_group: isogroup1 - zone: etcd1 - weight: 100 - endpoint: node1:9000 - hostname: node1 - port: 9000 - - id: nodeid2 - isolation_group: isogroup2 - zone: etcd1 - weight: 100 - endpoint: node2:9000 - hostname: node2 - port: 9000 - - id: nodeid3 - isolation_group: isogroup3 - zone: etcd1 - weight: 100 - endpoint: node3:9000 - hostname: node3 - port: 9000 diff --git a/src/cmd/tools/m3ctl/main/placements/examples/newNode.yaml b/src/cmd/tools/m3ctl/main/placements/examples/newNode.yaml deleted file mode 100644 index 8e735a4080..0000000000 --- a/src/cmd/tools/m3ctl/main/placements/examples/newNode.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -operation: newNode -instances: - - id: node1 - isolationGroup: isoGroup1 - zone: embedded - weight: 100 - endpoint: targetHostname1:9000 - hostname: newNodeHostname1 - port: 9000 - diff --git a/src/cmd/tools/m3ctl/main/placements/examples/replaceNode.yaml b/src/cmd/tools/m3ctl/main/placements/examples/replaceNode.yaml deleted file mode 100644 index 102b90f3ee..0000000000 --- a/src/cmd/tools/m3ctl/main/placements/examples/replaceNode.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -operation: replaceNode -leavingInstanceIDs: -- oldnodeid1 -candidates: -- id: newnodeid1 - isolationGroup: newnodeisogroup1 - zone: etcdzone1 - weight: 100 - endpoint: node11:9000 - hostname: node11 - port: 9000 - diff --git a/src/cmd/tools/m3ctl/main/placements/get.go b/src/cmd/tools/m3ctl/main/placements/get.go deleted file mode 100644 index 8101c17742..0000000000 --- a/src/cmd/tools/m3ctl/main/placements/get.go +++ /dev/null @@ -1,13 +0,0 @@ -package placements - -import ( - "fmt" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" -) - -func doGet(s placementArgs, endpoint string) { - url := fmt.Sprintf("%s%s", endpoint, DefaultPath) - client.DoGet(url, client.Dumper) - return -} diff --git a/src/cmd/tools/m3ctl/main/placements/init.go b/src/cmd/tools/m3ctl/main/placements/init.go deleted file mode 100644 index ff2cdeae0f..0000000000 --- a/src/cmd/tools/m3ctl/main/placements/init.go +++ /dev/null @@ -1,13 +0,0 @@ -package placements - -import ( - "log" -) - -func doInit(s placementArgs, endpoint string) { - log.Printf("placementArgs:%+v:\n", s) - //data := yaml.Load(s.initFlag.Value[0], &admin.PlacementInitRequest{}) - //url := fmt.Sprintf("%s%s%s", endpoint, DefaultPath, "/init") - //client.DoPost(url, data, client.Dumper) - return -} diff --git a/src/cmd/tools/m3ctl/main/placements/replace.go b/src/cmd/tools/m3ctl/main/placements/replace.go deleted file mode 100644 index 40d23ae656..0000000000 --- a/src/cmd/tools/m3ctl/main/placements/replace.go +++ /dev/null @@ -1,18 +0,0 @@ -package placements - -import ( - //"fmt" - - //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" - //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" - //"github.com/m3db/m3/src/query/generated/proto/admin" - //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" -) - -func doReplace(s placementArgs, endpoint string) { - //data := yaml.Load(s.replaceFlag.Value[0], &admin.PlacementReplaceRequest{}) - //url := fmt.Sprintf("%s%s%s", endpoint, DefaultPath, "/replace") - //client.DoPost(url, data, client.Dumper) - return -} From f08e1c61c108462b87bbee928215752b6a1678b6 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Mon, 3 Feb 2020 20:52:36 -0800 Subject: [PATCH 40/65] deleted cruft --- src/cmd/tools/m3ctl/main/apply/cmd.go | 2 +- .../m3ctl/main/checkArgs/popParseCheck.go | 2 +- .../tools/m3ctl/main/delete/placements/cmd.go | 2 +- .../tools/m3ctl/main/get/namespaces/cmd.go | 18 --------- .../tools/m3ctl/main/get/placements/cmd.go | 39 ------------------- src/cmd/tools/m3ctl/main/main.go | 18 --------- src/cmd/tools/m3ctl/main/yaml/types.go | 10 ----- 7 files changed, 3 insertions(+), 88 deletions(-) diff --git a/src/cmd/tools/m3ctl/main/apply/cmd.go b/src/cmd/tools/m3ctl/main/apply/cmd.go index db20bd5ae7..7c82f37a1c 100644 --- a/src/cmd/tools/m3ctl/main/apply/cmd.go +++ b/src/cmd/tools/m3ctl/main/apply/cmd.go @@ -59,7 +59,7 @@ func (ctx Context) PopParseDispatch(cli []string) error { inArgs := cli[1:] if err := ctx.Apply.Parse(inArgs); err != nil { ctx.Apply.Usage() - return &errors.FlagsError{} + return err } if ctx.Apply.NFlag() != 1 { ctx.Apply.Usage() diff --git a/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go b/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go index bbec4c8f7a..999b51b809 100644 --- a/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go +++ b/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go @@ -10,7 +10,7 @@ func PopParseAndCheck(args []string, fs *flag.FlagSet) *errors.FlagsError { thisArgs := args[1:] if err := fs.Parse(thisArgs); err != nil { fs.Usage() - return &errors.FlagsError{} + return err } if fs.NFlag() == 0 { fs.Usage() diff --git a/src/cmd/tools/m3ctl/main/delete/placements/cmd.go b/src/cmd/tools/m3ctl/main/delete/placements/cmd.go index 01ca22c8ea..7d95714568 100644 --- a/src/cmd/tools/m3ctl/main/delete/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/delete/placements/cmd.go @@ -67,7 +67,7 @@ func (ctx Context) PopParseDispatch(cli []string) error { inArgs := cli[1:] if err := ctx.Placement.Parse(inArgs); err != nil { ctx.Placement.Usage() - return &errors.FlagsError{} + return err } if ctx.Placement.NFlag() == 0 { fmt.Printf("3:%v:%v:\n", cli, ctx.Placement.NArg()) diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go index c067e643d5..8985d1072c 100644 --- a/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go @@ -17,29 +17,16 @@ type Context struct { handlers namespacesHandlers Globals checkArgs.GlobalOpts Namespaces *flag.FlagSet - //Add *flag.FlagSet - //Delete *flag.FlagSet - //Init *flag.FlagSet - //Replace *flag.FlagSet } type namespacesHandlers struct { xget func(*namespacesArgs, checkArgs.GlobalOpts) } -// everything needed to prep for this pl command level -// nothing that's needed below it -// just the stuff for parsing at the pl level func InitializeFlags() Context { return _setupFlags( &namespacesArgs{}, namespacesHandlers{ - //add: doAdd, - //delete: doDelete, - //xget: func(c *placementArgs, s string) {fmt.Print("deeper fake pl get handler")}, xget: get, - //xget: placements., - //xinit: doInit, - //replace: doReplace, }, ) } @@ -62,12 +49,7 @@ Default behaviour (no arguments) is to provide a json dump of the existing place return Context{ vals: finalArgs, handlers: handler, - //GlobalOpts: nil, Namespaces: namespaceFlags, - //Add: addFlags, - //Delete: deleteFlags, - //Init: initFlags, - //Replace: replaceFlags, } } diff --git a/src/cmd/tools/m3ctl/main/get/placements/cmd.go b/src/cmd/tools/m3ctl/main/get/placements/cmd.go index b46f43f317..1cb30dca60 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/placements/cmd.go @@ -11,65 +11,30 @@ import ( //"github.com/m3db/m3/src/x/config/configflag" ) -//const ( -// defaultPath = "/api/v1/services/m3db/placement" -//) - -// all the values from the cli args are stored in here -// for all the placement-related commands type placementArgs struct { - //deletePlacement *bool - //deleteNode *string - //initFlag configflag.FlagStringSlice - //newNodeFlag configflag.FlagStringSlice - //replaceFlag configflag.FlagStringSlice } -// this has all that the upper dispatcher needs to parse the cli type Context struct { vals *placementArgs handlers placementHandlers Globals checkArgs.GlobalOpts Placement *flag.FlagSet - //Add *flag.FlagSet - //Delete *flag.FlagSet - //Init *flag.FlagSet - //Replace *flag.FlagSet } type placementHandlers struct { xget func(*placementArgs, checkArgs.GlobalOpts) } -// everything needed to prep for this pl command level -// nothing that's needed below it -// just the stuff for parsing at the pl level func InitializeFlags() Context { return _setupFlags( &placementArgs{}, placementHandlers{ - //add: doAdd, - //delete: doDelete, - //xget: func(c *placementArgs, s string) {fmt.Print("deeper fake pl get handler")}, xget: doGet, - //xget: placements., - //xinit: doInit, - //replace: doReplace, }, ) } func _setupFlags(finalArgs *placementArgs, handler placementHandlers) Context { placementFlags := flag.NewFlagSet("pl", flag.ContinueOnError) - //deleteFlags := flag.NewFlagSet("delete", flag.ExitOnError) - //addFlags := flag.NewFlagSet("add", flag.ExitOnError) - //initFlags := flag.NewFlagSet("init", flag.ExitOnError) - //replaceFlags := flag.NewFlagSet("replace", flag.ExitOnError) - - //finalArgs.deletePlacement = deleteFlags.Bool("all", false, "delete the entire placement") - //finalArgs.deleteNode = deleteFlags.String("node", "", "delete the specified node in the placement") - //initFlags.Var(&finalArgs.initFlag, "f", "initialize a placement. Specify a yaml file.") - //addFlags.Var(&finalArgs.newNodeFlag, "f", "add a new node to the placement. Specify the filename of the yaml.") - //replaceFlags.Var(&finalArgs.replaceFlag, "f", "add a new node to the placement. Specify the filename of the yaml.") placementFlags.Usage = func() { fmt.Fprintf(os.Stderr, ` "%s" is for acting on placements. @@ -87,10 +52,6 @@ Default behaviour (no arguments) is to provide a json dump of the existing place handlers: handler, //GlobalOpts: nil, Placement: placementFlags, - //Add: addFlags, - //Delete: deleteFlags, - //Init: initFlags, - //Replace: replaceFlags, } } diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index d08ca3498d..38e9138d0b 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -38,16 +38,6 @@ func main() { // top-level option endPoint := flag.String("endpoint", defaultEndpoint, "The url for target m3db backend.") - // hooks and context for the next level - // the database-related subcommand - //createDatabaseYAML := configflag.FlagStringSlice{} - //databaseFlagSets := database.SetupFlags(&createDatabaseYAML) - - // the namespace-related subcommand - //namespaceArgs := namespaces.NamespaceArgs{} - //namespaceFlagSets := namespaces.SetupFlags(&namespaceArgs) - - //placementFlagSets := placements.InitializeFlags() getFlagSets := get.InitializeFlags() deleteFlagSets := delete.InitializeFlags() applyFlagSets := apply.InitializeFlags() @@ -82,14 +72,6 @@ Each subcommand has its own built-in help provided via "-h". // dispatch to the next level switch flag.Arg(0) { - //case databaseFlagSets.Database.Name(): - // database.ParseAndDo(&createDatabaseYAML, &databaseFlagSets, *endPoint) - //case namespaceFlagSets.Namespace.Name(): - // namespaces.ParseAndDo(&namespaceArgs, &namespaceFlagSets, *endPoint) - //case placementFlagSets.Placement.Name(): - // if err := placementFlagSets.PopParseDispatch(flag.Args(), *endPoint); err != nil { - // os.Exit(1) - // } case getFlagSets.Get.Name(): getFlagSets.GlobalOpts.Endpoint = *endPoint if err := getFlagSets.PopParseDispatch(flag.Args()); err != nil { diff --git a/src/cmd/tools/m3ctl/main/yaml/types.go b/src/cmd/tools/m3ctl/main/yaml/types.go index 810462b0c0..c4bd32067c 100644 --- a/src/cmd/tools/m3ctl/main/yaml/types.go +++ b/src/cmd/tools/m3ctl/main/yaml/types.go @@ -8,13 +8,3 @@ const ( dbcreatePath = "/api/v1/database/create" placementPath = "/api/v1/services/m3db/placement" ) - -//type OP int -//const ( -// Create OP = iota -//) -// -//type QQQ struct { -// operation OP -// admin.DatabaseCreateRequest -//} From 915a5b54db2fa76695e32dcd58304b290b699cea Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Tue, 4 Feb 2020 06:58:48 -0800 Subject: [PATCH 41/65] cleaning up names --- src/cmd/tools/m3ctl/main/apply/apply.go | 2 +- src/cmd/tools/m3ctl/main/apply/cmd.go | 20 +++++++++---------- .../m3ctl/main/checkArgs/popParseCheck.go | 2 +- src/cmd/tools/m3ctl/main/main.go | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/cmd/tools/m3ctl/main/apply/apply.go b/src/cmd/tools/m3ctl/main/apply/apply.go index ea56a26ca2..a09d863b88 100644 --- a/src/cmd/tools/m3ctl/main/apply/apply.go +++ b/src/cmd/tools/m3ctl/main/apply/apply.go @@ -7,7 +7,7 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" ) -func Apply(vals *applyArgs, globals checkArgs.GlobalOpts) { +func doApply(vals *applyArgs, globals checkArgs.GlobalOpts) { path, data := yaml.Load(vals.yamlFlag.Value[0]) url := fmt.Sprintf("%s%s", globals.Endpoint, path) client.DoPost(url, data, client.Dumper) diff --git a/src/cmd/tools/m3ctl/main/apply/cmd.go b/src/cmd/tools/m3ctl/main/apply/cmd.go index 7c82f37a1c..1a6203b34b 100644 --- a/src/cmd/tools/m3ctl/main/apply/cmd.go +++ b/src/cmd/tools/m3ctl/main/apply/cmd.go @@ -18,10 +18,10 @@ type Context struct { vals *applyArgs handlers applyHandlers GlobalOpts checkArgs.GlobalOpts - Apply *flag.FlagSet + Flags *flag.FlagSet } type applyHandlers struct { - xget func(*applyArgs, checkArgs.GlobalOpts) + handle func(*applyArgs, checkArgs.GlobalOpts) } func InitializeFlags() Context { @@ -30,7 +30,7 @@ func InitializeFlags() Context { yamlFlag: &configflag.FlagStringSlice{}, }, applyHandlers{ - xget: Apply, + handle: doApply, }) } func _setupFlags(finalArgs *applyArgs, handlers applyHandlers) Context { @@ -45,24 +45,24 @@ func _setupFlags(finalArgs *applyArgs, handlers applyHandlers) Context { return Context{ vals: finalArgs, - Apply: applyFlags, + Flags: applyFlags, handlers: handlers, } } func (ctx Context) PopParseDispatch(cli []string) error { if len(cli) < 1 { - ctx.Apply.Usage() + ctx.Flags.Usage() return &errors.FlagsError{} } inArgs := cli[1:] - if err := ctx.Apply.Parse(inArgs); err != nil { - ctx.Apply.Usage() + if err := ctx.Flags.Parse(inArgs); err != nil { + ctx.Flags.Usage() return err } - if ctx.Apply.NFlag() != 1 { - ctx.Apply.Usage() + if ctx.Flags.NFlag() != 1 { + ctx.Flags.Usage() return &errors.FlagsError{} } @@ -78,6 +78,6 @@ func (ctx Context) PopParseDispatch(cli []string) error { // no dispatching here // there are no subcommands func dispatcher(ctx Context) error { - ctx.handlers.xget(ctx.vals, ctx.GlobalOpts) + ctx.handlers.handle(ctx.vals, ctx.GlobalOpts) return nil } diff --git a/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go b/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go index 999b51b809..1468e04bfb 100644 --- a/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go +++ b/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go @@ -5,7 +5,7 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" ) -func PopParseAndCheck(args []string, fs *flag.FlagSet) *errors.FlagsError { +func PopParseAndCheck(args []string, fs *flag.FlagSet) error { thisArgs := args[1:] if err := fs.Parse(thisArgs); err != nil { diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 38e9138d0b..2c51af2be8 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -54,7 +54,7 @@ Usage of %s: Each subcommand has its own built-in help provided via "-h". -`, os.Args[0], applyFlagSets.Apply.Name(), +`, os.Args[0], applyFlagSets.Flags.Name(), //placementFlagSets.Placement.Name(), getFlagSets.Get.Name(), deleteFlagSets.Delete.Name()) @@ -84,7 +84,7 @@ Each subcommand has its own built-in help provided via "-h". fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - case applyFlagSets.Apply.Name(): + case applyFlagSets.Flags.Name(): applyFlagSets.GlobalOpts.Endpoint = *endPoint if err := applyFlagSets.PopParseDispatch(flag.Args()); err != nil { fmt.Fprintf(os.Stderr, err.Error()) From f6c462e05a23268558ebfe872df0cff324938ccf Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Tue, 4 Feb 2020 07:56:09 -0800 Subject: [PATCH 42/65] cleaning up --- src/cmd/tools/m3ctl/main/apply/cmd.go | 11 +-- .../m3ctl/main/checkArgs/popParseCheck.go | 3 - src/cmd/tools/m3ctl/main/delete/cmd.go | 56 ++----------- .../tools/m3ctl/main/delete/namespaces/cmd.go | 56 +++++-------- .../m3ctl/main/delete/namespaces/cmd_test.go | 16 ++-- .../tools/m3ctl/main/delete/placements/cmd.go | 49 +++++------ .../m3ctl/main/delete/placements/cmd_test.go | 17 ++-- .../m3ctl/main/delete/placements/delete.go | 2 +- src/cmd/tools/m3ctl/main/get/cmd.go | 83 ++----------------- .../tools/m3ctl/main/get/namespaces/cmd.go | 44 ++++------ .../m3ctl/main/get/namespaces/cmd_test.go | 18 ++-- .../tools/m3ctl/main/get/namespaces/get.go | 4 +- .../tools/m3ctl/main/get/placements/cmd.go | 42 ++++------ .../m3ctl/main/get/placements/cmd_test.go | 17 ++-- .../tools/m3ctl/main/get/placements/get.go | 2 +- src/cmd/tools/m3ctl/main/main.go | 10 +-- src/cmd/tools/m3ctl/main/placements/types.go | 1 - src/cmd/tools/m3ctl/main/yaml/load.go | 5 +- src/cmd/tools/m3ctl/main/yaml/load_test.go | 5 +- src/cmd/tools/m3ctl/main/yaml/peeker.go | 9 +- src/cmd/tools/m3ctl/main/yaml/peeker_test.go | 9 +- src/cmd/tools/m3ctl/main/yaml/types.go | 10 +-- 22 files changed, 130 insertions(+), 339 deletions(-) diff --git a/src/cmd/tools/m3ctl/main/apply/cmd.go b/src/cmd/tools/m3ctl/main/apply/cmd.go index 1a6203b34b..ccd946b391 100644 --- a/src/cmd/tools/m3ctl/main/apply/cmd.go +++ b/src/cmd/tools/m3ctl/main/apply/cmd.go @@ -3,17 +3,17 @@ package apply import ( "flag" "fmt" + "os" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" "github.com/m3db/m3/src/x/config/configflag" - "os" ) type applyArgs struct { yamlFlag *configflag.FlagStringSlice } - type Context struct { vals *applyArgs handlers applyHandlers @@ -34,15 +34,12 @@ func InitializeFlags() Context { }) } func _setupFlags(finalArgs *applyArgs, handlers applyHandlers) Context { - applyFlags := flag.NewFlagSet("apply", flag.ContinueOnError) applyFlags.Var(finalArgs.yamlFlag, "f", "Path to yaml.") - applyFlags.Usage = func() { fmt.Fprintf(os.Stderr, "help msg here for apply\n") applyFlags.PrintDefaults() } - return Context{ vals: finalArgs, Flags: applyFlags, @@ -55,7 +52,6 @@ func (ctx Context) PopParseDispatch(cli []string) error { ctx.Flags.Usage() return &errors.FlagsError{} } - inArgs := cli[1:] if err := ctx.Flags.Parse(inArgs); err != nil { ctx.Flags.Usage() @@ -65,14 +61,11 @@ func (ctx Context) PopParseDispatch(cli []string) error { ctx.Flags.Usage() return &errors.FlagsError{} } - if err := dispatcher(ctx); err != nil { fmt.Fprintf(os.Stderr, err.Error()) return err } - return nil - } // no dispatching here diff --git a/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go b/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go index 1468e04bfb..71e3a85d7d 100644 --- a/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go +++ b/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go @@ -6,7 +6,6 @@ import ( ) func PopParseAndCheck(args []string, fs *flag.FlagSet) error { - thisArgs := args[1:] if err := fs.Parse(thisArgs); err != nil { fs.Usage() @@ -16,7 +15,5 @@ func PopParseAndCheck(args []string, fs *flag.FlagSet) error { fs.Usage() return &errors.FlagsError{} } - return nil } - diff --git a/src/cmd/tools/m3ctl/main/delete/cmd.go b/src/cmd/tools/m3ctl/main/delete/cmd.go index e0af109f5b..9e69065d2f 100644 --- a/src/cmd/tools/m3ctl/main/delete/cmd.go +++ b/src/cmd/tools/m3ctl/main/delete/cmd.go @@ -3,69 +3,37 @@ package delete import ( "flag" "fmt" + "os" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/delete/namespaces" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/delete/placements" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" - "os" ) // this has all that the upper level needs to dispatch to here type Context struct { - //vals *placementArgs - //handlers placementHandler GlobalOpts checkArgs.GlobalOpts - Delete *flag.FlagSet - //Add *flag.FlagSet - //Delete *flag.FlagSet - //Init *flag.FlagSet - //Replace *flag.FlagSet + Flags *flag.FlagSet } -//type placementHandler struct { -// add func(placementArgs, string) -// delete func(placementArgs, string) -// xget func(placementArgs, string) -// xinit func(placementArgs, string) -// replace func(placementArgs, string) -//} -// setup hooks and context for this level -// everything needed to prep for this get command leve -// nothing that's needed below it -// just the stuff for parsing at the get level func InitializeFlags() Context { - //return _setupFlags( - //&placementArgs{}, - //placementHandler{ - // add: doAdd, - // delete: doDelete, - // xget: doGet, - // xinit: doInit, - // replace: doReplace, - // }, - //) - return _setupFlags() } func _setupFlags() Context { - deleteFlags := flag.NewFlagSet("delete", flag.ContinueOnError) deleteFlags.Usage = func() { fmt.Fprintf(os.Stderr, "delete help msg here\n") deleteFlags.PrintDefaults() } - - return Context{Delete:deleteFlags} + return Context{Flags: deleteFlags} } - func (ctx Context) PopParseDispatch(cli []string) error { - - thisFlagset := ctx.Delete + thisFlagset := ctx.Flags if len(cli) < 1 { thisFlagset.Usage() return &errors.FlagsError{} } - // pop and parse inArgs := cli[1:] if err := thisFlagset.Parse(inArgs); err != nil { @@ -76,32 +44,24 @@ func (ctx Context) PopParseDispatch(cli []string) error { thisFlagset.Usage() return &errors.FlagsError{} } - plctx := placements.InitializeFlags() nsctx := namespaces.InitializeFlags() - nextArgs := thisFlagset.Args() fmt.Print(nextArgs) switch nextArgs[0] { - case plctx.Placement.Name(): - fmt.Print("delete pl case") + case plctx.Flags.Name(): plctx.Globals = ctx.GlobalOpts if err := plctx.PopParseDispatch(nextArgs); err != nil { return err } - case nsctx.Namespaces.Name(): - fmt.Print("delete ns case") + case nsctx.Flags.Name(): nsctx.Globals = ctx.GlobalOpts if err := nsctx.PopParseDispatch(nextArgs); err != nil { return err } default: - fmt.Print("delete default case") thisFlagset.Usage() return &errors.FlagsError{} } - - fmt.Print("done delete with case") return nil - -} \ No newline at end of file +} diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go index e6f95d3ea2..83762f1686 100644 --- a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go @@ -3,9 +3,10 @@ package namespaces import ( "flag" "fmt" + "os" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" - "os" ) // all the values from the cli args are stored in here @@ -16,27 +17,25 @@ type namespacesArgs struct { // this has all that the upper dispatcher needs to parse the cli type Context struct { - vals *namespacesArgs - handlers namespacesHandlers - Globals checkArgs.GlobalOpts - Namespaces *flag.FlagSet + vals *namespacesArgs + handlers namespacesHandlers + Globals checkArgs.GlobalOpts + Flags *flag.FlagSet } type namespacesHandlers struct { - xdel func(*namespacesArgs, checkArgs.GlobalOpts) + handle func(*namespacesArgs, checkArgs.GlobalOpts) } func InitializeFlags() Context { return _setupFlags( &namespacesArgs{}, namespacesHandlers{ - xdel: doDelete, + handle: doDelete, }, ) } func _setupFlags(finalArgs *namespacesArgs, handler namespacesHandlers) Context { - nsFlags := flag.NewFlagSet("ns", flag.ContinueOnError) - finalArgs.nodeName = nsFlags.String("node", "", "delete the specified node in the placement") nsFlags.Usage = func() { fmt.Fprintf(os.Stderr, ` @@ -49,55 +48,38 @@ qqq `, nsFlags.Name()) nsFlags.PrintDefaults() } - return Context{ - vals: finalArgs, - handlers: handler, - Namespaces: nsFlags, + vals: finalArgs, + handlers: handler, + Flags: nsFlags, } } func (ctx Context) PopParseDispatch(cli []string) error { if len(cli) < 1 { - fmt.Printf("1:%v:\n", cli) - ctx.Namespaces.Usage() + ctx.Flags.Usage() return &errors.FlagsError{} } - inArgs := cli[1:] - if err := ctx.Namespaces.Parse(inArgs); err != nil { - fmt.Printf("2:%v:\n", cli) - - ctx.Namespaces.Usage() + if err := ctx.Flags.Parse(inArgs); err != nil { + ctx.Flags.Usage() return err } - if ctx.Namespaces.NFlag() == 0 { - fmt.Printf("3:%v:%v:\n", cli, ctx.Namespaces.NArg()) - - ctx.Namespaces.Usage() + if ctx.Flags.NFlag() == 0 { + ctx.Flags.Usage() return &errors.FlagsError{} } - if err := dispatcher(ctx); err != nil { - fmt.Printf("4:%v:\n", cli) - return err } - return nil - } - func dispatcher(ctx Context) error { - nextArgs := ctx.Namespaces.Args() - - fmt.Printf("nextArgs:%v:%v:\n", nextArgs, len(nextArgs)) - + nextArgs := ctx.Flags.Args() if len(nextArgs) != 0 { - ctx.Namespaces.Usage() + ctx.Flags.Usage() return &errors.FlagsError{"\nextra args supplied. See usage.\n"} } - - ctx.handlers.xdel(ctx.vals, ctx.Globals) + ctx.handlers.handle(ctx.vals, ctx.Globals) return nil } diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go index 855cb8b411..0f5c92ed27 100644 --- a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go @@ -6,22 +6,19 @@ import ( ) func makeStub() Context { - ctx := _setupFlags( + ctx := _setupFlags( &namespacesArgs{}, namespacesHandlers{ - xdel: func(*namespacesArgs, checkArgs.GlobalOpts) { return }, + handle: func(*namespacesArgs, checkArgs.GlobalOpts) { return }, }, ) - ctx.Globals.Endpoint = "fakeEndpoint" - return ctx } func TestBasic(t *testing.T) { - testData := []struct { - args []string - msg string + args []string + msg string successCondition func(error) bool }{ { @@ -59,15 +56,12 @@ func TestBasic(t *testing.T) { msg: "It should return an error because we got an empty val", successCondition: func(err error) bool { return err == nil }, }, - } - for _, v := range testData { ctx := makeStub() rv := ctx.PopParseDispatch(v.args) - if ! v.successCondition(rv) { + if !v.successCondition(rv) { t.Error(v.msg) } } - } diff --git a/src/cmd/tools/m3ctl/main/delete/placements/cmd.go b/src/cmd/tools/m3ctl/main/delete/placements/cmd.go index 7d95714568..99c0b9ddd6 100644 --- a/src/cmd/tools/m3ctl/main/delete/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/delete/placements/cmd.go @@ -3,9 +3,10 @@ package placements import ( "flag" "fmt" + "os" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" - "os" ) // all the values from the cli args are stored in here @@ -17,27 +18,25 @@ type placementArgs struct { // this has all that the upper dispatcher needs to parse the cli type Context struct { - vals *placementArgs - handlers placementHandlers - Globals checkArgs.GlobalOpts - Placement *flag.FlagSet + vals *placementArgs + handlers placementHandlers + Globals checkArgs.GlobalOpts + Flags *flag.FlagSet } type placementHandlers struct { - xdel func(*placementArgs, checkArgs.GlobalOpts) + handle func(*placementArgs, checkArgs.GlobalOpts) } func InitializeFlags() Context { return _setupFlags( &placementArgs{}, placementHandlers{ - xdel: doDelete, + handle: doDelete, }, ) } func _setupFlags(finalArgs *placementArgs, handler placementHandlers) Context { - placementFlags := flag.NewFlagSet("pl", flag.ContinueOnError) - finalArgs.deleteEntire = placementFlags.Bool("all", false, "delete the entire placement") finalArgs.nodeName = placementFlags.String("node", "", "delete the specified node in the placement") placementFlags.Usage = func() { @@ -51,47 +50,37 @@ qqq `, placementFlags.Name()) placementFlags.PrintDefaults() } - return Context{ - vals: finalArgs, - handlers: handler, - Placement: placementFlags, + vals: finalArgs, + handlers: handler, + Flags: placementFlags, } } func (ctx Context) PopParseDispatch(cli []string) error { if len(cli) < 1 { - ctx.Placement.Usage() + ctx.Flags.Usage() return &errors.FlagsError{} } - inArgs := cli[1:] - if err := ctx.Placement.Parse(inArgs); err != nil { - ctx.Placement.Usage() + if err := ctx.Flags.Parse(inArgs); err != nil { + ctx.Flags.Usage() return err } - if ctx.Placement.NFlag() == 0 { - fmt.Printf("3:%v:%v:\n", cli, ctx.Placement.NArg()) - - ctx.Placement.Usage() + if ctx.Flags.NFlag() == 0 { + ctx.Flags.Usage() return &errors.FlagsError{} } - if err := dispatcher(ctx); err != nil { return err } - return nil - } - func dispatcher(ctx Context) error { - nextArgs := ctx.Placement.Args() - + nextArgs := ctx.Flags.Args() if len(nextArgs) != 0 { - ctx.Placement.Usage() + ctx.Flags.Usage() return &errors.FlagsError{"\nextra args supplied. See usage\n"} } - ctx.handlers.xdel(ctx.vals, ctx.Globals) + ctx.handlers.handle(ctx.vals, ctx.Globals) return nil - } diff --git a/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go b/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go index 517b86bf11..18f66cdabd 100644 --- a/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go @@ -6,22 +6,19 @@ import ( ) func makeStub() Context { - ctx := _setupFlags( + ctx := _setupFlags( &placementArgs{}, placementHandlers{ - xdel: func(*placementArgs, checkArgs.GlobalOpts) { return }, + handle: func(*placementArgs, checkArgs.GlobalOpts) { return }, }, ) - ctx.Globals.Endpoint = "nuch" - return ctx } func TestBasic(t *testing.T) { - testData := []struct { - args []string - msg string + args []string + msg string successCondition func(error) bool }{ { @@ -64,16 +61,12 @@ func TestBasic(t *testing.T) { msg: "It should return an error because we got an empty val", successCondition: func(err error) bool { return err == nil }, }, - } - for _, v := range testData { ctx := makeStub() rv := ctx.PopParseDispatch(v.args) - if ! v.successCondition(rv) { + if !v.successCondition(rv) { t.Error(v.msg) } } - } - diff --git a/src/cmd/tools/m3ctl/main/delete/placements/delete.go b/src/cmd/tools/m3ctl/main/delete/placements/delete.go index ed4bf2d08b..087cdb96d3 100644 --- a/src/cmd/tools/m3ctl/main/delete/placements/delete.go +++ b/src/cmd/tools/m3ctl/main/delete/placements/delete.go @@ -3,8 +3,8 @@ package placements import ( "fmt" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" - common "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" + common "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" ) func doDelete(s *placementArgs, globals checkArgs.GlobalOpts) { diff --git a/src/cmd/tools/m3ctl/main/get/cmd.go b/src/cmd/tools/m3ctl/main/get/cmd.go index 0b88d5d302..77d16e1e9d 100644 --- a/src/cmd/tools/m3ctl/main/get/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/cmd.go @@ -3,132 +3,63 @@ package get import ( "flag" "fmt" + "os" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/get/namespaces" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/get/placements" - - //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" - "os" - - //"github.com/m3db/m3/src/x/config/configflag" ) -// all the values from the cli args are stored in here -// for all the placement-related commands -//type getArgs struct { -// deletePlacement *bool -// deleteNode *string -// initFlag configflag.FlagStringSlice -// newNodeFlag configflag.FlagStringSlice -// replaceFlag configflag.FlagStringSlice -//} - -// this has all that the upper level needs to dispatch to here type Context struct { - //vals *placementArgs - //handlers placementHandler GlobalOpts checkArgs.GlobalOpts - Get *flag.FlagSet - //Add *flag.FlagSet - //Delete *flag.FlagSet - //Init *flag.FlagSet - //Replace *flag.FlagSet + Get *flag.FlagSet } -//type placementHandler struct { -// add func(placementArgs, string) -// delete func(placementArgs, string) -// xget func(placementArgs, string) -// xinit func(placementArgs, string) -// replace func(placementArgs, string) -//} -// setup hooks and context for this level -// everything needed to prep for this get command leve -// nothing that's needed below it -// just the stuff for parsing at the get level func InitializeFlags() Context { - //return _setupFlags( - //&placementArgs{}, - //placementHandler{ - // add: doAdd, - // delete: doDelete, - // xget: doGet, - // xinit: doInit, - // replace: doReplace, - // }, - //) - return _setupFlags() } func _setupFlags() Context { - getFlags := flag.NewFlagSet("get", flag.ContinueOnError) getFlags.Usage = func() { fmt.Fprintf(os.Stderr, "help msg here\n") getFlags.PrintDefaults() } - - return Context{Get:getFlags} + return Context{Get: getFlags} } - -// parse this level -// get hooks for the next level -// dispatch func (ctx Context) PopParseDispatch(cli []string) error { - thisFlagset := ctx.Get - // right here args should be like "get ns -all" if len(cli) < 1 { thisFlagset.Usage() return &errors.FlagsError{} } - - // pop and parse inArgs := cli[1:] if err := thisFlagset.Parse(inArgs); err != nil { thisFlagset.Usage() return &errors.FlagsError{} } if thisFlagset.NArg() == 0 { - //ctx.handlers.xget(*ctx.vals, ep) thisFlagset.Usage() - //fmt.Print("stub get default action or error whatever is appropriate\n") return &errors.FlagsError{} } - - // contexts for next level - //plctx := placements.InitializeFlags() plctx := placements.InitializeFlags() nsctx := namespaces.InitializeFlags() - nextArgs := thisFlagset.Args() fmt.Print(nextArgs) switch nextArgs[0] { - case plctx.Placement.Name(): - fmt.Print("pl case") + case plctx.Flags.Name(): plctx.Globals = ctx.GlobalOpts if err := plctx.PopParseDispatch(nextArgs); err != nil { return err } - case nsctx.Namespaces.Name(): - fmt.Print("pl case") + case nsctx.Flags.Name(): nsctx.Globals = ctx.GlobalOpts if err := nsctx.PopParseDispatch(nextArgs); err != nil { return err } - //case plctx.Placement.Name(): - // fmt.Print("pl case") - // if err := plctx.PopParseDispatch(nextArgs, "fake endpoint"); err != nil { - // return err - // } default: - fmt.Print("default case") thisFlagset.Usage() return &errors.FlagsError{} } - - fmt.Print("done with case") return nil - -} \ No newline at end of file +} diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go index 8985d1072c..dfcbc17b7d 100644 --- a/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go @@ -3,9 +3,10 @@ package namespaces import ( "flag" "fmt" + "os" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" - "os" ) type namespacesArgs struct { @@ -13,27 +14,26 @@ type namespacesArgs struct { } type Context struct { - vals *namespacesArgs - handlers namespacesHandlers - Globals checkArgs.GlobalOpts - Namespaces *flag.FlagSet + vals *namespacesArgs + handlers namespacesHandlers + Globals checkArgs.GlobalOpts + Flags *flag.FlagSet } type namespacesHandlers struct { - xget func(*namespacesArgs, checkArgs.GlobalOpts) + handle func(*namespacesArgs, checkArgs.GlobalOpts) } func InitializeFlags() Context { return _setupFlags( &namespacesArgs{}, namespacesHandlers{ - xget: get, + handle: doGet, }, ) } func _setupFlags(finalArgs *namespacesArgs, handler namespacesHandlers) Context { namespaceFlags := flag.NewFlagSet("ns", flag.ContinueOnError) finalArgs.showAll = namespaceFlags.Bool("all", false, "get all the standard info for namespaces (otherwise default behaviour lists only the names)") - namespaceFlags.Usage = func() { fmt.Fprintf(os.Stderr, ` "%s" is for acting on placements. @@ -49,45 +49,37 @@ Default behaviour (no arguments) is to provide a json dump of the existing place return Context{ vals: finalArgs, handlers: handler, - Namespaces: namespaceFlags, + Flags: namespaceFlags, } } - func (ctx Context) PopParseDispatch(cli []string) error { - // right here args should be like "pl delete -node someName" if len(cli) < 1 { - ctx.Namespaces.Usage() + ctx.Flags.Usage() return &errors.FlagsError{} } - inArgs := cli[1:] - if err := ctx.Namespaces.Parse(inArgs); err != nil { - ctx.Namespaces.Usage() + if err := ctx.Flags.Parse(inArgs); err != nil { + ctx.Flags.Usage() return &errors.FlagsError{} } - if ctx.Namespaces.NArg() == 0 { - ctx.handlers.xget(ctx.vals, ctx.Globals) + if ctx.Flags.NArg() == 0 { + ctx.handlers.handle(ctx.vals, ctx.Globals) return nil } - if err := dispatcher(ctx); err != nil { fmt.Fprintf(os.Stderr, err.Error()) return err } - return nil - } - func dispatcher(ctx Context) error { - - nextArgs := ctx.Namespaces.Args() + nextArgs := ctx.Flags.Args() switch nextArgs[0] { case "": - ctx.handlers.xget(ctx.vals, ctx.Globals) + ctx.handlers.handle(ctx.vals, ctx.Globals) return nil default: - ctx.Namespaces.Usage() + ctx.Flags.Usage() return &errors.FlagsError{} } -} \ No newline at end of file +} diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go index 9856aa5d1d..c0cf130d48 100644 --- a/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go @@ -6,22 +6,19 @@ import ( ) func makeStub() Context { - ctx := _setupFlags( + ctx := _setupFlags( &namespacesArgs{}, namespacesHandlers{ - xget: func(*namespacesArgs, checkArgs.GlobalOpts) { return }, + handle: func(*namespacesArgs, checkArgs.GlobalOpts) { return }, }, ) - ctx.Globals.Endpoint = "nuch" - return ctx } func TestBasic(t *testing.T) { - testData := []struct { - args []string - msg string + args []string + msg string successCondition func(error) bool }{ { @@ -54,17 +51,12 @@ func TestBasic(t *testing.T) { msg: "It should return an error because we got an empty val", successCondition: func(err error) bool { return err == nil }, }, - } - for _, v := range testData { ctx := makeStub() rv := ctx.PopParseDispatch(v.args) - if ! v.successCondition(rv) { + if !v.successCondition(rv) { t.Error(v.msg) } } - } - - diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/get.go b/src/cmd/tools/m3ctl/main/get/namespaces/get.go index 7aa09953da..e51b8961f6 100644 --- a/src/cmd/tools/m3ctl/main/get/namespaces/get.go +++ b/src/cmd/tools/m3ctl/main/get/namespaces/get.go @@ -7,13 +7,13 @@ import ( "log" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - "github.com/m3db/m3/src/query/generated/proto/admin" common "github.com/m3db/m3/src/cmd/tools/m3ctl/main/namespaces" + "github.com/m3db/m3/src/query/generated/proto/admin" "github.com/gogo/protobuf/jsonpb" ) -func get(flags *namespacesArgs, globals checkArgs.GlobalOpts) { +func doGet(flags *namespacesArgs, globals checkArgs.GlobalOpts) { url := fmt.Sprintf("%s%s?%s", globals.Endpoint, common.DefaultPath, common.DebugQS) if *flags.showAll { client.DoGet(url, client.Dumper) diff --git a/src/cmd/tools/m3ctl/main/get/placements/cmd.go b/src/cmd/tools/m3ctl/main/get/placements/cmd.go index 1cb30dca60..ad9d64b6cc 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/placements/cmd.go @@ -3,37 +3,33 @@ package placements import ( "flag" "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" - //"github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" "os" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" - //"github.com/m3db/m3/src/x/config/configflag" ) type placementArgs struct { } - type Context struct { - vals *placementArgs - handlers placementHandlers - Globals checkArgs.GlobalOpts - Placement *flag.FlagSet + vals *placementArgs + handlers placementHandlers + Globals checkArgs.GlobalOpts + Flags *flag.FlagSet } type placementHandlers struct { - xget func(*placementArgs, checkArgs.GlobalOpts) + handle func(*placementArgs, checkArgs.GlobalOpts) } func InitializeFlags() Context { return _setupFlags( &placementArgs{}, placementHandlers{ - xget: doGet, + handle: doGet, }, ) } func _setupFlags(finalArgs *placementArgs, handler placementHandlers) Context { - placementFlags := flag.NewFlagSet("pl", flag.ContinueOnError) placementFlags.Usage = func() { fmt.Fprintf(os.Stderr, ` @@ -51,44 +47,36 @@ Default behaviour (no arguments) is to provide a json dump of the existing place vals: finalArgs, handlers: handler, //GlobalOpts: nil, - Placement: placementFlags, + Flags: placementFlags, } } - func (ctx Context) PopParseDispatch(cli []string) error { - // right here args should be like "pl delete -node someName" if len(cli) < 1 { - ctx.Placement.Usage() + ctx.Flags.Usage() return &errors.FlagsError{} } - inArgs := cli[1:] - if err := ctx.Placement.Parse(inArgs); err != nil { - ctx.Placement.Usage() + if err := ctx.Flags.Parse(inArgs); err != nil { + ctx.Flags.Usage() return &errors.FlagsError{} } - if ctx.Placement.NArg() == 0 { - ctx.handlers.xget(ctx.vals, ctx.Globals) + if ctx.Flags.NArg() == 0 { + ctx.handlers.handle(ctx.vals, ctx.Globals) return nil } - if err := dispatcher(ctx); err != nil { fmt.Fprintf(os.Stderr, err.Error()) return err } - return nil - } - func dispatcher(ctx Context) error { - nextArgs := ctx.Placement.Args() + nextArgs := ctx.Flags.Args() switch nextArgs[0] { case "": - ctx.handlers.xget(ctx.vals, ctx.Globals) + ctx.handlers.handle(ctx.vals, ctx.Globals) return nil default: return &errors.FlagsError{} } - } diff --git a/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go b/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go index 7a817c4b01..abad88c142 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go @@ -6,22 +6,19 @@ import ( ) func makeStub() Context { - ctx := _setupFlags( + ctx := _setupFlags( &placementArgs{}, placementHandlers{ - xget: func(*placementArgs, checkArgs.GlobalOpts) { return }, + handle: func(*placementArgs, checkArgs.GlobalOpts) { return }, }, ) - ctx.Globals.Endpoint = "nuch" - return ctx } func TestBasic(t *testing.T) { - testData := []struct { - args []string - msg string + args []string + msg string successCondition func(error) bool }{ { @@ -49,16 +46,12 @@ func TestBasic(t *testing.T) { msg: "It should return an error because we got an empty val", successCondition: func(err error) bool { return err == nil }, }, - } - for _, v := range testData { ctx := makeStub() rv := ctx.PopParseDispatch(v.args) - if ! v.successCondition(rv) { + if !v.successCondition(rv) { t.Error(v.msg) } } - } - diff --git a/src/cmd/tools/m3ctl/main/get/placements/get.go b/src/cmd/tools/m3ctl/main/get/placements/get.go index 6a8f97a64b..35af905519 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/get.go +++ b/src/cmd/tools/m3ctl/main/get/placements/get.go @@ -2,8 +2,8 @@ package placements import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" common "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" ) diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 2c51af2be8..53e4c2b918 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -38,10 +38,10 @@ func main() { // top-level option endPoint := flag.String("endpoint", defaultEndpoint, "The url for target m3db backend.") + // flagsets for next level down getFlagSets := get.InitializeFlags() deleteFlagSets := delete.InitializeFlags() applyFlagSets := apply.InitializeFlags() - flag.Usage = func() { fmt.Fprintf(flag.CommandLine.Output(), ` Usage of %s: @@ -55,21 +55,17 @@ Usage of %s: Each subcommand has its own built-in help provided via "-h". `, os.Args[0], applyFlagSets.Flags.Name(), - //placementFlagSets.Placement.Name(), getFlagSets.Get.Name(), - deleteFlagSets.Delete.Name()) + deleteFlagSets.Flags.Name()) flag.PrintDefaults() } - // parse this level flag.Parse() - if len(os.Args) < 2 { flag.Usage() os.Exit(1) } - // dispatch to the next level switch flag.Arg(0) { case getFlagSets.Get.Name(): @@ -78,7 +74,7 @@ Each subcommand has its own built-in help provided via "-h". fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } - case deleteFlagSets.Delete.Name(): + case deleteFlagSets.Flags.Name(): deleteFlagSets.GlobalOpts.Endpoint = *endPoint if err := deleteFlagSets.PopParseDispatch(flag.Args()); err != nil { fmt.Fprintf(os.Stderr, err.Error()) diff --git a/src/cmd/tools/m3ctl/main/placements/types.go b/src/cmd/tools/m3ctl/main/placements/types.go index 7c9ac71081..3cb13d53a0 100644 --- a/src/cmd/tools/m3ctl/main/placements/types.go +++ b/src/cmd/tools/m3ctl/main/placements/types.go @@ -3,4 +3,3 @@ package placements const ( DefaultPath = "/api/v1/services/m3db/placement" ) - diff --git a/src/cmd/tools/m3ctl/main/yaml/load.go b/src/cmd/tools/m3ctl/main/yaml/load.go index c52f6601a3..bd6303cde7 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load.go +++ b/src/cmd/tools/m3ctl/main/yaml/load.go @@ -28,12 +28,9 @@ func Load(path string) (string, io.Reader) { if err != nil { log.Fatalf("error inspecting the yaml:it might be bad yaml or it might be an unknown operation:%v:from yaml file:%s:", err, path) } - - rv, err := _load(content, pbmessage) - + rv, err := _load(content, pbmessage) return url, rv } - func _load(content []byte, target proto.Message) (io.Reader, error) { // unmarshal it into json if err := yaml.Unmarshal(content, target); err != nil { diff --git a/src/cmd/tools/m3ctl/main/yaml/load_test.go b/src/cmd/tools/m3ctl/main/yaml/load_test.go index c3974233ad..09d27bce85 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load_test.go +++ b/src/cmd/tools/m3ctl/main/yaml/load_test.go @@ -1,10 +1,11 @@ package yaml import ( - "github.com/gogo/protobuf/jsonpb" - pb "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" "io/ioutil" "testing" + + "github.com/gogo/protobuf/jsonpb" + pb "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" ) // this uses _load to get an encoded stream of the diff --git a/src/cmd/tools/m3ctl/main/yaml/peeker.go b/src/cmd/tools/m3ctl/main/yaml/peeker.go index 2f4525dfe1..d10b9b270e 100644 --- a/src/cmd/tools/m3ctl/main/yaml/peeker.go +++ b/src/cmd/tools/m3ctl/main/yaml/peeker.go @@ -2,9 +2,11 @@ package yaml import ( "fmt" + + yaml2 "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" + "github.com/ghodss/yaml" "github.com/gogo/protobuf/proto" - yaml2 "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" ) // peek into the yaml to see what it is expected to be @@ -14,16 +16,13 @@ import ( // // returns the url path, proto.Message, and error func peeker(data []byte) (string, proto.Message, error) { - type peeker struct { Operation string } - peek := &peeker{} if err := yaml.Unmarshal(data, &peek); err != nil { return "", nil, err } - switch peek.Operation { case opCreate: return dbcreatePath, &yaml2.DatabaseCreateRequestYaml{}, nil @@ -36,6 +35,4 @@ func peeker(data []byte) (string, proto.Message, error) { default: return "", nil, fmt.Errorf("Unknown operation specified in the yaml\n") } - } - diff --git a/src/cmd/tools/m3ctl/main/yaml/peeker_test.go b/src/cmd/tools/m3ctl/main/yaml/peeker_test.go index 148941d833..888b39a6a9 100644 --- a/src/cmd/tools/m3ctl/main/yaml/peeker_test.go +++ b/src/cmd/tools/m3ctl/main/yaml/peeker_test.go @@ -1,10 +1,11 @@ package yaml import ( - "github.com/gogo/protobuf/jsonpb" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" "io/ioutil" "testing" + + "github.com/gogo/protobuf/jsonpb" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" ) func TestPeekerPositive(t *testing.T) { @@ -16,22 +17,18 @@ func TestPeekerPositive(t *testing.T) { if err != nil { t.Fatalf("operation selector failed to encode the unknown operation yaml test data:%v:\n", err) } - if urlpath != dbcreatePath { t.Errorf("urlpath is wrong:expected:%s:got:%s:\n", dbcreatePath, urlpath) } - data, err := _load(content, pbmessage) if err != nil { t.Fatalf("failed to encode to protocol:%v:\n", err) } - dest := yaml.DatabaseCreateRequestYaml{} unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} if err := unmarshaller.Unmarshal(data, &dest); err != nil { t.Fatalf("operation selector failed to unmarshal unknown operation data:%v:\n", err) } - if dest.Operation != opCreate { t.Errorf("dest type does not have the correct type via operation selector:expected:%v:got:%v:", opCreate, dest.Operation) } diff --git a/src/cmd/tools/m3ctl/main/yaml/types.go b/src/cmd/tools/m3ctl/main/yaml/types.go index c4bd32067c..2c2756b268 100644 --- a/src/cmd/tools/m3ctl/main/yaml/types.go +++ b/src/cmd/tools/m3ctl/main/yaml/types.go @@ -1,10 +1,10 @@ package yaml const ( - opCreate = "create" - opInit = "init" - opReplace = "replaceNode" - opNewNode = "newNode" - dbcreatePath = "/api/v1/database/create" + opCreate = "create" + opInit = "init" + opReplace = "replaceNode" + opNewNode = "newNode" + dbcreatePath = "/api/v1/database/create" placementPath = "/api/v1/services/m3db/placement" ) From 82583856d6509ea60eabd8fb946d1e18184b542a Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Tue, 4 Feb 2020 16:16:30 -0800 Subject: [PATCH 43/65] add zap --- src/cmd/tools/m3ctl/main/apply/apply.go | 9 +++-- src/cmd/tools/m3ctl/main/apply/cmd.go | 16 ++++---- .../m3ctl/main/checkArgs/popParseCheck.go | 1 + src/cmd/tools/m3ctl/main/client/checker.go | 9 +++-- src/cmd/tools/m3ctl/main/client/http.go | 37 ++++++++++--------- src/cmd/tools/m3ctl/main/delete/cmd.go | 4 +- .../tools/m3ctl/main/delete/namespaces/cmd.go | 18 +++++---- .../m3ctl/main/delete/namespaces/cmd_test.go | 7 ++-- .../m3ctl/main/delete/namespaces/delete.go | 7 ++-- .../tools/m3ctl/main/delete/placements/cmd.go | 14 +++---- .../m3ctl/main/delete/placements/cmd_test.go | 7 ++-- .../m3ctl/main/delete/placements/delete.go | 15 ++++---- src/cmd/tools/m3ctl/main/get/cmd.go | 15 +++++--- .../tools/m3ctl/main/get/namespaces/cmd.go | 14 +++---- .../m3ctl/main/get/namespaces/cmd_test.go | 7 ++-- .../tools/m3ctl/main/get/namespaces/get.go | 18 ++++----- .../tools/m3ctl/main/get/placements/cmd.go | 20 +++++----- .../m3ctl/main/get/placements/cmd_test.go | 7 ++-- .../tools/m3ctl/main/get/placements/get.go | 10 ++--- .../main/{checkArgs => globalopts}/types.go | 4 +- src/cmd/tools/m3ctl/main/main.go | 17 +++++++-- src/cmd/tools/m3ctl/main/yaml/load.go | 9 +++-- src/cmd/tools/m3ctl/main/yaml/peeker.go | 7 ++-- src/cmd/tools/m3ctl/main/yaml/types.go | 1 - 24 files changed, 151 insertions(+), 122 deletions(-) rename src/cmd/tools/m3ctl/main/{checkArgs => globalopts}/types.go (59%) diff --git a/src/cmd/tools/m3ctl/main/apply/apply.go b/src/cmd/tools/m3ctl/main/apply/apply.go index a09d863b88..d34edeff10 100644 --- a/src/cmd/tools/m3ctl/main/apply/apply.go +++ b/src/cmd/tools/m3ctl/main/apply/apply.go @@ -2,14 +2,15 @@ package apply import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" ) -func doApply(vals *applyArgs, globals checkArgs.GlobalOpts) { - path, data := yaml.Load(vals.yamlFlag.Value[0]) +func doApply(vals *applyVals, globals globalopts.GlobalOpts) { + path, data := yaml.Load(vals.yamlFlag.Value[0], globals.Zap) url := fmt.Sprintf("%s%s", globals.Endpoint, path) - client.DoPost(url, data, client.Dumper) + client.DoPost(url, data, client.Dumper, globals.Zap) return } diff --git a/src/cmd/tools/m3ctl/main/apply/cmd.go b/src/cmd/tools/m3ctl/main/apply/cmd.go index ccd946b391..53f4a15d3f 100644 --- a/src/cmd/tools/m3ctl/main/apply/cmd.go +++ b/src/cmd/tools/m3ctl/main/apply/cmd.go @@ -5,35 +5,35 @@ import ( "fmt" "os" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" - + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" "github.com/m3db/m3/src/x/config/configflag" ) -type applyArgs struct { +type applyVals struct { yamlFlag *configflag.FlagStringSlice } type Context struct { - vals *applyArgs + vals *applyVals handlers applyHandlers - GlobalOpts checkArgs.GlobalOpts + GlobalOpts globalopts.GlobalOpts Flags *flag.FlagSet } type applyHandlers struct { - handle func(*applyArgs, checkArgs.GlobalOpts) + handle func(*applyVals, globalopts.GlobalOpts) } func InitializeFlags() Context { return _setupFlags( - &applyArgs{ + &applyVals{ yamlFlag: &configflag.FlagStringSlice{}, }, applyHandlers{ handle: doApply, }) } -func _setupFlags(finalArgs *applyArgs, handlers applyHandlers) Context { + +func _setupFlags(finalArgs *applyVals, handlers applyHandlers) Context { applyFlags := flag.NewFlagSet("apply", flag.ContinueOnError) applyFlags.Var(finalArgs.yamlFlag, "f", "Path to yaml.") applyFlags.Usage = func() { diff --git a/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go b/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go index 71e3a85d7d..6a65549620 100644 --- a/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go +++ b/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go @@ -2,6 +2,7 @@ package checkArgs import ( "flag" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" ) diff --git a/src/cmd/tools/m3ctl/main/client/checker.go b/src/cmd/tools/m3ctl/main/client/checker.go index c03843bab4..40627919e1 100644 --- a/src/cmd/tools/m3ctl/main/client/checker.go +++ b/src/cmd/tools/m3ctl/main/client/checker.go @@ -3,17 +3,18 @@ package client import ( "fmt" "io/ioutil" - "log" "net/http" + + "go.uber.org/zap" ) -func checkForAndHandleError(url string, resp *http.Response) { - log.Printf("resp.StatusCode:%d:\n", resp.StatusCode) +func checkForAndHandleError(url string, resp *http.Response, zl *zap.SugaredLogger) { + zl.Infof("resp.StatusCode:%d:\n", resp.StatusCode) if resp.StatusCode > 299 { dat, _ := ioutil.ReadAll(resp.Body) if dat != nil { fmt.Println(string(dat)) } - log.Fatalf("error from m3db:%s:url:%s:", resp.Status, url) + zl.Fatalf("error from m3db:%s:url:%s:", resp.Status, url) } } diff --git a/src/cmd/tools/m3ctl/main/client/http.go b/src/cmd/tools/m3ctl/main/client/http.go index 666db698c0..c06f7a261e 100644 --- a/src/cmd/tools/m3ctl/main/client/http.go +++ b/src/cmd/tools/m3ctl/main/client/http.go @@ -4,32 +4,33 @@ import ( "fmt" "io" "io/ioutil" - "log" "net/http" "time" + + "go.uber.org/zap" ) const timeout = time.Duration(5 * time.Second) -func DoGet(url string, getter func(reader io.Reader)) { - log.Printf("DoGet:url:%s:\n", url) +func DoGet(url string, getter func(reader io.Reader, zl *zap.SugaredLogger), zl *zap.SugaredLogger) { + zl.Infof("DoGet:url:%s:\n", url) client := http.Client{ Timeout: timeout, } resp, err := client.Get(url) if err != nil { - log.Fatal(err) + zl.Fatal(err) } defer func() { ioutil.ReadAll(resp.Body) resp.Body.Close() }() - checkForAndHandleError(url, resp) - getter(resp.Body) + checkForAndHandleError(url, resp, zl) + getter(resp.Body, zl) } -func DoPost(url string, data io.Reader, getter func(reader io.Reader)) { - log.Printf("DoPost:url:%s:\n", url) +func DoPost(url string, data io.Reader, getter func(reader io.Reader, zl *zap.SugaredLogger), zl *zap.SugaredLogger) { + zl.Infof("DoPost:url:%s:\n", url) client := &http.Client{ Timeout: timeout, } @@ -37,19 +38,19 @@ func DoPost(url string, data io.Reader, getter func(reader io.Reader)) { req.Header.Add("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { - log.Fatal(err) + zl.Fatal(err) } defer func() { ioutil.ReadAll(resp.Body) resp.Body.Close() }() - checkForAndHandleError(url, resp) - getter(resp.Body) + checkForAndHandleError(url, resp, zl) + getter(resp.Body, zl) } -func DoDelete(url string, getter func(reader io.Reader)) { - log.Printf("DoDelete:url:%s:\n", url) +func DoDelete(url string, getter func(reader io.Reader, zl *zap.SugaredLogger), zl *zap.SugaredLogger) { + zl.Infof("DoDelete:url:%s:\n", url) client := &http.Client{ Timeout: timeout, } @@ -57,20 +58,20 @@ func DoDelete(url string, getter func(reader io.Reader)) { req.Header.Add("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { - log.Fatal(err) + zl.Fatal(err) } defer func() { ioutil.ReadAll(resp.Body) resp.Body.Close() }() - checkForAndHandleError(url, resp) - getter(resp.Body) + checkForAndHandleError(url, resp, zl) + getter(resp.Body, zl) } -func Dumper(in io.Reader) { +func Dumper(in io.Reader, zl *zap.SugaredLogger) { dat, err := ioutil.ReadAll(in) if err != nil { - log.Fatal(err) + zl.Fatal(err) } fmt.Println(string(dat)) } diff --git a/src/cmd/tools/m3ctl/main/delete/cmd.go b/src/cmd/tools/m3ctl/main/delete/cmd.go index 9e69065d2f..4288b8711c 100644 --- a/src/cmd/tools/m3ctl/main/delete/cmd.go +++ b/src/cmd/tools/m3ctl/main/delete/cmd.go @@ -5,15 +5,15 @@ import ( "fmt" "os" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/delete/namespaces" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/delete/placements" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" ) // this has all that the upper level needs to dispatch to here type Context struct { - GlobalOpts checkArgs.GlobalOpts + GlobalOpts globalopts.GlobalOpts Flags *flag.FlagSet } diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go index 83762f1686..936caea91e 100644 --- a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go @@ -5,36 +5,36 @@ import ( "fmt" "os" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" ) // all the values from the cli args are stored in here // for all the placement-related commands -type namespacesArgs struct { +type namespacesVals struct { nodeName *string } - // this has all that the upper dispatcher needs to parse the cli type Context struct { - vals *namespacesArgs + vals *namespacesVals handlers namespacesHandlers - Globals checkArgs.GlobalOpts + Globals globalopts.GlobalOpts Flags *flag.FlagSet } type namespacesHandlers struct { - handle func(*namespacesArgs, checkArgs.GlobalOpts) + handle func(*namespacesVals, globalopts.GlobalOpts) } func InitializeFlags() Context { return _setupFlags( - &namespacesArgs{}, + &namespacesVals{}, namespacesHandlers{ handle: doDelete, }, ) } -func _setupFlags(finalArgs *namespacesArgs, handler namespacesHandlers) Context { + +func _setupFlags(finalArgs *namespacesVals, handler namespacesHandlers) Context { nsFlags := flag.NewFlagSet("ns", flag.ContinueOnError) finalArgs.nodeName = nsFlags.String("node", "", "delete the specified node in the placement") nsFlags.Usage = func() { @@ -54,6 +54,7 @@ qqq Flags: nsFlags, } } + func (ctx Context) PopParseDispatch(cli []string) error { if len(cli) < 1 { ctx.Flags.Usage() @@ -73,6 +74,7 @@ func (ctx Context) PopParseDispatch(cli []string) error { } return nil } + func dispatcher(ctx Context) error { nextArgs := ctx.Flags.Args() if len(nextArgs) != 0 { diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go index 0f5c92ed27..7efaf24572 100644 --- a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go @@ -1,15 +1,16 @@ package namespaces import ( - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "testing" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" ) func makeStub() Context { ctx := _setupFlags( - &namespacesArgs{}, + &namespacesVals{}, namespacesHandlers{ - handle: func(*namespacesArgs, checkArgs.GlobalOpts) { return }, + handle: func(*namespacesVals, globalopts.GlobalOpts) { return }, }, ) ctx.Globals.Endpoint = "fakeEndpoint" diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/delete.go b/src/cmd/tools/m3ctl/main/delete/namespaces/delete.go index 127a61497d..daf591b7e0 100644 --- a/src/cmd/tools/m3ctl/main/delete/namespaces/delete.go +++ b/src/cmd/tools/m3ctl/main/delete/namespaces/delete.go @@ -2,11 +2,12 @@ package namespaces import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" ) -func doDelete(flags *namespacesArgs, globals checkArgs.GlobalOpts) { +func doDelete(flags *namespacesVals, globals globalopts.GlobalOpts) { url := fmt.Sprintf("%s%s/%s", globals.Endpoint, "/api/v1/services/m3db/namespace", *flags.nodeName) - client.DoDelete(url, client.Dumper) + client.DoDelete(url, client.Dumper, globals.Zap) } diff --git a/src/cmd/tools/m3ctl/main/delete/placements/cmd.go b/src/cmd/tools/m3ctl/main/delete/placements/cmd.go index 99c0b9ddd6..af3c2e2b15 100644 --- a/src/cmd/tools/m3ctl/main/delete/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/delete/placements/cmd.go @@ -5,37 +5,37 @@ import ( "fmt" "os" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" ) // all the values from the cli args are stored in here // for all the placement-related commands -type placementArgs struct { +type placementVals struct { deleteEntire *bool nodeName *string } // this has all that the upper dispatcher needs to parse the cli type Context struct { - vals *placementArgs + vals *placementVals handlers placementHandlers - Globals checkArgs.GlobalOpts + Globals globalopts.GlobalOpts Flags *flag.FlagSet } type placementHandlers struct { - handle func(*placementArgs, checkArgs.GlobalOpts) + handle func(*placementVals, globalopts.GlobalOpts) } func InitializeFlags() Context { return _setupFlags( - &placementArgs{}, + &placementVals{}, placementHandlers{ handle: doDelete, }, ) } -func _setupFlags(finalArgs *placementArgs, handler placementHandlers) Context { +func _setupFlags(finalArgs *placementVals, handler placementHandlers) Context { placementFlags := flag.NewFlagSet("pl", flag.ContinueOnError) finalArgs.deleteEntire = placementFlags.Bool("all", false, "delete the entire placement") finalArgs.nodeName = placementFlags.String("node", "", "delete the specified node in the placement") diff --git a/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go b/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go index 18f66cdabd..05f960b581 100644 --- a/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go @@ -1,15 +1,16 @@ package placements import ( - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "testing" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" ) func makeStub() Context { ctx := _setupFlags( - &placementArgs{}, + &placementVals{}, placementHandlers{ - handle: func(*placementArgs, checkArgs.GlobalOpts) { return }, + handle: func(*placementVals, globalopts.GlobalOpts) { return }, }, ) ctx.Globals.Endpoint = "nuch" diff --git a/src/cmd/tools/m3ctl/main/delete/placements/delete.go b/src/cmd/tools/m3ctl/main/delete/placements/delete.go index 087cdb96d3..22ea601d8e 100644 --- a/src/cmd/tools/m3ctl/main/delete/placements/delete.go +++ b/src/cmd/tools/m3ctl/main/delete/placements/delete.go @@ -2,18 +2,19 @@ package placements import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - common "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" ) -func doDelete(s *placementArgs, globals checkArgs.GlobalOpts) { +func doDelete(s *placementVals, globals globalopts.GlobalOpts) { if *s.deleteEntire { - url := fmt.Sprintf("%s%s", globals.Endpoint, common.DefaultPath) - client.DoDelete(url, client.Dumper) + url := fmt.Sprintf("%s%s", globals.Endpoint, placements.DefaultPath) + client.DoDelete(url, client.Dumper, globals.Zap) return } - url := fmt.Sprintf("%s%s/%s", globals.Endpoint, common.DefaultPath, *s.nodeName) - client.DoDelete(url, client.Dumper) + url := fmt.Sprintf("%s%s/%s", globals.Endpoint, placements.DefaultPath, *s.nodeName) + client.DoDelete(url, client.Dumper, globals.Zap) return } diff --git a/src/cmd/tools/m3ctl/main/get/cmd.go b/src/cmd/tools/m3ctl/main/get/cmd.go index 77d16e1e9d..923f1d0102 100644 --- a/src/cmd/tools/m3ctl/main/get/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/cmd.go @@ -5,30 +5,32 @@ import ( "fmt" "os" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/get/namespaces" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/get/placements" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" ) type Context struct { - GlobalOpts checkArgs.GlobalOpts - Get *flag.FlagSet + GlobalOpts globalopts.GlobalOpts + Flags *flag.FlagSet } func InitializeFlags() Context { return _setupFlags() } + func _setupFlags() Context { getFlags := flag.NewFlagSet("get", flag.ContinueOnError) getFlags.Usage = func() { fmt.Fprintf(os.Stderr, "help msg here\n") getFlags.PrintDefaults() } - return Context{Get: getFlags} + return Context{Flags: getFlags} } + func (ctx Context) PopParseDispatch(cli []string) error { - thisFlagset := ctx.Get + thisFlagset := ctx.Flags if len(cli) < 1 { thisFlagset.Usage() return &errors.FlagsError{} @@ -36,12 +38,13 @@ func (ctx Context) PopParseDispatch(cli []string) error { inArgs := cli[1:] if err := thisFlagset.Parse(inArgs); err != nil { thisFlagset.Usage() - return &errors.FlagsError{} + return err } if thisFlagset.NArg() == 0 { thisFlagset.Usage() return &errors.FlagsError{} } + plctx := placements.InitializeFlags() nsctx := namespaces.InitializeFlags() nextArgs := thisFlagset.Args() diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go index dfcbc17b7d..d4229f10ae 100644 --- a/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go @@ -5,33 +5,33 @@ import ( "fmt" "os" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" ) -type namespacesArgs struct { +type namespacesVals struct { showAll *bool } type Context struct { - vals *namespacesArgs + vals *namespacesVals handlers namespacesHandlers - Globals checkArgs.GlobalOpts + Globals globalopts.GlobalOpts Flags *flag.FlagSet } type namespacesHandlers struct { - handle func(*namespacesArgs, checkArgs.GlobalOpts) + handle func(*namespacesVals, globalopts.GlobalOpts) } func InitializeFlags() Context { return _setupFlags( - &namespacesArgs{}, + &namespacesVals{}, namespacesHandlers{ handle: doGet, }, ) } -func _setupFlags(finalArgs *namespacesArgs, handler namespacesHandlers) Context { +func _setupFlags(finalArgs *namespacesVals, handler namespacesHandlers) Context { namespaceFlags := flag.NewFlagSet("ns", flag.ContinueOnError) finalArgs.showAll = namespaceFlags.Bool("all", false, "get all the standard info for namespaces (otherwise default behaviour lists only the names)") namespaceFlags.Usage = func() { diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go index c0cf130d48..92db6319ce 100644 --- a/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go @@ -1,15 +1,16 @@ package namespaces import ( - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "testing" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" ) func makeStub() Context { ctx := _setupFlags( - &namespacesArgs{}, + &namespacesVals{}, namespacesHandlers{ - handle: func(*namespacesArgs, checkArgs.GlobalOpts) { return }, + handle: func(*namespacesVals, globalopts.GlobalOpts) { return }, }, ) ctx.Globals.Endpoint = "nuch" diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/get.go b/src/cmd/tools/m3ctl/main/get/namespaces/get.go index e51b8961f6..26bdd84f9a 100644 --- a/src/cmd/tools/m3ctl/main/get/namespaces/get.go +++ b/src/cmd/tools/m3ctl/main/get/namespaces/get.go @@ -2,31 +2,31 @@ package namespaces import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" + "go.uber.org/zap" "io" - "log" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - common "github.com/m3db/m3/src/cmd/tools/m3ctl/main/namespaces" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/namespaces" "github.com/m3db/m3/src/query/generated/proto/admin" "github.com/gogo/protobuf/jsonpb" ) -func doGet(flags *namespacesArgs, globals checkArgs.GlobalOpts) { - url := fmt.Sprintf("%s%s?%s", globals.Endpoint, common.DefaultPath, common.DebugQS) +func doGet(flags *namespacesVals, globals globalopts.GlobalOpts) { + url := fmt.Sprintf("%s%s?%s", globals.Endpoint, namespaces.DefaultPath, namespaces.DebugQS) if *flags.showAll { - client.DoGet(url, client.Dumper) + client.DoGet(url, client.Dumper, globals.Zap) } else { - client.DoGet(url, showNames) + client.DoGet(url, showNames, globals.Zap) } } -func showNames(in io.Reader) { +func showNames(in io.Reader, zl *zap.SugaredLogger) { registry := admin.NamespaceGetResponse{} unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} if err := unmarshaller.Unmarshal(in, ®istry); err != nil { - log.Fatal(err) + zl.Fatal(err) } for k, _ := range registry.Registry.Namespaces { fmt.Println(k) diff --git a/src/cmd/tools/m3ctl/main/get/placements/cmd.go b/src/cmd/tools/m3ctl/main/get/placements/cmd.go index ad9d64b6cc..0434abc09b 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/placements/cmd.go @@ -5,31 +5,32 @@ import ( "fmt" "os" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" ) -type placementArgs struct { +type placementVals struct { } type Context struct { - vals *placementArgs + vals *placementVals handlers placementHandlers - Globals checkArgs.GlobalOpts + Globals globalopts.GlobalOpts Flags *flag.FlagSet } type placementHandlers struct { - handle func(*placementArgs, checkArgs.GlobalOpts) + handle func(*placementVals, globalopts.GlobalOpts) } func InitializeFlags() Context { return _setupFlags( - &placementArgs{}, + &placementVals{}, placementHandlers{ handle: doGet, }, ) } -func _setupFlags(finalArgs *placementArgs, handler placementHandlers) Context { + +func _setupFlags(finalArgs *placementVals, handler placementHandlers) Context { placementFlags := flag.NewFlagSet("pl", flag.ContinueOnError) placementFlags.Usage = func() { fmt.Fprintf(os.Stderr, ` @@ -46,10 +47,10 @@ Default behaviour (no arguments) is to provide a json dump of the existing place return Context{ vals: finalArgs, handlers: handler, - //GlobalOpts: nil, Flags: placementFlags, } } + func (ctx Context) PopParseDispatch(cli []string) error { if len(cli) < 1 { ctx.Flags.Usage() @@ -58,7 +59,7 @@ func (ctx Context) PopParseDispatch(cli []string) error { inArgs := cli[1:] if err := ctx.Flags.Parse(inArgs); err != nil { ctx.Flags.Usage() - return &errors.FlagsError{} + return err } if ctx.Flags.NArg() == 0 { ctx.handlers.handle(ctx.vals, ctx.Globals) @@ -70,6 +71,7 @@ func (ctx Context) PopParseDispatch(cli []string) error { } return nil } + func dispatcher(ctx Context) error { nextArgs := ctx.Flags.Args() switch nextArgs[0] { diff --git a/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go b/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go index abad88c142..63b004b182 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go @@ -1,15 +1,16 @@ package placements import ( - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "testing" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" ) func makeStub() Context { ctx := _setupFlags( - &placementArgs{}, + &placementVals{}, placementHandlers{ - handle: func(*placementArgs, checkArgs.GlobalOpts) { return }, + handle: func(*placementVals, globalopts.GlobalOpts) { return }, }, ) ctx.Globals.Endpoint = "nuch" diff --git a/src/cmd/tools/m3ctl/main/get/placements/get.go b/src/cmd/tools/m3ctl/main/get/placements/get.go index 35af905519..f82f35e64e 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/get.go +++ b/src/cmd/tools/m3ctl/main/get/placements/get.go @@ -3,13 +3,13 @@ package placements import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/checkArgs" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - common "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" ) -func doGet(s *placementArgs, globals checkArgs.GlobalOpts) { - url := fmt.Sprintf("%s%s", globals.Endpoint, common.DefaultPath) - client.DoGet(url, client.Dumper) +func doGet(s *placementVals, globals globalopts.GlobalOpts) { + url := fmt.Sprintf("%s%s", globals.Endpoint, placements.DefaultPath) + client.DoGet(url, client.Dumper, globals.Zap) return } diff --git a/src/cmd/tools/m3ctl/main/checkArgs/types.go b/src/cmd/tools/m3ctl/main/globalopts/types.go similarity index 59% rename from src/cmd/tools/m3ctl/main/checkArgs/types.go rename to src/cmd/tools/m3ctl/main/globalopts/types.go index 0ccdbbfa5f..f0c923c4e3 100644 --- a/src/cmd/tools/m3ctl/main/checkArgs/types.go +++ b/src/cmd/tools/m3ctl/main/globalopts/types.go @@ -1,8 +1,8 @@ -package checkArgs +package globalopts import "go.uber.org/zap" type GlobalOpts struct { Endpoint string - zap *zap.SugaredLogger + Zap *zap.SugaredLogger } diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 53e4c2b918..5ac01b49a0 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -23,10 +23,12 @@ package main import ( "flag" "fmt" + "os" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/apply" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/delete" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/get" - "os" + "go.uber.org/zap" ) const ( @@ -55,7 +57,7 @@ Usage of %s: Each subcommand has its own built-in help provided via "-h". `, os.Args[0], applyFlagSets.Flags.Name(), - getFlagSets.Get.Name(), + getFlagSets.Flags.Name(), deleteFlagSets.Flags.Name()) flag.PrintDefaults() @@ -66,22 +68,31 @@ Each subcommand has its own built-in help provided via "-h". flag.Usage() os.Exit(1) } + rawLogger, err := zap.NewDevelopment() + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + log := rawLogger.Sugar() // dispatch to the next level switch flag.Arg(0) { - case getFlagSets.Get.Name(): + case getFlagSets.Flags.Name(): getFlagSets.GlobalOpts.Endpoint = *endPoint + getFlagSets.GlobalOpts.Zap = log if err := getFlagSets.PopParseDispatch(flag.Args()); err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } case deleteFlagSets.Flags.Name(): deleteFlagSets.GlobalOpts.Endpoint = *endPoint + deleteFlagSets.GlobalOpts.Zap = log if err := deleteFlagSets.PopParseDispatch(flag.Args()); err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } case applyFlagSets.Flags.Name(): applyFlagSets.GlobalOpts.Endpoint = *endPoint + applyFlagSets.GlobalOpts.Zap = log if err := applyFlagSets.PopParseDispatch(flag.Args()); err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) diff --git a/src/cmd/tools/m3ctl/main/yaml/load.go b/src/cmd/tools/m3ctl/main/yaml/load.go index bd6303cde7..ec529d9485 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load.go +++ b/src/cmd/tools/m3ctl/main/yaml/load.go @@ -2,9 +2,9 @@ package yaml import ( "bytes" + "go.uber.org/zap" "io" "io/ioutil" - "log" "github.com/ghodss/yaml" "github.com/gogo/protobuf/jsonpb" @@ -19,18 +19,19 @@ import ( // // See the examples directories. // -func Load(path string) (string, io.Reader) { +func Load(path string, zl *zap.SugaredLogger) (string, io.Reader) { content, err := ioutil.ReadFile(path) if err != nil { - log.Fatal(err) + zl.Fatal(err) } url, pbmessage, err := peeker(content) if err != nil { - log.Fatalf("error inspecting the yaml:it might be bad yaml or it might be an unknown operation:%v:from yaml file:%s:", err, path) + zl.Fatalf("error inspecting the yaml:it might be bad yaml or it might be an unknown operation:%v:from yaml file:%s:", err, path) } rv, err := _load(content, pbmessage) return url, rv } + func _load(content []byte, target proto.Message) (io.Reader, error) { // unmarshal it into json if err := yaml.Unmarshal(content, target); err != nil { diff --git a/src/cmd/tools/m3ctl/main/yaml/peeker.go b/src/cmd/tools/m3ctl/main/yaml/peeker.go index d10b9b270e..58f7e7d4c9 100644 --- a/src/cmd/tools/m3ctl/main/yaml/peeker.go +++ b/src/cmd/tools/m3ctl/main/yaml/peeker.go @@ -2,6 +2,7 @@ package yaml import ( "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" yaml2 "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" @@ -27,11 +28,11 @@ func peeker(data []byte) (string, proto.Message, error) { case opCreate: return dbcreatePath, &yaml2.DatabaseCreateRequestYaml{}, nil case opInit: - return fmt.Sprintf("%s/init", placementPath), &yaml2.PlacementInitRequestYaml{}, nil + return fmt.Sprintf("%s/init", placements.DefaultPath), &yaml2.PlacementInitRequestYaml{}, nil case opReplace: - return fmt.Sprintf("%s/replace", placementPath), &yaml2.PlacementReplaceRequestYaml{}, nil + return fmt.Sprintf("%s/replace", placements.DefaultPath), &yaml2.PlacementReplaceRequestYaml{}, nil case opNewNode: - return fmt.Sprintf("%s", placementPath), &yaml2.PlacementInitRequestYaml{}, nil + return fmt.Sprintf("%s", placements.DefaultPath), &yaml2.PlacementInitRequestYaml{}, nil default: return "", nil, fmt.Errorf("Unknown operation specified in the yaml\n") } diff --git a/src/cmd/tools/m3ctl/main/yaml/types.go b/src/cmd/tools/m3ctl/main/yaml/types.go index 2c2756b268..d863859b02 100644 --- a/src/cmd/tools/m3ctl/main/yaml/types.go +++ b/src/cmd/tools/m3ctl/main/yaml/types.go @@ -6,5 +6,4 @@ const ( opReplace = "replaceNode" opNewNode = "newNode" dbcreatePath = "/api/v1/database/create" - placementPath = "/api/v1/services/m3db/placement" ) From 47d28b1e7966cadcb2991bce42093cb1148814f1 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Tue, 4 Feb 2020 20:33:51 -0800 Subject: [PATCH 44/65] add usage messages and zap --- src/cmd/tools/m3ctl/main/apply/apply.go | 2 +- src/cmd/tools/m3ctl/main/apply/cmd.go | 35 ++++++++++++++++++- src/cmd/tools/m3ctl/main/delete/cmd.go | 6 ++-- .../tools/m3ctl/main/delete/namespaces/cmd.go | 8 ++--- .../m3ctl/main/delete/namespaces/cmd_test.go | 8 ++--- .../tools/m3ctl/main/delete/placements/cmd.go | 6 +--- src/cmd/tools/m3ctl/main/get/cmd.go | 6 ++-- .../tools/m3ctl/main/get/namespaces/cmd.go | 7 +--- .../tools/m3ctl/main/get/placements/cmd.go | 7 +--- 9 files changed, 52 insertions(+), 33 deletions(-) diff --git a/src/cmd/tools/m3ctl/main/apply/apply.go b/src/cmd/tools/m3ctl/main/apply/apply.go index d34edeff10..7f371730b6 100644 --- a/src/cmd/tools/m3ctl/main/apply/apply.go +++ b/src/cmd/tools/m3ctl/main/apply/apply.go @@ -2,9 +2,9 @@ package apply import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" + "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" ) diff --git a/src/cmd/tools/m3ctl/main/apply/cmd.go b/src/cmd/tools/m3ctl/main/apply/cmd.go index 53f4a15d3f..61ac0e6740 100644 --- a/src/cmd/tools/m3ctl/main/apply/cmd.go +++ b/src/cmd/tools/m3ctl/main/apply/cmd.go @@ -37,7 +37,40 @@ func _setupFlags(finalArgs *applyVals, handlers applyHandlers) Context { applyFlags := flag.NewFlagSet("apply", flag.ContinueOnError) applyFlags.Var(finalArgs.yamlFlag, "f", "Path to yaml.") applyFlags.Usage = func() { - fmt.Fprintf(os.Stderr, "help msg here for apply\n") + fmt.Fprintf(os.Stderr, ` +Usage: m3ctl %s -f somedir/somename.yaml + +The "%s" subcommand takes its inputs from a yaml file and knows how to do the +following operations: + + * create - create a namespace and initialize a topology + * init - initializes a placement + * newNode - adds a node to a placement + * replaceNode - replaces a node in a placement + +Example yaml files are included in the yaml/examples directory. Here's an +example for database creation: + +--- +operation: create +type: cluster +namespace_name: default +retention_time: 168h +num_shards: 64 +replication_factor: 1 +hosts: +- id: m3db_seed + isolation_group: rack-a + zone: embedded + weight: 1024 + endpoint: m3db_seed:9000 + hostname: m3db_seed + port: 9000 + +' + + +`, applyFlags.Name(), applyFlags.Name()) applyFlags.PrintDefaults() } return Context{ diff --git a/src/cmd/tools/m3ctl/main/delete/cmd.go b/src/cmd/tools/m3ctl/main/delete/cmd.go index 4288b8711c..2d5ad92000 100644 --- a/src/cmd/tools/m3ctl/main/delete/cmd.go +++ b/src/cmd/tools/m3ctl/main/delete/cmd.go @@ -23,7 +23,10 @@ func InitializeFlags() Context { func _setupFlags() Context { deleteFlags := flag.NewFlagSet("delete", flag.ContinueOnError) deleteFlags.Usage = func() { - fmt.Fprintf(os.Stderr, "delete help msg here\n") + fmt.Fprintf(os.Stderr, ` +"%s" is for deletiion operations for namespaces and placements. + +`) deleteFlags.PrintDefaults() } return Context{Flags: deleteFlags} @@ -47,7 +50,6 @@ func (ctx Context) PopParseDispatch(cli []string) error { plctx := placements.InitializeFlags() nsctx := namespaces.InitializeFlags() nextArgs := thisFlagset.Args() - fmt.Print(nextArgs) switch nextArgs[0] { case plctx.Flags.Name(): plctx.Globals = ctx.GlobalOpts diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go index 936caea91e..199db4c1b1 100644 --- a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go @@ -36,14 +36,10 @@ func InitializeFlags() Context { func _setupFlags(finalArgs *namespacesVals, handler namespacesHandlers) Context { nsFlags := flag.NewFlagSet("ns", flag.ContinueOnError) - finalArgs.nodeName = nsFlags.String("node", "", "delete the specified node in the placement") + finalArgs.nodeName = nsFlags.String("id", "", "delete the specified node in the placement") nsFlags.Usage = func() { fmt.Fprintf(os.Stderr, ` -"%s" is for acting on placements. - -Description: - -qqq +The delete "%s" subcommand will delete namespace. `, nsFlags.Name()) nsFlags.PrintDefaults() diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go index 7efaf24572..538950c832 100644 --- a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go @@ -23,7 +23,7 @@ func TestBasic(t *testing.T) { successCondition func(error) bool }{ { - args: []string{"ns", "-node", "eee"}, + args: []string{"ns", "-id", "eee"}, msg: "It should return no error for sane args", successCondition: func(err error) bool { return err == nil }, }, @@ -43,17 +43,17 @@ func TestBasic(t *testing.T) { successCondition: func(err error) bool { return err != nil }, }, { - args: []string{"ns", "-node"}, + args: []string{"ns", "-id"}, msg: "It should return error because we ran with -node but no args", successCondition: func(err error) bool { return err != nil }, }, { - args: []string{"ns", "-node", "eee", "errr"}, + args: []string{"ns", "-id", "eee", "errr"}, msg: "It should return error because we got extra args", successCondition: func(err error) bool { return err != nil }, }, { - args: []string{"ns", "-node", ""}, + args: []string{"ns", "-id", ""}, msg: "It should return an error because we got an empty val", successCondition: func(err error) bool { return err == nil }, }, diff --git a/src/cmd/tools/m3ctl/main/delete/placements/cmd.go b/src/cmd/tools/m3ctl/main/delete/placements/cmd.go index af3c2e2b15..6063ff86a7 100644 --- a/src/cmd/tools/m3ctl/main/delete/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/delete/placements/cmd.go @@ -41,11 +41,7 @@ func _setupFlags(finalArgs *placementVals, handler placementHandlers) Context { finalArgs.nodeName = placementFlags.String("node", "", "delete the specified node in the placement") placementFlags.Usage = func() { fmt.Fprintf(os.Stderr, ` -"%s" is for acting on placements. - -Description: - -qqq +The delete "%s" subcommand will delete an entire placement, or the specified node from the placement. `, placementFlags.Name()) placementFlags.PrintDefaults() diff --git a/src/cmd/tools/m3ctl/main/get/cmd.go b/src/cmd/tools/m3ctl/main/get/cmd.go index 923f1d0102..afb705a158 100644 --- a/src/cmd/tools/m3ctl/main/get/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/cmd.go @@ -23,7 +23,10 @@ func InitializeFlags() Context { func _setupFlags() Context { getFlags := flag.NewFlagSet("get", flag.ContinueOnError) getFlags.Usage = func() { - fmt.Fprintf(os.Stderr, "help msg here\n") + fmt.Fprintf(os.Stderr, ` +"%s" is for displaying information about the namespaces and placements. + +`) getFlags.PrintDefaults() } return Context{Flags: getFlags} @@ -48,7 +51,6 @@ func (ctx Context) PopParseDispatch(cli []string) error { plctx := placements.InitializeFlags() nsctx := namespaces.InitializeFlags() nextArgs := thisFlagset.Args() - fmt.Print(nextArgs) switch nextArgs[0] { case plctx.Flags.Name(): plctx.Globals = ctx.GlobalOpts diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go index d4229f10ae..db099470a9 100644 --- a/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go @@ -36,12 +36,7 @@ func _setupFlags(finalArgs *namespacesVals, handler namespacesHandlers) Context finalArgs.showAll = namespaceFlags.Bool("all", false, "get all the standard info for namespaces (otherwise default behaviour lists only the names)") namespaceFlags.Usage = func() { fmt.Fprintf(os.Stderr, ` -"%s" is for acting on placements. - -Description: - -Default behaviour (no arguments) is to provide a json dump of the existing placement. - +The "%s" subcommand will list the namesspace names, or verbosely dump all details about the namespaces in json format. `, namespaceFlags.Name()) namespaceFlags.PrintDefaults() diff --git a/src/cmd/tools/m3ctl/main/get/placements/cmd.go b/src/cmd/tools/m3ctl/main/get/placements/cmd.go index 0434abc09b..7ad2601d3b 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/placements/cmd.go @@ -34,12 +34,7 @@ func _setupFlags(finalArgs *placementVals, handler placementHandlers) Context { placementFlags := flag.NewFlagSet("pl", flag.ContinueOnError) placementFlags.Usage = func() { fmt.Fprintf(os.Stderr, ` -"%s" is for acting on placements. - -Description: - -Default behaviour (no arguments) is to provide a json dump of the existing placement. - +"%s" is for displaying the existing placement. `, placementFlags.Name()) placementFlags.PrintDefaults() From 3467e72c342fa203f0a30965e16f64846dbe760b Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Tue, 4 Feb 2020 20:39:09 -0800 Subject: [PATCH 45/65] readme --- src/cmd/tools/m3ctl/README.md | 52 +++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/src/cmd/tools/m3ctl/README.md b/src/cmd/tools/m3ctl/README.md index b59b6a7ed7..1c4d64480e 100644 --- a/src/cmd/tools/m3ctl/README.md +++ b/src/cmd/tools/m3ctl/README.md @@ -28,38 +28,50 @@ Examples # show help m3ctl -h # create a database - m3ctl db create -f ./database/examples/devel.yaml + m3ctl apply -f ./database/examples/dbcreate.yaml # list namespaces - m3ctl ns + m3ctl get ns # delete a namespace - m3ctl ns delete -name default + m3ctl delete ns -id default # list placements - m3ctl pl + m3ctl get pl # point to some remote and list namespaces - m3ctl -endpoint http://localhost:7201 ns + m3ctl -endpoint http://localhost:7201 get ns # check the namespaces in a kubernetes cluster # first setup a tunnel via kubectl port-forward ... 7201 - m3ctl -endpoint http://localhost:7201 ns + m3ctl -endpoint http://localhost:7201 get ns # list the ids of the placements - m3ctl -endpoint http://localhost:7201 pl | jq .placement.instances[].id + m3ctl -endpoint http://localhost:7201 get pl | jq .placement.instances[].id -Some example yaml files are provided in the examples directories. -Here's one for database creation: +Some example yaml files for the "apply" subcommand are provided in the yaml/examples directory. +Here's one to initialize a topology: --- - type: cluster - namespace_name: default - retention_time: 168h + operation: init num_shards: 64 replication_factor: 1 - hosts: - - id: m3db_seed - isolation_group: rack-a - zone: embedded - weight: 1024 - endpoint: m3db_seed:9000 - hostname: m3db_seed - port: 9000 + instances: + - id: nodeid1 + isolation_group: isogroup1 + zone: etcd1 + weight: 100 + endpoint: node1:9000 + hostname: node1 + port: 9000 + - id: nodeid2 + isolation_group: isogroup2 + zone: etcd1 + weight: 100 + endpoint: node2:9000 + hostname: node2 + port: 9000 + - id: nodeid3 + isolation_group: isogroup3 + zone: etcd1 + weight: 100 + endpoint: node3:9000 + hostname: node3 + port: 9000 See the examples directories below. From b3384e3e91236798c236144e5601f41dbd2e9446 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Tue, 4 Feb 2020 20:40:56 -0800 Subject: [PATCH 46/65] readme and go fmt --- src/cmd/tools/m3ctl/README.md | 5 ++--- src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go | 1 + src/cmd/tools/m3ctl/main/get/placements/cmd.go | 2 +- src/cmd/tools/m3ctl/main/yaml/types.go | 10 +++++----- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/cmd/tools/m3ctl/README.md b/src/cmd/tools/m3ctl/README.md index 1c4d64480e..36754834f1 100644 --- a/src/cmd/tools/m3ctl/README.md +++ b/src/cmd/tools/m3ctl/README.md @@ -1,10 +1,9 @@ -M3DB Tool -======== +M3DB CLI Tool +============= This is a CLI tool to do some things that may be desirable for cluster introspection, or for operational purposes. - Where configuration data is required its provided via YAML. You can: diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go index 199db4c1b1..c690c6fe3a 100644 --- a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go @@ -14,6 +14,7 @@ import ( type namespacesVals struct { nodeName *string } + // this has all that the upper dispatcher needs to parse the cli type Context struct { vals *namespacesVals diff --git a/src/cmd/tools/m3ctl/main/get/placements/cmd.go b/src/cmd/tools/m3ctl/main/get/placements/cmd.go index 7ad2601d3b..47242d9452 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/placements/cmd.go @@ -42,7 +42,7 @@ func _setupFlags(finalArgs *placementVals, handler placementHandlers) Context { return Context{ vals: finalArgs, handlers: handler, - Flags: placementFlags, + Flags: placementFlags, } } diff --git a/src/cmd/tools/m3ctl/main/yaml/types.go b/src/cmd/tools/m3ctl/main/yaml/types.go index d863859b02..1fef5f541e 100644 --- a/src/cmd/tools/m3ctl/main/yaml/types.go +++ b/src/cmd/tools/m3ctl/main/yaml/types.go @@ -1,9 +1,9 @@ package yaml const ( - opCreate = "create" - opInit = "init" - opReplace = "replaceNode" - opNewNode = "newNode" - dbcreatePath = "/api/v1/database/create" + opCreate = "create" + opInit = "init" + opReplace = "replaceNode" + opNewNode = "newNode" + dbcreatePath = "/api/v1/database/create" ) From 7e56aaeb54a90c1b4349a1c03051c70ed690eff1 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Tue, 4 Feb 2020 20:44:44 -0800 Subject: [PATCH 47/65] restore a deleted tab from the Makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2273f044eb..b350d2e7fe 100644 --- a/Makefile +++ b/Makefile @@ -118,7 +118,7 @@ $(SERVICE)-linux-amd64: .PHONY: $(SERVICE)-docker-dev $(SERVICE)-docker-dev: clean-build $(SERVICE)-linux-amd64 mkdir -p ./bin/config - + # Hacky way to find all configs and put into ./bin/config/ find ./src | fgrep config | fgrep ".yml" | xargs -I{} cp {} ./bin/config/ find ./src | fgrep config | fgrep ".yaml" | xargs -I{} cp {} ./bin/config/ From bd3be5fff33a264fc147cd1f0bd9bf41881a3af1 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Wed, 5 Feb 2020 12:43:53 -0800 Subject: [PATCH 48/65] make the bottom return errors too --- src/cmd/tools/m3ctl/main/apply/apply.go | 10 +++--- src/cmd/tools/m3ctl/main/apply/cmd.go | 5 ++- src/cmd/tools/m3ctl/main/client/checker.go | 5 +-- src/cmd/tools/m3ctl/main/client/http.go | 36 +++++++++++-------- src/cmd/tools/m3ctl/main/delete/cmd.go | 2 +- .../tools/m3ctl/main/delete/namespaces/cmd.go | 6 ++-- .../m3ctl/main/delete/namespaces/cmd_test.go | 2 +- .../m3ctl/main/delete/namespaces/delete.go | 4 +-- .../tools/m3ctl/main/delete/placements/cmd.go | 5 ++- .../m3ctl/main/delete/placements/cmd_test.go | 2 +- .../m3ctl/main/delete/placements/delete.go | 8 ++--- .../tools/m3ctl/main/get/namespaces/cmd.go | 8 ++--- .../m3ctl/main/get/namespaces/cmd_test.go | 2 +- .../tools/m3ctl/main/get/namespaces/get.go | 11 +++--- .../tools/m3ctl/main/get/placements/cmd.go | 8 ++--- .../m3ctl/main/get/placements/cmd_test.go | 2 +- .../tools/m3ctl/main/get/placements/get.go | 5 ++- src/cmd/tools/m3ctl/main/yaml/load.go | 8 ++--- 18 files changed, 64 insertions(+), 65 deletions(-) diff --git a/src/cmd/tools/m3ctl/main/apply/apply.go b/src/cmd/tools/m3ctl/main/apply/apply.go index 7f371730b6..2f9081960a 100644 --- a/src/cmd/tools/m3ctl/main/apply/apply.go +++ b/src/cmd/tools/m3ctl/main/apply/apply.go @@ -8,9 +8,11 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" ) -func doApply(vals *applyVals, globals globalopts.GlobalOpts) { - path, data := yaml.Load(vals.yamlFlag.Value[0], globals.Zap) +func doApply(vals *applyVals, globals globalopts.GlobalOpts) error { + path, data, err := yaml.Load(vals.yamlFlag.Value[0], globals.Zap) + if err != nil { + return err + } url := fmt.Sprintf("%s%s", globals.Endpoint, path) - client.DoPost(url, data, client.Dumper, globals.Zap) - return + return client.DoPost(url, data, client.Dumper, globals.Zap) } diff --git a/src/cmd/tools/m3ctl/main/apply/cmd.go b/src/cmd/tools/m3ctl/main/apply/cmd.go index 61ac0e6740..bd8cd236c5 100644 --- a/src/cmd/tools/m3ctl/main/apply/cmd.go +++ b/src/cmd/tools/m3ctl/main/apply/cmd.go @@ -20,7 +20,7 @@ type Context struct { Flags *flag.FlagSet } type applyHandlers struct { - handle func(*applyVals, globalopts.GlobalOpts) + handle func(*applyVals, globalopts.GlobalOpts) error } func InitializeFlags() Context { @@ -104,6 +104,5 @@ func (ctx Context) PopParseDispatch(cli []string) error { // no dispatching here // there are no subcommands func dispatcher(ctx Context) error { - ctx.handlers.handle(ctx.vals, ctx.GlobalOpts) - return nil + return ctx.handlers.handle(ctx.vals, ctx.GlobalOpts) } diff --git a/src/cmd/tools/m3ctl/main/client/checker.go b/src/cmd/tools/m3ctl/main/client/checker.go index 40627919e1..a8ddd51c1e 100644 --- a/src/cmd/tools/m3ctl/main/client/checker.go +++ b/src/cmd/tools/m3ctl/main/client/checker.go @@ -8,13 +8,14 @@ import ( "go.uber.org/zap" ) -func checkForAndHandleError(url string, resp *http.Response, zl *zap.SugaredLogger) { +func checkForAndHandleError(url string, resp *http.Response, zl *zap.SugaredLogger) error { zl.Infof("resp.StatusCode:%d:\n", resp.StatusCode) if resp.StatusCode > 299 { dat, _ := ioutil.ReadAll(resp.Body) if dat != nil { fmt.Println(string(dat)) } - zl.Fatalf("error from m3db:%s:url:%s:", resp.Status, url) + return fmt.Errorf("error from m3db:%s:url:%s:", resp.Status, url) } + return nil } diff --git a/src/cmd/tools/m3ctl/main/client/http.go b/src/cmd/tools/m3ctl/main/client/http.go index c06f7a261e..286b3d6b4d 100644 --- a/src/cmd/tools/m3ctl/main/client/http.go +++ b/src/cmd/tools/m3ctl/main/client/http.go @@ -12,24 +12,26 @@ import ( const timeout = time.Duration(5 * time.Second) -func DoGet(url string, getter func(reader io.Reader, zl *zap.SugaredLogger), zl *zap.SugaredLogger) { +func DoGet(url string, getter func(reader io.Reader, zl *zap.SugaredLogger) error, zl *zap.SugaredLogger) error { zl.Infof("DoGet:url:%s:\n", url) client := http.Client{ Timeout: timeout, } resp, err := client.Get(url) if err != nil { - zl.Fatal(err) + return err } defer func() { ioutil.ReadAll(resp.Body) resp.Body.Close() }() - checkForAndHandleError(url, resp, zl) - getter(resp.Body, zl) + if err := checkForAndHandleError(url, resp, zl); err != nil { + return err + } + return getter(resp.Body, zl) } -func DoPost(url string, data io.Reader, getter func(reader io.Reader, zl *zap.SugaredLogger), zl *zap.SugaredLogger) { +func DoPost(url string, data io.Reader, getter func(reader io.Reader, zl *zap.SugaredLogger) error, zl *zap.SugaredLogger) error { zl.Infof("DoPost:url:%s:\n", url) client := &http.Client{ Timeout: timeout, @@ -38,18 +40,19 @@ func DoPost(url string, data io.Reader, getter func(reader io.Reader, zl *zap.Su req.Header.Add("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { - zl.Fatal(err) - + return err } defer func() { ioutil.ReadAll(resp.Body) resp.Body.Close() }() - checkForAndHandleError(url, resp, zl) - getter(resp.Body, zl) + if err := checkForAndHandleError(url, resp, zl); err != nil { + return err + } + return getter(resp.Body, zl) } -func DoDelete(url string, getter func(reader io.Reader, zl *zap.SugaredLogger), zl *zap.SugaredLogger) { +func DoDelete(url string, getter func(reader io.Reader, zl *zap.SugaredLogger) error, zl *zap.SugaredLogger) error { zl.Infof("DoDelete:url:%s:\n", url) client := &http.Client{ Timeout: timeout, @@ -58,20 +61,23 @@ func DoDelete(url string, getter func(reader io.Reader, zl *zap.SugaredLogger), req.Header.Add("Content-Type", "application/json") resp, err := client.Do(req) if err != nil { - zl.Fatal(err) + return err } defer func() { ioutil.ReadAll(resp.Body) resp.Body.Close() }() - checkForAndHandleError(url, resp, zl) - getter(resp.Body, zl) + if err := checkForAndHandleError(url, resp, zl); err != nil { + return err + } + return getter(resp.Body, zl) } -func Dumper(in io.Reader, zl *zap.SugaredLogger) { +func Dumper(in io.Reader, zl *zap.SugaredLogger) error { dat, err := ioutil.ReadAll(in) if err != nil { - zl.Fatal(err) + return err } fmt.Println(string(dat)) + return nil } diff --git a/src/cmd/tools/m3ctl/main/delete/cmd.go b/src/cmd/tools/m3ctl/main/delete/cmd.go index 2d5ad92000..554f204613 100644 --- a/src/cmd/tools/m3ctl/main/delete/cmd.go +++ b/src/cmd/tools/m3ctl/main/delete/cmd.go @@ -26,7 +26,7 @@ func _setupFlags() Context { fmt.Fprintf(os.Stderr, ` "%s" is for deletiion operations for namespaces and placements. -`) +`, deleteFlags.Name()) deleteFlags.PrintDefaults() } return Context{Flags: deleteFlags} diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go index c690c6fe3a..f07ea00643 100644 --- a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go @@ -23,7 +23,7 @@ type Context struct { Flags *flag.FlagSet } type namespacesHandlers struct { - handle func(*namespacesVals, globalopts.GlobalOpts) + handle func(*namespacesVals, globalopts.GlobalOpts) error } func InitializeFlags() Context { @@ -78,7 +78,5 @@ func dispatcher(ctx Context) error { ctx.Flags.Usage() return &errors.FlagsError{"\nextra args supplied. See usage.\n"} } - ctx.handlers.handle(ctx.vals, ctx.Globals) - return nil - + return ctx.handlers.handle(ctx.vals, ctx.Globals) } diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go index 538950c832..0ccbdbf579 100644 --- a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go @@ -10,7 +10,7 @@ func makeStub() Context { ctx := _setupFlags( &namespacesVals{}, namespacesHandlers{ - handle: func(*namespacesVals, globalopts.GlobalOpts) { return }, + handle: func(*namespacesVals, globalopts.GlobalOpts) error { return nil }, }, ) ctx.Globals.Endpoint = "fakeEndpoint" diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/delete.go b/src/cmd/tools/m3ctl/main/delete/namespaces/delete.go index daf591b7e0..935a84189b 100644 --- a/src/cmd/tools/m3ctl/main/delete/namespaces/delete.go +++ b/src/cmd/tools/m3ctl/main/delete/namespaces/delete.go @@ -7,7 +7,7 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" ) -func doDelete(flags *namespacesVals, globals globalopts.GlobalOpts) { +func doDelete(flags *namespacesVals, globals globalopts.GlobalOpts) error { url := fmt.Sprintf("%s%s/%s", globals.Endpoint, "/api/v1/services/m3db/namespace", *flags.nodeName) - client.DoDelete(url, client.Dumper, globals.Zap) + return client.DoDelete(url, client.Dumper, globals.Zap) } diff --git a/src/cmd/tools/m3ctl/main/delete/placements/cmd.go b/src/cmd/tools/m3ctl/main/delete/placements/cmd.go index 6063ff86a7..b1af1c3155 100644 --- a/src/cmd/tools/m3ctl/main/delete/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/delete/placements/cmd.go @@ -24,7 +24,7 @@ type Context struct { Flags *flag.FlagSet } type placementHandlers struct { - handle func(*placementVals, globalopts.GlobalOpts) + handle func(*placementVals, globalopts.GlobalOpts) error } func InitializeFlags() Context { @@ -77,6 +77,5 @@ func dispatcher(ctx Context) error { ctx.Flags.Usage() return &errors.FlagsError{"\nextra args supplied. See usage\n"} } - ctx.handlers.handle(ctx.vals, ctx.Globals) - return nil + return ctx.handlers.handle(ctx.vals, ctx.Globals) } diff --git a/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go b/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go index 05f960b581..81a714a1ed 100644 --- a/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go @@ -10,7 +10,7 @@ func makeStub() Context { ctx := _setupFlags( &placementVals{}, placementHandlers{ - handle: func(*placementVals, globalopts.GlobalOpts) { return }, + handle: func(*placementVals, globalopts.GlobalOpts) error { return nil }, }, ) ctx.Globals.Endpoint = "nuch" diff --git a/src/cmd/tools/m3ctl/main/delete/placements/delete.go b/src/cmd/tools/m3ctl/main/delete/placements/delete.go index 22ea601d8e..6dc526b39d 100644 --- a/src/cmd/tools/m3ctl/main/delete/placements/delete.go +++ b/src/cmd/tools/m3ctl/main/delete/placements/delete.go @@ -8,13 +8,11 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" ) -func doDelete(s *placementVals, globals globalopts.GlobalOpts) { +func doDelete(s *placementVals, globals globalopts.GlobalOpts) error { if *s.deleteEntire { url := fmt.Sprintf("%s%s", globals.Endpoint, placements.DefaultPath) - client.DoDelete(url, client.Dumper, globals.Zap) - return + return client.DoDelete(url, client.Dumper, globals.Zap) } url := fmt.Sprintf("%s%s/%s", globals.Endpoint, placements.DefaultPath, *s.nodeName) - client.DoDelete(url, client.Dumper, globals.Zap) - return + return client.DoDelete(url, client.Dumper, globals.Zap) } diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go b/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go index db099470a9..85859fe62a 100644 --- a/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go @@ -20,7 +20,7 @@ type Context struct { Flags *flag.FlagSet } type namespacesHandlers struct { - handle func(*namespacesVals, globalopts.GlobalOpts) + handle func(*namespacesVals, globalopts.GlobalOpts) error } func InitializeFlags() Context { @@ -58,8 +58,7 @@ func (ctx Context) PopParseDispatch(cli []string) error { return &errors.FlagsError{} } if ctx.Flags.NArg() == 0 { - ctx.handlers.handle(ctx.vals, ctx.Globals) - return nil + return ctx.handlers.handle(ctx.vals, ctx.Globals) } if err := dispatcher(ctx); err != nil { fmt.Fprintf(os.Stderr, err.Error()) @@ -71,8 +70,7 @@ func dispatcher(ctx Context) error { nextArgs := ctx.Flags.Args() switch nextArgs[0] { case "": - ctx.handlers.handle(ctx.vals, ctx.Globals) - return nil + return ctx.handlers.handle(ctx.vals, ctx.Globals) default: ctx.Flags.Usage() return &errors.FlagsError{} diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go index 92db6319ce..808a4a6752 100644 --- a/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go @@ -10,7 +10,7 @@ func makeStub() Context { ctx := _setupFlags( &namespacesVals{}, namespacesHandlers{ - handle: func(*namespacesVals, globalopts.GlobalOpts) { return }, + handle: func(*namespacesVals, globalopts.GlobalOpts) error { return nil }, }, ) ctx.Globals.Endpoint = "nuch" diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/get.go b/src/cmd/tools/m3ctl/main/get/namespaces/get.go index 26bdd84f9a..686b171882 100644 --- a/src/cmd/tools/m3ctl/main/get/namespaces/get.go +++ b/src/cmd/tools/m3ctl/main/get/namespaces/get.go @@ -13,22 +13,23 @@ import ( "github.com/gogo/protobuf/jsonpb" ) -func doGet(flags *namespacesVals, globals globalopts.GlobalOpts) { +func doGet(flags *namespacesVals, globals globalopts.GlobalOpts) error { url := fmt.Sprintf("%s%s?%s", globals.Endpoint, namespaces.DefaultPath, namespaces.DebugQS) if *flags.showAll { - client.DoGet(url, client.Dumper, globals.Zap) + return client.DoGet(url, client.Dumper, globals.Zap) } else { - client.DoGet(url, showNames, globals.Zap) + return client.DoGet(url, showNames, globals.Zap) } } -func showNames(in io.Reader, zl *zap.SugaredLogger) { +func showNames(in io.Reader, zl *zap.SugaredLogger) error { registry := admin.NamespaceGetResponse{} unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} if err := unmarshaller.Unmarshal(in, ®istry); err != nil { - zl.Fatal(err) + return err } for k, _ := range registry.Registry.Namespaces { fmt.Println(k) } + return nil } diff --git a/src/cmd/tools/m3ctl/main/get/placements/cmd.go b/src/cmd/tools/m3ctl/main/get/placements/cmd.go index 47242d9452..e1549622c4 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/cmd.go +++ b/src/cmd/tools/m3ctl/main/get/placements/cmd.go @@ -18,7 +18,7 @@ type Context struct { Flags *flag.FlagSet } type placementHandlers struct { - handle func(*placementVals, globalopts.GlobalOpts) + handle func(*placementVals, globalopts.GlobalOpts) error } func InitializeFlags() Context { @@ -57,8 +57,7 @@ func (ctx Context) PopParseDispatch(cli []string) error { return err } if ctx.Flags.NArg() == 0 { - ctx.handlers.handle(ctx.vals, ctx.Globals) - return nil + return ctx.handlers.handle(ctx.vals, ctx.Globals) } if err := dispatcher(ctx); err != nil { fmt.Fprintf(os.Stderr, err.Error()) @@ -71,8 +70,7 @@ func dispatcher(ctx Context) error { nextArgs := ctx.Flags.Args() switch nextArgs[0] { case "": - ctx.handlers.handle(ctx.vals, ctx.Globals) - return nil + return ctx.handlers.handle(ctx.vals, ctx.Globals) default: return &errors.FlagsError{} } diff --git a/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go b/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go index 63b004b182..5522ef29b7 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go +++ b/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go @@ -10,7 +10,7 @@ func makeStub() Context { ctx := _setupFlags( &placementVals{}, placementHandlers{ - handle: func(*placementVals, globalopts.GlobalOpts) { return }, + handle: func(*placementVals, globalopts.GlobalOpts) error { return nil }, }, ) ctx.Globals.Endpoint = "nuch" diff --git a/src/cmd/tools/m3ctl/main/get/placements/get.go b/src/cmd/tools/m3ctl/main/get/placements/get.go index f82f35e64e..d836918524 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/get.go +++ b/src/cmd/tools/m3ctl/main/get/placements/get.go @@ -8,8 +8,7 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" ) -func doGet(s *placementVals, globals globalopts.GlobalOpts) { +func doGet(s *placementVals, globals globalopts.GlobalOpts) error { url := fmt.Sprintf("%s%s", globals.Endpoint, placements.DefaultPath) - client.DoGet(url, client.Dumper, globals.Zap) - return + return client.DoGet(url, client.Dumper, globals.Zap) } diff --git a/src/cmd/tools/m3ctl/main/yaml/load.go b/src/cmd/tools/m3ctl/main/yaml/load.go index ec529d9485..7e14f18823 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load.go +++ b/src/cmd/tools/m3ctl/main/yaml/load.go @@ -19,17 +19,17 @@ import ( // // See the examples directories. // -func Load(path string, zl *zap.SugaredLogger) (string, io.Reader) { +func Load(path string, zl *zap.SugaredLogger) (string, io.Reader, error) { content, err := ioutil.ReadFile(path) if err != nil { - zl.Fatal(err) + return "", nil, err } url, pbmessage, err := peeker(content) if err != nil { - zl.Fatalf("error inspecting the yaml:it might be bad yaml or it might be an unknown operation:%v:from yaml file:%s:", err, path) + return "", nil, err } rv, err := _load(content, pbmessage) - return url, rv + return url, rv, nil } func _load(content []byte, target proto.Message) (io.Reader, error) { From 400bfe33f189dc9bc2b309193bae1eb668b03656 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Thu, 6 Feb 2020 08:22:11 -0800 Subject: [PATCH 49/65] fix bug in apply yaml --- src/cmd/tools/m3ctl/main/yaml/peeker.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/cmd/tools/m3ctl/main/yaml/peeker.go b/src/cmd/tools/m3ctl/main/yaml/peeker.go index 58f7e7d4c9..328bac7fa1 100644 --- a/src/cmd/tools/m3ctl/main/yaml/peeker.go +++ b/src/cmd/tools/m3ctl/main/yaml/peeker.go @@ -3,8 +3,7 @@ package yaml import ( "fmt" "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" - - yaml2 "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" + "github.com/m3db/m3/src/query/generated/proto/admin" "github.com/ghodss/yaml" "github.com/gogo/protobuf/proto" @@ -26,13 +25,13 @@ func peeker(data []byte) (string, proto.Message, error) { } switch peek.Operation { case opCreate: - return dbcreatePath, &yaml2.DatabaseCreateRequestYaml{}, nil + return dbcreatePath, &admin.DatabaseCreateRequest{}, nil case opInit: - return fmt.Sprintf("%s/init", placements.DefaultPath), &yaml2.PlacementInitRequestYaml{}, nil + return fmt.Sprintf("%s/init", placements.DefaultPath), &admin.PlacementInitRequest{}, nil case opReplace: - return fmt.Sprintf("%s/replace", placements.DefaultPath), &yaml2.PlacementReplaceRequestYaml{}, nil + return fmt.Sprintf("%s/replace", placements.DefaultPath), &admin.PlacementReplaceRequest{}, nil case opNewNode: - return fmt.Sprintf("%s", placements.DefaultPath), &yaml2.PlacementInitRequestYaml{}, nil + return fmt.Sprintf("%s", placements.DefaultPath), &admin.PlacementInitRequest{}, nil default: return "", nil, fmt.Errorf("Unknown operation specified in the yaml\n") } From 79a82f09f70e48a1979d18f8bc381264dad203c2 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Wed, 11 Mar 2020 08:16:26 -0700 Subject: [PATCH 50/65] reorg and fix peeker --- src/cmd/tools/m3ctl/{main => }/apply/apply.go | 6 +++--- src/cmd/tools/m3ctl/{main => }/apply/cmd.go | 4 ++-- .../{main => }/checkArgs/popParseCheck.go | 2 +- .../tools/m3ctl/{main => }/client/checker.go | 0 src/cmd/tools/m3ctl/{main => }/client/http.go | 0 src/cmd/tools/m3ctl/{main => }/delete/cmd.go | 8 ++++---- .../m3ctl/{main => }/delete/namespaces/cmd.go | 4 ++-- .../{main => }/delete/namespaces/cmd_test.go | 2 +- .../{main => }/delete/namespaces/delete.go | 4 ++-- .../m3ctl/{main => }/delete/placements/cmd.go | 4 ++-- .../{main => }/delete/placements/cmd_test.go | 2 +- .../{main => }/delete/placements/delete.go | 6 +++--- .../tools/m3ctl/{main => }/errors/types.go | 0 src/cmd/tools/m3ctl/{main => }/get/cmd.go | 10 +++++----- .../m3ctl/{main => }/get/namespaces/cmd.go | 4 ++-- .../{main => }/get/namespaces/cmd_test.go | 2 +- .../m3ctl/{main => }/get/namespaces/get.go | 6 +++--- .../m3ctl/{main => }/get/placements/cmd.go | 4 ++-- .../{main => }/get/placements/cmd_test.go | 2 +- .../m3ctl/{main => }/get/placements/get.go | 6 +++--- .../m3ctl/{main => }/globalopts/types.go | 0 src/cmd/tools/m3ctl/main/main.go | 6 +++--- .../m3ctl/{main => }/namespaces/types.go | 0 .../m3ctl/{main => }/placements/types.go | 0 .../m3ctl/{main => }/yaml/dbCreate.proto | 0 .../{main => }/yaml/examples/create.yaml | 0 .../{main => }/yaml/examples/develdb.yaml | 0 .../m3ctl/{main => }/yaml/examples/init.yaml | 0 .../{main => }/yaml/examples/newNode.yaml | 0 .../{main => }/yaml/examples/replaceNode.yaml | 0 .../{main => }/yaml/generated/dbCreate.pb.go | 4 ---- .../{main => }/yaml/generated/placement.pb.go | 0 src/cmd/tools/m3ctl/{main => }/yaml/load.go | 0 .../tools/m3ctl/{main => }/yaml/load_test.go | 2 +- src/cmd/tools/m3ctl/{main => }/yaml/peeker.go | 20 ++++++++++++------- .../m3ctl/{main => }/yaml/peeker_test.go | 12 +++++++---- .../m3ctl/{main => }/yaml/placement.proto | 0 .../{main => }/yaml/testdata/basicCreate.yaml | 0 .../yaml/testdata/unknownOperation.yaml | 0 src/cmd/tools/m3ctl/{main => }/yaml/types.go | 0 40 files changed, 63 insertions(+), 57 deletions(-) rename src/cmd/tools/m3ctl/{main => }/apply/apply.go (66%) rename src/cmd/tools/m3ctl/{main => }/apply/cmd.go (95%) rename src/cmd/tools/m3ctl/{main => }/checkArgs/popParseCheck.go (83%) rename src/cmd/tools/m3ctl/{main => }/client/checker.go (100%) rename src/cmd/tools/m3ctl/{main => }/client/http.go (100%) rename src/cmd/tools/m3ctl/{main => }/delete/cmd.go (85%) rename src/cmd/tools/m3ctl/{main => }/delete/namespaces/cmd.go (93%) rename src/cmd/tools/m3ctl/{main => }/delete/namespaces/cmd_test.go (97%) rename src/cmd/tools/m3ctl/{main => }/delete/namespaces/delete.go (71%) rename src/cmd/tools/m3ctl/{main => }/delete/placements/cmd.go (94%) rename src/cmd/tools/m3ctl/{main => }/delete/placements/cmd_test.go (97%) rename src/cmd/tools/m3ctl/{main => }/delete/placements/delete.go (70%) rename src/cmd/tools/m3ctl/{main => }/errors/types.go (100%) rename src/cmd/tools/m3ctl/{main => }/get/cmd.go (84%) rename src/cmd/tools/m3ctl/{main => }/get/namespaces/cmd.go (93%) rename src/cmd/tools/m3ctl/{main => }/get/namespaces/cmd_test.go (96%) rename src/cmd/tools/m3ctl/{main => }/get/namespaces/get.go (82%) rename src/cmd/tools/m3ctl/{main => }/get/placements/cmd.go (92%) rename src/cmd/tools/m3ctl/{main => }/get/placements/cmd_test.go (96%) rename src/cmd/tools/m3ctl/{main => }/get/placements/get.go (57%) rename src/cmd/tools/m3ctl/{main => }/globalopts/types.go (100%) rename src/cmd/tools/m3ctl/{main => }/namespaces/types.go (100%) rename src/cmd/tools/m3ctl/{main => }/placements/types.go (100%) rename src/cmd/tools/m3ctl/{main => }/yaml/dbCreate.proto (100%) rename src/cmd/tools/m3ctl/{main => }/yaml/examples/create.yaml (100%) rename src/cmd/tools/m3ctl/{main => }/yaml/examples/develdb.yaml (100%) rename src/cmd/tools/m3ctl/{main => }/yaml/examples/init.yaml (100%) rename src/cmd/tools/m3ctl/{main => }/yaml/examples/newNode.yaml (100%) rename src/cmd/tools/m3ctl/{main => }/yaml/examples/replaceNode.yaml (100%) rename src/cmd/tools/m3ctl/{main => }/yaml/generated/dbCreate.pb.go (98%) rename src/cmd/tools/m3ctl/{main => }/yaml/generated/placement.pb.go (100%) rename src/cmd/tools/m3ctl/{main => }/yaml/load.go (100%) rename src/cmd/tools/m3ctl/{main => }/yaml/load_test.go (96%) rename src/cmd/tools/m3ctl/{main => }/yaml/peeker.go (50%) rename src/cmd/tools/m3ctl/{main => }/yaml/peeker_test.go (71%) rename src/cmd/tools/m3ctl/{main => }/yaml/placement.proto (100%) rename src/cmd/tools/m3ctl/{main => }/yaml/testdata/basicCreate.yaml (100%) rename src/cmd/tools/m3ctl/{main => }/yaml/testdata/unknownOperation.yaml (100%) rename src/cmd/tools/m3ctl/{main => }/yaml/types.go (100%) diff --git a/src/cmd/tools/m3ctl/main/apply/apply.go b/src/cmd/tools/m3ctl/apply/apply.go similarity index 66% rename from src/cmd/tools/m3ctl/main/apply/apply.go rename to src/cmd/tools/m3ctl/apply/apply.go index 2f9081960a..496da6a54d 100644 --- a/src/cmd/tools/m3ctl/main/apply/apply.go +++ b/src/cmd/tools/m3ctl/apply/apply.go @@ -3,9 +3,9 @@ package apply import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml" + "github.com/m3db/m3/src/cmd/tools/m3ctl/client" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/yaml" ) func doApply(vals *applyVals, globals globalopts.GlobalOpts) error { diff --git a/src/cmd/tools/m3ctl/main/apply/cmd.go b/src/cmd/tools/m3ctl/apply/cmd.go similarity index 95% rename from src/cmd/tools/m3ctl/main/apply/cmd.go rename to src/cmd/tools/m3ctl/apply/cmd.go index bd8cd236c5..f00881023b 100644 --- a/src/cmd/tools/m3ctl/main/apply/cmd.go +++ b/src/cmd/tools/m3ctl/apply/cmd.go @@ -5,8 +5,8 @@ import ( "fmt" "os" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" "github.com/m3db/m3/src/x/config/configflag" ) diff --git a/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go b/src/cmd/tools/m3ctl/checkArgs/popParseCheck.go similarity index 83% rename from src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go rename to src/cmd/tools/m3ctl/checkArgs/popParseCheck.go index 6a65549620..10d1eb7ce4 100644 --- a/src/cmd/tools/m3ctl/main/checkArgs/popParseCheck.go +++ b/src/cmd/tools/m3ctl/checkArgs/popParseCheck.go @@ -3,7 +3,7 @@ package checkArgs import ( "flag" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" + "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" ) func PopParseAndCheck(args []string, fs *flag.FlagSet) error { diff --git a/src/cmd/tools/m3ctl/main/client/checker.go b/src/cmd/tools/m3ctl/client/checker.go similarity index 100% rename from src/cmd/tools/m3ctl/main/client/checker.go rename to src/cmd/tools/m3ctl/client/checker.go diff --git a/src/cmd/tools/m3ctl/main/client/http.go b/src/cmd/tools/m3ctl/client/http.go similarity index 100% rename from src/cmd/tools/m3ctl/main/client/http.go rename to src/cmd/tools/m3ctl/client/http.go diff --git a/src/cmd/tools/m3ctl/main/delete/cmd.go b/src/cmd/tools/m3ctl/delete/cmd.go similarity index 85% rename from src/cmd/tools/m3ctl/main/delete/cmd.go rename to src/cmd/tools/m3ctl/delete/cmd.go index 554f204613..95e52f31ef 100644 --- a/src/cmd/tools/m3ctl/main/delete/cmd.go +++ b/src/cmd/tools/m3ctl/delete/cmd.go @@ -5,10 +5,10 @@ import ( "fmt" "os" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/delete/namespaces" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/delete/placements" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/delete/namespaces" + "github.com/m3db/m3/src/cmd/tools/m3ctl/delete/placements" + "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" ) // this has all that the upper level needs to dispatch to here diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go b/src/cmd/tools/m3ctl/delete/namespaces/cmd.go similarity index 93% rename from src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go rename to src/cmd/tools/m3ctl/delete/namespaces/cmd.go index f07ea00643..3751ace181 100644 --- a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/delete/namespaces/cmd.go @@ -5,8 +5,8 @@ import ( "fmt" "os" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" ) // all the values from the cli args are stored in here diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/delete/namespaces/cmd_test.go similarity index 97% rename from src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go rename to src/cmd/tools/m3ctl/delete/namespaces/cmd_test.go index 0ccbdbf579..154be3bc14 100644 --- a/src/cmd/tools/m3ctl/main/delete/namespaces/cmd_test.go +++ b/src/cmd/tools/m3ctl/delete/namespaces/cmd_test.go @@ -3,7 +3,7 @@ package namespaces import ( "testing" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" ) func makeStub() Context { diff --git a/src/cmd/tools/m3ctl/main/delete/namespaces/delete.go b/src/cmd/tools/m3ctl/delete/namespaces/delete.go similarity index 71% rename from src/cmd/tools/m3ctl/main/delete/namespaces/delete.go rename to src/cmd/tools/m3ctl/delete/namespaces/delete.go index 935a84189b..ba988a8f8c 100644 --- a/src/cmd/tools/m3ctl/main/delete/namespaces/delete.go +++ b/src/cmd/tools/m3ctl/delete/namespaces/delete.go @@ -3,8 +3,8 @@ package namespaces import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/client" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" ) func doDelete(flags *namespacesVals, globals globalopts.GlobalOpts) error { diff --git a/src/cmd/tools/m3ctl/main/delete/placements/cmd.go b/src/cmd/tools/m3ctl/delete/placements/cmd.go similarity index 94% rename from src/cmd/tools/m3ctl/main/delete/placements/cmd.go rename to src/cmd/tools/m3ctl/delete/placements/cmd.go index b1af1c3155..9c4cab4028 100644 --- a/src/cmd/tools/m3ctl/main/delete/placements/cmd.go +++ b/src/cmd/tools/m3ctl/delete/placements/cmd.go @@ -5,8 +5,8 @@ import ( "fmt" "os" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" ) // all the values from the cli args are stored in here diff --git a/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go b/src/cmd/tools/m3ctl/delete/placements/cmd_test.go similarity index 97% rename from src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go rename to src/cmd/tools/m3ctl/delete/placements/cmd_test.go index 81a714a1ed..ae3b57dd11 100644 --- a/src/cmd/tools/m3ctl/main/delete/placements/cmd_test.go +++ b/src/cmd/tools/m3ctl/delete/placements/cmd_test.go @@ -3,7 +3,7 @@ package placements import ( "testing" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" ) func makeStub() Context { diff --git a/src/cmd/tools/m3ctl/main/delete/placements/delete.go b/src/cmd/tools/m3ctl/delete/placements/delete.go similarity index 70% rename from src/cmd/tools/m3ctl/main/delete/placements/delete.go rename to src/cmd/tools/m3ctl/delete/placements/delete.go index 6dc526b39d..1892e82099 100644 --- a/src/cmd/tools/m3ctl/main/delete/placements/delete.go +++ b/src/cmd/tools/m3ctl/delete/placements/delete.go @@ -3,9 +3,9 @@ package placements import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" + "github.com/m3db/m3/src/cmd/tools/m3ctl/client" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/placements" ) func doDelete(s *placementVals, globals globalopts.GlobalOpts) error { diff --git a/src/cmd/tools/m3ctl/main/errors/types.go b/src/cmd/tools/m3ctl/errors/types.go similarity index 100% rename from src/cmd/tools/m3ctl/main/errors/types.go rename to src/cmd/tools/m3ctl/errors/types.go diff --git a/src/cmd/tools/m3ctl/main/get/cmd.go b/src/cmd/tools/m3ctl/get/cmd.go similarity index 84% rename from src/cmd/tools/m3ctl/main/get/cmd.go rename to src/cmd/tools/m3ctl/get/cmd.go index afb705a158..682a4d2fd9 100644 --- a/src/cmd/tools/m3ctl/main/get/cmd.go +++ b/src/cmd/tools/m3ctl/get/cmd.go @@ -5,10 +5,10 @@ import ( "fmt" "os" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/get/namespaces" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/get/placements" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" + "github.com/m3db/m3/src/cmd/tools/m3ctl/get/namespaces" + "github.com/m3db/m3/src/cmd/tools/m3ctl/get/placements" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" ) type Context struct { @@ -26,7 +26,7 @@ func _setupFlags() Context { fmt.Fprintf(os.Stderr, ` "%s" is for displaying information about the namespaces and placements. -`) +`, getFlags.Name()) getFlags.PrintDefaults() } return Context{Flags: getFlags} diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go b/src/cmd/tools/m3ctl/get/namespaces/cmd.go similarity index 93% rename from src/cmd/tools/m3ctl/main/get/namespaces/cmd.go rename to src/cmd/tools/m3ctl/get/namespaces/cmd.go index 85859fe62a..cc07d34033 100644 --- a/src/cmd/tools/m3ctl/main/get/namespaces/cmd.go +++ b/src/cmd/tools/m3ctl/get/namespaces/cmd.go @@ -5,8 +5,8 @@ import ( "fmt" "os" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" ) type namespacesVals struct { diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/get/namespaces/cmd_test.go similarity index 96% rename from src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go rename to src/cmd/tools/m3ctl/get/namespaces/cmd_test.go index 808a4a6752..18c1356c0d 100644 --- a/src/cmd/tools/m3ctl/main/get/namespaces/cmd_test.go +++ b/src/cmd/tools/m3ctl/get/namespaces/cmd_test.go @@ -3,7 +3,7 @@ package namespaces import ( "testing" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" ) func makeStub() Context { diff --git a/src/cmd/tools/m3ctl/main/get/namespaces/get.go b/src/cmd/tools/m3ctl/get/namespaces/get.go similarity index 82% rename from src/cmd/tools/m3ctl/main/get/namespaces/get.go rename to src/cmd/tools/m3ctl/get/namespaces/get.go index 686b171882..75d9ee9451 100644 --- a/src/cmd/tools/m3ctl/main/get/namespaces/get.go +++ b/src/cmd/tools/m3ctl/get/namespaces/get.go @@ -5,9 +5,9 @@ import ( "go.uber.org/zap" "io" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/namespaces" + "github.com/m3db/m3/src/cmd/tools/m3ctl/client" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/namespaces" "github.com/m3db/m3/src/query/generated/proto/admin" "github.com/gogo/protobuf/jsonpb" diff --git a/src/cmd/tools/m3ctl/main/get/placements/cmd.go b/src/cmd/tools/m3ctl/get/placements/cmd.go similarity index 92% rename from src/cmd/tools/m3ctl/main/get/placements/cmd.go rename to src/cmd/tools/m3ctl/get/placements/cmd.go index e1549622c4..83beca6df8 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/cmd.go +++ b/src/cmd/tools/m3ctl/get/placements/cmd.go @@ -5,8 +5,8 @@ import ( "fmt" "os" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/errors" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" ) type placementVals struct { diff --git a/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go b/src/cmd/tools/m3ctl/get/placements/cmd_test.go similarity index 96% rename from src/cmd/tools/m3ctl/main/get/placements/cmd_test.go rename to src/cmd/tools/m3ctl/get/placements/cmd_test.go index 5522ef29b7..4db7271848 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/cmd_test.go +++ b/src/cmd/tools/m3ctl/get/placements/cmd_test.go @@ -3,7 +3,7 @@ package placements import ( "testing" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" ) func makeStub() Context { diff --git a/src/cmd/tools/m3ctl/main/get/placements/get.go b/src/cmd/tools/m3ctl/get/placements/get.go similarity index 57% rename from src/cmd/tools/m3ctl/main/get/placements/get.go rename to src/cmd/tools/m3ctl/get/placements/get.go index d836918524..51db9f76b8 100644 --- a/src/cmd/tools/m3ctl/main/get/placements/get.go +++ b/src/cmd/tools/m3ctl/get/placements/get.go @@ -3,9 +3,9 @@ package placements import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/client" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/globalopts" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" + "github.com/m3db/m3/src/cmd/tools/m3ctl/client" + "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" + "github.com/m3db/m3/src/cmd/tools/m3ctl/placements" ) func doGet(s *placementVals, globals globalopts.GlobalOpts) error { diff --git a/src/cmd/tools/m3ctl/main/globalopts/types.go b/src/cmd/tools/m3ctl/globalopts/types.go similarity index 100% rename from src/cmd/tools/m3ctl/main/globalopts/types.go rename to src/cmd/tools/m3ctl/globalopts/types.go diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 5ac01b49a0..0c399058e5 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -25,9 +25,9 @@ import ( "fmt" "os" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/apply" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/delete" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/get" + "github.com/m3db/m3/src/cmd/tools/m3ctl/apply" + "github.com/m3db/m3/src/cmd/tools/m3ctl/delete" + "github.com/m3db/m3/src/cmd/tools/m3ctl/get" "go.uber.org/zap" ) diff --git a/src/cmd/tools/m3ctl/main/namespaces/types.go b/src/cmd/tools/m3ctl/namespaces/types.go similarity index 100% rename from src/cmd/tools/m3ctl/main/namespaces/types.go rename to src/cmd/tools/m3ctl/namespaces/types.go diff --git a/src/cmd/tools/m3ctl/main/placements/types.go b/src/cmd/tools/m3ctl/placements/types.go similarity index 100% rename from src/cmd/tools/m3ctl/main/placements/types.go rename to src/cmd/tools/m3ctl/placements/types.go diff --git a/src/cmd/tools/m3ctl/main/yaml/dbCreate.proto b/src/cmd/tools/m3ctl/yaml/dbCreate.proto similarity index 100% rename from src/cmd/tools/m3ctl/main/yaml/dbCreate.proto rename to src/cmd/tools/m3ctl/yaml/dbCreate.proto diff --git a/src/cmd/tools/m3ctl/main/yaml/examples/create.yaml b/src/cmd/tools/m3ctl/yaml/examples/create.yaml similarity index 100% rename from src/cmd/tools/m3ctl/main/yaml/examples/create.yaml rename to src/cmd/tools/m3ctl/yaml/examples/create.yaml diff --git a/src/cmd/tools/m3ctl/main/yaml/examples/develdb.yaml b/src/cmd/tools/m3ctl/yaml/examples/develdb.yaml similarity index 100% rename from src/cmd/tools/m3ctl/main/yaml/examples/develdb.yaml rename to src/cmd/tools/m3ctl/yaml/examples/develdb.yaml diff --git a/src/cmd/tools/m3ctl/main/yaml/examples/init.yaml b/src/cmd/tools/m3ctl/yaml/examples/init.yaml similarity index 100% rename from src/cmd/tools/m3ctl/main/yaml/examples/init.yaml rename to src/cmd/tools/m3ctl/yaml/examples/init.yaml diff --git a/src/cmd/tools/m3ctl/main/yaml/examples/newNode.yaml b/src/cmd/tools/m3ctl/yaml/examples/newNode.yaml similarity index 100% rename from src/cmd/tools/m3ctl/main/yaml/examples/newNode.yaml rename to src/cmd/tools/m3ctl/yaml/examples/newNode.yaml diff --git a/src/cmd/tools/m3ctl/main/yaml/examples/replaceNode.yaml b/src/cmd/tools/m3ctl/yaml/examples/replaceNode.yaml similarity index 100% rename from src/cmd/tools/m3ctl/main/yaml/examples/replaceNode.yaml rename to src/cmd/tools/m3ctl/yaml/examples/replaceNode.yaml diff --git a/src/cmd/tools/m3ctl/main/yaml/generated/dbCreate.pb.go b/src/cmd/tools/m3ctl/yaml/generated/dbCreate.pb.go similarity index 98% rename from src/cmd/tools/m3ctl/main/yaml/generated/dbCreate.pb.go rename to src/cmd/tools/m3ctl/yaml/generated/dbCreate.pb.go index 358033c0d1..4eaa6bf306 100644 --- a/src/cmd/tools/m3ctl/main/yaml/generated/dbCreate.pb.go +++ b/src/cmd/tools/m3ctl/yaml/generated/dbCreate.pb.go @@ -21,10 +21,6 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package -// enum OperationType { -//CREATE = 0; -//INIT = 1; -//} type DatabaseCreateRequestYaml struct { Operation string `protobuf:"bytes,1,opt,name=Operation,proto3" json:"Operation,omitempty"` Request *admin.DatabaseCreateRequest `protobuf:"bytes,2,opt,name=Request,proto3" json:"Request,omitempty"` diff --git a/src/cmd/tools/m3ctl/main/yaml/generated/placement.pb.go b/src/cmd/tools/m3ctl/yaml/generated/placement.pb.go similarity index 100% rename from src/cmd/tools/m3ctl/main/yaml/generated/placement.pb.go rename to src/cmd/tools/m3ctl/yaml/generated/placement.pb.go diff --git a/src/cmd/tools/m3ctl/main/yaml/load.go b/src/cmd/tools/m3ctl/yaml/load.go similarity index 100% rename from src/cmd/tools/m3ctl/main/yaml/load.go rename to src/cmd/tools/m3ctl/yaml/load.go diff --git a/src/cmd/tools/m3ctl/main/yaml/load_test.go b/src/cmd/tools/m3ctl/yaml/load_test.go similarity index 96% rename from src/cmd/tools/m3ctl/main/yaml/load_test.go rename to src/cmd/tools/m3ctl/yaml/load_test.go index 09d27bce85..ebc4afb9e6 100644 --- a/src/cmd/tools/m3ctl/main/yaml/load_test.go +++ b/src/cmd/tools/m3ctl/yaml/load_test.go @@ -5,7 +5,7 @@ import ( "testing" "github.com/gogo/protobuf/jsonpb" - pb "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" + pb "github.com/m3db/m3/src/cmd/tools/m3ctl/yaml/generated" ) // this uses _load to get an encoded stream of the diff --git a/src/cmd/tools/m3ctl/main/yaml/peeker.go b/src/cmd/tools/m3ctl/yaml/peeker.go similarity index 50% rename from src/cmd/tools/m3ctl/main/yaml/peeker.go rename to src/cmd/tools/m3ctl/yaml/peeker.go index 328bac7fa1..fa4c80cffa 100644 --- a/src/cmd/tools/m3ctl/main/yaml/peeker.go +++ b/src/cmd/tools/m3ctl/yaml/peeker.go @@ -2,11 +2,10 @@ package yaml import ( "fmt" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/placements" - "github.com/m3db/m3/src/query/generated/proto/admin" - "github.com/ghodss/yaml" "github.com/gogo/protobuf/proto" + "github.com/m3db/m3/src/cmd/tools/m3ctl/placements" + pb "github.com/m3db/m3/src/cmd/tools/m3ctl/yaml/generated" ) // peek into the yaml to see what it is expected to be @@ -20,18 +19,25 @@ func peeker(data []byte) (string, proto.Message, error) { Operation string } peek := &peeker{} + + // this really does nothing more than unpack into the above + // private type to take a peek at Operation + // no data is saved from this + // nothing is returned from thie + // its just a peek + // and then it returns other data depending on the reults of the peek if err := yaml.Unmarshal(data, &peek); err != nil { return "", nil, err } switch peek.Operation { case opCreate: - return dbcreatePath, &admin.DatabaseCreateRequest{}, nil + return dbcreatePath, &pb.DatabaseCreateRequestYaml{}, nil case opInit: - return fmt.Sprintf("%s/init", placements.DefaultPath), &admin.PlacementInitRequest{}, nil + return fmt.Sprintf("%s/init", placements.DefaultPath), &pb.PlacementInitRequestYaml{}, nil case opReplace: - return fmt.Sprintf("%s/replace", placements.DefaultPath), &admin.PlacementReplaceRequest{}, nil + return fmt.Sprintf("%s/replace", placements.DefaultPath), &pb.PlacementReplaceRequestYaml{}, nil case opNewNode: - return fmt.Sprintf("%s", placements.DefaultPath), &admin.PlacementInitRequest{}, nil + return fmt.Sprintf("%s", placements.DefaultPath), &pb.PlacementInitRequestYaml{}, nil default: return "", nil, fmt.Errorf("Unknown operation specified in the yaml\n") } diff --git a/src/cmd/tools/m3ctl/main/yaml/peeker_test.go b/src/cmd/tools/m3ctl/yaml/peeker_test.go similarity index 71% rename from src/cmd/tools/m3ctl/main/yaml/peeker_test.go rename to src/cmd/tools/m3ctl/yaml/peeker_test.go index 888b39a6a9..84c8b954a4 100644 --- a/src/cmd/tools/m3ctl/main/yaml/peeker_test.go +++ b/src/cmd/tools/m3ctl/yaml/peeker_test.go @@ -1,11 +1,11 @@ package yaml import ( + pb "github.com/m3db/m3/src/cmd/tools/m3ctl/yaml/generated" "io/ioutil" "testing" "github.com/gogo/protobuf/jsonpb" - "github.com/m3db/m3/src/cmd/tools/m3ctl/main/yaml/generated" ) func TestPeekerPositive(t *testing.T) { @@ -24,13 +24,17 @@ func TestPeekerPositive(t *testing.T) { if err != nil { t.Fatalf("failed to encode to protocol:%v:\n", err) } - dest := yaml.DatabaseCreateRequestYaml{} + dest := pb.DatabaseCreateRequestYaml{} unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} if err := unmarshaller.Unmarshal(data, &dest); err != nil { t.Fatalf("operation selector failed to unmarshal unknown operation data:%v:\n", err) } - if dest.Operation != opCreate { - t.Errorf("dest type does not have the correct type via operation selector:expected:%v:got:%v:", opCreate, dest.Operation) + t.Logf("dest:%v:\n", dest) + if dest.Request.NamespaceName != "default" { + t.Errorf("dest NamespaceName does not have the correct value via operation:expected:%v:got:%v:", opCreate, dest.Request.NamespaceName) + } + if dest.Request.Type != "cluster" { + t.Errorf("dest type does not have the correct value via operation:expected:%v:got:%v:", opCreate, dest.Request.Type) } } func TestPeekerNegative(t *testing.T) { diff --git a/src/cmd/tools/m3ctl/main/yaml/placement.proto b/src/cmd/tools/m3ctl/yaml/placement.proto similarity index 100% rename from src/cmd/tools/m3ctl/main/yaml/placement.proto rename to src/cmd/tools/m3ctl/yaml/placement.proto diff --git a/src/cmd/tools/m3ctl/main/yaml/testdata/basicCreate.yaml b/src/cmd/tools/m3ctl/yaml/testdata/basicCreate.yaml similarity index 100% rename from src/cmd/tools/m3ctl/main/yaml/testdata/basicCreate.yaml rename to src/cmd/tools/m3ctl/yaml/testdata/basicCreate.yaml diff --git a/src/cmd/tools/m3ctl/main/yaml/testdata/unknownOperation.yaml b/src/cmd/tools/m3ctl/yaml/testdata/unknownOperation.yaml similarity index 100% rename from src/cmd/tools/m3ctl/main/yaml/testdata/unknownOperation.yaml rename to src/cmd/tools/m3ctl/yaml/testdata/unknownOperation.yaml diff --git a/src/cmd/tools/m3ctl/main/yaml/types.go b/src/cmd/tools/m3ctl/yaml/types.go similarity index 100% rename from src/cmd/tools/m3ctl/main/yaml/types.go rename to src/cmd/tools/m3ctl/yaml/types.go From 40b339ef7f29cba99980022c0153c9587d8ed718 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Sun, 15 Mar 2020 21:32:37 -0700 Subject: [PATCH 51/65] probably working again with cobra now --- src/cmd/tools/m3ctl/apply/apply.go | 11 +- src/cmd/tools/m3ctl/apply/cmd.go | 108 ----------- .../tools/m3ctl/checkArgs/popParseCheck.go | 20 -- src/cmd/tools/m3ctl/client/checker.go | 4 +- src/cmd/tools/m3ctl/client/http.go | 14 +- src/cmd/tools/m3ctl/delete/cmd.go | 69 ------- src/cmd/tools/m3ctl/delete/namespaces/cmd.go | 82 --------- .../tools/m3ctl/delete/namespaces/cmd_test.go | 68 ------- .../tools/m3ctl/delete/namespaces/delete.go | 13 -- src/cmd/tools/m3ctl/delete/placements/cmd.go | 81 -------- .../tools/m3ctl/delete/placements/cmd_test.go | 73 -------- .../tools/m3ctl/delete/placements/delete.go | 18 -- src/cmd/tools/m3ctl/get/cmd.go | 70 ------- src/cmd/tools/m3ctl/get/namespaces/cmd.go | 78 -------- .../tools/m3ctl/get/namespaces/cmd_test.go | 63 ------- src/cmd/tools/m3ctl/get/placements/cmd.go | 77 -------- .../tools/m3ctl/get/placements/cmd_test.go | 58 ------ src/cmd/tools/m3ctl/get/placements/get.go | 14 -- src/cmd/tools/m3ctl/main/main.go | 173 ++++++++++++------ src/cmd/tools/m3ctl/namespaces/delete.go | 16 ++ .../tools/m3ctl/{get => }/namespaces/get.go | 14 +- src/cmd/tools/m3ctl/placements/delete.go | 16 ++ src/cmd/tools/m3ctl/placements/get.go | 12 ++ src/cmd/tools/m3ctl/yaml/load.go | 2 +- 24 files changed, 181 insertions(+), 973 deletions(-) delete mode 100644 src/cmd/tools/m3ctl/apply/cmd.go delete mode 100644 src/cmd/tools/m3ctl/checkArgs/popParseCheck.go delete mode 100644 src/cmd/tools/m3ctl/delete/cmd.go delete mode 100644 src/cmd/tools/m3ctl/delete/namespaces/cmd.go delete mode 100644 src/cmd/tools/m3ctl/delete/namespaces/cmd_test.go delete mode 100644 src/cmd/tools/m3ctl/delete/namespaces/delete.go delete mode 100644 src/cmd/tools/m3ctl/delete/placements/cmd.go delete mode 100644 src/cmd/tools/m3ctl/delete/placements/cmd_test.go delete mode 100644 src/cmd/tools/m3ctl/delete/placements/delete.go delete mode 100644 src/cmd/tools/m3ctl/get/cmd.go delete mode 100644 src/cmd/tools/m3ctl/get/namespaces/cmd.go delete mode 100644 src/cmd/tools/m3ctl/get/namespaces/cmd_test.go delete mode 100644 src/cmd/tools/m3ctl/get/placements/cmd.go delete mode 100644 src/cmd/tools/m3ctl/get/placements/cmd_test.go delete mode 100644 src/cmd/tools/m3ctl/get/placements/get.go create mode 100644 src/cmd/tools/m3ctl/namespaces/delete.go rename src/cmd/tools/m3ctl/{get => }/namespaces/get.go (51%) create mode 100644 src/cmd/tools/m3ctl/placements/delete.go create mode 100644 src/cmd/tools/m3ctl/placements/get.go diff --git a/src/cmd/tools/m3ctl/apply/apply.go b/src/cmd/tools/m3ctl/apply/apply.go index 496da6a54d..664f7e84b3 100644 --- a/src/cmd/tools/m3ctl/apply/apply.go +++ b/src/cmd/tools/m3ctl/apply/apply.go @@ -2,17 +2,18 @@ package apply import ( "fmt" + "go.uber.org/zap" "github.com/m3db/m3/src/cmd/tools/m3ctl/client" - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" "github.com/m3db/m3/src/cmd/tools/m3ctl/yaml" ) -func doApply(vals *applyVals, globals globalopts.GlobalOpts) error { - path, data, err := yaml.Load(vals.yamlFlag.Value[0], globals.Zap) +func DoApply(endpoint string, filepath string, zapper *zap.Logger) error { + //path, data, err := yaml.Load(vals.yamlFlag.Value[0], globals.Zap) + path, data, err := yaml.Load(filepath, zapper) if err != nil { return err } - url := fmt.Sprintf("%s%s", globals.Endpoint, path) - return client.DoPost(url, data, client.Dumper, globals.Zap) + url := fmt.Sprintf("%s%s", endpoint, path) + return client.DoPost(url, data, client.Dumper, zapper) } diff --git a/src/cmd/tools/m3ctl/apply/cmd.go b/src/cmd/tools/m3ctl/apply/cmd.go deleted file mode 100644 index f00881023b..0000000000 --- a/src/cmd/tools/m3ctl/apply/cmd.go +++ /dev/null @@ -1,108 +0,0 @@ -package apply - -import ( - "flag" - "fmt" - "os" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" - "github.com/m3db/m3/src/x/config/configflag" -) - -type applyVals struct { - yamlFlag *configflag.FlagStringSlice -} -type Context struct { - vals *applyVals - handlers applyHandlers - GlobalOpts globalopts.GlobalOpts - Flags *flag.FlagSet -} -type applyHandlers struct { - handle func(*applyVals, globalopts.GlobalOpts) error -} - -func InitializeFlags() Context { - return _setupFlags( - &applyVals{ - yamlFlag: &configflag.FlagStringSlice{}, - }, - applyHandlers{ - handle: doApply, - }) -} - -func _setupFlags(finalArgs *applyVals, handlers applyHandlers) Context { - applyFlags := flag.NewFlagSet("apply", flag.ContinueOnError) - applyFlags.Var(finalArgs.yamlFlag, "f", "Path to yaml.") - applyFlags.Usage = func() { - fmt.Fprintf(os.Stderr, ` -Usage: m3ctl %s -f somedir/somename.yaml - -The "%s" subcommand takes its inputs from a yaml file and knows how to do the -following operations: - - * create - create a namespace and initialize a topology - * init - initializes a placement - * newNode - adds a node to a placement - * replaceNode - replaces a node in a placement - -Example yaml files are included in the yaml/examples directory. Here's an -example for database creation: - ---- -operation: create -type: cluster -namespace_name: default -retention_time: 168h -num_shards: 64 -replication_factor: 1 -hosts: -- id: m3db_seed - isolation_group: rack-a - zone: embedded - weight: 1024 - endpoint: m3db_seed:9000 - hostname: m3db_seed - port: 9000 - -' - - -`, applyFlags.Name(), applyFlags.Name()) - applyFlags.PrintDefaults() - } - return Context{ - vals: finalArgs, - Flags: applyFlags, - handlers: handlers, - } -} - -func (ctx Context) PopParseDispatch(cli []string) error { - if len(cli) < 1 { - ctx.Flags.Usage() - return &errors.FlagsError{} - } - inArgs := cli[1:] - if err := ctx.Flags.Parse(inArgs); err != nil { - ctx.Flags.Usage() - return err - } - if ctx.Flags.NFlag() != 1 { - ctx.Flags.Usage() - return &errors.FlagsError{} - } - if err := dispatcher(ctx); err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - return err - } - return nil -} - -// no dispatching here -// there are no subcommands -func dispatcher(ctx Context) error { - return ctx.handlers.handle(ctx.vals, ctx.GlobalOpts) -} diff --git a/src/cmd/tools/m3ctl/checkArgs/popParseCheck.go b/src/cmd/tools/m3ctl/checkArgs/popParseCheck.go deleted file mode 100644 index 10d1eb7ce4..0000000000 --- a/src/cmd/tools/m3ctl/checkArgs/popParseCheck.go +++ /dev/null @@ -1,20 +0,0 @@ -package checkArgs - -import ( - "flag" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" -) - -func PopParseAndCheck(args []string, fs *flag.FlagSet) error { - thisArgs := args[1:] - if err := fs.Parse(thisArgs); err != nil { - fs.Usage() - return err - } - if fs.NFlag() == 0 { - fs.Usage() - return &errors.FlagsError{} - } - return nil -} diff --git a/src/cmd/tools/m3ctl/client/checker.go b/src/cmd/tools/m3ctl/client/checker.go index a8ddd51c1e..018f2acffb 100644 --- a/src/cmd/tools/m3ctl/client/checker.go +++ b/src/cmd/tools/m3ctl/client/checker.go @@ -8,8 +8,8 @@ import ( "go.uber.org/zap" ) -func checkForAndHandleError(url string, resp *http.Response, zl *zap.SugaredLogger) error { - zl.Infof("resp.StatusCode:%d:\n", resp.StatusCode) +func checkForAndHandleError(url string, resp *http.Response, zl *zap.Logger) error { + zl.Info(fmt.Sprintf("resp.StatusCode:%d:\n", resp.StatusCode)) if resp.StatusCode > 299 { dat, _ := ioutil.ReadAll(resp.Body) if dat != nil { diff --git a/src/cmd/tools/m3ctl/client/http.go b/src/cmd/tools/m3ctl/client/http.go index 286b3d6b4d..4b35fad950 100644 --- a/src/cmd/tools/m3ctl/client/http.go +++ b/src/cmd/tools/m3ctl/client/http.go @@ -12,8 +12,8 @@ import ( const timeout = time.Duration(5 * time.Second) -func DoGet(url string, getter func(reader io.Reader, zl *zap.SugaredLogger) error, zl *zap.SugaredLogger) error { - zl.Infof("DoGet:url:%s:\n", url) +func DoGet(url string, getter func(reader io.Reader, zl *zap.Logger) error, zl *zap.Logger) error { + zl.Info(fmt.Sprintf("DoGet:url:%s:\n", url)) client := http.Client{ Timeout: timeout, } @@ -31,8 +31,8 @@ func DoGet(url string, getter func(reader io.Reader, zl *zap.SugaredLogger) erro return getter(resp.Body, zl) } -func DoPost(url string, data io.Reader, getter func(reader io.Reader, zl *zap.SugaredLogger) error, zl *zap.SugaredLogger) error { - zl.Infof("DoPost:url:%s:\n", url) +func DoPost(url string, data io.Reader, getter func(reader io.Reader, zl *zap.Logger) error, zl *zap.Logger) error { + zl.Info(fmt.Sprintf("DoPost:url:%s:\n", url)) client := &http.Client{ Timeout: timeout, } @@ -52,8 +52,8 @@ func DoPost(url string, data io.Reader, getter func(reader io.Reader, zl *zap.Su return getter(resp.Body, zl) } -func DoDelete(url string, getter func(reader io.Reader, zl *zap.SugaredLogger) error, zl *zap.SugaredLogger) error { - zl.Infof("DoDelete:url:%s:\n", url) +func DoDelete(url string, getter func(reader io.Reader, zl *zap.Logger) error, zl *zap.Logger) error { + zl.Info(fmt.Sprintf("DoDelete:url:%s:\n", url)) client := &http.Client{ Timeout: timeout, } @@ -73,7 +73,7 @@ func DoDelete(url string, getter func(reader io.Reader, zl *zap.SugaredLogger) e return getter(resp.Body, zl) } -func Dumper(in io.Reader, zl *zap.SugaredLogger) error { +func Dumper(in io.Reader, zl *zap.Logger) error { dat, err := ioutil.ReadAll(in) if err != nil { return err diff --git a/src/cmd/tools/m3ctl/delete/cmd.go b/src/cmd/tools/m3ctl/delete/cmd.go deleted file mode 100644 index 95e52f31ef..0000000000 --- a/src/cmd/tools/m3ctl/delete/cmd.go +++ /dev/null @@ -1,69 +0,0 @@ -package delete - -import ( - "flag" - "fmt" - "os" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/delete/namespaces" - "github.com/m3db/m3/src/cmd/tools/m3ctl/delete/placements" - "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" -) - -// this has all that the upper level needs to dispatch to here -type Context struct { - GlobalOpts globalopts.GlobalOpts - Flags *flag.FlagSet -} - -func InitializeFlags() Context { - return _setupFlags() -} -func _setupFlags() Context { - deleteFlags := flag.NewFlagSet("delete", flag.ContinueOnError) - deleteFlags.Usage = func() { - fmt.Fprintf(os.Stderr, ` -"%s" is for deletiion operations for namespaces and placements. - -`, deleteFlags.Name()) - deleteFlags.PrintDefaults() - } - return Context{Flags: deleteFlags} -} -func (ctx Context) PopParseDispatch(cli []string) error { - thisFlagset := ctx.Flags - if len(cli) < 1 { - thisFlagset.Usage() - return &errors.FlagsError{} - } - // pop and parse - inArgs := cli[1:] - if err := thisFlagset.Parse(inArgs); err != nil { - thisFlagset.Usage() - return err - } - if thisFlagset.NArg() == 0 { - thisFlagset.Usage() - return &errors.FlagsError{} - } - plctx := placements.InitializeFlags() - nsctx := namespaces.InitializeFlags() - nextArgs := thisFlagset.Args() - switch nextArgs[0] { - case plctx.Flags.Name(): - plctx.Globals = ctx.GlobalOpts - if err := plctx.PopParseDispatch(nextArgs); err != nil { - return err - } - case nsctx.Flags.Name(): - nsctx.Globals = ctx.GlobalOpts - if err := nsctx.PopParseDispatch(nextArgs); err != nil { - return err - } - default: - thisFlagset.Usage() - return &errors.FlagsError{} - } - return nil -} diff --git a/src/cmd/tools/m3ctl/delete/namespaces/cmd.go b/src/cmd/tools/m3ctl/delete/namespaces/cmd.go deleted file mode 100644 index 3751ace181..0000000000 --- a/src/cmd/tools/m3ctl/delete/namespaces/cmd.go +++ /dev/null @@ -1,82 +0,0 @@ -package namespaces - -import ( - "flag" - "fmt" - "os" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" -) - -// all the values from the cli args are stored in here -// for all the placement-related commands -type namespacesVals struct { - nodeName *string -} - -// this has all that the upper dispatcher needs to parse the cli -type Context struct { - vals *namespacesVals - handlers namespacesHandlers - Globals globalopts.GlobalOpts - Flags *flag.FlagSet -} -type namespacesHandlers struct { - handle func(*namespacesVals, globalopts.GlobalOpts) error -} - -func InitializeFlags() Context { - return _setupFlags( - &namespacesVals{}, - namespacesHandlers{ - handle: doDelete, - }, - ) -} - -func _setupFlags(finalArgs *namespacesVals, handler namespacesHandlers) Context { - nsFlags := flag.NewFlagSet("ns", flag.ContinueOnError) - finalArgs.nodeName = nsFlags.String("id", "", "delete the specified node in the placement") - nsFlags.Usage = func() { - fmt.Fprintf(os.Stderr, ` -The delete "%s" subcommand will delete namespace. - -`, nsFlags.Name()) - nsFlags.PrintDefaults() - } - return Context{ - vals: finalArgs, - handlers: handler, - Flags: nsFlags, - } -} - -func (ctx Context) PopParseDispatch(cli []string) error { - if len(cli) < 1 { - ctx.Flags.Usage() - return &errors.FlagsError{} - } - inArgs := cli[1:] - if err := ctx.Flags.Parse(inArgs); err != nil { - ctx.Flags.Usage() - return err - } - if ctx.Flags.NFlag() == 0 { - ctx.Flags.Usage() - return &errors.FlagsError{} - } - if err := dispatcher(ctx); err != nil { - return err - } - return nil -} - -func dispatcher(ctx Context) error { - nextArgs := ctx.Flags.Args() - if len(nextArgs) != 0 { - ctx.Flags.Usage() - return &errors.FlagsError{"\nextra args supplied. See usage.\n"} - } - return ctx.handlers.handle(ctx.vals, ctx.Globals) -} diff --git a/src/cmd/tools/m3ctl/delete/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/delete/namespaces/cmd_test.go deleted file mode 100644 index 154be3bc14..0000000000 --- a/src/cmd/tools/m3ctl/delete/namespaces/cmd_test.go +++ /dev/null @@ -1,68 +0,0 @@ -package namespaces - -import ( - "testing" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" -) - -func makeStub() Context { - ctx := _setupFlags( - &namespacesVals{}, - namespacesHandlers{ - handle: func(*namespacesVals, globalopts.GlobalOpts) error { return nil }, - }, - ) - ctx.Globals.Endpoint = "fakeEndpoint" - return ctx -} -func TestBasic(t *testing.T) { - testData := []struct { - args []string - msg string - successCondition func(error) bool - }{ - { - args: []string{"ns", "-id", "eee"}, - msg: "It should return no error for sane args", - successCondition: func(err error) bool { return err == nil }, - }, - { - args: []string{}, - msg: "It should return error because we got here without ns", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"ns"}, - msg: "It should return error because we got no args", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"ns", "-h"}, - msg: "It should return error because we ran with -h", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"ns", "-id"}, - msg: "It should return error because we ran with -node but no args", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"ns", "-id", "eee", "errr"}, - msg: "It should return error because we got extra args", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"ns", "-id", ""}, - msg: "It should return an error because we got an empty val", - successCondition: func(err error) bool { return err == nil }, - }, - } - for _, v := range testData { - ctx := makeStub() - rv := ctx.PopParseDispatch(v.args) - if !v.successCondition(rv) { - t.Error(v.msg) - } - } -} diff --git a/src/cmd/tools/m3ctl/delete/namespaces/delete.go b/src/cmd/tools/m3ctl/delete/namespaces/delete.go deleted file mode 100644 index ba988a8f8c..0000000000 --- a/src/cmd/tools/m3ctl/delete/namespaces/delete.go +++ /dev/null @@ -1,13 +0,0 @@ -package namespaces - -import ( - "fmt" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/client" - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" -) - -func doDelete(flags *namespacesVals, globals globalopts.GlobalOpts) error { - url := fmt.Sprintf("%s%s/%s", globals.Endpoint, "/api/v1/services/m3db/namespace", *flags.nodeName) - return client.DoDelete(url, client.Dumper, globals.Zap) -} diff --git a/src/cmd/tools/m3ctl/delete/placements/cmd.go b/src/cmd/tools/m3ctl/delete/placements/cmd.go deleted file mode 100644 index 9c4cab4028..0000000000 --- a/src/cmd/tools/m3ctl/delete/placements/cmd.go +++ /dev/null @@ -1,81 +0,0 @@ -package placements - -import ( - "flag" - "fmt" - "os" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" -) - -// all the values from the cli args are stored in here -// for all the placement-related commands -type placementVals struct { - deleteEntire *bool - nodeName *string -} - -// this has all that the upper dispatcher needs to parse the cli -type Context struct { - vals *placementVals - handlers placementHandlers - Globals globalopts.GlobalOpts - Flags *flag.FlagSet -} -type placementHandlers struct { - handle func(*placementVals, globalopts.GlobalOpts) error -} - -func InitializeFlags() Context { - return _setupFlags( - &placementVals{}, - placementHandlers{ - handle: doDelete, - }, - ) -} -func _setupFlags(finalArgs *placementVals, handler placementHandlers) Context { - placementFlags := flag.NewFlagSet("pl", flag.ContinueOnError) - finalArgs.deleteEntire = placementFlags.Bool("all", false, "delete the entire placement") - finalArgs.nodeName = placementFlags.String("node", "", "delete the specified node in the placement") - placementFlags.Usage = func() { - fmt.Fprintf(os.Stderr, ` -The delete "%s" subcommand will delete an entire placement, or the specified node from the placement. - -`, placementFlags.Name()) - placementFlags.PrintDefaults() - } - return Context{ - vals: finalArgs, - handlers: handler, - Flags: placementFlags, - } -} -func (ctx Context) PopParseDispatch(cli []string) error { - if len(cli) < 1 { - ctx.Flags.Usage() - return &errors.FlagsError{} - } - inArgs := cli[1:] - if err := ctx.Flags.Parse(inArgs); err != nil { - ctx.Flags.Usage() - return err - } - if ctx.Flags.NFlag() == 0 { - ctx.Flags.Usage() - return &errors.FlagsError{} - } - if err := dispatcher(ctx); err != nil { - return err - } - return nil -} -func dispatcher(ctx Context) error { - nextArgs := ctx.Flags.Args() - if len(nextArgs) != 0 { - ctx.Flags.Usage() - return &errors.FlagsError{"\nextra args supplied. See usage\n"} - } - return ctx.handlers.handle(ctx.vals, ctx.Globals) -} diff --git a/src/cmd/tools/m3ctl/delete/placements/cmd_test.go b/src/cmd/tools/m3ctl/delete/placements/cmd_test.go deleted file mode 100644 index ae3b57dd11..0000000000 --- a/src/cmd/tools/m3ctl/delete/placements/cmd_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package placements - -import ( - "testing" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" -) - -func makeStub() Context { - ctx := _setupFlags( - &placementVals{}, - placementHandlers{ - handle: func(*placementVals, globalopts.GlobalOpts) error { return nil }, - }, - ) - ctx.Globals.Endpoint = "nuch" - return ctx -} -func TestBasic(t *testing.T) { - testData := []struct { - args []string - msg string - successCondition func(error) bool - }{ - { - args: []string{"pl", "-all"}, - msg: "It should return no error for sane args for -all", - successCondition: func(err error) bool { return err == nil }, - }, - { - args: []string{"pl", "-node", "eee"}, - msg: "It should return no error for sane args for -node", - successCondition: func(err error) bool { return err == nil }, - }, - { - args: []string{}, - msg: "It should return error because we got here without pl", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"pl"}, - msg: "It should return error because we got no args", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"pl", "-h"}, - msg: "It should return error because we ran with -h", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"pl", "-node"}, - msg: "It should return error because we ran with -node but no args", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"pl", "-node", "eee", "errr"}, - msg: "It should return error because we got extra args", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"pl", "-node", ""}, - msg: "It should return an error because we got an empty val", - successCondition: func(err error) bool { return err == nil }, - }, - } - for _, v := range testData { - ctx := makeStub() - rv := ctx.PopParseDispatch(v.args) - if !v.successCondition(rv) { - t.Error(v.msg) - } - } -} diff --git a/src/cmd/tools/m3ctl/delete/placements/delete.go b/src/cmd/tools/m3ctl/delete/placements/delete.go deleted file mode 100644 index 1892e82099..0000000000 --- a/src/cmd/tools/m3ctl/delete/placements/delete.go +++ /dev/null @@ -1,18 +0,0 @@ -package placements - -import ( - "fmt" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/client" - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" - "github.com/m3db/m3/src/cmd/tools/m3ctl/placements" -) - -func doDelete(s *placementVals, globals globalopts.GlobalOpts) error { - if *s.deleteEntire { - url := fmt.Sprintf("%s%s", globals.Endpoint, placements.DefaultPath) - return client.DoDelete(url, client.Dumper, globals.Zap) - } - url := fmt.Sprintf("%s%s/%s", globals.Endpoint, placements.DefaultPath, *s.nodeName) - return client.DoDelete(url, client.Dumper, globals.Zap) -} diff --git a/src/cmd/tools/m3ctl/get/cmd.go b/src/cmd/tools/m3ctl/get/cmd.go deleted file mode 100644 index 682a4d2fd9..0000000000 --- a/src/cmd/tools/m3ctl/get/cmd.go +++ /dev/null @@ -1,70 +0,0 @@ -package get - -import ( - "flag" - "fmt" - "os" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" - "github.com/m3db/m3/src/cmd/tools/m3ctl/get/namespaces" - "github.com/m3db/m3/src/cmd/tools/m3ctl/get/placements" - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" -) - -type Context struct { - GlobalOpts globalopts.GlobalOpts - Flags *flag.FlagSet -} - -func InitializeFlags() Context { - return _setupFlags() -} - -func _setupFlags() Context { - getFlags := flag.NewFlagSet("get", flag.ContinueOnError) - getFlags.Usage = func() { - fmt.Fprintf(os.Stderr, ` -"%s" is for displaying information about the namespaces and placements. - -`, getFlags.Name()) - getFlags.PrintDefaults() - } - return Context{Flags: getFlags} -} - -func (ctx Context) PopParseDispatch(cli []string) error { - thisFlagset := ctx.Flags - if len(cli) < 1 { - thisFlagset.Usage() - return &errors.FlagsError{} - } - inArgs := cli[1:] - if err := thisFlagset.Parse(inArgs); err != nil { - thisFlagset.Usage() - return err - } - if thisFlagset.NArg() == 0 { - thisFlagset.Usage() - return &errors.FlagsError{} - } - - plctx := placements.InitializeFlags() - nsctx := namespaces.InitializeFlags() - nextArgs := thisFlagset.Args() - switch nextArgs[0] { - case plctx.Flags.Name(): - plctx.Globals = ctx.GlobalOpts - if err := plctx.PopParseDispatch(nextArgs); err != nil { - return err - } - case nsctx.Flags.Name(): - nsctx.Globals = ctx.GlobalOpts - if err := nsctx.PopParseDispatch(nextArgs); err != nil { - return err - } - default: - thisFlagset.Usage() - return &errors.FlagsError{} - } - return nil -} diff --git a/src/cmd/tools/m3ctl/get/namespaces/cmd.go b/src/cmd/tools/m3ctl/get/namespaces/cmd.go deleted file mode 100644 index cc07d34033..0000000000 --- a/src/cmd/tools/m3ctl/get/namespaces/cmd.go +++ /dev/null @@ -1,78 +0,0 @@ -package namespaces - -import ( - "flag" - "fmt" - "os" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" -) - -type namespacesVals struct { - showAll *bool -} - -type Context struct { - vals *namespacesVals - handlers namespacesHandlers - Globals globalopts.GlobalOpts - Flags *flag.FlagSet -} -type namespacesHandlers struct { - handle func(*namespacesVals, globalopts.GlobalOpts) error -} - -func InitializeFlags() Context { - return _setupFlags( - &namespacesVals{}, - namespacesHandlers{ - handle: doGet, - }, - ) -} -func _setupFlags(finalArgs *namespacesVals, handler namespacesHandlers) Context { - namespaceFlags := flag.NewFlagSet("ns", flag.ContinueOnError) - finalArgs.showAll = namespaceFlags.Bool("all", false, "get all the standard info for namespaces (otherwise default behaviour lists only the names)") - namespaceFlags.Usage = func() { - fmt.Fprintf(os.Stderr, ` -The "%s" subcommand will list the namesspace names, or verbosely dump all details about the namespaces in json format. - -`, namespaceFlags.Name()) - namespaceFlags.PrintDefaults() - } - return Context{ - vals: finalArgs, - handlers: handler, - Flags: namespaceFlags, - } -} -func (ctx Context) PopParseDispatch(cli []string) error { - if len(cli) < 1 { - ctx.Flags.Usage() - return &errors.FlagsError{} - } - inArgs := cli[1:] - if err := ctx.Flags.Parse(inArgs); err != nil { - ctx.Flags.Usage() - return &errors.FlagsError{} - } - if ctx.Flags.NArg() == 0 { - return ctx.handlers.handle(ctx.vals, ctx.Globals) - } - if err := dispatcher(ctx); err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - return err - } - return nil -} -func dispatcher(ctx Context) error { - nextArgs := ctx.Flags.Args() - switch nextArgs[0] { - case "": - return ctx.handlers.handle(ctx.vals, ctx.Globals) - default: - ctx.Flags.Usage() - return &errors.FlagsError{} - } -} diff --git a/src/cmd/tools/m3ctl/get/namespaces/cmd_test.go b/src/cmd/tools/m3ctl/get/namespaces/cmd_test.go deleted file mode 100644 index 18c1356c0d..0000000000 --- a/src/cmd/tools/m3ctl/get/namespaces/cmd_test.go +++ /dev/null @@ -1,63 +0,0 @@ -package namespaces - -import ( - "testing" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" -) - -func makeStub() Context { - ctx := _setupFlags( - &namespacesVals{}, - namespacesHandlers{ - handle: func(*namespacesVals, globalopts.GlobalOpts) error { return nil }, - }, - ) - ctx.Globals.Endpoint = "nuch" - return ctx -} -func TestBasic(t *testing.T) { - testData := []struct { - args []string - msg string - successCondition func(error) bool - }{ - { - args: []string{"ns"}, - msg: "It should return no error for sane args", - successCondition: func(err error) bool { return err == nil }, - }, - { - args: []string{"ns", "-all"}, - msg: "It should return no error for sane args for -all", - successCondition: func(err error) bool { return err == nil }, - }, - { - args: []string{}, - msg: "It should return error because we got here without pl", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"ns", "-h"}, - msg: "It should return error because we ran with -h", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"ns", "-all", "eee", "errr"}, - msg: "It should return error because we got extra args", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"ns", ""}, - msg: "It should return an error because we got an empty val", - successCondition: func(err error) bool { return err == nil }, - }, - } - for _, v := range testData { - ctx := makeStub() - rv := ctx.PopParseDispatch(v.args) - if !v.successCondition(rv) { - t.Error(v.msg) - } - } -} diff --git a/src/cmd/tools/m3ctl/get/placements/cmd.go b/src/cmd/tools/m3ctl/get/placements/cmd.go deleted file mode 100644 index 83beca6df8..0000000000 --- a/src/cmd/tools/m3ctl/get/placements/cmd.go +++ /dev/null @@ -1,77 +0,0 @@ -package placements - -import ( - "flag" - "fmt" - "os" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/errors" - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" -) - -type placementVals struct { -} -type Context struct { - vals *placementVals - handlers placementHandlers - Globals globalopts.GlobalOpts - Flags *flag.FlagSet -} -type placementHandlers struct { - handle func(*placementVals, globalopts.GlobalOpts) error -} - -func InitializeFlags() Context { - return _setupFlags( - &placementVals{}, - placementHandlers{ - handle: doGet, - }, - ) -} - -func _setupFlags(finalArgs *placementVals, handler placementHandlers) Context { - placementFlags := flag.NewFlagSet("pl", flag.ContinueOnError) - placementFlags.Usage = func() { - fmt.Fprintf(os.Stderr, ` -"%s" is for displaying the existing placement. - -`, placementFlags.Name()) - placementFlags.PrintDefaults() - } - return Context{ - vals: finalArgs, - handlers: handler, - Flags: placementFlags, - } -} - -func (ctx Context) PopParseDispatch(cli []string) error { - if len(cli) < 1 { - ctx.Flags.Usage() - return &errors.FlagsError{} - } - inArgs := cli[1:] - if err := ctx.Flags.Parse(inArgs); err != nil { - ctx.Flags.Usage() - return err - } - if ctx.Flags.NArg() == 0 { - return ctx.handlers.handle(ctx.vals, ctx.Globals) - } - if err := dispatcher(ctx); err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - return err - } - return nil -} - -func dispatcher(ctx Context) error { - nextArgs := ctx.Flags.Args() - switch nextArgs[0] { - case "": - return ctx.handlers.handle(ctx.vals, ctx.Globals) - default: - return &errors.FlagsError{} - } -} diff --git a/src/cmd/tools/m3ctl/get/placements/cmd_test.go b/src/cmd/tools/m3ctl/get/placements/cmd_test.go deleted file mode 100644 index 4db7271848..0000000000 --- a/src/cmd/tools/m3ctl/get/placements/cmd_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package placements - -import ( - "testing" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" -) - -func makeStub() Context { - ctx := _setupFlags( - &placementVals{}, - placementHandlers{ - handle: func(*placementVals, globalopts.GlobalOpts) error { return nil }, - }, - ) - ctx.Globals.Endpoint = "nuch" - return ctx -} -func TestBasic(t *testing.T) { - testData := []struct { - args []string - msg string - successCondition func(error) bool - }{ - { - args: []string{"pl"}, - msg: "It should return no error for sane args", - successCondition: func(err error) bool { return err == nil }, - }, - { - args: []string{}, - msg: "It should return error because we got here without pl", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"pl", "-h"}, - msg: "It should return error because we ran with -h", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"pl", "-node", "eee", "errr"}, - msg: "It should return error because we got extra args", - successCondition: func(err error) bool { return err != nil }, - }, - { - args: []string{"pl", ""}, - msg: "It should return an error because we got an empty val", - successCondition: func(err error) bool { return err == nil }, - }, - } - for _, v := range testData { - ctx := makeStub() - rv := ctx.PopParseDispatch(v.args) - if !v.successCondition(rv) { - t.Error(v.msg) - } - } -} diff --git a/src/cmd/tools/m3ctl/get/placements/get.go b/src/cmd/tools/m3ctl/get/placements/get.go deleted file mode 100644 index 51db9f76b8..0000000000 --- a/src/cmd/tools/m3ctl/get/placements/get.go +++ /dev/null @@ -1,14 +0,0 @@ -package placements - -import ( - "fmt" - - "github.com/m3db/m3/src/cmd/tools/m3ctl/client" - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" - "github.com/m3db/m3/src/cmd/tools/m3ctl/placements" -) - -func doGet(s *placementVals, globals globalopts.GlobalOpts) error { - url := fmt.Sprintf("%s%s", globals.Endpoint, placements.DefaultPath) - return client.DoGet(url, client.Dumper, globals.Zap) -} diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 0c399058e5..83cf0bb60b 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -21,84 +21,141 @@ package main import ( - "flag" "fmt" "os" "github.com/m3db/m3/src/cmd/tools/m3ctl/apply" - "github.com/m3db/m3/src/cmd/tools/m3ctl/delete" - "github.com/m3db/m3/src/cmd/tools/m3ctl/get" + "github.com/m3db/m3/src/cmd/tools/m3ctl/namespaces" + "github.com/m3db/m3/src/cmd/tools/m3ctl/placements" + "github.com/spf13/cobra" "go.uber.org/zap" ) const ( - defaultEndpoint = "http://localhost:7201" + DefaultEndpoint = "http://localhost:7201" +) + +var ( + endPoint string + yamlPath string + showAll bool + nodeName string ) func main() { - // top-level option - endPoint := flag.String("endpoint", defaultEndpoint, "The url for target m3db backend.") + rootCmd := &cobra.Command{ + Use: "cobra", + } + + rootCmd.PersistentFlags().StringVar(&endPoint, "endpoint", DefaultEndpoint, "m3db service endpoint") - // flagsets for next level down - getFlagSets := get.InitializeFlags() - deleteFlagSets := delete.InitializeFlags() - applyFlagSets := apply.InitializeFlags() - flag.Usage = func() { - fmt.Fprintf(flag.CommandLine.Output(), ` -Usage of %s: + getCmd := &cobra.Command{ + Use: "get []", + Short: "Get specified resources from the remote", + Long: `...`, + } - Specify one of the following subcommands, which are shorthand for database, placement, and namespace: + deleteCmd := &cobra.Command{ + Use: "delete []", + Short: "Delete specified resources from the remote", + Long: `...`, + } - %s - %s - %s + applyCmd := &cobra.Command{ + Use: "apply []", + Short: "Apply various yamls to remote endpoint", + Long: `...`, + Run: func(cmd *cobra.Command, args []string) { -Each subcommand has its own built-in help provided via "-h". + zapper, err := zap.NewDevelopment() + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } -`, os.Args[0], applyFlagSets.Flags.Name(), - getFlagSets.Flags.Name(), - deleteFlagSets.Flags.Name()) + zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) - flag.PrintDefaults() + if err := apply.DoApply(endPoint, yamlPath, zapper); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + + }, } - // parse this level - flag.Parse() - if len(os.Args) < 2 { - flag.Usage() - os.Exit(1) + + getNamespaceCmd := &cobra.Command{ + Use: "namespace []", + Short: "Get the namespaces from the remote endpoint", + Long: `...`, + Run: func(cmd *cobra.Command, args []string) { + + zapper, err := zap.NewDevelopment() + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + + zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) + + if err := namespaces.DoGet(endPoint, showAll, zapper); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + }, } - rawLogger, err := zap.NewDevelopment() - if err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - os.Exit(1) + + getPlacementCmd := &cobra.Command{ + Use: "placement []", + Short: "Get the placement from the remote endpoint", + Long: `...`, + Run: func(cmd *cobra.Command, args []string) { + + zapper, err := zap.NewDevelopment() + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + + zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) + + if err := placements.DoGet(endPoint, zapper); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + }, } - log := rawLogger.Sugar() - // dispatch to the next level - switch flag.Arg(0) { - case getFlagSets.Flags.Name(): - getFlagSets.GlobalOpts.Endpoint = *endPoint - getFlagSets.GlobalOpts.Zap = log - if err := getFlagSets.PopParseDispatch(flag.Args()); err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - os.Exit(1) - } - case deleteFlagSets.Flags.Name(): - deleteFlagSets.GlobalOpts.Endpoint = *endPoint - deleteFlagSets.GlobalOpts.Zap = log - if err := deleteFlagSets.PopParseDispatch(flag.Args()); err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - os.Exit(1) - } - case applyFlagSets.Flags.Name(): - applyFlagSets.GlobalOpts.Endpoint = *endPoint - applyFlagSets.GlobalOpts.Zap = log - if err := applyFlagSets.PopParseDispatch(flag.Args()); err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - os.Exit(1) - } - default: - flag.Usage() - os.Exit(1) + + deletePlacementCmd := &cobra.Command{ + Use: "placement []", + Short: "Delete the placement from the remote endpoint", + Long: `...`, + Run: func(cmd *cobra.Command, args []string) { + + zapper, err := zap.NewDevelopment() + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + + zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) + + if err := placements.DoDelete(endPoint, nodeName, showAll, zapper); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + }, } + + rootCmd.AddCommand(getCmd, applyCmd, deleteCmd) + applyCmd.Flags().StringVarP(&yamlPath, "file", "f", "", "times to echo the input") + getNamespaceCmd.Flags().BoolVarP(&showAll, "showAll", "a", false, "times to echo the input") + getCmd.AddCommand(getNamespaceCmd) + getCmd.AddCommand(getPlacementCmd) + deleteCmd.AddCommand(deletePlacementCmd) + deletePlacementCmd.Flags().BoolVarP(&showAll, "deleteAll", "a", false, "delete the entire placement") + deletePlacementCmd.Flags().StringVarP(&nodeName, "nodeName", "n", "", "which node to delete from the placement") + + rootCmd.Execute() + } diff --git a/src/cmd/tools/m3ctl/namespaces/delete.go b/src/cmd/tools/m3ctl/namespaces/delete.go new file mode 100644 index 0000000000..ea1544515e --- /dev/null +++ b/src/cmd/tools/m3ctl/namespaces/delete.go @@ -0,0 +1,16 @@ +package namespaces + +import ( + "fmt" + + "github.com/m3db/m3/src/cmd/tools/m3ctl/client" + //"github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" + "go.uber.org/zap" +) + +//func doDelete(flags *namespacesVals, globals globalopts.GlobalOpts) error { +func DoDelete(endpoint string, nodeName string, deleteEntire bool, zapper *zap.Logger) error { + + url := fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", nodeName) + return client.DoDelete(url, client.Dumper, zapper) +} diff --git a/src/cmd/tools/m3ctl/get/namespaces/get.go b/src/cmd/tools/m3ctl/namespaces/get.go similarity index 51% rename from src/cmd/tools/m3ctl/get/namespaces/get.go rename to src/cmd/tools/m3ctl/namespaces/get.go index 75d9ee9451..cdd0563f46 100644 --- a/src/cmd/tools/m3ctl/get/namespaces/get.go +++ b/src/cmd/tools/m3ctl/namespaces/get.go @@ -6,23 +6,21 @@ import ( "io" "github.com/m3db/m3/src/cmd/tools/m3ctl/client" - "github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" - "github.com/m3db/m3/src/cmd/tools/m3ctl/namespaces" "github.com/m3db/m3/src/query/generated/proto/admin" "github.com/gogo/protobuf/jsonpb" ) -func doGet(flags *namespacesVals, globals globalopts.GlobalOpts) error { - url := fmt.Sprintf("%s%s?%s", globals.Endpoint, namespaces.DefaultPath, namespaces.DebugQS) - if *flags.showAll { - return client.DoGet(url, client.Dumper, globals.Zap) +func DoGet(endpoint string, showAll bool, zapper *zap.Logger) error { + url := fmt.Sprintf("%s%s?%s", endpoint, DefaultPath, DebugQS) + if showAll { + return client.DoGet(url, client.Dumper, zapper) } else { - return client.DoGet(url, showNames, globals.Zap) + return client.DoGet(url, showNames, zapper) } } -func showNames(in io.Reader, zl *zap.SugaredLogger) error { +func showNames(in io.Reader, zl *zap.Logger) error { registry := admin.NamespaceGetResponse{} unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} if err := unmarshaller.Unmarshal(in, ®istry); err != nil { diff --git a/src/cmd/tools/m3ctl/placements/delete.go b/src/cmd/tools/m3ctl/placements/delete.go new file mode 100644 index 0000000000..079efb53cc --- /dev/null +++ b/src/cmd/tools/m3ctl/placements/delete.go @@ -0,0 +1,16 @@ +package placements + +import ( + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/client" + "go.uber.org/zap" +) + +func DoDelete(endpoint string, nodeName string, deleteEntire bool, zapper *zap.Logger) error { + if deleteEntire { + url := fmt.Sprintf("%s%s", endpoint, DefaultPath) + return client.DoDelete(url, client.Dumper, zapper) + } + url := fmt.Sprintf("%s%s/%s", endpoint, DefaultPath, nodeName) + return client.DoDelete(url, client.Dumper, zapper) +} diff --git a/src/cmd/tools/m3ctl/placements/get.go b/src/cmd/tools/m3ctl/placements/get.go new file mode 100644 index 0000000000..81489e282d --- /dev/null +++ b/src/cmd/tools/m3ctl/placements/get.go @@ -0,0 +1,12 @@ +package placements + +import ( + "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/client" + "go.uber.org/zap" +) + +func DoGet(endpoint string, zapper *zap.Logger) error { + url := fmt.Sprintf("%s%s", endpoint, DefaultPath) + return client.DoGet(url, client.Dumper, zapper) +} diff --git a/src/cmd/tools/m3ctl/yaml/load.go b/src/cmd/tools/m3ctl/yaml/load.go index 7e14f18823..68b80ae57f 100644 --- a/src/cmd/tools/m3ctl/yaml/load.go +++ b/src/cmd/tools/m3ctl/yaml/load.go @@ -19,7 +19,7 @@ import ( // // See the examples directories. // -func Load(path string, zl *zap.SugaredLogger) (string, io.Reader, error) { +func Load(path string, zl *zap.Logger) (string, io.Reader, error) { content, err := ioutil.ReadFile(path) if err != nil { return "", nil, err From 49bb6393ea5026d533cb7c4827fcdc5e62387c32 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Mon, 16 Mar 2020 09:04:40 -0700 Subject: [PATCH 52/65] tested with cobra and added some aliases --- src/cmd/tools/m3ctl/main/main.go | 33 ++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 83cf0bb60b..b385919bfb 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -51,21 +51,22 @@ func main() { rootCmd.PersistentFlags().StringVar(&endPoint, "endpoint", DefaultEndpoint, "m3db service endpoint") getCmd := &cobra.Command{ - Use: "get []", + Use: "get", Short: "Get specified resources from the remote", - Long: `...`, } deleteCmd := &cobra.Command{ - Use: "delete []", + Use: "delete", Short: "Delete specified resources from the remote", - Long: `...`, } applyCmd := &cobra.Command{ Use: "apply []", Short: "Apply various yamls to remote endpoint", - Long: `...`, + Long: `This will take specific yamls and send them over to the remote +endpoint. See the yaml/examples directory for examples. Operations such as +database creation, database init, adding a node, and replacing a node, are supported. +`, Run: func(cmd *cobra.Command, args []string) { zapper, err := zap.NewDevelopment() @@ -76,6 +77,14 @@ func main() { zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) + zapper.Debug(fmt.Sprintf("args:%v:\n", cmd.LocalFlags().Lookup("file").Value.String())) + + if len(cmd.LocalFlags().Lookup("file").Value.String()) == 0 { + fmt.Printf("Specify a path to a yaml file.\n") + cmd.Usage() + os.Exit(1) + } + if err := apply.DoApply(endPoint, yamlPath, zapper); err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) @@ -87,7 +96,7 @@ func main() { getNamespaceCmd := &cobra.Command{ Use: "namespace []", Short: "Get the namespaces from the remote endpoint", - Long: `...`, + Aliases: []string{"ns"}, Run: func(cmd *cobra.Command, args []string) { zapper, err := zap.NewDevelopment() @@ -106,9 +115,9 @@ func main() { } getPlacementCmd := &cobra.Command{ - Use: "placement []", + Use: "placement", Short: "Get the placement from the remote endpoint", - Long: `...`, + Aliases: []string{"pl"}, Run: func(cmd *cobra.Command, args []string) { zapper, err := zap.NewDevelopment() @@ -127,9 +136,9 @@ func main() { } deletePlacementCmd := &cobra.Command{ - Use: "placement []", + Use: "placement", Short: "Delete the placement from the remote endpoint", - Long: `...`, + Aliases: []string{"pl"}, Run: func(cmd *cobra.Command, args []string) { zapper, err := zap.NewDevelopment() @@ -148,11 +157,11 @@ func main() { } rootCmd.AddCommand(getCmd, applyCmd, deleteCmd) - applyCmd.Flags().StringVarP(&yamlPath, "file", "f", "", "times to echo the input") - getNamespaceCmd.Flags().BoolVarP(&showAll, "showAll", "a", false, "times to echo the input") getCmd.AddCommand(getNamespaceCmd) getCmd.AddCommand(getPlacementCmd) deleteCmd.AddCommand(deletePlacementCmd) + applyCmd.Flags().StringVarP(&yamlPath, "file", "f", "", "times to echo the input") + getNamespaceCmd.Flags().BoolVarP(&showAll, "showAll", "a", false, "times to echo the input") deletePlacementCmd.Flags().BoolVarP(&showAll, "deleteAll", "a", false, "delete the entire placement") deletePlacementCmd.Flags().StringVarP(&nodeName, "nodeName", "n", "", "which node to delete from the placement") From ee2e4426834574c15e6f30fefba7d786d7ff3417 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Mon, 16 Mar 2020 09:30:31 -0700 Subject: [PATCH 53/65] add delete namespace --- src/cmd/tools/m3ctl/main/main.go | 31 +++++++++++++++++++++--- src/cmd/tools/m3ctl/namespaces/delete.go | 5 ++-- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index b385919bfb..e04f6caeea 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -48,8 +48,6 @@ func main() { Use: "cobra", } - rootCmd.PersistentFlags().StringVar(&endPoint, "endpoint", DefaultEndpoint, "m3db service endpoint") - getCmd := &cobra.Command{ Use: "get", Short: "Get specified resources from the remote", @@ -61,7 +59,7 @@ func main() { } applyCmd := &cobra.Command{ - Use: "apply []", + Use: "apply", Short: "Apply various yamls to remote endpoint", Long: `This will take specific yamls and send them over to the remote endpoint. See the yaml/examples directory for examples. Operations such as @@ -156,14 +154,39 @@ database creation, database init, adding a node, and replacing a node, are suppo }, } + + deleteNamespaceCmd := &cobra.Command{ + Use: "namespace", + Short: "Delete the namespace from the remote endpoint", + Aliases: []string{"ns"}, + Run: func(cmd *cobra.Command, args []string) { + + zapper, err := zap.NewDevelopment() + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + + zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) + + if err := namespaces.DoDelete(endPoint, nodeName, zapper); err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + }, + } + rootCmd.AddCommand(getCmd, applyCmd, deleteCmd) getCmd.AddCommand(getNamespaceCmd) getCmd.AddCommand(getPlacementCmd) deleteCmd.AddCommand(deletePlacementCmd) + deleteCmd.AddCommand(deleteNamespaceCmd) + + rootCmd.PersistentFlags().StringVar(&endPoint, "endpoint", DefaultEndpoint, "m3db service endpoint") applyCmd.Flags().StringVarP(&yamlPath, "file", "f", "", "times to echo the input") getNamespaceCmd.Flags().BoolVarP(&showAll, "showAll", "a", false, "times to echo the input") deletePlacementCmd.Flags().BoolVarP(&showAll, "deleteAll", "a", false, "delete the entire placement") - deletePlacementCmd.Flags().StringVarP(&nodeName, "nodeName", "n", "", "which node to delete from the placement") + deleteCmd.PersistentFlags().StringVarP(&nodeName, "nodeName", "n", "", "which node to delete") rootCmd.Execute() diff --git a/src/cmd/tools/m3ctl/namespaces/delete.go b/src/cmd/tools/m3ctl/namespaces/delete.go index ea1544515e..6802b3edbc 100644 --- a/src/cmd/tools/m3ctl/namespaces/delete.go +++ b/src/cmd/tools/m3ctl/namespaces/delete.go @@ -8,9 +8,8 @@ import ( "go.uber.org/zap" ) -//func doDelete(flags *namespacesVals, globals globalopts.GlobalOpts) error { -func DoDelete(endpoint string, nodeName string, deleteEntire bool, zapper *zap.Logger) error { +func DoDelete(endpoint string, nsName string, zapper *zap.Logger) error { - url := fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", nodeName) + url := fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", nsName) return client.DoDelete(url, client.Dumper, zapper) } From 17dffdc827b5ec648e0170f9775497e026e02e10 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Mon, 16 Mar 2020 09:36:47 -0700 Subject: [PATCH 54/65] move output to logger per comment --- src/cmd/tools/m3ctl/client/checker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd/tools/m3ctl/client/checker.go b/src/cmd/tools/m3ctl/client/checker.go index 018f2acffb..0c486f8dcf 100644 --- a/src/cmd/tools/m3ctl/client/checker.go +++ b/src/cmd/tools/m3ctl/client/checker.go @@ -13,7 +13,7 @@ func checkForAndHandleError(url string, resp *http.Response, zl *zap.Logger) err if resp.StatusCode > 299 { dat, _ := ioutil.ReadAll(resp.Body) if dat != nil { - fmt.Println(string(dat)) + zl.Info(string(dat)) } return fmt.Errorf("error from m3db:%s:url:%s:", resp.Status, url) } From b0a787fcbbede1c6a38ae812a10ee3f376f2930d Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Mon, 16 Mar 2020 15:28:57 -0700 Subject: [PATCH 55/65] factor out the logger instantiation --- src/cmd/tools/m3ctl/main/main.go | 36 ++++++-------------------------- 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index e04f6caeea..c72c4d7db8 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -44,6 +44,12 @@ var ( func main() { + zapper, err := zap.NewDevelopment() + if err != nil { + fmt.Fprintf(os.Stderr, err.Error()) + os.Exit(1) + } + rootCmd := &cobra.Command{ Use: "cobra", } @@ -67,12 +73,6 @@ database creation, database init, adding a node, and replacing a node, are suppo `, Run: func(cmd *cobra.Command, args []string) { - zapper, err := zap.NewDevelopment() - if err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - os.Exit(1) - } - zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) zapper.Debug(fmt.Sprintf("args:%v:\n", cmd.LocalFlags().Lookup("file").Value.String())) @@ -97,12 +97,6 @@ database creation, database init, adding a node, and replacing a node, are suppo Aliases: []string{"ns"}, Run: func(cmd *cobra.Command, args []string) { - zapper, err := zap.NewDevelopment() - if err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - os.Exit(1) - } - zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) if err := namespaces.DoGet(endPoint, showAll, zapper); err != nil { @@ -118,12 +112,6 @@ database creation, database init, adding a node, and replacing a node, are suppo Aliases: []string{"pl"}, Run: func(cmd *cobra.Command, args []string) { - zapper, err := zap.NewDevelopment() - if err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - os.Exit(1) - } - zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) if err := placements.DoGet(endPoint, zapper); err != nil { @@ -139,12 +127,6 @@ database creation, database init, adding a node, and replacing a node, are suppo Aliases: []string{"pl"}, Run: func(cmd *cobra.Command, args []string) { - zapper, err := zap.NewDevelopment() - if err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - os.Exit(1) - } - zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) if err := placements.DoDelete(endPoint, nodeName, showAll, zapper); err != nil { @@ -161,12 +143,6 @@ database creation, database init, adding a node, and replacing a node, are suppo Aliases: []string{"ns"}, Run: func(cmd *cobra.Command, args []string) { - zapper, err := zap.NewDevelopment() - if err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - os.Exit(1) - } - zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) if err := namespaces.DoDelete(endPoint, nodeName, zapper); err != nil { From 79a10905d9ce521a9a849fe512f000cab13e7172 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Wed, 25 Mar 2020 13:42:29 -0700 Subject: [PATCH 56/65] address pr comments --- src/cmd/tools/m3ctl/apply/apply.go | 30 ++++++++++++-- src/cmd/tools/m3ctl/client/checker.go | 35 ++++++++++++++-- src/cmd/tools/m3ctl/client/http.go | 30 ++++++++++++-- src/cmd/tools/m3ctl/errors/types.go | 20 +++++++++ src/cmd/tools/m3ctl/globalopts/types.go | 8 ---- src/cmd/tools/m3ctl/main/main.go | 41 +++++++++---------- src/cmd/tools/m3ctl/namespaces/delete.go | 27 ++++++++++-- src/cmd/tools/m3ctl/namespaces/get.go | 27 ++++++++++-- src/cmd/tools/m3ctl/namespaces/types.go | 22 ++++++++++ src/cmd/tools/m3ctl/placements/delete.go | 27 ++++++++++-- src/cmd/tools/m3ctl/placements/get.go | 25 ++++++++++- src/cmd/tools/m3ctl/placements/types.go | 21 ++++++++++ .../yaml/{dbCreate.proto => db_create.proto} | 6 +-- .../examples/{newNode.yaml => new_node.yaml} | 0 .../{replaceNode.yaml => replace_node.yaml} | 0 .../{dbCreate.pb.go => db_create.pb.go} | 0 src/cmd/tools/m3ctl/yaml/load.go | 26 ++++++++++-- src/cmd/tools/m3ctl/yaml/load_test.go | 26 ++++++++++-- src/cmd/tools/m3ctl/yaml/peeker.go | 20 +++++++++ src/cmd/tools/m3ctl/yaml/peeker_test.go | 26 ++++++++++-- src/cmd/tools/m3ctl/yaml/placement.proto | 8 ++-- .../{basicCreate.yaml => basic_create.yaml} | 0 ...nOperation.yaml => unknown_operation.yaml} | 2 +- src/cmd/tools/m3ctl/yaml/types.go | 20 +++++++++ 24 files changed, 378 insertions(+), 69 deletions(-) delete mode 100644 src/cmd/tools/m3ctl/globalopts/types.go rename src/cmd/tools/m3ctl/yaml/{dbCreate.proto => db_create.proto} (67%) rename src/cmd/tools/m3ctl/yaml/examples/{newNode.yaml => new_node.yaml} (100%) rename src/cmd/tools/m3ctl/yaml/examples/{replaceNode.yaml => replace_node.yaml} (100%) rename src/cmd/tools/m3ctl/yaml/generated/{dbCreate.pb.go => db_create.pb.go} (100%) rename src/cmd/tools/m3ctl/yaml/testdata/{basicCreate.yaml => basic_create.yaml} (100%) rename src/cmd/tools/m3ctl/yaml/testdata/{unknownOperation.yaml => unknown_operation.yaml} (93%) diff --git a/src/cmd/tools/m3ctl/apply/apply.go b/src/cmd/tools/m3ctl/apply/apply.go index 664f7e84b3..0f52f11efc 100644 --- a/src/cmd/tools/m3ctl/apply/apply.go +++ b/src/cmd/tools/m3ctl/apply/apply.go @@ -1,3 +1,23 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package apply import ( @@ -8,12 +28,14 @@ import ( "github.com/m3db/m3/src/cmd/tools/m3ctl/yaml" ) -func DoApply(endpoint string, filepath string, zapper *zap.Logger) error { - //path, data, err := yaml.Load(vals.yamlFlag.Value[0], globals.Zap) - path, data, err := yaml.Load(filepath, zapper) +// DoApply does the API call to handle the kubectl apply command +// It looks at the yaml, figures out what kind of API call to make +// Sends it all off to the API +func DoApply(endpoint string, filepath string, logger *zap.Logger) error { + path, data, err := yaml.Load(filepath, logger) if err != nil { return err } url := fmt.Sprintf("%s%s", endpoint, path) - return client.DoPost(url, data, client.Dumper, zapper) + return client.DoPost(url, data, client.Dumper, logger) } diff --git a/src/cmd/tools/m3ctl/client/checker.go b/src/cmd/tools/m3ctl/client/checker.go index 0c486f8dcf..3347f42a18 100644 --- a/src/cmd/tools/m3ctl/client/checker.go +++ b/src/cmd/tools/m3ctl/client/checker.go @@ -1,3 +1,23 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package client import ( @@ -9,13 +29,20 @@ import ( ) func checkForAndHandleError(url string, resp *http.Response, zl *zap.Logger) error { - zl.Info(fmt.Sprintf("resp.StatusCode:%d:\n", resp.StatusCode)) - if resp.StatusCode > 299 { + if resp.StatusCode%100 != 2 { dat, _ := ioutil.ReadAll(resp.Body) if dat != nil { - zl.Info(string(dat)) + zl.Error("error response", + zap.Error(fmt.Errorf("status %d", resp.StatusCode)), + zap.String("url", url), + zap.ByteString("response", dat)) + } else { + zl.Error("error response", + zap.Error(fmt.Errorf("status %d", resp.StatusCode)), + zap.String("url", url), + zap.ByteString("response", dat)) } - return fmt.Errorf("error from m3db:%s:url:%s:", resp.Status, url) + return fmt.Errorf("error from m3db status=%s, url=%s\n", resp.Status, url) } return nil } diff --git a/src/cmd/tools/m3ctl/client/http.go b/src/cmd/tools/m3ctl/client/http.go index 4b35fad950..96b117006b 100644 --- a/src/cmd/tools/m3ctl/client/http.go +++ b/src/cmd/tools/m3ctl/client/http.go @@ -1,3 +1,23 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package client import ( @@ -12,8 +32,9 @@ import ( const timeout = time.Duration(5 * time.Second) +// DoGet is the low level call to the backend api for gets func DoGet(url string, getter func(reader io.Reader, zl *zap.Logger) error, zl *zap.Logger) error { - zl.Info(fmt.Sprintf("DoGet:url:%s:\n", url)) + zl.Info("request", zap.String("method", "get"), zap.String("url", url)) client := http.Client{ Timeout: timeout, } @@ -31,8 +52,9 @@ func DoGet(url string, getter func(reader io.Reader, zl *zap.Logger) error, zl * return getter(resp.Body, zl) } +// DoPost is the low level call to the backend api for posts func DoPost(url string, data io.Reader, getter func(reader io.Reader, zl *zap.Logger) error, zl *zap.Logger) error { - zl.Info(fmt.Sprintf("DoPost:url:%s:\n", url)) + zl.Info("request", zap.String("method", "post"), zap.String("url", url)) client := &http.Client{ Timeout: timeout, } @@ -52,8 +74,9 @@ func DoPost(url string, data io.Reader, getter func(reader io.Reader, zl *zap.Lo return getter(resp.Body, zl) } +// DoDelete is the low level call to the backend api for deletes func DoDelete(url string, getter func(reader io.Reader, zl *zap.Logger) error, zl *zap.Logger) error { - zl.Info(fmt.Sprintf("DoDelete:url:%s:\n", url)) + zl.Info("request", zap.String("method", "delete"), zap.String("url", url)) client := &http.Client{ Timeout: timeout, } @@ -73,6 +96,7 @@ func DoDelete(url string, getter func(reader io.Reader, zl *zap.Logger) error, z return getter(resp.Body, zl) } +// Dumper is a simple printer for http responses func Dumper(in io.Reader, zl *zap.Logger) error { dat, err := ioutil.ReadAll(in) if err != nil { diff --git a/src/cmd/tools/m3ctl/errors/types.go b/src/cmd/tools/m3ctl/errors/types.go index f2eaba018b..3b113bebf2 100644 --- a/src/cmd/tools/m3ctl/errors/types.go +++ b/src/cmd/tools/m3ctl/errors/types.go @@ -1,3 +1,23 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package errors type FlagsError struct { diff --git a/src/cmd/tools/m3ctl/globalopts/types.go b/src/cmd/tools/m3ctl/globalopts/types.go deleted file mode 100644 index f0c923c4e3..0000000000 --- a/src/cmd/tools/m3ctl/globalopts/types.go +++ /dev/null @@ -1,8 +0,0 @@ -package globalopts - -import "go.uber.org/zap" - -type GlobalOpts struct { - Endpoint string - Zap *zap.SugaredLogger -} diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index c72c4d7db8..90b43a58f9 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018 Uber Technologies, Inc. +// Copyright (c) 2020 Uber Technologies, Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -44,7 +44,7 @@ var ( func main() { - zapper, err := zap.NewDevelopment() + logger, err := zap.NewDevelopment() if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) @@ -73,18 +73,17 @@ database creation, database init, adding a node, and replacing a node, are suppo `, Run: func(cmd *cobra.Command, args []string) { - zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) + fileArg := cmd.LocalFlags().Lookup("file").Value.String() + logger.Debug("running command", zap.String("name", cmd.Name()), zap.String("args", fileArg)) - zapper.Debug(fmt.Sprintf("args:%v:\n", cmd.LocalFlags().Lookup("file").Value.String())) - - if len(cmd.LocalFlags().Lookup("file").Value.String()) == 0 { - fmt.Printf("Specify a path to a yaml file.\n") + if len(fileArg) == 0 { + logger.Error("specify a path to a yaml file.\n") cmd.Usage() os.Exit(1) } - if err := apply.DoApply(endPoint, yamlPath, zapper); err != nil { - fmt.Fprintf(os.Stderr, err.Error()) + if err := apply.DoApply(endPoint, yamlPath, logger); err != nil { + logger.Error("apply failed", zap.Error(err)) os.Exit(1) } @@ -97,10 +96,10 @@ database creation, database init, adding a node, and replacing a node, are suppo Aliases: []string{"ns"}, Run: func(cmd *cobra.Command, args []string) { - zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) + logger.Debug("running command", zap.String("command", cmd.Name())) - if err := namespaces.DoGet(endPoint, showAll, zapper); err != nil { - fmt.Fprintf(os.Stderr, err.Error()) + if err := namespaces.DoGet(endPoint, showAll, logger); err != nil { + logger.Error("get namespace failed", zap.Error(err)) os.Exit(1) } }, @@ -112,10 +111,10 @@ database creation, database init, adding a node, and replacing a node, are suppo Aliases: []string{"pl"}, Run: func(cmd *cobra.Command, args []string) { - zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) + logger.Debug("running command", zap.String("command", cmd.Name())) - if err := placements.DoGet(endPoint, zapper); err != nil { - fmt.Fprintf(os.Stderr, err.Error()) + if err := placements.DoGet(endPoint, logger); err != nil { + logger.Error("get placement failed", zap.Error(err)) os.Exit(1) } }, @@ -127,10 +126,10 @@ database creation, database init, adding a node, and replacing a node, are suppo Aliases: []string{"pl"}, Run: func(cmd *cobra.Command, args []string) { - zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) + logger.Debug("running command", zap.String("command", cmd.Name())) - if err := placements.DoDelete(endPoint, nodeName, showAll, zapper); err != nil { - fmt.Fprintf(os.Stderr, err.Error()) + if err := placements.DoDelete(endPoint, nodeName, showAll, logger); err != nil { + logger.Error("delete placement failed", zap.Error(err)) os.Exit(1) } }, @@ -143,10 +142,10 @@ database creation, database init, adding a node, and replacing a node, are suppo Aliases: []string{"ns"}, Run: func(cmd *cobra.Command, args []string) { - zapper.Debug(fmt.Sprintf("Running command:%s:\n", cmd.Name())) + logger.Debug("running command", zap.String("command", cmd.Name())) - if err := namespaces.DoDelete(endPoint, nodeName, zapper); err != nil { - fmt.Fprintf(os.Stderr, err.Error()) + if err := namespaces.DoDelete(endPoint, nodeName, logger); err != nil { + logger.Error("delete namespace failed", zap.Error(err)) os.Exit(1) } }, diff --git a/src/cmd/tools/m3ctl/namespaces/delete.go b/src/cmd/tools/m3ctl/namespaces/delete.go index 6802b3edbc..709c26dbcc 100644 --- a/src/cmd/tools/m3ctl/namespaces/delete.go +++ b/src/cmd/tools/m3ctl/namespaces/delete.go @@ -1,15 +1,34 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package namespaces import ( "fmt" "github.com/m3db/m3/src/cmd/tools/m3ctl/client" - //"github.com/m3db/m3/src/cmd/tools/m3ctl/globalopts" "go.uber.org/zap" ) -func DoDelete(endpoint string, nsName string, zapper *zap.Logger) error { - +// DoDelete calls the delete namespaces api on the backend +func DoDelete(endpoint string, nsName string, logger *zap.Logger) error { url := fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", nsName) - return client.DoDelete(url, client.Dumper, zapper) + return client.DoDelete(url, client.Dumper, logger) } diff --git a/src/cmd/tools/m3ctl/namespaces/get.go b/src/cmd/tools/m3ctl/namespaces/get.go index cdd0563f46..e50c0eb4ee 100644 --- a/src/cmd/tools/m3ctl/namespaces/get.go +++ b/src/cmd/tools/m3ctl/namespaces/get.go @@ -1,3 +1,23 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package namespaces import ( @@ -11,12 +31,13 @@ import ( "github.com/gogo/protobuf/jsonpb" ) -func DoGet(endpoint string, showAll bool, zapper *zap.Logger) error { +// DoGet calls the backend get namespace api +func DoGet(endpoint string, showAll bool, logger *zap.Logger) error { url := fmt.Sprintf("%s%s?%s", endpoint, DefaultPath, DebugQS) if showAll { - return client.DoGet(url, client.Dumper, zapper) + return client.DoGet(url, client.Dumper, logger) } else { - return client.DoGet(url, showNames, zapper) + return client.DoGet(url, showNames, logger) } } diff --git a/src/cmd/tools/m3ctl/namespaces/types.go b/src/cmd/tools/m3ctl/namespaces/types.go index 485bd1178c..c06a83756e 100644 --- a/src/cmd/tools/m3ctl/namespaces/types.go +++ b/src/cmd/tools/m3ctl/namespaces/types.go @@ -1,6 +1,28 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package namespaces const ( + // DefaultPath is the default url path for the namespace api calls DefaultPath = "/api/v1/namespace" + // DebugQS this is the query string to activate debug output in api responses DebugQS = "debug=true" ) diff --git a/src/cmd/tools/m3ctl/placements/delete.go b/src/cmd/tools/m3ctl/placements/delete.go index 079efb53cc..19678407c3 100644 --- a/src/cmd/tools/m3ctl/placements/delete.go +++ b/src/cmd/tools/m3ctl/placements/delete.go @@ -1,3 +1,23 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package placements import ( @@ -6,11 +26,12 @@ import ( "go.uber.org/zap" ) -func DoDelete(endpoint string, nodeName string, deleteEntire bool, zapper *zap.Logger) error { +// DoDelete does the delete api calls for placements +func DoDelete(endpoint string, nodeName string, deleteEntire bool, logger *zap.Logger) error { if deleteEntire { url := fmt.Sprintf("%s%s", endpoint, DefaultPath) - return client.DoDelete(url, client.Dumper, zapper) + return client.DoDelete(url, client.Dumper, logger) } url := fmt.Sprintf("%s%s/%s", endpoint, DefaultPath, nodeName) - return client.DoDelete(url, client.Dumper, zapper) + return client.DoDelete(url, client.Dumper, logger) } diff --git a/src/cmd/tools/m3ctl/placements/get.go b/src/cmd/tools/m3ctl/placements/get.go index 81489e282d..a132fbd2bb 100644 --- a/src/cmd/tools/m3ctl/placements/get.go +++ b/src/cmd/tools/m3ctl/placements/get.go @@ -1,3 +1,23 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package placements import ( @@ -6,7 +26,8 @@ import ( "go.uber.org/zap" ) -func DoGet(endpoint string, zapper *zap.Logger) error { +// DoGet calls the backend api for get placements +func DoGet(endpoint string, logger *zap.Logger) error { url := fmt.Sprintf("%s%s", endpoint, DefaultPath) - return client.DoGet(url, client.Dumper, zapper) + return client.DoGet(url, client.Dumper, logger) } diff --git a/src/cmd/tools/m3ctl/placements/types.go b/src/cmd/tools/m3ctl/placements/types.go index 3cb13d53a0..00917c3a34 100644 --- a/src/cmd/tools/m3ctl/placements/types.go +++ b/src/cmd/tools/m3ctl/placements/types.go @@ -1,5 +1,26 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package placements const ( + // DefaultPath is the url path for api calls for placements DefaultPath = "/api/v1/services/m3db/placement" ) diff --git a/src/cmd/tools/m3ctl/yaml/dbCreate.proto b/src/cmd/tools/m3ctl/yaml/db_create.proto similarity index 67% rename from src/cmd/tools/m3ctl/yaml/dbCreate.proto rename to src/cmd/tools/m3ctl/yaml/db_create.proto index 8c12db8072..5cca79a367 100644 --- a/src/cmd/tools/m3ctl/yaml/dbCreate.proto +++ b/src/cmd/tools/m3ctl/yaml/db_create.proto @@ -3,6 +3,6 @@ package yaml; import "github.com/m3db/m3/src/query/generated/proto/admin/database.proto"; message DatabaseCreateRequestYaml { - string Operation = 1; - admin.DatabaseCreateRequest Request = 2; -} \ No newline at end of file + string operation = 1; + admin.DatabaseCreateRequest request = 2; +} diff --git a/src/cmd/tools/m3ctl/yaml/examples/newNode.yaml b/src/cmd/tools/m3ctl/yaml/examples/new_node.yaml similarity index 100% rename from src/cmd/tools/m3ctl/yaml/examples/newNode.yaml rename to src/cmd/tools/m3ctl/yaml/examples/new_node.yaml diff --git a/src/cmd/tools/m3ctl/yaml/examples/replaceNode.yaml b/src/cmd/tools/m3ctl/yaml/examples/replace_node.yaml similarity index 100% rename from src/cmd/tools/m3ctl/yaml/examples/replaceNode.yaml rename to src/cmd/tools/m3ctl/yaml/examples/replace_node.yaml diff --git a/src/cmd/tools/m3ctl/yaml/generated/dbCreate.pb.go b/src/cmd/tools/m3ctl/yaml/generated/db_create.pb.go similarity index 100% rename from src/cmd/tools/m3ctl/yaml/generated/dbCreate.pb.go rename to src/cmd/tools/m3ctl/yaml/generated/db_create.pb.go diff --git a/src/cmd/tools/m3ctl/yaml/load.go b/src/cmd/tools/m3ctl/yaml/load.go index 68b80ae57f..7ec1ab2a15 100644 --- a/src/cmd/tools/m3ctl/yaml/load.go +++ b/src/cmd/tools/m3ctl/yaml/load.go @@ -1,3 +1,23 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package yaml import ( @@ -11,7 +31,7 @@ import ( "github.com/gogo/protobuf/proto" ) -// this reads a yaml representation of an m3 structure +// Load reads a yaml representation of an m3 structure // and produces an io.Reader of it protocol buffer-encoded // // we don't know anything about what the user it trying to do @@ -28,11 +48,11 @@ func Load(path string, zl *zap.Logger) (string, io.Reader, error) { if err != nil { return "", nil, err } - rv, err := _load(content, pbmessage) + rv, err := load(content, pbmessage) return url, rv, nil } -func _load(content []byte, target proto.Message) (io.Reader, error) { +func load(content []byte, target proto.Message) (io.Reader, error) { // unmarshal it into json if err := yaml.Unmarshal(content, target); err != nil { return nil, err diff --git a/src/cmd/tools/m3ctl/yaml/load_test.go b/src/cmd/tools/m3ctl/yaml/load_test.go index ebc4afb9e6..acd779b2e2 100644 --- a/src/cmd/tools/m3ctl/yaml/load_test.go +++ b/src/cmd/tools/m3ctl/yaml/load_test.go @@ -1,3 +1,23 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package yaml import ( @@ -8,18 +28,18 @@ import ( pb "github.com/m3db/m3/src/cmd/tools/m3ctl/yaml/generated" ) -// this uses _load to get an encoded stream of the +// this uses load to get an encoded stream of the // structure, then unmarshals it back into a struct // and verifies the unmarshalled struct matches // what was specified in the yaml func TestLoadBasic(t *testing.T) { - content, err := ioutil.ReadFile("./testdata/basicCreate.yaml") + content, err := ioutil.ReadFile("./testdata/basic_create.yaml") if err != nil { t.Fatalf("failed to read yaml test data:%v:\n", err) } // load the yaml and encode it source := pb.DatabaseCreateRequestYaml{} - data, err := _load(content, &source) + data, err := load(content, &source) if err != nil { t.Fatalf("failed to encode the basic test data:%v:\n", err) } diff --git a/src/cmd/tools/m3ctl/yaml/peeker.go b/src/cmd/tools/m3ctl/yaml/peeker.go index fa4c80cffa..84f09549a9 100644 --- a/src/cmd/tools/m3ctl/yaml/peeker.go +++ b/src/cmd/tools/m3ctl/yaml/peeker.go @@ -1,3 +1,23 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package yaml import ( diff --git a/src/cmd/tools/m3ctl/yaml/peeker_test.go b/src/cmd/tools/m3ctl/yaml/peeker_test.go index 84c8b954a4..863609436f 100644 --- a/src/cmd/tools/m3ctl/yaml/peeker_test.go +++ b/src/cmd/tools/m3ctl/yaml/peeker_test.go @@ -1,3 +1,23 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package yaml import ( @@ -9,7 +29,7 @@ import ( ) func TestPeekerPositive(t *testing.T) { - content, err := ioutil.ReadFile("./testdata/basicCreate.yaml") + content, err := ioutil.ReadFile("./testdata/basic_create.yaml") if err != nil { t.Fatalf("failed to read yaml test data:%v:\n", err) } @@ -20,7 +40,7 @@ func TestPeekerPositive(t *testing.T) { if urlpath != dbcreatePath { t.Errorf("urlpath is wrong:expected:%s:got:%s:\n", dbcreatePath, urlpath) } - data, err := _load(content, pbmessage) + data, err := load(content, pbmessage) if err != nil { t.Fatalf("failed to encode to protocol:%v:\n", err) } @@ -38,7 +58,7 @@ func TestPeekerPositive(t *testing.T) { } } func TestPeekerNegative(t *testing.T) { - content, err := ioutil.ReadFile("./testdata/unknownOperation.yaml") + content, err := ioutil.ReadFile("./testdata/unknown_operation.yaml") if err != nil { t.Fatalf("failed to read yaml test data:%v:\n", err) } diff --git a/src/cmd/tools/m3ctl/yaml/placement.proto b/src/cmd/tools/m3ctl/yaml/placement.proto index f4d4d9614b..bdf71f77eb 100644 --- a/src/cmd/tools/m3ctl/yaml/placement.proto +++ b/src/cmd/tools/m3ctl/yaml/placement.proto @@ -3,10 +3,10 @@ package yaml; import "github.com/m3db/m3/src/query/generated/proto/admin/placement.proto"; message PlacementInitRequestYaml { - string Operation = 1; - admin.PlacementInitRequest Request = 2; + string operation = 1; + admin.PlacementInitRequest request = 2; } message PlacementReplaceRequestYaml { - string Operation = 3; - admin.PlacementReplaceRequest Request = 4; + string operation = 3; + admin.PlacementReplaceRequest request = 4; } \ No newline at end of file diff --git a/src/cmd/tools/m3ctl/yaml/testdata/basicCreate.yaml b/src/cmd/tools/m3ctl/yaml/testdata/basic_create.yaml similarity index 100% rename from src/cmd/tools/m3ctl/yaml/testdata/basicCreate.yaml rename to src/cmd/tools/m3ctl/yaml/testdata/basic_create.yaml diff --git a/src/cmd/tools/m3ctl/yaml/testdata/unknownOperation.yaml b/src/cmd/tools/m3ctl/yaml/testdata/unknown_operation.yaml similarity index 93% rename from src/cmd/tools/m3ctl/yaml/testdata/unknownOperation.yaml rename to src/cmd/tools/m3ctl/yaml/testdata/unknown_operation.yaml index 2d2b3298b7..c721f32050 100644 --- a/src/cmd/tools/m3ctl/yaml/testdata/unknownOperation.yaml +++ b/src/cmd/tools/m3ctl/yaml/testdata/unknown_operation.yaml @@ -1,5 +1,5 @@ --- -operation: nonesuch +operation: unknown request: type: cluster namespace_name: default diff --git a/src/cmd/tools/m3ctl/yaml/types.go b/src/cmd/tools/m3ctl/yaml/types.go index 1fef5f541e..9a70a88e7a 100644 --- a/src/cmd/tools/m3ctl/yaml/types.go +++ b/src/cmd/tools/m3ctl/yaml/types.go @@ -1,3 +1,23 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package yaml const ( From e9835db1782390a2d6f22b52ea89eb404d64b57b Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Wed, 25 Mar 2020 14:52:15 -0700 Subject: [PATCH 57/65] go gmt and fix statusCode check --- src/cmd/tools/m3ctl/client/checker.go | 2 +- src/cmd/tools/m3ctl/main/main.go | 23 +++++++++++------------ src/cmd/tools/m3ctl/namespaces/types.go | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/cmd/tools/m3ctl/client/checker.go b/src/cmd/tools/m3ctl/client/checker.go index 3347f42a18..655ede4b0f 100644 --- a/src/cmd/tools/m3ctl/client/checker.go +++ b/src/cmd/tools/m3ctl/client/checker.go @@ -29,7 +29,7 @@ import ( ) func checkForAndHandleError(url string, resp *http.Response, zl *zap.Logger) error { - if resp.StatusCode%100 != 2 { + if resp.StatusCode/100 != 2 { dat, _ := ioutil.ReadAll(resp.Body) if dat != nil { zl.Error("error response", diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 90b43a58f9..176cdddb37 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -67,7 +67,7 @@ func main() { applyCmd := &cobra.Command{ Use: "apply", Short: "Apply various yamls to remote endpoint", - Long: `This will take specific yamls and send them over to the remote + Long: `This will take specific yamls and send them over to the remote endpoint. See the yaml/examples directory for examples. Operations such as database creation, database init, adding a node, and replacing a node, are supported. `, @@ -91,9 +91,9 @@ database creation, database init, adding a node, and replacing a node, are suppo } getNamespaceCmd := &cobra.Command{ - Use: "namespace []", - Short: "Get the namespaces from the remote endpoint", - Aliases: []string{"ns"}, + Use: "namespace []", + Short: "Get the namespaces from the remote endpoint", + Aliases: []string{"ns"}, Run: func(cmd *cobra.Command, args []string) { logger.Debug("running command", zap.String("command", cmd.Name())) @@ -106,9 +106,9 @@ database creation, database init, adding a node, and replacing a node, are suppo } getPlacementCmd := &cobra.Command{ - Use: "placement", - Short: "Get the placement from the remote endpoint", - Aliases: []string{"pl"}, + Use: "placement", + Short: "Get the placement from the remote endpoint", + Aliases: []string{"pl"}, Run: func(cmd *cobra.Command, args []string) { logger.Debug("running command", zap.String("command", cmd.Name())) @@ -121,8 +121,8 @@ database creation, database init, adding a node, and replacing a node, are suppo } deletePlacementCmd := &cobra.Command{ - Use: "placement", - Short: "Delete the placement from the remote endpoint", + Use: "placement", + Short: "Delete the placement from the remote endpoint", Aliases: []string{"pl"}, Run: func(cmd *cobra.Command, args []string) { @@ -135,10 +135,9 @@ database creation, database init, adding a node, and replacing a node, are suppo }, } - deleteNamespaceCmd := &cobra.Command{ - Use: "namespace", - Short: "Delete the namespace from the remote endpoint", + Use: "namespace", + Short: "Delete the namespace from the remote endpoint", Aliases: []string{"ns"}, Run: func(cmd *cobra.Command, args []string) { diff --git a/src/cmd/tools/m3ctl/namespaces/types.go b/src/cmd/tools/m3ctl/namespaces/types.go index c06a83756e..8046270391 100644 --- a/src/cmd/tools/m3ctl/namespaces/types.go +++ b/src/cmd/tools/m3ctl/namespaces/types.go @@ -24,5 +24,5 @@ const ( // DefaultPath is the default url path for the namespace api calls DefaultPath = "/api/v1/namespace" // DebugQS this is the query string to activate debug output in api responses - DebugQS = "debug=true" + DebugQS = "debug=true" ) From 79a68059fed663d7bac68c5b5bb2bf0a71ce67bc Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Wed, 25 Mar 2020 23:04:40 -0700 Subject: [PATCH 58/65] fix peeker test --- src/cmd/tools/m3ctl/main/main.go | 2 +- .../m3ctl/yaml/generated/db_create.pb.go | 37 +++++----- .../m3ctl/yaml/generated/placement.pb.go | 22 +++--- src/cmd/tools/m3ctl/yaml/load.go | 9 +-- src/cmd/tools/m3ctl/yaml/load_test.go | 70 ------------------- src/cmd/tools/m3ctl/yaml/peeker.go | 41 +++++++++-- src/cmd/tools/m3ctl/yaml/peeker_test.go | 24 +++++-- 7 files changed, 85 insertions(+), 120 deletions(-) delete mode 100644 src/cmd/tools/m3ctl/yaml/load_test.go diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 176cdddb37..41a7f8c41c 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -160,7 +160,7 @@ database creation, database init, adding a node, and replacing a node, are suppo applyCmd.Flags().StringVarP(&yamlPath, "file", "f", "", "times to echo the input") getNamespaceCmd.Flags().BoolVarP(&showAll, "showAll", "a", false, "times to echo the input") deletePlacementCmd.Flags().BoolVarP(&showAll, "deleteAll", "a", false, "delete the entire placement") - deleteCmd.PersistentFlags().StringVarP(&nodeName, "nodeName", "n", "", "which node to delete") + deleteCmd.PersistentFlags().StringVarP(&nodeName, "name", "n", "", "which namespace or node to delete") rootCmd.Execute() diff --git a/src/cmd/tools/m3ctl/yaml/generated/db_create.pb.go b/src/cmd/tools/m3ctl/yaml/generated/db_create.pb.go index 4eaa6bf306..2cd147d5b0 100644 --- a/src/cmd/tools/m3ctl/yaml/generated/db_create.pb.go +++ b/src/cmd/tools/m3ctl/yaml/generated/db_create.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-go. DO NOT EDIT. -// source: dbCreate.proto +// source: db_create.proto package yaml @@ -22,8 +22,8 @@ var _ = math.Inf const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type DatabaseCreateRequestYaml struct { - Operation string `protobuf:"bytes,1,opt,name=Operation,proto3" json:"Operation,omitempty"` - Request *admin.DatabaseCreateRequest `protobuf:"bytes,2,opt,name=Request,proto3" json:"Request,omitempty"` + Operation string `protobuf:"bytes,1,opt,name=operation,proto3" json:"operation,omitempty"` + Request *admin.DatabaseCreateRequest `protobuf:"bytes,2,opt,name=request,proto3" json:"request,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -33,7 +33,7 @@ func (m *DatabaseCreateRequestYaml) Reset() { *m = DatabaseCreateRequest func (m *DatabaseCreateRequestYaml) String() string { return proto.CompactTextString(m) } func (*DatabaseCreateRequestYaml) ProtoMessage() {} func (*DatabaseCreateRequestYaml) Descriptor() ([]byte, []int) { - return fileDescriptor_ac8e05fdfec588ce, []int{0} + return fileDescriptor_57e276f15713f139, []int{0} } func (m *DatabaseCreateRequestYaml) XXX_Unmarshal(b []byte) error { @@ -72,19 +72,20 @@ func init() { proto.RegisterType((*DatabaseCreateRequestYaml)(nil), "yaml.DatabaseCreateRequestYaml") } -func init() { proto.RegisterFile("dbCreate.proto", fileDescriptor_ac8e05fdfec588ce) } +func init() { proto.RegisterFile("db_create.proto", fileDescriptor_57e276f15713f139) } -var fileDescriptor_ac8e05fdfec588ce = []byte{ - // 174 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0x49, 0x72, 0x2e, - 0x4a, 0x4d, 0x2c, 0x49, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xa9, 0x4c, 0xcc, 0xcd, - 0x91, 0x72, 0x4c, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xcf, 0x35, 0x4e, - 0x49, 0xd2, 0xcf, 0x35, 0xd6, 0x2f, 0x2e, 0x4a, 0xd6, 0x2f, 0x2c, 0x4d, 0x2d, 0xaa, 0xd4, 0x4f, - 0x4f, 0xcd, 0x4b, 0x2d, 0x4a, 0x2c, 0x49, 0x4d, 0xd1, 0x07, 0xeb, 0xd1, 0x4f, 0x4c, 0xc9, 0xcd, - 0xcc, 0xd3, 0x4f, 0x49, 0x2c, 0x49, 0x4c, 0x4a, 0x2c, 0x86, 0x1a, 0xa4, 0x54, 0xc8, 0x25, 0xe9, - 0x02, 0x15, 0x81, 0x58, 0x10, 0x94, 0x5a, 0x58, 0x9a, 0x5a, 0x5c, 0x12, 0x99, 0x98, 0x9b, 0x23, - 0x24, 0xc3, 0xc5, 0xe9, 0x5f, 0x00, 0x32, 0x23, 0x33, 0x3f, 0x4f, 0x82, 0x51, 0x81, 0x51, 0x83, - 0x33, 0x08, 0x21, 0x20, 0x64, 0xc6, 0xc5, 0x0e, 0x55, 0x2c, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x6d, - 0x24, 0xa3, 0x07, 0xb6, 0x42, 0x0f, 0xab, 0x81, 0x41, 0x30, 0xc5, 0x49, 0x6c, 0x60, 0x9b, 0x8d, - 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x6d, 0xb1, 0x77, 0xc1, 0xd4, 0x00, 0x00, 0x00, +var fileDescriptor_57e276f15713f139 = []byte{ + // 177 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x8d, 0xb1, 0xca, 0xc2, 0x30, + 0x14, 0x46, 0xe9, 0xcf, 0x8f, 0xd2, 0x38, 0x08, 0x9d, 0xaa, 0x74, 0x28, 0x4e, 0x9d, 0x72, 0xc1, + 0x82, 0xbb, 0xe8, 0x13, 0x74, 0x73, 0x92, 0x9b, 0xe6, 0x52, 0x0b, 0x4d, 0xd3, 0xa6, 0x37, 0x43, + 0xdf, 0x5e, 0x8c, 0x15, 0x17, 0xd7, 0x8f, 0xf3, 0x9d, 0x23, 0xb6, 0x5a, 0xdd, 0x6b, 0x47, 0xc8, + 0x24, 0x07, 0x67, 0xd9, 0x26, 0xff, 0x33, 0x9a, 0x6e, 0x7f, 0x6e, 0x5a, 0x7e, 0x78, 0x25, 0x6b, + 0x6b, 0xc0, 0x94, 0x5a, 0x81, 0x29, 0x61, 0x72, 0x35, 0x8c, 0x9e, 0xdc, 0x0c, 0x0d, 0xf5, 0xe4, + 0x90, 0x49, 0x43, 0xf8, 0x00, 0x6a, 0xd3, 0xf6, 0xa0, 0x91, 0x51, 0xe1, 0xb4, 0x88, 0x0e, 0xa3, + 0xd8, 0x5d, 0x97, 0xe5, 0x12, 0x02, 0x15, 0x8d, 0x9e, 0x26, 0xbe, 0xa1, 0xe9, 0x92, 0x4c, 0xc4, + 0x76, 0x78, 0x39, 0x5a, 0xdb, 0xa7, 0x51, 0x1e, 0x15, 0x71, 0xf5, 0x1d, 0x92, 0x93, 0x58, 0xbb, + 0x37, 0x9c, 0xfe, 0xe5, 0x51, 0xb1, 0x39, 0x66, 0x32, 0x24, 0xe4, 0x4f, 0x61, 0xf5, 0x81, 0xd5, + 0x2a, 0x94, 0xcb, 0x67, 0x00, 0x00, 0x00, 0xff, 0xff, 0xbe, 0x30, 0x42, 0x7b, 0xd5, 0x00, 0x00, + 0x00, } diff --git a/src/cmd/tools/m3ctl/yaml/generated/placement.pb.go b/src/cmd/tools/m3ctl/yaml/generated/placement.pb.go index dce3e3eeac..3abcbf79de 100644 --- a/src/cmd/tools/m3ctl/yaml/generated/placement.pb.go +++ b/src/cmd/tools/m3ctl/yaml/generated/placement.pb.go @@ -22,8 +22,8 @@ var _ = math.Inf const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package type PlacementInitRequestYaml struct { - Operation string `protobuf:"bytes,1,opt,name=Operation,proto3" json:"Operation,omitempty"` - Request *admin.PlacementInitRequest `protobuf:"bytes,2,opt,name=Request,proto3" json:"Request,omitempty"` + Operation string `protobuf:"bytes,1,opt,name=operation,proto3" json:"operation,omitempty"` + Request *admin.PlacementInitRequest `protobuf:"bytes,2,opt,name=request,proto3" json:"request,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -69,8 +69,8 @@ func (m *PlacementInitRequestYaml) GetRequest() *admin.PlacementInitRequest { } type PlacementReplaceRequestYaml struct { - Operation string `protobuf:"bytes,3,opt,name=Operation,proto3" json:"Operation,omitempty"` - Request *admin.PlacementReplaceRequest `protobuf:"bytes,4,opt,name=Request,proto3" json:"Request,omitempty"` + Operation string `protobuf:"bytes,3,opt,name=operation,proto3" json:"operation,omitempty"` + Request *admin.PlacementReplaceRequest `protobuf:"bytes,4,opt,name=request,proto3" json:"request,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -123,18 +123,18 @@ func init() { func init() { proto.RegisterFile("placement.proto", fileDescriptor_ae0216eeb0d08e49) } var fileDescriptor_ae0216eeb0d08e49 = []byte{ - // 200 bytes of a gzipped FileDescriptorProto + // 201 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2f, 0xc8, 0x49, 0x4c, 0x4e, 0xcd, 0x4d, 0xcd, 0x2b, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xa9, 0x4c, 0xcc, 0xcd, 0x91, 0x72, 0x4a, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xcf, 0x35, 0x4e, 0x49, 0xd2, 0xcf, 0x35, 0xd6, 0x2f, 0x2e, 0x4a, 0xd6, 0x2f, 0x2c, 0x4d, 0x2d, 0xaa, 0xd4, 0x4f, 0x4f, 0xcd, 0x4b, 0x2d, 0x4a, 0x2c, 0x49, 0x4d, 0xd1, 0x07, 0xeb, 0xd1, 0x4f, 0x4c, 0xc9, 0xcd, 0xcc, 0xd3, 0x47, 0x33, 0x49, 0x29, 0x9f, 0x4b, 0x22, 0x00, 0x26, 0xe4, 0x99, 0x97, 0x59, - 0x12, 0x94, 0x5a, 0x58, 0x9a, 0x5a, 0x5c, 0x12, 0x99, 0x98, 0x9b, 0x23, 0x24, 0xc3, 0xc5, 0xe9, + 0x12, 0x94, 0x5a, 0x58, 0x9a, 0x5a, 0x5c, 0x12, 0x99, 0x98, 0x9b, 0x23, 0x24, 0xc3, 0xc5, 0x99, 0x5f, 0x00, 0x32, 0x23, 0x33, 0x3f, 0x4f, 0x82, 0x51, 0x81, 0x51, 0x83, 0x33, 0x08, 0x21, 0x20, - 0x64, 0xca, 0xc5, 0x0e, 0x55, 0x2c, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x6d, 0x24, 0xad, 0x07, 0xb6, - 0x42, 0x0f, 0x9b, 0x79, 0x41, 0x30, 0xb5, 0x4a, 0xa5, 0x5c, 0xd2, 0x70, 0x05, 0x41, 0xa9, 0x60, - 0xe7, 0xe0, 0xb4, 0x93, 0x19, 0xdd, 0x4e, 0x0b, 0x84, 0x9d, 0x2c, 0x60, 0x3b, 0xe5, 0xd0, 0xed, - 0x44, 0x35, 0x12, 0x6e, 0x6d, 0x12, 0x1b, 0xd8, 0xbb, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x34, 0x29, 0x78, 0x38, 0x4b, 0x01, 0x00, 0x00, + 0x64, 0xca, 0xc5, 0x5e, 0x04, 0x51, 0x2c, 0xc1, 0xa4, 0xc0, 0xa8, 0xc1, 0x6d, 0x24, 0xad, 0x07, + 0xb6, 0x42, 0x0f, 0x9b, 0x79, 0x41, 0x30, 0xb5, 0x4a, 0xa5, 0x5c, 0xd2, 0x70, 0x05, 0x41, 0xa9, + 0x60, 0xe7, 0xe0, 0xb4, 0x93, 0x19, 0xdd, 0x4e, 0x0b, 0x84, 0x9d, 0x2c, 0x60, 0x3b, 0xe5, 0xd0, + 0xed, 0x44, 0x35, 0x12, 0x6e, 0x6d, 0x12, 0x1b, 0xd8, 0xbb, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, + 0xff, 0x5e, 0x24, 0x27, 0x1e, 0x4b, 0x01, 0x00, 0x00, } diff --git a/src/cmd/tools/m3ctl/yaml/load.go b/src/cmd/tools/m3ctl/yaml/load.go index 7ec1ab2a15..34c93a05a9 100644 --- a/src/cmd/tools/m3ctl/yaml/load.go +++ b/src/cmd/tools/m3ctl/yaml/load.go @@ -26,7 +26,6 @@ import ( "io" "io/ioutil" - "github.com/ghodss/yaml" "github.com/gogo/protobuf/jsonpb" "github.com/gogo/protobuf/proto" ) @@ -48,15 +47,11 @@ func Load(path string, zl *zap.Logger) (string, io.Reader, error) { if err != nil { return "", nil, err } - rv, err := load(content, pbmessage) + rv, err := load(pbmessage) return url, rv, nil } -func load(content []byte, target proto.Message) (io.Reader, error) { - // unmarshal it into json - if err := yaml.Unmarshal(content, target); err != nil { - return nil, err - } +func load(target proto.Message) (io.Reader, error) { // marshal it into protocol buffers var data *bytes.Buffer data = bytes.NewBuffer(nil) diff --git a/src/cmd/tools/m3ctl/yaml/load_test.go b/src/cmd/tools/m3ctl/yaml/load_test.go deleted file mode 100644 index acd779b2e2..0000000000 --- a/src/cmd/tools/m3ctl/yaml/load_test.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2020 Uber Technologies, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package yaml - -import ( - "io/ioutil" - "testing" - - "github.com/gogo/protobuf/jsonpb" - pb "github.com/m3db/m3/src/cmd/tools/m3ctl/yaml/generated" -) - -// this uses load to get an encoded stream of the -// structure, then unmarshals it back into a struct -// and verifies the unmarshalled struct matches -// what was specified in the yaml -func TestLoadBasic(t *testing.T) { - content, err := ioutil.ReadFile("./testdata/basic_create.yaml") - if err != nil { - t.Fatalf("failed to read yaml test data:%v:\n", err) - } - // load the yaml and encode it - source := pb.DatabaseCreateRequestYaml{} - data, err := load(content, &source) - if err != nil { - t.Fatalf("failed to encode the basic test data:%v:\n", err) - } - dest := pb.DatabaseCreateRequestYaml{} - unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} - // unmarshal the stream back into a struct and verify it - if err := unmarshaller.Unmarshal(data, &dest); err != nil { - t.Fatalf("failed to unmarshal basic test data:%v:\n", err) - } - if dest.Operation != opCreate { - t.Errorf("dest type does not have the correct type:expected:%v:got:%v:", opCreate, dest.Operation) - } - if dest.Request.ReplicationFactor != 327 { - t.Errorf("in and out ReplicationFactor did not match:expected:%d:got:%d:\n", source.Request.ReplicationFactor, dest.Request.ReplicationFactor) - } - if dest.Request.ReplicationFactor != source.Request.ReplicationFactor { - t.Errorf("in and out ReplicationFactor did not match:expected:%d:got:%d:\n", source.Request.ReplicationFactor, dest.Request.ReplicationFactor) - } - if dest.Request.NamespaceName != "default" { - t.Errorf("namespace is wrong:expected:%s:got:%s:\n", "default", dest.Request.NamespaceName) - } - if len(dest.Request.Hosts) != 1 { - t.Errorf("number of hosts is wrong:expected:%d:got:%d:\n", 1, len(dest.Request.Hosts)) - } - if dest.Request.Hosts[0].Id != "m3db_seed" { - t.Errorf("hostname is wrong:expected:%s:got:%s:\n", "m3db_seed", dest.Request.Hosts[0]) - } -} diff --git a/src/cmd/tools/m3ctl/yaml/peeker.go b/src/cmd/tools/m3ctl/yaml/peeker.go index 84f09549a9..f32ab70d32 100644 --- a/src/cmd/tools/m3ctl/yaml/peeker.go +++ b/src/cmd/tools/m3ctl/yaml/peeker.go @@ -24,8 +24,9 @@ import ( "fmt" "github.com/ghodss/yaml" "github.com/gogo/protobuf/proto" + "github.com/m3db/m3/src/cmd/tools/m3ctl/placements" - pb "github.com/m3db/m3/src/cmd/tools/m3ctl/yaml/generated" + "github.com/m3db/m3/src/query/generated/proto/admin" ) // peek into the yaml to see what it is expected to be @@ -45,19 +46,47 @@ func peeker(data []byte) (string, proto.Message, error) { // no data is saved from this // nothing is returned from thie // its just a peek - // and then it returns other data depending on the reults of the peek + // and then it returns other data depending on the results of the peek if err := yaml.Unmarshal(data, &peek); err != nil { return "", nil, err } switch peek.Operation { case opCreate: - return dbcreatePath, &pb.DatabaseCreateRequestYaml{}, nil + q := struct { + Request admin.DatabaseCreateRequest + }{} + if err := yaml.Unmarshal(data, &q); err != nil { + return "", nil, err + } + pb := q.Request + return dbcreatePath, &pb, nil case opInit: - return fmt.Sprintf("%s/init", placements.DefaultPath), &pb.PlacementInitRequestYaml{}, nil + q := struct { + Request admin.PlacementInitRequest + }{} + if err := yaml.Unmarshal(data, &q); err != nil { + return "", nil, err + } + pb := q.Request + return fmt.Sprintf("%s/init", placements.DefaultPath), &pb, nil case opReplace: - return fmt.Sprintf("%s/replace", placements.DefaultPath), &pb.PlacementReplaceRequestYaml{}, nil + q := struct { + Request admin.PlacementReplaceRequest + }{} + if err := yaml.Unmarshal(data, &q); err != nil { + return "", nil, err + } + pb := q.Request + return fmt.Sprintf("%s/replace", placements.DefaultPath), &pb, nil case opNewNode: - return fmt.Sprintf("%s", placements.DefaultPath), &pb.PlacementInitRequestYaml{}, nil + q := struct { + Request admin.PlacementInitRequest + }{} + if err := yaml.Unmarshal(data, &q); err != nil { + return "", nil, err + } + pb := q.Request + return fmt.Sprintf("%s", placements.DefaultPath), &pb, nil default: return "", nil, fmt.Errorf("Unknown operation specified in the yaml\n") } diff --git a/src/cmd/tools/m3ctl/yaml/peeker_test.go b/src/cmd/tools/m3ctl/yaml/peeker_test.go index 863609436f..f822b4cb4e 100644 --- a/src/cmd/tools/m3ctl/yaml/peeker_test.go +++ b/src/cmd/tools/m3ctl/yaml/peeker_test.go @@ -21,11 +21,12 @@ package yaml import ( - pb "github.com/m3db/m3/src/cmd/tools/m3ctl/yaml/generated" "io/ioutil" "testing" "github.com/gogo/protobuf/jsonpb" + + "github.com/m3db/m3/src/query/generated/proto/admin" ) func TestPeekerPositive(t *testing.T) { @@ -40,21 +41,30 @@ func TestPeekerPositive(t *testing.T) { if urlpath != dbcreatePath { t.Errorf("urlpath is wrong:expected:%s:got:%s:\n", dbcreatePath, urlpath) } - data, err := load(content, pbmessage) + data, err := load(pbmessage) if err != nil { t.Fatalf("failed to encode to protocol:%v:\n", err) } - dest := pb.DatabaseCreateRequestYaml{} + var dest admin.DatabaseCreateRequest unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} if err := unmarshaller.Unmarshal(data, &dest); err != nil { t.Fatalf("operation selector failed to unmarshal unknown operation data:%v:\n", err) } t.Logf("dest:%v:\n", dest) - if dest.Request.NamespaceName != "default" { - t.Errorf("dest NamespaceName does not have the correct value via operation:expected:%v:got:%v:", opCreate, dest.Request.NamespaceName) + if dest.NamespaceName != "default" { + t.Errorf("dest NamespaceName does not have the correct value via operation:expected:%v:got:%v:", opCreate, dest.NamespaceName) + } + if dest.Type != "cluster" { + t.Errorf("dest type does not have the correct value via operation:expected:%v:got:%v:", opCreate, dest.Type) + } + if dest.ReplicationFactor != 327 { + t.Errorf("in and out ReplicationFactor did not match:expected:%d:got:%d:\n", 327, dest.ReplicationFactor) + } + if len(dest.Hosts) != 1 { + t.Errorf("number of hosts is wrong:expected:%d:got:%d:\n", 1, len(dest.Hosts)) } - if dest.Request.Type != "cluster" { - t.Errorf("dest type does not have the correct value via operation:expected:%v:got:%v:", opCreate, dest.Request.Type) + if dest.Hosts[0].Id != "m3db_seed" { + t.Errorf("hostname is wrong:expected:%s:got:%s:\n", "m3db_seed", dest.Hosts[0]) } } func TestPeekerNegative(t *testing.T) { From e0caad999c53c3aba3e5e1f10967dd96324979c6 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Wed, 25 Mar 2020 23:23:14 -0700 Subject: [PATCH 59/65] fix example yamls which didnt match the tests --- src/cmd/tools/m3ctl/yaml/examples/create.yaml | 49 ++++++++++--------- .../tools/m3ctl/yaml/examples/develdb.yaml | 27 +++++----- src/cmd/tools/m3ctl/yaml/examples/init.yaml | 49 ++++++++++--------- .../tools/m3ctl/yaml/examples/new_node.yaml | 18 +++---- .../m3ctl/yaml/examples/replace_node.yaml | 21 ++++---- 5 files changed, 84 insertions(+), 80 deletions(-) diff --git a/src/cmd/tools/m3ctl/yaml/examples/create.yaml b/src/cmd/tools/m3ctl/yaml/examples/create.yaml index f4b33ceb18..0d53cbfe82 100644 --- a/src/cmd/tools/m3ctl/yaml/examples/create.yaml +++ b/src/cmd/tools/m3ctl/yaml/examples/create.yaml @@ -1,27 +1,28 @@ --- operation: create -type: cluster -namespace_name: 1week_namespace -retention_time: 168h -num_shards: 1024 -replication_factor: 3 -hosts: -- id: m3db001 - isolationGroup: us-east1-a - zone: embedded - weight: 100 - address: 10.142.0.1 - port: 9000 -- id: m3db002 - isolationGroup: us-east1-b - zone: embedded - weight: 100 - address: 10.142.0.2 - port: 9000 -- id: m3db003 - isolationGroup: us-east1-c - zone: embedded - weight: 100 - address: 10.142.0.3 - port: 9000 +request: + type: cluster + namespace_name: 1week_namespace + retention_time: 168h + num_shards: 1024 + replication_factor: 3 + hosts: + - id: m3db001 + isolationGroup: us-east1-a + zone: embedded + weight: 100 + address: 10.142.0.1 + port: 9000 + - id: m3db002 + isolationGroup: us-east1-b + zone: embedded + weight: 100 + address: 10.142.0.2 + port: 9000 + - id: m3db003 + isolationGroup: us-east1-c + zone: embedded + weight: 100 + address: 10.142.0.3 + port: 9000 diff --git a/src/cmd/tools/m3ctl/yaml/examples/develdb.yaml b/src/cmd/tools/m3ctl/yaml/examples/develdb.yaml index c324320c12..6b7d774d9e 100644 --- a/src/cmd/tools/m3ctl/yaml/examples/develdb.yaml +++ b/src/cmd/tools/m3ctl/yaml/examples/develdb.yaml @@ -1,16 +1,17 @@ --- operation: create -type: cluster -namespace_name: default -retention_time: 168h -num_shards: 64 -replication_factor: 1 -hosts: -- id: m3db_seed - isolation_group: rack-a - zone: embedded - weight: 1024 - endpoint: m3db_seed:9000 - hostname: m3db_seed - port: 9000 +request: + type: cluster + namespace_name: default + retention_time: 168h + num_shards: 64 + replication_factor: 1 + hosts: + - id: m3db_seed + isolation_group: rack-a + zone: embedded + weight: 1024 + endpoint: m3db_seed:9000 + hostname: m3db_seed + port: 9000 diff --git a/src/cmd/tools/m3ctl/yaml/examples/init.yaml b/src/cmd/tools/m3ctl/yaml/examples/init.yaml index cff7140666..f86723c266 100644 --- a/src/cmd/tools/m3ctl/yaml/examples/init.yaml +++ b/src/cmd/tools/m3ctl/yaml/examples/init.yaml @@ -1,26 +1,27 @@ --- operation: init -num_shards: 64 -replication_factor: 1 -instances: - - id: nodeid1 - isolation_group: isogroup1 - zone: etcd1 - weight: 100 - endpoint: node1:9000 - hostname: node1 - port: 9000 - - id: nodeid2 - isolation_group: isogroup2 - zone: etcd1 - weight: 100 - endpoint: node2:9000 - hostname: node2 - port: 9000 - - id: nodeid3 - isolation_group: isogroup3 - zone: etcd1 - weight: 100 - endpoint: node3:9000 - hostname: node3 - port: 9000 +request: + num_shards: 64 + replication_factor: 1 + instances: + - id: nodeid1 + isolation_group: isogroup1 + zone: etcd1 + weight: 100 + endpoint: node1:9000 + hostname: node1 + port: 9000 + - id: nodeid2 + isolation_group: isogroup2 + zone: etcd1 + weight: 100 + endpoint: node2:9000 + hostname: node2 + port: 9000 + - id: nodeid3 + isolation_group: isogroup3 + zone: etcd1 + weight: 100 + endpoint: node3:9000 + hostname: node3 + port: 9000 \ No newline at end of file diff --git a/src/cmd/tools/m3ctl/yaml/examples/new_node.yaml b/src/cmd/tools/m3ctl/yaml/examples/new_node.yaml index 8e735a4080..abdccf73bd 100644 --- a/src/cmd/tools/m3ctl/yaml/examples/new_node.yaml +++ b/src/cmd/tools/m3ctl/yaml/examples/new_node.yaml @@ -1,11 +1,11 @@ --- operation: newNode -instances: - - id: node1 - isolationGroup: isoGroup1 - zone: embedded - weight: 100 - endpoint: targetHostname1:9000 - hostname: newNodeHostname1 - port: 9000 - +request: + instances: + - id: node1 + isolationGroup: isoGroup1 + zone: embedded + weight: 100 + endpoint: targetHostname1:9000 + hostname: newNodeHostname1 + port: 9000 \ No newline at end of file diff --git a/src/cmd/tools/m3ctl/yaml/examples/replace_node.yaml b/src/cmd/tools/m3ctl/yaml/examples/replace_node.yaml index 102b90f3ee..37ee51120a 100644 --- a/src/cmd/tools/m3ctl/yaml/examples/replace_node.yaml +++ b/src/cmd/tools/m3ctl/yaml/examples/replace_node.yaml @@ -1,13 +1,14 @@ --- operation: replaceNode -leavingInstanceIDs: -- oldnodeid1 -candidates: -- id: newnodeid1 - isolationGroup: newnodeisogroup1 - zone: etcdzone1 - weight: 100 - endpoint: node11:9000 - hostname: node11 - port: 9000 +request: + leavingInstanceIDs: + - oldnodeid1 + candidates: + - id: newnodeid1 + isolationGroup: newnodeisogroup1 + zone: etcdzone1 + weight: 100 + endpoint: node11:9000 + hostname: node11 + port: 9000 From 02a952a466c190875c175c0c2d9b2e676b399563 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Thu, 26 Mar 2020 09:56:34 -0700 Subject: [PATCH 60/65] clean it up a bit --- src/cmd/tools/m3ctl/yaml/peeker.go | 47 ++++++++++-------------------- 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/src/cmd/tools/m3ctl/yaml/peeker.go b/src/cmd/tools/m3ctl/yaml/peeker.go index f32ab70d32..60c3f7fc3c 100644 --- a/src/cmd/tools/m3ctl/yaml/peeker.go +++ b/src/cmd/tools/m3ctl/yaml/peeker.go @@ -24,15 +24,13 @@ import ( "fmt" "github.com/ghodss/yaml" "github.com/gogo/protobuf/proto" - "github.com/m3db/m3/src/cmd/tools/m3ctl/placements" + + //"github.com/m3db/m3/src/cmd/tools/m3ctl/placements" "github.com/m3db/m3/src/query/generated/proto/admin" ) // peek into the yaml to see what it is expected to be -// don't try to decode the entire thing since its -// going into something that's currently unknown -// so just grab the "operation" then dispatch // // returns the url path, proto.Message, and error func peeker(data []byte) (string, proto.Message, error) { @@ -43,51 +41,38 @@ func peeker(data []byte) (string, proto.Message, error) { // this really does nothing more than unpack into the above // private type to take a peek at Operation - // no data is saved from this - // nothing is returned from thie // its just a peek - // and then it returns other data depending on the results of the peek if err := yaml.Unmarshal(data, &peek); err != nil { return "", nil, err } + switch peek.Operation { case opCreate: - q := struct { - Request admin.DatabaseCreateRequest - }{} - if err := yaml.Unmarshal(data, &q); err != nil { + payload := struct {Request admin.DatabaseCreateRequest}{} + if err := yaml.Unmarshal(data, &payload); err != nil { return "", nil, err } - pb := q.Request - return dbcreatePath, &pb, nil + return dbcreatePath, &payload.Request, nil case opInit: - q := struct { - Request admin.PlacementInitRequest - }{} - if err := yaml.Unmarshal(data, &q); err != nil { + payload := struct {Request admin.PlacementInitRequest}{} + if err := yaml.Unmarshal(data, &payload); err != nil { return "", nil, err } - pb := q.Request - return fmt.Sprintf("%s/init", placements.DefaultPath), &pb, nil + return fmt.Sprintf("%s/init", placements.DefaultPath), &payload.Request, nil case opReplace: - q := struct { - Request admin.PlacementReplaceRequest - }{} - if err := yaml.Unmarshal(data, &q); err != nil { + payload := struct {Request admin.PlacementReplaceRequest}{} + if err := yaml.Unmarshal(data, &payload); err != nil { return "", nil, err } - pb := q.Request - return fmt.Sprintf("%s/replace", placements.DefaultPath), &pb, nil + return fmt.Sprintf("%s/replace", placements.DefaultPath), &payload.Request, nil case opNewNode: - q := struct { - Request admin.PlacementInitRequest - }{} - if err := yaml.Unmarshal(data, &q); err != nil { + payload := struct {Request admin.PlacementInitRequest}{} + if err := yaml.Unmarshal(data, &payload); err != nil { return "", nil, err } - pb := q.Request - return fmt.Sprintf("%s", placements.DefaultPath), &pb, nil + return fmt.Sprintf("%s", placements.DefaultPath), &payload.Request, nil default: return "", nil, fmt.Errorf("Unknown operation specified in the yaml\n") } + } From fcafd1188dd4e0e54bcfee1a6d21191ee815b718 Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Thu, 26 Mar 2020 09:57:02 -0700 Subject: [PATCH 61/65] go fmt --- src/cmd/tools/m3ctl/yaml/peeker.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cmd/tools/m3ctl/yaml/peeker.go b/src/cmd/tools/m3ctl/yaml/peeker.go index 60c3f7fc3c..3a84e427a3 100644 --- a/src/cmd/tools/m3ctl/yaml/peeker.go +++ b/src/cmd/tools/m3ctl/yaml/peeker.go @@ -48,25 +48,25 @@ func peeker(data []byte) (string, proto.Message, error) { switch peek.Operation { case opCreate: - payload := struct {Request admin.DatabaseCreateRequest}{} + payload := struct{ Request admin.DatabaseCreateRequest }{} if err := yaml.Unmarshal(data, &payload); err != nil { return "", nil, err } return dbcreatePath, &payload.Request, nil case opInit: - payload := struct {Request admin.PlacementInitRequest}{} + payload := struct{ Request admin.PlacementInitRequest }{} if err := yaml.Unmarshal(data, &payload); err != nil { return "", nil, err } return fmt.Sprintf("%s/init", placements.DefaultPath), &payload.Request, nil case opReplace: - payload := struct {Request admin.PlacementReplaceRequest}{} + payload := struct{ Request admin.PlacementReplaceRequest }{} if err := yaml.Unmarshal(data, &payload); err != nil { return "", nil, err } return fmt.Sprintf("%s/replace", placements.DefaultPath), &payload.Request, nil case opNewNode: - payload := struct {Request admin.PlacementInitRequest}{} + payload := struct{ Request admin.PlacementInitRequest }{} if err := yaml.Unmarshal(data, &payload); err != nil { return "", nil, err } From 0a613b2202305a7e5031d37ee5ac04e74223457d Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Thu, 26 Mar 2020 10:03:24 -0700 Subject: [PATCH 62/65] tiny cleanup --- src/cmd/tools/m3ctl/yaml/peeker.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/cmd/tools/m3ctl/yaml/peeker.go b/src/cmd/tools/m3ctl/yaml/peeker.go index 3a84e427a3..94699e523c 100644 --- a/src/cmd/tools/m3ctl/yaml/peeker.go +++ b/src/cmd/tools/m3ctl/yaml/peeker.go @@ -22,11 +22,11 @@ package yaml import ( "fmt" + "github.com/ghodss/yaml" "github.com/gogo/protobuf/proto" - "github.com/m3db/m3/src/cmd/tools/m3ctl/placements" - //"github.com/m3db/m3/src/cmd/tools/m3ctl/placements" + "github.com/m3db/m3/src/cmd/tools/m3ctl/placements" "github.com/m3db/m3/src/query/generated/proto/admin" ) @@ -46,6 +46,8 @@ func peeker(data []byte) (string, proto.Message, error) { return "", nil, err } + // now the payload is of known type + // unmarshal it and return the proto.Message switch peek.Operation { case opCreate: payload := struct{ Request admin.DatabaseCreateRequest }{} From 0a6e31842bfb89a435b339cb0459ae08144b14fc Mon Sep 17 00:00:00 2001 From: Brian McQueen Date: Tue, 7 Apr 2020 10:19:09 -0700 Subject: [PATCH 63/65] fixed nil data case in checkForAndHandleError error log line --- src/cmd/tools/m3ctl/client/checker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd/tools/m3ctl/client/checker.go b/src/cmd/tools/m3ctl/client/checker.go index 655ede4b0f..001ef17ecc 100644 --- a/src/cmd/tools/m3ctl/client/checker.go +++ b/src/cmd/tools/m3ctl/client/checker.go @@ -40,7 +40,7 @@ func checkForAndHandleError(url string, resp *http.Response, zl *zap.Logger) err zl.Error("error response", zap.Error(fmt.Errorf("status %d", resp.StatusCode)), zap.String("url", url), - zap.ByteString("response", dat)) + zap.String("response", "not available")) } return fmt.Errorf("error from m3db status=%s, url=%s\n", resp.Status, url) } From c654e4451ddfbac13464dd1c284a2fa25fd876f6 Mon Sep 17 00:00:00 2001 From: Rob Skillington Date: Tue, 14 Apr 2020 17:32:51 -0400 Subject: [PATCH 64/65] Address feedback --- .fossa.yml | 6 +- Makefile | 2 +- .../{m3ctl => r2ctl}/config/config.go | 0 .../{m3ctl => r2ctl}/config/server.go | 0 .../services/{m3ctl => r2ctl}/main/main.go | 2 +- src/cmd/tools/m3ctl/apply/apply.go | 12 +- src/cmd/tools/m3ctl/client/checker.go | 10 +- src/cmd/tools/m3ctl/client/http.go | 87 ++++++---- src/cmd/tools/m3ctl/main/main.go | 154 ++++++++++++++---- src/cmd/tools/m3ctl/namespaces/delete.go | 9 +- src/cmd/tools/m3ctl/namespaces/get.go | 29 +--- src/cmd/tools/m3ctl/placements/delete.go | 14 +- src/cmd/tools/m3ctl/placements/get.go | 10 +- .../m3ctl/yaml/generated/db_create.pb.go | 23 ++- .../m3ctl/yaml/generated/placement.pb.go | 23 ++- src/ctl/public/r2/v1/swagger/swagger.json | 2 +- 16 files changed, 270 insertions(+), 113 deletions(-) rename src/cmd/services/{m3ctl => r2ctl}/config/config.go (100%) rename src/cmd/services/{m3ctl => r2ctl}/config/server.go (100%) rename src/cmd/services/{m3ctl => r2ctl}/main/main.go (99%) diff --git a/.fossa.yml b/.fossa.yml index f495e83c0a..45a9f148c6 100755 --- a/.fossa.yml +++ b/.fossa.yml @@ -42,10 +42,10 @@ analyze: path: src/cmd/services/m3coordinator/main options: allow-unresolved: true - - name: github.com/m3db/m3/src/cmd/services/m3ctl/main + - name: github.com/m3db/m3/src/cmd/services/r2ctl/main type: go - target: github.com/m3db/m3/src/cmd/services/m3ctl/main - path: src/cmd/services/m3ctl/main + target: github.com/m3db/m3/src/cmd/services/r2ctl/main + path: src/cmd/services/r2ctl/main options: allow-unresolved: true - name: github.com/m3db/m3/src/cmd/services/m3dbnode/main diff --git a/Makefile b/Makefile index 1c93e201a6..947093fb42 100644 --- a/Makefile +++ b/Makefile @@ -61,11 +61,11 @@ SERVICES := \ m3aggregator \ m3query \ m3collector \ - m3ctl \ m3em_agent \ m3nsch_server \ m3nsch_client \ m3comparator \ + r2ctl \ SUBDIRS := \ x \ diff --git a/src/cmd/services/m3ctl/config/config.go b/src/cmd/services/r2ctl/config/config.go similarity index 100% rename from src/cmd/services/m3ctl/config/config.go rename to src/cmd/services/r2ctl/config/config.go diff --git a/src/cmd/services/m3ctl/config/server.go b/src/cmd/services/r2ctl/config/server.go similarity index 100% rename from src/cmd/services/m3ctl/config/server.go rename to src/cmd/services/r2ctl/config/server.go diff --git a/src/cmd/services/m3ctl/main/main.go b/src/cmd/services/r2ctl/main/main.go similarity index 99% rename from src/cmd/services/m3ctl/main/main.go rename to src/cmd/services/r2ctl/main/main.go index 40fe8e1332..7ad9973fc8 100644 --- a/src/cmd/services/m3ctl/main/main.go +++ b/src/cmd/services/r2ctl/main/main.go @@ -29,7 +29,7 @@ import ( "syscall" "time" - "github.com/m3db/m3/src/cmd/services/m3ctl/config" + "github.com/m3db/m3/src/cmd/services/r2ctl/config" "github.com/m3db/m3/src/ctl/auth" "github.com/m3db/m3/src/ctl/server/http" "github.com/m3db/m3/src/ctl/service/health" diff --git a/src/cmd/tools/m3ctl/apply/apply.go b/src/cmd/tools/m3ctl/apply/apply.go index 0f52f11efc..235020b423 100644 --- a/src/cmd/tools/m3ctl/apply/apply.go +++ b/src/cmd/tools/m3ctl/apply/apply.go @@ -22,6 +22,7 @@ package apply import ( "fmt" + "go.uber.org/zap" "github.com/m3db/m3/src/cmd/tools/m3ctl/client" @@ -31,11 +32,16 @@ import ( // DoApply does the API call to handle the kubectl apply command // It looks at the yaml, figures out what kind of API call to make // Sends it all off to the API -func DoApply(endpoint string, filepath string, logger *zap.Logger) error { +func DoApply( + endpoint string, + headers map[string]string, + filepath string, + logger *zap.Logger, +) ([]byte, error) { path, data, err := yaml.Load(filepath, logger) if err != nil { - return err + return nil, err } url := fmt.Sprintf("%s%s", endpoint, path) - return client.DoPost(url, data, client.Dumper, logger) + return client.DoPost(url, headers, data, logger) } diff --git a/src/cmd/tools/m3ctl/client/checker.go b/src/cmd/tools/m3ctl/client/checker.go index 001ef17ecc..c9bbabf79d 100644 --- a/src/cmd/tools/m3ctl/client/checker.go +++ b/src/cmd/tools/m3ctl/client/checker.go @@ -30,19 +30,19 @@ import ( func checkForAndHandleError(url string, resp *http.Response, zl *zap.Logger) error { if resp.StatusCode/100 != 2 { - dat, _ := ioutil.ReadAll(resp.Body) - if dat != nil { + body, err := ioutil.ReadAll(resp.Body) + if err == nil { zl.Error("error response", zap.Error(fmt.Errorf("status %d", resp.StatusCode)), zap.String("url", url), - zap.ByteString("response", dat)) + zap.ByteString("response", body)) } else { zl.Error("error response", zap.Error(fmt.Errorf("status %d", resp.StatusCode)), zap.String("url", url), - zap.String("response", "not available")) + zap.Error(fmt.Errorf("response not available: %v", err))) } - return fmt.Errorf("error from m3db status=%s, url=%s\n", resp.Status, url) + return fmt.Errorf("error response: status=%s, url=%s", resp.Status, url) } return nil } diff --git a/src/cmd/tools/m3ctl/client/http.go b/src/cmd/tools/m3ctl/client/http.go index 96b117006b..fa617a591d 100644 --- a/src/cmd/tools/m3ctl/client/http.go +++ b/src/cmd/tools/m3ctl/client/http.go @@ -21,7 +21,6 @@ package client import ( - "fmt" "io" "io/ioutil" "net/http" @@ -32,76 +31,100 @@ import ( const timeout = time.Duration(5 * time.Second) -// DoGet is the low level call to the backend api for gets -func DoGet(url string, getter func(reader io.Reader, zl *zap.Logger) error, zl *zap.Logger) error { - zl.Info("request", zap.String("method", "get"), zap.String("url", url)) +// DoGet is the low level call to the backend api for gets. +func DoGet( + url string, + headers map[string]string, + l *zap.Logger, +) ([]byte, error) { + l.Info("request", zap.String("method", "get"), zap.String("url", url)) client := http.Client{ Timeout: timeout, } - resp, err := client.Get(url) + req, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { - return err + return nil, err + } + + setHeadersWithDefaults(req, headers) + resp, err := client.Do(req) + if err != nil { + return nil, err } defer func() { ioutil.ReadAll(resp.Body) resp.Body.Close() }() - if err := checkForAndHandleError(url, resp, zl); err != nil { - return err + if err := checkForAndHandleError(url, resp, l); err != nil { + return nil, err } - return getter(resp.Body, zl) + return ioutil.ReadAll(resp.Body) } -// DoPost is the low level call to the backend api for posts -func DoPost(url string, data io.Reader, getter func(reader io.Reader, zl *zap.Logger) error, zl *zap.Logger) error { - zl.Info("request", zap.String("method", "post"), zap.String("url", url)) +// DoPost is the low level call to the backend api for posts. +func DoPost( + url string, + headers map[string]string, + data io.Reader, + l *zap.Logger, +) ([]byte, error) { + l.Info("request", zap.String("method", "post"), zap.String("url", url)) client := &http.Client{ Timeout: timeout, } req, err := http.NewRequest(http.MethodPost, url, data) - req.Header.Add("Content-Type", "application/json") + if err != nil { + return nil, err + } + + setHeadersWithDefaults(req, headers) resp, err := client.Do(req) if err != nil { - return err + return nil, err } defer func() { ioutil.ReadAll(resp.Body) resp.Body.Close() }() - if err := checkForAndHandleError(url, resp, zl); err != nil { - return err + if err := checkForAndHandleError(url, resp, l); err != nil { + return nil, err } - return getter(resp.Body, zl) + return ioutil.ReadAll(resp.Body) } -// DoDelete is the low level call to the backend api for deletes -func DoDelete(url string, getter func(reader io.Reader, zl *zap.Logger) error, zl *zap.Logger) error { - zl.Info("request", zap.String("method", "delete"), zap.String("url", url)) +// DoDelete is the low level call to the backend api for deletes. +func DoDelete( + url string, + headers map[string]string, + l *zap.Logger, +) ([]byte, error) { + l.Info("request", zap.String("method", "delete"), zap.String("url", url)) client := &http.Client{ Timeout: timeout, } req, err := http.NewRequest(http.MethodDelete, url, nil) - req.Header.Add("Content-Type", "application/json") + if err != nil { + return nil, err + } + + setHeadersWithDefaults(req, headers) resp, err := client.Do(req) if err != nil { - return err + return nil, err } defer func() { ioutil.ReadAll(resp.Body) resp.Body.Close() }() - if err := checkForAndHandleError(url, resp, zl); err != nil { - return err + if err := checkForAndHandleError(url, resp, l); err != nil { + return nil, err } - return getter(resp.Body, zl) + return ioutil.ReadAll(resp.Body) } -// Dumper is a simple printer for http responses -func Dumper(in io.Reader, zl *zap.Logger) error { - dat, err := ioutil.ReadAll(in) - if err != nil { - return err +func setHeadersWithDefaults(req *http.Request, headers map[string]string) { + req.Header.Set("Content-Type", "application/json") + for k, v := range headers { + req.Header.Set(k, v) } - fmt.Println(string(dat)) - return nil } diff --git a/src/cmd/tools/m3ctl/main/main.go b/src/cmd/tools/m3ctl/main/main.go index 41a7f8c41c..875ffb0e1d 100644 --- a/src/cmd/tools/m3ctl/main/main.go +++ b/src/cmd/tools/m3ctl/main/main.go @@ -21,35 +21,71 @@ package main import ( + "bytes" + "encoding/json" "fmt" "os" + "strings" "github.com/m3db/m3/src/cmd/tools/m3ctl/apply" "github.com/m3db/m3/src/cmd/tools/m3ctl/namespaces" "github.com/m3db/m3/src/cmd/tools/m3ctl/placements" + "github.com/m3db/m3/src/query/generated/proto/admin" + + "github.com/gogo/protobuf/jsonpb" "github.com/spf13/cobra" "go.uber.org/zap" + "go.uber.org/zap/zapcore" ) const ( - DefaultEndpoint = "http://localhost:7201" + defaultEndpoint = "http://localhost:7201" ) -var ( - endPoint string - yamlPath string - showAll bool - nodeName string -) +// Defaults are (so output is easily consumable by JSON tools like "jq"). +// - Error log level so usually not printing anything unless error encountered +// so the output can be completely JSON. +// - Do not print log stack traces so errors aren't overwhelming output. +var defaultLoggerOptions = loggerOptions{ + level: zapcore.ErrorLevel, + enableStacktrace: false, +} -func main() { +type loggerOptions struct { + level zapcore.Level + enableStacktrace bool +} - logger, err := zap.NewDevelopment() +func mustNewLogger(opts loggerOptions) *zap.Logger { + loggerCfg := zap.NewDevelopmentConfig() + loggerCfg.Level = zap.NewAtomicLevelAt(opts.level) + loggerCfg.DisableStacktrace = !opts.enableStacktrace + logger, err := loggerCfg.Build() if err != nil { fmt.Fprintf(os.Stderr, err.Error()) os.Exit(1) } + return logger +} + +func main() { + var ( + debug bool + endPoint string + headers = make(map[string]string) + yamlPath string + showAll bool + deleteAll bool + nodeName string + ) + + logger := mustNewLogger(defaultLoggerOptions) + defer func() { + logger.Sync() + fmt.Printf("\n") // End line since most commands finish without an endpoint. + }() + rootCmd := &cobra.Command{ Use: "cobra", } @@ -72,21 +108,19 @@ endpoint. See the yaml/examples directory for examples. Operations such as database creation, database init, adding a node, and replacing a node, are supported. `, Run: func(cmd *cobra.Command, args []string) { - fileArg := cmd.LocalFlags().Lookup("file").Value.String() logger.Debug("running command", zap.String("name", cmd.Name()), zap.String("args", fileArg)) if len(fileArg) == 0 { - logger.Error("specify a path to a yaml file.\n") - cmd.Usage() - os.Exit(1) + logger.Fatal("need to specify a path to YAML file") } - if err := apply.DoApply(endPoint, yamlPath, logger); err != nil { - logger.Error("apply failed", zap.Error(err)) - os.Exit(1) + resp, err := apply.DoApply(endPoint, headers, yamlPath, logger) + if err != nil { + logger.Fatal("apply failed", zap.Error(err)) } + os.Stdout.Write(resp) }, } @@ -95,13 +129,32 @@ database creation, database init, adding a node, and replacing a node, are suppo Short: "Get the namespaces from the remote endpoint", Aliases: []string{"ns"}, Run: func(cmd *cobra.Command, args []string) { - logger.Debug("running command", zap.String("command", cmd.Name())) - if err := namespaces.DoGet(endPoint, showAll, logger); err != nil { - logger.Error("get namespace failed", zap.Error(err)) - os.Exit(1) + resp, err := namespaces.DoGet(endPoint, headers, logger) + if err != nil { + logger.Fatal("get namespace failed", zap.Error(err)) + } + + if !showAll { + var registry admin.NamespaceGetResponse + unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} + reader := bytes.NewReader(resp) + if err := unmarshaller.Unmarshal(reader, ®istry); err != nil { + logger.Fatal("could not unmarshal response", zap.Error(err)) + } + var namespaces []string + for k := range registry.Registry.Namespaces { + namespaces = append(namespaces, k) + } + // Keep output consistent and output JSON. + if err := json.NewEncoder(os.Stdout).Encode(namespaces); err != nil { + logger.Fatal("could not encode output", zap.Error(err)) + } + return } + + os.Stdout.Write(resp) }, } @@ -110,13 +163,14 @@ database creation, database init, adding a node, and replacing a node, are suppo Short: "Get the placement from the remote endpoint", Aliases: []string{"pl"}, Run: func(cmd *cobra.Command, args []string) { - logger.Debug("running command", zap.String("command", cmd.Name())) - if err := placements.DoGet(endPoint, logger); err != nil { - logger.Error("get placement failed", zap.Error(err)) - os.Exit(1) + resp, err := placements.DoGet(endPoint, headers, logger) + if err != nil { + logger.Fatal("get placement failed", zap.Error(err)) } + + os.Stdout.Write(resp) }, } @@ -125,13 +179,14 @@ database creation, database init, adding a node, and replacing a node, are suppo Short: "Delete the placement from the remote endpoint", Aliases: []string{"pl"}, Run: func(cmd *cobra.Command, args []string) { - logger.Debug("running command", zap.String("command", cmd.Name())) - if err := placements.DoDelete(endPoint, nodeName, showAll, logger); err != nil { - logger.Error("delete placement failed", zap.Error(err)) - os.Exit(1) + resp, err := placements.DoDelete(endPoint, headers, nodeName, deleteAll, logger) + if err != nil { + logger.Fatal("delete placement failed", zap.Error(err)) } + + os.Stdout.Write(resp) }, } @@ -140,13 +195,14 @@ database creation, database init, adding a node, and replacing a node, are suppo Short: "Delete the namespace from the remote endpoint", Aliases: []string{"ns"}, Run: func(cmd *cobra.Command, args []string) { - logger.Debug("running command", zap.String("command", cmd.Name())) - if err := namespaces.DoDelete(endPoint, nodeName, logger); err != nil { - logger.Error("delete namespace failed", zap.Error(err)) - os.Exit(1) + resp, err := namespaces.DoDelete(endPoint, headers, nodeName, logger) + if err != nil { + logger.Fatal("delete namespace failed", zap.Error(err)) } + + os.Stdout.Write(resp) }, } @@ -156,12 +212,38 @@ database creation, database init, adding a node, and replacing a node, are suppo deleteCmd.AddCommand(deletePlacementCmd) deleteCmd.AddCommand(deleteNamespaceCmd) - rootCmd.PersistentFlags().StringVar(&endPoint, "endpoint", DefaultEndpoint, "m3db service endpoint") + var headersSlice []string + rootCmd.PersistentFlags().BoolVarP(&debug, "debug", "d", false, "debug log output level (cannot use JSON output)") + rootCmd.PersistentFlags().StringVar(&endPoint, "endpoint", defaultEndpoint, "m3coordinator endpoint URL") + rootCmd.PersistentFlags().StringSliceVarP(&headersSlice, "header", "H", []string{}, "headers to append to requests") applyCmd.Flags().StringVarP(&yamlPath, "file", "f", "", "times to echo the input") - getNamespaceCmd.Flags().BoolVarP(&showAll, "showAll", "a", false, "times to echo the input") - deletePlacementCmd.Flags().BoolVarP(&showAll, "deleteAll", "a", false, "delete the entire placement") + getNamespaceCmd.Flags().BoolVarP(&showAll, "show-all", "a", false, "times to echo the input") + deletePlacementCmd.Flags().BoolVarP(&deleteAll, "delete-all", "a", false, "delete the entire placement") deleteCmd.PersistentFlags().StringVarP(&nodeName, "name", "n", "", "which namespace or node to delete") - rootCmd.Execute() + rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error { + // Override logger if debug flag set. + if debug { + logger = mustNewLogger(loggerOptions{ + level: zapcore.DebugLevel, + enableStacktrace: true, + }) + } + + // Parse headers slice. + for _, h := range headersSlice { + parts := strings.Split(h, ":") + if len(parts) != 2 { + return fmt.Errorf( + "header must be of format 'name: value': actual='%s'", h) + } + + name, value := strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]) + headers[name] = value + } + return nil + } + + rootCmd.Execute() } diff --git a/src/cmd/tools/m3ctl/namespaces/delete.go b/src/cmd/tools/m3ctl/namespaces/delete.go index 709c26dbcc..4feafe49eb 100644 --- a/src/cmd/tools/m3ctl/namespaces/delete.go +++ b/src/cmd/tools/m3ctl/namespaces/delete.go @@ -28,7 +28,12 @@ import ( ) // DoDelete calls the delete namespaces api on the backend -func DoDelete(endpoint string, nsName string, logger *zap.Logger) error { +func DoDelete( + endpoint string, + headers map[string]string, + nsName string, + logger *zap.Logger, +) ([]byte, error) { url := fmt.Sprintf("%s%s/%s", endpoint, "/api/v1/services/m3db/namespace", nsName) - return client.DoDelete(url, client.Dumper, logger) + return client.DoDelete(url, headers, logger) } diff --git a/src/cmd/tools/m3ctl/namespaces/get.go b/src/cmd/tools/m3ctl/namespaces/get.go index e50c0eb4ee..00efd478e5 100644 --- a/src/cmd/tools/m3ctl/namespaces/get.go +++ b/src/cmd/tools/m3ctl/namespaces/get.go @@ -22,33 +22,18 @@ package namespaces import ( "fmt" + "go.uber.org/zap" - "io" "github.com/m3db/m3/src/cmd/tools/m3ctl/client" - "github.com/m3db/m3/src/query/generated/proto/admin" - - "github.com/gogo/protobuf/jsonpb" ) // DoGet calls the backend get namespace api -func DoGet(endpoint string, showAll bool, logger *zap.Logger) error { +func DoGet( + endpoint string, + headers map[string]string, + logger *zap.Logger, +) ([]byte, error) { url := fmt.Sprintf("%s%s?%s", endpoint, DefaultPath, DebugQS) - if showAll { - return client.DoGet(url, client.Dumper, logger) - } else { - return client.DoGet(url, showNames, logger) - } -} - -func showNames(in io.Reader, zl *zap.Logger) error { - registry := admin.NamespaceGetResponse{} - unmarshaller := &jsonpb.Unmarshaler{AllowUnknownFields: true} - if err := unmarshaller.Unmarshal(in, ®istry); err != nil { - return err - } - for k, _ := range registry.Registry.Namespaces { - fmt.Println(k) - } - return nil + return client.DoGet(url, headers, logger) } diff --git a/src/cmd/tools/m3ctl/placements/delete.go b/src/cmd/tools/m3ctl/placements/delete.go index 19678407c3..1bf29a1aac 100644 --- a/src/cmd/tools/m3ctl/placements/delete.go +++ b/src/cmd/tools/m3ctl/placements/delete.go @@ -22,16 +22,24 @@ package placements import ( "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/client" + "go.uber.org/zap" ) // DoDelete does the delete api calls for placements -func DoDelete(endpoint string, nodeName string, deleteEntire bool, logger *zap.Logger) error { +func DoDelete( + endpoint string, + headers map[string]string, + nodeName string, + deleteEntire bool, + logger *zap.Logger, +) ([]byte, error) { if deleteEntire { url := fmt.Sprintf("%s%s", endpoint, DefaultPath) - return client.DoDelete(url, client.Dumper, logger) + return client.DoDelete(url, headers, logger) } url := fmt.Sprintf("%s%s/%s", endpoint, DefaultPath, nodeName) - return client.DoDelete(url, client.Dumper, logger) + return client.DoDelete(url, headers, logger) } diff --git a/src/cmd/tools/m3ctl/placements/get.go b/src/cmd/tools/m3ctl/placements/get.go index a132fbd2bb..4845a0065f 100644 --- a/src/cmd/tools/m3ctl/placements/get.go +++ b/src/cmd/tools/m3ctl/placements/get.go @@ -22,12 +22,18 @@ package placements import ( "fmt" + "github.com/m3db/m3/src/cmd/tools/m3ctl/client" + "go.uber.org/zap" ) // DoGet calls the backend api for get placements -func DoGet(endpoint string, logger *zap.Logger) error { +func DoGet( + endpoint string, + headers map[string]string, + logger *zap.Logger, +) ([]byte, error) { url := fmt.Sprintf("%s%s", endpoint, DefaultPath) - return client.DoGet(url, client.Dumper, logger) + return client.DoGet(url, headers, logger) } diff --git a/src/cmd/tools/m3ctl/yaml/generated/db_create.pb.go b/src/cmd/tools/m3ctl/yaml/generated/db_create.pb.go index 2cd147d5b0..425a5ab05a 100644 --- a/src/cmd/tools/m3ctl/yaml/generated/db_create.pb.go +++ b/src/cmd/tools/m3ctl/yaml/generated/db_create.pb.go @@ -1,13 +1,34 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: db_create.proto +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package yaml import ( fmt "fmt" + math "math" + proto "github.com/golang/protobuf/proto" admin "github.com/m3db/m3/src/query/generated/proto/admin" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/src/cmd/tools/m3ctl/yaml/generated/placement.pb.go b/src/cmd/tools/m3ctl/yaml/generated/placement.pb.go index 3abcbf79de..a6144371b8 100644 --- a/src/cmd/tools/m3ctl/yaml/generated/placement.pb.go +++ b/src/cmd/tools/m3ctl/yaml/generated/placement.pb.go @@ -1,13 +1,34 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // source: placement.proto +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + package yaml import ( fmt "fmt" + math "math" + proto "github.com/golang/protobuf/proto" admin "github.com/m3db/m3/src/query/generated/proto/admin" - math "math" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/src/ctl/public/r2/v1/swagger/swagger.json b/src/ctl/public/r2/v1/swagger/swagger.json index 6a7523be34..90d569d0a3 100644 --- a/src/ctl/public/r2/v1/swagger/swagger.json +++ b/src/ctl/public/r2/v1/swagger/swagger.json @@ -6,7 +6,7 @@ "title": "R2 API", "license": { "name": "MIT", - "url": "https://github.com/m3db/m3ctl/blob/master/LICENSE.md" + "url": "https://github.com/m3db/m3/blob/master/LICENSE.md" } }, "host": "localhost:9000", From a11e6c1a5fd4e5959e251f6667e592caab74a4b0 Mon Sep 17 00:00:00 2001 From: Rob Skillington Date: Tue, 14 Apr 2020 17:35:09 -0400 Subject: [PATCH 65/65] Delete unused --- src/cmd/tools/m3ctl/errors/types.go | 32 ----------------------------- 1 file changed, 32 deletions(-) delete mode 100644 src/cmd/tools/m3ctl/errors/types.go diff --git a/src/cmd/tools/m3ctl/errors/types.go b/src/cmd/tools/m3ctl/errors/types.go deleted file mode 100644 index 3b113bebf2..0000000000 --- a/src/cmd/tools/m3ctl/errors/types.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2020 Uber Technologies, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -package errors - -type FlagsError struct { - Message string -} - -func (e *FlagsError) Error() string { - if e == nil { - return "" - } - return e.Message -}