Merge pull request #549 from openziti/release-next

Release 0.24.0
This commit is contained in:
Paul Lorenz
2021-12-01 11:22:24 -05:00
committed by GitHub
115 changed files with 3288 additions and 2599 deletions
+50
View File
@@ -1,3 +1,53 @@
# Release 0.24.0
## Breaking Changes
* ziti-fabric-gw has been removed since the fabric now has its own REST API
* ziti-fabric-test is no longer being built by default and won't be included in future release bundles. Use `go build --tags all ./...` to build it
* ziti-fabric has been deprecated. Most of its features are now available in the `ziti` CLI under `ziti fabric`
## What's New
* Feature: Fabric REST API
* Performance: Additional route selection work
* Bug Fix: Fix controller deadlock which can happen if a control channel is closed while controller is responding
* Bug fix: Fix panic for UDP-only tproxy intercepts
## Fabric REST API
The fabric now has a REST API in addition to the channel2 management API. To enable it, add the fabric binding to the apis section off the xweb config, as follows:
```
apis:
# binding - required
# Specifies an API to bind to this webListener. Built-in APIs are
# - health-checks
- binding: fabric
```
If running without the edge, the fabric API uses client certificates for authorization, much like the existing channel2 mgmt based API does. If running with the edge, the edge provides authentication/authorization for the fabric REST APIs.
### Supported Operations
These operations are supported in the REST API. The ziti CLI has been updated to use this in the new `ziti fabric` sub-command.
* Services: create/read/update/delete
* Routers: create/read/update/delete
* Terminators: create/read/update/delete
* Links: read/update
* Circuits: read/delete
### Unsupported Operations
Some operations from ziti-fabric aren't get supported:
* Stream metrics/traces/circuits
* This feature may be re-implemented in terms of websockets, or may be left as-is, or may be dropped
* Inspect (get stackdumps)
* This will be ported to `ziti fabric`
* Decode trace files
* This may be ported to `ziti-ops`
# Release 0.23.1
## What's New
+1
View File
@@ -198,6 +198,7 @@ web:
# - fabric-management
- binding: health-checks
options: { }
- binding: fabric
- binding: edge-management
# options - variable optional/required
# This section is used to define values that are specified by the API they are associated with.
+1 -1
View File
@@ -196,4 +196,4 @@ web:
# Specifies an API to bind to this webListener. Built-in APIs are
# - health-checks
- binding: health-checks
options: { }
- binding: fabric
+10 -7
View File
@@ -18,6 +18,7 @@ replace go.etcd.io/bbolt => github.com/openziti/bbolt v1.3.6-0.20210317142109-54
require (
github.com/Jeffail/gabs v1.4.0
github.com/Jeffail/gabs/v2 v2.6.1
github.com/MakeNowJust/heredoc v1.0.0
github.com/MichaelMure/go-term-markdown v0.1.4
github.com/alecthomas/chroma v0.9.2
@@ -30,18 +31,16 @@ require (
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/protobuf v1.5.2
github.com/google/go-cmp v0.5.6
github.com/gorilla/mux v1.8.0
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.3
github.com/openziti/edge v0.20.133
github.com/openziti/fabric v0.16.133
github.com/openziti/edge v0.21.0
github.com/openziti/fabric v0.17.0
github.com/openziti/foundation v0.16.7
github.com/openziti/sdk-golang v0.15.116
github.com/pborman/uuid v1.2.0
github.com/pkg/errors v0.9.1
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0
github.com/rs/cors v1.7.0
github.com/russross/blackfriday v1.5.2
github.com/shirou/gopsutil v2.20.9+incompatible
github.com/sirupsen/logrus v1.8.1
@@ -49,7 +48,6 @@ require (
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.8.1
github.com/stretchr/testify v1.7.0
github.com/urfave/negroni v1.0.0
github.com/valyala/fasttemplate v1.2.1
go.etcd.io/bbolt v1.3.5-0.20200615073812-232d8fc87f50
golang.org/x/net v0.0.0-20211029224645-99673261e6eb
@@ -98,6 +96,7 @@ require (
github.com/gomarkdown/markdown v0.0.0-20191123064959-2c17d62f5098 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/handlers v1.5.1 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
@@ -136,14 +135,13 @@ require (
github.com/parallaxsecond/parsec-client-go v0.0.0-20210416104105-e2d188152601 // indirect
github.com/pelletier/go-toml v1.9.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
github.com/speps/go-hashids v2.0.0+incompatible // indirect
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf // indirect
github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
@@ -166,3 +164,8 @@ require (
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
require (
github.com/jedib0t/go-pretty/v6 v6.2.4
github.com/rivo/uniseg v0.2.0 // indirect
)
+13 -10
View File
@@ -66,6 +66,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Jeffail/gabs v1.4.0 h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo=
github.com/Jeffail/gabs v1.4.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
github.com/Jeffail/gabs/v2 v2.6.1 h1:wwbE6nTQTwIMsMxzi6XFQQYRZ6wDc1mSdxoAN+9U4Gk=
github.com/Jeffail/gabs/v2 v2.6.1/go.mod h1:xCn81vdHKxFUuWWAaD5jCTQDNPBMh5pPs9IJ+NcziBI=
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
@@ -228,6 +229,7 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa h1:RDBNVkRviHZtvDvId8XSGPu3rmpmSe+wKRcEWNgsfWU=
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E=
github.com/getkin/kin-openapi v0.13.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw=
github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -533,6 +535,8 @@ github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jedib0t/go-pretty/v6 v6.2.4 h1:wdaj2KHD2W+mz8JgJ/Q6L/T5dB7kyqEFI16eLq7GEmk=
github.com/jedib0t/go-pretty/v6 v6.2.4/go.mod h1:+nE9fyyHGil+PuISTCrp7avEdo6bqoMwqZnuiK2r2a0=
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
@@ -660,6 +664,7 @@ github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHX
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
@@ -760,10 +765,10 @@ 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.133 h1:hOI4lgnBLDfXqN+TEiSQ+BWstpESXm5Bnb3a4tACdZ8=
github.com/openziti/edge v0.20.133/go.mod h1:qKZ1BGv2BFtqAVYLVRm8tUdMb0hJ4heMONDOVM6Kra8=
github.com/openziti/fabric v0.16.133 h1:BKzcPswTLSv5Mfu0DnDCP0alLyMsYTOr6ze89AOjgIY=
github.com/openziti/fabric v0.16.133/go.mod h1:GJF5f7Sz2WzQ4ov2TFALDsSyjw0paJYzzkY2mw1pZV8=
github.com/openziti/edge v0.21.0 h1:wQCCcWsPYGs3FCvjIKMXJnnc7C8Y4DLatnWDSSa84F0=
github.com/openziti/edge v0.21.0/go.mod h1:6EGDEyV5qUT4oQk2AzMzLKak5tsatxwVJOX6fvoRmyo=
github.com/openziti/fabric v0.17.0 h1:eE2vpnQcuR0k5WtU7n1qX4SxqKwbBmIsMGvk2nPbHH0=
github.com/openziti/fabric v0.17.0/go.mod h1:6AGi2vTZckhZ5W6DfUml8ITUh+UTq1jJabwVNVglcX0=
github.com/openziti/foundation v0.16.7 h1:Ryuo4wp5CeXJAZYujbXfxuo6/GPpHnvJimESNTopRFY=
github.com/openziti/foundation v0.16.7/go.mod h1:DrzmWd4wka7/RlA37KTN2q+dz9dVSH6YJ9VP6xxf28w=
github.com/openziti/sdk-golang v0.15.116 h1:6/GqsQ4lLw62PZjl0KZyeOgo/1GVgCcX4pBfsZRX2CY=
@@ -795,6 +800,7 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -836,8 +842,6 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -930,8 +934,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf h1:Z2X3Os7oRzpdJ75iPqWZc0HeJWFYNCvKsfpQwFpRNTA=
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0=
github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125 h1:3SNcvBmEPE1YlB1JpVZouslJpI3GBNoiqW7+wb0Rz7w=
github.com/teris-io/shortid v0.0.0-20201117134242-e59966efd125/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -939,8 +943,6 @@ github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
@@ -1174,6 +1176,7 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cO
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+1 -1
View File
@@ -1 +1 @@
0.23
0.24
+1 -1
View File
@@ -18,7 +18,7 @@ package main
import (
"github.com/michaelquigley/pfxlog"
"github.com/openziti/edge/build"
"github.com/openziti/fabric/build"
"github.com/openziti/foundation/transport"
"github.com/openziti/foundation/transport/quic"
"github.com/openziti/foundation/transport/tcp"
-44
View File
@@ -1,44 +0,0 @@
/*
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 main
import (
"github.com/michaelquigley/pfxlog"
"github.com/openziti/foundation/transport"
"github.com/openziti/foundation/transport/quic"
"github.com/openziti/foundation/transport/tcp"
"github.com/openziti/foundation/transport/tls"
"github.com/openziti/foundation/transport/transwarp"
"github.com/openziti/foundation/transport/transwarptls"
"github.com/openziti/foundation/transport/wss"
"github.com/openziti/ziti/ziti-fabric-gw/subcmd"
"github.com/sirupsen/logrus"
)
func init() {
pfxlog.GlobalInit(logrus.InfoLevel, pfxlog.DefaultOptions().SetTrimPrefix("github.com/openziti/").NoColor())
transport.AddAddressParser(quic.AddressParser{})
transport.AddAddressParser(tls.AddressParser{})
transport.AddAddressParser(tcp.AddressParser{})
transport.AddAddressParser(transwarp.AddressParser{})
transport.AddAddressParser(transwarptls.AddressParser{})
transport.AddAddressParser(wss.AddressParser{})
}
func main() {
subcmd.Execute()
}
-78
View File
@@ -1,78 +0,0 @@
/*
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 subcmd
import (
"errors"
"fmt"
"gopkg.in/yaml.v2"
"io/ioutil"
"github.com/openziti/foundation/transport"
"bytes"
)
type Config struct {
MgmtGwListenAddress string `yaml:"listenAddress"`
MgmtGwCertPath string `yaml:"certPath"`
MgmtGwKeyPath string `yaml:"keyPath"`
MgmtAddr string `yaml:"mgmt"`
mgmtAddress transport.Address
MgmtCertPath string `yaml:"mgmtCertPath"`
MgmtKeyPath string `yaml:"mgmtKeyPath"`
MgmtCaCertPath string `yaml:"mgmtCaCertPath"`
}
func loadConfig(path string) (*Config, error) {
buf, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
config := &Config{}
err = yaml.NewDecoder(bytes.NewBuffer(buf)).Decode(config)
if err != nil {
return nil, err
}
if config.MgmtGwListenAddress == "" {
return nil, errors.New("configuration missing [listenAddress]")
}
if config.MgmtAddr == "" {
return nil, errors.New("configuration missing [mgmt]")
}
config.mgmtAddress, err = transport.ParseAddress(config.MgmtAddr)
if err != nil {
return nil, errors.New(fmt.Sprintf("cannot parse [mgmt] (%s)", err))
}
if config.MgmtCertPath == "" {
return nil, errors.New("configuration missing [mgmtCertPath]")
}
if config.MgmtKeyPath == "" {
return nil, errors.New("configuration missing [mgmtKeyPath]")
}
if config.MgmtCaCertPath == "" {
return nil, errors.New("configuration missing [mgmtCaCertPath]")
}
return config, nil
}
-79
View File
@@ -1,79 +0,0 @@
/*
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 subcmd
import (
"encoding/json"
"github.com/golang/protobuf/proto"
"github.com/michaelquigley/pfxlog"
"github.com/openziti/fabric/pb/mgmt_pb"
"github.com/openziti/foundation/channel2"
"net/http"
)
func handleCreateService(w http.ResponseWriter, req *http.Request) {
defer func() { _ = req.Body.Close() }()
decoder := json.NewDecoder(req.Body)
var svc service
err := decoder.Decode(&svc)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode(err.Error()); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
return
}
request := &mgmt_pb.CreateServiceRequest{
Service: &mgmt_pb.Service{
Id: svc.Id,
Terminators: []*mgmt_pb.Terminator{{
RouterId: svc.Egress,
Binding: svc.Binding,
Address: svc.EndpointAddress,
}},
},
}
body, err := proto.Marshal(request)
if err != nil {
panic(err)
}
requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_CreateServiceRequestType), body)
waitCh, err := mgmtCh.SendAndWait(requestMsg)
if err == nil {
select {
case responseMsg := <-waitCh:
if responseMsg.ContentType == channel2.ContentTypeResultType {
result := channel2.UnmarshalResult(responseMsg)
if result.Success {
if err := json.NewEncoder(w).Encode(&data{Data: make([]interface{}, 0)}); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
w.WriteHeader(http.StatusOK)
} else {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode(result.Message); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
}
}
} else {
pfxlog.Logger().Errorf("unexpected error (%s)", err)
}
}
-109
View File
@@ -1,109 +0,0 @@
/*
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 subcmd
import (
"encoding/json"
"github.com/golang/protobuf/proto"
"github.com/gorilla/mux"
"github.com/michaelquigley/pfxlog"
"github.com/openziti/fabric/pb/mgmt_pb"
"github.com/openziti/foundation/channel2"
"net/http"
"time"
)
func handleGetService(w http.ResponseWriter, req *http.Request) {
vars := mux.Vars(req)
id := vars["id"]
request := &mgmt_pb.GetServiceRequest{ServiceId: id}
body, err := proto.Marshal(request)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode(err.Error()); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
return
}
requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_GetServiceRequestType), body)
waitCh, err := mgmtCh.SendAndWait(requestMsg)
if err == nil {
select {
case responseMsg := <-waitCh:
if responseMsg.ContentType == int32(mgmt_pb.ContentType_GetServiceResponseType) {
response := &mgmt_pb.GetServiceResponse{}
err := proto.Unmarshal(responseMsg.Body, response)
if err == nil {
if err := json.NewEncoder(w).Encode(convertService(response.Service)); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
} else {
w.WriteHeader(http.StatusBadRequest)
if err := json.NewEncoder(w).Encode(err.Error()); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
} else if responseMsg.ContentType == channel2.ContentTypeResultType {
result := channel2.UnmarshalResult(responseMsg)
if result.Success {
// This should never happen (i.e. success should take the form of a GetServiceResponseType)
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode("unexpected response"); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
} else {
w.WriteHeader(http.StatusNotFound)
if err := json.NewEncoder(w).Encode("invalid ID specified"); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
} else {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode("unexpected response"); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
case <-time.After(5 * time.Second):
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode("timeout"); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
} else {
pfxlog.Logger().Errorf("unexpected error (%s)", err)
}
}
func convertService(svc *mgmt_pb.Service) interface{} {
d := &data{Data: make([]interface{}, 0)}
address := ""
router := ""
if len(svc.Terminators) > 0 {
address = svc.Terminators[0].Address
router = svc.Terminators[0].RouterId
}
d.Data = append(d.Data, &service{
Id: svc.Id,
EndpointAddress: address,
Egress: router,
})
return d
}
-95
View File
@@ -1,95 +0,0 @@
/*
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 subcmd
import (
"github.com/openziti/foundation/channel2"
"github.com/openziti/fabric/pb/mgmt_pb"
"encoding/json"
"github.com/golang/protobuf/proto"
"github.com/michaelquigley/pfxlog"
"net/http"
"time"
)
func handleListLinks(w http.ResponseWriter, _ *http.Request) {
request := &mgmt_pb.ListLinksRequest{}
body, err := proto.Marshal(request)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
pfxlog.Logger().Errorf("error encoding json (%s)", err)
return
}
requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_ListLinksRequestType), body)
waitCh, err := mgmtCh.SendAndWait(requestMsg)
if err == nil {
select {
case responseMsg := <-waitCh:
if responseMsg.ContentType == int32(mgmt_pb.ContentType_ListLinksResponseType) {
response := &mgmt_pb.ListLinksResponse{}
err := proto.Unmarshal(responseMsg.Body, response)
if err == nil {
if err := json.NewEncoder(w).Encode(convertLinks(response.Links)); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
} else {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode(err.Error()); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
} else {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode("unexpected response"); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
case <-time.After(5 * time.Second):
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode("timeout"); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
} else {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode(err.Error()); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
}
func convertLinks(in []*mgmt_pb.Link) interface{} {
d := &data{}
for _, l := range in {
srcLatency := float64(l.SrcLatency) / 1000000000.0
dstLatency := float64(l.DstLatency) / 1000000000.0
d.Data = append(d.Data, &link{
Id: l.Id,
Src: l.Src,
Dst: l.Dst,
State: l.State,
Down: l.Down,
Cost: l.Cost,
SrcLatency: srcLatency,
DstLatency: dstLatency,
})
}
return d
}
-86
View File
@@ -1,86 +0,0 @@
/*
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 subcmd
import (
"github.com/openziti/foundation/channel2"
"github.com/openziti/fabric/pb/mgmt_pb"
"encoding/json"
"github.com/golang/protobuf/proto"
"github.com/michaelquigley/pfxlog"
"net/http"
"time"
)
func handleListRouters(w http.ResponseWriter, req *http.Request) {
request := &mgmt_pb.ListRoutersRequest{}
body, err := proto.Marshal(request)
if err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_ListRoutersRequestType), body)
waitCh, err := mgmtCh.SendAndWait(requestMsg)
if err == nil {
select {
case responseMsg := <-waitCh:
if responseMsg.ContentType == int32(mgmt_pb.ContentType_ListRoutersResponseType) {
response := &mgmt_pb.ListRoutersResponse{}
err := proto.Unmarshal(responseMsg.Body, response)
if err == nil {
if err := json.NewEncoder(w).Encode(convertRouters(response.Routers)); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
} else {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode(err.Error()); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
} else {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode("unexpected response"); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
case <-time.After(5 * time.Second):
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode("timeout"); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
} else {
pfxlog.Logger().Errorf("unexpected error (%s)", err)
}
}
func convertRouters(in []*mgmt_pb.Router) interface{} {
d := &data{Data: make([]interface{}, 0)}
for _, r := range in {
d.Data = append(d.Data, &router{
Id: r.Id,
Fingerprint: r.Fingerprint,
ListenerAddress: r.ListenerAddress,
Connected: r.Connected,
})
}
return d
}
-91
View File
@@ -1,91 +0,0 @@
/*
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 subcmd
import (
"encoding/json"
"github.com/golang/protobuf/proto"
"github.com/michaelquigley/pfxlog"
"github.com/openziti/fabric/pb/mgmt_pb"
"github.com/openziti/foundation/channel2"
"net/http"
"time"
)
func handleListServices(w http.ResponseWriter, req *http.Request) {
request := &mgmt_pb.ListServicesRequest{}
body, err := proto.Marshal(request)
if err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
w.WriteHeader(http.StatusInternalServerError)
return
}
requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_ListServicesRequestType), body)
waitCh, err := mgmtCh.SendAndWait(requestMsg)
if err == nil {
select {
case responseMsg := <-waitCh:
if responseMsg.ContentType == int32(mgmt_pb.ContentType_ListServicesResponseType) {
response := &mgmt_pb.ListServicesResponse{}
err := proto.Unmarshal(responseMsg.Body, response)
if err == nil {
if err := json.NewEncoder(w).Encode(convertServices(response.Services)); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
} else {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode(err.Error()); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
} else {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode("unexpected response"); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
case <-time.After(5 * time.Second):
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode("timeout"); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
} else {
pfxlog.Logger().Errorf("unexpected error (%s)", err)
}
}
func convertServices(in []*mgmt_pb.Service) interface{} {
d := &data{Data: make([]interface{}, 0)}
for _, svc := range in {
address := ""
router := ""
if len(svc.Terminators) > 0 {
address = svc.Terminators[0].Address
router = svc.Terminators[0].RouterId
}
d.Data = append(d.Data, &service{
Id: svc.Id,
EndpointAddress: address,
Egress: router,
})
}
return d
}
-96
View File
@@ -1,96 +0,0 @@
/*
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 subcmd
import (
"encoding/json"
"github.com/golang/protobuf/proto"
"github.com/michaelquigley/pfxlog"
"github.com/openziti/fabric/pb/mgmt_pb"
"github.com/openziti/foundation/channel2"
"net/http"
"time"
)
func handleListCircuits(w http.ResponseWriter, _ *http.Request) {
request := &mgmt_pb.ListCircuitsRequest{}
body, err := proto.Marshal(request)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
pfxlog.Logger().Errorf("error encoding json (%s)", err)
return
}
requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_ListCircuitsRequestType), body)
waitCh, err := mgmtCh.SendAndWait(requestMsg)
if err == nil {
select {
case responseMsg := <-waitCh:
if responseMsg.ContentType == int32(mgmt_pb.ContentType_ListCircuitsResponseType) {
response := &mgmt_pb.ListCircuitsResponse{}
err := proto.Unmarshal(responseMsg.Body, response)
if err == nil {
if err := json.NewEncoder(w).Encode(convertCircuits(response.Circuits)); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
} else {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode(err.Error()); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
} else {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode("unexpected response"); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
case <-time.After(5 * time.Second):
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode("timeout"); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
} else {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode(err.Error()); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
}
func convertCircuits(in []*mgmt_pb.Circuit) interface{} {
d := &data{}
for _, s := range in {
c := &path{}
for _, p := range s.Path.Nodes {
c.Path = append(c.Path, p)
}
for _, l := range s.Path.Links {
c.Links = append(c.Links, l)
}
d.Data = append(d.Data, &circuit{
Id: s.Id,
ClientId: s.ClientId,
ServiceId: s.ServiceId,
Circuit: c,
})
}
return d
}
-58
View File
@@ -1,58 +0,0 @@
/*
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 subcmd
type path struct {
Path []string `json:"path"`
Links []string `json:"links"`
}
type data struct {
Data []interface{} `json:"data"`
}
type link struct {
Id string `json:"id"`
Src string `json:"src"`
Dst string `json:"dst"`
State string `json:"state"`
Down bool `json:"down"`
Cost int32 `json:"cost"`
SrcLatency float64 `json:"srcLatency"`
DstLatency float64 `json:"dstLatency"`
}
type router struct {
Id string `json:"id"`
Fingerprint string `json:"fingerprint"`
ListenerAddress string `json:"listenerAddress"`
Connected bool `json:"connected"`
}
type service struct {
Id string `json:"id"`
Binding string `json:"binding"`
EndpointAddress string `json:"endpointAddress"`
Egress string `json:"egress"`
}
type circuit struct {
Id string `json:"id"`
ClientId string `json:"clientId"`
ServiceId string `json:"serviceId"`
Circuit *path `json:"circuit"`
}
-79
View File
@@ -1,79 +0,0 @@
/*
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 subcmd
import (
"github.com/openziti/foundation/channel2"
"github.com/openziti/fabric/pb/mgmt_pb"
"encoding/json"
"github.com/golang/protobuf/proto"
"github.com/gorilla/mux"
"github.com/michaelquigley/pfxlog"
"net/http"
"time"
)
func handleRemoveService(w http.ResponseWriter, req *http.Request) {
defer func() { _ = req.Body.Close() }()
vars := mux.Vars(req)
id := vars["id"]
request := &mgmt_pb.RemoveServiceRequest{ServiceId: id}
body, err := proto.Marshal(request)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode(err.Error()); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
return
}
requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_RemoveServiceRequestType), body)
waitCh, err := mgmtCh.SendAndWait(requestMsg)
if err == nil {
select {
case responseMsg := <-waitCh:
if responseMsg.ContentType == channel2.ContentTypeResultType {
result := channel2.UnmarshalResult(responseMsg)
if result.Success {
if err := json.NewEncoder(w).Encode(&data{Data: make([]interface{}, 0)}); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
w.WriteHeader(http.StatusOK)
} else {
w.WriteHeader(http.StatusBadRequest)
}
} else {
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode("unexpected response"); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
return
}
case <-time.After(5 * time.Second):
w.WriteHeader(http.StatusInternalServerError)
if err := json.NewEncoder(w).Encode("timeout"); err != nil {
pfxlog.Logger().Errorf("error encoding json (%s)", err)
}
}
} else {
pfxlog.Logger().Errorf("unexpected error (%s)", err)
}
}
-44
View File
@@ -1,44 +0,0 @@
/*
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 subcmd
import (
"fmt"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
func init() {
root.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose logging")
}
var root = &cobra.Command{
Use: "ziti-fabric-gw",
Short: "Ziti Fabric Management API Gateway",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
if verbose {
logrus.SetLevel(logrus.DebugLevel)
}
},
}
var verbose bool
func Execute() {
if err := root.Execute(); err != nil {
println(fmt.Errorf("error: %s", err))
}
}
-124
View File
@@ -1,124 +0,0 @@
/*
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 subcmd
import (
"github.com/gorilla/mux"
"github.com/michaelquigley/pfxlog"
"github.com/openziti/foundation/channel2"
"github.com/openziti/foundation/common/constants"
"github.com/openziti/foundation/identity/identity"
"github.com/openziti/foundation/transport"
"github.com/rs/cors"
"github.com/spf13/cobra"
"github.com/urfave/negroni"
"net/http"
)
func init() {
root.AddCommand(runCmd)
}
var (
mgmtCh mgmtChannel
mgmtAddress transport.Address
)
var runCmd = &cobra.Command{
Use: "run <config>",
Short: "Run configuration",
Args: cobra.ExactArgs(1),
Run: run,
}
func run(_ *cobra.Command, args []string) {
if config, err := loadConfig(args[0]); err == nil {
if id, err := identity.LoadClientIdentity(config.MgmtCertPath, config.MgmtKeyPath, config.MgmtCaCertPath); err == nil {
dialer := channel2.NewClassicDialer(id, config.mgmtAddress, nil)
if mc, err := channel2.NewChannel("ziti-fabric-gw", dialer, nil); err == nil {
log := pfxlog.Logger()
SetMgmtCh(mc)
router := NewRouter()
/**
* Configure the CORS handler
*/
c := cors.New(cors.Options{
AllowedOrigins: []string{"*"},
AllowedMethods: []string{
"GET", "POST", "PATCH", "DELETE", "OPTIONS",
},
AllowedHeaders: []string{
"Content-Type",
"Accept",
constants.ZitiSession,
},
Debug: false, // Enable Debugging for testing, disable this in production
})
n := negroni.New()
n.Use(negroni.NewLogger()) // Insert the REST tracing middleware
n.Use(c) // Insert the CORS middleware
n.UseHandler(router)
log.Info("started")
if config.MgmtGwCertPath != "" && config.MgmtGwKeyPath != "" {
log.Fatal(http.ListenAndServeTLS(config.MgmtGwListenAddress, config.MgmtGwCertPath, config.MgmtGwKeyPath, n))
} else {
log.Fatal(http.ListenAndServe(config.MgmtGwListenAddress, n))
}
} else {
panic(err)
}
} else {
panic(err)
}
} else {
panic(err)
}
}
type mgmtChannel interface {
SendAndWait(requestMsg *channel2.Message) (chan *channel2.Message, error)
}
// SetMgmtCh sets the channel between this fabric-gw server and the controller. We export this method for testability
func SetMgmtCh(c mgmtChannel) {
mgmtCh = c
}
// NewRouter builds the ziti-router for the server. We export this method for testability
func NewRouter() http.Handler {
router := mux.NewRouter()
router.Use(addJsonContentType)
router.HandleFunc("/ctrl/links", handleListLinks).Methods("GET")
router.HandleFunc("/ctrl/routers", handleListRouters).Methods("GET")
router.HandleFunc("/ctrl/services", handleListServices).Methods("GET")
router.HandleFunc("/ctrl/services", handleCreateService).Methods("POST")
router.HandleFunc("/ctrl/services/{id}", handleGetService).Methods("GET")
router.HandleFunc("/ctrl/services/{id}", handleRemoveService).Methods("DELETE")
router.HandleFunc("/ctrl/sessions", handleListCircuits).Methods("GET")
return router
}
func addJsonContentType(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
next.ServeHTTP(w, r)
})
}
-35
View File
@@ -1,35 +0,0 @@
/*
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 subcmd
import (
"github.com/openziti/ziti/common/version"
"fmt"
"github.com/spf13/cobra"
)
func init() {
root.AddCommand(versionCmd)
}
var versionCmd = &cobra.Command{
Use: "version",
Short: "Show component version",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(version.GetBuildMetadata(verbose))
},
}
+2
View File
@@ -1,3 +1,5 @@
//go:build all
/*
Copyright NetFoundry, Inc.
+2
View File
@@ -17,6 +17,7 @@
package main
import (
"fmt"
"github.com/michaelquigley/pfxlog"
"github.com/openziti/foundation/transport"
"github.com/openziti/foundation/transport/quic"
@@ -41,5 +42,6 @@ func init() {
}
func main() {
fmt.Println("DEPRECATION WARNING: ziti-fabric is deprecated and will be removed in a future release. Use ziti fabric instead.")
subcmd.Execute()
}
+323
View File
@@ -0,0 +1,323 @@
package logs
import (
"bufio"
"fmt"
"github.com/Jeffail/gabs/v2"
"github.com/openziti/foundation/util/stringz"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"os"
"regexp"
"sort"
"strings"
"time"
)
type ParseContext struct {
path string
lineNumber int
eof bool
line string
}
func ScanLines(ctx *ParseContext, callback func(ctx *ParseContext) error) error {
file, err := os.Open(ctx.path)
if err != nil {
return err
}
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
ctx.line = line
if err := callback(ctx); err != nil {
return errors.Wrapf(err, "error parsing %v on line %v", ctx.path, ctx.lineNumber)
}
ctx.lineNumber++
}
ctx.eof = true
return callback(ctx)
}
type JsonParseContext struct {
ParseContext
entry *gabs.Container
}
func (self *JsonParseContext) RequiredString(path ...string) (string, error) {
v := self.entry.Search(path...)
if v == nil || v.Data() == nil {
return "", errors.Errorf("%v not found in log entry", strings.Join(path, "."))
}
s, ok := v.Data().(string)
if !ok {
return "", errors.Errorf("%v is not a string", strings.Join(path, "."))
}
return s, nil
}
func (self *JsonParseContext) ParseJsonEntry() error {
input := self.line
idx := strings.IndexByte(self.line, '{')
if idx < 0 {
fmt.Printf("WARN: non-json line: %v", self.line)
return nil
}
if idx > 0 {
input = input[idx:]
}
entry, err := gabs.ParseJSON([]byte(input))
if err != nil {
return err
}
self.entry = entry
return nil
}
func ScanJsonLines(ctx *JsonParseContext, callback func(ctx *JsonParseContext) error) error {
return ScanLines(&ctx.ParseContext, func(*ParseContext) error {
if ctx.eof {
return callback(ctx)
}
if err := ctx.ParseJsonEntry(); err != nil {
return err
}
if ctx.entry != nil {
return callback(ctx)
}
return nil
})
}
type LogMatcher interface {
Matches(ctx *JsonParseContext) (bool, error)
}
type LogFilter interface {
LogMatcher
Id() string
Label() string
Desc() string
}
type filter struct {
LogMatcher
id string
label string
desc string
}
func (self *filter) Id() string {
return self.id
}
func (self *filter) Label() string {
return self.label
}
func (self *filter) Desc() string {
return self.desc
}
type JsonLogsParser struct {
bucketSize time.Duration
currentBucket time.Time
filters []LogFilter
bucketMatches map[LogFilter]int
unmatched int
maxUnmatchedLoggedPerBucket int
ignore []string
}
func (self *JsonLogsParser) validate() error {
ids := map[string]int{}
for idx, k := range self.filters {
if v, found := ids[k.Id()]; found {
return errors.Errorf("duplicate filter id %v at indices %v and %v", k.Id(), idx, v)
}
ids[k.Id()] = idx
}
return nil
}
func (self *JsonLogsParser) ShowCategories(*cobra.Command, []string) {
for _, filter := range self.filters {
fmt.Printf("%v (%v): %v\n", filter.Id(), filter.Label(), filter.Desc())
}
}
func (self *JsonLogsParser) examineLogEntry(ctx *JsonParseContext) error {
if ctx.eof {
self.dumpBucket()
return nil
}
if err := self.bucket(ctx); err != nil {
return err
}
for _, filter := range self.filters {
match, err := filter.Matches(ctx)
if err != nil {
return err
}
if match {
current := self.bucketMatches[filter]
self.bucketMatches[filter] = current + 1
return nil
}
}
self.unmatched++
if self.unmatched <= self.maxUnmatchedLoggedPerBucket {
fmt.Printf("WARN: unmatched line: %v\n\n", ctx.line)
}
return nil
}
func (self *JsonLogsParser) bucket(ctx *JsonParseContext) error {
s, err := ctx.RequiredString("time")
if err != nil {
return err
}
t, err := time.Parse(time.RFC3339, s)
if err != nil {
return errors.Errorf("time is in an unexpected format: %v", s)
}
interval := t.Truncate(self.bucketSize)
if interval != self.currentBucket {
if !self.currentBucket.IsZero() {
self.dumpBucket()
}
self.currentBucket = interval
self.bucketMatches = map[LogFilter]int{}
self.unmatched = 0
}
return nil
}
func (self *JsonLogsParser) dumpBucket() {
var filters []LogFilter
for k := range self.bucketMatches {
if !stringz.Contains(self.ignore, k.Id()) {
filters = append(filters, k)
}
}
sort.Slice(filters, func(i, j int) bool {
return filters[i].Label() < filters[j].Label()
})
if len(filters) == 0 && self.unmatched == 0 {
return
}
fmt.Printf("%v\n---------------------------------------------------\n", self.currentBucket.Format(time.RFC3339))
for _, filter := range filters {
fmt.Printf(" %v (%v): %0000v\n", filter.Id(), filter.Label(), self.bucketMatches[filter])
}
if self.unmatched > 0 {
fmt.Printf(" unmatched: %0000v\n", self.unmatched)
}
fmt.Println()
}
func FieldStartsWith(field, substring string) LogMatcher {
return &EntryFieldStartsWithMatcher{
field: field,
prefix: substring,
}
}
type EntryFieldStartsWithMatcher struct {
field string
prefix string
}
func (self *EntryFieldStartsWithMatcher) Matches(ctx *JsonParseContext) (bool, error) {
fieldValue, err := ctx.RequiredString(self.field)
if err != nil {
return false, err
}
return strings.HasPrefix(fieldValue, self.prefix), nil
}
func FieldContains(field, substring string) LogMatcher {
return &EntryFieldContainsMatcher{
field: field,
substring: substring,
}
}
type EntryFieldContainsMatcher struct {
field string
substring string
}
func (self *EntryFieldContainsMatcher) Matches(ctx *JsonParseContext) (bool, error) {
fieldValue, err := ctx.RequiredString(self.field)
if err != nil {
return false, err
}
return strings.Contains(fieldValue, self.substring), nil
}
func FieldEquals(field, substring string) LogMatcher {
return &EntryFieldContainsMatcher{
field: field,
substring: substring,
}
}
type EntryFieldEqualsMatcher struct {
field string
value string
}
func (self *EntryFieldEqualsMatcher) Matches(ctx *JsonParseContext) (bool, error) {
fieldValue, err := ctx.RequiredString(self.field)
if err != nil {
return false, err
}
return fieldValue == self.value, nil
}
func AndMatchers(matchers ...LogMatcher) LogMatcher {
return &AndMatcher{matchers: matchers}
}
type AndMatcher struct {
matchers []LogMatcher
}
func (self *AndMatcher) Matches(ctx *JsonParseContext) (bool, error) {
for _, matcher := range self.matchers {
result, err := matcher.Matches(ctx)
if !result || err != nil {
return result, err
}
}
return true, nil
}
func FieldMatches(field, expr string) LogMatcher {
regex, err := regexp.Compile(expr)
if err != nil {
panic(err)
}
return &EntryFieldMatchesMatcher{
field: field,
regex: regex,
}
}
type EntryFieldMatchesMatcher struct {
field string
regex *regexp.Regexp
}
func (self *EntryFieldMatchesMatcher) Matches(ctx *JsonParseContext) (bool, error) {
fieldValue, err := ctx.RequiredString(self.field)
if err != nil {
return false, err
}
return self.regex.MatchString(fieldValue), nil
}
+316
View File
@@ -0,0 +1,316 @@
package logs
import (
"github.com/spf13/cobra"
"time"
)
func NewLogsCommand() *cobra.Command {
logsCmd := &cobra.Command{
Use: "logs",
Short: "commands related to analyzing various ziti component logs",
}
parseRouterLogs := &ParseRouterLogs{}
parseRouterLogs.Init()
parseRouterLogsCmd := &cobra.Command{
Use: "router",
Short: "Parse router logs",
Args: cobra.ExactArgs(1),
RunE: parseRouterLogs.run,
}
parseRouterLogsCmd.Flags().DurationVarP(&parseRouterLogs.bucketSize, "interval", "n", time.Hour, "Interval for which to aggregate log messages")
parseRouterLogsCmd.Flags().IntVarP(&parseRouterLogs.maxUnmatchedLoggedPerBucket, "max-unmatched", "u", 1, "Maximum unmatched log messages to output per bucket")
parseRouterLogsCmd.Flags().StringSliceVar(&parseRouterLogs.ignore, "ignore", []string{"IDLE", "CONF"}, "Filters to ignore")
showRouterLogCategoriesCmd := &cobra.Command{
Use: "categories",
Short: "Show router log entry categories",
Run: parseRouterLogs.ShowCategories,
}
parseRouterLogsCmd.AddCommand(showRouterLogCategoriesCmd)
logsCmd.AddCommand(parseRouterLogsCmd)
return logsCmd
}
type ParseRouterLogs struct {
JsonLogsParser
}
func (self *ParseRouterLogs) Init() {
self.filters = getRouterLogFilters()
}
func getRouterLogFilters() []LogFilter {
return []LogFilter{
&filter{
id: "IDLE",
label: "idle circuit scanner",
desc: "a circuit has been idle for at least one minute and the controller will be checked to see if the circuit is still valid",
LogMatcher: AndMatchers(
FieldContains("file", "forwarder/scanner.go"),
FieldContains("msg", " idle after "),
)},
&filter{
id: "CONF",
label: "circuit confirmation send",
desc: "controller has been notified of idle circuits and can respond if they are no longer valid",
LogMatcher: AndMatchers(
FieldContains("msg", "sent confirmation for "),
FieldContains("file", "forwarder/scanner.go"),
)},
&filter{
id: "TSCX",
label: "tunnel dial success",
desc: "a router embedded tunneler has made a successful connection to a server hosting an application",
LogMatcher: AndMatchers(
FieldStartsWith("msg", "successful connection "),
FieldContains("file", "xgress_edge_tunnel/dialer.go"),
)},
&filter{
id: "DSTX",
label: "routing destination exists",
desc: "attempting to establish a circuit, but a previous dial attempt already established the egress connection",
LogMatcher: AndMatchers(
FieldStartsWith("msg", "destination exists for "),
FieldContains("file", "handler_ctrl/route.go"),
)},
&filter{
id: "XGRF",
label: "xgress read failure",
desc: "read failure on the client or server side of the circuit; will cause the circuit to be torn down",
LogMatcher: AndMatchers(
FieldStartsWith("msg", "read failed"),
FieldContains("file", "xgress/xgress.go"),
)},
&filter{
id: "XGWF",
label: "xgress write failure",
desc: "write failure on the client or server side of the circuit; will cause the circuit to be torn down",
LogMatcher: AndMatchers(
FieldStartsWith("msg", "write failed"),
FieldContains("file", "xgress/xgress.go"),
)},
&filter{
id: "XGBF",
label: "xgress can't buffer",
desc: "while a circuit was being closed, data was received from the client or server",
LogMatcher: AndMatchers(
FieldStartsWith("msg", "failure to buffer payload"),
FieldEquals("error", "payload buffer closed"),
FieldContains("file", "xgress/xgress.go"),
)},
&filter{
id: "RCFM",
label: "can't forward",
desc: "router can't forward a message most likely because the circuit is in the middle of being torn down",
LogMatcher: AndMatchers(
FieldStartsWith("msg", "unable to forward"),
FieldContains("file", "handler_xgress/receive.go"),
)},
&filter{
id: "CSTO",
label: "circuit not started in time",
desc: "the terminating side of the circuit didn't receive a start from the initiating side",
LogMatcher: AndMatchers(
FieldEquals("msg", "xgress circuit not started in time, closing"),
FieldContains("file", "xgress/xgress.go"),
)},
&filter{
id: "TLSC",
label: "no tls certification provided",
desc: "a connection attempt was made to a TLS listener but no certificate was provided",
LogMatcher: AndMatchers(
FieldStartsWith("msg", "error receiving hello from "),
FieldContains("msg", "tls: client didn't provide a certificate"),
FieldContains("file", "channel2/classic_listener.go"),
)},
&filter{
id: "LCYT",
label: "latency timeout",
desc: "a latency ping was sent, but no response was received within the timeout",
LogMatcher: AndMatchers(
FieldStartsWith("msg", "latency timeout after "),
FieldContains("file", "metrics/latency.go"),
)},
&filter{
id: "CHRX",
label: "channel rx error",
desc: "channel read failed",
LogMatcher: AndMatchers(
FieldStartsWith("msg", "rx error"),
FieldContains("msg", "connection reset by peer"),
FieldContains("file", "channel2/impl.go"),
)},
&filter{
id: "LNKS",
label: "dialing split channel link",
desc: "a link is being dialed to another router with separate connections for data and acknowledgements",
LogMatcher: AndMatchers(
FieldStartsWith("msg", "dialing link with split payload/ack channels"),
FieldContains("file", "xlink_transport/dialer.go"),
)},
&filter{
id: "LNKR",
label: "controller requesting dial",
desc: "received a request from the controller to dial another router",
LogMatcher: AndMatchers(
FieldStartsWith("msg", "received link connect request"),
FieldContains("file", "handler_ctrl/dial.go"),
)},
&filter{
id: "LNKD",
label: "dialing link",
desc: "dialing another router to establish a link",
LogMatcher: AndMatchers(
FieldEquals("msg", "dialing link"),
FieldContains("file", "handler_ctrl/dial.go"),
)},
&filter{
id: "LNKE",
label: "link established",
desc: "a link to another router has been established",
LogMatcher: AndMatchers(
FieldEquals("msg", "link established"),
FieldContains("file", "handler_ctrl/dial.go"),
)},
&filter{
id: "LNKP",
label: "dialing link payload channel",
desc: "dialing the link payload channel of a link",
LogMatcher: AndMatchers(
FieldStartsWith("msg", "dialing payload channel for"),
FieldContains("file", "xlink_transport/dialer.go"),
)},
&filter{
id: "LNKK",
label: "dialing link ack channel",
desc: "dialing the link ack channel of a link",
LogMatcher: AndMatchers(
FieldStartsWith("msg", "dialing ack channel for"),
FieldContains("file", "xlink_transport/dialer.go"),
)},
&filter{
id: "LNKC",
label: "link closed",
desc: "a router to router link was closed",
LogMatcher: AndMatchers(
FieldEquals("msg", "link closed"),
FieldContains("file", "handler_link/close.go"),
)},
&filter{
id: "FLTS",
label: "link fault sent",
desc: "the router notified the controller that a link failed",
LogMatcher: AndMatchers(
FieldEquals("msg", "transmitted link fault"),
FieldContains("file", "handler_link/close.go"),
)},
&filter{
id: "LNKA",
label: "link accepted",
desc: "another router has dialed this router and a link has been established",
LogMatcher: AndMatchers(
FieldStartsWith("msg", "accepted new link"),
FieldContains("file", "router/accepter.go"),
)},
&filter{
id: "RCNB",
label: "starting reconnect",
desc: "the router to controller control channel connection died and the router trying to reconnect",
LogMatcher: AndMatchers(
FieldContains("msg", "starting reconnection process"),
FieldContains("file", "channel2/reconnecting_impl.go"),
)},
&filter{
id: "RCNF",
label: "reconnect failed",
desc: "the router attempted to reconnect the control channel and failed",
LogMatcher: AndMatchers(
FieldContains("file", "channel2/reconnecting_dialer.go"),
FieldMatches("msg", "reconnection attempt.*failed"),
)},
&filter{
id: "RCNS",
label: "reconnect succeeded",
desc: "the router attempted to reconnect the control channel and succeeded",
LogMatcher: AndMatchers(
FieldEquals("msg", "reconnected"),
FieldContains("file", "channel2/reconnecting_impl.go"),
)},
&filter{
id: "RCNP",
label: "reconnect ping",
desc: "the router is checking the control channel to see if it needs to be reconnected",
LogMatcher: AndMatchers(
FieldContains("file", "channel2/reconnecting_impl.go"),
FieldContains("func", "pingInstance"),
)},
&filter{
id: "RCPF",
label: "reconnect ping failed",
desc: "the router control channel ping failed",
LogMatcher: AndMatchers(
FieldContains("msg", "unable to ping"),
FieldContains("file", "channel2/reconnecting_dialer.go"),
)},
&filter{
id: "HELO",
label: "received ctrl hello",
desc: "the controller sent us a hello message after a control channel was established or reconnected",
LogMatcher: AndMatchers(
FieldContains("msg", "received server hello"),
FieldContains("file", "handler_edge_ctrl/hello.go"),
)},
&filter{
id: "SSST",
label: "api session sync started",
desc: "The controller has started a full api session sync",
LogMatcher: AndMatchers(
FieldContains("file", "handler_edge_ctrl/apiSessionAdded.go"),
FieldMatches("msg", "api session.*starting"),
)},
&filter{
id: "SSCH",
label: "api session data received",
desc: "The controller sent a chunk of api session data",
LogMatcher: AndMatchers(
FieldContains("file", "handler_edge_ctrl/apiSessionAdded.go"),
FieldStartsWith("msg", "received api session sync chunk"),
)},
&filter{
id: "SSDN",
label: "api session sync finished",
desc: "The controller has finished a full api session sync",
LogMatcher: AndMatchers(
FieldContains("file", "handler_edge_ctrl/apiSessionAdded.go"),
FieldStartsWith("msg", "finished sychronizing api sessions"),
)},
&filter{
id: "CHAC",
label: "accepted connection",
desc: "a tcp connection has been accepted",
LogMatcher: AndMatchers(
FieldEquals("msg", "accepted connection"),
FieldContains("file", "transport/tcp/listener.go"),
)},
}
}
func (self *ParseRouterLogs) run(cmd *cobra.Command, args []string) error {
if err := self.validate(); err != nil {
return err
}
ctx := &JsonParseContext{
ParseContext: ParseContext{
path: args[0],
},
}
return ScanJsonLines(ctx, self.examineLogEntry)
}
+78
View File
@@ -0,0 +1,78 @@
//go:build all
/*
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 main
import (
"fmt"
"github.com/michaelquigley/pfxlog"
"github.com/openziti/fabric/build"
"github.com/openziti/ziti/common/version"
"github.com/openziti/ziti/ziti-ops/logs"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
var verbose bool
var logFormatter string
func init() {
options := pfxlog.DefaultOptions().SetTrimPrefix("github.com/openziti/").NoColor()
pfxlog.GlobalInit(logrus.InfoLevel, options)
build.InitBuildInfo(version.GetCmdBuildInfo())
root.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose logging")
root.PersistentFlags().StringVar(&logFormatter, "log-formatter", "", "Specify log formatter [json|pfxlog|text]")
root.AddCommand(&cobra.Command{
Use: "version",
Short: "Show component version",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println(version.GetBuildMetadata(verbose))
},
})
root.AddCommand(logs.NewLogsCommand())
}
var root = &cobra.Command{
Use: "ziti-ops",
Short: "Ziti Ops Tools",
PersistentPreRun: func(cmd *cobra.Command, args []string) {
if verbose {
logrus.SetLevel(logrus.DebugLevel)
}
switch logFormatter {
case "pfxlog":
pfxlog.SetFormatter(pfxlog.NewFormatter(pfxlog.DefaultOptions().SetTrimPrefix("github.com/openziti/").StartingToday()))
case "json":
pfxlog.SetFormatter(&logrus.JSONFormatter{TimestampFormat: "2006-01-02T15:04:05.000Z"})
case "text":
pfxlog.SetFormatter(&logrus.TextFormatter{})
default:
// let logrus do its own thing
}
},
}
func main() {
if err := root.Execute(); err != nil {
fmt.Printf("error: %s\n", err)
}
}
+1 -1
View File
@@ -18,7 +18,7 @@ package main
import (
"github.com/michaelquigley/pfxlog"
"github.com/openziti/edge/build"
"github.com/openziti/fabric/build"
"github.com/openziti/foundation/transport"
"github.com/openziti/foundation/transport/quic"
"github.com/openziti/foundation/transport/tcp"
+1 -1
View File
@@ -135,6 +135,6 @@ func waitForShutdown(r *router.Router, config *router.Config) {
pfxlog.Logger().Info("shutting down ziti-router")
if err := r.Shutdown(); err != nil {
pfxlog.Logger().Info("error encountered during shutdown: %v", err)
pfxlog.Logger().WithError(err).Info("error encountered during shutdown")
}
}
+52
View File
@@ -0,0 +1,52 @@
package api
import (
"github.com/fatih/color"
"github.com/openziti/foundation/storage/boltz"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"net/url"
"strings"
)
func DeleteEntitiesOfType(api util.API, o *Options, entityType string, ids []string, body string) error {
for _, id := range ids {
err := util.ControllerDelete(api, entityType, id, body, o.Out, o.OutputJSONRequest, o.OutputJSONResponse, o.Timeout, o.Verbose)
if err != nil {
o.Printf("delete of %v with id %v: %v\n", boltz.GetSingularEntityType(entityType), id, color.New(color.FgRed, color.Bold).Sprint("FAIL"))
return err
}
o.Printf("delete of %v with id %v: %v\n", boltz.GetSingularEntityType(entityType), id, color.New(color.FgGreen, color.Bold).Sprint("OK"))
}
return nil
}
// DeleteEntityOfTypeWhere implements the commands to delete various entity types
func DeleteEntityOfTypeWhere(api util.API, options *Options, entityType string, body string) error {
filter := strings.Join(options.Args, " ")
params := url.Values{}
params.Add("filter", filter)
children, pageInfo, err := ListEntitiesOfType(api, entityType, params, options.OutputJSONResponse, options.Out, options.Timeout, options.Verbose)
if err != nil {
return err
}
options.Printf("filter returned ")
pageInfo.Output(options)
var ids []string
for _, entity := range children {
id, _ := entity.Path("id").Data().(string)
ids = append(ids, id)
}
return DeleteEntitiesOfType(api, options, entityType, ids, body)
}
func GetPlural(entityType string) string {
if strings.HasSuffix(entityType, "y") {
return strings.TrimSuffix(entityType, "y") + "ies"
}
return entityType + "s"
}
+24
View File
@@ -0,0 +1,24 @@
package api
import "github.com/Jeffail/gabs"
func SetJSONValue(container *gabs.Container, value interface{}, path ...string) {
if _, err := container.Set(value, path...); err != nil {
panic(err)
}
}
func GetJsonValue(container *gabs.Container, path string) interface{} {
return container.Path(path).Data()
}
func GetJsonString(container *gabs.Container, path string) string {
v := GetJsonValue(container, path)
if v == nil {
return ""
}
if s, ok := v.(string); ok {
return s
}
return ""
}
+136
View File
@@ -0,0 +1,136 @@
package api
import (
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/foundation/util/errorz"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/pkg/errors"
"io"
"net/url"
"os"
"reflect"
"strings"
)
// ListEntitiesOfType queries the Ziti Controller for entities of the given type
func ListEntitiesWithOptions(api util.API, entityType string, options *Options) ([]*gabs.Container, *Paging, error) {
params := url.Values{}
if len(options.Args) > 0 {
params.Add("filter", options.Args[0])
}
return ListEntitiesOfType(api, entityType, params, options.OutputJSONResponse, options.Out, options.Timeout, options.Verbose)
}
// ListEntitiesOfType queries the Ziti Controller for entities of the given type
func ListEntitiesOfType(api util.API, entityType string, params url.Values, logJSON bool, out io.Writer, timeout int, verbose bool) ([]*gabs.Container, *Paging, error) {
jsonParsed, err := util.ControllerList(api, entityType, params, logJSON, out, timeout, verbose)
if err != nil {
return nil, nil, err
}
children, err := jsonParsed.S("data").Children()
return children, getPaging(jsonParsed), err
}
func getPaging(c *gabs.Container) *Paging {
pagingInfo := &Paging{}
pagination := c.S("meta", "pagination")
if pagination != nil {
pagingInfo.limit = toInt64(pagination, "limit", pagingInfo)
pagingInfo.offset = toInt64(pagination, "offset", pagingInfo)
pagingInfo.count = toInt64(pagination, "totalCount", pagingInfo)
} else {
pagingInfo.SetError(errors.New("meta.pagination section not found in result"))
}
return pagingInfo
}
type Paging struct {
limit int64
offset int64
count int64
errorz.ErrorHolderImpl
}
func (p *Paging) Output(o *Options) {
if p.HasError() {
_, _ = fmt.Fprintf(o.Out, "unable to retrieve paging information: %v\n", p.Err)
} else if p.count == 0 {
_, _ = fmt.Fprintln(o.Out, "results: none")
} else {
first := p.offset + 1
last := p.offset + p.limit
if last > p.count || last < 0 { // if p.limit is maxint, last will rollover and be negative
last = p.count
}
_, _ = fmt.Fprintf(o.Out, "results: %v-%v of %v\n", first, last, p.count)
}
}
func toInt64(c *gabs.Container, path string, errorHolder errorz.ErrorHolder) int64 {
data := c.S(path).Data()
if data == nil {
errorHolder.SetError(errors.Errorf("%v not found", path))
return 0
}
val, ok := data.(float64)
if !ok {
errorHolder.SetError(errors.Errorf("%v not a number, it's a %v", path, reflect.TypeOf(data)))
return 0
}
return int64(val)
}
func FilterEntitiesOfType(api util.API, entityType string, filter string, logJSON bool, out io.Writer, timeout int, verbose bool) ([]*gabs.Container, *Paging, error) {
params := url.Values{}
params.Add("filter", filter)
return ListEntitiesOfType(api, entityType, params, logJSON, out, timeout, verbose)
}
func MapNameToID(api util.API, entityType string, o *Options, idOrName string) (string, error) {
result, err := MapNamesToIDs(api, entityType, o, idOrName)
if err != nil {
return "", err
}
if len(result) != 1 {
return "", errors.Errorf("found %v results for input %v when mapping %v to id", len(result), idOrName, entityType)
}
return result[0], nil
}
func MapNamesToIDs(api util.API, entityType string, o *Options, list ...string) ([]string, error) {
var result []string
for _, val := range list {
if strings.HasPrefix(val, "id") {
id := strings.TrimPrefix(val, "id:")
result = append(result, id)
} else {
query := fmt.Sprintf(`id = "%s" or name="%s"`, val, val)
if strings.HasPrefix(val, "name") {
name := strings.TrimPrefix(val, "name:")
query = fmt.Sprintf(`name="%s"`, name)
}
list, _, err := FilterEntitiesOfType(api, entityType, query, false, nil, o.Timeout, o.Verbose)
if err != nil {
return nil, err
}
if len(list) > 1 {
fmt.Printf("Found multiple %v matching %v. Please specify which you want by prefixing with id: or name:\n", entityType, val)
return nil, errors.Errorf("ambigous if %v is id or name", val)
}
for _, entity := range list {
entityId, _ := entity.Path("id").Data().(string)
result = append(result, entityId)
if val, found := os.LookupEnv("ZITI_CLI_DEBUG"); found && strings.EqualFold("true", val) {
fmt.Printf("Found %v with id %v for name %v\n", entityType, entityId, val)
}
}
}
}
return result, nil
}
+54
View File
@@ -0,0 +1,54 @@
package api
import (
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
"github.com/spf13/cobra"
"io"
)
// Options are common options for edge controller commands
type Options struct {
common.CommonOptions
OutputJSONRequest bool
OutputJSONResponse bool
OutputCSV bool
}
func (options *Options) OutputResponseJson() bool {
return options.OutputJSONResponse
}
func (options *Options) OutputRequestJson() bool {
return options.OutputJSONRequest
}
func (options *Options) OutputWriter() io.Writer {
return options.CommonOptions.Out
}
func (options *Options) ErrOutputWriter() io.Writer {
return options.CommonOptions.Err
}
func (options *Options) AddCommonFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&common.CliIdentity, "cli-identity", "i", "", "Specify the saved identity you want the CLI to use when connect to the controller with")
cmd.Flags().BoolVarP(&options.OutputJSONResponse, "output-json", "j", false, "Output the full JSON response from the Ziti Edge Controller")
cmd.Flags().BoolVar(&options.OutputJSONRequest, "output-request-json", false, "Output the full JSON request to the Ziti Edge Controller")
cmd.Flags().IntVarP(&options.Timeout, "timeout", "", 5, "Timeout for REST operations (specified in seconds)")
cmd.Flags().BoolVarP(&options.Verbose, "verbose", "", false, "Enable verbose logging")
}
func (options *Options) LogCreateResult(entityType string, result *gabs.Container, err error) error {
if err != nil {
return err
}
if !options.OutputJSONResponse {
id := result.S("data", "id").Data()
_, err = fmt.Fprintf(options.Out, "New %v %v created with id: %v\n", entityType, options.Args[0], id)
return err
}
return nil
}
+7 -1
View File
@@ -19,6 +19,8 @@ package cmd
import (
goflag "flag"
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/fabric"
"io"
"os"
"path/filepath"
@@ -123,12 +125,15 @@ func NewCmdRoot(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Comm
// defaultClusterName := os.Getenv("ZITI_CLUSTER_NAME")
// cmd.PersistentFlags().StringVarP(&rootCommand.clusterName, "name", "", defaultClusterName, "Name of cluster. Overrides ZITI_CLUSTER_NAME environment variable")
p := common.NewOptionsProvider(out, err)
initCommands := NewCmdInit(f, out, err)
createCommands := NewCmdCreate(f, out, err)
updateCommands := NewCmdUpdate(f, out, err)
executeCommands := NewCmdExecute(f, out, err)
psCommands := NewCmdPs(f, out, err)
pkiCommands := NewCmdPKI(f, out, err)
fabricCommand := fabric.NewFabricCmd(p)
edgeCommand := edge.NewCmdEdge(f, out, err)
logFilter := NewCmdLogFormat(f, out, err)
unwrapIdentityFileCommand := NewUnwrapIdentityFileCommand(f, out, err)
@@ -162,8 +167,9 @@ func NewCmdRoot(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Comm
},
},
{
Message: "Interacting with Ziti edge components",
Message: "Interacting with the Ziti controller",
Commands: []*cobra.Command{
fabricCommand,
edgeCommand,
},
},
-55
View File
@@ -29,10 +29,7 @@ import (
var ZITI_COMPONENTS = []string{
c.ZITI,
c.ZITI_CONTROLLER,
c.ZITI_ENROLLER,
c.ZITI_FABRIC,
c.ZITI_FABRIC_GW,
c.ZITI_FABRIC_TEST,
c.ZITI_PROX_C,
c.ZITI_ROUTER,
c.ZITI_TUNNEL,
@@ -169,55 +166,3 @@ func (o *CommonOptions) createInitialControllerConfig() error {
return nil
}
func (o *CommonOptions) createInitialMgmtGwConfig() error {
configDir, err := util.ConfigDir()
if err != nil {
return err
}
gwConfigDir, err := util.ZitiAppConfigDir(c.ZITI_FABRIC_GW)
if err != nil {
return err
}
fileName := filepath.Join(gwConfigDir, c.CONFIGFILENAME) + ".json"
_, err = os.Stat(fileName)
if err == nil {
return fmt.Errorf("config file (%s) already exists", fileName)
}
cfgfile, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
return err
}
if err := cfgfile.Close(); err != nil {
return err
}
viper.SetConfigType("json")
viper.SetConfigName(c.CONFIGFILENAME)
viper.AddConfigPath(gwConfigDir)
// Set some default values
viper.SetDefault("listenAddress", "localhost:10080")
viper.SetDefault("mgmt", "tls:0.0.0.0:10000")
viper.SetDefault("identity.default.description", "This identity is used if one is not specified at execution time")
viper.SetDefault("identity.default.mgmtGwCertPath", configDir+"/fabric/ca/intermediate/certs/mgmt-gw.cert.pem")
viper.SetDefault("identity.default.mgmtGwKeyPath", configDir+"/fabric/ca/intermediate/private/mgmt-gw.key.pem")
viper.SetDefault("identity.default.mgmtCertPath", configDir+"/fabric/ca/intermediate/certs/mgmt-gw.cert.pem")
viper.SetDefault("identity.default.mgmtKeyPath", configDir+"/fabric/ca/intermediate/private/mgmt-gw.key.pem")
viper.SetDefault("identity.default.mgmtCaCertPath", configDir+"/fabric/ca/intermediate/certs/ca-chain.cert.pem")
viper.SetDefault("identity.a.description", "This identity is just demonstrating that multiple identities can exist (you need to fill out remaining fields)")
viper.SetDefault("identity.b.description", "This identity is just demonstrating that multiple identities can exist (you need to fill out remaining fields)")
err = viper.WriteConfig()
if err != nil {
return err
}
return nil
}
+6 -5
View File
@@ -18,12 +18,13 @@ package edge
import (
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/pkg/errors"
"os"
"strings"
)
func mapNameToID(entityType string, val string, o edgeOptions) (string, error) {
func mapNameToID(entityType string, val string, o api.Options) (string, error) {
list, _, err := filterEntitiesOfType(entityType, fmt.Sprintf("id=\"%s\"", val), false, nil, o.Timeout, o.Verbose)
if err != nil {
return "", err
@@ -54,7 +55,7 @@ func mapNameToID(entityType string, val string, o edgeOptions) (string, error) {
return entityId, nil
}
func mapIdToName(entityType string, val string, o edgeOptions) (string, error) {
func mapIdToName(entityType string, val string, o api.Options) (string, error) {
list, _, err := filterEntitiesOfType(entityType, fmt.Sprintf(`id="%s"`, val), false, nil, o.Timeout, o.Verbose)
if err != nil {
return "", err
@@ -69,7 +70,7 @@ func mapIdToName(entityType string, val string, o edgeOptions) (string, error) {
return name, nil
}
func mapNamesToIDs(entityType string, o edgeOptions, list ...string) ([]string, error) {
func mapNamesToIDs(entityType string, o api.Options, list ...string) ([]string, error) {
var result []string
for _, val := range list {
if strings.HasPrefix(val, "id") {
@@ -103,10 +104,10 @@ func mapNamesToIDs(entityType string, o edgeOptions, list ...string) ([]string,
return result, nil
}
func mapIdentityNameToID(nameOrId string, o edgeOptions) (string, error) {
func mapIdentityNameToID(nameOrId string, o api.Options) (string, error) {
return mapNameToID("identities", nameOrId, o)
}
func mapCaNameToID(nameOrId string, o edgeOptions) (string, error) {
func mapCaNameToID(nameOrId string, o api.Options) (string, error) {
return mapNameToID("cas", nameOrId, o)
}
+6 -5
View File
@@ -17,12 +17,13 @@
package edge
import (
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"io"
"github.com/Jeffail/gabs"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
)
@@ -53,7 +54,7 @@ func newCreateCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Com
return cmd
}
// createEntityOfType create an entity of the given type on the Ziti Edge Controller
func createEntityOfType(entityType string, body string, options *edgeOptions) (*gabs.Container, error) {
return util.EdgeControllerCreate(entityType, body, options.Out, options.OutputJSONRequest, options.OutputJSONResponse, options.Timeout, options.Verbose)
// CreateEntityOfType create an entity of the given type on the Ziti Controller
func CreateEntityOfType(entityType string, body string, options *api.Options) (*gabs.Container, error) {
return util.ControllerCreate("edge", entityType, body, options.Out, options.OutputJSONRequest, options.OutputJSONResponse, options.Timeout, options.Verbose)
}
@@ -17,6 +17,7 @@
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
"github.com/spf13/cobra"
@@ -25,7 +26,7 @@ import (
// newCreateAuthenticatorCmd creates the 'edge controller create authenticator' command
func newCreateAuthenticatorCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := edgeOptions{
options := api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
OutputJSONResponse: false,
}
@@ -23,20 +23,21 @@ import (
"github.com/Jeffail/gabs"
"github.com/openziti/edge/rest_management_api_client/authenticator"
"github.com/openziti/foundation/util/term"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
)
type createAuthenticatorUpdb struct {
edgeOptions
api.Options
idOrName string
password string
username string
}
func newCreateAuthenticatorUpdb(idType string, options edgeOptions) *cobra.Command {
updbOptions := &createAuthenticatorUpdb{edgeOptions: options}
func newCreateAuthenticatorUpdb(idType string, options api.Options) *cobra.Command {
updbOptions := &createAuthenticatorUpdb{Options: options}
cmd := &cobra.Command{
Use: idType + " <identityIdOrName> <username> [<password>]",
@@ -81,7 +82,7 @@ func runCreateIdentityPassword(idType string, options *createAuthenticatorUpdb)
return errors.New("an identity must be specified")
}
identityId, err := mapIdentityNameToID(options.idOrName, options.edgeOptions)
identityId, err := mapIdentityNameToID(options.idOrName, options.Options)
if err != nil {
return err
@@ -122,12 +123,12 @@ func runCreateIdentityPassword(idType string, options *createAuthenticatorUpdb)
}
authenticatorData := gabs.New()
setJSONValue(authenticatorData, identityId, "identityId")
setJSONValue(authenticatorData, options.password, "password")
setJSONValue(authenticatorData, options.username, "username")
setJSONValue(authenticatorData, "updb", "method")
api.SetJSONValue(authenticatorData, identityId, "identityId")
api.SetJSONValue(authenticatorData, options.password, "password")
api.SetJSONValue(authenticatorData, options.username, "username")
api.SetJSONValue(authenticatorData, "updb", "method")
if _, err = createEntityOfType("authenticators", authenticatorData.String(), &options.edgeOptions); err != nil {
if _, err = CreateEntityOfType("authenticators", authenticatorData.String(), &options.Options); err != nil {
return err
}
+12 -11
View File
@@ -19,6 +19,7 @@ package edge
import (
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"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"
@@ -28,7 +29,7 @@ import (
)
type createCaOptions struct {
edgeOptions
api.Options
tags map[string]string
name string
caPath string
@@ -43,7 +44,7 @@ type createCaOptions struct {
// newCreateCaCmd creates the 'edge controller create ca local' command for the given entity type
func newCreateCaCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &createCaOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{
Factory: f,
Out: out,
@@ -99,17 +100,17 @@ func newCreateCaCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.C
func runCreateCa(options *createCaOptions) (err error) {
data := gabs.New()
setJSONValue(data, options.name, "name")
setJSONValue(data, options.autoCaEnrollment, "isAutoCaEnrollmentEnabled")
setJSONValue(data, options.ottCaEnrollment, "isOttCaEnrollmentEnabled")
setJSONValue(data, options.authEnabled, "isAuthEnabled")
setJSONValue(data, string(options.caPemBytes), "certPem")
setJSONValue(data, options.identityRoles, "identityRoles")
api.SetJSONValue(data, options.name, "name")
api.SetJSONValue(data, options.autoCaEnrollment, "isAutoCaEnrollmentEnabled")
api.SetJSONValue(data, options.ottCaEnrollment, "isOttCaEnrollmentEnabled")
api.SetJSONValue(data, options.authEnabled, "isAuthEnabled")
api.SetJSONValue(data, string(options.caPemBytes), "certPem")
api.SetJSONValue(data, options.identityRoles, "identityRoles")
if options.Cmd.Flag("identity-name-format").Changed {
setJSONValue(data, options.identityNameFormat, "identityNameFormat")
api.SetJSONValue(data, options.identityNameFormat, "identityNameFormat")
}
result, err := createEntityOfType("cas", data.String(), &options.edgeOptions)
return options.logCreateResult("ca", result, err)
result, err := CreateEntityOfType("cas", data.String(), &options.Options)
return options.LogCreateResult("ca", result, err)
}
+9 -8
View File
@@ -19,6 +19,7 @@ package edge
import (
"encoding/json"
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
"io/ioutil"
@@ -32,14 +33,14 @@ import (
)
type createConfigOptions struct {
edgeOptions
api.Options
jsonFile string
}
// newCreateConfigCmd creates the 'edge controller create service-policy' command
func newCreateConfigCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &createConfigOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
},
}
@@ -95,15 +96,15 @@ func runCreateConfig(o *createConfigOptions) error {
return errors.Errorf("unable to parse data as json: %v", err)
}
configTypeId, err := mapNameToID("config-types", o.Args[1], o.edgeOptions)
configTypeId, err := mapNameToID("config-types", o.Args[1], o.Options)
if err != nil {
return err
}
entityData := gabs.New()
setJSONValue(entityData, o.Args[0], "name")
setJSONValue(entityData, configTypeId, "configTypeId")
setJSONValue(entityData, dataMap, "data")
result, err := createEntityOfType("configs", entityData.String(), &o.edgeOptions)
return o.logCreateResult("config", result, err)
api.SetJSONValue(entityData, o.Args[0], "name")
api.SetJSONValue(entityData, configTypeId, "configTypeId")
api.SetJSONValue(entityData, dataMap, "data")
result, err := CreateEntityOfType("configs", entityData.String(), &o.Options)
return o.LogCreateResult("config", result, err)
}
+7 -6
View File
@@ -19,6 +19,7 @@ package edge
import (
"encoding/json"
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
"io/ioutil"
@@ -32,14 +33,14 @@ import (
)
type createConfigTypeOptions struct {
edgeOptions
api.Options
schemaFile string
}
// newCreateConfigTypeCmd creates the 'edge controller create service-policy' command
func newCreateConfigTypeCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &createConfigTypeOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
},
}
@@ -96,11 +97,11 @@ func runCreateConfigType(o *createConfigTypeOptions) error {
}
entityData := gabs.New()
setJSONValue(entityData, o.Args[0], "name")
api.SetJSONValue(entityData, o.Args[0], "name")
if schemaMap != nil {
setJSONValue(entityData, schemaMap, "schema")
api.SetJSONValue(entityData, schemaMap, "schema")
}
result, err := createEntityOfType("config-types", entityData.String(), &o.edgeOptions)
return o.logCreateResult("config type", result, err)
result, err := CreateEntityOfType("config-types", entityData.String(), &o.Options)
return o.LogCreateResult("config type", result, err)
}
+11 -10
View File
@@ -18,6 +18,7 @@ package edge
import (
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
"io/ioutil"
@@ -29,7 +30,7 @@ import (
)
type createEdgeRouterOptions struct {
edgeOptions
api.Options
isTunnelerEnabled bool
roleAttributes []string
jwtOutputFile string
@@ -39,7 +40,7 @@ type createEdgeRouterOptions struct {
func newCreateEdgeRouterCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &createEdgeRouterOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
},
}
@@ -75,14 +76,14 @@ func newCreateEdgeRouterCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer)
// runCreateEdgeRouter implements the command to create a gateway on the edge controller
func runCreateEdgeRouter(o *createEdgeRouterOptions) error {
entityData := gabs.New()
setJSONValue(entityData, o.Args[0], "name")
setJSONValue(entityData, o.isTunnelerEnabled, "isTunnelerEnabled")
setJSONValue(entityData, o.roleAttributes, "roleAttributes")
setJSONValue(entityData, o.tags, "tags")
setJSONValue(entityData, o.appData, "appData")
api.SetJSONValue(entityData, o.Args[0], "name")
api.SetJSONValue(entityData, o.isTunnelerEnabled, "isTunnelerEnabled")
api.SetJSONValue(entityData, o.roleAttributes, "roleAttributes")
api.SetJSONValue(entityData, o.tags, "tags")
api.SetJSONValue(entityData, o.appData, "appData")
result, err := createEntityOfType("edge-routers", entityData.String(), &o.edgeOptions)
if err := o.logCreateResult("edge router", result, err); err != nil {
result, err := CreateEntityOfType("edge-routers", entityData.String(), &o.Options)
if err := o.LogCreateResult("edge router", result, err); err != nil {
return err
}
@@ -96,7 +97,7 @@ func runCreateEdgeRouter(o *createEdgeRouterOptions) error {
}
func getEdgeRouterJwt(o *createEdgeRouterOptions, id string) error {
newRouter, err := DetailEntityOfType("edge-routers", id, o.OutputJSONResponse, o.Out, o.edgeOptions.Timeout, o.edgeOptions.Verbose)
newRouter, err := DetailEntityOfType("edge-routers", id, o.OutputJSONResponse, o.Out, o.Options.Timeout, o.Options.Verbose)
if err != nil {
return err
}
@@ -17,6 +17,7 @@
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
"github.com/Jeffail/gabs"
@@ -27,7 +28,7 @@ import (
)
type createEdgeRouterPolicyOptions struct {
edgeOptions
api.Options
edgeRouterRoles []string
identityRoles []string
semantic string
@@ -36,7 +37,7 @@ type createEdgeRouterPolicyOptions struct {
// newCreateEdgeRouterPolicyCmd creates the 'edge controller create edge-router-policy' command
func newCreateEdgeRouterPolicyCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &createEdgeRouterPolicyOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
},
}
@@ -68,24 +69,24 @@ func newCreateEdgeRouterPolicyCmd(f cmdutil.Factory, out io.Writer, errOut io.Wr
// runCreateEdgeRouterPolicy create a new edgeRouterPolicy on the Ziti Edge Controller
func runCreateEdgeRouterPolicy(o *createEdgeRouterPolicyOptions) error {
edgeRouterRoles, err := convertNamesToIds(o.edgeRouterRoles, "edge-routers", o.edgeOptions)
edgeRouterRoles, err := convertNamesToIds(o.edgeRouterRoles, "edge-routers", o.Options)
if err != nil {
return err
}
identityRoles, err := convertNamesToIds(o.identityRoles, "identities", o.edgeOptions)
identityRoles, err := convertNamesToIds(o.identityRoles, "identities", o.Options)
if err != nil {
return err
}
entityData := gabs.New()
setJSONValue(entityData, o.Args[0], "name")
setJSONValue(entityData, edgeRouterRoles, "edgeRouterRoles")
setJSONValue(entityData, identityRoles, "identityRoles")
api.SetJSONValue(entityData, o.Args[0], "name")
api.SetJSONValue(entityData, edgeRouterRoles, "edgeRouterRoles")
api.SetJSONValue(entityData, identityRoles, "identityRoles")
if o.semantic != "" {
setJSONValue(entityData, o.semantic, "semantic")
api.SetJSONValue(entityData, o.semantic, "semantic")
}
result, err := createEntityOfType("edge-router-policies", entityData.String(), &o.edgeOptions)
return o.logCreateResult("edge router policy", result, err)
result, err := CreateEntityOfType("edge-router-policies", entityData.String(), &o.Options)
return o.LogCreateResult("edge router policy", result, err)
}
+20 -19
View File
@@ -18,6 +18,7 @@ package edge
import (
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/pkg/errors"
"io"
"io/ioutil"
@@ -33,7 +34,7 @@ import (
)
type createIdentityOptions struct {
edgeOptions
api.Options
isAdmin bool
roleAttributes []string
jwtOutputFile string
@@ -50,7 +51,7 @@ type createIdentityOptions struct {
func newCreateIdentityCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
newOptions := func() *createIdentityOptions {
return &createIdentityOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
},
}
@@ -104,19 +105,19 @@ func newCreateIdentityOfTypeCmd(idType string, options *createIdentityOptions) *
func runCreateIdentity(idType string, o *createIdentityOptions) error {
entityData := gabs.New()
setJSONValue(entityData, o.Args[0], "name")
setJSONValue(entityData, strings.Title(idType), "type")
api.SetJSONValue(entityData, o.Args[0], "name")
api.SetJSONValue(entityData, strings.Title(idType), "type")
o.username = strings.TrimSpace(o.username)
if o.username != "" {
setJSONValue(entityData, o.username, "enrollment", "updb")
api.SetJSONValue(entityData, o.username, "enrollment", "updb")
} else {
setJSONValue(entityData, true, "enrollment", "ott")
api.SetJSONValue(entityData, true, "enrollment", "ott")
}
setJSONValue(entityData, o.isAdmin, "isAdmin")
setJSONValue(entityData, o.roleAttributes, "roleAttributes")
setJSONValue(entityData, o.tags, "tags")
setJSONValue(entityData, o.appData, "appData")
api.SetJSONValue(entityData, o.isAdmin, "isAdmin")
api.SetJSONValue(entityData, o.roleAttributes, "roleAttributes")
api.SetJSONValue(entityData, o.tags, "tags")
api.SetJSONValue(entityData, o.appData, "appData")
if o.defaultHostingPrecedence != "" {
prec, err := normalizeAndValidatePrecedence(o.defaultHostingPrecedence)
@@ -124,26 +125,26 @@ func runCreateIdentity(idType string, o *createIdentityOptions) error {
return err
}
setJSONValue(entityData, prec, "defaultHostingPrecedence")
api.SetJSONValue(entityData, prec, "defaultHostingPrecedence")
}
setJSONValue(entityData, o.defaultHostingCost, "defaultHostingCost")
api.SetJSONValue(entityData, o.defaultHostingCost, "defaultHostingCost")
for k, v := range o.serviceCosts {
if v < 0 || v > math.MaxUint16 {
return errors.Errorf("hosting costs must be in the range %v-%v", 0, math.MaxUint16)
}
id, err := mapNameToID("services", k, o.edgeOptions)
id, err := mapNameToID("services", k, o.Options)
if err != nil {
return err
}
delete(o.serviceCosts, k)
o.serviceCosts[id] = v
}
setJSONValue(entityData, o.serviceCosts, "serviceHostingCosts")
api.SetJSONValue(entityData, o.serviceCosts, "serviceHostingCosts")
for k, v := range o.servicePrecedences {
id, err := mapNameToID("services", k, o.edgeOptions)
id, err := mapNameToID("services", k, o.Options)
if err != nil {
return err
}
@@ -156,16 +157,16 @@ func runCreateIdentity(idType string, o *createIdentityOptions) error {
delete(o.servicePrecedences, k)
o.servicePrecedences[id] = prec
}
setJSONValue(entityData, o.servicePrecedences, "serviceHostingPrecedences")
api.SetJSONValue(entityData, o.servicePrecedences, "serviceHostingPrecedences")
result, err := createEntityOfType("identities", entityData.String(), &o.edgeOptions)
if err := o.logCreateResult("identity", result, err); err != nil {
result, err := CreateEntityOfType("identities", entityData.String(), &o.Options)
if err := o.LogCreateResult("identity", result, err); err != nil {
return err
}
if o.jwtOutputFile != "" {
id := result.S("data", "id").Data().(string)
if err := getIdentityJwt(o, id, o.edgeOptions.Timeout, o.edgeOptions.Verbose); err != nil {
if err := getIdentityJwt(o, id, o.Options.Timeout, o.Options.Verbose); err != nil {
return err
}
}
+25 -24
View File
@@ -21,6 +21,7 @@ import (
"github.com/Jeffail/gabs"
"github.com/openziti/edge/rest_management_api_client/posture_checks"
"github.com/openziti/edge/rest_model"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
@@ -47,7 +48,7 @@ func newCreatePostureCheckCmd(out io.Writer, errOut io.Writer) *cobra.Command {
}
type createPostureCheckOptions struct {
edgeOptions
api.Options
name string
tags map[string]string
roleAttributes []string
@@ -108,7 +109,7 @@ func (options *createPostureCheckOptions) addPostureFlags(cmd *cobra.Command) {
func newCreatePostureCheckMacCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &createPostureCheckMacOptions{
createPostureCheckOptions: createPostureCheckOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{
Out: out,
Err: errOut,
@@ -147,7 +148,7 @@ func newCreatePostureCheckMacCmd(out io.Writer, errOut io.Writer) *cobra.Command
func newCreatePostureCheckDomainCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &createPostureCheckDomainOptions{
createPostureCheckOptions: createPostureCheckOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{
Out: out,
Err: errOut,
@@ -186,7 +187,7 @@ func newCreatePostureCheckDomainCmd(out io.Writer, errOut io.Writer) *cobra.Comm
func newCreatePostureCheckProcessCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &createPostureCheckProcessOptions{
createPostureCheckOptions: createPostureCheckOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{
Out: out,
Err: errOut,
@@ -239,7 +240,7 @@ func newCreatePostureCheckProcessCmd(out io.Writer, errOut io.Writer) *cobra.Com
func newCreatePostureCheckProcessMultiCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &createPostureCheckProcessMultiOptions{
createPostureCheckOptions: createPostureCheckOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{
Out: out,
Err: errOut,
@@ -433,8 +434,8 @@ func runCreatePostureCheckProcess(o *createPostureCheckProcessOptions) error {
entityData := gabs.New()
setPostureCheckEntityValues(entityData, &o.createPostureCheckOptions, PostureCheckTypeProcess)
setJSONValue(entityData, o.normalizedOs, "process", "osType")
setJSONValue(entityData, o.path, "process", "path")
api.SetJSONValue(entityData, o.normalizedOs, "process", "osType")
api.SetJSONValue(entityData, o.path, "process", "path")
hashes, err := cleanSha512s(o.hashes)
@@ -443,7 +444,7 @@ func runCreatePostureCheckProcess(o *createPostureCheckProcessOptions) error {
}
if len(hashes) > 0 {
setJSONValue(entityData, hashes, "process", "hashes")
api.SetJSONValue(entityData, hashes, "process", "hashes")
}
if o.signer != "" {
@@ -453,11 +454,11 @@ func runCreatePostureCheckProcess(o *createPostureCheckProcessOptions) error {
return err
}
setJSONValue(entityData, cleanSigner, "process", "signerFingerprint")
api.SetJSONValue(entityData, cleanSigner, "process", "signerFingerprint")
}
result, err := createEntityOfType("posture-checks", entityData.String(), &o.edgeOptions)
return o.logCreateResult("posture check", result, err)
result, err := CreateEntityOfType("posture-checks", entityData.String(), &o.Options)
return o.LogCreateResult("posture check", result, err)
}
func runCreatePostureCheckProcessMulti(options *createPostureCheckProcessMultiOptions) error {
@@ -514,10 +515,10 @@ func runCreatePostureCheckProcessMulti(options *createPostureCheckProcessMultiOp
}
func setPostureCheckEntityValues(entity *gabs.Container, options *createPostureCheckOptions, typeId string) {
setJSONValue(entity, options.Args[0], "name")
setJSONValue(entity, options.roleAttributes, "roleAttributes")
setJSONValue(entity, options.tags, "tags")
setJSONValue(entity, typeId, "typeId")
api.SetJSONValue(entity, options.Args[0], "name")
api.SetJSONValue(entity, options.roleAttributes, "roleAttributes")
api.SetJSONValue(entity, options.tags, "tags")
api.SetJSONValue(entity, typeId, "typeId")
}
func cleanMacAddresses(inAddresses []string) ([]string, error) {
@@ -557,9 +558,9 @@ func runCreatePostureCheckMac(o *createPostureCheckMacOptions) (err error) {
return fmt.Errorf("must specify at least one MAC Address, multiple values may be separated by commas")
}
setJSONValue(entityData, addresses, "macAddresses")
api.SetJSONValue(entityData, addresses, "macAddresses")
result, err := createEntityOfType("posture-checks", entityData.String(), &o.edgeOptions)
result, err := CreateEntityOfType("posture-checks", entityData.String(), &o.Options)
if err != nil {
panic(err)
@@ -603,9 +604,9 @@ func runCreatePostureCheckDomain(o *createPostureCheckDomainOptions) (err error)
return fmt.Errorf("must specify at least one domain, multiple values may be separated by commas or multiple flags")
}
setJSONValue(entityData, domains, "domains")
api.SetJSONValue(entityData, domains, "domains")
result, err := createEntityOfType("posture-checks", entityData.String(), &o.edgeOptions)
result, err := CreateEntityOfType("posture-checks", entityData.String(), &o.Options)
if err != nil {
panic(err)
@@ -624,7 +625,7 @@ func newCreatePostureCheckOsCmd(out io.Writer, errOut io.Writer) *cobra.Command
options := &createPostureCheckOsOptions{
createPostureCheckOptions: createPostureCheckOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{
Out: out,
Err: errOut,
@@ -677,9 +678,9 @@ func runCreatePostureCheckOs(o *createPostureCheckOsOptions) error {
entityData := gabs.New()
setPostureCheckEntityValues(entityData, &o.createPostureCheckOptions, PostureCheckTypeOS)
setJSONValue(entityData, osSpecs, "operatingSystems")
api.SetJSONValue(entityData, osSpecs, "operatingSystems")
result, err := createEntityOfType("posture-checks", entityData.String(), &o.edgeOptions)
result, err := CreateEntityOfType("posture-checks", entityData.String(), &o.Options)
if err != nil {
panic(err)
@@ -728,7 +729,7 @@ func parseOsSpec(osSpecStr string) (*osSpec, error) {
func newCreatePostureCheckMfaCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := createPostureCheckMfaOptions{
createPostureCheckOptions: createPostureCheckOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{
Out: out,
Err: errOut,
@@ -782,7 +783,7 @@ func runCreatePostureCheckMfa(o *createPostureCheckMfaOptions) error {
setPostureCheckEntityValues(entityData, &o.createPostureCheckOptions, PostureCheckTypeMFA)
result, err := createEntityOfType("posture-checks", entityData.String(), &o.edgeOptions)
result, err := CreateEntityOfType("posture-checks", entityData.String(), &o.Options)
if err != nil {
panic(err)
+12 -11
View File
@@ -18,6 +18,7 @@ package edge
import (
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"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"
@@ -26,7 +27,7 @@ import (
)
type createServiceOptions struct {
edgeOptions
api.Options
terminatorStrategy string
tags map[string]string
roleAttributes []string
@@ -38,7 +39,7 @@ type createServiceOptions struct {
// newCreateServiceCmd creates the 'edge controller create service local' command for the given entity type
func newCreateServiceCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &createServiceOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{
Factory: f,
Out: out,
@@ -77,23 +78,23 @@ func newCreateServiceCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *co
// runCreateService implements the command to create a service
func runCreateService(o *createServiceOptions) (err error) {
configs, err := mapNamesToIDs("configs", o.edgeOptions, o.configs...)
configs, err := mapNamesToIDs("configs", o.Options, o.configs...)
if err != nil {
return err
}
entityData := gabs.New()
setJSONValue(entityData, o.Args[0], "name")
api.SetJSONValue(entityData, o.Args[0], "name")
if o.terminatorStrategy != "" {
setJSONValue(entityData, o.terminatorStrategy, "terminatorStrategy")
api.SetJSONValue(entityData, o.terminatorStrategy, "terminatorStrategy")
}
setJSONValue(entityData, o.encryption.Get(), "encryptionRequired")
api.SetJSONValue(entityData, o.encryption.Get(), "encryptionRequired")
setJSONValue(entityData, o.roleAttributes, "roleAttributes")
setJSONValue(entityData, configs, "configs")
setJSONValue(entityData, o.tags, "tags")
api.SetJSONValue(entityData, o.roleAttributes, "roleAttributes")
api.SetJSONValue(entityData, configs, "configs")
api.SetJSONValue(entityData, o.tags, "tags")
result, err := createEntityOfType("services", entityData.String(), &o.edgeOptions)
return o.logCreateResult("service", result, err)
result, err := CreateEntityOfType("services", entityData.String(), &o.Options)
return o.LogCreateResult("service", result, err)
}
@@ -17,6 +17,7 @@
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
"github.com/Jeffail/gabs"
@@ -27,7 +28,7 @@ import (
)
type createServiceEdgeRouterPolicyOptions struct {
edgeOptions
api.Options
edgeRouterRoles []string
serviceRoles []string
semantic string
@@ -36,7 +37,7 @@ type createServiceEdgeRouterPolicyOptions struct {
// newCreateServiceEdgeRouterPolicyCmd creates the 'edge controller create service-edge-router-policy' command
func newCreateServiceEdgeRouterPolicyCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &createServiceEdgeRouterPolicyOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
},
}
@@ -68,23 +69,23 @@ func newCreateServiceEdgeRouterPolicyCmd(f cmdutil.Factory, out io.Writer, errOu
// runCreateServiceEdgeRouterPolicy create a new edgeRouterPolicy on the Ziti Edge Controller
func runCreateServiceEdgeRouterPolicy(o *createServiceEdgeRouterPolicyOptions) error {
edgeRouterRoles, err := convertNamesToIds(o.edgeRouterRoles, "edge-routers", o.edgeOptions)
edgeRouterRoles, err := convertNamesToIds(o.edgeRouterRoles, "edge-routers", o.Options)
if err != nil {
return err
}
serviceRoles, err := convertNamesToIds(o.serviceRoles, "services", o.edgeOptions)
serviceRoles, err := convertNamesToIds(o.serviceRoles, "services", o.Options)
if err != nil {
return err
}
entityData := gabs.New()
setJSONValue(entityData, o.Args[0], "name")
setJSONValue(entityData, edgeRouterRoles, "edgeRouterRoles")
setJSONValue(entityData, serviceRoles, "serviceRoles")
api.SetJSONValue(entityData, o.Args[0], "name")
api.SetJSONValue(entityData, edgeRouterRoles, "edgeRouterRoles")
api.SetJSONValue(entityData, serviceRoles, "serviceRoles")
if o.semantic != "" {
setJSONValue(entityData, o.semantic, "semantic")
api.SetJSONValue(entityData, o.semantic, "semantic")
}
result, err := createEntityOfType("service-edge-router-policies", entityData.String(), &o.edgeOptions)
return o.logCreateResult("service edge router policy", result, err)
result, err := CreateEntityOfType("service-edge-router-policies", entityData.String(), &o.Options)
return o.LogCreateResult("service edge router policy", result, err)
}
+15 -14
View File
@@ -17,6 +17,7 @@
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
"strings"
@@ -29,7 +30,7 @@ import (
)
type createServicePolicyOptions struct {
edgeOptions
api.Options
serviceRoles []string
identityRoles []string
postureCheckRoles []string
@@ -39,7 +40,7 @@ type createServicePolicyOptions struct {
// newCreateServicePolicyCmd creates the 'edge controller create service-policy' command
func newCreateServicePolicyCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &createServicePolicyOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -77,36 +78,36 @@ func runCreateServicePolicy(o *createServicePolicyOptions) error {
return errors.Errorf("Invalid policy type '%v'. Valid values: [Bind, Dial]", policyType)
}
serviceRoles, err := convertNamesToIds(o.serviceRoles, "services", o.edgeOptions)
serviceRoles, err := convertNamesToIds(o.serviceRoles, "services", o.Options)
if err != nil {
return err
}
identityRoles, err := convertNamesToIds(o.identityRoles, "identities", o.edgeOptions)
identityRoles, err := convertNamesToIds(o.identityRoles, "identities", o.Options)
if err != nil {
return err
}
postureCheckRoles, err := convertNamesToIds(o.postureCheckRoles, "posture-checks", o.edgeOptions)
postureCheckRoles, err := convertNamesToIds(o.postureCheckRoles, "posture-checks", o.Options)
if err != nil {
return err
}
entityData := gabs.New()
setJSONValue(entityData, o.Args[0], "name")
setJSONValue(entityData, o.Args[1], "type")
setJSONValue(entityData, serviceRoles, "serviceRoles")
setJSONValue(entityData, identityRoles, "identityRoles")
setJSONValue(entityData, postureCheckRoles, "postureCheckRoles")
api.SetJSONValue(entityData, o.Args[0], "name")
api.SetJSONValue(entityData, o.Args[1], "type")
api.SetJSONValue(entityData, serviceRoles, "serviceRoles")
api.SetJSONValue(entityData, identityRoles, "identityRoles")
api.SetJSONValue(entityData, postureCheckRoles, "postureCheckRoles")
if o.semantic != "" {
setJSONValue(entityData, o.semantic, "semantic")
api.SetJSONValue(entityData, o.semantic, "semantic")
}
result, err := createEntityOfType("service-policies", entityData.String(), &o.edgeOptions)
return o.logCreateResult("service policy", result, err)
result, err := CreateEntityOfType("service-policies", entityData.String(), &o.Options)
return o.LogCreateResult("service policy", result, err)
}
func convertNamesToIds(roles []string, entityType string, o edgeOptions) ([]string, error) {
func convertNamesToIds(roles []string, entityType string, o api.Options) ([]string, error) {
var result []string
for _, val := range roles {
if strings.HasPrefix(val, "@") {
+13 -12
View File
@@ -21,6 +21,7 @@ import (
"github.com/Jeffail/gabs"
"github.com/openziti/edge/router/xgress_edge_transport"
"github.com/openziti/foundation/util/stringz"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"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"
@@ -30,7 +31,7 @@ import (
)
type createTerminatorOptions struct {
edgeOptions
api.Options
binding string
cost int32
precedence string
@@ -40,7 +41,7 @@ type createTerminatorOptions struct {
// newCreateTerminatorCmd creates the 'edge controller create Terminator local' command for the given entity type
func newCreateTerminatorCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &createTerminatorOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{
Factory: f,
Out: out,
@@ -77,21 +78,21 @@ func newCreateTerminatorCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer)
// runCreateTerminator implements the command to create a Terminator
func runCreateTerminator(o *createTerminatorOptions) (err error) {
entityData := gabs.New()
service, err := mapNameToID("services", o.Args[0], o.edgeOptions)
service, err := mapNameToID("services", o.Args[0], o.Options)
if err != nil {
return err
}
router, err := mapNameToID("edge-routers", o.Args[1], o.edgeOptions)
router, err := mapNameToID("edge-routers", o.Args[1], o.Options)
if err != nil {
router = o.Args[1] // might be a pure fabric router, id might not be UUID
}
setJSONValue(entityData, service, "service")
setJSONValue(entityData, router, "router")
setJSONValue(entityData, o.binding, "binding")
setJSONValue(entityData, o.Args[2], "address")
setJSONValue(entityData, o.identity, "identity")
api.SetJSONValue(entityData, service, "service")
api.SetJSONValue(entityData, router, "router")
api.SetJSONValue(entityData, o.binding, "binding")
api.SetJSONValue(entityData, o.Args[2], "address")
api.SetJSONValue(entityData, o.identity, "identity")
if o.cost > 0 {
if o.cost > math.MaxUint16 {
if _, err = fmt.Fprintf(o.Out, "Invalid cost %v. Must be positive number less than or equal to %v\n", o.cost, math.MaxUint16); err != nil {
@@ -99,7 +100,7 @@ func runCreateTerminator(o *createTerminatorOptions) (err error) {
}
return
}
setJSONValue(entityData, o.cost, "cost")
api.SetJSONValue(entityData, o.cost, "cost")
}
if o.precedence != "" {
validValues := []string{"default", "required", "failed"}
@@ -109,10 +110,10 @@ func runCreateTerminator(o *createTerminatorOptions) (err error) {
}
return
}
setJSONValue(entityData, o.precedence, "precedence")
api.SetJSONValue(entityData, o.precedence, "precedence")
}
result, err := createEntityOfType("terminators", entityData.String(), &o.edgeOptions)
result, err := CreateEntityOfType("terminators", entityData.String(), &o.Options)
if err != nil {
return err
}
+6 -5
View File
@@ -3,6 +3,7 @@ package edge
import (
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
@@ -13,13 +14,13 @@ import (
)
type dbCheckIntegrityOptions struct {
edgeOptions
api.Options
fix bool
}
func newDbCheckIntegrityCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &dbCheckIntegrityOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -53,7 +54,7 @@ func runCheckIntegrityDb(o *dbCheckIntegrityOptions) error {
target = "database/check-data-integrity"
}
if _, err := util.EdgeControllerUpdate(target, "", o.Out, http.MethodPost, o.OutputJSONRequest, o.OutputJSONResponse, o.edgeOptions.Timeout, o.edgeOptions.Verbose); err != nil {
if _, err := util.ControllerUpdate("edge", target, "", o.Out, http.MethodPost, o.OutputJSONRequest, o.OutputJSONResponse, o.Options.Timeout, o.Options.Verbose); err != nil {
return err
}
@@ -63,7 +64,7 @@ func runCheckIntegrityDb(o *dbCheckIntegrityOptions) error {
func newDbCheckIntegrityStatusCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &dbCheckIntegrityOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -89,7 +90,7 @@ func newDbCheckIntegrityStatusCmd(out io.Writer, errOut io.Writer) *cobra.Comman
}
func runCheckIntegrityStatus(o *dbCheckIntegrityOptions) error {
body, err := util.EdgeControllerList("database/data-integrity-results", nil, o.OutputJSONResponse, o.Out, o.edgeOptions.Timeout, o.edgeOptions.Verbose)
body, err := util.EdgeControllerList("database/data-integrity-results", nil, o.OutputJSONResponse, o.Out, o.Options.Timeout, o.Options.Verbose)
if err != nil {
return err
}
+4 -3
View File
@@ -17,6 +17,7 @@
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
@@ -26,12 +27,12 @@ import (
)
type dbSnapshotOptions struct {
edgeOptions
api.Options
}
func newDbSnapshotCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &dbSnapshotOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -57,6 +58,6 @@ func newDbSnapshotCmd(out io.Writer, errOut io.Writer) *cobra.Command {
}
func runSnapshotDb(o *dbSnapshotOptions) error {
_, err := util.EdgeControllerUpdate("database/snapshot", "", o.Out, http.MethodPost, false, false, o.edgeOptions.Timeout, o.edgeOptions.Verbose)
_, err := util.ControllerUpdate("edge", "database/snapshot", "", o.Out, http.MethodPost, false, false, o.Options.Timeout, o.Options.Verbose)
return err
}
+11 -11
View File
@@ -19,11 +19,11 @@ package edge
import (
"github.com/fatih/color"
"github.com/openziti/foundation/storage/boltz"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
"net/url"
"strings"
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
@@ -42,8 +42,8 @@ func newDeleteCmd(out io.Writer, errOut io.Writer) *cobra.Command {
},
}
newOptions := func() *edgeOptions {
return &edgeOptions{
newOptions := func() *api.Options {
return &api.Options{
CommonOptions: common.CommonOptions{
Out: out,
Err: errOut,
@@ -70,7 +70,7 @@ func newDeleteCmd(out io.Writer, errOut io.Writer) *cobra.Command {
}
// newDeleteCmdForEntityType creates the delete command for the given entity type
func newDeleteCmdForEntityType(entityType string, options *edgeOptions, aliases ...string) *cobra.Command {
func newDeleteCmdForEntityType(entityType string, options *api.Options, aliases ...string) *cobra.Command {
cmd := &cobra.Command{
Use: entityType + " <id>",
Short: "deletes " + getPlural(entityType) + " managed by the Ziti Edge Controller",
@@ -94,7 +94,7 @@ func newDeleteCmdForEntityType(entityType string, options *edgeOptions, aliases
return cmd
}
func newDeleteWhereCmdForEntityType(entityType string, options *edgeOptions) *cobra.Command {
func newDeleteWhereCmdForEntityType(entityType string, options *api.Options) *cobra.Command {
cmd := &cobra.Command{
Use: "where <filter>",
Short: "deletes " + getPlural(entityType) + " matching the filter managed by the Ziti Edge Controller",
@@ -116,7 +116,7 @@ func newDeleteWhereCmdForEntityType(entityType string, options *edgeOptions) *co
}
// runDeleteEntityOfType implements the commands to delete various entity types
func runDeleteEntityOfType(o *edgeOptions, entityType string) error {
func runDeleteEntityOfType(o *api.Options, entityType string) error {
var err error
ids := o.Args
if entityType != "terminators" && entityType != "api-sessions" && entityType != "sessions" {
@@ -128,9 +128,9 @@ func runDeleteEntityOfType(o *edgeOptions, entityType string) error {
return deleteEntitiesOfType(o, entityType, ids)
}
func deleteEntitiesOfType(o *edgeOptions, entityType string, ids []string) error {
func deleteEntitiesOfType(o *api.Options, entityType string, ids []string) error {
for _, id := range ids {
_, err := util.EdgeControllerDelete(entityType, id, o.Out, o.OutputJSONResponse, o.Timeout, o.Verbose)
err := util.ControllerDelete("edge", entityType, id, "", o.Out, o.OutputJSONRequest, o.OutputJSONResponse, o.Timeout, o.Verbose)
if err != nil {
o.Printf("delete of %v with id %v: %v\n", boltz.GetSingularEntityType(entityType), id, color.New(color.FgRed, color.Bold).Sprint("FAIL"))
return err
@@ -141,7 +141,7 @@ func deleteEntitiesOfType(o *edgeOptions, entityType string, ids []string) error
}
// runDeleteEntityOfType implements the commands to delete various entity types
func runDeleteEntityOfTypeWhere(options *edgeOptions, entityType string) error {
func runDeleteEntityOfTypeWhere(options *api.Options, entityType string) error {
filter := strings.Join(options.Args, " ")
params := url.Values{}
@@ -171,6 +171,6 @@ func getPlural(entityType string) string {
return entityType + "s"
}
func deleteEntityOfType(entityType string, id string, options *edgeOptions) (*gabs.Container, error) {
return util.EdgeControllerDelete(entityType, id, options.Out, options.OutputJSONResponse, options.Timeout, options.Verbose)
func deleteEntityOfType(entityType string, id string, options *api.Options) error {
return util.ControllerDelete("edge", entityType, id, "", options.Out, options.OutputJSONRequest, options.OutputJSONResponse, options.Timeout, options.Verbose)
}
@@ -17,10 +17,11 @@
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/spf13/cobra"
)
func newDeleteAuthenticatorCmd(idType string, options *edgeOptions) *cobra.Command {
func newDeleteAuthenticatorCmd(idType string, options *api.Options) *cobra.Command {
cmd := &cobra.Command{
Use: idType,
@@ -20,18 +20,19 @@ import (
"context"
"fmt"
"github.com/openziti/edge/rest_management_api_client/authenticator"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
)
import cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
type deleteUpdbOptions struct {
edgeOptions
api.Options
}
func newDeleteAuthenticatorUpdb(idType string, options *edgeOptions) *cobra.Command {
func newDeleteAuthenticatorUpdb(idType string, options *api.Options) *cobra.Command {
updbOptions := deleteUpdbOptions{
edgeOptions: *options,
Options: *options,
}
cmd := &cobra.Command{
@@ -55,7 +56,7 @@ func newDeleteAuthenticatorUpdb(idType string, options *edgeOptions) *cobra.Comm
}
func runDeleteUpdb(idOrName string, options *deleteUpdbOptions) error {
identityId, err := mapIdentityNameToID(idOrName, options.edgeOptions)
identityId, err := mapIdentityNameToID(idOrName, options.Options)
if err != nil {
return err
@@ -91,7 +92,7 @@ func runDeleteUpdb(idOrName string, options *deleteUpdbOptions) error {
authenticatorId := *result.Payload.Data[0].ID
_, err = deleteEntityOfType(fmt.Sprintf("authenticators/%s", authenticatorId), "", &options.edgeOptions)
err = deleteEntityOfType(fmt.Sprintf("authenticators/%s", authenticatorId), "", &options.Options)
if err != nil {
return err
+1 -1
View File
@@ -23,7 +23,7 @@ import (
)
func DetailEntityOfType(entityType, entityId string, logJSON bool, out io.Writer, timeout int, verbose bool) (*gabs.Container, error) {
jsonParsed, err := util.EdgeControllerDetailEntity(entityType, entityId, logJSON, out, timeout, verbose)
jsonParsed, err := util.ControllerDetailEntity("edge", entityType, entityId, logJSON, out, timeout, verbose)
if err != nil {
return nil, err
+45 -44
View File
@@ -23,6 +23,7 @@ import (
"github.com/openziti/edge/rest_management_api_client/certificate_authority"
"github.com/openziti/edge/rest_model"
"github.com/openziti/foundation/util/errorz"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
@@ -46,8 +47,8 @@ func newListCmd(out io.Writer, errOut io.Writer) *cobra.Command {
},
}
newOptions := func() *edgeOptions {
return &edgeOptions{
newOptions := func() *api.Options {
return &api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
}
}
@@ -145,7 +146,7 @@ func newPagingInfo(meta *rest_model.Meta) paging {
return paging{}
}
func (p *paging) output(o *edgeOptions) {
func (p *paging) output(o *api.Options) {
if p.HasError() {
_, _ = fmt.Fprintf(o.Out, "unable to retrieve paging information: %v\n", p.Err)
} else if p.count == 0 {
@@ -160,9 +161,9 @@ func (p *paging) output(o *edgeOptions) {
}
}
type listCommandRunner func(*edgeOptions) error
type listCommandRunner func(*api.Options) error
type outputFunction func(o *edgeOptions, children []*gabs.Container, pagingInfo *paging) error
type outputFunction func(o *api.Options, children []*gabs.Container, pagingInfo *paging) error
func newEntityListRootCmd(entityType string, aliases ...string) *cobra.Command {
desc := fmt.Sprintf("list entities related to a %v instance managed by the Ziti Edge Controller", entityType)
@@ -179,7 +180,7 @@ func newEntityListRootCmd(entityType string, aliases ...string) *cobra.Command {
}
// newListCmdForEntityType creates the list command for the given entity type
func newListCmdForEntityType(entityType string, command listCommandRunner, options *edgeOptions, aliases ...string) *cobra.Command {
func newListCmdForEntityType(entityType string, command listCommandRunner, options *api.Options, aliases ...string) *cobra.Command {
cmd := &cobra.Command{
Use: entityType + " <filter>?",
Short: "lists " + entityType + " managed by the Ziti Edge Controller",
@@ -203,7 +204,7 @@ func newListCmdForEntityType(entityType string, command listCommandRunner, optio
}
// newListServicesCmd creates the list command for the given entity type
func newListServicesCmd(options *edgeOptions) *cobra.Command {
func newListServicesCmd(options *api.Options) *cobra.Command {
var asIdentity string
var configTypes []string
var roleFilters []string
@@ -235,7 +236,7 @@ func newListServicesCmd(options *edgeOptions) *cobra.Command {
}
// newListEdgeRoutersCmd creates the list command for the given entity type
func newListEdgeRoutersCmd(options *edgeOptions) *cobra.Command {
func newListEdgeRoutersCmd(options *api.Options) *cobra.Command {
var roleFilters []string
var roleSemantic string
@@ -264,7 +265,7 @@ func newListEdgeRoutersCmd(options *edgeOptions) *cobra.Command {
}
// newListEdgeRoutersCmd creates the list command for the given entity type
func newListIdentitiesCmd(options *edgeOptions) *cobra.Command {
func newListIdentitiesCmd(options *api.Options) *cobra.Command {
var roleFilters []string
var roleSemantic string
@@ -292,7 +293,7 @@ func newListIdentitiesCmd(options *edgeOptions) *cobra.Command {
}
// newSubListCmdForEntityType creates the list command for the given entity type
func newSubListCmdForEntityType(entityType string, subType string, outputF outputFunction, options *edgeOptions) *cobra.Command {
func newSubListCmdForEntityType(entityType string, subType string, outputF outputFunction, options *api.Options) *cobra.Command {
desc := fmt.Sprintf("lists %v related to a %v instanced managed by the Ziti Edge Controller", subType, entityType)
cmd := &cobra.Command{
Use: fmt.Sprintf("%v <id or name>", subType),
@@ -316,7 +317,7 @@ func newSubListCmdForEntityType(entityType string, subType string, outputF outpu
}
// listEntitiesOfType queries the Ziti Controller for entities of the given type
func listEntitiesWithOptions(entityType string, options *edgeOptions) ([]*gabs.Container, *paging, error) {
func listEntitiesWithOptions(entityType string, options *api.Options) ([]*gabs.Container, *paging, error) {
params := url.Values{}
if len(options.Args) > 0 {
params.Add("filter", options.Args[0])
@@ -377,7 +378,7 @@ func getPaging(c *gabs.Container) *paging {
}
// listEntitiesOfType queries the Ziti Controller for entities of the given type
func filterSubEntitiesOfType(entityType, subType, entityId, filter string, o *edgeOptions) ([]*gabs.Container, *paging, error) {
func filterSubEntitiesOfType(entityType, subType, entityId, filter string, o *api.Options) ([]*gabs.Container, *paging, error) {
jsonParsed, err := util.EdgeControllerListSubEntities(entityType, subType, entityId, filter, o.OutputJSONResponse, o.Out, o.Timeout, o.Verbose)
if err != nil {
@@ -391,7 +392,7 @@ func filterSubEntitiesOfType(entityType, subType, entityId, filter string, o *ed
return children, getPaging(jsonParsed), err
}
func runListEdgeRouters(roleFilters []string, roleSemantic string, options *edgeOptions) error {
func runListEdgeRouters(roleFilters []string, roleSemantic string, options *api.Options) error {
params := url.Values{}
if len(options.Args) > 0 {
params.Add("filter", options.Args[0])
@@ -410,7 +411,7 @@ func runListEdgeRouters(roleFilters []string, roleSemantic string, options *edge
return outputEdgeRouters(options, children, paging)
}
func outputEdgeRouters(o *edgeOptions, children []*gabs.Container, pagingInfo *paging) error {
func outputEdgeRouters(o *api.Options, children []*gabs.Container, pagingInfo *paging) error {
if o.OutputJSONResponse {
return nil
}
@@ -428,7 +429,7 @@ func outputEdgeRouters(o *edgeOptions, children []*gabs.Container, pagingInfo *p
return nil
}
func runListEdgeRouterPolicies(o *edgeOptions) error {
func runListEdgeRouterPolicies(o *api.Options) error {
children, paging, err := listEntitiesWithOptions("edge-router-policies", o)
if err != nil {
return err
@@ -436,7 +437,7 @@ func runListEdgeRouterPolicies(o *edgeOptions) error {
return outputEdgeRouterPolicies(o, children, paging)
}
func outputEdgeRouterPolicies(o *edgeOptions, children []*gabs.Container, pagingInfo *paging) error {
func outputEdgeRouterPolicies(o *api.Options, children []*gabs.Container, pagingInfo *paging) error {
if o.OutputJSONResponse {
return nil
}
@@ -464,7 +465,7 @@ func outputEdgeRouterPolicies(o *edgeOptions, children []*gabs.Container, paging
return nil
}
func runListTerminators(o *edgeOptions) error {
func runListTerminators(o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions("terminators", o)
if err != nil {
return err
@@ -472,7 +473,7 @@ func runListTerminators(o *edgeOptions) error {
return outputTerminators(o, children, pagingInfo)
}
func outputTerminators(o *edgeOptions, children []*gabs.Container, pagingInfo *paging) error {
func outputTerminators(o *api.Options, children []*gabs.Container, pagingInfo *paging) error {
if o.OutputJSONResponse {
return nil
}
@@ -497,7 +498,7 @@ func outputTerminators(o *edgeOptions, children []*gabs.Container, pagingInfo *p
return nil
}
func runListServices(asIdentity string, configTypes []string, roleFilters []string, roleSemantic string, options *edgeOptions) error {
func runListServices(asIdentity string, configTypes []string, roleFilters []string, roleSemantic string, options *api.Options) error {
params := url.Values{}
if len(options.Args) > 0 {
params.Add("filter", options.Args[0])
@@ -530,7 +531,7 @@ func runListServices(asIdentity string, configTypes []string, roleFilters []stri
return outputServices(options, children, pagingInfo)
}
func outputServices(o *edgeOptions, children []*gabs.Container, pagingInfo *paging) error {
func outputServices(o *api.Options, children []*gabs.Container, pagingInfo *paging) error {
if o.OutputJSONResponse {
return nil
}
@@ -551,7 +552,7 @@ func outputServices(o *edgeOptions, children []*gabs.Container, pagingInfo *pagi
return nil
}
func outputServiceConfigs(o *edgeOptions, children []*gabs.Container, pagingInfo *paging) error {
func outputServiceConfigs(o *api.Options, children []*gabs.Container, pagingInfo *paging) error {
if o.OutputJSONResponse {
return nil
}
@@ -570,7 +571,7 @@ func outputServiceConfigs(o *edgeOptions, children []*gabs.Container, pagingInfo
return nil
}
func runListServiceEdgeRouterPolices(o *edgeOptions) error {
func runListServiceEdgeRouterPolices(o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions("service-edge-router-policies", o)
if err != nil {
return err
@@ -578,7 +579,7 @@ func runListServiceEdgeRouterPolices(o *edgeOptions) error {
return outputServiceEdgeRouterPolicies(o, children, pagingInfo)
}
func outputServiceEdgeRouterPolicies(o *edgeOptions, children []*gabs.Container, pagingInfo *paging) error {
func outputServiceEdgeRouterPolicies(o *api.Options, children []*gabs.Container, pagingInfo *paging) error {
if o.OutputJSONResponse {
return nil
}
@@ -603,7 +604,7 @@ func outputServiceEdgeRouterPolicies(o *edgeOptions, children []*gabs.Container,
return nil
}
func runListServicePolices(o *edgeOptions) error {
func runListServicePolices(o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions("service-policies", o)
if err != nil {
return err
@@ -611,7 +612,7 @@ func runListServicePolices(o *edgeOptions) error {
return outputServicePolicies(o, children, pagingInfo)
}
func outputServicePolicies(o *edgeOptions, children []*gabs.Container, pagingInfo *paging) error {
func outputServicePolicies(o *api.Options, children []*gabs.Container, pagingInfo *paging) error {
if o.OutputJSONResponse {
return nil
}
@@ -681,7 +682,7 @@ func mapRoleIdsToNames(c *gabs.Container, path string) ([]string, error) {
}
// runListIdentities implements the command to list identities
func runListIdentities(roleFilters []string, roleSemantic string, options *edgeOptions) error {
func runListIdentities(roleFilters []string, roleSemantic string, options *api.Options) error {
params := url.Values{}
if len(options.Args) > 0 {
params.Add("filter", options.Args[0])
@@ -700,7 +701,7 @@ func runListIdentities(roleFilters []string, roleSemantic string, options *edgeO
}
// outputIdentities implements the command to list identities
func outputIdentities(o *edgeOptions, children []*gabs.Container, pagingInfo *paging) error {
func outputIdentities(o *api.Options, children []*gabs.Container, pagingInfo *paging) error {
if o.OutputJSONResponse {
return nil
}
@@ -719,7 +720,7 @@ func outputIdentities(o *edgeOptions, children []*gabs.Container, pagingInfo *pa
return nil
}
func outputPostureCheck(o *edgeOptions, entity *gabs.Container) error {
func outputPostureCheck(o *api.Options, entity *gabs.Container) error {
id, _ := entity.Path("id").Data().(string)
typeId, _ := entity.Path("typeId").Data().(string)
name, _ := entity.Path("name").Data().(string)
@@ -819,7 +820,7 @@ func getEllipsesStrings(values []string, lead, lag int) []string {
return ret
}
func outputPostureChecks(o *edgeOptions, children []*gabs.Container, pagingInfo *paging) error {
func outputPostureChecks(o *api.Options, children []*gabs.Container, pagingInfo *paging) error {
if o.OutputJSONResponse {
return nil
}
@@ -834,7 +835,7 @@ func outputPostureChecks(o *edgeOptions, children []*gabs.Container, pagingInfo
return nil
}
func runListCAs(o *edgeOptions) error {
func runListCAs(o *api.Options) error {
client, err := util.NewEdgeManagementClient(o)
if err != nil {
@@ -924,7 +925,7 @@ func runListCAs(o *edgeOptions) error {
return nil
}
func runListConfigTypes(o *edgeOptions) error {
func runListConfigTypes(o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions("config-types", o)
if err != nil {
return err
@@ -945,7 +946,7 @@ func runListConfigTypes(o *edgeOptions) error {
return nil
}
func runListConfigs(o *edgeOptions) error {
func runListConfigs(o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions("configs", o)
if err != nil {
return err
@@ -953,7 +954,7 @@ func runListConfigs(o *edgeOptions) error {
return outputConfigs(o, children, pagingInfo)
}
func outputConfigs(o *edgeOptions, children []*gabs.Container, pagingInfo *paging) error {
func outputConfigs(o *api.Options, children []*gabs.Container, pagingInfo *paging) error {
if o.OutputJSONResponse {
return nil
}
@@ -975,7 +976,7 @@ func outputConfigs(o *edgeOptions, children []*gabs.Container, pagingInfo *pagin
return nil
}
func runListApiSessions(o *edgeOptions) error {
func runListApiSessions(o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions("api-sessions", o)
if err != nil {
return err
@@ -997,7 +998,7 @@ func runListApiSessions(o *edgeOptions) error {
return err
}
func runListSessions(o *edgeOptions) error {
func runListSessions(o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions("sessions", o)
if err != nil {
@@ -1021,7 +1022,7 @@ func runListSessions(o *edgeOptions) error {
return err
}
func runListTransitRouters(o *edgeOptions) error {
func runListTransitRouters(o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions("transit-routers", o)
if err != nil {
@@ -1043,19 +1044,19 @@ func runListTransitRouters(o *edgeOptions) error {
return err
}
func runListEdgeRouterRoleAttributes(o *edgeOptions) error {
func runListEdgeRouterRoleAttributes(o *api.Options) error {
return runListRoleAttributes("edge-router", o)
}
func runListIdentityRoleAttributes(o *edgeOptions) error {
func runListIdentityRoleAttributes(o *api.Options) error {
return runListRoleAttributes("identity", o)
}
func runListServiceRoleAttributes(o *edgeOptions) error {
func runListServiceRoleAttributes(o *api.Options) error {
return runListRoleAttributes("service", o)
}
func runListRoleAttributes(entityType string, o *edgeOptions) error {
func runListRoleAttributes(entityType string, o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions(entityType+"-role-attributes", o)
if err != nil {
@@ -1075,7 +1076,7 @@ func runListRoleAttributes(entityType string, o *edgeOptions) error {
return err
}
func runListChilden(parentType, childType string, o *edgeOptions, outputF outputFunction) error {
func runListChilden(parentType, childType string, o *api.Options, outputF outputFunction) error {
idOrName := o.Args[0]
parentId, err := mapNameToID(parentType, idOrName, *o)
if err != nil {
@@ -1099,7 +1100,7 @@ func runListChilden(parentType, childType string, o *edgeOptions, outputF output
return outputF(o, children, pagingInfo)
}
func runListPostureChecks(o *edgeOptions) error {
func runListPostureChecks(o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions("posture-checks", o)
if err != nil {
@@ -1113,7 +1114,7 @@ func runListPostureChecks(o *edgeOptions) error {
return err
}
func runListSummary(o *edgeOptions) error {
func runListSummary(o *api.Options) error {
jsonParsed, err := util.EdgeControllerList("summary", url.Values{}, o.OutputJSONResponse, o.Out, o.Timeout, o.Verbose)
if o.OutputJSONResponse {
@@ -1150,7 +1151,7 @@ func containerArrayToString(containers []*gabs.Container, limit int) string {
return strings.Join(values, ",")
}
func runListPostureCheckTypes(o *edgeOptions) error {
func runListPostureCheckTypes(o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions("posture-check-types", o)
if err != nil {
+21 -20
View File
@@ -20,6 +20,7 @@ import (
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/foundation/util/term"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
@@ -34,11 +35,11 @@ import (
// loginOptions are the flags for login commands
type loginOptions struct {
edgeOptions
api.Options
Username string
Password string
Token string
Cert string
CaCert string
ReadOnly bool
Yes bool
IgnoreConfig bool
@@ -47,7 +48,7 @@ type loginOptions struct {
// newLoginCmd creates the command
func newLoginCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &loginOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -72,7 +73,7 @@ func newLoginCmd(out io.Writer, errOut io.Writer) *cobra.Command {
cmd.Flags().StringVarP(&options.Username, "username", "u", "", "username to use for authenticating to the Ziti Edge Controller ")
cmd.Flags().StringVarP(&options.Password, "password", "p", "", "password to use for authenticating to the Ziti Edge Controller, if -u is supplied and -p is not, a value will be prompted for")
cmd.Flags().StringVarP(&options.Token, "token", "t", "", "if an api token has already been acquired, it can be set in the config with this option. This will set the session to read only by default")
cmd.Flags().StringVarP(&options.Cert, "cert", "c", "", "additional root certificates used by the Ziti Edge Controller")
cmd.Flags().StringVarP(&options.CaCert, "cert", "c", "", "additional root certificates used by the Ziti Edge Controller")
cmd.Flags().BoolVar(&options.ReadOnly, "read-only", false, "marks this login as read-only. Note: this is not a guarantee that nothing can be changed on the server. Care should still be taken!")
cmd.Flags().BoolVarP(&options.Yes, "yes", "y", false, "If set, responds to prompts with yes. This will result in untrusted certs being accepted or updated.")
cmd.Flags().BoolVar(&options.IgnoreConfig, "ignore-config", false, "If set, does not use value from the config file for hostname or username. Values must be entered or will be prompted for.")
@@ -92,7 +93,7 @@ func (o *loginOptions) Run() error {
var host string
if len(o.Args) == 0 {
if defaultId := config.Identities[id]; defaultId != nil && !o.IgnoreConfig {
if defaultId := config.EdgeIdentities[id]; defaultId != nil && !o.IgnoreConfig {
host = defaultId.Url
o.Printf("Using controller url: %v from identity '%v' in config file: %v\n", host, id, configFile)
} else {
@@ -122,12 +123,12 @@ func (o *loginOptions) Run() error {
return err
}
if certAbs, err := filepath.Abs(o.Cert); err == nil {
o.Cert = certAbs
if certAbs, err := filepath.Abs(o.CaCert); err == nil {
o.CaCert = certAbs
}
if ctrlUrl.Path == "" {
host = util.EdgeControllerGetManagementApiBasePath(host, o.Cert)
host = util.EdgeControllerGetManagementApiBasePath(host, o.CaCert)
} else {
host = host + ctrlUrl.Path
}
@@ -139,7 +140,7 @@ func (o *loginOptions) Run() error {
if o.Token == "" {
for o.Username == "" {
if defaultId := config.Identities[id]; defaultId != nil && defaultId.Username != "" && !o.IgnoreConfig {
if defaultId := config.EdgeIdentities[id]; defaultId != nil && defaultId.Username != "" && !o.IgnoreConfig {
o.Username = defaultId.Username
o.Printf("Using username: %v from identity '%v' in config file: %v\n", o.Username, id, configFile)
} else if o.Username, err = term.Prompt("Enter username: "); err != nil {
@@ -159,7 +160,7 @@ func (o *loginOptions) Run() error {
body := container.String()
jsonParsed, err := util.EdgeControllerLogin(host, o.Cert, body, o.Out, o.OutputJSONResponse, o.edgeOptions.Timeout, o.edgeOptions.Verbose)
jsonParsed, err := util.EdgeControllerLogin(host, o.CaCert, body, o.Out, o.OutputJSONResponse, o.Options.Timeout, o.Options.Verbose)
if err != nil {
return err
@@ -181,22 +182,22 @@ func (o *loginOptions) Run() error {
}
}
absCertPath, err := filepath.Abs(o.Cert)
absCertPath, err := filepath.Abs(o.CaCert)
if err == nil {
o.Cert = absCertPath
o.CaCert = absCertPath
}
loginIdentity := &util.RestClientIdentity{
loginIdentity := &util.RestClientEdgeIdentity{
Url: host,
Username: o.Username,
Token: o.Token,
LoginTime: time.Now().Format(time.RFC3339),
Cert: o.Cert,
CaCert: o.CaCert,
ReadOnly: o.ReadOnly,
}
o.Printf("Saving identity '%v' to %v\n", id, configFile)
config.Identities[id] = loginIdentity
config.EdgeIdentities[id] = loginIdentity
err = util.PersistRestClientConfig(config)
@@ -209,7 +210,7 @@ func (o *loginOptions) ConfigureCerts(host string, ctrlUrl *url.URL) error {
return err
}
if !isServerTrusted && o.Cert == "" {
if !isServerTrusted && o.CaCert == "" {
wellKnownCerts, certs, err := util.GetWellKnownCerts(host)
if err != nil {
return errors.Wrapf(err, "unable to retrieve server certificate authority from %v", host)
@@ -229,7 +230,7 @@ func (o *loginOptions) ConfigureCerts(host string, ctrlUrl *url.URL) error {
}
if savedCerts != nil {
o.Cert = certFile
o.CaCert = certFile
if !util.AreCertsSame(o, wellKnownCerts, savedCerts) {
o.Printf("WARNING: server supplied certificate authority doesn't match cached certs at %v\n", certFile)
replace := o.Yes
@@ -256,7 +257,7 @@ func (o *loginOptions) ConfigureCerts(host string, ctrlUrl *url.URL) error {
}
}
if importCerts {
o.Cert, err = util.WriteCert(o, ctrlUrl.Hostname(), wellKnownCerts)
o.CaCert, err = util.WriteCert(o, ctrlUrl.Hostname(), wellKnownCerts)
if err != nil {
return err
}
@@ -264,13 +265,13 @@ func (o *loginOptions) ConfigureCerts(host string, ctrlUrl *url.URL) error {
o.Println("WARNING: no certificate authority provided for server, continuing but login will likely fail")
}
}
} else if isServerTrusted && o.Cert != "" {
} else if isServerTrusted && o.CaCert != "" {
override, err := o.askYesNo("Server certificate authority is already trusted. Are you sure you want to provide an additional CA [Y/N]: ")
if err != nil {
return err
}
if !override {
o.Cert = ""
o.CaCert = ""
}
}
+4 -3
View File
@@ -17,6 +17,7 @@
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
@@ -26,13 +27,13 @@ import (
// logoutOptions are the flags for logout commands
type logoutOptions struct {
edgeOptions
api.Options
}
// newLogoutCmd creates the command
func newLogoutCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &logoutOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -67,6 +68,6 @@ func (o *logoutOptions) Run() error {
id := config.GetIdentity()
o.Printf("Removing identity '%v' from %v\n", id, configFile)
delete(config.Identities, id)
delete(config.EdgeIdentities, id)
return util.PersistRestClientConfig(config)
}
+15 -14
View File
@@ -19,6 +19,7 @@ package edge
import (
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
@@ -44,14 +45,14 @@ func newPolicyAdivsorCmd(out io.Writer, errOut io.Writer) *cobra.Command {
}
type policyAdvisorOptions struct {
edgeOptions
api.Options
quiet bool
}
// newPolicyAdvisorIdentitiesCmd creates the 'edge controller policy-advisor identities' command
func newPolicyAdvisorIdentitiesCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &policyAdvisorOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -80,7 +81,7 @@ func newPolicyAdvisorIdentitiesCmd(out io.Writer, errOut io.Writer) *cobra.Comma
// newPolicyAdvisorServicesCmd creates the 'edge controller policy-advisor services' command
func newPolicyAdvisorServicesCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &policyAdvisorOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -109,12 +110,12 @@ func newPolicyAdvisorServicesCmd(out io.Writer, errOut io.Writer) *cobra.Command
// runIdentitiesPolicyAdvisor create a new policyAdvisor on the Ziti Edge Controller
func runIdentitiesPolicyAdvisor(o *policyAdvisorOptions) error {
if len(o.Args) > 0 {
identityId, err := mapNameToID("identities", o.Args[0], o.edgeOptions)
identityId, err := mapNameToID("identities", o.Args[0], o.Options)
if err != nil {
return err
}
if len(o.Args) > 1 {
serviceId, err := mapNameToID("services", o.Args[1], o.edgeOptions)
serviceId, err := mapNameToID("services", o.Args[1], o.Options)
if err != nil {
return err
}
@@ -139,13 +140,13 @@ func runIdentitiesPolicyAdvisor(o *policyAdvisorOptions) error {
// runServicesPolicyAdvisor create a new policyAdvisor on the Ziti Edge Controller
func runServicesPolicyAdvisor(o *policyAdvisorOptions) error {
if len(o.Args) > 0 {
serviceId, err := mapNameToID("services", o.Args[0], o.edgeOptions)
serviceId, err := mapNameToID("services", o.Args[0], o.Options)
if err != nil {
return err
}
if len(o.Args) > 1 {
identityId, err := mapNameToID("identities", o.Args[1], o.edgeOptions)
identityId, err := mapNameToID("identities", o.Args[1], o.Options)
if err != nil {
return err
}
@@ -205,7 +206,7 @@ func runPolicyAdvisorForIdentities(o *policyAdvisorOptions) error {
done := false
for !done {
filter := fmt.Sprintf(`true skip %v limit 2`, skip)
children, _, err := filterEntitiesOfType("identities", filter, false, o.Out, o.edgeOptions.Timeout, o.edgeOptions.Verbose)
children, _, err := filterEntitiesOfType("identities", filter, false, o.Out, o.Options.Timeout, o.Options.Verbose)
if err != nil {
panic(err)
}
@@ -235,7 +236,7 @@ func runPolicyAdvisorForServices(o *policyAdvisorOptions) error {
done := false
for !done {
filter := fmt.Sprintf(`true skip %v limit 2`, skip)
children, _, err := filterEntitiesOfType("services", filter, false, o.Out, o.edgeOptions.Timeout, o.edgeOptions.Verbose)
children, _, err := filterEntitiesOfType("services", filter, false, o.Out, o.Options.Timeout, o.Options.Verbose)
if err != nil {
panic(err)
}
@@ -266,7 +267,7 @@ func runPolicyAdvisorForIdentity(identityId string, o *policyAdvisorOptions) err
for !done {
filter := "true limit 2"
filter = fmt.Sprintf(`true skip %v limit 2`, skip)
children, _, err := filterSubEntitiesOfType("identities", "services", identityId, filter, &o.edgeOptions)
children, _, err := filterSubEntitiesOfType("identities", "services", identityId, filter, &o.Options)
if err != nil {
panic(err)
}
@@ -284,7 +285,7 @@ func runPolicyAdvisorForIdentity(identityId string, o *policyAdvisorOptions) err
}
if skip == 0 {
identityName, err := mapIdToName("identities", identityId, o.edgeOptions)
identityName, err := mapIdToName("identities", identityId, o.Options)
if err != nil {
return err
}
@@ -301,7 +302,7 @@ func runPolicyAdvisorForService(serviceId string, o *policyAdvisorOptions) error
for !done {
filter := "true limit 2"
filter = fmt.Sprintf(`true skip %v limit 2`, skip)
children, _, err := filterSubEntitiesOfType("services", "identities", serviceId, filter, &o.edgeOptions)
children, _, err := filterSubEntitiesOfType("services", "identities", serviceId, filter, &o.Options)
if err != nil {
return err
}
@@ -319,7 +320,7 @@ func runPolicyAdvisorForService(serviceId string, o *policyAdvisorOptions) error
}
if skip == 0 {
serviceName, err := mapIdToName("services", serviceId, o.edgeOptions)
serviceName, err := mapIdToName("services", serviceId, o.Options)
if err != nil {
return err
}
@@ -331,7 +332,7 @@ func runPolicyAdvisorForService(serviceId string, o *policyAdvisorOptions) error
}
func runPolicyAdvisorForIdentityAndService(identityId, serviceId string, o *policyAdvisorOptions) error {
result, err := util.EdgeControllerList("identities/"+identityId+"/policy-advice/"+serviceId, nil, o.OutputJSONResponse, o.Out, o.edgeOptions.Timeout, o.edgeOptions.Verbose)
result, err := util.EdgeControllerList("identities/"+identityId+"/policy-advice/"+serviceId, nil, o.OutputJSONResponse, o.Out, o.Options.Timeout, o.Options.Verbose)
if err != nil || o.OutputJSONResponse {
return err
}
-51
View File
@@ -17,11 +17,9 @@
package edge
import (
"fmt"
"github.com/openziti/ziti/common/enrollment"
"io"
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
@@ -35,49 +33,6 @@ func NewCmdEdge(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Comma
return cmd
}
// edgeOptions are common options for edge controller commands
type edgeOptions struct {
common.CommonOptions
OutputJSONRequest bool
OutputJSONResponse bool
}
func (options *edgeOptions) OutputRequestJson() bool {
return options.OutputJSONRequest
}
func (options *edgeOptions) OutputResponseJson() bool {
return options.OutputJSONResponse
}
func (options *edgeOptions) OutputWriter() io.Writer {
return options.CommonOptions.Out
}
func (options *edgeOptions) ErrOutputWriter() io.Writer {
return options.CommonOptions.Err
}
func (options *edgeOptions) AddCommonFlags(cmd *cobra.Command) {
cmd.Flags().StringVarP(&common.CliIdentity, "cli-identity", "i", "", "Specify the saved identity you want the CLI to use when connect to the controller with")
cmd.Flags().BoolVarP(&options.OutputJSONResponse, "output-json", "j", false, "Output the full JSON response from the Ziti Edge Controller")
cmd.Flags().BoolVar(&options.OutputJSONRequest, "output-request-json", false, "Output the full JSON request to the Ziti Edge Controller")
cmd.Flags().IntVarP(&options.Timeout, "timeout", "", 5, "Timeout for REST operations (specified in seconds)")
cmd.Flags().BoolVarP(&options.Verbose, "verbose", "", false, "Enable verbose logging")
}
func (options *edgeOptions) logCreateResult(entityType string, result *gabs.Container, err error) error {
if err != nil {
return err
}
if !options.OutputJSONResponse {
id := result.S("data", "id").Data()
_, err = fmt.Fprintf(options.Out, "New %v %v created with id: %v\n", entityType, options.Args[0], id)
return err
}
return nil
}
func populateEdgeCommands(f cmdutil.Factory, out io.Writer, errOut io.Writer, cmd *cobra.Command) *cobra.Command {
p := common.NewOptionsProvider(out, errOut)
cmd.AddCommand(newCreateCmd(f, out, errOut))
@@ -97,9 +52,3 @@ func populateEdgeCommands(f cmdutil.Factory, out io.Writer, errOut io.Writer, cm
cmd.AddCommand(newTraceRouteCmd(out, errOut))
return cmd
}
func setJSONValue(container *gabs.Container, value interface{}, path ...string) {
if _, err := container.Set(value, path...); err != nil {
panic(err)
}
}
+9 -8
View File
@@ -19,6 +19,7 @@ package edge
import (
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/spf13/cobra"
@@ -26,7 +27,7 @@ import (
)
type traceIdentityOptions struct {
edgeOptions
api.Options
disable bool
duration string
traceId string
@@ -46,7 +47,7 @@ func newTraceCmd(out io.Writer, errOut io.Writer) *cobra.Command {
func newTraceIdentityCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &traceIdentityOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -76,24 +77,24 @@ func newTraceIdentityCmd(out io.Writer, errOut io.Writer) *cobra.Command {
}
func runTraceIdentity(o *traceIdentityOptions) error {
id, err := mapNameToID("identities", o.Args[0], o.edgeOptions)
id, err := mapNameToID("identities", o.Args[0], o.Options)
if err != nil {
return err
}
entityData := gabs.New()
setJSONValue(entityData, !o.disable, "enabled")
setJSONValue(entityData, o.duration, "duration")
api.SetJSONValue(entityData, !o.disable, "enabled")
api.SetJSONValue(entityData, o.duration, "duration")
if o.traceId != "" {
setJSONValue(entityData, o.traceId, "traceId")
api.SetJSONValue(entityData, o.traceId, "traceId")
}
if len(o.Args) > 1 {
setJSONValue(entityData, o.Args[1:], "channels")
api.SetJSONValue(entityData, o.Args[1:], "channels")
}
result, err := putEntityOfType("identities/"+id+"/trace", entityData.String(), &o.edgeOptions)
result, err := putEntityOfType("identities/"+id+"/trace", entityData.String(), &o.Options)
if err != nil {
return err
+4 -3
View File
@@ -4,6 +4,7 @@ import (
"fmt"
"github.com/openziti/sdk-golang/ziti"
"github.com/openziti/sdk-golang/ziti/config"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/sirupsen/logrus"
@@ -14,7 +15,7 @@ import (
)
type traceRouteOptions struct {
edgeOptions
api.Options
skipIntermediate bool
hops uint8
configFile string
@@ -23,7 +24,7 @@ type traceRouteOptions struct {
func newTraceRouteCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &traceRouteOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -98,7 +99,7 @@ func (o *traceRouteOptions) Run() error {
hopLabel := result.HopId
if result.HopType == "forwarder" {
hopLabel, err = mapIdToName("transit-routers", result.HopId, o.edgeOptions)
hopLabel, err = mapIdToName("transit-routers", result.HopId, o.Options)
if err != nil {
hopLabel = result.HopId
routerNameLookupsFailed = true
+3 -2
View File
@@ -5,6 +5,7 @@ import (
"fmt"
"github.com/fatih/color"
"github.com/openziti/foundation/util/term"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/tutorial"
@@ -61,13 +62,13 @@ type tutorialOptions struct {
}
type firstServiceTutorialOptions struct {
edgeOptions
api.Options
tutorialOptions
}
func newFirstServiceTutorialCmd(p common.OptionsProvider) *cobra.Command {
options := &firstServiceTutorialOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: p(),
},
}
@@ -7,7 +7,7 @@ import (
"strings"
)
// edgeOptions are common options for edge controller commands
// Options are common options for edge controller commands
type plainEchoClientOptions struct {
common.CommonOptions
port uint16
@@ -7,7 +7,7 @@ import (
"time"
)
// edgeOptions are common options for edge controller commands
// Options are common options for edge controller commands
type plainEchoServerOptions struct {
common.CommonOptions
port uint16
@@ -8,7 +8,7 @@ import (
"strings"
)
// edgeOptions are common options for edge controller commands
// Options are common options for edge controller commands
type zitiEchoClientOptions struct {
common.CommonOptions
identity string
@@ -7,7 +7,7 @@ import (
"time"
)
// edgeOptions are common options for edge controller commands
// Options are common options for edge controller commands
type zitiEchoServerOptions struct {
common.CommonOptions
identity string
+8 -7
View File
@@ -18,6 +18,7 @@ package edge
import (
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
@@ -54,27 +55,27 @@ func newUpdateCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Com
return cmd
}
func putEntityOfType(entityType string, body string, options *edgeOptions) (*gabs.Container, error) {
func putEntityOfType(entityType string, body string, options *api.Options) (*gabs.Container, error) {
return updateEntityOfType(entityType, body, options, resty.MethodPut)
}
func patchEntityOfType(entityType string, body string, options *edgeOptions) (*gabs.Container, error) {
func patchEntityOfType(entityType string, body string, options *api.Options) (*gabs.Container, error) {
return updateEntityOfType(entityType, body, options, resty.MethodPatch)
}
func postEntityOfType(entityType string, body string, options *edgeOptions) (*gabs.Container, error) {
func postEntityOfType(entityType string, body string, options *api.Options) (*gabs.Container, error) {
return updateEntityOfType(entityType, body, options, resty.MethodPost)
}
func deleteEntityOfTypeWithBody(entityType string, body string, options *edgeOptions) (*gabs.Container, error) {
func deleteEntityOfTypeWithBody(entityType string, body string, options *api.Options) (*gabs.Container, error) {
return updateEntityOfType(entityType, body, options, resty.MethodDelete)
}
// updateEntityOfType updates an entity of the given type on the Ziti Edge Controller
func updateEntityOfType(entityType string, body string, options *edgeOptions, method string) (*gabs.Container, error) {
return util.EdgeControllerUpdate(entityType, body, options.Out, method, options.OutputJSONRequest, options.OutputJSONResponse, options.Timeout, options.Verbose)
func updateEntityOfType(entityType string, body string, options *api.Options, method string) (*gabs.Container, error) {
return util.ControllerUpdate(util.EdgeAPI, entityType, body, options.Out, method, options.OutputJSONRequest, options.OutputJSONResponse, options.Timeout, options.Verbose)
}
func doRequest(entityType string, options *edgeOptions, doRequest func(request *resty.Request, url string) (*resty.Response, error)) (*gabs.Container, error) {
func doRequest(entityType string, options *api.Options, doRequest func(request *resty.Request, url string) (*resty.Response, error)) (*gabs.Container, error) {
return util.EdgeControllerRequest(entityType, options.Out, options.OutputJSONResponse, options.Timeout, options.Verbose, doRequest)
}
@@ -17,6 +17,7 @@
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
"github.com/spf13/cobra"
@@ -25,7 +26,7 @@ import (
// newUpdateAuthenticatorCmd creates the 'edge controller update authenticator' command
func newUpdateAuthenticatorCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := edgeOptions{
options := api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
OutputJSONResponse: false,
}
@@ -23,13 +23,14 @@ import (
"github.com/Jeffail/gabs"
"github.com/openziti/edge/rest_management_api_client/authenticator"
"github.com/openziti/foundation/util/term"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
)
import cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
type updateUpdbOptions struct {
edgeOptions
api.Options
identity string
newPassword string
currentPassword string
@@ -37,9 +38,9 @@ type updateUpdbOptions struct {
self bool
}
func newUpdateAuthenticatorUpdb(idType string, options edgeOptions) *cobra.Command {
func newUpdateAuthenticatorUpdb(idType string, options api.Options) *cobra.Command {
updbOptions := updateUpdbOptions{
edgeOptions: options,
Options: options,
}
cmd := &cobra.Command{
Use: idType + " (--identity <identityIdOrName> -p <newPassword>) | (-c <currentPassword> -n <newPassword>)",
@@ -74,17 +75,17 @@ func runUpdateUpdbPassword(idType string, options *updateUpdbOptions) error {
}
if options.identity != "" {
return setIdentityPassword(options.identity, options.identityPassword, options.edgeOptions)
return setIdentityPassword(options.identity, options.identityPassword, options.Options)
}
if options.self {
return updateSelfPassword(options.currentPassword, options.newPassword, options.edgeOptions)
return updateSelfPassword(options.currentPassword, options.newPassword, options.Options)
}
return errors.New("invalid arguments, requires --self or --identity, see help for details")
}
func updateSelfPassword(current string, new string, options edgeOptions) error {
func updateSelfPassword(current string, new string, options api.Options) error {
var err error
if current == "" {
if current, err = term.PromptPassword("Enter your current password: ", false); err != nil {
@@ -99,8 +100,8 @@ func updateSelfPassword(current string, new string, options edgeOptions) error {
}
passwordData := gabs.New()
setJSONValue(passwordData, current, "currentPassword")
setJSONValue(passwordData, new, "password")
api.SetJSONValue(passwordData, current, "currentPassword")
api.SetJSONValue(passwordData, new, "password")
respEnvelope, err := util.EdgeControllerList("current-identity/authenticators", map[string][]string{"filter": {`method="updb"`}}, options.OutputJSONResponse, options.Out, options.Timeout, options.Verbose)
@@ -129,7 +130,7 @@ func updateSelfPassword(current string, new string, options edgeOptions) error {
return nil
}
func setIdentityPassword(identity, password string, options edgeOptions) error {
func setIdentityPassword(identity, password string, options api.Options) error {
id, err := mapIdentityNameToID(identity, options)
if err != nil {
@@ -182,7 +183,7 @@ func setIdentityPassword(identity, password string, options edgeOptions) error {
}
passwordData := gabs.New()
setJSONValue(passwordData, password, "password")
api.SetJSONValue(passwordData, password, "password")
_, err = patchEntityOfType(fmt.Sprintf("authenticators/%s", *authenticatorId), passwordData.String(), &options)
+6 -5
View File
@@ -20,6 +20,7 @@ import (
"fmt"
"github.com/openziti/edge/rest_management_api_client/certificate_authority"
"github.com/openziti/edge/rest_model"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
@@ -32,7 +33,7 @@ import (
)
type updateCaOptions struct {
edgeOptions
api.Options
verify bool
verifyCertPath string
verifyCertBytes []byte
@@ -48,7 +49,7 @@ type updateCaOptions struct {
// newUpdateAuthenticatorCmd creates the 'edge controller update authenticator' command
func newUpdateCaCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := updateCaOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
OutputJSONResponse: false,
},
@@ -115,7 +116,7 @@ func runUpdateCa(options updateCaOptions) error {
return runVerifyCa(options)
}
id, err := mapCaNameToID(options.nameOrId, options.edgeOptions)
id, err := mapCaNameToID(options.nameOrId, options.Options)
if err != nil {
return err
@@ -181,13 +182,13 @@ func runUpdateCa(options updateCaOptions) error {
}
func runVerifyCa(options updateCaOptions) error {
id, err := mapCaNameToID(options.nameOrId, options.edgeOptions)
id, err := mapCaNameToID(options.nameOrId, options.Options)
if err != nil {
return err
}
_, err = doRequest("cas/"+id+"/verify", &options.edgeOptions, func(request *resty.Request, url string) (response *resty.Response, e error) {
_, err = doRequest("cas/"+id+"/verify", &options.Options, func(request *resty.Request, url string) (response *resty.Response, e error) {
return request.SetHeader("Content-Type", "text/plain").
SetBody(string(options.verifyCertBytes)).
Post(url)
+7 -6
View File
@@ -19,6 +19,7 @@ package edge
import (
"encoding/json"
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
"io/ioutil"
@@ -32,7 +33,7 @@ import (
)
type updateConfigOptions struct {
edgeOptions
api.Options
name string
data string
jsonFile string
@@ -41,7 +42,7 @@ type updateConfigOptions struct {
// newUpdateConfigCmd updates the 'edge controller update service-policy' command
func newUpdateConfigCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &updateConfigOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
},
}
@@ -72,7 +73,7 @@ func newUpdateConfigCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cob
// runUpdateConfig update a new config on the Ziti Edge Controller
func runUpdateConfig(o *updateConfigOptions) error {
id, err := mapNameToID("configs", o.Args[0], o.edgeOptions)
id, err := mapNameToID("configs", o.Args[0], o.Options)
if err != nil {
return err
}
@@ -80,7 +81,7 @@ func runUpdateConfig(o *updateConfigOptions) error {
change := false
if o.Cmd.Flags().Changed("name") {
setJSONValue(entityData, o.name, "name")
api.SetJSONValue(entityData, o.name, "name")
change = true
}
@@ -107,7 +108,7 @@ func runUpdateConfig(o *updateConfigOptions) error {
fmt.Printf("Failing parsing JSON: %+v\n", err)
return errors.Errorf("unable to parse data as json: %v", err)
}
setJSONValue(entityData, dataMap, "data")
api.SetJSONValue(entityData, dataMap, "data")
change = true
}
@@ -115,7 +116,7 @@ func runUpdateConfig(o *updateConfigOptions) error {
return errors.New("no change specified. must specify at least one attribute to change")
}
_, err = patchEntityOfType(fmt.Sprintf("configs/%v", id), entityData.String(), &o.edgeOptions)
_, err = patchEntityOfType(fmt.Sprintf("configs/%v", id), entityData.String(), &o.Options)
if err != nil {
panic(err)
+11 -10
View File
@@ -18,6 +18,7 @@ package edge
import (
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
"github.com/pkg/errors"
@@ -30,7 +31,7 @@ import (
)
type updateEdgeRouterOptions struct {
edgeOptions
api.Options
name string
isTunnelerEnabled bool
roleAttributes []string
@@ -41,7 +42,7 @@ type updateEdgeRouterOptions struct {
func newUpdateEdgeRouterCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &updateEdgeRouterOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
},
}
@@ -78,7 +79,7 @@ func newUpdateEdgeRouterCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer)
// runUpdateEdgeRouter update a new edgeRouter on the Ziti Edge Controller
func runUpdateEdgeRouter(o *updateEdgeRouterOptions) error {
id, err := mapNameToID("edge-routers", o.Args[0], o.edgeOptions)
id, err := mapNameToID("edge-routers", o.Args[0], o.Options)
if err != nil {
return err
}
@@ -86,27 +87,27 @@ func runUpdateEdgeRouter(o *updateEdgeRouterOptions) error {
change := false
if o.Cmd.Flags().Changed("name") {
setJSONValue(entityData, o.name, "name")
api.SetJSONValue(entityData, o.name, "name")
change = true
}
if o.Cmd.Flags().Changed("tunneler-enabled") {
setJSONValue(entityData, o.isTunnelerEnabled, "isTunnelerEnabled")
api.SetJSONValue(entityData, o.isTunnelerEnabled, "isTunnelerEnabled")
change = true
}
if o.Cmd.Flags().Changed("role-attributes") {
setJSONValue(entityData, o.roleAttributes, "roleAttributes")
api.SetJSONValue(entityData, o.roleAttributes, "roleAttributes")
change = true
}
if o.Cmd.Flags().Changed("tags") {
setJSONValue(entityData, o.tags, "tags")
api.SetJSONValue(entityData, o.tags, "tags")
change = true
}
if o.Cmd.Flags().Changed("app-data") {
setJSONValue(entityData, o.appData, "appData")
api.SetJSONValue(entityData, o.appData, "appData")
change = true
}
@@ -115,9 +116,9 @@ func runUpdateEdgeRouter(o *updateEdgeRouterOptions) error {
}
if o.usePut {
_, err = putEntityOfType(fmt.Sprintf("edge-routers/%v", id), entityData.String(), &o.edgeOptions)
_, err = putEntityOfType(fmt.Sprintf("edge-routers/%v", id), entityData.String(), &o.Options)
} else {
_, err = patchEntityOfType(fmt.Sprintf("edge-routers/%v", id), entityData.String(), &o.edgeOptions)
_, err = patchEntityOfType(fmt.Sprintf("edge-routers/%v", id), entityData.String(), &o.Options)
}
return err
}
@@ -18,6 +18,7 @@ package edge
import (
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
"github.com/pkg/errors"
@@ -30,7 +31,7 @@ import (
)
type updateEdgeRouterPolicyOptions struct {
edgeOptions
api.Options
name string
edgeRouterRoles []string
identityRoles []string
@@ -38,7 +39,7 @@ type updateEdgeRouterPolicyOptions struct {
func newUpdateEdgeRouterPolicyCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &updateEdgeRouterPolicyOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
},
}
@@ -69,17 +70,17 @@ func newUpdateEdgeRouterPolicyCmd(f cmdutil.Factory, out io.Writer, errOut io.Wr
}
func runUpdateEdgeRouterPolicy(o *updateEdgeRouterPolicyOptions) error {
id, err := mapNameToID("edge-router-policies", o.Args[0], o.edgeOptions)
id, err := mapNameToID("edge-router-policies", o.Args[0], o.Options)
if err != nil {
return err
}
edgeRouterRoles, err := convertNamesToIds(o.edgeRouterRoles, "edge-routers", o.edgeOptions)
edgeRouterRoles, err := convertNamesToIds(o.edgeRouterRoles, "edge-routers", o.Options)
if err != nil {
return err
}
identityRoles, err := convertNamesToIds(o.identityRoles, "identities", o.edgeOptions)
identityRoles, err := convertNamesToIds(o.identityRoles, "identities", o.Options)
if err != nil {
return err
}
@@ -88,17 +89,17 @@ func runUpdateEdgeRouterPolicy(o *updateEdgeRouterPolicyOptions) error {
change := false
if o.Cmd.Flags().Changed("name") {
setJSONValue(entityData, o.name, "name")
api.SetJSONValue(entityData, o.name, "name")
change = true
}
if o.Cmd.Flags().Changed("edge-router-roles") {
setJSONValue(entityData, edgeRouterRoles, "edgeRouterRoles")
api.SetJSONValue(entityData, edgeRouterRoles, "edgeRouterRoles")
change = true
}
if o.Cmd.Flags().Changed("identity-roles") {
setJSONValue(entityData, identityRoles, "identityRoles")
api.SetJSONValue(entityData, identityRoles, "identityRoles")
change = true
}
@@ -106,6 +107,6 @@ func runUpdateEdgeRouterPolicy(o *updateEdgeRouterPolicyOptions) error {
return errors.New("no change specified. must specify at least one attribute to change")
}
_, err = patchEntityOfType(fmt.Sprintf("edge-router-policies/%v", id), entityData.String(), &o.edgeOptions)
_, err = patchEntityOfType(fmt.Sprintf("edge-router-policies/%v", id), entityData.String(), &o.Options)
return err
}
+15 -14
View File
@@ -19,6 +19,7 @@ package edge
import (
"fmt"
"github.com/openziti/sdk-golang/ziti"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
"math"
"strings"
@@ -33,7 +34,7 @@ import (
)
type updateIdentityOptions struct {
edgeOptions
api.Options
name string
roleAttributes []string
defaultHostingPrecedence string
@@ -46,7 +47,7 @@ type updateIdentityOptions struct {
func newUpdateIdentityCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &updateIdentityOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
},
}
@@ -83,7 +84,7 @@ func newUpdateIdentityCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *c
// runUpdateIdentity update a new identity on the Ziti Edge Controller
func runUpdateIdentity(o *updateIdentityOptions) error {
id, err := mapNameToID("identities", o.Args[0], o.edgeOptions)
id, err := mapNameToID("identities", o.Args[0], o.Options)
if err != nil {
return err
}
@@ -91,17 +92,17 @@ func runUpdateIdentity(o *updateIdentityOptions) error {
change := false
if o.Cmd.Flags().Changed("name") {
setJSONValue(entityData, o.name, "name")
api.SetJSONValue(entityData, o.name, "name")
change = true
}
if o.Cmd.Flags().Changed("role-attributes") {
setJSONValue(entityData, o.roleAttributes, "roleAttributes")
api.SetJSONValue(entityData, o.roleAttributes, "roleAttributes")
change = true
}
if o.Cmd.Flags().Changed("default-hosting-cost") {
setJSONValue(entityData, o.defaultHostingCost, "defaultHostingCost")
api.SetJSONValue(entityData, o.defaultHostingCost, "defaultHostingCost")
change = true
}
@@ -110,7 +111,7 @@ func runUpdateIdentity(o *updateIdentityOptions) error {
if err != nil {
return err
}
setJSONValue(entityData, prec, "defaultHostingPrecedence")
api.SetJSONValue(entityData, prec, "defaultHostingPrecedence")
change = true
}
@@ -119,20 +120,20 @@ func runUpdateIdentity(o *updateIdentityOptions) error {
if v < 0 || v > math.MaxUint16 {
return errors.Errorf("hosting costs must be in the range %v-%v", 0, math.MaxUint16)
}
id, err := mapNameToID("services", k, o.edgeOptions)
id, err := mapNameToID("services", k, o.Options)
if err != nil {
return err
}
delete(o.serviceCosts, k)
o.serviceCosts[id] = v
}
setJSONValue(entityData, o.serviceCosts, "serviceHostingCosts")
api.SetJSONValue(entityData, o.serviceCosts, "serviceHostingCosts")
change = true
}
if o.Cmd.Flags().Changed("service-precedences") {
for k, v := range o.servicePrecedences {
id, err := mapNameToID("services", k, o.edgeOptions)
id, err := mapNameToID("services", k, o.Options)
if err != nil {
return err
}
@@ -145,17 +146,17 @@ func runUpdateIdentity(o *updateIdentityOptions) error {
delete(o.servicePrecedences, k)
o.servicePrecedences[id] = prec
}
setJSONValue(entityData, o.servicePrecedences, "serviceHostingPrecedences")
api.SetJSONValue(entityData, o.servicePrecedences, "serviceHostingPrecedences")
change = true
}
if o.Cmd.Flags().Changed("tags") {
setJSONValue(entityData, o.tags, "tags")
api.SetJSONValue(entityData, o.tags, "tags")
change = true
}
if o.Cmd.Flags().Changed("app-data") {
setJSONValue(entityData, o.appData, "appData")
api.SetJSONValue(entityData, o.appData, "appData")
change = true
}
@@ -163,7 +164,7 @@ func runUpdateIdentity(o *updateIdentityOptions) error {
return errors.New("no change specified. must specify at least one attribute to change")
}
_, err = patchEntityOfType(fmt.Sprintf("identities/%v", id), entityData.String(), &o.edgeOptions)
_, err = patchEntityOfType(fmt.Sprintf("identities/%v", id), entityData.String(), &o.Options)
return err
}
@@ -18,6 +18,7 @@ package edge
import (
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
"github.com/Jeffail/gabs"
@@ -28,13 +29,13 @@ import (
)
type updateIdentityConfigsOptions struct {
edgeOptions
api.Options
remove bool
}
func newUpdateIdentityConfigsCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &updateIdentityConfigsOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
},
}
@@ -63,17 +64,17 @@ func newUpdateIdentityConfigsCmd(f cmdutil.Factory, out io.Writer, errOut io.Wri
// runupdateIdentityConfigs update a new identity on the Ziti Edge Controller
func runupdateIdentityConfigs(o *updateIdentityConfigsOptions) error {
id, err := mapNameToID("identities", o.Args[0], o.edgeOptions)
id, err := mapNameToID("identities", o.Args[0], o.Options)
if err != nil {
return err
}
serviceId, err := mapNameToID("services", o.Args[1], o.edgeOptions)
serviceId, err := mapNameToID("services", o.Args[1], o.Options)
if err != nil {
return err
}
configId, err := mapNameToID("configs", o.Args[2], o.edgeOptions)
configId, err := mapNameToID("configs", o.Args[2], o.Options)
if err != nil {
return err
}
@@ -89,9 +90,9 @@ func runupdateIdentityConfigs(o *updateIdentityConfigsOptions) error {
body := entityData.String()
if o.remove {
_, err = deleteEntityOfTypeWithBody(path, body, &o.edgeOptions)
_, err = deleteEntityOfTypeWithBody(path, body, &o.Options)
} else {
_, err = postEntityOfType(path, body, &o.edgeOptions)
_, err = postEntityOfType(path, body, &o.Options)
}
return err
}
+46 -45
View File
@@ -18,6 +18,7 @@ package edge
import (
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"io"
@@ -44,7 +45,7 @@ func newUpdatePostureCheckCmd(out io.Writer, errOut io.Writer) *cobra.Command {
}
type updatePostureCheckOptions struct {
edgeOptions
api.Options
name string
tags map[string]string
roleAttributes []string
@@ -84,7 +85,7 @@ type updatePostureCheckOsOptions struct {
func newUpdatePostureCheckMacCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &updatePostureCheckMacOptions{
updatePostureCheckOptions: updatePostureCheckOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
},
@@ -117,7 +118,7 @@ func newUpdatePostureCheckMacCmd(out io.Writer, errOut io.Writer) *cobra.Command
// runUpdatePostureCheckMac update a new identity on the Ziti Edge Controller
func runUpdatePostureCheckMac(o *updatePostureCheckMacOptions) error {
id, err := mapNameToID("posture-checks", o.Args[0], o.edgeOptions)
id, err := mapNameToID("posture-checks", o.Args[0], o.Options)
if err != nil {
return err
}
@@ -125,17 +126,17 @@ func runUpdatePostureCheckMac(o *updatePostureCheckMacOptions) error {
change := false
if o.Cmd.Flags().Changed("name") {
setJSONValue(entityData, o.name, "name")
api.SetJSONValue(entityData, o.name, "name")
change = true
}
if o.Cmd.Flags().Changed("role-attributes") {
setJSONValue(entityData, o.roleAttributes, "roleAttributes")
api.SetJSONValue(entityData, o.roleAttributes, "roleAttributes")
change = true
}
if o.Cmd.Flags().Changed("mac-addresses") {
setJSONValue(entityData, o.addresses, "macAddresses")
api.SetJSONValue(entityData, o.addresses, "macAddresses")
change = true
}
@@ -143,16 +144,16 @@ func runUpdatePostureCheckMac(o *updatePostureCheckMacOptions) error {
return errors.New("no change specified. must specify at least one attribute to change")
}
setJSONValue(entityData, PostureCheckTypeMAC, "typeId")
api.SetJSONValue(entityData, PostureCheckTypeMAC, "typeId")
_, err = patchEntityOfType(fmt.Sprintf("posture-checks/%v", id), entityData.String(), &o.edgeOptions)
_, err = patchEntityOfType(fmt.Sprintf("posture-checks/%v", id), entityData.String(), &o.Options)
return err
}
func newUpdatePostureCheckDomainCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &updatePostureCheckDomainOptions{
updatePostureCheckOptions: updatePostureCheckOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
},
@@ -186,7 +187,7 @@ func newUpdatePostureCheckDomainCmd(out io.Writer, errOut io.Writer) *cobra.Comm
func newUpdatePostureCheckMfaCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &updatePostureCheckMfaOptions{
updatePostureCheckOptions: updatePostureCheckOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
},
@@ -229,7 +230,7 @@ func newUpdatePostureCheckMfaCmd(out io.Writer, errOut io.Writer) *cobra.Command
}
func runUpdatePostureCheckMfa(o *updatePostureCheckMfaOptions) error {
id, err := mapNameToID("posture-checks", o.Args[0], o.edgeOptions)
id, err := mapNameToID("posture-checks", o.Args[0], o.Options)
if err != nil {
return err
}
@@ -237,47 +238,47 @@ func runUpdatePostureCheckMfa(o *updatePostureCheckMfaOptions) error {
change := false
if o.Cmd.Flags().Changed("name") {
setJSONValue(entityData, o.name, "name")
api.SetJSONValue(entityData, o.name, "name")
change = true
}
if o.Cmd.Flags().Changed("seconds") {
setJSONValue(entityData, o.timeoutSeconds, "timeoutSeconds")
api.SetJSONValue(entityData, o.timeoutSeconds, "timeoutSeconds")
change = true
}
if o.Cmd.Flags().Changed("wake") {
setJSONValue(entityData, o.promptOnWake, "promptOnWake")
api.SetJSONValue(entityData, o.promptOnWake, "promptOnWake")
change = true
}
if o.Cmd.Flags().Changed("no-wake") {
setJSONValue(entityData, false, "promptOnWake")
api.SetJSONValue(entityData, false, "promptOnWake")
change = true
}
if o.Cmd.Flags().Changed("unlock") {
setJSONValue(entityData, o.promptOnUnlock, "promptOnUnlock")
api.SetJSONValue(entityData, o.promptOnUnlock, "promptOnUnlock")
change = true
}
if o.Cmd.Flags().Changed("no-unlock") {
setJSONValue(entityData, false, "promptOnUnlock")
api.SetJSONValue(entityData, false, "promptOnUnlock")
change = true
}
if o.Cmd.Flags().Changed("ignore-legacy") {
setJSONValue(entityData, o.ignoreLegacyEndpoints, "ignoreLegacyEndpoints")
api.SetJSONValue(entityData, o.ignoreLegacyEndpoints, "ignoreLegacyEndpoints")
change = true
}
if o.Cmd.Flags().Changed("no-ignore-legacy") {
setJSONValue(entityData, false, "ignoreLegacyEndpoints")
api.SetJSONValue(entityData, false, "ignoreLegacyEndpoints")
change = true
}
if o.Cmd.Flags().Changed("role-attributes") {
setJSONValue(entityData, o.roleAttributes, "roleAttributes")
api.SetJSONValue(entityData, o.roleAttributes, "roleAttributes")
change = true
}
@@ -285,15 +286,15 @@ func runUpdatePostureCheckMfa(o *updatePostureCheckMfaOptions) error {
return errors.New("no change specified. must specify at least one attribute to change")
}
setJSONValue(entityData, PostureCheckTypeMFA, "typeId")
api.SetJSONValue(entityData, PostureCheckTypeMFA, "typeId")
_, err = patchEntityOfType(fmt.Sprintf("posture-checks/%v", id), entityData.String(), &o.edgeOptions)
_, err = patchEntityOfType(fmt.Sprintf("posture-checks/%v", id), entityData.String(), &o.Options)
return err
}
// runUpdatePostureCheckDomain update a new identity on the Ziti Edge Controller
func runUpdatePostureCheckDomain(o *updatePostureCheckDomainOptions) error {
id, err := mapNameToID("posture-checks", o.Args[0], o.edgeOptions)
id, err := mapNameToID("posture-checks", o.Args[0], o.Options)
if err != nil {
return err
}
@@ -301,12 +302,12 @@ func runUpdatePostureCheckDomain(o *updatePostureCheckDomainOptions) error {
change := false
if o.Cmd.Flags().Changed("name") {
setJSONValue(entityData, o.name, "name")
api.SetJSONValue(entityData, o.name, "name")
change = true
}
if o.Cmd.Flags().Changed("role-attributes") {
setJSONValue(entityData, o.roleAttributes, "roleAttributes")
api.SetJSONValue(entityData, o.roleAttributes, "roleAttributes")
change = true
}
@@ -315,7 +316,7 @@ func runUpdatePostureCheckDomain(o *updatePostureCheckDomainOptions) error {
return fmt.Errorf("must specify at least one domain, multiple values may be separated by commas")
}
setJSONValue(entityData, o.domains, "domains")
api.SetJSONValue(entityData, o.domains, "domains")
change = true
}
@@ -323,9 +324,9 @@ func runUpdatePostureCheckDomain(o *updatePostureCheckDomainOptions) error {
return errors.New("no change specified. must specify at least one attribute to change")
}
setJSONValue(entityData, PostureCheckTypeDomain, "typeId")
api.SetJSONValue(entityData, PostureCheckTypeDomain, "typeId")
_, err = patchEntityOfType(fmt.Sprintf("posture-checks/%v", id), entityData.String(), &o.edgeOptions)
_, err = patchEntityOfType(fmt.Sprintf("posture-checks/%v", id), entityData.String(), &o.Options)
return err
}
@@ -334,7 +335,7 @@ func runUpdatePostureCheckDomain(o *updatePostureCheckDomainOptions) error {
func newUpdatePostureCheckProcessCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &updatePostureCheckProcessOptions{
updatePostureCheckOptions: updatePostureCheckOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
},
@@ -372,7 +373,7 @@ func newUpdatePostureCheckProcessCmd(out io.Writer, errOut io.Writer) *cobra.Com
// runUpdatePostureCheckProcess update a new identity on the Ziti Edge Controller
func runUpdatePostureCheckProcess(o *updatePostureCheckProcessOptions) error {
id, err := mapNameToID("posture-checks", o.Args[0], o.edgeOptions)
id, err := mapNameToID("posture-checks", o.Args[0], o.Options)
if err != nil {
return err
}
@@ -380,17 +381,17 @@ func runUpdatePostureCheckProcess(o *updatePostureCheckProcessOptions) error {
change := false
if o.Cmd.Flags().Changed("name") {
setJSONValue(entityData, o.name, "name")
api.SetJSONValue(entityData, o.name, "name")
change = true
}
if o.Cmd.Flags().Changed("role-attributes") {
setJSONValue(entityData, o.roleAttributes, "roleAttributes")
api.SetJSONValue(entityData, o.roleAttributes, "roleAttributes")
change = true
}
if o.Cmd.Flags().Changed("path") {
setJSONValue(entityData, o.path, "process", "path")
api.SetJSONValue(entityData, o.path, "process", "path")
change = true
}
@@ -401,7 +402,7 @@ func runUpdatePostureCheckProcess(o *updatePostureCheckProcessOptions) error {
return err
}
setJSONValue(entityData, o.hashes, "process", "hashes")
api.SetJSONValue(entityData, o.hashes, "process", "hashes")
change = true
}
@@ -412,7 +413,7 @@ func runUpdatePostureCheckProcess(o *updatePostureCheckProcessOptions) error {
return err
}
setJSONValue(entityData, o.signer, "process", "signerFingerprint")
api.SetJSONValue(entityData, o.signer, "process", "signerFingerprint")
change = true
}
@@ -423,7 +424,7 @@ func runUpdatePostureCheckProcess(o *updatePostureCheckProcessOptions) error {
return fmt.Errorf("invalid os type [%s]: expected %s|%s|%s|%s", o.os, OsLinux, OsMacOs, OsWindows, OsWindowsServer)
}
setJSONValue(entityData, o.os, "process", "osType")
api.SetJSONValue(entityData, o.os, "process", "osType")
change = true
}
@@ -431,9 +432,9 @@ func runUpdatePostureCheckProcess(o *updatePostureCheckProcessOptions) error {
return errors.New("no change specified. must specify at least one attribute to change")
}
setJSONValue(entityData, PostureCheckTypeProcess, "typeId")
api.SetJSONValue(entityData, PostureCheckTypeProcess, "typeId")
_, err = patchEntityOfType(fmt.Sprintf("posture-checks/%v", id), entityData.String(), &o.edgeOptions)
_, err = patchEntityOfType(fmt.Sprintf("posture-checks/%v", id), entityData.String(), &o.Options)
return err
}
@@ -441,7 +442,7 @@ func runUpdatePostureCheckProcess(o *updatePostureCheckProcessOptions) error {
func newUpdatePostureCheckOsCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &updatePostureCheckOsOptions{
updatePostureCheckOptions: updatePostureCheckOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
},
@@ -474,7 +475,7 @@ func newUpdatePostureCheckOsCmd(out io.Writer, errOut io.Writer) *cobra.Command
// runUpdatePostureCheckOs update a new identity on the Ziti Edge Controller
func runUpdatePostureCheckOs(o *updatePostureCheckOsOptions) error {
id, err := mapNameToID("posture-checks", o.Args[0], o.edgeOptions)
id, err := mapNameToID("posture-checks", o.Args[0], o.Options)
if err != nil {
return err
}
@@ -482,12 +483,12 @@ func runUpdatePostureCheckOs(o *updatePostureCheckOsOptions) error {
change := false
if o.Cmd.Flags().Changed("name") {
setJSONValue(entityData, o.name, "name")
api.SetJSONValue(entityData, o.name, "name")
change = true
}
if o.Cmd.Flags().Changed("role-attributes") {
setJSONValue(entityData, o.roleAttributes, "roleAttributes")
api.SetJSONValue(entityData, o.roleAttributes, "roleAttributes")
change = true
}
@@ -500,7 +501,7 @@ func runUpdatePostureCheckOs(o *updatePostureCheckOsOptions) error {
oses = append(oses, osSpec)
}
}
setJSONValue(entityData, oses, "operatingSystems")
api.SetJSONValue(entityData, oses, "operatingSystems")
change = true
}
@@ -508,8 +509,8 @@ func runUpdatePostureCheckOs(o *updatePostureCheckOsOptions) error {
return errors.New("no change specified. must specify at least one attribute to change")
}
setJSONValue(entityData, PostureCheckTypeOS, "typeId")
api.SetJSONValue(entityData, PostureCheckTypeOS, "typeId")
_, err = patchEntityOfType(fmt.Sprintf("posture-checks/%v", id), entityData.String(), &o.edgeOptions)
_, err = patchEntityOfType(fmt.Sprintf("posture-checks/%v", id), entityData.String(), &o.Options)
return err
}
+11 -10
View File
@@ -18,6 +18,7 @@ package edge
import (
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
"github.com/pkg/errors"
@@ -30,7 +31,7 @@ import (
)
type updateServiceOptions struct {
edgeOptions
api.Options
name string
terminatorStrategy string
roleAttributes []string
@@ -40,7 +41,7 @@ type updateServiceOptions struct {
func newUpdateServiceCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &updateServiceOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
},
}
@@ -75,7 +76,7 @@ func newUpdateServiceCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *co
// runUpdateService update a new service on the Ziti Edge Controller
func runUpdateService(o *updateServiceOptions) error {
id, err := mapNameToID("services", o.Args[0], o.edgeOptions)
id, err := mapNameToID("services", o.Args[0], o.Options)
if err != nil {
return err
}
@@ -83,31 +84,31 @@ func runUpdateService(o *updateServiceOptions) error {
change := false
if o.Cmd.Flags().Changed("name") {
setJSONValue(entityData, o.name, "name")
api.SetJSONValue(entityData, o.name, "name")
change = true
}
if o.Cmd.Flags().Changed("role-attributes") {
setJSONValue(entityData, o.roleAttributes, "roleAttributes")
api.SetJSONValue(entityData, o.roleAttributes, "roleAttributes")
change = true
}
if o.Cmd.Flags().Changed("terminator-strategy") {
setJSONValue(entityData, o.terminatorStrategy, "terminatorStrategy")
api.SetJSONValue(entityData, o.terminatorStrategy, "terminatorStrategy")
change = true
}
if o.Cmd.Flags().Changed("encryption") {
setJSONValue(entityData, o.encryption.Get(), "encryptionRequired")
api.SetJSONValue(entityData, o.encryption.Get(), "encryptionRequired")
change = true
}
if o.Cmd.Flags().Changed("configs") {
configs, err := mapNamesToIDs("configs", o.edgeOptions, o.configs...)
configs, err := mapNamesToIDs("configs", o.Options, o.configs...)
if err != nil {
return err
}
setJSONValue(entityData, configs, "configs")
api.SetJSONValue(entityData, configs, "configs")
change = true
}
@@ -115,6 +116,6 @@ func runUpdateService(o *updateServiceOptions) error {
return errors.New("no change specified. must specify at least one attribute to change")
}
_, err = patchEntityOfType(fmt.Sprintf("services/%v", id), entityData.String(), &o.edgeOptions)
_, err = patchEntityOfType(fmt.Sprintf("services/%v", id), entityData.String(), &o.Options)
return err
}
@@ -18,6 +18,7 @@ package edge
import (
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
"github.com/pkg/errors"
@@ -30,7 +31,7 @@ import (
)
type updateServiceEdgeRouterPolicyOptions struct {
edgeOptions
api.Options
name string
edgeRouterRoles []string
serviceRoles []string
@@ -38,7 +39,7 @@ type updateServiceEdgeRouterPolicyOptions struct {
func newUpdateServiceEdgeRouterPolicyCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &updateServiceEdgeRouterPolicyOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
},
}
@@ -69,17 +70,17 @@ func newUpdateServiceEdgeRouterPolicyCmd(f cmdutil.Factory, out io.Writer, errOu
}
func runUpdateServiceEdgeRouterPolicy(o *updateServiceEdgeRouterPolicyOptions) error {
id, err := mapNameToID("service-edge-router-policies", o.Args[0], o.edgeOptions)
id, err := mapNameToID("service-edge-router-policies", o.Args[0], o.Options)
if err != nil {
return err
}
edgeRouterRoles, err := convertNamesToIds(o.edgeRouterRoles, "edge-routers", o.edgeOptions)
edgeRouterRoles, err := convertNamesToIds(o.edgeRouterRoles, "edge-routers", o.Options)
if err != nil {
return err
}
serviceRoles, err := convertNamesToIds(o.serviceRoles, "services", o.edgeOptions)
serviceRoles, err := convertNamesToIds(o.serviceRoles, "services", o.Options)
if err != nil {
return err
}
@@ -88,17 +89,17 @@ func runUpdateServiceEdgeRouterPolicy(o *updateServiceEdgeRouterPolicyOptions) e
change := false
if o.Cmd.Flags().Changed("name") {
setJSONValue(entityData, o.name, "name")
api.SetJSONValue(entityData, o.name, "name")
change = true
}
if o.Cmd.Flags().Changed("edge-router-roles") {
setJSONValue(entityData, edgeRouterRoles, "edgeRouterRoles")
api.SetJSONValue(entityData, edgeRouterRoles, "edgeRouterRoles")
change = true
}
if o.Cmd.Flags().Changed("service-roles") {
setJSONValue(entityData, serviceRoles, "serviceRoles")
api.SetJSONValue(entityData, serviceRoles, "serviceRoles")
change = true
}
@@ -106,6 +107,6 @@ func runUpdateServiceEdgeRouterPolicy(o *updateServiceEdgeRouterPolicyOptions) e
return errors.New("no change specified. must specify at least one attribute to change")
}
_, err = patchEntityOfType(fmt.Sprintf("service-edge-router-policies/%v", id), entityData.String(), &o.edgeOptions)
_, err = patchEntityOfType(fmt.Sprintf("service-edge-router-policies/%v", id), entityData.String(), &o.Options)
return err
}
+12 -11
View File
@@ -18,6 +18,7 @@ package edge
import (
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
"github.com/pkg/errors"
@@ -30,7 +31,7 @@ import (
)
type updateServicePolicyOptions struct {
edgeOptions
api.Options
name string
serviceRoles []string
identityRoles []string
@@ -39,7 +40,7 @@ type updateServicePolicyOptions struct {
func newUpdateServicePolicyCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &updateServicePolicyOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
},
}
@@ -71,22 +72,22 @@ func newUpdateServicePolicyCmd(f cmdutil.Factory, out io.Writer, errOut io.Write
}
func runUpdateServicePolicy(o *updateServicePolicyOptions) error {
id, err := mapNameToID("service-policies", o.Args[0], o.edgeOptions)
id, err := mapNameToID("service-policies", o.Args[0], o.Options)
if err != nil {
return err
}
serviceRoles, err := convertNamesToIds(o.serviceRoles, "services", o.edgeOptions)
serviceRoles, err := convertNamesToIds(o.serviceRoles, "services", o.Options)
if err != nil {
return err
}
identityRoles, err := convertNamesToIds(o.identityRoles, "identities", o.edgeOptions)
identityRoles, err := convertNamesToIds(o.identityRoles, "identities", o.Options)
if err != nil {
return err
}
postureCheckRoles, err := convertNamesToIds(o.postureCheckRoles, "posture-checks", o.edgeOptions)
postureCheckRoles, err := convertNamesToIds(o.postureCheckRoles, "posture-checks", o.Options)
if err != nil {
return err
}
@@ -95,22 +96,22 @@ func runUpdateServicePolicy(o *updateServicePolicyOptions) error {
change := false
if o.Cmd.Flags().Changed("name") {
setJSONValue(entityData, o.name, "name")
api.SetJSONValue(entityData, o.name, "name")
change = true
}
if o.Cmd.Flags().Changed("service-roles") {
setJSONValue(entityData, serviceRoles, "serviceRoles")
api.SetJSONValue(entityData, serviceRoles, "serviceRoles")
change = true
}
if o.Cmd.Flags().Changed("identity-roles") {
setJSONValue(entityData, identityRoles, "identityRoles")
api.SetJSONValue(entityData, identityRoles, "identityRoles")
change = true
}
if o.Cmd.Flags().Changed("posture-check-roles") {
setJSONValue(entityData, postureCheckRoles, "postureCheckRoles")
api.SetJSONValue(entityData, postureCheckRoles, "postureCheckRoles")
change = true
}
@@ -118,6 +119,6 @@ func runUpdateServicePolicy(o *updateServicePolicyOptions) error {
return errors.New("no change specified. must specify at least one attribute to change")
}
_, err = patchEntityOfType(fmt.Sprintf("service-policies/%v", id), entityData.String(), &o.edgeOptions)
_, err = patchEntityOfType(fmt.Sprintf("service-policies/%v", id), entityData.String(), &o.Options)
return err
}
+10 -9
View File
@@ -21,6 +21,7 @@ import (
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/foundation/util/stringz"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"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"
@@ -31,7 +32,7 @@ import (
)
type updateTerminatorOptions struct {
edgeOptions
api.Options
router string
address string
binding string
@@ -41,7 +42,7 @@ type updateTerminatorOptions struct {
func newUpdateTerminatorCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &updateTerminatorOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{
Factory: f,
Out: out,
@@ -79,24 +80,24 @@ func newUpdateTerminatorCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer)
func runUpdateTerminator(o *updateTerminatorOptions) (err error) {
entityData := gabs.New()
router, err := mapNameToID("edge-routers", o.router, o.edgeOptions)
router, err := mapNameToID("edge-routers", o.router, o.Options)
if err != nil {
router = o.router // might be a pure fabric router, id might not be UUID
}
change := false
if o.Cmd.Flags().Changed("router") {
setJSONValue(entityData, router, "router")
api.SetJSONValue(entityData, router, "router")
change = true
}
if o.Cmd.Flags().Changed("binding") {
setJSONValue(entityData, o.binding, "binding")
api.SetJSONValue(entityData, o.binding, "binding")
change = true
}
if o.Cmd.Flags().Changed("address") {
setJSONValue(entityData, o.address, "address")
api.SetJSONValue(entityData, o.address, "address")
change = true
}
@@ -104,7 +105,7 @@ func runUpdateTerminator(o *updateTerminatorOptions) (err error) {
if o.cost > math.MaxUint16 {
return errors2.Errorf("Invalid cost %v. Must be positive number less than or equal to %v", o.cost, math.MaxUint16)
}
setJSONValue(entityData, o.cost, "cost")
api.SetJSONValue(entityData, o.cost, "cost")
change = true
}
@@ -113,7 +114,7 @@ func runUpdateTerminator(o *updateTerminatorOptions) (err error) {
if !stringz.Contains(validValues, o.precedence) {
return errors2.Errorf("Invalid precedence %v. Must be one of %+v", o.precedence, validValues)
}
setJSONValue(entityData, o.precedence, "precedence")
api.SetJSONValue(entityData, o.precedence, "precedence")
change = true
}
@@ -121,6 +122,6 @@ func runUpdateTerminator(o *updateTerminatorOptions) (err error) {
return errors.New("no change specified. must specify at least one attribute to change")
}
_, err = patchEntityOfType(fmt.Sprintf("terminators/%v", o.Args[0]), entityData.String(), &o.edgeOptions)
_, err = patchEntityOfType(fmt.Sprintf("terminators/%v", o.Args[0]), entityData.String(), &o.Options)
return err
}
+5 -4
View File
@@ -17,6 +17,7 @@
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
@@ -26,13 +27,13 @@ import (
// useOptions are the flags for use commands
type useOptions struct {
edgeOptions
api.Options
}
// newUseCmd creates the command
func newUseCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &useOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -67,7 +68,7 @@ func (o *useOptions) Run() error {
// If no identities specified, list known identities
if len(o.Args) == 0 {
id := config.GetIdentity()
for k, v := range config.Identities {
for k, v := range config.EdgeIdentities {
o.Printf("id: %12v | current: %5v | read-only: %5v | urL: %v\n", k, k == id, v.ReadOnly, v.Url)
}
return nil
@@ -75,6 +76,6 @@ func (o *useOptions) Run() error {
id := o.Args[0]
config.Default = id
o.Printf("Settting identity '%v' as default in %v\n", id, configFile)
o.Printf("Setting identity '%v' as default in %v\n", id, configFile)
return util.PersistRestClientConfig(config)
}
+2 -1
View File
@@ -17,6 +17,7 @@
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"io"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
@@ -42,6 +43,6 @@ func newVerifyCmd(out io.Writer, errOut io.Writer) *cobra.Command {
}
// createEntityOfType create an entity of the given type on the Ziti Edge Controller
func verifyEntityOfType(entityType, body, id string, options *edgeOptions) error {
func verifyEntityOfType(entityType, body, id string, options *api.Options) error {
return util.EdgeControllerVerify(entityType, id, body, options.Out, options.OutputJSONResponse, options.Timeout, options.Verbose)
}
+6 -5
View File
@@ -28,6 +28,7 @@ import (
"fmt"
nfpem "github.com/openziti/foundation/util/pem"
"github.com/openziti/foundation/util/term"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
@@ -40,7 +41,7 @@ import (
)
type verifyCaOptions struct {
edgeOptions
api.Options
certPath string
certPemBytes []byte
@@ -61,7 +62,7 @@ type verifyCaOptions struct {
// newVerifyCaCmd creates the 'edge controller verify ca' command for the given entity type
func newVerifyCaCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &verifyCaOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{
Out: out,
Err: errOut,
@@ -133,14 +134,14 @@ func newVerifyCaCmd(out io.Writer, errOut io.Writer) *cobra.Command {
func runValidateCa(options *verifyCaOptions) error {
var err error
options.caId, err = mapCaNameToID(options.caNameOrId, options.edgeOptions)
options.caId, err = mapCaNameToID(options.caNameOrId, options.Options)
if err != nil {
return err
}
if options.isGenerateCert {
jsonContainer, err := util.EdgeControllerRequest("cas/"+options.caId, options.Out, options.OutputJSONResponse, options.edgeOptions.Timeout, options.edgeOptions.Verbose, func(request *resty.Request, url string) (*resty.Response, error) { return request.Get(url) })
jsonContainer, err := util.EdgeControllerRequest("cas/"+options.caId, options.Out, options.OutputJSONResponse, options.Options.Timeout, options.Options.Verbose, func(request *resty.Request, url string) (*resty.Response, error) { return request.Get(url) })
if err != nil {
return fmt.Errorf("could not request ca [%s] (%v}", options.caId, err)
@@ -159,7 +160,7 @@ func runValidateCa(options *verifyCaOptions) error {
}
}
return util.EdgeControllerVerify("cas", options.caId, string(options.certPemBytes), options.Out, options.OutputJSONResponse, options.edgeOptions.Timeout, options.edgeOptions.Verbose)
return util.EdgeControllerVerify("cas", options.caId, string(options.certPemBytes), options.Out, options.OutputJSONResponse, options.Options.Timeout, options.Options.Verbose)
}
func generateCert(options *verifyCaOptions, token string) ([]byte, crypto.Signer, error) {
+4 -3
View File
@@ -18,6 +18,7 @@ package edge
import (
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
@@ -27,13 +28,13 @@ import (
// versionOptions are the flags for version commands
type versionOptions struct {
edgeOptions
api.Options
}
// newVersionCmd creates the command
func newVersionCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &versionOptions{
edgeOptions: edgeOptions{
Options: api.Options{
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -58,7 +59,7 @@ func newVersionCmd(out io.Writer, errOut io.Writer) *cobra.Command {
// Run implements this command
func (o *versionOptions) Run() error {
jsonParsed, err := util.EdgeControllerList("version", nil, o.OutputJSONResponse, o.Out, o.edgeOptions.Timeout, o.edgeOptions.Verbose)
jsonParsed, err := util.EdgeControllerList("version", nil, o.OutputJSONResponse, o.Out, o.Options.Timeout, o.Options.Verbose)
if err != nil {
return err
}
+82
View File
@@ -0,0 +1,82 @@
/*
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 fabric
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
)
type addIdentityOptions struct {
common.CommonOptions
caCert string
clientCert string
clientKey string
readOnly bool
}
func newAddIdentityCmd(p common.OptionsProvider) *cobra.Command {
options := &addIdentityOptions{
CommonOptions: p(),
}
cmd := &cobra.Command{
Use: "add-identity <server-url>",
Short: "adds a fabric identity for connecting to the Ziti Controller",
Args: cobra.ExactArgs(1),
RunE: options.run,
}
cmd.Flags().StringVarP(&common.CliIdentity, "cli-identity", "i", "", "Specify the saved identity you want the CLI to use when connect to the controller with")
cmd.Flags().StringVar(&options.caCert, "ca-cert", "", "additional root certificates used by the Ziti Controller")
cmd.Flags().StringVar(&options.clientCert, "client-cert", "", "client certificate used to authenticate to the Ziti Controller")
cmd.Flags().StringVar(&options.clientKey, "client-key", "", "client certificate key used to authenticate to the Ziti Controller")
cmd.Flags().BoolVar(&options.readOnly, "read-only", false, "marks this login as read-only. Note: this is not a guarantee that nothing can be changed on the server. Care should still be taken!")
for _, required := range []string{"ca-cert", "client-cert", "client-key"} {
if err := cmd.MarkFlagRequired(required); err != nil {
panic(err)
}
}
return cmd
}
func (o *addIdentityOptions) run(_ *cobra.Command, args []string) error {
config, configFile, err := util.LoadRestClientConfig()
if err != nil {
return err
}
id := config.GetIdentity()
loginIdentity := &util.RestClientFabricIdentity{
Url: args[0],
CaCert: o.caCert,
ClientCert: o.clientCert,
ClientKey: o.clientKey,
ReadOnly: o.readOnly,
}
o.Printf("Saving identity '%v' to %v\n", id, configFile)
config.FabricIdentities[id] = loginIdentity
err = util.PersistRestClientConfig(config)
return nil
}
+91
View File
@@ -0,0 +1,91 @@
/*
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 fabric
import (
"crypto/sha1"
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/foundation/identity/certtools"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
"github.com/spf13/cobra"
)
type createRouterOptions struct {
api.Options
name string
tags map[string]string
}
// newCreateRouterCmd creates the 'fabric create router' command for the given entity type
func newCreateRouterCmd(p common.OptionsProvider) *cobra.Command {
options := &createRouterOptions{
Options: api.Options{
CommonOptions: p(),
},
tags: make(map[string]string),
}
cmd := &cobra.Command{
Use: "router <path-to-cert>",
Short: "creates a router managed by the Ziti Controller",
Args: cobra.MinimumNArgs(1),
RunE: options.createRouter,
SuggestFor: []string{},
}
// allow interspersing positional args and flags
cmd.Flags().SetInterspersed(true)
cmd.Flags().StringToStringVarP(&options.tags, "tags", "t", nil, "Add tags to router definition")
cmd.Flags().StringVar(&options.name, "name", "", "Specifies the router name. If not specified, the id in the controller cert will be used")
options.AddCommonFlags(cmd)
return cmd
}
// createRouter implements the command to create a router
func (o *createRouterOptions) createRouter(_ *cobra.Command, args []string) error {
cert, err := certtools.LoadCertFromFile(args[0])
if err != nil {
return err
}
entityData := gabs.New()
id := cert[0].Subject.CommonName
name := id
if o.name != "" {
name = o.name
}
fingerprint := fmt.Sprintf("%x", sha1.Sum(cert[0].Raw))
api.SetJSONValue(entityData, id, "id")
api.SetJSONValue(entityData, name, "name")
api.SetJSONValue(entityData, fingerprint, "fingerprint")
api.SetJSONValue(entityData, o.tags, "tags")
result, err := createEntityOfType("routers", entityData.String(), &o.Options)
if err != nil {
return err
}
if !o.OutputJSONResponse {
id := result.S("data", "id").Data()
_, err = fmt.Fprintf(o.Out, "New %v %v created with id: %v\n", "router", name, id)
return err
}
return nil
}
@@ -0,0 +1,71 @@
/*
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 fabric
import (
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
"github.com/spf13/cobra"
)
type createServiceOptions struct {
api.Options
terminatorStrategy string
tags map[string]string
}
// newCreateServiceCmd creates the 'fabric create service' command for the given entity type
func newCreateServiceCmd(p common.OptionsProvider) *cobra.Command {
options := &createServiceOptions{
Options: api.Options{
CommonOptions: p(),
},
tags: make(map[string]string),
}
cmd := &cobra.Command{
Use: "service <name>",
Short: "creates a service managed by the Ziti Controller",
Args: cobra.MinimumNArgs(1),
RunE: options.createService,
SuggestFor: []string{},
}
// allow interspersing positional args and flags
cmd.Flags().SetInterspersed(true)
cmd.Flags().StringToStringVarP(&options.tags, "tags", "t", nil, "Add tags to service definition")
cmd.Flags().StringVar(&options.terminatorStrategy, "terminator-strategy", "", "Specifies the terminator strategy for the service")
options.AddCommonFlags(cmd)
return cmd
}
// createService implements the command to create a service
func (o *createServiceOptions) createService(_ *cobra.Command, args []string) (err error) {
o.Args = args
entityData := gabs.New()
api.SetJSONValue(entityData, args[0], "name")
if o.terminatorStrategy != "" {
api.SetJSONValue(entityData, o.terminatorStrategy, "terminatorStrategy")
}
api.SetJSONValue(entityData, o.tags, "tags")
result, err := createEntityOfType("services", entityData.String(), &o.Options)
return o.LogCreateResult("service", result, err)
}
@@ -0,0 +1,110 @@
/*
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 fabric
import (
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/edge/router/xgress_edge_transport"
"github.com/openziti/foundation/util/stringz"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
"math"
)
type createTerminatorOptions struct {
api.Options
binding string
cost int32
precedence string
identity string
}
// newCreateTerminatorCmd creates the 'fabric create terminator' command
func newCreateTerminatorCmd(p common.OptionsProvider) *cobra.Command {
options := &createTerminatorOptions{
Options: api.Options{CommonOptions: p()},
}
cmd := &cobra.Command{
Use: "terminator service router address",
Short: "creates a service terminator managed by the Ziti Controller",
Args: cobra.ExactArgs(3),
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := runCreateTerminator(options)
cmdhelper.CheckErr(err)
},
SuggestFor: []string{},
}
// allow interspersing positional args and flags
cmd.Flags().SetInterspersed(true)
cmd.Flags().StringVar(&options.binding, "binding", xgress_edge_transport.BindingName, "Set the terminator binding")
cmd.Flags().Int32VarP(&options.cost, "cost", "c", 0, "Set the terminator cost")
cmd.Flags().StringVarP(&options.precedence, "precedence", "p", "", "Set the terminator precedence ('default', 'required' or 'failed')")
cmd.Flags().StringVar(&options.identity, "identity", "", "Set the terminator identity")
options.AddCommonFlags(cmd)
return cmd
}
// runCreateTerminator implements the command to create a Terminator
func runCreateTerminator(o *createTerminatorOptions) (err error) {
entityData := gabs.New()
service, err := api.MapNameToID(util.FabricAPI, "services", &o.Options, o.Args[0])
if err != nil {
return err
}
router, err := api.MapNameToID(util.FabricAPI, "routers", &o.Options, o.Args[1])
if err != nil {
return err
}
api.SetJSONValue(entityData, service, "service")
api.SetJSONValue(entityData, router, "router")
api.SetJSONValue(entityData, o.binding, "binding")
api.SetJSONValue(entityData, o.Args[2], "address")
api.SetJSONValue(entityData, o.identity, "identity")
if o.cost > 0 {
if o.cost > math.MaxUint16 {
if _, err = fmt.Fprintf(o.Out, "Invalid cost %v. Must be positive number less than or equal to %v\n", o.cost, math.MaxUint16); err != nil {
panic(err)
}
return
}
api.SetJSONValue(entityData, o.cost, "cost")
}
if o.precedence != "" {
validValues := []string{"default", "required", "failed"}
if !stringz.Contains(validValues, o.precedence) {
if _, err = fmt.Fprintf(o.Out, "Invalid precedence %v. Must be one of %+v\n", o.precedence, validValues); err != nil {
panic(err)
}
return
}
api.SetJSONValue(entityData, o.precedence, "precedence")
}
result, err := createEntityOfType("terminators", entityData.String(), &o.Options)
return o.LogCreateResult("terminator", result, err)
}
+136
View File
@@ -0,0 +1,136 @@
/*
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 fabric
import (
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
)
type deleteOptions struct {
api.Options
isCircuit bool
immediate bool
}
func (self *deleteOptions) AddCommonFlags(cmd *cobra.Command) {
self.Options.AddCommonFlags(cmd)
if self.isCircuit {
if self.isCircuit {
cmd.Flags().BoolVar(&self.immediate, "immediate", false, "delete the circuit immediately, without allowing a graceful shutdown")
}
}
}
func (self *deleteOptions) GetBody() string {
if self.isCircuit {
c := gabs.New()
api.SetJSONValue(c, self.immediate, "immediate")
return c.String()
}
return ""
}
// newDeleteCmd creates a command object for the "edge controller delete" command
func newDeleteCmd(p common.OptionsProvider) *cobra.Command {
cmd := &cobra.Command{
Use: "delete",
Short: "deletes various entities managed by the Ziti Controller",
Run: func(cmd *cobra.Command, args []string) {
err := cmd.Help()
cmdhelper.CheckErr(err)
},
}
newOptions := func(isCircuit bool) *deleteOptions {
return &deleteOptions{
Options: api.Options{CommonOptions: p()},
isCircuit: true,
}
}
cmd.AddCommand(newDeleteCmdForEntityType("circuit", newOptions(true)))
cmd.AddCommand(newDeleteCmdForEntityType("router", newOptions(false)))
cmd.AddCommand(newDeleteCmdForEntityType("service", newOptions(false)))
cmd.AddCommand(newDeleteCmdForEntityType("terminator", newOptions(false)))
return cmd
}
// newDeleteCmdForEntityType creates the delete command for the given entity type
func newDeleteCmdForEntityType(entityType string, options *deleteOptions, aliases ...string) *cobra.Command {
cmd := &cobra.Command{
Use: entityType + " <id>",
Short: "deletes " + api.GetPlural(entityType) + " managed by the Ziti Controller",
Args: cobra.MinimumNArgs(1),
Aliases: append(aliases, api.GetPlural(entityType)),
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := runDeleteEntityOfType(options, api.GetPlural(entityType))
cmdhelper.CheckErr(err)
},
SuggestFor: []string{},
}
// allow interspersing positional args and flags
cmd.Flags().SetInterspersed(true)
options.AddCommonFlags(cmd)
cmd.AddCommand(newDeleteWhereCmdForEntityType(entityType, options))
return cmd
}
func newDeleteWhereCmdForEntityType(entityType string, options *deleteOptions) *cobra.Command {
cmd := &cobra.Command{
Use: "where <filter>",
Short: "deletes " + api.GetPlural(entityType) + " matching the filter managed by the Ziti Controller",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := api.DeleteEntityOfTypeWhere("fabric", &options.Options, api.GetPlural(entityType), options.GetBody())
cmdhelper.CheckErr(err)
},
SuggestFor: []string{},
}
// allow interspersing positional args and flags
cmd.Flags().SetInterspersed(true)
options.AddCommonFlags(cmd)
return cmd
}
// runDeleteEntityOfType implements the commands to delete various entity types
func runDeleteEntityOfType(o *deleteOptions, entityType string) error {
var err error
ids := o.Args
if entityType != "terminators" && entityType != "links" && entityType != "circuits" {
ids, err = api.MapNamesToIDs("fabric", entityType, &o.Options, ids...)
}
if err != nil {
return err
}
return api.DeleteEntitiesOfType(util.FabricAPI, &o.Options, entityType, ids, o.GetBody())
}
+326
View File
@@ -0,0 +1,326 @@
/*
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 fabric
import (
"fmt"
"github.com/Jeffail/gabs"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
"strings"
)
// newListCmd creates a command object for the "controller list" command
func newListCmd(p common.OptionsProvider) *cobra.Command {
listCmd := &cobra.Command{
Use: "list",
Short: "Lists various entities managed by the Ziti Controller",
Run: func(cmd *cobra.Command, args []string) {
err := cmd.Help()
cmdhelper.CheckErr(err)
},
}
newOptions := func() *api.Options {
return &api.Options{CommonOptions: p()}
}
listCmd.AddCommand(newListCmdForEntityType("circuits", runListCircuits, newOptions()))
listCmd.AddCommand(newListCmdForEntityType("links", runListLinks, newOptions()))
listCmd.AddCommand(newListCmdForEntityType("routers", runListRouters, newOptions()))
listCmd.AddCommand(newListCmdForEntityType("services", runListServices, newOptions()))
listCmd.AddCommand(newListCmdForEntityType("terminators", runListTerminators, newOptions()))
return listCmd
}
func listEntitiesWithOptions(entityType string, options *api.Options) ([]*gabs.Container, *api.Paging, error) {
return api.ListEntitiesWithOptions(util.FabricAPI, entityType, options)
}
type listCommandRunner func(*api.Options) error
// newListCmdForEntityType creates the list command for the given entity type
func newListCmdForEntityType(entityType string, command listCommandRunner, options *api.Options, aliases ...string) *cobra.Command {
cmd := &cobra.Command{
Use: entityType + " <filter>?",
Short: "lists " + entityType + " managed by the Ziti Controller",
Args: cobra.MaximumNArgs(1),
Aliases: aliases,
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := command(options)
cmdhelper.CheckErr(err)
},
SuggestFor: []string{},
}
// allow interspersing positional args and flags
cmd.Flags().SetInterspersed(true)
cmd.Flags().BoolVar(&options.OutputCSV, "csv", false, "Output CSV instead of a formatted table")
options.AddCommonFlags(cmd)
return cmd
}
func runListCircuits(o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions("circuits", o)
if err != nil {
return err
}
return outputCircuits(o, children, pagingInfo)
}
func outputCircuits(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error {
if o.OutputJSONResponse {
return nil
}
t := table.NewWriter()
t.SetStyle(table.StyleRounded)
t.AppendHeader(table.Row{"ID", "Client", "Service", "Path"})
for _, entity := range children {
id := api.GetJsonString(entity, "id")
client := api.GetJsonString(entity, "clientId")
service := api.GetJsonString(entity, "service.name")
path := strings.Builder{}
nodes, err := getEntityRef(entity.Path("path.nodes"))
if err != nil {
return err
}
links, err := getEntityRef(entity.Path("path.links"))
if err != nil {
return err
}
if len(nodes) > 0 {
path.WriteString("r/")
path.WriteString(nodes[0].name)
for idx, node := range nodes[1:] {
link := links[idx]
path.WriteString(" -> l/")
path.WriteString(link.id)
path.WriteString(" -> r/")
path.WriteString(node.name)
}
}
t.AppendRow(table.Row{id, client, service, path.String()})
}
renderTable(o, t, pagingInfo)
return nil
}
type entityRef struct {
id string
name string
}
func getEntityRef(c *gabs.Container) ([]*entityRef, error) {
if c == nil || c.Data() == nil {
return nil, nil
}
children, err := c.Children()
if err != nil {
return nil, err
}
var result []*entityRef
for _, child := range children {
id := api.GetJsonString(child, "id")
name := api.GetJsonString(child, "name")
result = append(result, &entityRef{
id: id,
name: name,
})
}
return result, nil
}
func runListLinks(o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions("links", o)
if err != nil {
return err
}
return outputLinks(o, children, pagingInfo)
}
func outputLinks(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error {
if o.OutputJSONResponse {
return nil
}
t := table.NewWriter()
t.SetStyle(table.StyleRounded)
columnConfigs := make([]table.ColumnConfig, 9)
columnConfigs[4] = table.ColumnConfig{Align: text.AlignRight}
columnConfigs[5] = table.ColumnConfig{Align: text.AlignRight}
t.SetColumnConfigs(columnConfigs)
t.AppendHeader(table.Row{"ID", "Dialer", "Acceptor", "Static Cost", "Src Latency", "Dst Latency", "State", "Status", "Full Cost"})
for _, entity := range children {
id := entity.Path("id").Data().(string)
srcRouter := entity.Path("sourceRouter.name").Data().(string)
dstRouter := entity.Path("destRouter.name").Data().(string)
staticCost := entity.Path("staticCost").Data().(float64)
srcLatency := entity.Path("sourceLatency").Data().(float64) / 1_000_000
dstLatency := entity.Path("destLatency").Data().(float64) / 1_000_000
state := entity.Path("state").Data().(string)
down := entity.Path("down").Data().(bool)
cost := entity.Path("cost").Data().(float64)
status := "up"
if down {
status = "down"
}
t.AppendRow(table.Row{id, srcRouter, dstRouter, staticCost,
fmt.Sprintf("%.2vms", srcLatency),
fmt.Sprintf("%.2vms", dstLatency),
state, status, cost})
}
renderTable(o, t, pagingInfo)
return nil
}
func runListTerminators(o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions("terminators", o)
if err != nil {
return err
}
return outputTerminators(o, children, pagingInfo)
}
func outputTerminators(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error {
if o.OutputJSONResponse {
return nil
}
t := table.NewWriter()
t.SetStyle(table.StyleRounded)
t.AppendHeader(table.Row{"ID", "Service", "Router", "Binding", "Address", "Identity", "Cost", "Precedence", "Dynamic Cost"})
for _, entity := range children {
id, _ := entity.Path("id").Data().(string)
service := entity.Path("service.name").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)
staticCost := entity.Path("cost").Data().(float64)
precedence := entity.Path("precedence").Data().(string)
dynamicCost := entity.Path("dynamicCost").Data().(float64)
t.AppendRow(table.Row{id, service, router, binding, address, identity, staticCost, precedence, dynamicCost})
}
renderTable(o, t, pagingInfo)
return nil
}
func runListServices(o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions("services", o)
if err != nil {
return err
}
return outputServices(o, children, pagingInfo)
}
func outputServices(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error {
if o.OutputJSONResponse {
return nil
}
t := table.NewWriter()
t.SetStyle(table.StyleRounded)
t.AppendHeader(table.Row{"ID", "Name", "Terminator Strategy"})
for _, entity := range children {
id := entity.Path("id").Data().(string)
name := entity.Path("name").Data().(string)
terminatorStrategy, _ := entity.Path("terminatorStrategy").Data().(string)
t.AppendRow(table.Row{id, name, terminatorStrategy})
}
renderTable(o, t, pagingInfo)
return nil
}
func runListRouters(o *api.Options) error {
children, pagingInfo, err := listEntitiesWithOptions("routers", o)
if err != nil {
return err
}
return outputRouters(o, children, pagingInfo)
}
func outputRouters(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error {
if o.OutputJSONResponse {
return nil
}
t := table.NewWriter()
t.SetStyle(table.StyleRounded)
t.AppendHeader(table.Row{"ID", "Name", "Online", "Version"})
for _, entity := range children {
id := entity.Path("id").Data().(string)
name := entity.Path("name").Data().(string)
connected := entity.Path("connected").Data().(bool)
versionInfo := entity.Path("versionInfo")
var version string
if versionInfo != nil {
v := versionInfo.Path("version").Data().(string)
os := versionInfo.Path("os").Data().(string)
arch := versionInfo.Path("arch").Data().(string)
version = fmt.Sprintf("%v on %v/%v", v, os, arch)
}
t.AppendRow(table.Row{id, name, connected, version})
}
renderTable(o, t, pagingInfo)
return nil
}
func renderTable(o *api.Options, t table.Writer, pagingInfo *api.Paging) {
if o.OutputCSV {
if _, err := fmt.Fprintln(o.Cmd.OutOrStdout(), t.RenderCSV()); err != nil {
panic(err)
}
} else {
if _, err := fmt.Fprintln(o.Cmd.OutOrStdout(), t.Render()); err != nil {
panic(err)
}
pagingInfo.Output(o)
}
}
@@ -0,0 +1,68 @@
/*
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 fabric
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
)
// removeIdentityOptions are the flags for removeIdentity commands
type removeIdentityOptions struct {
common.CommonOptions
}
// newRemoveIdentityCmd creates the command
func newRemoveIdentityCmd(p common.OptionsProvider) *cobra.Command {
options := &removeIdentityOptions{
CommonOptions: p(),
}
cmd := &cobra.Command{
Use: "remove-identity",
Short: "remove an identity for a Ziti Controller instance",
Args: cobra.ExactArgs(0),
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := options.Run()
cmdhelper.CheckErr(err)
},
SuggestFor: []string{},
}
// allow interspersing positional args and flags
cmd.Flags().SetInterspersed(true)
cmd.Flags().StringVarP(&common.CliIdentity, "cli-identity", "i", "", "Specify the saved identity you want the CLI to use when connect to the controller with")
return cmd
}
// Run implements this command
func (o *removeIdentityOptions) Run() error {
config, configFile, err := util.LoadRestClientConfig()
if err != nil {
return err
}
id := config.GetIdentity()
o.Printf("Removing fabric identity '%v' from %v\n", id, configFile)
delete(config.FabricIdentities, id)
return util.PersistRestClientConfig(config)
}
+84
View File
@@ -0,0 +1,84 @@
/*
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 fabric
import (
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
"gopkg.in/resty.v1"
)
// NewFabricCmd creates a command object for the fabric command
func NewFabricCmd(p common.OptionsProvider) *cobra.Command {
fabricCmd := util.NewEmptyParentCmd("fabric", "Interact with Ziti Fabric Components")
fabricCmd.AddCommand(newAddIdentityCmd(p), newRemoveIdentityCmd(p))
fabricCmd.AddCommand(newCreateCommand(p), newListCmd(p), newUpdateCommand(p), newDeleteCmd(p))
return fabricCmd
}
func newCreateCommand(p common.OptionsProvider) *cobra.Command {
createCmd := &cobra.Command{
Use: "create",
Short: "creates various entities managed by the Ziti Controller",
Run: func(cmd *cobra.Command, args []string) {
cmdhelper.CheckErr(cmd.Help())
},
}
createCmd.AddCommand(newCreateRouterCmd(p))
createCmd.AddCommand(newCreateServiceCmd(p))
createCmd.AddCommand(newCreateTerminatorCmd(p))
return createCmd
}
func newUpdateCommand(p common.OptionsProvider) *cobra.Command {
updateCmd := &cobra.Command{
Use: "update",
Short: "update various entities managed by the Ziti Controller",
Run: func(cmd *cobra.Command, args []string) {
cmdhelper.CheckErr(cmd.Help())
},
}
updateCmd.AddCommand(newUpdateLinkCmd(p))
updateCmd.AddCommand(newUpdateRouterCmd(p))
updateCmd.AddCommand(newUpdateServiceCmd(p))
updateCmd.AddCommand(newUpdateTerminatorCmd(p))
return updateCmd
}
// createEntityOfType create an entity of the given type on the Ziti Controller
func createEntityOfType(entityType string, body string, options *api.Options) (*gabs.Container, error) {
return util.ControllerCreate("fabric", entityType, body, options.Out, options.OutputJSONRequest, options.OutputJSONResponse, options.Timeout, options.Verbose)
}
func patchEntityOfType(entityType string, body string, options *api.Options) (*gabs.Container, error) {
return updateEntityOfType(entityType, body, options, resty.MethodPatch)
}
// updateEntityOfType updates an entity of the given type on the Ziti Edge Controller
func updateEntityOfType(entityType string, body string, options *api.Options, method string) (*gabs.Container, error) {
return util.ControllerUpdate(util.FabricAPI, entityType, body, options.Out, method, options.OutputJSONRequest, options.OutputJSONResponse, options.Timeout, options.Verbose)
}
+84
View File
@@ -0,0 +1,84 @@
/*
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 fabric
import (
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/pkg/errors"
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/spf13/cobra"
)
type updateLinkOptions struct {
api.Options
down bool
staticCost uint32
}
func newUpdateLinkCmd(p common.OptionsProvider) *cobra.Command {
options := &updateLinkOptions{
Options: api.Options{CommonOptions: p()},
}
cmd := &cobra.Command{
Use: "link <idOrName>",
Short: "updates a link managed by the Ziti Controller",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := runUpdateLink(options)
cmdhelper.CheckErr(err)
},
SuggestFor: []string{},
}
// allow interspersing positional args and flags
cmd.Flags().SetInterspersed(true)
cmd.Flags().BoolVar(&options.down, "down", true, "Set link up or down")
cmd.Flags().Uint32Var(&options.staticCost, "static-cost", 0, "Specifies the static cost of the link")
options.AddCommonFlags(cmd)
return cmd
}
// runUpdateLink update a new link on the Ziti Edge Controller
func runUpdateLink(o *updateLinkOptions) error {
entityData := gabs.New()
change := false
if o.Cmd.Flags().Changed("down") {
api.SetJSONValue(entityData, o.down, "down")
change = true
}
if o.Cmd.Flags().Changed("static-cost") {
api.SetJSONValue(entityData, o.staticCost, "staticCost")
change = true
}
if !change {
return errors.New("no change specified. must specify at least one attribute to change")
}
_, err := patchEntityOfType(fmt.Sprintf("links/%v", o.Args[0]), entityData.String(), &o.Options)
return err
}
+89
View File
@@ -0,0 +1,89 @@
/*
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 fabric
import (
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/pkg/errors"
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/spf13/cobra"
)
type updateRouterOptions struct {
api.Options
name string
fingerprint string
}
func newUpdateRouterCmd(p common.OptionsProvider) *cobra.Command {
options := &updateRouterOptions{
Options: api.Options{CommonOptions: p()},
}
cmd := &cobra.Command{
Use: "router <idOrName>",
Short: "updates a router managed by the Ziti Controller",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := runUpdateRouter(options)
cmdhelper.CheckErr(err)
},
SuggestFor: []string{},
}
// allow interspersing positional args and flags
cmd.Flags().SetInterspersed(true)
cmd.Flags().StringVarP(&options.name, "name", "n", "", "Set the router name")
cmd.Flags().StringVar(&options.fingerprint, "fingerprint", "", "Sets the router fingerprint")
options.AddCommonFlags(cmd)
return cmd
}
// runUpdateRouter update a new router on the Ziti Edge Controller
func runUpdateRouter(o *updateRouterOptions) error {
id, err := api.MapNameToID(util.FabricAPI, "routers", &o.Options, o.Args[0])
if err != nil {
return err
}
entityData := gabs.New()
change := false
if o.Cmd.Flags().Changed("name") {
api.SetJSONValue(entityData, o.name, "name")
change = true
}
if o.Cmd.Flags().Changed("fingerprint") {
api.SetJSONValue(entityData, o.fingerprint, "fingerprint")
change = true
}
if !change {
return errors.New("no change specified. must specify at least one attribute to change")
}
_, err = patchEntityOfType(fmt.Sprintf("routers/%v", id), entityData.String(), &o.Options)
return err
}
@@ -0,0 +1,89 @@
/*
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 fabric
import (
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/pkg/errors"
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/spf13/cobra"
)
type updateServiceOptions struct {
api.Options
name string
terminatorStrategy string
}
func newUpdateServiceCmd(p common.OptionsProvider) *cobra.Command {
options := &updateServiceOptions{
Options: api.Options{CommonOptions: p()},
}
cmd := &cobra.Command{
Use: "service <idOrName>",
Short: "updates a service managed by the Ziti Controller",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := runUpdateService(options)
cmdhelper.CheckErr(err)
},
SuggestFor: []string{},
}
// allow interspersing positional args and flags
cmd.Flags().SetInterspersed(true)
cmd.Flags().StringVarP(&options.name, "name", "n", "", "Set the name of the service")
cmd.Flags().StringVar(&options.terminatorStrategy, "terminator-strategy", "", "Specifies the terminator strategy for the service")
options.AddCommonFlags(cmd)
return cmd
}
// runUpdateService update a new service on the Ziti Edge Controller
func runUpdateService(o *updateServiceOptions) error {
id, err := api.MapNameToID(util.FabricAPI, "services", &o.Options, o.Args[0])
if err != nil {
return err
}
entityData := gabs.New()
change := false
if o.Cmd.Flags().Changed("name") {
api.SetJSONValue(entityData, o.name, "name")
change = true
}
if o.Cmd.Flags().Changed("terminator-strategy") {
api.SetJSONValue(entityData, o.terminatorStrategy, "terminatorStrategy")
change = true
}
if !change {
return errors.New("no change specified. must specify at least one attribute to change")
}
_, err = patchEntityOfType(fmt.Sprintf("services/%v", id), entityData.String(), &o.Options)
return err
}
@@ -0,0 +1,120 @@
/*
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 fabric
import (
"errors"
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/foundation/util/stringz"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/api"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
errors2 "github.com/pkg/errors"
"github.com/spf13/cobra"
"math"
)
type updateTerminatorOptions struct {
api.Options
router string
address string
binding string
cost int32
precedence string
}
func newUpdateTerminatorCmd(p common.OptionsProvider) *cobra.Command {
options := &updateTerminatorOptions{
Options: api.Options{CommonOptions: p()},
}
cmd := &cobra.Command{
Use: "terminator <id>",
Short: "updates a service terminator",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := runUpdateTerminator(options)
cmdhelper.CheckErr(err)
},
SuggestFor: []string{},
}
// allow interspersing positional args and flags
cmd.Flags().SetInterspersed(true)
cmd.Flags().StringVar(&options.router, "router", "", "Set the terminator router")
cmd.Flags().StringVar(&options.address, "address", "", "Set the terminator address")
cmd.Flags().StringVar(&options.binding, "binding", "", "Set the terminator binding")
cmd.Flags().Int32VarP(&options.cost, "cost", "c", 0, "Set the terminator cost")
cmd.Flags().StringVarP(&options.precedence, "precedence", "p", "", "Set the terminator precedence ('default', 'required' or 'failed')")
options.AddCommonFlags(cmd)
return cmd
}
// runUpdateTerminator implements the command to update a Terminator
func runUpdateTerminator(o *updateTerminatorOptions) (err error) {
entityData := gabs.New()
router, err := api.MapNameToID(util.FabricAPI, "routers", &o.Options, o.router)
if err != nil {
return err
}
change := false
if o.Cmd.Flags().Changed("router") {
api.SetJSONValue(entityData, router, "router")
change = true
}
if o.Cmd.Flags().Changed("binding") {
api.SetJSONValue(entityData, o.binding, "binding")
change = true
}
if o.Cmd.Flags().Changed("address") {
api.SetJSONValue(entityData, o.address, "address")
change = true
}
if o.Cmd.Flags().Changed("cost") {
if o.cost > math.MaxUint16 {
return errors2.Errorf("Invalid cost %v. Must be positive number less than or equal to %v", o.cost, math.MaxUint16)
}
api.SetJSONValue(entityData, o.cost, "cost")
change = true
}
if o.Cmd.Flags().Changed("precedence") {
validValues := []string{"default", "required", "failed"}
if !stringz.Contains(validValues, o.precedence) {
return errors2.Errorf("Invalid precedence %v. Must be one of %+v", o.precedence, validValues)
}
api.SetJSONValue(entityData, o.precedence, "precedence")
change = true
}
if !change {
return errors.New("no change specified. must specify at least one attribute to change")
}
_, err = patchEntityOfType(fmt.Sprintf("terminators/%v", o.Args[0]), entityData.String(), &o.Options)
return err
}
-2
View File
@@ -100,8 +100,6 @@ func (o *InitOptions) Run() error {
return nil
case c.ZITI_FABRIC:
return nil
case c.ZITI_FABRIC_GW:
err = o.createInitialMgmtGwConfig()
case c.ZITI:
err = o.createInitialZitiConfig()
default:
-3
View File
@@ -70,12 +70,9 @@ func NewCmdInstall(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Co
cmd.AddCommand(NewCmdInstallZitiController(f, out, errOut))
cmd.AddCommand(NewCmdInstallZitiFabric(f, out, errOut))
cmd.AddCommand(NewCmdInstallZitiFabricTest(f, out, errOut))
cmd.AddCommand(NewCmdInstallZitiMgmtGw(f, out, errOut))
cmd.AddCommand(NewCmdInstallZitiRouter(f, out, errOut))
cmd.AddCommand(NewCmdInstallZitiTunnel(f, out, errOut))
cmd.AddCommand(NewCmdInstallZitiEdgeTunnel(f, out, errOut))
cmd.AddCommand(NewCmdInstallZitiEnroller(f, out, errOut))
cmd.AddCommand(NewCmdInstallZitiProxC(f, out, errOut))
// cmd.AddCommand(NewCmdInstallAnsible(f, out, errOut)) // Disable/hide this for now
-15
View File
@@ -100,26 +100,11 @@ func (o *InstallZitiALLOptions) Run() error {
log.Errorf("Error: install failed %s \n", err.Error())
}
err = o.install(c.ZITI_ENROLLER)
if err != nil {
log.Errorf("Error: install failed %s \n", err.Error())
}
err = o.install(c.ZITI_FABRIC)
if err != nil {
log.Errorf("Error: install failed %s \n", err.Error())
}
err = o.install(c.ZITI_FABRIC_GW)
if err != nil {
log.Errorf("Error: install failed %s \n", err.Error())
}
err = o.install(c.ZITI_FABRIC_TEST)
if err != nil {
log.Errorf("Error: install failed %s \n", err.Error())
}
err = o.install(c.ZITI_PROX_C)
if err != nil {
log.Errorf("Error: install failed %s \n", err.Error())
@@ -1,94 +0,0 @@
/*
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 cmd
import (
"io"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/templates"
c "github.com/openziti/ziti/ziti/cmd/ziti/constants"
"github.com/openziti/ziti/ziti/cmd/ziti/internal/log"
"github.com/openziti/ziti/common/version"
"github.com/blang/semver"
"github.com/spf13/cobra"
)
var (
installZitiEnrollerLong = templates.LongDesc(`
Installs the Ziti Enroller app if it has not been installed already
`)
installZitiEnrollerExample = templates.Examples(`
# Install the Ziti Enroller app
ziti install ziti-enroller
`)
)
// InstallZitiEnrollerOptions the options for the upgrade ziti-enroller command
type InstallZitiEnrollerOptions struct {
InstallOptions
Version string
}
// NewCmdInstallZitiEnroller defines the command
func NewCmdInstallZitiEnroller(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &InstallZitiEnrollerOptions{
InstallOptions: InstallOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
},
}
cmd := &cobra.Command{
Use: "ziti-enroller",
Short: "Installs the Ziti Enroller app - if it has not been installed already",
Aliases: []string{"enroller"},
Long: installZitiEnrollerLong,
Example: installZitiEnrollerExample,
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := options.Run()
cmdhelper.CheckErr(err)
},
}
cmd.Flags().StringVarP(&options.Version, "version", "v", "", "The specific version to install")
options.addCommonFlags(cmd)
return cmd
}
// Run implements the command
func (o *InstallZitiEnrollerOptions) Run() error {
newVersion, err := o.getLatestZitiAppVersion(version.GetBranch(), c.ZITI_ENROLLER)
if err != nil {
return err
}
if o.Version != "" {
newVersion, err = semver.Make(o.Version)
}
log.Infoln("Attempting to install '" + c.ZITI_ENROLLER + "' version: " + newVersion.String())
return o.installZitiApp(version.GetBranch(), c.ZITI_ENROLLER, false, newVersion.String())
}

Some files were not shown because too many files have changed in this diff Show More