Implement first service tutorial

This commit is contained in:
Paul Lorenz
2021-08-11 09:13:22 -04:00
parent 19695516a5
commit adcc1762c3
98 changed files with 2849 additions and 1351 deletions
+50
View File
@@ -5,6 +5,56 @@
* Bug fix: Fabric v0.16.93 fixes `xgress.GetCircuit` to provide a `ctrl not ready` error response when requests arrive before the router is fully online.
* Bug fix: Ziti CLI will no longer truncate paths on logins with explicit URLs
* Bug fix: Ziti CLI will now correctly check the proper lengths of sha512 hashes in hex format
* Feature: Ziti CLI improvements
* New interactive tutorial covering creating your first service. Run using: `ziti edge tutorial first-service`
* You can now delete multiple entities at once, by providing multiple ids. Ex: `ziti edge delete services one two` or `ziti edge delete service one two` will both work.
* You can now delete multiple entities at once, by providing a filter. Ex: `ziti edge delete services where 'name contains "foo"`
* Create and delete output now has additional context.
* Feature: Terminators can now be filtered by service and router name: Ex: `ziti edge list terminators 'service.name = "echo"'`
* Feature: New event type `edge.entityCounts`
## Entity Count Events
The Ziti Controller can now generate events with a summary of how many of each entity type are currently in the data store. It can be configured with an interval for how often the event will be generated. The default interval is five minutes.
```
events:
jsonLogger:
subscriptions:
- type: edge.entityCounts
interval: 5m
```
Here is an example of the JSON output of the event:
```
{
"namespace": "edge.entityCounts",
"timestamp": "2021-08-19T13:39:54.056181406-04:00",
"counts": {
"apiSessionCertificates": 0,
"apiSessions": 9,
"authenticators": 4,
"cas": 0,
"configTypes": 5,
"configs": 2,
"edgeRouterPolicies": 4,
"enrollments": 0,
"eventLogs": 0,
"geoRegions": 17,
"identities": 6,
"identityTypes": 4,
"mfas": 0,
"postureCheckTypes": 5,
"postureChecks": 0,
"routers": 2,
"serviceEdgeRouterPolicies": 2,
"servicePolicies": 5,
"services": 3,
"sessions": 0
},
"error": ""
}
```
# Release 0.22.0
+11 -9
View File
@@ -41,8 +41,8 @@ mgmt:
# the number of milliseconds to wait before a hello synchronization fails and closes the connection (30ms to 60000ms, default: 1000ms)
#connectTimeoutMs: 3000
#metrics:
#file:
#metrics:
#file:
#path: /tmp/ziti-controller-metrics.log
#maxsizemb: 100:wq
# Supported formats: json, plain
@@ -52,9 +52,9 @@ mgmt:
#url: http://localhost:8086
#database: ziti
#events:
# jsonLogger:
# subscriptions:
events:
jsonLogger:
subscriptions:
# - type: fabric.routers
# - type: fabric.terminators
# - type: metrics
@@ -69,10 +69,12 @@ mgmt:
# - type: fabric.usage
# - type: services
# - type: fabric.usage
# handler:
# type: file
# format: json
# path: /tmp/ziti-events.log
- type: edge.entityCounts
interval: 5s
handler:
type: file
format: json
path: /tmp/ziti-events.log
# xctrl_example
#
+9 -5
View File
@@ -19,8 +19,10 @@ 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/MakeNowJust/heredoc v1.0.0
github.com/MichaelMure/go-term-markdown v0.1.4
github.com/alecthomas/chroma v0.9.2
github.com/blang/semver v3.5.1+incompatible
github.com/fatih/color v1.7.0
github.com/fatih/color v1.9.0
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa
github.com/go-acme/lego/v4 v4.2.0
github.com/go-openapi/runtime v0.19.30
@@ -32,13 +34,14 @@ require (
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d
github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19
github.com/michaelquigley/pfxlog v0.6.1
github.com/openziti/edge v0.20.25
github.com/openziti/fabric v0.16.93
github.com/openziti/foundation v0.15.69
github.com/openziti/sdk-golang v0.15.81
github.com/openziti/edge v0.20.29
github.com/openziti/fabric v0.16.97
github.com/openziti/foundation v0.15.71
github.com/openziti/sdk-golang v0.15.85
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/rivo/uniseg v0.2.0 // indirect
github.com/rs/cors v1.7.0
github.com/russross/blackfriday v1.5.2
github.com/shirou/gopsutil v2.20.9+incompatible
@@ -48,6 +51,7 @@ require (
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-20210805182204-aaa1db679c0d
google.golang.org/grpc v1.38.0
+61 -10
View File
@@ -45,8 +45,9 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
github.com/AppsFlyer/go-sundheit v0.4.0 h1:7ECd0YWaXJQ9LzdCFrpGxJVeAgXvNarN6uwxrJsh69A=
github.com/AppsFlyer/go-sundheit v0.4.0/go.mod h1:iZ8zWMS7idcvmqewf5mEymWWgoOiG/0WD4+aeh+heX4=
github.com/AppsFlyer/go-sundheit v0.5.0 h1:/VxpyigCfJrq1r97mn9HPiAB2qrhcTFHwNIIDr15CZM=
github.com/AppsFlyer/go-sundheit v0.5.0/go.mod h1:2ZM0BnfqT/mljBQO224VbL5XH06TgWuQ6Cn+cTtCpTY=
github.com/Azure/azure-sdk-for-go v32.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-autorest/autorest v0.1.0/go.mod h1:AKyIcETwSUFxIcs/Wnq/C+kwCtlEYGUVd7FPNb2slmg=
github.com/Azure/go-autorest/autorest v0.5.0/go.mod h1:9HLKlQjVBH6U3oDfsXOeVc56THsLPw1L03yban4xThw=
@@ -67,6 +68,10 @@ github.com/Jeffail/gabs v1.4.0 h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo=
github.com/Jeffail/gabs v1.4.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/MichaelMure/go-term-markdown v0.1.4 h1:Ir3kBXDUtOX7dEv0EaQV8CNPpH+T7AfTh0eniMOtNcs=
github.com/MichaelMure/go-term-markdown v0.1.4/go.mod h1:EhcA3+pKYnlUsxYKBJ5Sn1cTQmmBMjeNlpV8nRb+JxA=
github.com/MichaelMure/go-term-text v0.3.1 h1:Kw9kZanyZWiCHOYu9v/8pWEgDQ6UVN9/ix2Vd2zzWf0=
github.com/MichaelMure/go-term-text v0.3.1/go.mod h1:QgVjAEDUnRMlzpS6ky5CGblux7ebeiLnuy9dAaFZu8o=
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
@@ -82,6 +87,17 @@ github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 h1:5sXbqlSomvdjl
github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/akamai/AkamaiOPEN-edgegrid-golang v0.9.18/go.mod h1:L+HB2uBoDgi3+r1pJEJcbGwyyHhd2QXaGsKLbDwtm8Q=
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U=
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI=
github.com/alecthomas/chroma v0.7.1/go.mod h1:gHw09mkX1Qp80JlYbmN9L3+4R5o6DJJ3GRShh+AICNc=
github.com/alecthomas/chroma v0.9.2 h1:yU1sE2+TZbLIQPMk30SolL2Hn53SR/Pv750f7qZ/XMs=
github.com/alecthomas/chroma v0.9.2/go.mod h1:eMuEnpA18XbG/WhOWtCzJHS7WqEtDAI+HxdwoW0nVSk=
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo=
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0=
github.com/alecthomas/kong v0.2.1-0.20190708041108-0548c6b1afae/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=
github.com/alecthomas/kong v0.2.4/go.mod h1:kQOmtJgV+Lb4aj+I2LEn40cbtawdWJ9Y8QLq+lElKxE=
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY=
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/aliyun/alibaba-cloud-sdk-go v1.61.458/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA=
@@ -147,6 +163,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -159,6 +177,11 @@ github.com/dgryski/dgoogauth v0.0.0-20190221195224-5a805980a5f3 h1:AqeKSZIG/NIC7
github.com/dgryski/dgoogauth v0.0.0-20190221195224-5a805980a5f3/go.mod h1:hEfFauPHz7+NnjR/yHJGhrKo1Za+zStgwUETx3yzqgY=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dnsimple/dnsimple-go v0.63.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c71tQlGr9SeGrg=
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
@@ -169,6 +192,8 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/ef-ds/deque v1.0.4 h1:iFAZNmveMT9WERAkqLJ+oaABF9AcVQ5AjXem/hroniI=
github.com/ef-ds/deque v1.0.4/go.mod h1:gXDnTC3yqvBcHbq2lcExjtAcVrOnJCbMcZXmuj8Z4tg=
github.com/eliukblau/pixterm/pkg/ansimage v0.0.0-20191210081756-9fb6cf8c2f75 h1:vbix8DDQ/rfatfFr/8cf/sJfIL69i4BcZfjrVOxsMqk=
github.com/eliukblau/pixterm/pkg/ansimage v0.0.0-20191210081756-9fb6cf8c2f75/go.mod h1:0gZuvTO1ikSA5LtTI6E13LEOdWQNjIo5MTQOvrV0eFg=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -179,8 +204,9 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/exoscale/egoscale v0.23.0/go.mod h1:hRo78jkjkCDKpivQdRBEpNYF5+cVpCJCPDg2/r45KaY=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
@@ -383,6 +409,8 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y=
github.com/gomarkdown/markdown v0.0.0-20191123064959-2c17d62f5098 h1:Qxs3bNRWe8GTcKMxYOSXm0jx6j0de8XUtb/fsP3GZ0I=
github.com/gomarkdown/markdown v0.0.0-20191123064959-2c17d62f5098/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -546,6 +574,8 @@ github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kyokomi/emoji/v2 v2.2.8 h1:jcofPxjHWEkJtkIbcLHvZhxKgCPl6C7MyjTrD4KDqUE=
github.com/kyokomi/emoji/v2 v2.2.8/go.mod h1:JUcn42DTdsXJo1SWanHh4HKDEyPaR5CqkmoirZZP9qE=
github.com/labbsr0x/bindman-dns-webhook v1.0.2/go.mod h1:p6b+VCXIR8NYKpDr8/dg1HKfQoRHCdcsROXKvmoehKA=
github.com/labbsr0x/goh v1.0.1/go.mod h1:8K2UhVoaWXcCU7Lxoa2omWnC8gyW8px7/lmO61c027w=
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
@@ -556,6 +586,8 @@ github.com/liquidweb/liquidweb-go v1.6.1/go.mod h1:UDcVnAMDkZxpw4Y7NOHkqoeiGacVL
github.com/lucas-clemente/quic-go v0.18.0/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg=
github.com/lucas-clemente/quic-go v0.18.1 h1:DMR7guC0NtVS8zNZR3IO7NARZvZygkSC56GGtC6cyys=
github.com/lucas-clemente/quic-go v0.18.1/go.mod h1:yXttHsSNxQi8AWijC/vLP+OJczXqzHSOcJrM5ITUlCg=
github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac=
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/lucsky/cuid v1.2.1 h1:MtJrL2OFhvYufUIn48d35QGXyeTC8tn0upumW9WwTHg=
github.com/lucsky/cuid v1.2.1/go.mod h1:QaaJqckboimOmhRSJXSx/+IT+VTfxfPGSo/6mfgUfmE=
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
@@ -582,19 +614,24 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
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.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=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43 h1:WgyLFv10Ov49JAQI/ZLUkCZ7VJS3r74hwFIGXJsgZlY=
@@ -686,14 +723,15 @@ 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.25 h1:MJxT6HHdKvbM/kxFASOXLkxaFJ0YMO5jt4fBwb0jxq8=
github.com/openziti/edge v0.20.25/go.mod h1:Xgc3v/85gWML7XuGMA6TiWCQk/MiHxPyfDhxgJFS7XY=
github.com/openziti/fabric v0.16.93 h1:vybizRqfegTj8n9IZG7m2MU1hJUS3mDv8TdAHK/qcOM=
github.com/openziti/fabric v0.16.93/go.mod h1:zONdz/0rklchq807hu3j8e6CE+n1zic4spfFblTUrgY=
github.com/openziti/foundation v0.15.69 h1:+FuN1RkZUMbUWdAozvyoXKVv5ZYBaVd1e+HUS33YmsE=
github.com/openziti/foundation v0.15.69/go.mod h1:Njk4vQbg6ILR/RQiU5DQOk35oMulQRPGHLn386+RSew=
github.com/openziti/sdk-golang v0.15.81 h1:ye3zsrzRukWzI4yds2XpMXcx/jv8R6Ocs6lxGvxQWy4=
github.com/openziti/sdk-golang v0.15.81/go.mod h1:YuS2GO5sthpny/ycoQB2bXDVET0KNKLLZ/9uGfMH4+k=
github.com/openziti/edge v0.20.29 h1:Dsn+q0FvOVdXvoqaGmSC7jtotnS1fNvOAX5yeZ7aOko=
github.com/openziti/edge v0.20.29/go.mod h1:VKUk+AjKZ4dLnVXQaquoTrt5Sp2QQf55/wcJGBiS9bE=
github.com/openziti/fabric v0.16.96/go.mod h1:unmDyUxL/FKyvSVZdFzkQfVl1gwaeTYV62R7dv2zCxQ=
github.com/openziti/fabric v0.16.97 h1:30J85Yxg4ZOlnrTMwZp+gVCoFGKRvIp9WMPR0GUqiU8=
github.com/openziti/fabric v0.16.97/go.mod h1:unmDyUxL/FKyvSVZdFzkQfVl1gwaeTYV62R7dv2zCxQ=
github.com/openziti/foundation v0.15.71 h1:GOAFIZtthfKhWbuW2W7j4EPXAKDL3oRU9jJVWW9JUzg=
github.com/openziti/foundation v0.15.71/go.mod h1:Njk4vQbg6ILR/RQiU5DQOk35oMulQRPGHLn386+RSew=
github.com/openziti/sdk-golang v0.15.85 h1:Su7rcN34gcJjWghnovwjiB8KUa5QyTmukJb7H+9G9J0=
github.com/openziti/sdk-golang v0.15.85/go.mod h1:EcgYTqC9tr7b5HSiRP+v86tqbR9BjHom1xYfdBctUoc=
github.com/oracle/oci-go-sdk v24.2.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
github.com/orcaman/concurrent-map v0.0.0-20210106121528-16402b402231 h1:fa50YL1pzKW+1SsBnJDOHppJN9stOEwS+CRWyUtyYGU=
@@ -746,6 +784,9 @@ github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKc
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@@ -759,6 +800,7 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sacloud/libsacloud v1.36.2/go.mod h1:P7YAOVmnIn3DKHqCZcUKYUXmSwGBm3yS7IBEjKVSrjg=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil v2.20.9+incompatible h1:msXs2frUV+O/JLva9EDLpuJ84PrFsdCTCQex8PUdtkQ=
github.com/shirou/gopsutil v2.20.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
@@ -850,9 +892,11 @@ github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex
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=
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
@@ -909,6 +953,7 @@ go.uber.org/ratelimit v0.0.0-20180316092928-c15da0234277/go.mod h1:2X8KaoNd1J0lZ
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -951,6 +996,9 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20191206065243-da761ea9ff43 h1:gQ6GUSD102fPgli+Yb4cR/cGaHF7tNBt+GYoRCpGC7s=
golang.org/x/image v0.0.0-20191206065243-da761ea9ff43/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -999,6 +1047,7 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -1074,6 +1123,7 @@ golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1115,6 +1165,7 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-55
View File
@@ -1,55 +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 util
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/table"
"io"
"os"
)
type Factory interface {
CreateTable(out io.Writer) table.Table
}
type factory struct {
Batch bool
impersonateUser string
}
// NewFactory creates a factory with the default Kubernetes resources defined
// if optionalClientConfig is nil, then flags will be bound to a new clientcmd.ClientConfig.
// if optionalClientConfig is not nil, then this factory will make use of it.
func NewFactory() Factory {
return &factory{}
}
func (f *factory) SetBatch(batch bool) {
f.Batch = batch
}
// ImpersonateUser returns a new factory impersonating the given user
func (f *factory) ImpersonateUser(user string) Factory {
copy := *f
copy.impersonateUser = user
return &copy
}
func (f *factory) CreateTable(out io.Writer) table.Table {
return table.CreateTable(os.Stdout)
}
+2 -4
View File
@@ -24,7 +24,7 @@ import (
"path/filepath"
"strings"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/edge_controller"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/edge"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
c "github.com/openziti/ziti/ziti/cmd/ziti/constants"
@@ -126,11 +126,10 @@ func NewCmdRoot(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Comm
initCommands := NewCmdInit(f, out, err)
createCommands := NewCmdCreate(f, out, err)
updateCommands := NewCmdUpdate(f, out, err)
deleteCommands := NewCmdDelete(f, out, err)
executeCommands := NewCmdExecute(f, out, err)
psCommands := NewCmdPs(f, out, err)
pkiCommands := NewCmdPKI(f, out, err)
edgeCommand := edge_controller.NewCmdEdge(f, out, err)
edgeCommand := edge.NewCmdEdge(f, out, err)
logFilter := NewCmdLogFormat(f, out, err)
unwrapIdentityFileCommand := NewUnwrapIdentityFileCommand(f, out, err)
@@ -151,7 +150,6 @@ func NewCmdRoot(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Comm
initCommands,
createCommands,
updateCommands,
deleteCommands,
},
},
{
+11
View File
@@ -34,6 +34,17 @@ type Factory interface {
CreateTable(out io.Writer) table.Table
}
type OptionsProvider func() CommonOptions
func NewOptionsProvider(out, err io.Writer) OptionsProvider {
return func() CommonOptions {
return CommonOptions{
Out: out,
Err: err,
}
}
}
// CommonOptions contains common options and helper methods
type CommonOptions struct {
Factory Factory
@@ -0,0 +1,200 @@
v: 3
#trace:
# path: ctrl.trace
profile:
# cpu:
# path: /home/plorenz/tmp/ctrl.cpu.pprof
# memory:
# path: ctrl.memprof
db: {{.DatabaseFile}}
identity:
cert: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ctrl-client.cert.pem
server_cert: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ctrl-server.cert.pem
key: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/private/ctrl.key.pem
ca: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ca-chain.cert.pem
# the endpoint that routers will connect to the controller over.
ctrl:
listener: tls:{{ .ControlPlane.BindAddress }}:{{ .ControlPlane.Port }}
#options:
# (optional) settings
# set the maximum number of connect requests that are buffered and waiting to be acknowledged (1 to 5000, default 1000)
#maxQueuedConnects: 50
# the maximum number of connects that have begun hello synchronization (1 to 1000, default 16)
#maxOutstandingConnects: 100
# the number of milliseconds to wait before a hello synchronization fails and closes the connection (30ms to 60000ms, default: 1000ms)
#connectTimeoutMs: 3000
# the endpoint that management tools connect to the controller over.
mgmt:
listener: tls:{{ .ManagementPlance.BindAddress }}:{{ .ManagementPlane.Port }}
#options:
# (optional) settings
# set the maximum number of connect requests that are buffered and waiting to be acknowledged (1 to 5000, default 1000)
#maxQueuedConnects: 50
# the maximum number of connects that have begun hello synchronization (1 to 1000, default 16)
#maxOutstandingConnects: 100
# the number of milliseconds to wait before a hello synchronization fails and closes the connection (30ms to 60000ms, default: 1000ms)
#connectTimeoutMs: 3000
#metrics:
#influxdb:
#url: http://localhost:8086
#database: ziti
#events:
# jsonLogger:
# subscriptions:
# - type: fabric.routers
# - type: fabric.terminators
# - type: metrics
# sourceFilter: .*
# metricFilter: .*egress.*m1_rate*
# - type: fabric.circuits
# include:
# - created
# - type: edge.sessions
# include:
# - created
# - type: fabric.usage
# - type: services
# - type: fabric.usage
# handler:
# type: file
# format: json
# path: /tmp/ziti-events.log
healthChecks:
boltCheck:
# How often to try entering a bolt read tx. Defaults to 30 seconds
interval: 30s
# When to timeout the check. Defaults to 15 seconds
timeout: 15s
# How long to wait before starting the check. Defaults to 15 seconds
initialDelay: 15s
{{if .EdgeEnabled }}
# By having an 'edge' section defined, the ziti-controller will attempt to parse the edge configuration. Removing this
# section, commenting out, or altering the name of the section will cause the edge to not run.
edge:
# This section represents the configuration of the Edge API that is served over HTTPS
api:
#(optional, default 90s) Alters how frequently heartbeat and last activity values are persisted
# activityUpdateInterval: 90s
#(optional, default 250) The number of API Sessions updated for last activity per transaction
# activityUpdateBatchSize: 250
# sessionTimeout - optional, default 10m
# The number of minutes before an Edge API session will timeout. Timeouts are reset by
# API requests and connections that are maintained to Edge Routers
sessionTimeout: 30m
# address - required
# The default address (host:port) to use for enrollment for the Client API. This value must match one of the addresses
# defined in a bind point's address field for the `edge-client` API in the web section.
address: 127.0.0.1:1280
# enrollment - required
# A section containing settings pertaining to enrollment.
enrollment:
# signingCert - required
# A Ziti Identity configuration section that specifically makes use of the cert and key fields to define
# a signing certificate from the PKI that the Ziti environment is using to sign certificates. The signingCert.cert
# will be added to the /.well-known CA store that is used to bootstrap trust with the Ziti Controller.
signingCert:
cert: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/intermediate.cert.pem
key: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/private/intermediate.key.decrypted.pem
# edgeIdentity - optional
# A section for identity enrollment specific settings
edgeIdentity:
# duration - optional, default 5m
# The length of time that a Ziti Edge Identity enrollment should remain valid. After
# this duration, the enrollment will expire and not longer be usable.
duration: 5m
# edgeRouter - Optional
# A section for edge router enrollment specific settings.
edgeRouter:
# duration - optional, default 5m
# The length of time that a Ziti Edge Router enrollment should remain valid. After
# this duration, the enrollment will expire and not longer be usable.
duration: 5m
{{end}}
# web - optional
# Defines webListeners that will be hosted by the controller. Each webListener can host many APIs and be bound to many
# bind points.
web:
# name - required
# Provides a name for this listener, used for logging output. Not required to be unique, but is highly suggested.
- name: all-apis-localhost
# bindPoints - required
# One or more bind points are required. A bind point specifies an interface (interface:port string) that defines
# where on the host machine the webListener will listen and the address (host:port) that should be used to
# publicly address the webListener(i.e. mydomain.com, localhost, 127.0.0.1). This public address may be used for
# incoming address resolution as well as used in responses in the API.
bindPoints:
#interface - required
# A host:port string on which network interface to listen on. 0.0.0.0 will listen on all interfaces
- interface: {{.Web.BindAddress}}:{{ .Web.Port }}
# address - required
# The public address that external incoming requests will be able to resolve. Used in request processing and
# response content that requires full host:port/path addresses.
address: {{.Web.ExternalAddress}}:{{ .Web.ExternalPort }}
# identity - optional
# Allows the webListener to have a specific identity instead of defaulting to the root `identity` section.
# identity:
# cert: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ctrl-client.cert.pem
# server_cert: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ctrl-server.cert.pem
# key: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/private/ctrl.key.pem
# ca: ${ZITI_SOURCE}/ziti/etc/ca/intermediate/certs/ca-chain.cert.pem
# options - optional
# Allows the specification of webListener level options - mainly dealing with HTTP/TLS settings. These options are
# used for all http servers started by the current webListener.
options:
# idleTimeout - optional, default 5000ms
# The maximum amount of idle time in milliseconds allowed for pipelined HTTP requests. Setting this too high
# can cause resources on the host to be consumed as clients remain connected and idle. Lowering this value
# will cause clients to reconnect on subsequent HTTPs requests.
idleTimeout: 5000ms #http timeouts, new
# readTimeout - optional, default 5000ms
# The maximum amount of time in milliseconds http servers will wait to read the first incoming requests. A higher
# value risks consuming resources on the host with clients that are acting bad faith or suffering from high latency
# or packet loss. A lower value can risk losing connections to high latency/packet loss clients.
readTimeout: 5000ms
# writeTimeout - optional, default 10000ms
# The total maximum time in milliseconds that the http server will wait for a single requests to be received and
# responded too. A higher value can allow long running requests to consume resources on the host. A lower value
# can risk ending requests before the server has a chance to respond.
writeTimeout: 100000ms
# minTLSVersion - optional, default TSL1.2
# The minimum version of TSL to support
minTLSVersion: TLS1.2
# maxTLSVersion - optional, default TSL1.3
# The maximum version of TSL to support
maxTLSVersion: TLS1.3
# apis - required
# Allows one or more APIs to be bound to this webListener
apis:
# binding - required
# Specifies an API to bind to this webListener. Built-in APIs are
# - health-checks
# - edge-management
# - edge-client
# - fabric-management
{{if .HealthChecksEnabled }}
- binding: health-checks
options: {}
{{end}}
{{if .EdgeManagementEnabled }}
- binding: edge-management
# options - variable optional/required
# This section is used to define values that are specified by the API they are associated with.
# These settings are per API. The example below is for the `edge-api` and contains both optional values and
# required values.
options: {}
{{end}}
{{if .EdgeClientEnabled}}
- binding: edge-client
options: {}
{{end}}
+5 -30
View File
@@ -17,23 +17,15 @@
package cmd
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
"github.com/spf13/cobra"
"io"
"github.com/spf13/cobra"
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"
)
// CreateOptions contains the command line options
type CreateOptions struct {
CommonOptions
DisableImport bool
OutDir string
}
var (
createLong = templates.LongDesc(`
Creates a new Ziti resource.
@@ -43,28 +35,16 @@ var (
// NewCmdCreate creates a command object for the "create" command
func NewCmdCreate(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
}
cmd := &cobra.Command{
Use: "create",
Short: "Create a new resource",
Long: createLong,
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := options.Run()
cmdhelper.CheckErr(err)
cmdhelper.CheckErr(cmd.Help())
},
}
cmd.AddCommand(NewCmdCreateConfig(f, out, errOut))
// cmd.AddCommand(NewCmdCreateStateStore(f, out, errOut))
cmd.AddCommand(NewCmdCreateConfig(common.NewOptionsProvider(out, errOut)))
cmd.AddCommand(NewCmdCreateEnvironment(f, out, errOut))
cmd.AddCommand(NewCmdPKICreateCA(f, out, errOut))
@@ -75,8 +55,3 @@ func NewCmdCreate(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Com
return cmd
}
// Run implements this command
func (o *CreateOptions) Run() error {
return o.Cmd.Help()
}
+6 -17
View File
@@ -17,17 +17,14 @@
package cmd
import (
"io"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/spf13/cobra"
)
// CreateConfigOptions the options for the create spring command
type CreateConfigOptions struct {
CreateOptions
common.CommonOptions
Namespace string
Version string
ReleaseName string
@@ -35,15 +32,9 @@ type CreateConfigOptions struct {
}
// NewCmdCreateConfig creates a command object for the "create" command
func NewCmdCreateConfig(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func NewCmdCreateConfig(p common.OptionsProvider) *cobra.Command {
options := &CreateConfigOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
},
CommonOptions: p(),
}
cmd := &cobra.Command{
@@ -58,10 +49,8 @@ func NewCmdCreateConfig(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cob
},
}
cmd.AddCommand(NewCmdCreateConfigController(f, out, errOut))
cmd.AddCommand(NewCmdCreateConfigRouter(f, out, errOut))
cmd.AddCommand(NewCmdCreateConfigMgmt(f, out, errOut))
cmd.AddCommand(NewCmdCreateConfigGw(f, out, errOut))
cmd.AddCommand(NewCmdCreateConfigController(p))
cmd.AddCommand(NewCmdCreateConfigRouter(p))
options.addFlags(cmd, "", "")
return cmd
+37 -15
View File
@@ -17,14 +17,16 @@
package cmd
import (
"fmt"
"github.com/spf13/cobra"
"io"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
_ "embed"
"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/cmd/templates"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"os"
"path/filepath"
"text/template"
)
const (
@@ -46,24 +48,23 @@ var (
`)
)
//go:embed config_templates/controller.yml
var controllerConfigTemplate string
// CreateConfigControllerOptions the options for the create spring command
type CreateConfigControllerOptions struct {
CreateConfigOptions
OutputFile string
DatabaseFile string
CtrlListener string
}
// NewCmdCreateConfigController creates a command object for the "create" command
func NewCmdCreateConfigController(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func NewCmdCreateConfigController(p common.OptionsProvider) *cobra.Command {
options := &CreateConfigControllerOptions{
CreateConfigOptions: CreateConfigOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
},
CommonOptions: p(),
},
}
@@ -81,7 +82,6 @@ func NewCmdCreateConfigController(f cmdutil.Factory, out io.Writer, errOut io.Wr
},
}
options.addCommonFlags(cmd)
options.addFlags(cmd, "", defaultCtrlListener)
return cmd
@@ -93,5 +93,27 @@ func (o *CreateConfigControllerOptions) Run() error {
return util.MissingOption(optionCtrlListener)
}
return fmt.Errorf("UNIMPLEMENTED: '%s'", "create config controller")
tmpl, err := template.New("controller-config").Parse(controllerConfigTemplate)
if err != nil {
return err
}
baseDir := filepath.Base(o.OutputFile)
if baseDir != "." {
if err := os.MkdirAll(baseDir, 0700); err != nil {
return errors.Wrapf(err, "unable to create directory to house config file: %v", o.OutputFile)
}
}
f, err := os.Create(o.OutputFile)
if err != nil {
return errors.Wrapf(err, "unable to create config file: %v", o.OutputFile)
}
defer func() { _ = f.Close() }()
if err := tmpl.Execute(f, o); err != nil {
return errors.Wrap(err, "unable to execute template")
}
return nil
}
-127
View File
@@ -1,127 +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 (
"fmt"
"github.com/spf13/cobra"
"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/ziti/cmd/ziti/util"
)
const (
optionListenAddress = "listenAddress"
defaultListenAddress = "localhost:10080"
optionMgmt = "mgmt"
defaultMgmt = "tls:0.0.0.0:10000"
optionMgmtGwCertPath = "mgmtGwCertPath"
optionMgmtGwKeyPath = "mgmtGwKeyPath"
optionMgmtCertPath = "mgmtCertPath"
optionMgmtKeyPath = "mgmtKeyPath"
optionMgmtCaCertPath = "mgmtCaCertPath"
)
var (
createConfigGwLong = templates.LongDesc(`
Creates the gw config
`)
createConfigGwExample = templates.Examples(`
# Create the gw config
ziti create config gw
# Create the gw config with a particular ctrlListener
ziti create config gw -listenAddress localhost:10080
`)
)
// CreateConfigGwOptions the options for the create spring command
type CreateConfigGwOptions struct {
CreateConfigOptions
ListenAddress string
Mgmt string
MgmtGwCertPath string
MgmtGwKeyPath string
MgmtCertPath string
MgmtKeyPath string
MgmtCaCertPath string
}
// NewCmdCreateConfigGw creates a command object for the "create" command
func NewCmdCreateConfigGw(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &CreateConfigGwOptions{
CreateConfigOptions: CreateConfigOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
},
},
}
cmd := &cobra.Command{
Use: "gw",
Short: "Create a gw config",
Aliases: []string{"g"},
Long: createConfigGwLong,
Example: createConfigGwExample,
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := options.Run()
cmdhelper.CheckErr(err)
},
}
options.addCommonFlags(cmd)
options.addFlags(cmd, "", defaultCtrlListener)
cmd.Flags().StringVarP(&options.ListenAddress, optionListenAddress, "l", "", "Where the GW should listen for incoming REST requests")
return cmd
}
// Run implements the command
func (o *CreateConfigGwOptions) Run() error {
if o.ListenAddress == "" {
log.Infof("%s not specified; using default (%s)\n", optionListenAddress, defaultListenAddress)
o.ListenAddress = defaultListenAddress
// return util.MissingOption(optionListenAddress)
}
gwConfigDir, err := util.ZitiAppConfigDir(c.ZITI_FABRIC_GW)
if err != nil {
return fmt.Errorf("err")
}
return fmt.Errorf("UNIMPLEMENTED: '%s'", gwConfigDir)
}
-94
View File
@@ -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 (
"fmt"
"github.com/spf13/cobra"
"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"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
)
var (
createConfigMgmtLong = templates.LongDesc(`
Creates the mgmt config
`)
createConfigMgmtExample = templates.Examples(`
# Create the mgmt config
ziti create config mgmt
# Create the mgmt config with a particular ctrlListener
ziti create config mgmt -ctrlListener quic:0.0.0.0:6262
`)
)
// CreateConfigMgmtOptions the options for the create spring command
type CreateConfigMgmtOptions struct {
CreateConfigOptions
CtrlAddress string
}
// NewCmdCreateConfigMgmt creates a command object for the "create" command
func NewCmdCreateConfigMgmt(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &CreateConfigMgmtOptions{
CreateConfigOptions: CreateConfigOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
},
},
}
cmd := &cobra.Command{
Use: "mgmt",
Short: "Create a mgmt config",
Aliases: []string{"m"},
Long: createConfigMgmtLong,
Example: createConfigMgmtExample,
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := options.Run()
cmdhelper.CheckErr(err)
},
}
options.addCommonFlags(cmd)
options.addFlags(cmd, "", defaultCtrlListener)
return cmd
}
// Run implements the command
func (o *CreateConfigMgmtOptions) Run() error {
if o.CtrlAddress == "" {
return util.MissingOption(optionCtrlAddress)
}
return fmt.Errorf("UNIMPLEMENTED: '%s'", "create config mgmt")
// return nil
}
+4 -13
View File
@@ -18,13 +18,11 @@ package cmd
import (
"fmt"
"github.com/spf13/cobra"
"io"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
"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/cmd/templates"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
)
const (
@@ -54,16 +52,10 @@ type CreateConfigRouterOptions struct {
}
// NewCmdCreateConfigRouter creates a command object for the "create" command
func NewCmdCreateConfigRouter(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func NewCmdCreateConfigRouter(p common.OptionsProvider) *cobra.Command {
options := &CreateConfigRouterOptions{
CreateConfigOptions: CreateConfigOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
},
CommonOptions: p(),
},
}
@@ -81,7 +73,6 @@ func NewCmdCreateConfigRouter(f cmdutil.Factory, out io.Writer, errOut io.Writer
},
}
options.addCommonFlags(cmd)
options.addFlags(cmd, "", defaultCtrlListener)
return cmd
+5 -9
View File
@@ -28,7 +28,7 @@ import (
// CreateEnvironmentOptions the options for the create spring command
type CreateEnvironmentOptions struct {
CreateOptions
CommonOptions
EnvName string
}
@@ -36,12 +36,10 @@ type CreateEnvironmentOptions struct {
// NewCmdCreateEnvironment creates a command object for the "create" command
func NewCmdCreateEnvironment(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &CreateEnvironmentOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
}
@@ -65,12 +63,10 @@ func NewCmdCreateEnvironment(f cmdutil.Factory, out io.Writer, errOut io.Writer)
func (o *CreateEnvironmentOptions) addFlags(cmd *cobra.Command, defaultNamespace string, defaultOptionRelease string) {
cmd.Flags().StringVarP(&o.EnvName, "name", "", "", "Name of new 'environment'")
cmd.MarkFlagRequired("name")
}
// Run implements this command
func (o *CreateEnvironmentOptions) Run() error {
deps := make([]string, 0)
deps = append(deps, "ansible")
err := o.installMissingDependencies(deps)
-127
View File
@@ -1,127 +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 (
"fmt"
"github.com/spf13/cobra"
"io"
"os/user"
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"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
)
// const (
// optionCtrlAddress = "ctrlAddress"
// defaultCtrlAddress = "quic:0.0.0.0:6262"
// )
var (
createStateStoreLong = templates.LongDesc(`
Creates the ziti state-store in S3
`)
createStateStoreExample = templates.Examples(`
# Create the ziti state store in S3
ziti create state-store
`)
)
// CreateStateStoreOptions the options for the create spring command
type CreateStateStoreOptions struct {
CreateOptions
}
// NewCmdCreateStateStore creates a command object for the "create" command
func NewCmdCreateStateStore(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &CreateStateStoreOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
},
}
cmd := &cobra.Command{
Use: "state-store",
Short: "Create a ziti state-store",
Aliases: []string{"ss"},
Long: createStateStoreLong,
Example: createStateStoreExample,
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := options.Run()
cmdhelper.CheckErr(err)
},
}
options.addCommonFlags(cmd)
return cmd
}
// Run implements the command
func (o *CreateStateStoreOptions) Run() error {
var defaultBucketName string
defaultBucketName = "ziti-state-store"
bucketName, err := util.PickValue("S3 Bucket Name:", defaultBucketName, true)
if err != nil {
return fmt.Errorf("%s", err)
}
if bucketName == defaultBucketName {
usr, err := user.Current()
if err != nil {
return fmt.Errorf("%s", err)
}
bucketNamePrefix, err := util.PickValue("S3 Bucket Name Prefix (needed because you chose default bucket name):", usr.Username, true)
if err != nil {
return fmt.Errorf("%s", err)
}
bucketName = bucketNamePrefix + "-" + bucketName
}
err = util.RunAWSCommand("s3api", "create-bucket", "--bucket", bucketName, "--region", "us-east-1")
if err != nil {
return fmt.Errorf("Unable to create state-store bucket '%s'", bucketName)
}
err = util.RunAWSCommand("s3api", "put-bucket-versioning", "--bucket", bucketName, "--versioning-configuration", "Status=Enabled")
if err != nil {
return fmt.Errorf("Unable to activate versioning on state-store bucket '%s'", bucketName)
}
fmt.Println("\nSuccessfully created S3 bucket '" + bucketName + "'")
fmt.Println("\nNow, you should create the following environment variable in your current shell and your bash profile:")
fmt.Println("\n\tZITI_STATE_STORE=s3://" + bucketName)
fmt.Println("")
return nil
}
-77
View File
@@ -1,77 +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"
"github.com/spf13/cobra"
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"
)
// DeleteOptions are the flags for delete commands
type DeleteOptions struct {
CommonOptions
}
var (
deleteLong = templates.LongDesc(`
Deletes a resource.
`)
deleteExample = templates.Examples(`
# Delete the controller config
ziti delete config controller
`)
)
// NewCmdDelete creates a command object for the generic "delete" action
func NewCmdDelete(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &DeleteOptions{
CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
}
cmd := &cobra.Command{
Use: "delete TYPE [flags]",
Short: "Deletes one or many resources",
Long: deleteLong,
Example: deleteExample,
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := options.Run()
cmdhelper.CheckErr(err)
},
SuggestFor: []string{"remove", "rm", "del"},
}
cmd.AddCommand(NewCmdDeleteStateStore(f, out, errOut))
return cmd
}
// Run implements this command
func (o *DeleteOptions) Run() error {
return o.Cmd.Help()
}
-105
View File
@@ -1,105 +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 (
"fmt"
"github.com/spf13/cobra"
"io"
"os"
"strings"
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"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
)
var (
deleteStateStoreLong = templates.LongDesc(`
Deletes the ziti state-store from S3
`)
deleteStateStoreExample = templates.Examples(`
# Delete the ziti state store from S3
ziti delete state-store
`)
)
// DeleteStateStoreOptions the options for the delete state-store command
type DeleteStateStoreOptions struct {
DeleteOptions
}
// NewCmdDeleteStateStore creates a command object for the "delete" command
func NewCmdDeleteStateStore(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &DeleteStateStoreOptions{
DeleteOptions: DeleteOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
},
}
cmd := &cobra.Command{
Use: "state-store",
Short: "Delete a ziti state-store",
Aliases: []string{"ss"},
Long: deleteStateStoreLong,
Example: deleteStateStoreExample,
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := options.Run()
cmdhelper.CheckErr(err)
},
}
options.addCommonFlags(cmd)
return cmd
}
// Run implements the command
func (o *DeleteStateStoreOptions) Run() error {
var bucketName string
if bucketName = os.Getenv("ZITI_STATE_STORE"); bucketName == "" {
return fmt.Errorf("ZITI_STATE_STORE environment variable is not set")
}
fmt.Println("\nZITI_STATE_STORE environment variable contains '" + bucketName + "'")
bucketName = strings.Replace(bucketName, "s3://", "", 1)
message := fmt.Sprintf("Are you sure you want to remove S3 bucket '%s' ?", bucketName)
if util.Confirm(message, true, "Please indicate if you would like to remove this S3 bucket.") {
err := util.RunAWSCommand("s3api", "delete-bucket", "--bucket", bucketName)
if err != nil {
return fmt.Errorf("Unable to delete state-store bucket '%s': '%s'", bucketName, err)
}
fmt.Println("\nSuccessfully removed S3 bucket '" + bucketName + "'")
}
return nil
}
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"io"
@@ -33,8 +33,7 @@ func newCreateCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Com
Short: "creates various entities managed by the Ziti Edge Controller",
Long: "Creates various entities managed by the Ziti Edge Controller",
Run: func(cmd *cobra.Command, args []string) {
err := cmd.Help()
cmdhelper.CheckErr(err)
cmdhelper.CheckErr(cmd.Help())
},
}
@@ -48,13 +47,13 @@ func newCreateCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Com
cmd.AddCommand(newCreateIdentityCmd(f, out, errOut))
cmd.AddCommand(newCreateServiceCmd(f, out, errOut))
cmd.AddCommand(newCreateServiceEdgeRouterPolicyCmd(f, out, errOut))
cmd.AddCommand(newCreateServicePolicyCmd(f, out, errOut))
cmd.AddCommand(newCreatePostureCheckCmd(f, out, errOut))
cmd.AddCommand(newCreateServicePolicyCmd(out, errOut))
cmd.AddCommand(newCreatePostureCheckCmd(out, errOut))
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.OutputJSONResponse, options.Timeout, options.Verbose)
return util.EdgeControllerCreate(entityType, body, options.Out, options.OutputJSONRequest, options.OutputJSONResponse, options.Timeout, options.Verbose)
}
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"context"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
@@ -105,16 +105,5 @@ func runCreateCa(options *createCaOptions) (err error) {
setJSONValue(data, options.identityRoles, "identityRoles")
result, err := createEntityOfType("cas", data.String(), &options.edgeOptions)
if err != nil {
panic(err)
}
id := result.S("data", "id").Data()
if _, err = fmt.Fprintf(options.Out, "%v\n", id); err != nil {
panic(err)
}
return err
return options.logCreateResult("ca", result, err)
}
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"encoding/json"
@@ -105,16 +105,5 @@ func runCreateConfig(o *createConfigOptions) error {
setJSONValue(entityData, configTypeId, "configTypeId")
setJSONValue(entityData, dataMap, "data")
result, err := createEntityOfType("configs", entityData.String(), &o.edgeOptions)
if err != nil {
panic(err)
}
configId := result.S("data", "id").Data()
if _, err := fmt.Fprintf(o.Out, "%v\n", configId); err != nil {
panic(err)
}
return err
return o.logCreateResult("config", result, err)
}
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"encoding/json"
@@ -102,16 +102,5 @@ func runCreateConfigType(o *createConfigTypeOptions) error {
}
result, err := createEntityOfType("config-types", entityData.String(), &o.edgeOptions)
if err != nil {
panic(err)
}
configTypeId := result.S("data", "id").Data()
if _, err := fmt.Fprintf(o.Out, "%v\n", configTypeId); err != nil {
panic(err)
}
return err
return o.logCreateResult("config type", result, err)
}
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
@@ -82,22 +82,12 @@ func runCreateEdgeRouter(o *createEdgeRouterOptions) error {
setJSONValue(entityData, o.appData, "appData")
result, err := createEntityOfType("edge-routers", entityData.String(), &o.edgeOptions)
if err != nil {
if err := o.logCreateResult("edge router", result, err); err != nil {
return err
}
id := result.S("data", "id").Data().(string)
if !o.OutputJSONResponse {
//output id
if _, err = fmt.Fprintf(o.Out, "%v\n", id); err != nil {
panic(err)
}
}
if o.jwtOutputFile != "" {
id := result.S("data", "id").Data().(string)
if err := getEdgeRouterJwt(o, id); err != nil {
return err
}
@@ -14,10 +14,9 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
"io"
"github.com/Jeffail/gabs"
@@ -87,16 +86,5 @@ func runCreateEdgeRouterPolicy(o *createEdgeRouterPolicyOptions) error {
}
result, err := createEntityOfType("edge-router-policies", entityData.String(), &o.edgeOptions)
if err != nil {
panic(err)
}
edgeRouterPolicyId := result.S("data", "id").Data()
if _, err := fmt.Fprintf(o.Out, "%v\n", edgeRouterPolicyId); err != nil {
panic(err)
}
return err
return o.logCreateResult("edge router policy", result, err)
}
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
@@ -159,18 +159,12 @@ func runCreateIdentity(idType string, o *createIdentityOptions) error {
setJSONValue(entityData, o.servicePrecedences, "serviceHostingPrecedences")
result, err := createEntityOfType("identities", entityData.String(), &o.edgeOptions)
if err != nil {
panic(err)
}
id := result.S("data", "id").Data().(string)
if _, err = fmt.Fprintf(o.Out, "%v\n", id); err != nil {
panic(err)
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 {
return err
}
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
@@ -22,7 +22,6 @@ import (
"github.com/openziti/edge/rest_management_api_client/posture_checks"
"github.com/openziti/edge/rest_model"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
@@ -32,17 +31,17 @@ import (
)
// newCreatePostureCheckCmd creates the 'edge controller create posture-check' command
func newCreatePostureCheckCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newCreatePostureCheckCmd(out io.Writer, errOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "posture-check",
}
cmd.AddCommand(newCreatePostureCheckMacCmd(f, out, errOut))
cmd.AddCommand(newCreatePostureCheckDomainCmd(f, out, errOut))
cmd.AddCommand(newCreatePostureCheckProcessCmd(f, out, errOut))
cmd.AddCommand(newCreatePostureCheckOsCmd(f, out, errOut))
cmd.AddCommand(newCreatePostureCheckMfaCmd(f, out, errOut))
cmd.AddCommand(newCreatePostureCheckProcessMultiCmd(f, out, errOut))
cmd.AddCommand(newCreatePostureCheckMacCmd(out, errOut))
cmd.AddCommand(newCreatePostureCheckDomainCmd(out, errOut))
cmd.AddCommand(newCreatePostureCheckProcessCmd(out, errOut))
cmd.AddCommand(newCreatePostureCheckOsCmd(out, errOut))
cmd.AddCommand(newCreatePostureCheckMfaCmd(out, errOut))
cmd.AddCommand(newCreatePostureCheckProcessMultiCmd(out, errOut))
return cmd
}
@@ -106,14 +105,13 @@ func (options *createPostureCheckOptions) addPostureFlags(cmd *cobra.Command) {
cmd.Flags().StringSliceVarP(&options.roleAttributes, "role-attributes", "a", nil, "Role attributes of the new service")
}
func newCreatePostureCheckMacCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newCreatePostureCheckMacCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &createPostureCheckMacOptions{
createPostureCheckOptions: createPostureCheckOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{
Factory: f,
Out: out,
Err: errOut,
Out: out,
Err: errOut,
},
},
tags: make(map[string]string),
@@ -146,14 +144,13 @@ func newCreatePostureCheckMacCmd(f cmdutil.Factory, out io.Writer, errOut io.Wri
return cmd
}
func newCreatePostureCheckDomainCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newCreatePostureCheckDomainCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &createPostureCheckDomainOptions{
createPostureCheckOptions: createPostureCheckOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{
Factory: f,
Out: out,
Err: errOut,
Out: out,
Err: errOut,
},
},
tags: make(map[string]string),
@@ -186,14 +183,13 @@ func newCreatePostureCheckDomainCmd(f cmdutil.Factory, out io.Writer, errOut io.
return cmd
}
func newCreatePostureCheckProcessCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newCreatePostureCheckProcessCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &createPostureCheckProcessOptions{
createPostureCheckOptions: createPostureCheckOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{
Factory: f,
Out: out,
Err: errOut,
Out: out,
Err: errOut,
},
},
tags: make(map[string]string),
@@ -240,14 +236,13 @@ func newCreatePostureCheckProcessCmd(f cmdutil.Factory, out io.Writer, errOut io
return cmd
}
func newCreatePostureCheckProcessMultiCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newCreatePostureCheckProcessMultiCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &createPostureCheckProcessMultiOptions{
createPostureCheckOptions: createPostureCheckOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{
Factory: f,
Out: out,
Err: errOut,
Out: out,
Err: errOut,
},
},
tags: make(map[string]string),
@@ -462,18 +457,7 @@ func runCreatePostureCheckProcess(o *createPostureCheckProcessOptions) error {
}
result, err := createEntityOfType("posture-checks", entityData.String(), &o.edgeOptions)
if err != nil {
panic(err)
}
checkId := result.S("data", "id").Data()
if _, err = fmt.Fprintf(o.Out, "%v\n", checkId); err != nil {
panic(err)
}
return err
return o.logCreateResult("posture check", result, err)
}
func runCreatePostureCheckProcessMulti(options *createPostureCheckProcessMultiOptions) error {
@@ -636,15 +620,14 @@ func runCreatePostureCheckDomain(o *createPostureCheckDomainOptions) (err error)
return err
}
func newCreatePostureCheckOsCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newCreatePostureCheckOsCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &createPostureCheckOsOptions{
createPostureCheckOptions: createPostureCheckOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{
Factory: f,
Out: out,
Err: errOut,
Out: out,
Err: errOut,
},
},
tags: make(map[string]string),
@@ -742,14 +725,13 @@ func parseOsSpec(osSpecStr string) (*osSpec, error) {
}, nil
}
func newCreatePostureCheckMfaCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newCreatePostureCheckMfaCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := createPostureCheckMfaOptions{
createPostureCheckOptions: createPostureCheckOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{
Factory: f,
Out: out,
Err: errOut,
Out: out,
Err: errOut,
},
},
tags: make(map[string]string),
@@ -14,10 +14,9 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
@@ -96,16 +95,5 @@ func runCreateService(o *createServiceOptions) (err error) {
setJSONValue(entityData, o.tags, "tags")
result, err := createEntityOfType("services", entityData.String(), &o.edgeOptions)
if err != nil {
return err
}
serviceId := result.S("data", "id").Data()
if _, err = fmt.Fprintf(o.Out, "%v\n", serviceId); err != nil {
return err
}
return err
return o.logCreateResult("service", result, err)
}
@@ -14,10 +14,9 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
"io"
"github.com/Jeffail/gabs"
@@ -86,16 +85,5 @@ func runCreateServiceEdgeRouterPolicy(o *createServiceEdgeRouterPolicyOptions) e
}
result, err := createEntityOfType("service-edge-router-policies", entityData.String(), &o.edgeOptions)
if err != nil {
panic(err)
}
edgeRouterPolicyId := result.S("data", "id").Data()
if _, err := fmt.Fprintf(o.Out, "%v\n", edgeRouterPolicyId); err != nil {
panic(err)
}
return err
return o.logCreateResult("service edge router policy", result, err)
}
@@ -14,10 +14,9 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
"io"
"strings"
@@ -25,7 +24,6 @@ import (
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/spf13/cobra"
)
@@ -39,10 +37,10 @@ type createServicePolicyOptions struct {
}
// newCreateServicePolicyCmd creates the 'edge controller create service-policy' command
func newCreateServicePolicyCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newCreateServicePolicyCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &createServicePolicyOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -104,18 +102,7 @@ func runCreateServicePolicy(o *createServicePolicyOptions) error {
setJSONValue(entityData, o.semantic, "semantic")
}
result, err := createEntityOfType("service-policies", entityData.String(), &o.edgeOptions)
if err != nil {
panic(err)
}
servicePolicyId := result.S("data", "id").Data()
if _, err := fmt.Fprintf(o.Out, "%v\n", servicePolicyId); err != nil {
panic(err)
}
return err
return o.logCreateResult("service policy", result, err)
}
func convertNamesToIds(roles []string, entityType string, o edgeOptions) ([]string, error) {
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
@@ -113,16 +113,15 @@ func runCreateTerminator(o *createTerminatorOptions) (err error) {
}
result, err := createEntityOfType("terminators", entityData.String(), &o.edgeOptions)
if err != nil {
panic(err)
return err
}
TerminatorId := result.S("data", "id").Data()
if _, err = fmt.Fprintf(o.Out, "%v\n", TerminatorId); err != nil {
panic(err)
if !o.OutputJSONResponse {
id := result.S("data", "id").Data()
_, err = fmt.Fprintf(o.Out, "New %v created with id: %v\n", "terminator", id)
return err
}
return nil
return err
}
+24
View File
@@ -0,0 +1,24 @@
package edge
import (
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/spf13/cobra"
"io"
)
func newDbCmd(out io.Writer, errOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "db",
Short: "Database management operations for the Ziti Edge Controller",
Run: func(cmd *cobra.Command, args []string) {
err := cmd.Help()
cmdhelper.CheckErr(err)
},
}
cmd.AddCommand(newDbSnapshotCmd(out, errOut))
cmd.AddCommand(newDbCheckIntegrityCmd(out, errOut))
cmd.AddCommand(newDbCheckIntegrityStatusCmd(out, errOut))
return cmd
}
@@ -1,10 +1,9 @@
package edge_controller
package edge
import (
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/pkg/errors"
@@ -18,10 +17,10 @@ type dbCheckIntegrityOptions struct {
fix bool
}
func newDbCheckIntegrityCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newDbCheckIntegrityCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &dbCheckIntegrityOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -62,10 +61,10 @@ func runCheckIntegrityDb(o *dbCheckIntegrityOptions) error {
return err
}
func newDbCheckIntegrityStatusCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newDbCheckIntegrityStatusCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &dbCheckIntegrityOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -14,11 +14,10 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
@@ -30,10 +29,10 @@ type dbSnapshotOptions struct {
edgeOptions
}
func newDbSnapshotCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newDbSnapshotCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &dbSnapshotOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
+176
View File
@@ -0,0 +1,176 @@
/*
Copyright NetFoundry, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package edge
import (
"github.com/fatih/color"
"github.com/openziti/foundation/storage/boltz"
"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"
"github.com/spf13/cobra"
)
// newDeleteCmd creates a command object for the "edge controller delete" command
func newDeleteCmd(out io.Writer, errOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "delete",
Short: "deletes various entities managed by the Ziti Edge Controller",
Long: "deletes various entities managed by the Ziti Edge Controller",
Run: func(cmd *cobra.Command, args []string) {
err := cmd.Help()
cmdhelper.CheckErr(err)
},
}
newOptions := func() *edgeOptions {
return &edgeOptions{
CommonOptions: common.CommonOptions{
Out: out,
Err: errOut,
},
}
}
cmd.AddCommand(newDeleteCmdForEntityType("api-session", newOptions()))
cmd.AddCommand(newDeleteAuthenticatorCmd("authenticator", newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("ca", newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("config", newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("config-type", newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("edge-router", newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("edge-router-policy", newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("identity", newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("service", newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("service-edge-router-policy", newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("service-policy", newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("session", newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("terminator", newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("posture-check", newOptions()))
return cmd
}
// newDeleteCmdForEntityType creates the delete command for the given entity type
func newDeleteCmdForEntityType(entityType string, options *edgeOptions) *cobra.Command {
cmd := &cobra.Command{
Use: entityType + " <id>",
Short: "deletes " + getPlural(entityType) + " managed by the Ziti Edge Controller",
Args: cobra.MinimumNArgs(1),
Aliases: []string{getPlural(entityType)},
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := runDeleteEntityOfType(options, 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 *edgeOptions) *cobra.Command {
cmd := &cobra.Command{
Use: "where <filter>",
Short: "deletes " + getPlural(entityType) + " matching the filter managed by the Ziti Edge Controller",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := runDeleteEntityOfTypeWhere(options, getPlural(entityType))
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 *edgeOptions, entityType string) error {
var err error
ids := o.Args
if entityType != "terminators" && entityType != "api-sessions" && entityType != "sessions" {
ids, err = mapNamesToIDs(entityType, *o, ids...)
}
if err != nil {
return err
}
return deleteEntitiesOfType(o, entityType, ids)
}
func deleteEntitiesOfType(o *edgeOptions, entityType string, ids []string) error {
for _, id := range ids {
_, err := util.EdgeControllerDelete(entityType, id, o.Out, 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
}
// runDeleteEntityOfType implements the commands to delete various entity types
func runDeleteEntityOfTypeWhere(options *edgeOptions, entityType string) error {
filter := strings.Join(options.Args, " ")
params := url.Values{}
params.Add("filter", filter)
children, pageInfo, err := listEntitiesOfType(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(options, entityType, ids)
}
func getPlural(entityType string) string {
if strings.HasSuffix(entityType, "y") {
return strings.TrimSuffix(entityType, "y") + "ies"
}
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)
}
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"github.com/spf13/cobra"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"context"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"github.com/Jeffail/gabs"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"errors"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"encoding/json"
@@ -24,7 +24,6 @@ import (
"github.com/openziti/edge/rest_model"
"github.com/openziti/foundation/util/errorz"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/pkg/errors"
@@ -36,7 +35,7 @@ import (
)
// newListCmd creates a command object for the "controller list" command
func newListCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newListCmd(out io.Writer, errOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Short: "Lists various entities managed by the Ziti Edge Controller",
@@ -49,11 +48,7 @@ func newListCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Comma
newOptions := func() *edgeOptions {
return &edgeOptions{
CommonOptions: common.CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
}
}
@@ -327,6 +322,12 @@ func listEntitiesWithOptions(entityType string, options *edgeOptions) ([]*gabs.C
return listEntitiesOfType(entityType, params, options.OutputJSONResponse, options.Out, options.Timeout, options.Verbose)
}
func listEntitiesWithFilter(entityType string, filter string) ([]*gabs.Container, *paging, error) {
params := url.Values{}
params.Add("filter", filter)
return listEntitiesOfType(entityType, params, false, nil, 5, false)
}
func filterEntitiesOfType(entityType string, filter string, logJSON bool, out io.Writer, timeout int, verbose bool) ([]*gabs.Container, *paging, error) {
params := url.Values{}
params.Add("filter", filter)
@@ -14,14 +14,13 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/foundation/util/term"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/pkg/errors"
@@ -36,19 +35,20 @@ import (
// loginOptions are the flags for login commands
type loginOptions struct {
edgeOptions
Username string
Password string
Token string
Cert string
ReadOnly bool
Yes bool
Username string
Password string
Token string
Cert string
ReadOnly bool
Yes bool
IgnoreConfig bool
}
// newLoginCmd creates the command
func newLoginCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newLoginCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &loginOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -56,7 +56,7 @@ func newLoginCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Comm
Use: "login my.controller.hostname[:port]/path",
Short: "logs into a Ziti Edge Controller instance",
Long: `login allows the ziti command to establish a session with a Ziti Edge Controller, allowing more commands to be run against the controller.`,
Args: cobra.MinimumNArgs(1),
Args: cobra.RangeArgs(0, 1),
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
@@ -75,6 +75,7 @@ func newLoginCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Comm
cmd.Flags().StringVarP(&options.Cert, "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.")
options.AddCommonFlags(cmd)
return cmd
@@ -82,7 +83,30 @@ func newLoginCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Comm
// Run implements this command
func (o *loginOptions) Run() error {
host := o.Args[0]
config, configFile, err := util.LoadRestClientConfig()
if err != nil {
return err
}
id := config.GetIdentity()
var host string
if len(o.Args) == 0 {
if defaultId := config.Identities[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 {
if host, err = term.Prompt("Enter controller host[:port] (default localhost:1280): "); err != nil {
return err
}
if host == "" {
host = "localhost:1280"
}
}
} else {
host = o.Args[0]
}
if !strings.HasPrefix(host, "http") {
host = "https://" + host
}
@@ -115,12 +139,15 @@ func (o *loginOptions) Run() error {
if o.Token == "" {
for o.Username == "" {
if o.Username, err = term.Prompt("Enter username: "); err != nil {
if defaultId := config.Identities[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 {
return err
}
}
if o.Username != "" && o.Password == "" {
if o.Password == "" {
if o.Password, err = term.PromptPassword("Enter password: ", false); err != nil {
return err
}
@@ -161,18 +188,13 @@ func (o *loginOptions) Run() error {
loginIdentity := &util.RestClientIdentity{
Url: host,
Username: o.Username,
Token: o.Token,
LoginTime: time.Now().Format(time.RFC3339),
Cert: o.Cert,
ReadOnly: o.ReadOnly,
}
config, configFile, err := util.LoadRestClientConfig()
if err != nil {
return err
}
id := config.GetIdentity()
o.Printf("Saving identity '%v' to %v\n", id, configFile)
config.Identities[id] = loginIdentity
@@ -14,11 +14,10 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
@@ -31,10 +30,10 @@ type logoutOptions struct {
}
// newLogoutCmd creates the command
func newLogoutCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newLogoutCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &logoutOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -14,13 +14,12 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
@@ -28,7 +27,7 @@ import (
)
// newPolicyAdvisor creates a command object for the "controller policy-advisor" command
func newPolicyAdivsorCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newPolicyAdivsorCmd(out io.Writer, errOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "policy-advisor",
Short: "runs sanity checks on various policy related entities managed by the Ziti Edge Controller",
@@ -38,8 +37,8 @@ func newPolicyAdivsorCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *co
},
}
cmd.AddCommand(newPolicyAdvisorIdentitiesCmd(f, out, errOut))
cmd.AddCommand(newPolicyAdvisorServicesCmd(f, out, errOut))
cmd.AddCommand(newPolicyAdvisorIdentitiesCmd(out, errOut))
cmd.AddCommand(newPolicyAdvisorServicesCmd(out, errOut))
return cmd
}
@@ -50,10 +49,10 @@ type policyAdvisorOptions struct {
}
// newPolicyAdvisorIdentitiesCmd creates the 'edge controller policy-advisor identities' command
func newPolicyAdvisorIdentitiesCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newPolicyAdvisorIdentitiesCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &policyAdvisorOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -79,10 +78,10 @@ func newPolicyAdvisorIdentitiesCmd(f cmdutil.Factory, out io.Writer, errOut io.W
}
// newPolicyAdvisorServicesCmd creates the 'edge controller policy-advisor services' command
func newPolicyAdvisorServicesCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newPolicyAdvisorServicesCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &policyAdvisorOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -14,9 +14,10 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
"github.com/openziti/ziti/common/enrollment"
"io"
@@ -64,20 +65,35 @@ func (options *edgeOptions) AddCommonFlags(cmd *cobra.Command) {
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))
cmd.AddCommand(newDeleteCmd(f, out, errOut))
cmd.AddCommand(newLoginCmd(f, out, errOut))
cmd.AddCommand(newLogoutCmd(f, out, errOut))
cmd.AddCommand(newUseCmd(f, out, errOut))
cmd.AddCommand(newListCmd(f, out, errOut))
cmd.AddCommand(newDeleteCmd(out, errOut))
cmd.AddCommand(newLoginCmd(out, errOut))
cmd.AddCommand(newLogoutCmd(out, errOut))
cmd.AddCommand(newUseCmd(out, errOut))
cmd.AddCommand(newListCmd(out, errOut))
cmd.AddCommand(newUpdateCmd(f, out, errOut))
cmd.AddCommand(newVersionCmd(f, out, errOut))
cmd.AddCommand(newPolicyAdivsorCmd(f, out, errOut))
cmd.AddCommand(newVerifyCmd(f, out, errOut))
cmd.AddCommand(newDbCmd(f, out, errOut))
cmd.AddCommand(newVersionCmd(out, errOut))
cmd.AddCommand(newPolicyAdivsorCmd(out, errOut))
cmd.AddCommand(newVerifyCmd(out, errOut))
cmd.AddCommand(newDbCmd(out, errOut))
cmd.AddCommand(enrollment.NewEnrollCommand())
cmd.AddCommand(newTraceCmd(f, out, errOut))
cmd.AddCommand(newTraceCmd(out, errOut))
cmd.AddCommand(newTutorialCmd(p))
return cmd
}
@@ -14,13 +14,12 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/spf13/cobra"
"io"
@@ -34,21 +33,21 @@ type traceIdentityOptions struct {
}
// newCreateIdentityCmd creates the 'edge controller create identity' command
func newTraceCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newTraceCmd(out io.Writer, errOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "trace",
Short: "manages tracing by the Ziti Edge Controller",
}
cmd.AddCommand(newTraceIdentityCmd(f, out, errOut))
cmd.AddCommand(newTraceIdentityCmd(out, errOut))
return cmd
}
func newTraceIdentityCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newTraceIdentityCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &traceIdentityOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
+425
View File
@@ -0,0 +1,425 @@
package edge
import (
_ "embed"
"fmt"
"github.com/fatih/color"
"github.com/openziti/foundation/util/term"
"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"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"net/url"
"os"
"strconv"
"strings"
"time"
)
//go:embed tutorials/first-service.md
var firstServiceTutorialSource []byte
//go:embed tutorial_plain_echo_server.go
var plainEchoServerSource string
//go:embed tutorial_plain_echo_client.go
var plainEchoClientSource string
//go:embed tutorial_ziti_echo_client.go
var zitiEchoClientSource string
//go:embed tutorial_ziti_echo_server.go
var zitiEchoServerSource string
func newTutorialCmd(p common.OptionsProvider) *cobra.Command {
cmd := &cobra.Command{
Use: "tutorial",
Short: "Interactive tutorials for learning about Ziti",
Run: func(cmd *cobra.Command, args []string) {
err := cmd.Help()
cmdhelper.CheckErr(err)
},
}
cmd.AddCommand(newFirstServiceTutorialCmd(p))
cmd.AddCommand(newPlainEchoServerCmd(p))
cmd.AddCommand(newPlainEchoClientCmd(p))
cmd.AddCommand(newZitiEchoClientCmd(p))
cmd.AddCommand(newZitiEchoServerCmd(p))
return cmd
}
type tutorialOptions struct {
controllerUrl string
username string
password string
newlinePause time.Duration
assumeDefault bool
}
type firstServiceTutorialOptions struct {
edgeOptions
tutorialOptions
}
func newFirstServiceTutorialCmd(p common.OptionsProvider) *cobra.Command {
options := &firstServiceTutorialOptions{
edgeOptions: edgeOptions{
CommonOptions: p(),
},
}
cmd := &cobra.Command{
Use: "first-service",
Short: "Walks you through creating a service, identity and policies",
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().StringVar(&options.controllerUrl, "controller-url", "", "The Ziti controller URL to use")
cmd.Flags().StringVarP(&options.username, "username", "u", "", "The Ziti controller username to use")
cmd.Flags().StringVarP(&options.password, "password", "p", "", "The Ziti controller password to use")
cmd.Flags().DurationVar(&options.newlinePause, "newline-pause", time.Millisecond*10, "How long to pause between lines when scrolling")
cmd.Flags().BoolVar(&options.assumeDefault, "assume-default", false, "Non-interactive mode, assuming default input when user input is required")
options.AddCommonFlags(cmd)
return cmd
}
func (self *firstServiceTutorialOptions) run() error {
t := tutorial.NewRunner()
t.NewLinePause = self.newlinePause
t.AssumeDefault = self.assumeDefault
t.RegisterActionHandler("ziti", &ZitiRunnerAction{})
t.RegisterActionHandler("ziti-login", &ZitiLoginAction{
options: &self.tutorialOptions,
})
t.RegisterActionHandler("keep-session-alive", &KeepSessionAliveAction{})
t.RegisterActionHandler("select-edge-router", &SelectEdgeRouterAction{})
plainEchoServerActions := &PlainEchoServerActions{}
t.RegisterActionHandlerF("run-plain-echo-server", plainEchoServerActions.Start)
t.RegisterActionHandlerF("stop-plain-echo-server", plainEchoServerActions.Stop)
zitiEchoServerActions := &ZitiEchoServerActions{}
t.RegisterActionHandlerF("run-ziti-echo-server", zitiEchoServerActions.Start)
t.RegisterActionHandlerF("stop-ziti-echo-server", zitiEchoServerActions.Stop)
showActionHandler := tutorial.NewShowActionHandler()
showActionHandler.Add("tutorial_plain_echo_server.go", plainEchoServerSource)
showActionHandler.Add("tutorial_plain_echo_client.go", plainEchoClientSource)
showActionHandler.Add("tutorial_ziti_echo_client.go", zitiEchoClientSource)
showActionHandler.Add("tutorial_ziti_echo_server.go", zitiEchoServerSource)
t.RegisterActionHandler("show", showActionHandler)
return t.Run(firstServiceTutorialSource)
}
type ZitiLoginAction struct {
options *tutorialOptions
}
func (self *ZitiLoginAction) Execute(ctx *tutorial.ActionContext) error {
cmd := "ziti edge login --ignore-config"
if self.options.controllerUrl != "" {
cmd += " " + self.options.controllerUrl
}
if self.options.username != "" {
cmd += " --username " + self.options.username
}
if self.options.password != "" {
cmd += " --password " + self.options.password
}
ctx.Body = cmd
return (&ZitiRunnerAction{}).Execute(ctx)
}
type ZitiRunnerAction struct{}
func (self *ZitiRunnerAction) Execute(ctx *tutorial.ActionContext) error {
if strings.EqualFold("true", ctx.Headers["templatize"]) {
body, err := ctx.Runner.Template(ctx.Body)
if err != nil {
return err
}
ctx.Body = body
}
lines := strings.Split(ctx.Body, "\n")
var cmds [][]string
buf := &strings.Builder{}
buf.WriteString("About to execute:\n\n")
for _, line := range lines {
line = strings.TrimSpace(line)
if len(line) > 0 {
params := tutorial.ParseArgumentsWithStrings(line)
if params[0] != "ziti" {
return errors.Errorf("invalid parameter for ziti action, must start with 'ziti': %v", ctx.Body)
}
params[0] = line
cmds = append(cmds, params)
ctx.Runner.LeftPadBuilder(buf)
buf.WriteString(" ")
buf.WriteString(color.New(color.Bold).Sprintf(line))
buf.WriteRune('\n')
}
}
buf.WriteRune('\n')
ctx.Runner.LeftPadBuilder(buf)
buf.WriteString("Continue [Y/N] (default Y): ")
if !ctx.Runner.AssumeDefault {
tutorial.Continue(buf.String(), true)
}
fmt.Println("")
c := color.New(color.FgBlue, color.Bold)
colorStdOut := !strings.EqualFold("false", ctx.Headers["colorStdOut"])
allowRetry := strings.EqualFold("true", ctx.Headers["allowRetry"])
failOk := strings.EqualFold("true", ctx.Headers["failOk"])
for _, cmd := range cmds {
_, _ = c.Printf("$ %v\n", cmd[0])
done := false
for !done {
if err := tutorial.Exec(os.Args[0], colorStdOut, cmd[1:]...); err != nil {
if failOk {
return nil
}
if allowRetry {
retry, err2 := tutorial.AskYesNoWithDefault(fmt.Sprintf("operation failed with err: %v. Retry [Y/N] (default Y):", err), true)
if err2 != nil {
fmt.Printf("error while asking about retry: %v\n", err2)
return err
}
if !retry {
return err
}
} else {
return err
}
} else {
done = true
}
}
}
return nil
}
type KeepSessionAliveAction struct{}
func (self *KeepSessionAliveAction) Execute(ctx *tutorial.ActionContext) error {
interval := time.Minute
if val, ok := ctx.Headers["interval"]; ok {
if d, err := time.ParseDuration(val); err != nil {
return err
} else {
interval = d
}
}
fmt.Printf("Running session refresh every %v\n", interval)
go func() {
ticker := time.NewTicker(interval)
for {
select {
case <-ticker.C:
_, _, _ = listEntitiesOfType("edge-routers", url.Values{}, false, nil, 10, false)
}
}
}()
return nil
}
type edgeRouter struct {
id string
name string
}
type SelectEdgeRouterAction struct{}
func (self *SelectEdgeRouterAction) Execute(ctx *tutorial.ActionContext) error {
for {
err := self.SelectEdgeRouter(ctx)
if err == nil {
return nil
}
retry, err2 := tutorial.AskYesNoWithDefault(fmt.Sprintf("Error getting edge router (err=%v). Try again? [Y/N] (default Y): ", err), true)
if err2 != nil {
fmt.Printf("encountered error prompting for input: %v\n", err2)
return err
}
if !retry {
return err
}
}
}
func (self *SelectEdgeRouterAction) SelectEdgeRouter(ctx *tutorial.ActionContext) error {
fmt.Println("")
valid := false
var edgeRouterName string
for !valid {
children, _, err := listEntitiesWithFilter("edge-routers", "limit none")
if err != nil {
return errors.Wrap(err, "unable to list edge routers")
}
var ers []*edgeRouter
if len(children) == 0 {
return errors.New("no edge routers found")
}
for _, child := range children {
isOnline := child.S("isOnline").Data().(bool)
if isOnline {
id := child.S("id").Data().(string)
name := child.S("name").Data().(string)
ers = append(ers, &edgeRouter{id: id, name: name})
}
}
if len(ers) == 0 {
fmt.Println("Error: no online edge routers found. Found these offline edge routers: ")
for _, child := range children {
id := child.S("id").Data().(string)
name := child.S("name").Data().(string)
fmt.Printf("id: %10v name: %10v\n", id, name)
}
return errors.New("no on-line edge routers")
}
fmt.Printf("Available edge routers: \n\n")
for idx, er := range ers {
fmt.Printf(" %v: %v\n", idx+1, er.name)
}
fmt.Print(" R: Refresh list from controller\n")
var val string
if !ctx.Runner.AssumeDefault {
val, err = term.Prompt("\nSelect edge router, by number or name (default 1): ")
if err != nil {
return err
}
}
if val == "" {
edgeRouterName = ers[0].name
valid = true
} else {
if idx, err := strconv.Atoi(val); err == nil {
if idx > 0 && idx <= len(ers) {
edgeRouterName = ers[idx-1].name
valid = true
}
}
}
if !valid {
for _, er := range ers {
if val == er.name {
edgeRouterName = val
valid = true
}
}
}
if !valid {
if strings.EqualFold("r", val) {
fmt.Println("Refreshing edge router list")
} else {
fmt.Printf("Invalid input %v\n", val)
}
}
}
ctx.Runner.AddVariable("edgeRouterName", edgeRouterName)
return nil
}
type PlainEchoServerActions struct {
server plainEchoServer
}
func (self *PlainEchoServerActions) Start(ctx *tutorial.ActionContext) error {
if !ctx.Runner.AssumeDefault {
start, err := tutorial.AskYesNoWithDefault("Start plain-echo-server? [Y/N] (default Y): ", true)
if err != nil {
return err
}
if !start {
return nil
}
}
if err := self.server.run(); err != nil {
return err
}
ctx.Runner.AddVariable("port", self.server.Port)
return nil
}
func (self *PlainEchoServerActions) Stop(ctx *tutorial.ActionContext) error {
if !ctx.Runner.AssumeDefault {
start, err := tutorial.AskYesNoWithDefault("Stop plain-echo-server? [Y/N] (default Y): ", true)
if err != nil {
return err
}
if !start {
return nil
}
}
if self.server.listener != nil {
return self.server.stop()
}
return nil
}
type ZitiEchoServerActions struct {
server zitiEchoServer
}
func (self *ZitiEchoServerActions) Start(ctx *tutorial.ActionContext) error {
logrus.SetLevel(logrus.WarnLevel)
self.server.identityJson = "echo-server.json"
if !ctx.Runner.AssumeDefault {
start, err := tutorial.AskYesNoWithDefault("Start ziti-echo-server? [Y/N] (default Y): ", true)
if err != nil {
return err
}
if !start {
return nil
}
}
if err := self.server.run(); err != nil {
return err
}
return nil
}
func (self *ZitiEchoServerActions) Stop(*tutorial.ActionContext) error {
if self.server.listener != nil {
return self.server.stop()
}
return nil
}
@@ -0,0 +1,27 @@
package edge
import (
"fmt"
"github.com/fatih/color"
"io"
"net/http"
"net/url"
"os"
)
type plainEchoClient struct {
host string
port uint16
}
func (self *plainEchoClient) echo(input string) error {
input = url.QueryEscape(input)
u := fmt.Sprintf("http://%v:%v?input=%v", self.host, self.port, input)
resp, err := (&http.Client{}).Get(u)
if err == nil {
c := color.New(color.FgBlue, color.Bold)
c.Print("\nplain-http-echo-client: ")
_, err = io.Copy(os.Stdout, resp.Body)
}
return err
}
@@ -0,0 +1,49 @@
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/spf13/cobra"
"strings"
)
// edgeOptions are common options for edge controller commands
type plainEchoClientOptions struct {
common.CommonOptions
port uint16
host string
}
func (self *plainEchoClientOptions) run() error {
echoClient := &plainEchoClient{
host: self.host,
port: self.port,
}
return echoClient.echo(strings.Join(self.Args, " "))
}
func newPlainEchoClientCmd(p common.OptionsProvider) *cobra.Command {
options := &plainEchoClientOptions{
CommonOptions: p(),
}
cmd := &cobra.Command{
Use: "plain-echo-client strings to echo",
Short: "Runs a simple http echo client",
Args: cobra.MinimumNArgs(1),
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().Uint16Var(&options.port, "port", 80, "Specify the port to dial on")
cmd.Flags().StringVar(&options.host, "host", "localhost", "Specify the host to connect to")
return cmd
}
@@ -0,0 +1,45 @@
package edge
import (
"fmt"
"github.com/fatih/color"
"net"
"net/http"
)
type plainEchoServer struct {
Port int
listener net.Listener
}
func (s *plainEchoServer) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
input := r.URL.Query().Get("input")
result := fmt.Sprintf("As you say, '%v', indeed!\n", input)
c := color.New(color.FgBlue, color.Bold)
c.Print("\nplain-http-echo-server: ")
fmt.Printf("received input '%v'\n", input)
if _, err := rw.Write([]byte(result)); err != nil {
panic(err)
}
}
func (s *plainEchoServer) run() (err error) {
bindAddr := fmt.Sprintf("127.0.0.1:%v", s.Port)
s.listener, err = net.Listen("tcp", bindAddr)
if err != nil {
return err
}
addr := s.listener.Addr().(*net.TCPAddr)
s.Port = addr.Port
c := color.New(color.FgBlue, color.Bold)
c.Print("\nplain-http-echo-server: ")
fmt.Printf("listening on %v\n", addr)
go func() { _ = http.Serve(s.listener, http.HandlerFunc(s.ServeHTTP)) }()
return nil
}
func (s *plainEchoServer) stop() error {
return s.listener.Close()
}
@@ -0,0 +1,50 @@
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/spf13/cobra"
"time"
)
// edgeOptions are common options for edge controller commands
type plainEchoServerOptions struct {
common.CommonOptions
port uint16
}
func (self *plainEchoServerOptions) run() error {
echoServer := &plainEchoServer{
Port: int(self.port),
}
if err := echoServer.run(); err != nil {
return err
}
time.Sleep(time.Hour * 24 * 365 * 100)
return nil
}
func newPlainEchoServerCmd(p common.OptionsProvider) *cobra.Command {
options := &plainEchoServerOptions{
CommonOptions: p(),
}
cmd := &cobra.Command{
Use: "plain-echo-server",
Short: "Runs a simple http echo service",
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().Uint16Var(&options.port, "port", 0, "Specify the port to listen on")
return cmd
}
@@ -0,0 +1,51 @@
package edge
import (
"context"
"fmt"
"github.com/fatih/color"
"github.com/openziti/sdk-golang/ziti"
"github.com/openziti/sdk-golang/ziti/config"
"io"
"net"
"net/http"
"net/url"
"os"
"strings"
)
func NewZitiEchoClient(identityJson string) (*zitiEchoClient, error) {
config, err := config.NewFromFile(identityJson)
if err != nil {
return nil, err
}
zitiContext := ziti.NewContextWithConfig(config)
dial := func(_ context.Context, _ string, addr string) (net.Conn, error) {
service := strings.Split(addr, ":")[0] // assume host is service
return zitiContext.Dial(service)
}
zitiTransport := http.DefaultTransport.(*http.Transport).Clone()
zitiTransport.DialContext = dial
return &zitiEchoClient{
httpClient: &http.Client{Transport: zitiTransport},
}, nil
}
type zitiEchoClient struct {
httpClient *http.Client
}
func (self *zitiEchoClient) echo(input string) error {
u := fmt.Sprintf("http://echo?input=%v", url.QueryEscape(input))
resp, err := self.httpClient.Get(u)
if err == nil {
c := color.New(color.FgGreen, color.Bold)
c.Print("\nziti-http-echo-client: ")
_, err = io.Copy(os.Stdout, resp.Body)
}
return err
}
@@ -0,0 +1,49 @@
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"strings"
)
// edgeOptions are common options for edge controller commands
type zitiEchoClientOptions struct {
common.CommonOptions
identity string
}
func (self *zitiEchoClientOptions) run() error {
logrus.SetLevel(logrus.WarnLevel)
echoClient, err := NewZitiEchoClient(self.identity)
if err != nil {
return err
}
return echoClient.echo(strings.Join(self.Args, " "))
}
func newZitiEchoClientCmd(p common.OptionsProvider) *cobra.Command {
options := &zitiEchoClientOptions{
CommonOptions: p(),
}
cmd := &cobra.Command{
Use: "ziti-echo-client strings to echo",
Short: "Runs a ziti-enabled http echo client",
Args: cobra.MinimumNArgs(1),
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().StringVar(&options.identity, "identity", "echo-client.json", "Specify the config file to use")
return cmd
}
@@ -0,0 +1,48 @@
package edge
import (
"fmt"
"github.com/fatih/color"
"github.com/openziti/sdk-golang/ziti"
"github.com/openziti/sdk-golang/ziti/config"
"net"
"net/http"
)
type zitiEchoServer struct {
identityJson string
listener net.Listener
}
func (s *zitiEchoServer) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
input := r.URL.Query().Get("input")
result := fmt.Sprintf("As you say, '%v', indeed!\n", input)
c := color.New(color.FgGreen, color.Bold)
c.Print("\nziti-http-echo-server: ")
fmt.Printf("received input '%v'\n", input)
if _, err := rw.Write([]byte(result)); err != nil {
panic(err)
}
}
func (s *zitiEchoServer) run() (err error) {
config, err := config.NewFromFile(s.identityJson)
if err != nil {
return err
}
zitiContext := ziti.NewContextWithConfig(config)
if s.listener, err = zitiContext.Listen("echo"); err != nil {
return err
}
c := color.New(color.FgGreen, color.Bold)
c.Print("\nziti-http-echo-server: ")
fmt.Println("listening for connections from echo server")
go func() { _ = http.Serve(s.listener, http.HandlerFunc(s.ServeHTTP)) }()
return nil
}
func (s *zitiEchoServer) stop() error {
return s.listener.Close()
}
@@ -0,0 +1,50 @@
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/spf13/cobra"
"time"
)
// edgeOptions are common options for edge controller commands
type zitiEchoServerOptions struct {
common.CommonOptions
identity string
}
func (self *zitiEchoServerOptions) run() error {
echoServer := &zitiEchoServer{
identityJson: self.identity,
}
if err := echoServer.run(); err != nil {
return err
}
time.Sleep(time.Hour * 24 * 365 * 100)
return nil
}
func newZitiEchoServerCmd(p common.OptionsProvider) *cobra.Command {
options := &zitiEchoServerOptions{
CommonOptions: p(),
}
cmd := &cobra.Command{
Use: "ziti-echo-server",
Short: "Runs a ziti-based http echo service",
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().StringVar(&options.identity, "identity", "echo-server.json", "Specify the config file to use")
return cmd
}
@@ -0,0 +1,474 @@
# Introduction
Hello. In this tutorial we’re going to go explore services, identities and polices.
Please note: this tutorial can be run interactively, by running 'ziti edge tutorial first-service'. It can also be viewed as a web page [here](https://github.com/openziti/ziti/blob/release-next/ziti/cmd/ziti/cmd/edge/tutorials/first-service.md). It may be convenient to be able to view both at the same time. The interactive version will save you a lot of typing or copy/pasting, but content may be easier to read in a web-browser.
<!---action:pause -->
## Goals
Let’s say you’re the founder of CloudEcho, the number one provider of echo services. When someone needs to hear back what they’ve said, you are here to make that happen. Any way that a customer needs an echo, be it TCP, UDP or HTTP based echo services, you’ve got them covered. You’ve decided to try integrating Ziti into your services and clients. We’re going to look at a few different ways to do that integration and explore different areas of the Ziti model to build an understanding of how to provide and consume services. In this tutorial we’re going look at how to Zitify the HTTP echo service.
<!---action:pause -->
## Prerequisites
First, let’s make sure you’ve got an environment running you can work with. We need a Ziti controller and at least one edge router to work with. If you don’t have a controller and edge router running,
you can use the quick-start script found [here](https://github.com/openziti/ziti/tree/release-next/quickstart). The fastest way to invoke the quick-start is to run
`source <(wget -qO- https://raw.githubusercontent.com/openziti/ziti/release-next/quickstart/docker/image/ziti-cli-functions.sh); expressInstall`
### Authenticate to the controller
Let's make sure we can connect with the controller. We're going to log in with the Ziti CLI, which will then let us run the rest of our operations.
```action:ziti-login allowRetry=true
ziti edge login
```
Ziti API sessions usually expire after a few minutes. In order to make sure that this session doesn't timeout while the tutorial is running, we're going to run a session keep-alive in the background.
```action:keep-session-alive interval=1m
If your session times out you can run ziti edge login again.
```
### Select Edge Router
Great, now that we’re logged in, let’s find our local edge router.
Note that this tutorial assumes that you’ve got an edge router running on the same machine as this tutorial. We'll be using localhost when telling the edge router how to connect to the tutorial services. If you don’t have an edge router running locally, please add one now.
```action:select-edge-router
Pick the name of an edge router to use. It will be referenced in this tutorial as ${edgeRouterName}
```
### Cleanup Tutorial Entities
Finally, in case you've run this tutorial before or have done other experimentation with this sytem the tutorial may not run cleanly. To ensure a clean run we're going to clean up any entities that would conflict with entities created as part of this tutorial.
```action:ziti
ziti edge delete service echo
ziti edge delete identities founder-laptop echo-server
ziti edge delete service-policies echo-clients echo-servers
ziti edge delete edge-router-policies echo-clients echo-servers
ziti edge delete service-edge-router-policy echo
```
# Setting up the Echo Service
We want to run our echo service over Ziti. We need to create various entities in Ziti for this to work, but the first is the service itself. The most important property of a Ziti service is its name. The service name is similar to a DNS name. When we connect to a service or host a service, we do so by name.
## Creating the Echo Service
Let’s create the echo service. The only required property we're providing for now is the name.
```action:ziti
ziti edge create service echo
```
Now that the service has been created, let’s query the service and see what shows up.
```action:ziti
ziti edge list services 'name="echo"'
```
<!---action:pause -->
## Connecting Ziti to our Service
So, now Ziti has an echo service, but that service doesn’t go anywhere, and we don’t have any way to use it yet. We’re going to start by connecting the service to the applications hosting the service.
### Plain Echo Service
Let’s start by assuming we don’t want to make any changes to our server software yet. We’re just going to run an echo server which uses the standard library facilities. Let's start that service now. The source can be found [here](../tutorial_plain_echo_server.go).
<!---action:show src=tutorial_plain_echo_server.go highlight=go-->
```action:run-plain-echo-server
ziti edge tutorial plain-echo-server
```
The output for this service will be prefixed with plain-http-echo-server. The service is running on port ${port}. We can hit this service with a browser at
```
http://localhost:${port}?input=trees%20are%20tall
```
to see the output. Or we can run it with the tutorial plain echo client. The client output will be prefixed with plain-echo-client.
The source for the plain client code is very simple, and can be found here: [here](../tutorial_plain_echo_client.go)
<!---action:show src=tutorial_plain_echo_client.go highlight=go-->
Let's run it and see what the output looks. At this point, we're not sending any traffic over the Ziti network.
```action:ziti templatize=true colorStdOut=false
ziti edge tutorial plain-echo-client --port ${port} trees are tall
```
<!---action:pause -->
### Terminators Overview
Now that we’ve got the service running, we can tell Ziti how to connect to it. We do that by creating a terminator for the service. A terminator represents an off ramp from the Ziti fabric. When we make a connection through Ziti to a service, the fabric will select a terminator to which traffic will be routed for that connection. For some types of terminators, each connection to the service will result in a new connection from the router to the hosting application. For others, an existing connection between the router and the hosting application will be used.
### Creating the Terminator
Let's create the terminator. The arguments to the create terminator command are:
1. **echo**: The service we’re creating the terminator for
1. **${edgeRouterName}**: The edge router we want to use to connect to the application server
1. **tcp:localhost:${port}**: The application server address. The format is protocol:hostname-or-ip:port. The protocol can be any of tcp, udp or tls. This address is what the edge router will try to make a
connection to when someone uses the service.
```action:ziti templatize=true
ziti edge create terminator echo ${edgeRouterName} tcp:localhost:${port}
```
### Terminator Properties
Let's take a look at our new terminator:
```action:ziti failOk=true
ziti edge list terminators 'service.name="echo"'
```
<!---action:pause -->
# Client Application
In order to use the echo service, we need a client application. Our application could embed a Ziti SDK, but unmodified applications can also access Ziti services using a tunneler application. See [Tunnelers](https://openziti.github.io/ziti/clients/tunneler.html) for more information. Even though we're not covering tunnelers here, they are built with the Ziti SDKS. Therefore, all the following setup and configuration applies to them.
<!---action:pause -->
## SDK Client
Let's take a look at our SDK client code (viewable [here](../tutorial_ziti_echo_client.go)). If you compare it with the plain version, you'll notice the actual client code is very similar. The main differences are
1. We have to load our configuration, so that we can initialize a Ziti Context
2. We have to intercept the Dial in the HTTP client, so we can send it through Ziti
3. Instead of host:port for the address, we use the service name 'echo'
<!---action:show src=tutorial_ziti_echo_client.go highlight=go-->
We can't actually run it yet, because we don't have a configuration for it. As a next step, let's see how we can configure our client, so we can run it.
<!---action:pause -->
# Identity Setup
The main thing our client needs to connect to the Ziti network is an identity. One of the primary functions of Ziti is controlling access to services. In order for us to access the echo service, our client application needs an identity, so that we can permit that identity access.
## What is an Identity?
It's tempting to think of an identity as either a user or a device, but neither of those is entirely correct. A user may have multiple devices, each of which accesses the same service. In general a user will have a separate identity for each device from which they access the service. There are a few reasons for this approach:
* By enrolling each device individually we don’t transfer the credentials between devices. Because we generate the credentials each device, they can’t be intercepted.
* If someone compromises one device, we can disable just that identity, rather than everything for a given user.
* Traffic becomes attributable to a given device, which can be useful in a number of ways, including identifying misbehaving applications.
If a user belongs to multiple Ziti networks, they will likely have multiple identities per device. In general, multiple identities on the same device for the same user will not cause any conflicts, unlike trying to run multiple VPNs concurrently. Even when using a Ziti tunnelers, each tunneler can host multiple identities concurrently and there will only be problems if multiple services try to claim the same DNS name or IP.
Creating the Identity
When creating an identity you can specify the identity type as being one of user, service or device. These types are currently just descriptive, and do not affect how Ziti uses the identities. Let’s say you’re running your own software on your laptop. Since you are the company founder, we’ll name the identity founder-laptop. We're also going to assign the identity a role attribute of management. We can use this later when setting up policies.
```action:ziti
ziti edge create identity user founder-laptop -o founder-laptop.jwt --role-attributes management
```
We have now created a new identity of type user with name founder-laptop. When Ziti created the identity, a one-time-token was also generated, which we’ve stored in founder-client.jwt. We’ll use this token to enroll our identity and create the configuration file for our client application.
Let’s take a look at our new identity:
```action:ziti
ziti edge list identities 'name="founder-laptop"'
```
In addition to the id, name and type we can see that identities, like services and edge routers, also have role-attributes. In the next section we'll be configuring service access, and we’ll see how role attributes come into play.
Before we can use our new identity, we need to enroll it. Enrolling the identity uses up the one-time-token and generates the configuration, keys and certificates that a client needs to use a Ziti network.
```action:ziti
ziti edge enroll -j founder-laptop.jwt -o founder-laptop.json
```
The resulting json file has the address of the Ziti controller, as well as the keys and certificates it needs to establish its identity and communicate securely with that controller.
As you saw, the usual flow for enrolling an application in a ziti network has two steps. However, unlike in our approach here, we don’t generally rely on the Ziti CLI to enroll applications and generate a config file. A more conventional flow would be:
1. Create an identity for the application, which includes generating a JWT
1. The application imports JWT, enrolls in the application and stores the configuration in its own format.
1. Two ways that applications can import JWTs are by reading a file or reading a QR code
The reason enrollment is broken into two steps is because we only want the keys and certificates to exist on their final destination. We may transmit the JWT, but once enrollment has completed the JWT cannot be re-used. If someone later steals the JWT, they won’t be able to enroll, as the JWT will no longer be valid. If some intercepts the JWT and uses it to enroll before the intended recipient does, the intended recipient’s enrollment will fail. This lets us know that something is wrong, we can disable the identity, and the intrusion will have been quickly detected.
<!---action:pause-->
## Trying the Ziti Client
Now that we’re enrolled, let’s try to use our echo service.
```action:ziti failOk=true
ziti edge tutorial ziti-echo-client --identity founder-laptop.json trees are tall
```
Hopefully it comes as no surprise that the echo service wasn’t found, given that we haven’t granted our identity any access yet.
# Policy Configuration
The Ziti CLI comes with a tool called policy-advisor to help you figure out if you have correctly configured your policies. Let’s try it out. It can be run either from a service or identity-centric perspective. This following command will check if the founder-laptop identity can access the echo service.
```action:ziti
ziti edge policy-advisor identities -q founder-laptop echo
```
It should give us three errors.
1. That the identity has no access to the service
1. That the identity has no access to edge routers
1. That the service has no access to edge routers
Let’s tackle these one at a time.
**Note:** If you don’t see all of those errors, you most likely have other policies affecting your identity or service.
## Service Policy Setup
First we need to grant access to use the service via a service policy. There are two types of service policies:
* Dial - allow using a service
* Bind - allow hosting a service
For now, we just need a dial policy. Later, when we try hosting the echo service with an SDK embedded application, we’ll need a bind policy as well. We're going to explicitly add our service and identity to this policy. The service we'll reference by name. The identity we'll include by role attribute.
For a deep dive into policies, see [here](https://openziti.github.io/ziti/policies/overview.html).
```action:ziti
ziti edge create service-policy echo-clients Dial --service-roles '@echo' --identity-roles '#management'
```
Let’s check and make sure it’s there:
```action:ziti
ziti edge list service-policies 'name="echo-clients"'
```
If we run the policy-advisor, we should see that we have fixed the first error, and that we have Dial permissions for the echo service.
```action:ziti
ziti edge policy-advisor identities -q founder-laptop echo
```
If we try to run the client again, it still won’t work, but we should see a different error:
```action:ziti failOk=true
ziti edge tutorial ziti-echo-client --identity founder-laptop.json trees are tall
```
This error indicates that we have access to the service, but not to any edge routers.
<!---action:pause-->
# Edge Router Policy Setup
Now we need to give our client access to one or more edge routers. Edge routers are how client traffic enters a Ziti network. We need to be able to limit which identities can access specific edge routers. Certain edge routers may be dedicated to specific regions, users or services.
```action:ziti templatize=true
ziti edge create edge-router-policy echo-clients --edge-router-roles '@${edgeRouterName}' --identity-roles '#management'
```
Taking a look, we should see now see our new edge router policy in place.
```action:ziti
ziti edge list edge-router-policies 'name="echo-clients"'
```
If we run the policy advisor again, we should see a change.
```action:ziti
ziti edge policy-advisor identities -q founder-laptop echo
```
We should only have one error left, letting us know that the service doesn’t have any edge routers available to it.
If we run the client again, we’ll see the same error:
```action:ziti failOk=true
ziti edge tutorial ziti-echo-client --identity founder-laptop.json trees are tall
```
This is because the edge routers that can be used when establishing a session is the set of edge routers that the identity and service have in common.
Looking at an example:
1. We have an identity which has access to edge routers A, B, C
2. We have a service which can be accessed via edge routers C, D, E
3. That identity can only access the service via edge router C, since that's the only one they have in common
Even though our identity now has access to our edge router, our service does not.
<!---action:pause-->
# Service Edge Router Policies
In the same way that we can assign edge routers to users, we can also assign them to services. You may wish to do this to conform with local regulations or to give services exclusive access to certain edge routers to meet SLAs.
Since we don’t have any special requirements right now, let’s let the echo service use all edge routers. There’s a special role attribute of #all which will match all entities of a given type.
```action:ziti
ziti edge create service-edge-router-policy echo --edge-router-roles '#all' --service-roles '@echo'
```
Now if we run the policy advisor again, we should not see any errors.
```action:ziti
ziti edge policy-advisor identities -q founder-laptop echo
```
We should now finally be able to run the client and get some validation.
```action:ziti colorStdOut=false
ziti edge tutorial ziti-echo-client --identity founder-laptop.json trees are tall
```
We have our first successful connecton through Ziti! **\o/**
<!---action:pause-->
# SDK-Embedded Server
Now that we’ve gotten our end-to-end test working let’s replace our plain server with a Zitified version.
## Clean up plain server
Before configuring and running our ziti-embedded server, we're going to stop the plain server and remove any related configurion.
```action:stop-plain-echo-server
Stop the plain echo server
```
We’ve stopped the echo server. If we now run the client, we’ll see an error saying that dialing the service fails.
```action:ziti colorStdOut=false failOk=true
ziti edge tutorial ziti-echo-client --identity founder-laptop.json trees are tall
```
We’re going to also remove the terminator, since that now points to an address where nothing is running.
```action:ziti
ziti edge delete terminators where 'service.name="echo"'
```
If we now run the client, we’ll see an error saying that the service has no terminators.
```action:ziti colorStdOut=false failOk=true
ziti edge tutorial ziti-echo-client --identity founder-laptop.json trees are tall
```
## Hosting Identity
Since we’re going to use the SDK in the server, we need an identity for the server.
```action:ziti
ziti edge create identity service echo-server -o echo-server.jwt --role-attributes echo-server
```
We’ll then enroll the server identity.
```action:ziti
ziti edge enroll -j echo-server.jwt -o echo-server.json
```
## Ziti Server Code
If you look at the server code, viewable [here](../tutorial_ziti_echo_server.go), you should notice very few changes from the plain echo server. The actual request processing code is unchanged.
<!---action:show src=tutorial_ziti_echo_server.go highlight=go-->
Let’s try running it and see what happens.
```action:ziti colorStdOut=false failOk=true
ziti edge tutorial ziti-echo-server --identity echo-server.json
```
Since we haven’t given this identity access to the server, it fails.
## Server Side Policy Configuration
Let’s run the policy advisor first and see what it has to say.
```action:ziti
ziti edge policy-advisor identities -q echo-server echo
```
We should only see two errors.
* The identity does not have access to the service
* The identity does not have access to any edge routers
We already granted the echo service to all edge routers, so that is no longer an issue.
First, let’s grant the identity access to the service. Unlike before, we’re not granting access to use the service, but to host it. So instead of a Dial policy, we need to create a Bind policy.
```action:ziti
ziti edge create service-policy echo-servers Bind --service-roles '@echo' --identity-roles '#echo-server'
```
We now have two service policies, one for clients and one for hosts
```action:ziti
ziti edge list service-policies 'name contains "echo"'
```
Running the policy advisor again, we should be down to one error:
```action:ziti
ziti edge policy-advisor identities -q echo-server echo
```
Finally, we create an edge router policy for the hosting identity. In this case, it has the same servers as the client side, but generally client side and hosting side identities will use different sets of edge routers.
```action:ziti templatize=true
ziti edge create edge-router-policy echo-servers --edge-router-roles '@${edgeRouterName}' --identity-roles '#echo-server'
```
We should now get a clean bill of health from the policy advisor
```action:ziti
ziti edge policy-advisor identities -q echo-server echo
```
Let’s give it a try now and see what happens:
```action:run-ziti-echo-server
ziti edge tutorial ziti-echo-server
```
Our client should work correctly. Hang on, you may be saying… won’t it fail with a ‘no terminators’ error? After all, we haven’t created a new terminator yet. Well, let’s take a look at our terminators:
```action:ziti failOk=true
ziti edge list terminators 'service.name="echo"'
```
There’s a terminator present, which looks quite different from the one we created manually. This terminator was created dynamically when the ziti-echo-server application bound the service. Client connections for echo will now get made over the existing network connection that the server application has with the edge router. When you stop the server application, the terminator will be removed.
This has some interesting benefits. For example, this can make horizontal scale easier to accomplish. When you spin up new instances of the server application, they can connect, dynamically create a terminator and start receiving a portion of the service traffic. When you stop an application, or it dies, the connection goes away, and the terminator is automatically removed. New connections won’t try to connect that application server anymore.
Hosting configuration and topologies is a big topic. For now, let’s try out our client with our single server instance running:
```action:ziti colorStdOut=false
ziti edge tutorial ziti-echo-client --identity founder-laptop.json trees are tall
```
Success, we now have a Ziti SDK-embedded client, communicating with a Ziti SDK-embedded server.
Thanks for taking the time to learn about Ziti services, identities and policies!
Hopefully you’ve gotten a better idea of:
* How to create and manage services and identities
* How terminators connect the Ziti fabric with application servers
* How to manage client access with identities and service policies
* How edge routers can be assigned across identities with edge router policies
* How edge routers can be assigned across services with service edge router polices
See the [Documentation Hub](https://openziti.github.io/) for more resources.
@@ -0,0 +1,57 @@
# Introduction
This document contains more in-depth information for various Ziti topics. Most of this should be folded into the docs, but it's here as a resource for now.
## Edge Router Topologies
When developing or testing we may send all traffic through a single router. This is not how a Ziti network would commonly be deployed. Usually there would be multiple routers co-located with the application servers, hosted so that they were not reachable from the public internet. These routers would reach out to routers hosted on the public internet. Clients would connect to the public facing routers.
## Service Properties
Let’s take a look at each of the service properties:
### id
A system generated immutable ID. Different UIs like the CLI and the admin console will generally allow you to reference things by name. The ID just provides a stable unique ID, as opposed to the name, which must also be unique but can change.
### name
A user provided unique, mutable identifier. Generally used for display.
### encryption required
Ziti encrypts communications between processes when configured with TLS. This means data will be encrypted on the wire between the client and routers and in the context of router to router communication. Routers must decrypt data in memory in order to perform routing. This can be avoided, as Ziti SDKs also provide for transparent end-to-end encryption. This means that Ziti SDKs will encrypt your data before it enters a Ziti network, and it won't be decrypted until it is received on the other side. This flag controls whether this encryption is mandatory. If you set the flag on a service and end-to-end encryption handshaking fails, the SDKs will fail the connection rather than falling back to unencrypted communication.
### terminator strategy
This comes into play when you have multiple ways to route traffic to the application(s) hosting the service. This could be:
* Multiple application servers, either for a HA (high availability) or horizontal scaling
* Multiple routers configured to go to a single application server, for redundancy or performance of the Ziti network
* A combination of the two
The strategy determines how we pick which application gets a particular connection attempt via which route.
See [Ziti Services | Terminators](https://openziti.github.io/ziti/services/overview.html?tabs=create-service-ui#terminators) for more information.
### role attributes
Used by the policy system. We’ll cover this in more details shortly.
# Terminator
Taking a look at the results, the id, service, router and address properties should all make sense. Let’s take a brief look at some properties.
#### binding
Different terminators can be handled by different code in the routers. This tells the router how this terminator should be treated. An edge_transport binding directs the router to use a module which knows how to handle edge end-to-end encryption and connect to TCP and TLS addresses. We’ll see a different type of binding when we look at app-embedded hosting.
#### identity
Used by P2P or mesh type services, for example VoIP. Generally used when you have multiple applications all hosting the same service, and you need to be able to reach a specific one. For example, you may have many VoIP applications all hosting a VoIP service. When you dial the service, you'll want to connect to the specific application that the person you're trying to reach is running.
#### cost, precedence and dynamic-cost
These properties are all used by terminator strategies. We’ll cover them in the hosting tutorial.
Now that we have configured the service side of our service, let’s take a look at the client side.
# Tunnelers
If we have an existing client application which doesn’t have Ziti embedded, the Ziti project provides some applications which can bridge the gap between a plain client application and a Ziti-hosted service. They generally work by acting as a proxy, intercepting network traffic and redirecting it through Ziti. They can even intercept DNS names and IP addresses, so that client configuration doesn’t need to change. We're not going to demonstrate a tunneler as part of this tutorial, but know that there are options available for those cases where embedding an SDK into the application isn’t feasible, or you need an intermediary solution.
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"github.com/Jeffail/gabs"
@@ -49,7 +49,7 @@ func newUpdateCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Com
cmd.AddCommand(newUpdateServicePolicyCmd(f, out, errOut))
cmd.AddCommand(newUpdateServiceEdgeRouterPolicyCmd(f, out, errOut))
cmd.AddCommand(newUpdateTerminatorCmd(f, out, errOut))
cmd.AddCommand(newUpdatePostureCheckCmd(f, out, errOut))
cmd.AddCommand(newUpdatePostureCheckCmd(out, errOut))
return cmd
}
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"context"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"encoding/json"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
@@ -25,21 +25,20 @@ import (
"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/spf13/cobra"
)
// newUpdatePostureCheckCmd creates the 'edge controller update posture-check' command
func newUpdatePostureCheckCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newUpdatePostureCheckCmd(out io.Writer, errOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "posture-check",
}
cmd.AddCommand(newUpdatePostureCheckMacCmd(f, out, errOut))
cmd.AddCommand(newUpdatePostureCheckDomainCmd(f, out, errOut))
cmd.AddCommand(newUpdatePostureCheckProcessCmd(f, out, errOut))
cmd.AddCommand(newUpdatePostureCheckOsCmd(f, out, errOut))
cmd.AddCommand(newUpdatePostureCheckMfaCmd(f, out, errOut))
cmd.AddCommand(newUpdatePostureCheckMacCmd(out, errOut))
cmd.AddCommand(newUpdatePostureCheckDomainCmd(out, errOut))
cmd.AddCommand(newUpdatePostureCheckProcessCmd(out, errOut))
cmd.AddCommand(newUpdatePostureCheckOsCmd(out, errOut))
cmd.AddCommand(newUpdatePostureCheckMfaCmd(out, errOut))
return cmd
}
@@ -82,11 +81,11 @@ type updatePostureCheckOsOptions struct {
os []string
}
func newUpdatePostureCheckMacCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newUpdatePostureCheckMacCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &updatePostureCheckMacOptions{
updatePostureCheckOptions: updatePostureCheckOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
},
addresses: nil,
@@ -150,11 +149,11 @@ func runUpdatePostureCheckMac(o *updatePostureCheckMacOptions) error {
return err
}
func newUpdatePostureCheckDomainCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newUpdatePostureCheckDomainCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &updatePostureCheckDomainOptions{
updatePostureCheckOptions: updatePostureCheckOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
},
domains: nil,
@@ -184,11 +183,11 @@ func newUpdatePostureCheckDomainCmd(f cmdutil.Factory, out io.Writer, errOut io.
return cmd
}
func newUpdatePostureCheckMfaCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newUpdatePostureCheckMfaCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &updatePostureCheckMfaOptions{
updatePostureCheckOptions: updatePostureCheckOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
},
timeoutSeconds: -1,
@@ -332,11 +331,11 @@ func runUpdatePostureCheckDomain(o *updatePostureCheckDomainOptions) error {
//process
func newUpdatePostureCheckProcessCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newUpdatePostureCheckProcessCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &updatePostureCheckProcessOptions{
updatePostureCheckOptions: updatePostureCheckOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
},
hashes: nil,
@@ -439,11 +438,11 @@ func runUpdatePostureCheckProcess(o *updatePostureCheckProcessOptions) error {
}
// os
func newUpdatePostureCheckOsCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newUpdatePostureCheckOsCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &updatePostureCheckOsOptions{
updatePostureCheckOptions: updatePostureCheckOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
},
os: nil,
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"errors"
@@ -14,11 +14,10 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
@@ -31,10 +30,10 @@ type useOptions struct {
}
// newUseCmd creates the command
func newUseCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newUseCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &useOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
@@ -14,19 +14,18 @@
limitations under the License.
*/
package edge_controller
package edge
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/util"
"github.com/spf13/cobra"
)
// newVerifyCmd creates a command object for the "controller verify" command
func newVerifyCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newVerifyCmd(out io.Writer, errOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "verify",
Short: "verifies various entities managed by the Ziti Edge Controller",
@@ -37,7 +36,7 @@ func newVerifyCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Com
},
}
cmd.AddCommand(newVerifyCaCmd(f, out, errOut))
cmd.AddCommand(newVerifyCaCmd(out, errOut))
return cmd
}
@@ -14,7 +14,7 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"crypto"
@@ -29,7 +29,6 @@ import (
nfpem "github.com/openziti/foundation/util/pem"
"github.com/openziti/foundation/util/term"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
@@ -60,13 +59,12 @@ type verifyCaOptions struct {
}
// newVerifyCaCmd creates the 'edge controller verify ca' command for the given entity type
func newVerifyCaCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newVerifyCaCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &verifyCaOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{
Factory: f,
Out: out,
Err: errOut,
Out: out,
Err: errOut,
},
},
}
@@ -14,12 +14,11 @@
limitations under the License.
*/
package edge_controller
package edge
import (
"fmt"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
@@ -32,10 +31,10 @@ type versionOptions struct {
}
// newVersionCmd creates the command
func newVersionCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
func newVersionCmd(out io.Writer, errOut io.Writer) *cobra.Command {
options := &versionOptions{
edgeOptions: edgeOptions{
CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut},
CommonOptions: common.CommonOptions{Out: out, Err: errOut},
},
}
-26
View File
@@ -1,26 +0,0 @@
package edge_controller
import (
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/spf13/cobra"
"io"
)
// newListCmd creates a command object for the "controller list" command
func newDbCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "db",
Short: "Database management operations for the Ziti Edge Controller",
Run: func(cmd *cobra.Command, args []string) {
err := cmd.Help()
cmdhelper.CheckErr(err)
},
}
cmd.AddCommand(newDbSnapshotCmd(f, out, errOut))
cmd.AddCommand(newDbCheckIntegrityCmd(f, out, errOut))
cmd.AddCommand(newDbCheckIntegrityStatusCmd(f, out, errOut))
return cmd
}
-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 edge_controller
import (
"io"
"strings"
"github.com/Jeffail/gabs"
"github.com/openziti/ziti/ziti/cmd/ziti/cmd/common"
cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory"
cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers"
"github.com/openziti/ziti/ziti/cmd/ziti/util"
"github.com/spf13/cobra"
)
// newDeleteCmd creates a command object for the "edge controller delete" command
func newDeleteCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
cmd := &cobra.Command{
Use: "delete",
Short: "deletes various entities managed by the Ziti Edge Controller",
Long: "deletes various entities managed by the Ziti Edge Controller",
Run: func(cmd *cobra.Command, args []string) {
err := cmd.Help()
cmdhelper.CheckErr(err)
},
}
newOptions := func() *edgeOptions {
return &edgeOptions{
CommonOptions: common.CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
}
}
cmd.AddCommand(newDeleteCmdForEntityType("api-session", runDeleteEntityOfType, newOptions()))
cmd.AddCommand(newDeleteAuthenticatorCmd("authenticator", newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("ca", runDeleteEntityOfType, newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("config", runDeleteEntityOfType, newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("config-type", runDeleteEntityOfType, newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("edge-router", runDeleteEntityOfType, newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("edge-router-policy", runDeleteEntityOfType, newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("identity", runDeleteEntityOfType, newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("service", runDeleteEntityOfType, newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("service-edge-router-policy", runDeleteEntityOfType, newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("service-policy", runDeleteEntityOfType, newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("session", runDeleteEntityOfType, newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("terminator", runDeleteEntityOfType, newOptions()))
cmd.AddCommand(newDeleteCmdForEntityType("posture-check", runDeleteEntityOfType, newOptions()))
return cmd
}
type deleteCmdRunner func(*edgeOptions, string) error
// newDeleteCmdForEntityType creates the delete command for the given entity type
func newDeleteCmdForEntityType(entityType string, command deleteCmdRunner, options *edgeOptions) *cobra.Command {
cmd := &cobra.Command{
Use: entityType + " <id>",
Short: "deletes entity of type " + entityType + " managed by the Ziti Edge Controller",
Long: "deletes entity of type " + entityType + " managed by the Ziti Edge Controller",
Args: cobra.ExactArgs(1),
Run: func(cmd *cobra.Command, args []string) {
options.Cmd = cmd
options.Args = args
err := command(options, getPlural(entityType))
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 *edgeOptions, entityType string) error {
var err error
ids := []string{o.Args[0]}
if entityType != "terminators" && entityType != "api-sessions" && entityType != "sessions" {
ids, err = mapNamesToIDs(entityType, *o, o.Args[0])
}
if err != nil {
return err
}
for _, id := range ids {
_, err := util.EdgeControllerDelete(entityType, id, o.Out, o.OutputJSONResponse, o.Timeout, o.Verbose)
if err != nil {
return err
}
}
return nil
}
func getPlural(entityType string) string {
if strings.HasSuffix(entityType, "y") {
return strings.TrimSuffix(entityType, "y") + "ies"
}
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)
}
-1
View File
@@ -73,7 +73,6 @@ func NewCmdUpgrade(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Co
cmd.AddCommand(NewCmdUpgradeZitiMgmtGw(f, out, errOut))
cmd.AddCommand(NewCmdUpgradeZitiRouter(f, out, errOut))
cmd.AddCommand(NewCmdUpgradeZitiTunnel(f, out, errOut))
cmd.AddCommand(NewCmdUpgradeZitiEnroller(f, out, errOut))
cmd.AddCommand(NewCmdUpgradeZitiProxC(f, out, errOut))
cmd.AddCommand(NewCmdUpgradeZitiEdgeTunnel(f, out, errOut))
+6 -8
View File
@@ -19,11 +19,11 @@ package cmd
import (
"io"
"github.com/openziti/ziti/common/version"
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/common/version"
"github.com/spf13/cobra"
)
@@ -40,7 +40,7 @@ var (
// UpgradeZitiOptions the options for the create spring command
type UpgradeZitiOptions struct {
CreateOptions
CommonOptions
Version string
}
@@ -48,12 +48,10 @@ type UpgradeZitiOptions struct {
// NewCmdUpgradeZiti defines the command
func NewCmdUpgradeZiti(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &UpgradeZitiOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
}
+6 -8
View File
@@ -19,11 +19,11 @@ package cmd
import (
"io"
"github.com/openziti/ziti/common/version"
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/common/version"
"github.com/spf13/cobra"
)
@@ -40,7 +40,7 @@ var (
// UpgradeZitiControllerOptions the options for the upgrade ziti-controller command
type UpgradeZitiControllerOptions struct {
CreateOptions
CommonOptions
Version string
}
@@ -48,12 +48,10 @@ type UpgradeZitiControllerOptions struct {
// NewCmdUpgradeZitiController defines the command
func NewCmdUpgradeZitiController(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &UpgradeZitiControllerOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
}
@@ -40,7 +40,7 @@ var (
// UpgradeZitiEdgeTunnelOptions the options for the upgrade ziti-edge-tunnel command
type UpgradeZitiEdgeTunnelOptions struct {
CreateOptions
CommonOptions
Version string
}
@@ -48,12 +48,10 @@ type UpgradeZitiEdgeTunnelOptions struct {
// NewCmdUpgradeZitiEdgeTunnel defines the command
func NewCmdUpgradeZitiEdgeTunnel(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &UpgradeZitiEdgeTunnelOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
}
@@ -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/common/version"
"github.com/spf13/cobra"
)
var (
upgradeZitiEnrollerLong = templates.LongDesc(`
Upgrades the Ziti Enroller app if there is a newer release
`)
upgradeZitiEnrollerExample = templates.Examples(`
# Upgrades the Ziti Enroller app
ziti upgrade ziti-enroller
`)
)
// UpgradeZitiEnrollerOptions the options for the upgrade ziti-enroller command
type UpgradeZitiEnrollerOptions struct {
CreateOptions
Version string
}
// NewCmdUpgradeZitiEnroller defines the command
func NewCmdUpgradeZitiEnroller(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &UpgradeZitiEnrollerOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
},
}
cmd := &cobra.Command{
Use: "ziti-enroller",
Short: "Upgrades the Ziti Enroller app - if there is a new version available",
Aliases: []string{"enroller"},
Long: upgradeZitiEnrollerLong,
Example: upgradeZitiEnrollerExample,
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 upgrade to")
options.addCommonFlags(cmd)
return cmd
}
// Run implements the command
func (o *UpgradeZitiEnrollerOptions) Run() error {
newVersion, err := o.getLatestZitiAppVersion(version.GetBranch(), c.ZITI_ENROLLER)
if err != nil {
return err
}
newVersionStr := newVersion.String()
if o.Version != "" {
newVersionStr = o.Version
}
o.deleteInstalledBinary(c.ZITI_ENROLLER)
return o.installZitiApp(version.GetBranch(), c.ZITI_ENROLLER, true, newVersionStr)
}
+6 -8
View File
@@ -19,11 +19,11 @@ package cmd
import (
"io"
"github.com/openziti/ziti/common/version"
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/common/version"
"github.com/spf13/cobra"
)
@@ -40,7 +40,7 @@ var (
// UpgradeZitiFabricOptions the options for the upgrade ziti-fabric command
type UpgradeZitiFabricOptions struct {
CreateOptions
CommonOptions
Version string
}
@@ -48,12 +48,10 @@ type UpgradeZitiFabricOptions struct {
// NewCmdUpgradeZitiFabric defines the command
func NewCmdUpgradeZitiFabric(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &UpgradeZitiFabricOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
}
+6 -8
View File
@@ -19,11 +19,11 @@ package cmd
import (
"io"
"github.com/openziti/ziti/common/version"
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/common/version"
"github.com/spf13/cobra"
)
@@ -40,7 +40,7 @@ var (
// UpgradeZitiFabricTestOptions the options for the upgrade ziti-fabric-test command
type UpgradeZitiFabricTestOptions struct {
CreateOptions
CommonOptions
Version string
}
@@ -48,12 +48,10 @@ type UpgradeZitiFabricTestOptions struct {
// NewCmdUpgradeZitiFabricTest defines the command
func NewCmdUpgradeZitiFabricTest(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &UpgradeZitiFabricTestOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
}
+6 -8
View File
@@ -19,11 +19,11 @@ package cmd
import (
"io"
"github.com/openziti/ziti/common/version"
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/common/version"
"github.com/spf13/cobra"
)
@@ -40,7 +40,7 @@ var (
// UpgradeZitiMgmtGwOptions the options for the upgrade ziti-fabric-gw command
type UpgradeZitiMgmtGwOptions struct {
CreateOptions
CommonOptions
Version string
}
@@ -48,12 +48,10 @@ type UpgradeZitiMgmtGwOptions struct {
// NewCmdUpgradeZitiMgmtGw defines the command
func NewCmdUpgradeZitiMgmtGw(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &UpgradeZitiMgmtGwOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
}
+5 -7
View File
@@ -40,7 +40,7 @@ var (
// UpgradeZitiProxCOptions the options for the upgrade ziti-prox-c command
type UpgradeZitiProxCOptions struct {
CreateOptions
CommonOptions
Version string
}
@@ -48,12 +48,10 @@ type UpgradeZitiProxCOptions struct {
// NewCmdUpgradeZitiProxC defines the command
func NewCmdUpgradeZitiProxC(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &UpgradeZitiProxCOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
}
+6 -8
View File
@@ -19,11 +19,11 @@ package cmd
import (
"io"
"github.com/openziti/ziti/common/version"
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/common/version"
"github.com/spf13/cobra"
)
@@ -40,7 +40,7 @@ var (
// UpgradeZitiRouterOptions the options for the upgrade ziti-router command
type UpgradeZitiRouterOptions struct {
CreateOptions
CommonOptions
Version string
}
@@ -48,12 +48,10 @@ type UpgradeZitiRouterOptions struct {
// NewCmdUpgradeZitiRouter defines the command
func NewCmdUpgradeZitiRouter(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &UpgradeZitiRouterOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
}
+6 -8
View File
@@ -19,11 +19,11 @@ package cmd
import (
"io"
"github.com/openziti/ziti/common/version"
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/common/version"
"github.com/spf13/cobra"
)
@@ -40,7 +40,7 @@ var (
// UpgradeZitiTunnelOptions the options for the upgrade ziti-tunnel command
type UpgradeZitiTunnelOptions struct {
CreateOptions
CommonOptions
Version string
}
@@ -48,12 +48,10 @@ type UpgradeZitiTunnelOptions struct {
// NewCmdUpgradeZitiTunnel defines the command
func NewCmdUpgradeZitiTunnel(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command {
options := &UpgradeZitiTunnelOptions{
CreateOptions: CreateOptions{
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
CommonOptions: CommonOptions{
Factory: f,
Out: out,
Err: errOut,
},
}
+9 -27
View File
@@ -229,81 +229,63 @@ func (o *VersionOptions) versionCheckZitiApp(zitiApp string) error {
func (o *VersionOptions) upgradeZiti() error {
options := &UpgradeZitiOptions{
CreateOptions: CreateOptions{
CommonOptions: o.CommonOptions,
},
CommonOptions: o.CommonOptions,
}
return options.Run()
}
func (o *VersionOptions) upgradeZitiController() error {
options := &UpgradeZitiControllerOptions{
CreateOptions: CreateOptions{
CommonOptions: o.CommonOptions,
},
CommonOptions: o.CommonOptions,
}
return options.Run()
}
func (o *VersionOptions) upgradeZitiFabric() error {
options := &UpgradeZitiFabricOptions{
CreateOptions: CreateOptions{
CommonOptions: o.CommonOptions,
},
CommonOptions: o.CommonOptions,
}
return options.Run()
}
func (o *VersionOptions) upgradeZitiFabricTest() error {
options := &UpgradeZitiFabricTestOptions{
CreateOptions: CreateOptions{
CommonOptions: o.CommonOptions,
},
CommonOptions: o.CommonOptions,
}
return options.Run()
}
func (o *VersionOptions) upgradeZitiMgmtGw() error {
options := &UpgradeZitiMgmtGwOptions{
CreateOptions: CreateOptions{
CommonOptions: o.CommonOptions,
},
CommonOptions: o.CommonOptions,
}
return options.Run()
}
func (o *VersionOptions) upgradeZitiProxC() error {
options := &UpgradeZitiProxCOptions{
CreateOptions: CreateOptions{
CommonOptions: o.CommonOptions,
},
CommonOptions: o.CommonOptions,
}
return options.Run()
}
func (o *VersionOptions) upgradeZitiRouter() error {
options := &UpgradeZitiRouterOptions{
CreateOptions: CreateOptions{
CommonOptions: o.CommonOptions,
},
CommonOptions: o.CommonOptions,
}
return options.Run()
}
func (o *VersionOptions) upgradeZitiTunnel() error {
options := &UpgradeZitiTunnelOptions{
CreateOptions: CreateOptions{
CommonOptions: o.CommonOptions,
},
CommonOptions: o.CommonOptions,
}
return options.Run()
}
func (o *VersionOptions) upgradeZitiEdgeTunnel() error {
options := &UpgradeZitiEdgeTunnelOptions{
CreateOptions: CreateOptions{
CommonOptions: o.CommonOptions,
},
CommonOptions: o.CommonOptions,
}
return options.Run()
}
+134
View File
@@ -0,0 +1,134 @@
package tutorial
import (
"fmt"
"github.com/fatih/color"
"github.com/openziti/foundation/util/term"
"io"
"os"
"os/exec"
"strings"
)
func Exec(program string, colorStdout bool, args ...string) error {
p := exec.Command(program, args...)
stdErrWrapper := &WriterWrapper{
c: color.New(color.FgRed),
w: os.Stdout,
}
p.Stdin = os.Stdin
if colorStdout {
stdOutWrapper := &WriterWrapper{
c: color.New(color.FgBlue),
w: os.Stdout,
}
p.Stdout = stdOutWrapper
} else {
p.Stdout = os.Stdout
}
p.Stderr = stdErrWrapper
if err := p.Run(); err != nil {
return err
}
return nil
}
func Continue(prompt string, defaultValue bool) {
resp, err := AskYesNoWithDefault(prompt, defaultValue)
if err != nil {
fmt.Printf("\nerror: %v. exiting\n", err)
os.Exit(1)
}
if !resp {
fmt.Print("\nok, exiting\n")
os.Exit(0)
}
}
func AskYesNo(prompt string) (bool, error) {
filter := &yesNoFilter{}
if _, err := Ask(prompt, filter.Accept); err != nil {
return false, err
}
return filter.result, nil
}
func AskYesNoWithDefault(prompt string, defaultVal bool) (bool, error) {
filter := &yesNoDefaultFilter{
defaultVal: defaultVal,
}
if _, err := Ask(prompt, filter.Accept); err != nil {
return false, err
}
return filter.result, nil
}
func Ask(prompt string, f func(string) bool) (string, error) {
for {
val, err := term.Prompt(prompt)
if err != nil {
return "", err
}
val = strings.TrimSpace(val)
if f(val) {
return val, nil
}
fmt.Printf("Invalid input: %v\n", val)
}
}
type yesNoFilter struct {
result bool
}
func (self *yesNoFilter) Accept(s string) bool {
if strings.EqualFold("y", s) || strings.EqualFold("yes", s) {
self.result = true
return true
}
if strings.EqualFold("n", s) || strings.EqualFold("no", s) {
self.result = false
return true
}
return false
}
type yesNoDefaultFilter struct {
result bool
defaultVal bool
}
func (self *yesNoDefaultFilter) Accept(s string) bool {
if s == "" {
self.result = self.defaultVal
return true
}
if strings.EqualFold("y", s) || strings.EqualFold("yes", s) {
self.result = true
return true
}
if strings.EqualFold("n", s) || strings.EqualFold("no", s) {
self.result = false
return true
}
return false
}
type WriterWrapper struct {
c *color.Color
w io.Writer
}
func (self *WriterWrapper) Write(p []byte) (n int, err error) {
return self.c.Fprint(self.w, string(p))
}
+35
View File
@@ -0,0 +1,35 @@
package tutorial
import (
"strings"
"unicode"
)
func ParseArgumentsWithStrings(val string) []string {
var result []string
current := &strings.Builder{}
inString := false
for _, r := range val {
if r == '\'' {
if inString {
inString = false
} else {
inString = true
}
} else if !inString && unicode.IsSpace(r) {
if current.Len() > 0 {
result = append(result, current.String())
current.Reset()
}
} else {
current.WriteRune(r)
}
}
if current.Len() > 0 {
result = append(result, current.String())
}
return result
}
+37
View File
@@ -0,0 +1,37 @@
package tutorial
import (
"reflect"
"testing"
)
func TestParseArgumentsWithStrings(t *testing.T) {
tests := []struct {
name string
args string
want []string
}{
{
name: "one",
args: "one two three 'four five'",
want: []string{"one", "two", "three", "four five"},
},
{
name: "two",
args: " one two three 'four five' ",
want: []string{"one", "two", "three", "four five"},
},
{
name: "two",
args: " one two three 'four \"five\"' ",
want: []string{"one", "two", "three", "four \"five\""},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := ParseArgumentsWithStrings(tt.args); !reflect.DeepEqual(got, tt.want) {
t.Errorf("ParseArgumentsWithStrings() = %v, want %v", got, tt.want)
}
})
}
}
+315
View File
@@ -0,0 +1,315 @@
package tutorial
import (
"bytes"
"fmt"
markdown "github.com/MichaelMure/go-term-markdown"
"github.com/fatih/color"
"github.com/openziti/foundation/util/term"
"github.com/pkg/errors"
"github.com/valyala/fasttemplate"
"io"
"sort"
"strings"
"time"
)
const (
codeActionBlockStart = "```action:"
codeActionBlockEnd = "```"
commentActionBlockStart = "<!---action:"
commentActionBlockEnd = "-->"
actionMarker = "f572d396fae9206628714fb2ce00f72e94f2258f"
)
func NewRunner() *Runner {
result := &Runner{
actionHandlers: map[string]ActionHandler{},
variables: map[string]interface{}{},
LineWidth: 75,
LeftPad: 5,
NewLinePause: time.Millisecond * 20,
}
result.RegisterActionHandlerF("echo", func(ctx *ActionContext) error {
fmt.Printf("echo: %v", ctx.Body)
return nil
})
result.RegisterActionHandlerF("userInput", result.HandlePromptForInput)
result.RegisterActionHandlerF("pause", result.HandlePause)
return result
}
type ActionContext struct {
Action string
Headers map[string]string
Body string
Runner *Runner
}
type ActionHandler interface {
Execute(ctx *ActionContext) error
}
type ActionHandlerF func(ctx *ActionContext) error
func (self ActionHandlerF) Execute(ctx *ActionContext) error {
return self(ctx)
}
type Runner struct {
LineWidth int
LeftPad int
NewLinePause time.Duration
AssumeDefault bool
actionHandlers map[string]ActionHandler
actions []func() error
variables map[string]interface{}
}
func (self *Runner) AddVariable(name string, val interface{}) {
self.variables[name] = val
}
func (self *Runner) Run(source []byte) error {
markdownSource, err := self.transformSource(source)
if err != nil {
return err
}
renderedMarkdown := markdown.Render(string(markdownSource), self.LineWidth, self.LeftPad)
return self.runMarkdown(renderedMarkdown)
}
func (self *Runner) runMarkdown(source []byte) error {
fmt.Println("")
pauseWriter := NewSlowWriter(self.NewLinePause)
for {
next := bytes.Index(source, []byte(actionMarker))
if next < 0 {
if err := self.EmitTemplatized(string(source), pauseWriter); err != nil {
return err
}
fmt.Println("")
return nil
}
if next == 0 {
source = source[len(actionMarker):]
action := self.nextAction()
if err := action(); err != nil {
return err
}
} else {
md := source[0:next]
if err := self.EmitTemplatized(string(md), pauseWriter); err != nil {
return err
}
source = source[next:]
}
}
}
func (self *Runner) nextAction() func() error {
result := self.actions[0]
self.actions = self.actions[1:]
return result
}
func (self *Runner) transformSource(source []byte) ([]byte, error) {
var result []byte
for {
if len(source) == 0 {
return result, nil
}
var behavior parseBehavior
if CodeAction.IsStarting(source) {
behavior = CodeAction
} else if CommentAction.IsStarting(source) {
behavior = CommentAction
}
if behavior != nil {
source = source[len(behavior.GetStartToken()):]
endIndex := bytes.Index(source, []byte(behavior.GetEndToken()))
if endIndex < 0 {
return nil, errors.Errorf("no end %v found for action block", behavior.GetEndToken())
}
actionSource := source[:endIndex]
source = source[endIndex+len(behavior.GetEndToken()):]
var actionHeader, body string
nlIndex := bytes.IndexByte(actionSource, '\n')
if nlIndex < 1 {
actionHeader = string(actionSource)
} else {
actionHeader = strings.TrimSpace(string(actionSource[:nlIndex]))
body = strings.TrimSpace(string(actionSource[nlIndex+1 : endIndex]))
}
actionDef := strings.TrimSpace(actionHeader)
action, headers := self.parseAction(actionDef)
handler, ok := self.actionHandlers[action]
if !ok {
return nil, errors.Errorf("no handler found for action: %v. Available: %+v", action, self.actionIds())
}
ctx := &ActionContext{
Action: action,
Headers: headers,
Body: body,
Runner: self,
}
self.actions = append(self.actions, func() error {
return handler.Execute(ctx)
})
result = append(result, []byte(actionMarker)...)
} else {
result = append(result, source[0])
source = source[1:]
}
}
}
func (self *Runner) parseAction(s string) (string, map[string]string) {
var action string
headers := map[string]string{}
idx := strings.IndexByte(s, ' ')
if idx < 1 {
return s, headers
}
action = s[:idx]
rest := s[idx+1:]
for _, kv := range strings.Split(rest, " ") {
vals := strings.Split(kv, "=")
if len(vals) < 2 {
headers[vals[0]] = ""
} else {
headers[vals[0]] = vals[1]
}
}
return action, headers
}
func (self *Runner) actionIds() []string {
var result []string
for k := range self.actionHandlers {
result = append(result, k)
}
sort.Strings(result)
return result
}
func (self *Runner) RegisterActionHandler(action string, handler ActionHandler) {
self.actionHandlers[action] = handler
}
func (self *Runner) RegisterActionHandlerF(action string, handler func(ctx *ActionContext) error) {
self.actionHandlers[action] = ActionHandlerF(handler)
}
func (self *Runner) LeftPadBuilder(b *strings.Builder) {
for i := 0; i < self.LeftPad; i++ {
b.WriteRune(' ')
}
}
func (self *Runner) EmitTemplatized(s string, out io.Writer) error {
_, err := fasttemplate.ExecuteFunc(s, "${", "}", out, func(w io.Writer, tag string) (int, error) {
tag = strings.ReplaceAll(tag, "\n", "") // in case we hit a line-break
tag = strings.ReplaceAll(tag, " ", "") // in case we hit a line-break
val, ok := self.variables[tag]
if !ok {
return 0, errors.Errorf("unknown template value: '%v'", tag)
}
buf := []byte(fmt.Sprintf("%v", val))
return w.Write(buf)
})
return err
}
func (self *Runner) Template(s string) (string, error) {
buf := &strings.Builder{}
_, err := fasttemplate.ExecuteFunc(s, "${", "}", buf, func(w io.Writer, tag string) (int, error) {
val, ok := self.variables[tag]
if !ok {
return 0, errors.Errorf("unknown template value: '%v'", tag)
}
buf := []byte(fmt.Sprintf("%v", val))
return w.Write(buf)
})
return buf.String(), err
}
func (self *Runner) HandlePromptForInput(ctx *ActionContext) error {
varName, ok := ctx.Headers["variable"]
if !ok {
return errors.New("prompt must specify which variable to set")
}
var val string
var err error
for val == "" {
val, err = term.Prompt(ctx.Body + " ")
if err != nil {
return err
}
}
ctx.Runner.AddVariable(varName, val)
return nil
}
func (self *Runner) HandlePause(*ActionContext) error {
if !self.AssumeDefault {
c := color.New(color.FgHiWhite, color.Bold)
_, err := term.Prompt(c.Sprintf("Press enter to continue: "))
return err
}
return nil
}
type parseBehavior interface {
IsStarting(source []byte) bool
GetStartToken() string
GetEndToken() string
}
type CodeActionBlock struct{}
func (self CodeActionBlock) IsStarting(source []byte) bool {
return startsWith(source, []byte(codeActionBlockStart))
}
func (self CodeActionBlock) GetStartToken() string {
return codeActionBlockStart
}
func (self CodeActionBlock) GetEndToken() string {
return codeActionBlockEnd
}
type CommentActionBlock struct{}
func (self CommentActionBlock) IsStarting(source []byte) bool {
return startsWith(source, []byte(commentActionBlockStart))
}
func (self CommentActionBlock) GetStartToken() string {
return commentActionBlockStart
}
func (self CommentActionBlock) GetEndToken() string {
return commentActionBlockEnd
}
func startsWith(b []byte, val []byte) bool {
if len(b) < len(val) {
return false
}
return bytes.Equal(b[:len(val)], val)
}
var CodeAction = CodeActionBlock{}
var CommentAction = CommentActionBlock{}
+64
View File
@@ -0,0 +1,64 @@
package tutorial
import (
"fmt"
"github.com/alecthomas/chroma/quick"
"github.com/pkg/errors"
)
func NewShowActionHandler() *ShowActionHandler {
return &ShowActionHandler{
data: map[string]string{},
}
}
type ShowActionHandler struct {
data map[string]string
}
func (self *ShowActionHandler) Execute(ctx *ActionContext) error {
name, ok := ctx.Headers["src"]
if !ok {
return errors.New("no name specified in show")
}
content, ok := self.data[name]
if !ok {
return errors.Errorf("no contents found to show for name: '%v'", name)
}
if !ctx.Runner.AssumeDefault {
view, err := AskYesNoWithDefault(fmt.Sprintf("View source for %v? [Y/N] (default N): ", name), false)
if err != nil {
return err
}
if !view {
return nil
}
}
codeWriter := NewSlowWriter(ctx.Runner.NewLinePause)
fmt.Println("")
fmt.Printf("%v:\n", name)
for i := 0; i < 80; i++ {
fmt.Print("-")
}
fmt.Println("")
if lang, found := ctx.Headers["highlight"]; found {
if err := quick.Highlight(codeWriter, content, lang, "terminal", "friendly"); err != nil {
return err
}
} else {
_, _ = fmt.Fprintln(codeWriter, content)
}
for i := 0; i < 80; i++ {
fmt.Print("-")
}
fmt.Println("")
return ctx.Runner.HandlePause(ctx)
}
func (self *ShowActionHandler) Add(name, contents string) {
self.data[name] = contents
}
+43
View File
@@ -0,0 +1,43 @@
package tutorial
import (
"io"
"os"
"time"
)
func NewSlowWriter(newlinePause time.Duration) io.Writer {
return &slowWriter{
delay: newlinePause,
}
}
type slowWriter struct {
delay time.Duration
}
func (self *slowWriter) Write(p []byte) (n int, err error) {
var buf []byte
written := 0
for _, b := range p {
buf = append(buf, b)
if b == '\n' {
time.Sleep(self.delay)
n, err := os.Stdout.Write(buf)
buf = buf[0:0]
written += n
if err != nil {
return written, err
}
}
}
if len(buf) > 0 {
n, err := os.Stdout.Write(buf)
written += n
if err != nil {
return written, err
}
}
return written, nil
}
+1
View File
@@ -26,6 +26,7 @@ func (self *RestClientConfig) GetIdentity() string {
type RestClientIdentity struct {
Url string `json:"url"`
Username string `json:"username"`
Token string `json:"token"`
LoginTime string `json:"loginTime"`
Cert string `json:"cert,omitempty"`
+18 -7
View File
@@ -675,7 +675,7 @@ func EdgeControllerList(path string, params url.Values, logJSON bool, out io.Wri
}
resp, err := client.
SetTimeout(time.Duration(time.Duration(timeout)*time.Second)).
SetTimeout(time.Duration(timeout)*time.Second).
SetDebug(verbose).
R().
SetHeader("Content-Type", "application/json").
@@ -886,7 +886,7 @@ func (e EdgeManagementAuth) AuthenticateRequest(request openApiRuntime.ClientReq
}
// EdgeControllerCreate will create entities of the given type in the given Edge Controller
func EdgeControllerCreate(entityType string, body string, out io.Writer, logJSON bool, timeout int, verbose bool) (*gabs.Container, error) {
func EdgeControllerCreate(entityType string, body string, out io.Writer, logRequestJson, logResponseJson bool, timeout int, verbose bool) (*gabs.Container, error) {
restClientIdentity, err := LoadSelectedRWIdentity()
if err != nil {
return nil, err
@@ -897,6 +897,14 @@ func EdgeControllerCreate(entityType string, body string, out io.Writer, logJSON
if restClientIdentity.Cert != "" {
client.SetRootCertificate(restClientIdentity.Cert)
}
url := restClientIdentity.GetBaseUrl() + "/" + entityType
if logRequestJson {
fmt.Printf("%v to %v\n", "POST", url)
outputJson(out, []byte(body))
fmt.Println()
}
resp, err := client.
SetTimeout(time.Duration(timeout)*time.Second).
SetDebug(verbose).
@@ -904,7 +912,7 @@ func EdgeControllerCreate(entityType string, body string, out io.Writer, logJSON
SetHeader("Content-Type", "application/json").
SetHeader(constants.ZitiSession, restClientIdentity.Token).
SetBody(body).
Post(restClientIdentity.GetBaseUrl() + "/" + entityType)
Post(url)
if err != nil {
return nil, fmt.Errorf("unable to create %v instance in Ziti Edge Controller at %v. Error: %v", entityType, restClientIdentity.Url, err)
@@ -915,7 +923,7 @@ func EdgeControllerCreate(entityType string, body string, out io.Writer, logJSON
entityType, restClientIdentity.GetBaseUrl(), resp.Status(), prettyPrintResponse(resp))
}
if logJSON {
if logResponseJson {
outputJson(out, resp.Body())
}
@@ -929,7 +937,7 @@ func EdgeControllerCreate(entityType string, body string, out io.Writer, logJSON
}
// EdgeControllerDelete will delete entities of the given type in the given Edge Controller
func EdgeControllerDelete(entityType string, id string, out io.Writer, logJSON bool, timeout int, verbose bool) (*gabs.Container, error) {
func EdgeControllerDelete(entityType string, id string, out io.Writer, logResponseJson bool, timeout int, verbose bool) (*gabs.Container, error) {
restClientIdentity, err := LoadSelectedRWIdentity()
if err != nil {
return nil, err
@@ -960,7 +968,7 @@ func EdgeControllerDelete(entityType string, id string, out io.Writer, logJSON b
entityPath, restClientIdentity.GetBaseUrl(), resp.Status(), prettyPrintResponse(resp))
}
if logJSON {
if logResponseJson {
outputJson(out, resp.Body())
}
@@ -986,7 +994,10 @@ func EdgeControllerUpdate(entityType string, body string, out io.Writer, method
client.SetRootCertificate(restClientIdentity.Cert)
}
url := restClientIdentity.GetBaseUrl() + "/" + entityType
if logRequestJson {
fmt.Printf("%v to %v\n", method, url)
outputJson(out, []byte(body))
fmt.Println()
}
@@ -998,7 +1009,7 @@ func EdgeControllerUpdate(entityType string, body string, out io.Writer, method
SetHeader("Content-Type", "application/json").
SetHeader(constants.ZitiSession, restClientIdentity.Token).
SetBody(body).
Execute(method, restClientIdentity.GetBaseUrl()+"/"+entityType)
Execute(method, url)
if err != nil {
return nil, fmt.Errorf("unable to update %v instance in Ziti Edge Controller at %v. Error: %v", entityType, restClientIdentity.GetBaseUrl(), err)