diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c49851f7..20b7bed0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,15 @@ * Feature: new `ziti edge list summary` command, which shows database entity counts * Bug fix: ziti-fabric didn't always report an error to the OS when it had an error * Refactor: All protobuf packages have been prefixed with `ziti.` to help prevent namespace clashes. Should not be a breaking change. +* Feature: Selective debug logging by identity for path selection and circuit establishment + * `ziti edge trace identity ` will turn on debug logging for selecting paths and establishing circuits + * Addition context for these operations including circuitId, sessionid and apiSessionId should now be in log messages regardless of whether tracing is enabled + * Tracing is enabled for a given duration, which defaults to 10 minutes ## Breaking Changes Fabric sessions renamed to circuits. External integrators may be impacted by changes to events. See below for details. +### Ziti CLI Commands under `ziti edge` now reserve the `-i` flag for specifying client identity. Any command line argumet which previously had a `-i` short version now only has a long version. diff --git a/etc/ctrl.with.edge.yml b/etc/ctrl.with.edge.yml index 97acb4205..53023a033 100644 --- a/etc/ctrl.with.edge.yml +++ b/etc/ctrl.with.edge.yml @@ -68,6 +68,7 @@ mgmt: # - created # - type: fabric.usage # - type: services +# - type: fabric.usage # handler: # type: file # format: json diff --git a/go.mod b/go.mod index aa86833c9..6e110d1fa 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,8 @@ go 1.16 //replace github.com/openziti/edge => ../edge +//replace github.com/michaelquigley/pfxlog => ../pfxlog + replace go.etcd.io/bbolt => github.com/openziti/bbolt v1.3.6-0.20210317142109-547da822475e require ( @@ -21,7 +23,7 @@ require ( github.com/fatih/color v1.7.0 github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa github.com/go-acme/lego/v4 v4.2.0 - github.com/go-openapi/runtime v0.19.29 + github.com/go-openapi/runtime v0.19.30 github.com/go-openapi/strfmt v0.20.1 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/protobuf v1.5.2 @@ -30,10 +32,10 @@ require ( github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19 github.com/michaelquigley/pfxlog v0.6.1 - github.com/openziti/edge v0.20.11 - github.com/openziti/fabric v0.16.88 - github.com/openziti/foundation v0.15.67 - github.com/openziti/sdk-golang v0.15.77 + github.com/openziti/edge v0.20.20 + github.com/openziti/fabric v0.16.92 + github.com/openziti/foundation v0.15.69 + github.com/openziti/sdk-golang v0.15.80 github.com/pborman/uuid v1.2.0 github.com/pkg/errors v0.9.1 github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 diff --git a/go.sum b/go.sum index 5098f6eae..72b99abfd 100644 --- a/go.sum +++ b/go.sum @@ -259,8 +259,8 @@ github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29g github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= -github.com/go-openapi/runtime v0.19.29 h1:5IIvCaIDbxetN674vX9eOxvoZ9mYGQ16fV1Q0VSG+NA= -github.com/go-openapi/runtime v0.19.29/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M= +github.com/go-openapi/runtime v0.19.30 h1:bVDeSf4HU9EMth+lHD1EthaHe1SFoUVPaUvQtkGS9g8= +github.com/go-openapi/runtime v0.19.30/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= @@ -338,7 +338,6 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= -github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= @@ -549,8 +548,8 @@ github.com/liquidweb/liquidweb-go v1.6.1/go.mod h1:UDcVnAMDkZxpw4Y7NOHkqoeiGacVL github.com/lucas-clemente/quic-go v0.18.0/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg= github.com/lucas-clemente/quic-go v0.18.1 h1:DMR7guC0NtVS8zNZR3IO7NARZvZygkSC56GGtC6cyys= github.com/lucas-clemente/quic-go v0.18.1/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg= -github.com/lucsky/cuid v1.2.0 h1:8J7qLbiHRf80X4EqsfmSJkf/tgC5bdj9fLsbwOL29tU= -github.com/lucsky/cuid v1.2.0/go.mod h1:QaaJqckboimOmhRSJXSx/+IT+VTfxfPGSo/6mfgUfmE= +github.com/lucsky/cuid v1.2.1 h1:MtJrL2OFhvYufUIn48d35QGXyeTC8tn0upumW9WwTHg= +github.com/lucsky/cuid v1.2.1/go.mod h1:QaaJqckboimOmhRSJXSx/+IT+VTfxfPGSo/6mfgUfmE= github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= @@ -610,7 +609,6 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyex github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/michaelquigley/pfxlog v0.3.1/go.mod h1:pwJmJ9nN787xk9U+0z8/5nP2GMhU6GGCTfgBWGpiXaQ= -github.com/michaelquigley/pfxlog v0.6.0/go.mod h1:z864Y2uU0O4QA5OoclXIOdoX5Tme2zm66FLAJ+R1jZs= github.com/michaelquigley/pfxlog v0.6.1 h1:Ip/5LQchoyFp/MSvdYjFzy6fSsDt2DV4CEl72w/v29g= github.com/michaelquigley/pfxlog v0.6.1/go.mod h1:z864Y2uU0O4QA5OoclXIOdoX5Tme2zm66FLAJ+R1jZs= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= @@ -679,17 +677,16 @@ github.com/openziti/bbolt v1.3.6-0.20210317142109-547da822475e h1:ST9+54UtCr96S5 github.com/openziti/bbolt v1.3.6-0.20210317142109-547da822475e/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= github.com/openziti/dilithium v0.3.3 h1:PLgQ6PMNLSTzCFbX/h98cmudgz/cU6TmjdSv5NAPD8k= github.com/openziti/dilithium v0.3.3/go.mod h1:vsCjI2AU/hon9e+dLhUFbCNGesJDj2ASgkySOcpmvjo= -github.com/openziti/edge v0.20.11 h1:yhIdSGjsEF6DFeXGgFmRR0s96mP1yG1wBh+vjEOgEdg= -github.com/openziti/edge v0.20.11/go.mod h1:xcQES1RBtsqgcP5iI6inC/eQz33HZRHZ6Bd4zZ04l3M= -github.com/openziti/fabric v0.16.86/go.mod h1:J8Y+bjHoSD0sXFSTUba+RGJ3P1YT6pPpPIvQtc9NPJM= -github.com/openziti/fabric v0.16.88 h1:awBCSynkzf+9TdconrIjPc0dPGCQil0FWgu2jCZVMiU= -github.com/openziti/fabric v0.16.88/go.mod h1:/6x+qy2xZdzkYvP+yDsKXPNsWkbUUGwmikF5LEinX6c= -github.com/openziti/foundation v0.15.66/go.mod h1:03nGRyp9bOrKm4KEjvXN//g4c/E1qtT/2M77Hfi78lY= -github.com/openziti/foundation v0.15.67 h1:Zj2oEkhOlf/FhxmZQ4QAjX5jRcquejNT1gCm/RQLvdw= -github.com/openziti/foundation v0.15.67/go.mod h1:Njk4vQbg6ILR/RQiU5DQOk35oMulQRPGHLn386+RSew= -github.com/openziti/sdk-golang v0.15.75/go.mod h1:Peez3s/zjaLfYTyEmnOQY/nbjFvpZtpYyeY9m20YJmc= -github.com/openziti/sdk-golang v0.15.77 h1:Vl3Ub/z3edJ8hLOfztmCNgIcwtqQH9vKEQFd7x673pA= -github.com/openziti/sdk-golang v0.15.77/go.mod h1:hn4/6DIwjR6Te1lHXsP5Plc3hbZtQvHLLseqklT/ywI= +github.com/openziti/edge v0.20.20 h1:5zqhJmDnBIzjStpVfjOjTROl6Gl19xNHTPE6WJ4bPv4= +github.com/openziti/edge v0.20.20/go.mod h1:aK6+rWXtcFyC+q508tt5otb6XVu1U+uwB4A3rbM/OIA= +github.com/openziti/fabric v0.16.91/go.mod h1:iZIAbL2h5nm3bBwgHyk+xQVFBLYTewrKzYtqxjA+MS0= +github.com/openziti/fabric v0.16.92 h1:gZjZ++7ylQK7QeR29jgs8a80sPIbG+RYaZ6arB1BsaQ= +github.com/openziti/fabric v0.16.92/go.mod h1:zONdz/0rklchq807hu3j8e6CE+n1zic4spfFblTUrgY= +github.com/openziti/foundation v0.15.68/go.mod h1:Njk4vQbg6ILR/RQiU5DQOk35oMulQRPGHLn386+RSew= +github.com/openziti/foundation v0.15.69 h1:+FuN1RkZUMbUWdAozvyoXKVv5ZYBaVd1e+HUS33YmsE= +github.com/openziti/foundation v0.15.69/go.mod h1:Njk4vQbg6ILR/RQiU5DQOk35oMulQRPGHLn386+RSew= +github.com/openziti/sdk-golang v0.15.80 h1:aopTQtAzh2p3qMHqbEsmBp8bICYkxK84voJpCBLJ3iA= +github.com/openziti/sdk-golang v0.15.80/go.mod h1:3Y4GA2/YY+WDtz1HhLXbL7VdBzKuQu9Jfddm3J+N+AY= github.com/oracle/oci-go-sdk v24.2.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= github.com/orcaman/concurrent-map v0.0.0-20210106121528-16402b402231 h1:fa50YL1pzKW+1SsBnJDOHppJN9stOEwS+CRWyUtyYGU= diff --git a/ziti/cmd/ziti/cmd/edge_controller/list.go b/ziti/cmd/ziti/cmd/edge_controller/list.go index 56cf8b902..c3549ac47 100644 --- a/ziti/cmd/ziti/cmd/edge_controller/list.go +++ b/ziti/cmd/ziti/cmd/edge_controller/list.go @@ -476,7 +476,7 @@ func outputTerminators(o *edgeOptions, children []*gabs.Container, pagingInfo *p for _, entity := range children { id, _ := entity.Path("id").Data().(string) service := entity.Path("service.name").Data().(string) - router := entity.Path("router.id").Data().(string) + router := entity.Path("router.name").Data().(string) binding := entity.Path("binding").Data().(string) address := entity.Path("address").Data().(string) identity := entity.Path("identity").Data().(string) diff --git a/ziti/cmd/ziti/cmd/edge_controller/root.go b/ziti/cmd/ziti/cmd/edge_controller/root.go index 3ee2244bf..81750f97a 100644 --- a/ziti/cmd/ziti/cmd/edge_controller/root.go +++ b/ziti/cmd/ziti/cmd/edge_controller/root.go @@ -77,6 +77,7 @@ func populateEdgeCommands(f cmdutil.Factory, out io.Writer, errOut io.Writer, cm cmd.AddCommand(newVerifyCmd(f, out, errOut)) cmd.AddCommand(newDbCmd(f, out, errOut)) cmd.AddCommand(enrollment.NewEnrollCommand()) + cmd.AddCommand(newTraceCmd(f, out, errOut)) return cmd } diff --git a/ziti/cmd/ziti/cmd/edge_controller/trace_identity.go b/ziti/cmd/ziti/cmd/edge_controller/trace_identity.go new file mode 100644 index 000000000..5dc7d5bf5 --- /dev/null +++ b/ziti/cmd/ziti/cmd/edge_controller/trace_identity.go @@ -0,0 +1,114 @@ +/* + Copyright NetFoundry, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package edge_controller + +import ( + "fmt" + "github.com/Jeffail/gabs" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + "github.com/spf13/cobra" + "io" +) + +type traceIdentityOptions struct { + edgeOptions + disable bool + duration string + traceId string +} + +// newCreateIdentityCmd creates the 'edge controller create identity' command +func newTraceCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { + cmd := &cobra.Command{ + Use: "trace", + Short: "manages tracing by the Ziti Edge Controller", + } + + cmd.AddCommand(newTraceIdentityCmd(f, out, errOut)) + + return cmd +} + +func newTraceIdentityCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { + options := &traceIdentityOptions{ + edgeOptions: edgeOptions{ + CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + }, + } + + cmd := &cobra.Command{ + Use: "identity", + Short: "enables/disables tracing for sessions from an identity managed by the Ziti Edge Controller", + Args: cobra.MinimumNArgs(1), + Run: func(cmd *cobra.Command, args []string) { + options.Cmd = cmd + options.Args = args + err := runTraceIdentity(options) + cmdhelper.CheckErr(err) + }, + SuggestFor: []string{}, + } + + // allow interspersing positional args and flags + cmd.Flags().SetInterspersed(true) + cmd.Flags().BoolVar(&options.disable, "disable", false, "Disables tracing for the identity (default false)") + cmd.Flags().StringVarP(&options.duration, "duration", "d", "10m", "how long to enable tracing for (default 10 minutes)") + cmd.Flags().StringVar(&options.traceId, "trace-id", "", "Unique id to use when tracing") + + options.AddCommonFlags(cmd) + + return cmd +} + +func runTraceIdentity(o *traceIdentityOptions) error { + id, err := mapNameToID("identities", o.Args[0], o.edgeOptions) + if err != nil { + return err + } + + entityData := gabs.New() + setJSONValue(entityData, !o.disable, "enabled") + setJSONValue(entityData, o.duration, "duration") + + if o.traceId != "" { + setJSONValue(entityData, o.traceId, "traceId") + } + + if len(o.Args) > 1 { + setJSONValue(entityData, o.Args[1:], "channels") + } + + result, err := putEntityOfType("identities/"+id+"/trace", entityData.String(), &o.edgeOptions) + + if err != nil { + return err + } + + traceId := result.S("data", "traceId").Data().(string) + until := result.S("data", "until").Data().(string) + enabled := result.S("data", "enabled").Data().(bool) + + if enabled { + _, err = fmt.Fprintf(o.Out, "tracing enabled for identity %v until %v with id: %v\n", id, until, traceId) + return err + } + + _, err = fmt.Fprintf(o.Out, "tracing disabled for identity %v\n", id) + return err +} diff --git a/ziti/cmd/ziti/util/rest.go b/ziti/cmd/ziti/util/rest.go index 75542ae03..40b269a02 100644 --- a/ziti/cmd/ziti/util/rest.go +++ b/ziti/cmd/ziti/util/rest.go @@ -565,7 +565,7 @@ func EdgeControllerLogin(url string, cert string, authentication string, out io. } if resp.StatusCode() != http.StatusOK { - return nil, fmt.Errorf("unable to authenticate to %v. Status code: %v, Server returned: %v", url, resp.Status(), resp.String()) + return nil, fmt.Errorf("unable to authenticate to %v. Status code: %v, Server returned: %v", url, resp.Status(), prettyPrintResponse(resp)) } if logJSON { @@ -580,6 +580,15 @@ func EdgeControllerLogin(url string, cert string, authentication string, out io. return jsonParsed, nil } +func prettyPrintResponse(resp *resty.Response) string { + out := resp.String() + var prettyJSON bytes.Buffer + if err := json.Indent(&prettyJSON, []byte(out), "", " "); err == nil { + return prettyJSON.String() + } + return out +} + func outputJson(out io.Writer, data []byte) { var prettyJSON bytes.Buffer if err := json.Indent(&prettyJSON, data, "", " "); err == nil { @@ -621,7 +630,7 @@ func EdgeControllerDetailEntity(entityType, entityId string, logJSON bool, out i if resp.StatusCode() != http.StatusOK { return nil, fmt.Errorf("error listing %v in Ziti Edge Controller. Status code: %v, Server returned: %v", - queryUrl, resp.Status(), resp.String()) + queryUrl, resp.Status(), prettyPrintResponse(resp)) } if logJSON { @@ -679,7 +688,7 @@ func EdgeControllerList(path string, params url.Values, logJSON bool, out io.Wri if resp.StatusCode() != http.StatusOK { return nil, fmt.Errorf("error listing %v in Ziti Edge Controller. Status code: %v, Server returned: %v", - queryUrl, resp.Status(), resp.String()) + queryUrl, resp.Status(), prettyPrintResponse(resp)) } if logJSON { @@ -903,7 +912,7 @@ func EdgeControllerCreate(entityType string, body string, out io.Writer, logJSON if resp.StatusCode() != http.StatusCreated { return nil, fmt.Errorf("error creating %v instance in Ziti Edge Controller at %v. Status code: %v, Server returned: %v", - entityType, restClientIdentity.GetBaseUrl(), resp.Status(), resp.String()) + entityType, restClientIdentity.GetBaseUrl(), resp.Status(), prettyPrintResponse(resp)) } if logJSON { @@ -948,7 +957,7 @@ func EdgeControllerDelete(entityType string, id string, out io.Writer, logJSON b if resp.StatusCode() != http.StatusOK { return nil, fmt.Errorf("error deleting %v instance in Ziti Edge Controller at %v. Status code: %v, Server returned: %v", - entityPath, restClientIdentity.GetBaseUrl(), resp.Status(), resp.String()) + entityPath, restClientIdentity.GetBaseUrl(), resp.Status(), prettyPrintResponse(resp)) } if logJSON { @@ -997,7 +1006,7 @@ func EdgeControllerUpdate(entityType string, body string, out io.Writer, method if resp.StatusCode() != http.StatusOK && resp.StatusCode() != http.StatusAccepted { return nil, fmt.Errorf("error updating %v instance in Ziti Edge Controller at %v. Status code: %v, Server returned: %v", - entityType, restClientIdentity.GetBaseUrl(), resp.Status(), resp.String()) + entityType, restClientIdentity.GetBaseUrl(), resp.Status(), prettyPrintResponse(resp)) } if logResponseJSON { @@ -1044,7 +1053,7 @@ func EdgeControllerVerify(entityType, id, body string, out io.Writer, logJSON bo if resp.StatusCode() != http.StatusOK { return fmt.Errorf("error verifying %v instance (%v) in Ziti Edge Controller at %v. Status code: %v, Server returned: %v", - entityType, id, restClientIdentity.GetBaseUrl(), resp.Status(), resp.String()) + entityType, id, restClientIdentity.GetBaseUrl(), resp.Status(), prettyPrintResponse(resp)) } if logJSON { @@ -1081,7 +1090,7 @@ func EdgeControllerRequest(entityType string, out io.Writer, logJSON bool, timeo if resp.StatusCode() != http.StatusOK { return nil, fmt.Errorf("error performing request [%s] %v instance in Ziti Edge Controller at %v. Status code: %v, Server returned: %v", - request.Method, entityType, restClientIdentity.GetBaseUrl(), resp.Status(), resp.String()) + request.Method, entityType, restClientIdentity.GetBaseUrl(), resp.Status(), prettyPrintResponse(resp)) } if logJSON {