diff --git a/.github/workflows/jenkins-smoketest.yml b/.github/workflows/jenkins-smoketest.yml new file mode 100644 index 000000000..d996bcf95 --- /dev/null +++ b/.github/workflows/jenkins-smoketest.yml @@ -0,0 +1,31 @@ +name: Jenkins Smoketest +on: + workflow_call: + inputs: + ziti_version: + description: 'Semantic Version from `ziti-ci -q get-current-version`' + type: string + required: false + workflow_dispatch: + inputs: + ziti_version: + description: 'Semantic Version from `ziti-ci -q get-current-version`' + type: string + required: false + +jobs: + jenkins-smoketest: + runs-on: ubuntu-latest + name: POST Webhook to Jenkinstest + steps: + - name: Trigger Smoketest + if: ${{ env.ZITI_JENKINS_WEBHOOK_URL != null }} + env: + ZITI_JENKINS_WEBHOOK_URL: ${{ secrets.ZITI_JENKINS_WEBHOOK_URL }} + uses: openziti/ziti-webhook-action@v2 + with: + ziti-id: ${{ secrets.ZITI_JENKINS_IDENTITY }} + webhook-url: ${{ secrets.ZITI_JENKINS_WEBHOOK_URL }} + webhook-secret: ${{ secrets.ZITI_JENKINS_WEBHOOK_SECRET }} + data: | + ziti-version=${{ github.event.inputs.ziti_version }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bafd63830..af218374d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -77,10 +77,12 @@ jobs: path: release/ retention-days: 5 - tag-and-publish: + linux-build: name: Build and Publish Linux Binaries and Docker Image runs-on: ubuntu-18.04 needs: [ mac-os-build, windows-build ] + outputs: + ziti_version: ${{ steps.get_version.outputs.ziti_version }} steps: - name: Git Checkout uses: actions/checkout@v2 @@ -136,17 +138,31 @@ jobs: $(go env GOPATH)/bin/ziti-ci tag -v -f version $(go env GOPATH)/bin/ziti-ci publish-to-github - - name: Trigger Smoketest - if: github.repository_owner == 'openziti' + - name: Get Ziti Version + id: get_version env: - JFROG_API_KEY: ${{ secrets.JFROG_API_KEY }} - jenkins_user: ${{ secrets.JENKINS_USER }} - jenkins_user_token: ${{ secrets.JENKINS_USER_TOKEN }} - jenkins_job_token: ${{ secrets.JENKINS_JOB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + ZITI_VERSION="$($(go env GOPATH)/bin/ziti-ci -q get-current-version)" + # drop the leading 'v', if any + ZITI_VERSION=${ZITI_VERSION#v} + if ! [[ "${ZITI_VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + # fail the job because we could not obtain the current version from ziti-ci + echo "ERROR: ZITI_VERSION=${ZITI_VERSION}" + exit 1 + else + # Set output parameters. + echo "DEBUG: ZITI_VERSION=${ZITI_VERSION}" + echo ::set-output name=ziti_version::${ZITI_VERSION} + fi + + - name: Publish to Artifactory + if: ${{ env.JFROG_API_KEY != null && github.repository == 'openziti/ziti' }} run: | $(go env GOPATH)/bin/ziti-ci publish-to-artifactory - $(go env GOPATH)/bin/ziti-ci trigger-jenkins-smoke-build + env: + JFROG_API_KEY: ${{ secrets.JFROG_API_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Set up QEMU if: github.repository_owner == 'openziti' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-v')) @@ -171,24 +187,16 @@ jobs: env: SNAPSHOT_REPO: openziti/ziti-tunnel RELEASE_REPO: netfoundry/ziti-tunnel + ZITI_VERSION: ${{ steps.get_version.outputs.ziti_version }} id: tagprep run: | # the Docker cross-build only runs on branches main or release-v* - # where ziti-ci always computes and pushes a new release tag - ZITI_VERSION="$($(go env GOPATH)/bin/ziti-ci -q get-current-version)" - # drop the leading 'v', if any - ZITI_VERSION=${ZITI_VERSION#v} + # where ziti-ci always computes and publishes a new release tag DOCKER_TAGS="" - if [[ "${ZITI_VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - for REPO in ${SNAPSHOT_REPO} ${RELEASE_REPO}; do - DOCKER_TAGS+=",${REPO}:${ZITI_VERSION},${REPO}:latest" - done - else - # fail the job because we could not obtain the current version from ziti-ci - exit 1 - fi - DOCKER_TAGS=${DOCKER_TAGS#,} # drop leading comma char, if exists - # Set output parameters. + for REPO in ${SNAPSHOT_REPO} ${RELEASE_REPO}; do + DOCKER_TAGS+=",${REPO}:${ZITI_VERSION},${REPO}:latest" + done + DOCKER_TAGS=${DOCKER_TAGS#,} # drop leading comma char echo "DEBUG: DOCKER_TAGS=${DOCKER_TAGS}" echo ::set-output name=tags::${DOCKER_TAGS} @@ -204,3 +212,20 @@ jobs: platforms: linux/amd64,linux/arm/v7,linux/arm64 push: true tags: ${{ steps.tagprep.outputs.tags }} + + # END linux-build-steps + + smoketest: + # BEGIN smoketest-job + # + # Any event that triggers this main workflow also triggers the smoketest steps, + # but only if at least one of the needed secrets is present. This avoids + # running job steps that can't succeed without the secrets e.g. in PR + # builds from repo forks. + # + needs: linux-build + if: ${{ github.repository == 'openziti/ziti' }} + name: Trigger Smoketest + uses: ./.github/workflows/jenkins-smoketest.yml + with: + ziti_version: ${{ needs.linux-build.outputs.ziti_version }} diff --git a/.github/workflows/mattermost-ziti-webhook.yml b/.github/workflows/mattermost-ziti-webhook.yml index 30b26c5c0..fb6d0802c 100644 --- a/.github/workflows/mattermost-ziti-webhook.yml +++ b/.github/workflows/mattermost-ziti-webhook.yml @@ -10,13 +10,14 @@ on: push: fork: release: + workflow_dispatch: jobs: mattermost-ziti-webhook: - runs-on: macos-latest + runs-on: ubuntu-latest name: POST Webhook steps: - - uses: openziti/ziti-webhook-action@main + - uses: openziti/ziti-webhook-action@v2 if: github.repository_owner == 'openziti' with: ziti-id: ${{ secrets.ZITI_MATTERMOST_IDENTITY }} diff --git a/.gitignore b/.gitignore index 8fe9a3062..3bab62e2e 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ linux-build *.log /build/ go.work +go.work.sum +.github/workflows/localtest.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 95a6ed5e1..747c22505 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,80 @@ +# Release 0.25.5 + +* Bug fix: Fixes an issue where dial could fail if the terminator router didn't response to routing last +* Enhancement: Updated Control Channel to use new heartbeat logging mirroring Links in Release `0.25.0` +* Enhancement: Added Circuit Creation Timespan which denotes how long the fabric took to construct a requested circuit. +```json +{ + "namespace": "namespace", + "event_type": "event_type", + "circuit_id": "circuit_id", + "timestamp": "2022-04-07T14:00:52.0500632-05:00", + "client_id": "client_id", + "service_id": "service_id", + "creation_timespan": 5000000, //Timespan in nanoseconds + "path": "path" +} +``` + +* Bug fix: Fixes an issue where Edge administrator checks would not take default admin flag into account +* Bug fix: Fix an issue with docker-compose quickstart not properly loading env vars +* Enhancement: Add support for Apple M1 using the ziti quickstart CLI script +* Enhancement: Use an env file for docker-compose quickstart for easier version changes and other duplicated field values +* Enhancement: Allow for version override using the ziti quickstart CLI script +* Change: Renamed `pushDevBuild.sh` to `buildLocalDev.sh`, the script used for building a local dev version of the docker quickstart image +* Bug fix: Fixes an issues where `isAdmin` would always default to false on updates (put/patch) +* Bug fix: Identity property `externalId` was not properly rendering on `GET` and not handled consistently on `PUT` and `PATCH` +* Enhancement: External JWT Signer Issuer & Audience Validation +* Enhancement: Add ability to define local interface binding for link and controller dial +* Bug fix: Edge Management REST API Doc shows Edge Client REST API Doc +* Enhancement: `ziti db explore ` command has been added to explore offline database files +* Enhancement: The mgmt API is now available via websocket. The stream commands are now available on `ziti fabric` +* Enhancement: Most list commands have been updated with tabular output +* Enhancement: `ziti edge show` is now available with subcommands `config` and `config-type` + * `ziti edge list configs` no longer shows the associated json. It can be viewed using `ziti edge show config ` +* Enhancement: `ziti edge update config-type` is now available +* Enhancement: `ziti edge create|update identity` now supports `--external-id` +* Bug fix: Fixes an issue where the router config would use hostname instead of the DNS name +* Bug fix: When establishing links, a link could be closed while being registered, leading the controlller and router to get out of sync +* Enhancement: Add min router cost. Helps to minimize unnecessary hops. + * Defaults to 10, configurable in the controller config with the minRouterCost value under `network:` +* Enhancement: Can now see xgress instance and link send buffer pointer values in circuit inspections. This allows correlating to stackdumps +* Enhancement: Can now see xgress related goroutines by using `ziti fabric inspect '.*' circuitAndStacks:` +* Enhancement: If a router connects to the controller but is already connected, the new connection now takes precedence + * There is a configurable churn limit, which limits how often this can happen. + * The default is 1 minute and is settable via `routerConnectChurnLimit` under `network` +* Enhancement: Flow control changes + * Duplicate acks won't shrink window. Duplicate acks imply retransmits and the retransmits already affect the window size + * Drop min round trip time scaling to 1.5 as will get scaled up as needed by duplicate ack detection + * Drop round trip time addition to 0 from 100ms and rely purely on scaling + * Avoid potential stall by always allowing at least one payload into sender side, even when receiver is full. + * This way if receiver signal to sender is lost, we'll still having something trying to send +* Enhancement: When router reconnects to controller, re-establish any embedded tunneler hosting on that router to ensure router and controller are in sync + + +## External JWT Signer Issuer & Audience Validation + +External JWT Signers (endpoint `/external-jwt-signers`) now support `issuer` and `audience` optional string fields. +These fields may be set to `null` on `POST`/`PUT`/`PATCH` or omitted; which will result in no validation of incoming +JWT's `aud` and `iss` fields. If `issuer` is defined, JWT `iss` fields will be validated. If `audience` is defined, JWT +`aud` fields will be validated. If a JWT contains multiple audience values as an array of strings and will be validated, +validation will check if the External JWT Signer's `audience` value is present as one of the values. + +## Add ability to define local interface binding for link and controller dial + +The network interface used to dial the controller and router links can be provided in the router configuration file. The interface can be provided as either a name or an IP address. + +```yaml +ctrl: + endpoint: tls:127.0.0.1:6262 + bind: wlp5s0 + +link: + dialers: + - binding: transport + bind: 192.168.1.11 +``` + # Release 0.25.4 **NOTE**: Link management is undergoing some restructuring to support better link costing and multiple interfaces. The link types introduced in 0.25 should not be used. A more complete replacement is coming soon. @@ -206,12 +283,12 @@ set to a valid external JWT signer and assigned to the target identity(ies). External JWT Signers can be managed on the following new REST Edge Management API endpoints: -- List `GET /edge/v1/management/ext-jwt-signers` -- Create `POST /edge/v1/management/ext-jwt-signers` -- Detail `GET /edge/v1/management/ext-jwt-signers/{id}` -- Replace `PUT /edge/v1/management/ext-jwt-signers/{id}` -- Patch `PATCH /edge/v1/management/ext-jwt-signers/{id}` -- Delete `Delete /edge/v1/management/ext-jwt-signers/{id}` +- List `GET /edge/v1/management/external-jwt-signers` +- Create `POST /edge/v1/management/external-jwt-signers` +- Detail `GET /edge/v1/management/external-jwt-signers/{id}` +- Replace `PUT /edge/v1/management/external-jwt-signers/{id}` +- Patch `PATCH /edge/v1/management/external-jwt-signers/{id}` +- Delete `Delete /edge/v1/management/external-jwt-signers/{id}` And support the following properties: @@ -225,7 +302,7 @@ And support the following properties: Example Create: -`POST /edge/v1/management/ext-jwt-signers` +`POST /edge/v1/management/external-jwt-signers` ```json { "certPem": "-----BEGIN CERTIFICATE-----\nMIIBizC ...", diff --git a/README.md b/README.md index f404f3401..a731cb50c 100644 --- a/README.md +++ b/README.md @@ -8,11 +8,11 @@ Ziti represents the next generation of secure, open-source networking for your a * [Local Deployment](https://github.com/openziti/ziti/blob/master/doc/003-local-deploy.md) * [Release Notes](https://github.com/openziti/ziti/blob/master/CHANGELOG.md) -## What is Ziti? -* The Ziti fabric provides a scalable, plugable, networking mesh with built in smart routing -* The Ziti edge components provide a secure, Zero Trust entry point into your network -* The Ziti SDKs allow you to integrate Ziti directly into your applications -* The Ziti tunnelers and proxies allow existing applications and networks to take advantage of a Ziti deployment +## What is OpenZiti? +* The OpenZiti fabric provides a scalable, plugable, networking mesh with built in smart routing +* The OpenZiti edge components provide a secure, Zero Trust entry point into your network +* The OpenZiti SDKs allow you to integrate Ziti directly into your applications +* The OpenZiti tunnelers and proxies allow existing applications and networks to take advantage of a Ziti deployment **Security Features** * Zero Trust and Application Segmentation @@ -25,7 +25,7 @@ Ziti represents the next generation of secure, open-source networking for your a **Developer Focus** * [Open source code, available with the Apache 2.0 license](https://github.com/openziti) -* Fully programable REST management APIs +* Fully programmable REST management APIs * [SDKs for a variety of programming languages](https://openziti.github.io/ziti/clients/sdks) * [Application specific configuration store allowing centralized management of configuration allowing you to add structured configuration specific to your application](https://openziti.github.io/ziti/config-store/overview) * An extensible fabric, allowing you to add your own @@ -76,8 +76,8 @@ End-to-end encryption means that even if systems between the client and server a ## Getting started with Ziti If you are looking to jump right in feet first you can follow along with one of our [up-and-running quickstart -guides](~/ziti/quickstarts/quickstart-overview.md). The quickstart will leverage Amazon Web Services (AWS) and will have you -launch an AMI which will get you up and running in no time. +guides](https://openziti.github.io/ziti/quickstarts/quickstart-overview.html). These guides are designed to get an +overlay network quickly and allow you to run it all locally, use docker or host it anywhere. This environment is perfect for evaluators to get to know Ziti and the capabilities it offers. The environement was not designed for large scale deployment or for long-term usage. If you are looking for a managed service to help you run a @@ -93,12 +93,13 @@ The Ziti project welcomes contributions including, but not limited to, code, doc * [foundation](https://github.com/openziti/foundation): project which contains library code used across multiple projects * SDKs * [ziti-sdk-c] (https://github.com/openziti/ziti-sdk-c): C SDK - * [ziti-sdk-csharp] (https://github.com/openziti/ziti-sdk-csharp): C# SDK + * [sdk-golang] (https://github.com/openziti/sdk-golang): Go SDK * [ziti-sdk-jvm] (https://github.com/openziti/ziti-sdk-jvm): SDK for JVM based languages * [ziti-sdk-swift] (https://github.com/openziti/ziti-sdk-swift): Swift SDK * [ziti-sdk-nodejs] (https://github.com/openziti/ziti-sdk-nodejs): NodeJS SDK - * [sdk-golang] (https://github.com/openziti/sdk-golang): Go SDK - * [ziti-doc](https://github.com/openziti/ziti-doc): Documention (which you are currently reading) -* A [Discourse forum](https://openziti.discourse.group/) is available + * [ziti-sdk-csharp] (https://github.com/openziti/ziti-sdk-csharp): C# SDK + * [ziti-doc](https://github.com/openziti/ziti-doc): Powers the static documentation site +* A [Discourse forum](https://openziti.discourse.group/) is available, jump in and ask questions! -Ziti was developed and open sourced by [Netfoundry, Inc](https://netfoundry.io). Netfoundry continues to fund and contribute to Ziti. +Ziti was developed and open sourced by [Netfoundry, Inc](https://netfoundry.io). NetFoundry continues to fund and +contribute to OpenZiti. diff --git a/apply-semver-tag.sh b/apply-semver-tag.sh deleted file mode 100755 index 1a92baf29..000000000 --- a/apply-semver-tag.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -# -# This script is invoked from the pre-bump-semver.sh script after a semver bump -# but before that bump is pushed back to the Git server. -# - -MANIFEST="common/version/VERSION" -declare -x SCRIPTPATH="${0}" -FULLPATH=${SCRIPTPATH%/*}/$MANIFEST - -if [ -f $FULLPATH ] -then - LINE=$(grep -o ${FULLPATH} -e '^[0]\.[0-9]*\.[0-9]*'); - IFS='.' read -r -a array <<< "$LINE" - $(git tag -a ${array[0]}.${array[1]}.${array[2]} -m "${array[0]}.${array[1]}.${array[2]}") -fi; diff --git a/bump-semver.sh b/bump-semver.sh deleted file mode 100755 index 178c8f53b..000000000 --- a/bump-semver.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -# -# This script is invoked from the pre-bump-semver.sh script if the following is true: -# 1) the branch involved is master -# 2) the most recent commit was a merge-commit -# -# What we do here is increment the "patch" level in the VERSION file -# - -MANIFEST="common/version/VERSION" -declare -x SCRIPTPATH="${0}" -FULLPATH=${SCRIPTPATH%/*}/$MANIFEST - -if [ -f $FULLPATH ] -then - LINE=$(grep -o ${FULLPATH} -e '^[0]\.[0-9]*\.[0-9]*'); - IFS='.' read -r -a array <<< "$LINE" - VERSION=(${array[2]}); - INCREMENTED=$(($VERSION+1)) - sed "s/${array[0]}\.${array[1]}\.${array[2]}/${array[0]}\.${array[1]}\.${INCREMENTED}/" $FULLPATH > $FULLPATH.tmp && mv $FULLPATH.tmp $FULLPATH -fi; diff --git a/common/enrollment/enroll.go b/common/enrollment/enroll.go index b1abef3a7..69a2d7303 100644 --- a/common/enrollment/enroll.go +++ b/common/enrollment/enroll.go @@ -34,6 +34,7 @@ import ( // global state used by all subcommands are located here for easy discovery var verbose bool +var removeJwt bool var keyAlg config.KeyAlgVar var jwtpath, outpath, keyPath, certPath, idname, caOverride, username, password string @@ -85,6 +86,7 @@ func NewEnrollCommand() *cobra.Command { enrollSubCmd.Flags().StringVarP(&caOverride, "ca", "", "", "Additional trusted certificates") enrollSubCmd.Flags().StringVarP(&username, "username", "u", "", "Username for updb enrollment, prompted if not provided and necessary") enrollSubCmd.Flags().StringVarP(&password, "password", "p", "", "Password for updb enrollment, prompted if not provided and necessary") + enrollSubCmd.Flags().BoolVar(&removeJwt, "rm", false, "Remove the JWT on success") keyAlg.Set("RSA") // set default enrollSubCmd.Flags().VarP(&keyAlg, "keyAlg", "a", "Crypto algorithm to use when generating private key") @@ -170,7 +172,13 @@ func processEnrollment() error { flags.Password = password } - return enroll.EnrollUpdb(flags) + err = enroll.EnrollUpdb(flags) + if err == nil { + if rmErr := os.Remove(jwtpath); rmErr != nil { + pfxlog.Logger().WithError(rmErr).Warnf("unable to remove JWT file as requested: %v", jwtpath) + } + } + return err } conf, err := enroll.Enroll(flags) @@ -188,6 +196,10 @@ func processEnrollment() error { enc.SetEscapeHTML(false) encErr := enc.Encode(&conf) + if err = os.Remove(jwtpath); err != nil { + pfxlog.Logger().WithError(err).Warnf("unable to remove JWT file as requested: %v", jwtpath) + } + if encErr == nil { pfxlog.Logger().Infof("enrolled successfully. identity file written to: %s", outpath) return nil diff --git a/etc/ctrl.with.edge.yml b/etc/ctrl.with.edge.yml index 8c892d5a3..f926847f7 100644 --- a/etc/ctrl.with.edge.yml +++ b/etc/ctrl.with.edge.yml @@ -1,5 +1,13 @@ v: 3 +network: + # Sets router minimum cost. Defaults to 10 + minRouterCost: 10 + + # Sets how often a new control channel connection can take over for a router with an existing control channel connection + # Defaults to 1 minute + routerConnectChurnLimit: 1m + #trace: # path: ctrl.trace diff --git a/etc/ctrl.yml b/etc/ctrl.yml index 9d54fd146..62b67fd12 100644 --- a/etc/ctrl.yml +++ b/etc/ctrl.yml @@ -44,7 +44,14 @@ identity: # running on the network. # cycleSeconds: 15 - # + + # Sets router minimum cost. Defaults to 10 + minRouterCost: 10 + + # Sets how often a new control channel connection can take over for a router with an existing control channel connection + # Defaults to 1 minute + routerConnectChurnLimit: 1m + #smart: # # Defines the fractional upper limit of underperforming circuits that are candidates to be re-routed. If diff --git a/go.mod b/go.mod index 27056f7ad..2bd36eecd 100644 --- a/go.mod +++ b/go.mod @@ -27,22 +27,23 @@ require ( github.com/fatih/color v1.13.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.23.3 + github.com/go-openapi/runtime v0.24.0 github.com/go-openapi/strfmt v0.21.2 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/protobuf v1.5.2 - github.com/google/go-cmp v0.5.7 + github.com/google/go-cmp v0.5.8 github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d github.com/jedib0t/go-pretty/v6 v6.2.4 github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19 github.com/michaelquigley/pfxlog v0.6.9 - github.com/openziti/channel v0.18.20 - github.com/openziti/edge v0.21.169 - github.com/openziti/fabric v0.17.88 + github.com/openziti/channel v0.18.29 + github.com/openziti/edge v0.21.200 + github.com/openziti/fabric v0.17.116 github.com/openziti/foundation v0.17.22 - github.com/openziti/sdk-golang v0.16.41 - github.com/openziti/storage v0.1.2 - github.com/openziti/transport v0.1.1 + github.com/openziti/sdk-golang v0.16.55 + github.com/openziti/storage v0.1.4 + github.com/openziti/transport v0.1.5 + github.com/openziti/ziti-db-explorer v1.1.1 github.com/pborman/uuid v1.2.0 github.com/pkg/errors v0.9.1 github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 @@ -57,6 +58,7 @@ require ( go.etcd.io/bbolt v1.3.6 golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd google.golang.org/grpc v1.42.0 + google.golang.org/protobuf v1.28.0 gopkg.in/AlecAivazis/survey.v1 v1.8.7 gopkg.in/resty.v1 v1.12.0 gopkg.in/yaml.v2 v2.4.0 @@ -66,13 +68,12 @@ require ( require ( github.com/AppsFlyer/go-sundheit v0.5.0 // indirect github.com/MichaelMure/go-term-text v0.3.1 // indirect - github.com/PuerkitoBio/purell v1.1.1 // indirect - github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect github.com/andybalholm/brotli v1.0.4 // indirect github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20211106181442-e4c1a74c66bd // indirect github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/biogo/store v0.0.0-20200525035639-8c94ae1e7c9c // indirect - github.com/cenkalti/backoff/v4 v4.1.2 // indirect + github.com/c-bata/go-prompt v0.2.6 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/coreos/go-iptables v0.6.0 // indirect github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -83,16 +84,16 @@ require ( github.com/docker/go-units v0.4.0 // indirect github.com/ef-ds/deque v1.0.4 // indirect github.com/eliukblau/pixterm/pkg/ansimage v0.0.0-20191210081756-9fb6cf8c2f75 // indirect - github.com/emirpasic/gods v1.12.0 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/felixge/httpsnoop v1.0.1 // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/analysis v0.21.2 // indirect github.com/go-openapi/errors v0.20.2 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.0 // indirect github.com/go-openapi/loads v0.21.1 // indirect - github.com/go-openapi/spec v0.20.4 // indirect + github.com/go-openapi/spec v0.20.6 // indirect github.com/go-openapi/swag v0.21.1 // indirect github.com/go-openapi/validate v0.21.0 // indirect github.com/go-stack/stack v1.8.1 // indirect @@ -101,7 +102,6 @@ require ( github.com/google/uuid v1.3.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/mux v1.8.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect @@ -120,13 +120,14 @@ require ( github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.12 // indirect + github.com/mattn/go-tty v0.0.3 // indirect github.com/mdlayher/netlink v1.6.0 // indirect github.com/mdlayher/socket v0.1.1 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect - github.com/miekg/dns v1.1.47 // indirect + github.com/miekg/dns v1.1.48 // indirect github.com/miekg/pkcs11 v1.1.1 // indirect github.com/mitchellh/go-ps v1.0.0 // indirect - github.com/mitchellh/mapstructure v1.4.3 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/natefinch/lumberjack v2.0.0+incompatible // indirect github.com/netfoundry/secretstream v0.1.2 // indirect github.com/oklog/ulid v1.3.1 // indirect @@ -135,8 +136,9 @@ require ( github.com/orcaman/concurrent-map v0.0.0-20210106121528-16402b402231 // indirect github.com/parallaxsecond/parsec-client-go v0.0.0-20220111122524-cb78842db373 // indirect github.com/pelletier/go-toml v1.9.4 // indirect + github.com/pkg/term v1.2.0-beta.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rivo/uniseg v0.2.0 // indirect + github.com/rodaine/table v1.0.1 // indirect github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect github.com/speps/go-hashids v2.0.0+incompatible // indirect github.com/spf13/afero v1.6.0 // indirect @@ -153,18 +155,23 @@ require ( github.com/yusufpapurcu/wmi v1.2.2 // indirect go.mongodb.org/mongo-driver v1.8.3 // indirect go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 // indirect - golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 // indirect + golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f // indirect golang.org/x/image v0.0.0-20191206065243-da761ea9ff43 // indirect golang.org/x/mod v0.5.1 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f // indirect - golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect + golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba // indirect + golang.org/x/term v0.0.0-20220411215600-e5f449aeb171 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/tools v0.1.7 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect - google.golang.org/protobuf v1.28.0 // indirect gopkg.in/ini.v1 v1.66.2 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) + +require ( + github.com/Jeffail/gabs/v2 v2.6.1 + github.com/gorilla/websocket v1.5.0 + github.com/rivo/uniseg v0.2.0 // indirect +) diff --git a/go.sum b/go.sum index 597921e83..ccf5bae23 100644 --- a/go.sum +++ b/go.sum @@ -55,7 +55,6 @@ 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/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= @@ -78,6 +77,7 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Jeffail/gabs v1.4.0 h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo= github.com/Jeffail/gabs v1.4.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= +github.com/Jeffail/gabs/v2 v2.6.1 h1:wwbE6nTQTwIMsMxzi6XFQQYRZ6wDc1mSdxoAN+9U4Gk= github.com/Jeffail/gabs/v2 v2.6.1/go.mod h1:xCn81vdHKxFUuWWAaD5jCTQDNPBMh5pPs9IJ+NcziBI= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= @@ -89,14 +89,10 @@ github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nB 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= github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87/go.mod h1:iGLljf5n9GjT6kc0HBvyI1nOKnGQbNB66VzSNbK5iks= -github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -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/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U= @@ -115,7 +111,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/aliyun/alibaba-cloud-sdk-go v1.61.458/go.mod h1:pUKYbK5JQ+1Dfxk80P0qxGqe5dkxDoabbZS7zOcouyA= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= @@ -130,15 +125,10 @@ github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= -github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.30.20/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= -github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= @@ -153,9 +143,11 @@ github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/c-bata/go-prompt v0.2.6 h1:POP+nrHE+DfLYx370bedwNhsqmpCUynWPxuHi0C5vZI= +github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdfpU9wwHfY= github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg= -github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= -github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -221,7 +213,6 @@ github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55k 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= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -232,8 +223,9 @@ 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/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -269,8 +261,6 @@ github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= -github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-acme/lego/v4 v4.2.0 h1:zEvpcDLqvzOlNUGBMA0MCKPpb9UBbnBzgWwCIbTEt2g= github.com/go-acme/lego/v4 v4.2.0/go.mod h1:jmhqxBaangB8txXZKjRLTPXFXUwPCTU2fU8S9/eQzBI= github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= @@ -286,110 +276,33 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= -github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= -github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= -github.com/go-openapi/analysis v0.19.4/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= -github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= -github.com/go-openapi/analysis v0.19.10/go.mod h1:qmhS3VNFxBlquFJ0RGoDtylO9y4pgTAUNE9AEEMdlJQ= -github.com/go-openapi/analysis v0.19.16/go.mod h1:GLInF007N83Ad3m8a/CbQ5TPzdnGT7workfHwuVjNVk= -github.com/go-openapi/analysis v0.20.0/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og= -github.com/go-openapi/analysis v0.20.1/go.mod h1:BMchjvaHDykmRMsK40iPtvyOfFdMMxlOmQr9FBZk+Og= github.com/go-openapi/analysis v0.21.2 h1:hXFrOYFHUAMQdu6zwAiKKJHJQ8kqZs1ux/ru1P1wLJU= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= -github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= -github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= -github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= -github.com/go-openapi/errors v0.19.3/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= -github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.1/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.20.2 h1:dxy7PGTqEh94zj2E3h1cUmQQWiM1+aeCROfAr02EmK8= github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= -github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= -github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= -github.com/go-openapi/loads v0.19.3/go.mod h1:YVfqhUCdahYwR3f3iiwQLhicVRvLlU/WO5WPaZvcvSI= -github.com/go-openapi/loads v0.19.5/go.mod h1:dswLCAdonkRufe/gSUC3gN8nTSaB9uaS2es0x5/IbjY= -github.com/go-openapi/loads v0.19.6/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= -github.com/go-openapi/loads v0.19.7/go.mod h1:brCsvE6j8mnbmGBh103PT/QLHfbyDxA4hsKvYBNEGVc= -github.com/go-openapi/loads v0.20.0/go.mod h1:2LhKquiE513rN5xC6Aan6lYOSddlL8Mp20AW9kpviM4= -github.com/go-openapi/loads v0.20.2/go.mod h1:hTVUotJ+UonAMMZsvakEgmWKgtulweO9vYP2bQYKA/o= -github.com/go-openapi/loads v0.21.0/go.mod h1:rHYve9nZrQ4CJhyeIIFJINGCg1tQpx2yJrrNo8sf1ws= +github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/loads v0.21.1 h1:Wb3nVZpdEzDTcly8S4HMkey6fjARRzb7iEaySimlDW0= github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= -github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= -github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= -github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= -github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= -github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= -github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= -github.com/go-openapi/runtime v0.21.0/go.mod h1:aQg+kaIQEn+A2CRSY1TxbM8+sT9g2V3aLc1FbIAnbbs= -github.com/go-openapi/runtime v0.23.3 h1:/dxjx4KCOQI5ImBMz036F6v/DzZ2NUjSRvbLJs1rgoE= -github.com/go-openapi/runtime v0.23.3/go.mod h1:AKurw9fNre+h3ELZfk6ILsfvPN+bvvlaU/M9q/r9hpk= -github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= -github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= -github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/spec v0.19.6/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= -github.com/go-openapi/spec v0.19.8/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= -github.com/go-openapi/spec v0.19.15/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= -github.com/go-openapi/spec v0.20.0/go.mod h1:+81FIL1JwC5P3/Iuuozq3pPE9dXdIEGxFutcFKaVbmU= -github.com/go-openapi/spec v0.20.1/go.mod h1:93x7oh+d+FQsmsieroS4cmR3u0p/ywH649a3qwC9OsQ= -github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg= -github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= +github.com/go-openapi/runtime v0.24.0 h1:vTgDijpGLCgJOJTdAp5kG+O+nRsVCbH417YQ3O0iZo0= +github.com/go-openapi/runtime v0.24.0/go.mod h1:AKurw9fNre+h3ELZfk6ILsfvPN+bvvlaU/M9q/r9hpk= github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= -github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= -github.com/go-openapi/strfmt v0.19.2/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= -github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= -github.com/go-openapi/strfmt v0.19.4/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= -github.com/go-openapi/strfmt v0.19.5/go.mod h1:eftuHTlB/dI8Uq8JJOyRlieZf+WkkxUuk0dgdHXr2Qk= -github.com/go-openapi/strfmt v0.19.11/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= -github.com/go-openapi/strfmt v0.20.0/go.mod h1:UukAYgTaQfqJuAFlNxxMWNvMYiwiXtLsF2VwmoFtbtc= -github.com/go-openapi/strfmt v0.20.2/go.mod h1:43urheQI9dNtE5lTZQfuFJvjYJKPrxicATpEfZwHUNk= +github.com/go-openapi/spec v0.20.6 h1:ich1RQ3WDbfoeTqTAb+5EIxNmpKVJZWBNah9RAT0jIQ= +github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= github.com/go-openapi/strfmt v0.21.2 h1:5NDNgadiX1Vhemth/TH4gCGopWSTdDjxl60H3B7f+os= github.com/go-openapi/strfmt v0.21.2/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.7/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= -github.com/go-openapi/swag v0.19.9/go.mod h1:ao+8BpOPyKdpQz3AOJfbeEVpLmWAvlT1IfTe5McPyhY= -github.com/go-openapi/swag v0.19.12/go.mod h1:eFdyEBkTdoAf/9RXBvj4cr1nH7GD8Kzo5HTt47gr72M= -github.com/go-openapi/swag v0.19.13/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU= github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= -github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= -github.com/go-openapi/validate v0.19.3/go.mod h1:90Vh6jjkTn+OT1Eefm0ZixWNFjhtOH7vS9k0lo6zwJo= -github.com/go-openapi/validate v0.19.10/go.mod h1:RKEZTUWDkxKQxN2jDT7ZnZi2bhZlbNMAuKvKB+IaGx8= -github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0waH08tGe6kAQ4= -github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI= -github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0= -github.com/go-openapi/validate v0.20.3/go.mod h1:goDdqVGiigM3jChcrYJxD2joalke3ZXeftD16byIjA4= github.com/go-openapi/validate v0.21.0 h1:+Wqk39yKOhfpLqNLEC0/eViCkzM5FVXVqrvt526+wcI= github.com/go-openapi/validate v0.21.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= @@ -488,8 +401,9 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-licenses v0.0.0-20201026145851-73411c8fa237/go.mod h1:g1VOUGKZYIqe8lDq2mL7plhAWXqrEaGUs7eIjthN1sk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= @@ -599,7 +513,7 @@ github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df/go.mod h1:QMZY7/J/KSQEhK github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb-client-go/v2 v2.2.2/go.mod h1:fa/d1lAdUHxuc1jedx30ZfNG573oQTQmUni3N6pcW+0= -github.com/influxdata/influxdb-client-go/v2 v2.8.1/go.mod h1:x7Jo5UHHl+w8wu8UnGiNobDDHygojXwJX4mx7rXGKMk= +github.com/influxdata/influxdb-client-go/v2 v2.8.2/go.mod h1:x7Jo5UHHl+w8wu8UnGiNobDDHygojXwJX4mx7rXGKMk= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d h1:/WZQPMZNsjZ7IlCpsLGdQBINg5bxKQ1K1sh6awxLtkA= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= @@ -615,8 +529,6 @@ github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -643,10 +555,8 @@ github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19 h1:WjT3fLi9n8YWh/Ih8Q1LHAPsTqGddPcHqscN+PJ3i68= github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19/go.mod h1:hY+WOq6m2FpbvyrI93sMaypsttvaIL5nhVR92dTMUcQ= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/kolo/xmlrpc v0.0.0-20200310150728-e0350524596b/go.mod h1:o03bZfuBwAXHetKXuInt4S7omeXUu62/A845kiycsSQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -658,7 +568,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -684,11 +593,9 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= -github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= @@ -720,11 +627,14 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= +github.com/mattn/go-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI= +github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mdlayher/netlink v1.6.0 h1:rOHX5yl7qnlpiVkFWoqccueppMtXzeziFjWAjLg6sz0= github.com/mdlayher/netlink v1.6.0/go.mod h1:0o3PlBmGst1xve7wQ7j/hwpNaFaH4qCRyWCdcZk8/vA= @@ -741,8 +651,8 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.47 h1:J9bWiXbqMbnZPcY8Qi2E3EWIBsIm6MZzzJB9VRg5gL8= -github.com/miekg/dns v1.1.47/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.48 h1:Ucfr7IIVyMBz4lRE8qmGUuZ4Wt3/ZGu9hmcMT3Uu4tQ= +github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -757,12 +667,11 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4 github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= @@ -809,27 +718,24 @@ github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openziti/channel v0.18.20 h1:tQC0VbJm54tp2E4+Grt7jjaomR9nK7egMi6AmfBp2oo= -github.com/openziti/channel v0.18.20/go.mod h1:P6hCAQuuhTA5UGCZZWK/tro4L8WN5exPocC7gyc+7Ms= +github.com/openziti/channel v0.18.29 h1:5di0d9tRg/leuN7o7gQwIVQuPZSnETjcUDIF5x5USM8= +github.com/openziti/channel v0.18.29/go.mod h1:YDGdH2I8tJ76WQgHTprgHX6dV9MBlrc1nOYpMY8h8+A= 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.21.169 h1:gCkgut6ntn10WYKAfybLbiLiKDDhH/SiTXrIITNif5o= -github.com/openziti/edge v0.21.169/go.mod h1:5iymsfUc7vMuBih80e2GDfy3sUMUM0oojJKHDzGMVmM= -github.com/openziti/fabric v0.17.88 h1:8cA0McXNgi4P7MN31TbwNUEC45DuQtII+VRe+ylGQyM= -github.com/openziti/fabric v0.17.88/go.mod h1:+5lGx6Pv9XeBa2AxT3s3skjbbL6gwvbbTuQAqOCnOAY= -github.com/openziti/foundation v0.17.20/go.mod h1:Nnr0vsqovHJimkdBHf2s4ZJAgvNhg6UdVqP+s0nY3P4= -github.com/openziti/foundation v0.17.21/go.mod h1:Nnr0vsqovHJimkdBHf2s4ZJAgvNhg6UdVqP+s0nY3P4= +github.com/openziti/edge v0.21.200 h1:V9EA2LrMeFLEtTdQfbU2A2dK1S8LyG0n6pO/yGdhXts= +github.com/openziti/edge v0.21.200/go.mod h1:6VxiwFTllM7Kns725R43wReUE8/ZDJe4gdzScfpQ4zs= +github.com/openziti/fabric v0.17.116 h1:CqhgO5QfXLFwWoxLteQY6z64LP0N25oK6U3gmxBFXg0= +github.com/openziti/fabric v0.17.116/go.mod h1:2FQTFPTFuObsu1xsMw3ZPnFH3HlEXHuG/k186y4ND/E= github.com/openziti/foundation v0.17.22 h1:zFfgNHdLocEcoBqtognpJnYsVQaTm28EwqMNjBw8avk= github.com/openziti/foundation v0.17.22/go.mod h1:Nnr0vsqovHJimkdBHf2s4ZJAgvNhg6UdVqP+s0nY3P4= -github.com/openziti/sdk-golang v0.16.40/go.mod h1:Xfz92DahfoAhfsx1FsAA0YnzwG/YHZaPaJTmZqWz8pk= -github.com/openziti/sdk-golang v0.16.41 h1:ZFFiTaxflJW3BsOpPfb404dzLgQFZD7tMhdTodMH+1I= -github.com/openziti/sdk-golang v0.16.41/go.mod h1:4M9NX/mUtRgfJoMTerdmZkVJvbAAEc4I/yN8Bf2ugYw= -github.com/openziti/storage v0.1.1/go.mod h1:UIQP0wcEx/sryPILk4Z1/71NbfJft3Gk8PkEAvar858= -github.com/openziti/storage v0.1.2 h1:CerlyWnfiZPrb8CVp4qOv4guQv+RVM78qFDKPVtEAL4= -github.com/openziti/storage v0.1.2/go.mod h1:UIQP0wcEx/sryPILk4Z1/71NbfJft3Gk8PkEAvar858= -github.com/openziti/transport v0.1.0/go.mod h1:2n6p2AZu3H9NzbJbQ7vOGFwtZKpvy8tIp+x+J7G5Sw0= -github.com/openziti/transport v0.1.1 h1:HaSr8H+1edEpQ60WN05+KBfSlq8B7U1G1tUxDuezMTw= -github.com/openziti/transport v0.1.1/go.mod h1:2n6p2AZu3H9NzbJbQ7vOGFwtZKpvy8tIp+x+J7G5Sw0= +github.com/openziti/sdk-golang v0.16.55 h1:LwIMjtwzTL37TuJN4OOZ3P7YO55rFG8HFc3EgDY8Uek= +github.com/openziti/sdk-golang v0.16.55/go.mod h1:kqMVnWbBx1OT9HCr/VeZX4JHspzrSVTCmGmjAEjrXZI= +github.com/openziti/storage v0.1.4 h1:horz3P0fABJH6R2Orvl2OLksmhXHpCaHP+0TCKfbGPM= +github.com/openziti/storage v0.1.4/go.mod h1:aMf2fqWAyXjXH7N0CxfpeGMrlLIDCT7nRSR3cGrsEoI= +github.com/openziti/transport v0.1.5 h1:+MgLyUDOsDdixm7GT9TgHd2pBIREf2AHsPa2D6mMNhY= +github.com/openziti/transport v0.1.5/go.mod h1:NK1wWR16q1IBgvItzruGtvDc2C7AaJpRQqryC2tGIgA= +github.com/openziti/ziti-db-explorer v1.1.1 h1:G0eoTby+aIjjt5TxEfR+FMI2CWd4RvZFjzaIMX2lEBw= +github.com/openziti/ziti-db-explorer v1.1.1/go.mod h1:h76h7Tsb+khb0v+CqYKL6ifUfJbUMjGBFU2IvupfBE4= 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= @@ -850,7 +756,6 @@ github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= @@ -863,6 +768,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/profile v1.5.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= +github.com/pkg/term v1.2.0-beta.2 h1:L3y/h2jkuBVFdWiJvNfYfKmzcCnILw7mJWm2JQuMppw= +github.com/pkg/term v1.2.0-beta.2/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -902,6 +809,8 @@ github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqn 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/rodaine/table v1.0.1 h1:U/VwCnUxlVYxw8+NJiLIuCxA/xa6jL38MY3FYysVWWQ= +github.com/rodaine/table v1.0.1/go.mod h1:UVEtfBsflpeEcD56nF4F5AocNFta0ZuolpSVdPtlmP4= 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= @@ -1024,7 +933,6 @@ github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPU 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= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/vultr/govultr/v2 v2.0.0/go.mod h1:2PsEeg+gs3p/Fo5Pw8F9mv+DUBEOlrNZ8GmCTGmhOhs= @@ -1032,8 +940,6 @@ github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0B github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= -github.com/xdg/stringprep v0.0.0-20180714160509-73f8eece6fdc/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= @@ -1060,14 +966,6 @@ go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3 go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= -go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= -go.mongodb.org/mongo-driver v1.3.0/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= -go.mongodb.org/mongo-driver v1.3.4/go.mod h1:MSWZXKOynuguX+JSvwP8i+58jYCXxbia8HS3gZBapIE= -go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= -go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= -go.mongodb.org/mongo-driver v1.4.6/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= -go.mongodb.org/mongo-driver v1.5.1/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= go.mongodb.org/mongo-driver v1.8.3 h1:TDKlTkGDKm9kkJVUOAXDK5/fkqKHJVwYQSpoRfB43R4= @@ -1105,15 +1003,11 @@ golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190418165655-df01cb2cc480/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= @@ -1131,8 +1025,9 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220321153916-2c7772ba3064/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o= -golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f h1:OeJjE6G4dgCY4PIXvIRQbE8+RX+uXZyGhUy/ksMGJoc= +golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1178,7 +1073,6 @@ golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1190,7 +1084,6 @@ golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1200,7 +1093,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL 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-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1217,7 +1109,6 @@ golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -1226,7 +1117,6 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= @@ -1296,7 +1186,6 @@ golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5h 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= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1305,7 +1194,6 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1344,6 +1232,8 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1380,12 +1270,15 @@ golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f h1:rlezHXNlxYWvBCzNses9Dlc7nGFaNMJeqLolcmQSSZY= golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba h1:AyHWHCBVlIYI5rgEM3o+1PLd0sLPcIAoaUckGQMaWtw= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.0.0-20220411215600-e5f449aeb171 h1:EH1Deb8WZJ0xc0WK//leUHXcX9aLE5SymusoTmMZye8= +golang.org/x/term v0.0.0-20220411215600-e5f449aeb171/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1407,9 +1300,7 @@ golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030000716-a0a13e073c7b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1423,8 +1314,6 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= diff --git a/pre-bump-semver.sh b/pre-bump-semver.sh deleted file mode 100755 index f8bd0ce6a..000000000 --- a/pre-bump-semver.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/sh -# -# If we are on the master branch, and the last commit was a merge commit -# then we have work to do. -# -# We need to auto-bump the semver. -# -# We will then commit the new semver file and publish it back to the repo, -# which will cause a new build to be done using the new semver. -# - -ENABLED_BRANCH=master - -BRANCH=$(git rev-parse --abbrev-ref HEAD) - -if [ "$BRANCH" = "$ENABLED_BRANCH" ] -then - - REV=$(git rev-parse --short HEAD 2> /dev/null) - MSHA=$(git rev-list -1 --merges ${REV}~1..${REV}) - if [ ! -z "$MSHA" ] - then - - # Ensure we are topped off - git pull origin $BRANCH > /dev/null 2>&1 - - # If the VERSION file was NOT updated as part of this commit (i.e. not manually updated due to branch having a breaking-change) - MODS=$(git diff --name-only --diff-filter=M @~..@) - VMOD=$(echo ${MODS} | grep common/version/VERSION) - if [ -z "$VMOD" ] - then - - # Auto-bump the semver - ./bump-semver.sh - - # Commit the new/bumped semver - git commit -am "semver bump" --no-verify > /dev/null 2>&1 - - # Lay down the tag for the new semver - ./apply-semver-tag.sh - - # Publish the bumped semver up into the repo so everyone receives it - git push origin HEAD > /dev/null 2>&1 - - # Publish the tags as well - git push origin --tags - - # Inform Makefile to stop executing and exit. The push that was performed above - # will cause another build to start, and it will do the entire build using the - # newly-bumped semver. - exit 200 - - # If the VERSION file WAS updated as part of this commit (i.e. it was manually updated due to branch having a breaking-change) - else - # Add/publish the tag for the new manually updated semver - ./apply-semver-tag.sh - git push origin --tags - fi - fi -fi - -exit 100 diff --git a/quickstart/docker/.env b/quickstart/docker/.env new file mode 100644 index 000000000..4222022e0 --- /dev/null +++ b/quickstart/docker/.env @@ -0,0 +1,5 @@ +# OpenZiti Variables +ZITI_IMAGE=openziti/quickstart +ZITI_VERSION=latest +ZITI_CONTROLLER_RAWNAME=ziti-controller +ZITI_EDGE_CONTROLLER_RAWNAME=ziti-edge-controller \ No newline at end of file diff --git a/quickstart/docker/README.md b/quickstart/docker/README.md index fa05e51aa..cd6f7023a 100644 --- a/quickstart/docker/README.md +++ b/quickstart/docker/README.md @@ -4,8 +4,8 @@ Building and Deploying the Latest Quickstart Docker Image Build Docker Image for Local Dev (probably for docker-compose testing) ------------------ 1. change to this directory: `cd quickstart/docker` -2. run the questionably named `./pushDevBuild.sh` which will create a `openziti/quickstart:dev` tag -3. update `docker-compose.yml` and replace `:latest` with `:dev` +2. run the script `./buildLocalDev.sh` which will create a `openziti/quickstart:dev` tag +3. update `.env` and change the value for `ZITI_VERSION` to `dev` 4. run `docker-compose` as normal Build Docker Image For Publication @@ -22,6 +22,5 @@ Build Docker Image For Publication 2. Push Docker Image to dockerhub ------------------ -1. retag the image locally to match the expected version: `docker push openziti/quickstart:0.19.3` -1. push the latest: `docker push openziti/quickstart` -1. push the versioned tag: `docker push openziti/quickstart:0.19.3` +1. `source ./image/ziti-cli-functions.sh` +1. just run `./pushLatestDocker.sh` \ No newline at end of file diff --git a/quickstart/docker/all.localhost.env b/quickstart/docker/all.localhost.env deleted file mode 100644 index 482f78eb9..000000000 --- a/quickstart/docker/all.localhost.env +++ /dev/null @@ -1,3 +0,0 @@ -ZITI_CONTROLLER_RAWNAME=localhost -ZITI_EDGE_CONTROLLER_RAWNAME=localhost -ZITI_ZAC_RAWNAME=localhost diff --git a/quickstart/docker/attach.container.to.compose.sh b/quickstart/docker/attach.container.to.compose.sh index ae92d8bde..869485d01 100644 --- a/quickstart/docker/attach.container.to.compose.sh +++ b/quickstart/docker/attach.container.to.compose.sh @@ -1 +1 @@ -docker run --network docker_zitiblue --rm -it openziti/quickstart /bin/bash +docker run -v docker_ziti-fs:/openziti --network docker_zitiblue --rm -it openziti/quickstart /bin/bash diff --git a/quickstart/docker/pushDevBuild.sh b/quickstart/docker/buildLocalDev.sh old mode 100644 new mode 100755 similarity index 62% rename from quickstart/docker/pushDevBuild.sh rename to quickstart/docker/buildLocalDev.sh index 6af87a550..8dc9a0bad --- a/quickstart/docker/pushDevBuild.sh +++ b/quickstart/docker/buildLocalDev.sh @@ -1,9 +1,31 @@ #!/usr/bin/env bash set -eo pipefail +echo "${SHELL}" + +# This method is required for users bash prior to version 4. More specifically this is to support Mac users as Mac uses +# an older version of bash. +myrealpath() { + OURPWD=$PWD + cd "$(dirname "$1")" + LINK=$(readlink "$(basename "$1")") + while [ "$LINK" ]; do + cd "$(dirname "$LINK")" + LINK=$(readlink "$(basename "$1")") + done + REALPATH="$PWD/$(basename "$1")" + cd "$OURPWD" + echo "$REALPATH" +} + SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" -ZITI_QUICKSTART_ROOT="$(realpath ${SCRIPT_DIR}/..)" -ZITI_ROOT="$(realpath ${ZITI_QUICKSTART_ROOT}/..)" +if [ "${BASH_VERSINFO:-0}" -lt 4 ]; then + ZITI_QUICKSTART_ROOT="$(myrealpath "${SCRIPT_DIR}"/..)" + ZITI_ROOT="$(myrealpath "${ZITI_QUICKSTART_ROOT}"/..)" +else + ZITI_QUICKSTART_ROOT="$(realpath "${SCRIPT_DIR}"/..)" + ZITI_ROOT="$(realpath "${ZITI_QUICKSTART_ROOT}"/..)" +fi ZITI_DOCKER_ROOT="${ZITI_QUICKSTART_ROOT}/docker" echo "SCRIPT_DIR :$SCRIPT_DIR" diff --git a/quickstart/docker/default.env b/quickstart/docker/default.env deleted file mode 100644 index 1c8441c14..000000000 --- a/quickstart/docker/default.env +++ /dev/null @@ -1,3 +0,0 @@ -ZITI_CONTROLLER_RAWNAME=ziti-controller -ZITI_EDGE_CONTROLLER_RAWNAME=ziti-edge-controller -ZITI_ZAC_RAWNAME=ziti-zac diff --git a/quickstart/docker/docker-compose.yml b/quickstart/docker/docker-compose.yml index 227e6099e..801b84300 100644 --- a/quickstart/docker/docker-compose.yml +++ b/quickstart/docker/docker-compose.yml @@ -1,9 +1,9 @@ version: '2.4' services: ziti-controller: - image: openziti/quickstart:latest + image: "${ZITI_IMAGE}:${ZITI_VERSION}" env_file: - - ./default.env + - ./.env ports: - "1280:1280" networks: @@ -19,10 +19,12 @@ services: - "/openziti/scripts/run-controller.sh" ziti-edge-router: - image: openziti/quickstart:latest + image: "${ZITI_IMAGE}:${ZITI_VERSION}" + depends_on: + - ziti-controller environment: - - ZITI_CONTROLLER_RAWNAME=ziti-controller - - ZITI_EDGE_CONTROLLER_RAWNAME=ziti-edge-controller + - ZITI_CONTROLLER_RAWNAME="${ZITI_CONTROLLER_RAWNAME}" + - ZITI_EDGE_CONTROLLER_RAWNAME="${ZITI_EDGE_CONTROLLER_RAWNAME}" - ZITI_EDGE_ROUTER_RAWNAME=ziti-edge-router ports: - "3022:3022" @@ -35,10 +37,12 @@ services: command: "/openziti/scripts/run-router.sh edge" ziti-edge-router-wss: - image: openziti/quickstart:latest + image: "${ZITI_IMAGE}:${ZITI_VERSION}" + depends_on: + - ziti-controller environment: - - ZITI_CONTROLLER_RAWNAME=ziti-controller - - ZITI_EDGE_CONTROLLER_RAWNAME=ziti-edge-controller + - ZITI_CONTROLLER_RAWNAME="${ZITI_CONTROLLER_RAWNAME}" + - ZITI_EDGE_CONTROLLER_RAWNAME="${ZITI_EDGE_CONTROLLER_RAWNAME}" - ZITI_EDGE_ROUTER_RAWNAME=ziti-edge-router-wss - ZITI_EDGE_ROUTER_PORT=3023 ports: @@ -52,10 +56,12 @@ services: command: "/openziti/scripts/run-router.sh wss" ziti-fabric-router-br: - image: openziti/quickstart:latest + image: "${ZITI_IMAGE}:${ZITI_VERSION}" + depends_on: + - ziti-controller environment: - - ZITI_CONTROLLER_RAWNAME=ziti-controller - - ZITI_EDGE_CONTROLLER_RAWNAME=ziti-edge-controller + - ZITI_CONTROLLER_RAWNAME="${ZITI_CONTROLLER_RAWNAME}" + - ZITI_EDGE_CONTROLLER_RAWNAME="${ZITI_EDGE_CONTROLLER_RAWNAME}" - ZITI_EDGE_ROUTER_RAWNAME=ziti-fabric-router-br #ports: # - 3024:3024 @@ -68,10 +74,12 @@ services: command: "/openziti/scripts/run-router.sh fabric" ziti-private-red: - image: openziti/quickstart:latest + image: "${ZITI_IMAGE}:${ZITI_VERSION}" + depends_on: + - ziti-controller environment: - - ZITI_CONTROLLER_RAWNAME=ziti-controller - - ZITI_EDGE_CONTROLLER_RAWNAME=ziti-edge-controller + - ZITI_CONTROLLER_RAWNAME="${ZITI_CONTROLLER_RAWNAME}" + - ZITI_EDGE_CONTROLLER_RAWNAME="${ZITI_EDGE_CONTROLLER_RAWNAME}" - ZITI_EDGE_ROUTER_RAWNAME=ziti-private-red #ports: # - 3025:3025 @@ -83,10 +91,12 @@ services: command: "/openziti/scripts/run-router.sh private" ziti-private-blue: - image: openziti/quickstart:latest + image: "${ZITI_IMAGE}:${ZITI_VERSION}" + depends_on: + - ziti-controller environment: - - ZITI_CONTROLLER_RAWNAME=ziti-controller - - ZITI_EDGE_CONTROLLER_RAWNAME=ziti-edge-controller + - ZITI_CONTROLLER_RAWNAME="${ZITI_CONTROLLER_RAWNAME}" + - ZITI_EDGE_CONTROLLER_RAWNAME="${ZITI_EDGE_CONTROLLER_RAWNAME}" - ZITI_EDGE_ROUTER_RAWNAME=ziti-private-blue #ports: # - 3026:3026 @@ -112,10 +122,11 @@ services: image: openziti/zac environment: - ZAC_SERVER_CERT_CHAIN=/openziti/pki/ziti-controller-intermediate/certs/ziti-controller-server.cert - - ZAC_SERVER_KEY=/openziti/pki/ziti-controller-intermediate/keys/ziti-controller-server.key -it + - ZAC_SERVER_KEY=/openziti/pki/ziti-controller-intermediate/keys/ziti-controller-server.key ports: - "1408:1408" - "8443:8443" + working_dir: /usr/src/app volumes: - ziti-fs:/openziti @@ -125,8 +136,9 @@ services: networks: zitired: + driver: bridge zitiblue: - + driver: bridge volumes: ziti-fs: diff --git a/quickstart/docker/image/run-controller.sh b/quickstart/docker/image/run-controller.sh index 55d99abba..de06f3c2c 100755 --- a/quickstart/docker/image/run-controller.sh +++ b/quickstart/docker/image/run-controller.sh @@ -20,9 +20,4 @@ createControllerConfig # create a place for the internal db mkdir -p $ZITI_HOME/db -#"${ZITI_SCRIPTS}/create-fabric-identity.sh" -createFabricIdentity - "${ZITI_BIN_DIR}/ziti-controller" run "${ZITI_HOME}/ziti-edge-controller.yaml" - -${ZITI_HOME}/pki/ziti-controller-intermediate/keys/ziti-dotzeet.key diff --git a/quickstart/docker/image/run-router.sh b/quickstart/docker/image/run-router.sh old mode 100644 new mode 100755 index bb92f3595..ce98e425a --- a/quickstart/docker/image/run-router.sh +++ b/quickstart/docker/image/run-router.sh @@ -42,12 +42,16 @@ if [[ "$1" == "private" ]]; then fi echo "---------- Creating edge-router ${ZITI_EDGE_ROUTER_HOSTNAME}...." -"${ZITI_BIN_DIR}/ziti" edge delete edge-router "${ZITI_EDGE_ROUTER_HOSTNAME}" -"${ZITI_BIN_DIR}/ziti" edge create edge-router "${ZITI_EDGE_ROUTER_HOSTNAME}" -o "${ZITI_HOME}/${ZITI_EDGE_ROUTER_HOSTNAME}.jwt" -t -a "${ZITI_EDGE_ROUTER_ROLES}" -sleep 1 -echo "---------- Enrolling edge-router ${ZITI_EDGE_ROUTER_HOSTNAME}...." -"${ZITI_BIN_DIR}/ziti-router" enroll "${ZITI_HOME}/${ZITI_EDGE_ROUTER_HOSTNAME}.yaml" --jwt "${ZITI_HOME}/${ZITI_EDGE_ROUTER_HOSTNAME}.jwt" -echo "" +found=$(ziti edge list edge-routers 'name = "'"${ZITI_EDGE_ROUTER_HOSTNAME}"'"' | grep -c "${ZITI_EDGE_ROUTER_HOSTNAME}") +if [[ found -gt 0 ]]; then + echo "---------- Found existing edge-router ${ZITI_EDGE_ROUTER_HOSTNAME}...." +else + "${ZITI_BIN_DIR}/ziti" edge create edge-router "${ZITI_EDGE_ROUTER_HOSTNAME}" -o "${ZITI_HOME}/${ZITI_EDGE_ROUTER_HOSTNAME}.jwt" -t -a "${ZITI_EDGE_ROUTER_ROLES}" + sleep 1 + echo "---------- Enrolling edge-router ${ZITI_EDGE_ROUTER_HOSTNAME}...." + "${ZITI_BIN_DIR}/ziti-router" enroll "${ZITI_HOME}/${ZITI_EDGE_ROUTER_HOSTNAME}.yaml" --jwt "${ZITI_HOME}/${ZITI_EDGE_ROUTER_HOSTNAME}.jwt" + echo "" +fi "${ZITI_BIN_DIR}/ziti-router" run "${ZITI_HOME}/${ZITI_EDGE_ROUTER_RAWNAME}.yaml" > "${ZITI_HOME}/ziti-${ZITI_EDGE_ROUTER_HOSTNAME}.log" diff --git a/quickstart/docker/image/ziti-cli-functions.sh b/quickstart/docker/image/ziti-cli-functions.sh old mode 100644 new mode 100755 index cd6f027a4..b5b1b8366 --- a/quickstart/docker/image/ziti-cli-functions.sh +++ b/quickstart/docker/image/ziti-cli-functions.sh @@ -127,6 +127,36 @@ function checkHostsFile { fi } +function verifyZitiVersionExists { + setupZitiHome + + if ! setOs; then + return 1 + fi + + ZITI_ARCH="amd64" + if [[ "$(uname -a)" == *"arm"* ]] && [[ "${ZITI_OSTYPE}" == "darwin" ]]; then + echo -e "$(YELLOW "WARN: It has been detected that you are using an Apple computer with ARM architecture. Deployment of Apple ARM architecture distributions is currently unsupported through git, the installer will pull darwin amd distribution instead.")" + elif [[ "$(uname -a)" == *"arm"* ]]; then + ZITI_ARCH="arm" + fi + + unset ZITI_BINARIES_VERSION + + ziticurl="$(curl -s https://api.github.com/repos/openziti/ziti/releases/tags/"${ZITI_VERSION_OVERRIDE}")" + # shellcheck disable=SC2155 + export ZITI_BINARIES_FILE=$(echo "${ziticurl}" | tr '\r\n' ' ' | jq -r '.assets[] | select(.name | startswith("'"ziti-${ZITI_OSTYPE}-${ZITI_ARCH}"'")) | .name') + # shellcheck disable=SC2155 + export ZITI_BINARIES_VERSION=$(echo "${ziticurl}" | tr '\r\n' ' ' | jq -r '.tag_name') + + # Check if there was an error while trying to get the requested version + if [[ "${ZITI_BINARIES_VERSION-}" == "null" ]]; then + return 1 + fi + + echo "ZITI_BINARIES_VERSION: ${ZITI_BINARIES_VERSION}" +} + function getLatestZitiVersion { setupZitiHome @@ -135,7 +165,9 @@ function getLatestZitiVersion { fi ZITI_ARCH="amd64" - if [[ "$(uname -a)" == *"arm"* ]]; then + if [[ "$(uname -a)" == *"arm"* ]] && [[ "${ZITI_OSTYPE}" == "darwin" ]]; then + echo -e "$(YELLOW "WARN: It has been detected that you are using an Apple computer with ARM architecture. Deployment of Apple ARM architecture distributions is currently unsupported through git, the installer will pull darwin amd distribution instead.")" + elif [[ "$(uname -a)" == *"arm"* ]]; then ZITI_ARCH="arm" fi @@ -151,7 +183,7 @@ function getLatestZitiVersion { echo "ZITI_BINARIES_VERSION: ${ZITI_BINARIES_VERSION}" } -function getLatestZiti { +function getZiti { setupZitiHome checkEnvVariable ZITI_HOME retVal=$? @@ -167,8 +199,17 @@ function getLatestZiti { mkdir -p "${ziti_bin_root}" - if ! getLatestZitiVersion; then - return 1 + # Get the latest version unless a specific version is specified + if [[ "${ZITI_VERSION_OVERRIDE-}" == "" ]]; then + if ! getLatestZitiVersion; then + return 1 + fi + else + # Check if an error occurred while trying to pull desired version (happens with incorrect version or formatting issue) + if ! verifyZitiVersionExists; then + echo -e " * $(RED "ERROR: This version of ziti (${ZITI_VERSION_OVERRIDE}) could not be found. Please check the version and try again. The version should follow the format \"vx.x.x\".") " + return 1 + fi fi if [[ "${ZITI_BIN_DIR-}" == "" ]]; then export ZITI_BIN_DIR="${ziti_bin_root}/ziti-${ZITI_BINARIES_VERSION}"; else echo "Using ZITI_BIN_DIR: ${ZITI_BIN_DIR}"; fi @@ -325,12 +366,12 @@ function generateEnvFile { export ZITI_BIN_ROOT="${ZITI_HOME-}/ziti-bin" fi + export ENV_FILE="${ZITI_HOME-}/${ZITI_NETWORK-}.env" + if ! ziti_createEnvFile; then return 1 fi - export ENV_FILE="${ZITI_HOME-}/${ZITI_NETWORK-}.env" - echo -e "environment file sourced from: $(BLUE "${ENV_FILE}")" } @@ -342,7 +383,37 @@ function ziti_expressConfiguration { echo " " if [[ "${REPLY}" == [Yy]* ]]; then echo -e "$(GREEN "Clearing existing Ziti variables and continuing with express install")" + + # Check if the user chose a specific version + specifiedVersion="" + if [[ "${ZITI_VERSION_OVERRIDE-}" != "" ]] && [[ "${ZITI_VERSION_OVERRIDE-}" != "${ZITI_BINARIES_VERSION-}" ]]; then + # Don't allow overriding the version if ziti quickstart was already run, the DB may not be compatible + echo -e "$(RED " --- Overriding the ziti version is not supported if the version differs from one already installed. ---")" + echo -en "Would you like to continue by using the latest version. (y/N)?" + read -r + echo " " + if [[ "${REPLY}" == [Yy]* ]]; then + unset ZITI_VERSION_OVERRIDE + else + return 1 + fi + elif [[ "${ZITI_VERSION_OVERRIDE-}" != "" ]]; then + echo -e "$(RED " --- You have set the ZITI_VERSION_OVERRIDE value to ${ZITI_VERSION_OVERRIDE}. ---")" + echo -en "Would you like to use this version again, choosing no will pull the latest version. (y/N)?" + read -r + echo " " + if [[ "${REPLY}" == [Yy]* ]]; then + specifiedVersion="${ZITI_VERSION_OVERRIDE}" + fi + fi + + # Silently clear ziti variables unsetZitiEnv "-s" + + if [[ "${specifiedVersion}" != "" ]]; then + export ZITI_VERSION_OVERRIDE="${specifiedVersion}" + fi + # Stop any devices currently running to avoid port collisions stopAllEdgeRouters stopZitiController @@ -384,8 +455,8 @@ function ziti_expressConfiguration { setupZitiHome echo -e "ZITI HOME SET TO: $(BLUE "${ZITI_HOME}")" - if ! getLatestZiti "no"; then - echo -e "$(RED "getLatestZiti failed")" + if ! getZiti "no"; then + echo -e "$(RED "getZiti failed")" return 1 fi if ! generateEnvFile; then @@ -701,20 +772,9 @@ function createPki { pki_create_intermediate "${ZITI_SIGNING_ROOTCA_NAME}" "${ZITI_SPURIOUS_INTERMEDIATE}" 2 pki_create_intermediate "${ZITI_SPURIOUS_INTERMEDIATE}" "${ZITI_SIGNING_INTERMEDIATE_NAME}" 1 - if ! test -f "${ZITI_PKI}/${ZITI_CONTROLLER_INTERMEDIATE_NAME}/keys/${ZITI_NETWORK-}-dotzeet.key"; then - echo "Creating ziti-fabric client certificate for network: ${ZITI_NETWORK-}" - "${ZITI_BIN_DIR-}/ziti" pki create client --pki-root="${ZITI_PKI_OS_SPECIFIC}" --ca-name="${ZITI_CONTROLLER_INTERMEDIATE_NAME}" \ - --client-file="${ZITI_NETWORK-}-dotzeet" \ - --client-name "${ZITI_NETWORK-} Management" - else - echo "Creating ziti-fabric client certificate for network: ${ZITI_NETWORK-}" - echo "key exists" - fi echo " " - pki_client_server "${ZITI_CONTROLLER_HOSTNAME}" "${ZITI_CONTROLLER_INTERMEDIATE_NAME}" "${ZITI_CONTROLLER_IP_OVERRIDE-}" pki_client_server "${ZITI_EDGE_CONTROLLER_HOSTNAME}" "${ZITI_EDGE_CONTROLLER_INTERMEDIATE_NAME}" "${ZITI_EDGE_CONTROLLER_IP_OVERRIDE-}" - } @@ -825,20 +885,6 @@ function createEdgeRouterConfig { echo -e "edge router configuration file written to: $(BLUE "${output_file}")" } -function createFabricIdentity { - output_file="${ZITI_HOME}/identities.yml" -cat > "${output_file}" <", - Short: "Start loop2 dialer", + Short: "Start loop3 dialer", Args: cobra.ExactArgs(1), }, } @@ -180,9 +180,11 @@ func (cmd *dialerCmd) connect() net.Conn { panic(err) } - _, id, err := dotziti.LoadIdentity(cmd.identity) - if err != nil { - panic(err) + id := &identity.TokenId{Token: "test"} + if endpoint.Type() != "tcp" || !cmd.direct { + if _, id, err = dotziti.LoadIdentity(cmd.identity); err != nil { + panic(err) + } } if cmd.direct { diff --git a/ziti-fabric-test/subcmd/loop3/listener.go b/ziti-fabric-test/subcmd/loop3/listener.go index 61552c624..827d913ca 100644 --- a/ziti-fabric-test/subcmd/loop3/listener.go +++ b/ziti-fabric-test/subcmd/loop3/listener.go @@ -22,13 +22,14 @@ import ( "github.com/openziti/foundation/agent" "github.com/openziti/foundation/identity/dotziti" "github.com/openziti/foundation/identity/identity" - "github.com/openziti/transport" "github.com/openziti/sdk-golang/ziti" "github.com/openziti/sdk-golang/ziti/config" + "github.com/openziti/transport" loop3_pb "github.com/openziti/ziti/ziti-fabric-test/subcmd/loop3/pb" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "net" + "net/http" "strings" ) @@ -38,18 +39,19 @@ func init() { } type listenerCmd struct { - cmd *cobra.Command - identity string - bindAddress string - edgeConfigFile string - test *loop3_pb.Test + cmd *cobra.Command + identity string + bindAddress string + edgeConfigFile string + healthCheckAddr string + test *loop3_pb.Test } func newListenerCmd() *listenerCmd { result := &listenerCmd{ cmd: &cobra.Command{ Use: "listener", - Short: "Start loop2 listener", + Short: "Start loop3 listener", Args: cobra.MaximumNArgs(1), }, } @@ -60,6 +62,7 @@ func newListenerCmd() *listenerCmd { flags.StringVarP(&result.identity, "identity", "i", "default", ".ziti/identities.yml name") flags.StringVarP(&result.bindAddress, "bind", "b", "tcp:127.0.0.1:8171", "Listener bind address") flags.StringVarP(&result.edgeConfigFile, "config-file", "c", "", "Edge SDK config file") + flags.StringVar(&result.healthCheckAddr, "health-check-addr", "", "Edge SDK config file") return result } @@ -70,7 +73,18 @@ func (cmd *listenerCmd) run(_ *cobra.Command, args []string) { var err error shutdownClean := false if err = agent.Listen(agent.Options{ShutdownCleanup: &shutdownClean}); err != nil { - pfxlog.Logger().WithError(err).Error("unable to start CLI agent") + log.WithError(err).Error("unable to start CLI agent") + } + + if cmd.healthCheckAddr != "" { + go func() { + err = http.ListenAndServe(cmd.healthCheckAddr, http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + writer.WriteHeader(200) + })) + if err != nil { + log.WithError(err).Fatalf("unable to start health check endpoint on addr [%v]", cmd.healthCheckAddr) + } + }() } var scenario *Scenario @@ -96,17 +110,21 @@ func (cmd *listenerCmd) run(_ *cobra.Command, args []string) { defer close(closer) } + log.Infof("binding to address '%v'", cmd.bindAddress) if strings.HasPrefix(cmd.bindAddress, "edge") { cmd.listenEdge() } else { - _, id, err := dotziti.LoadIdentity(cmd.identity) + bindAddress, err := transport.ParseAddress(cmd.bindAddress) if err != nil { panic(err) } - bindAddress, err := transport.ParseAddress(cmd.bindAddress) - if err != nil { - panic(err) + id := &identity.TokenId{Token: "test"} + if bindAddress.Type() != "tcp" { + _, id, err = dotziti.LoadIdentity(cmd.identity) + if err != nil { + panic(err) + } } cmd.listen(bindAddress, id) diff --git a/ziti-fabric-test/subcmd/loop3/pb/generate.go b/ziti-fabric-test/subcmd/loop3/pb/generate.go new file mode 100644 index 000000000..b4641b229 --- /dev/null +++ b/ziti-fabric-test/subcmd/loop3/pb/generate.go @@ -0,0 +1,5 @@ +//go:generate protoc -I ./ ./loop3.proto --go_out=paths=source_relative:./ + +package loop3_pb + +// Here to provide the go:generate line above diff --git a/ziti-fabric-test/subcmd/loop3/pb/loop3.pb.go b/ziti-fabric-test/subcmd/loop3/pb/loop3.pb.go index f50bb1d6a..2894c28c9 100644 --- a/ziti-fabric-test/subcmd/loop3/pb/loop3.pb.go +++ b/ziti-fabric-test/subcmd/loop3/pb/loop3.pb.go @@ -1,177 +1,318 @@ // Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.19.1 // source: loop3.proto package loop3_pb import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) type Test struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - TxRequests int32 `protobuf:"varint,2,opt,name=txRequests,proto3" json:"txRequests,omitempty"` - TxPacing int32 `protobuf:"varint,3,opt,name=txPacing,proto3" json:"txPacing,omitempty"` - TxMaxJitter int32 `protobuf:"varint,4,opt,name=txMaxJitter,proto3" json:"txMaxJitter,omitempty"` - RxRequests int32 `protobuf:"varint,5,opt,name=rxRequests,proto3" json:"rxRequests,omitempty"` - RxTimeout int32 `protobuf:"varint,6,opt,name=rxTimeout,proto3" json:"rxTimeout,omitempty"` - PayloadMinBytes int32 `protobuf:"varint,7,opt,name=payloadMinBytes,proto3" json:"payloadMinBytes,omitempty"` - PayloadMaxBytes int32 `protobuf:"varint,8,opt,name=payloadMaxBytes,proto3" json:"payloadMaxBytes,omitempty"` - LatencyFrequency int32 `protobuf:"varint,9,opt,name=latencyFrequency,proto3" json:"latencyFrequency,omitempty"` - TxBlockType string `protobuf:"bytes,10,opt,name=txBlockType,proto3" json:"txBlockType,omitempty"` - RxBlockType string `protobuf:"bytes,11,opt,name=rxBlockType,proto3" json:"rxBlockType,omitempty"` - RxSeqBlockSize int32 `protobuf:"varint,12,opt,name=rxSeqBlockSize,proto3" json:"rxSeqBlockSize,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + TxRequests int32 `protobuf:"varint,2,opt,name=txRequests,proto3" json:"txRequests,omitempty"` + TxPacing string `protobuf:"bytes,3,opt,name=txPacing,proto3" json:"txPacing,omitempty"` + TxMaxJitter string `protobuf:"bytes,4,opt,name=txMaxJitter,proto3" json:"txMaxJitter,omitempty"` + TxPauseEvery string `protobuf:"bytes,5,opt,name=txPauseEvery,proto3" json:"txPauseEvery,omitempty"` + TxPauseFor string `protobuf:"bytes,6,opt,name=txPauseFor,proto3" json:"txPauseFor,omitempty"` + RxRequests int32 `protobuf:"varint,7,opt,name=rxRequests,proto3" json:"rxRequests,omitempty"` + RxTimeout int32 `protobuf:"varint,8,opt,name=rxTimeout,proto3" json:"rxTimeout,omitempty"` + RxPauseEvery string `protobuf:"bytes,9,opt,name=rxPauseEvery,proto3" json:"rxPauseEvery,omitempty"` + RxPauseFor string `protobuf:"bytes,10,opt,name=rxPauseFor,proto3" json:"rxPauseFor,omitempty"` + PayloadMinBytes int32 `protobuf:"varint,11,opt,name=payloadMinBytes,proto3" json:"payloadMinBytes,omitempty"` + PayloadMaxBytes int32 `protobuf:"varint,12,opt,name=payloadMaxBytes,proto3" json:"payloadMaxBytes,omitempty"` + LatencyFrequency int32 `protobuf:"varint,13,opt,name=latencyFrequency,proto3" json:"latencyFrequency,omitempty"` + TxBlockType string `protobuf:"bytes,14,opt,name=txBlockType,proto3" json:"txBlockType,omitempty"` + RxBlockType string `protobuf:"bytes,15,opt,name=rxBlockType,proto3" json:"rxBlockType,omitempty"` + RxSeqBlockSize int32 `protobuf:"varint,16,opt,name=rxSeqBlockSize,proto3" json:"rxSeqBlockSize,omitempty"` + RxPacing string `protobuf:"bytes,17,opt,name=rxPacing,proto3" json:"rxPacing,omitempty"` + RxMaxJitter string `protobuf:"bytes,18,opt,name=rxMaxJitter,proto3" json:"rxMaxJitter,omitempty"` } -func (m *Test) Reset() { *m = Test{} } -func (m *Test) String() string { return proto.CompactTextString(m) } -func (*Test) ProtoMessage() {} +func (x *Test) Reset() { + *x = Test{} + if protoimpl.UnsafeEnabled { + mi := &file_loop3_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Test) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Test) ProtoMessage() {} + +func (x *Test) ProtoReflect() protoreflect.Message { + mi := &file_loop3_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Test.ProtoReflect.Descriptor instead. func (*Test) Descriptor() ([]byte, []int) { - return fileDescriptor_fb557b01f1ee4776, []int{0} + return file_loop3_proto_rawDescGZIP(), []int{0} } -func (m *Test) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Test.Unmarshal(m, b) -} -func (m *Test) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Test.Marshal(b, m, deterministic) -} -func (m *Test) XXX_Merge(src proto.Message) { - xxx_messageInfo_Test.Merge(m, src) -} -func (m *Test) XXX_Size() int { - return xxx_messageInfo_Test.Size(m) -} -func (m *Test) XXX_DiscardUnknown() { - xxx_messageInfo_Test.DiscardUnknown(m) -} - -var xxx_messageInfo_Test proto.InternalMessageInfo - -func (m *Test) GetName() string { - if m != nil { - return m.Name +func (x *Test) GetName() string { + if x != nil { + return x.Name } return "" } -func (m *Test) GetTxRequests() int32 { - if m != nil { - return m.TxRequests +func (x *Test) GetTxRequests() int32 { + if x != nil { + return x.TxRequests } return 0 } -func (m *Test) GetTxPacing() int32 { - if m != nil { - return m.TxPacing - } - return 0 -} - -func (m *Test) GetTxMaxJitter() int32 { - if m != nil { - return m.TxMaxJitter - } - return 0 -} - -func (m *Test) GetRxRequests() int32 { - if m != nil { - return m.RxRequests - } - return 0 -} - -func (m *Test) GetRxTimeout() int32 { - if m != nil { - return m.RxTimeout - } - return 0 -} - -func (m *Test) GetPayloadMinBytes() int32 { - if m != nil { - return m.PayloadMinBytes - } - return 0 -} - -func (m *Test) GetPayloadMaxBytes() int32 { - if m != nil { - return m.PayloadMaxBytes - } - return 0 -} - -func (m *Test) GetLatencyFrequency() int32 { - if m != nil { - return m.LatencyFrequency - } - return 0 -} - -func (m *Test) GetTxBlockType() string { - if m != nil { - return m.TxBlockType +func (x *Test) GetTxPacing() string { + if x != nil { + return x.TxPacing } return "" } -func (m *Test) GetRxBlockType() string { - if m != nil { - return m.RxBlockType +func (x *Test) GetTxMaxJitter() string { + if x != nil { + return x.TxMaxJitter } return "" } -func (m *Test) GetRxSeqBlockSize() int32 { - if m != nil { - return m.RxSeqBlockSize +func (x *Test) GetTxPauseEvery() string { + if x != nil { + return x.TxPauseEvery + } + return "" +} + +func (x *Test) GetTxPauseFor() string { + if x != nil { + return x.TxPauseFor + } + return "" +} + +func (x *Test) GetRxRequests() int32 { + if x != nil { + return x.RxRequests } return 0 } -func init() { - proto.RegisterType((*Test)(nil), "loop3.pb.Test") +func (x *Test) GetRxTimeout() int32 { + if x != nil { + return x.RxTimeout + } + return 0 } -func init() { - proto.RegisterFile("loop3.proto", fileDescriptor_fb557b01f1ee4776) +func (x *Test) GetRxPauseEvery() string { + if x != nil { + return x.RxPauseEvery + } + return "" } -var fileDescriptor_fb557b01f1ee4776 = []byte{ - // 261 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x64, 0x91, 0xc1, 0x4a, 0xf3, 0x40, - 0x10, 0xc7, 0xe9, 0xd7, 0xb4, 0x5f, 0x32, 0x11, 0x95, 0x39, 0x2d, 0x22, 0x52, 0x3c, 0x48, 0xf1, - 0xe0, 0xa5, 0x6f, 0xd0, 0x83, 0x07, 0xa1, 0x20, 0x69, 0x5e, 0x60, 0x1b, 0x07, 0x59, 0x4c, 0xb3, - 0xe9, 0x66, 0x0a, 0x1b, 0x1f, 0xc7, 0x27, 0x35, 0x99, 0x14, 0xb3, 0xd6, 0xdb, 0xcc, 0xef, 0xff, - 0xe3, 0x9f, 0xec, 0x2e, 0xa4, 0xa5, 0xb5, 0xf5, 0xea, 0xa9, 0x76, 0x96, 0x2d, 0xc6, 0xa7, 0x65, - 0x77, 0xff, 0x35, 0x85, 0x28, 0xa7, 0x86, 0x11, 0x21, 0xaa, 0xf4, 0x9e, 0xd4, 0x64, 0x31, 0x59, - 0x26, 0x99, 0xcc, 0x78, 0x07, 0xc0, 0x3e, 0xa3, 0xc3, 0xb1, 0x13, 0x1a, 0xf5, 0xaf, 0x4b, 0x66, - 0x59, 0x40, 0xf0, 0x06, 0x62, 0xf6, 0xaf, 0xba, 0x30, 0xd5, 0xbb, 0x9a, 0x4a, 0xfa, 0xb3, 0xe3, - 0x02, 0x52, 0xf6, 0x1b, 0xed, 0x5f, 0x0c, 0x33, 0x39, 0x15, 0x49, 0x1c, 0xa2, 0xbe, 0xdd, 0x8d, - 0xed, 0xb3, 0xa1, 0x7d, 0x24, 0x78, 0x0b, 0x89, 0xf3, 0xb9, 0xd9, 0x93, 0x3d, 0xb2, 0x9a, 0x4b, - 0x3c, 0x02, 0x5c, 0xc2, 0x55, 0xad, 0xdb, 0xd2, 0xea, 0xb7, 0x8d, 0xa9, 0xd6, 0x2d, 0x53, 0xa3, - 0xfe, 0x8b, 0x73, 0x8e, 0x43, 0x53, 0xfb, 0xc1, 0x8c, 0x7f, 0x9b, 0x27, 0x8c, 0x8f, 0x70, 0x5d, - 0x6a, 0xa6, 0xaa, 0x68, 0x9f, 0x5d, 0xff, 0x17, 0xdd, 0xa0, 0x12, 0x51, 0xff, 0xf0, 0xe1, 0x7c, - 0xeb, 0xd2, 0x16, 0x1f, 0x79, 0x5b, 0x93, 0x02, 0xb9, 0xb6, 0x10, 0xf5, 0x86, 0x0b, 0x8c, 0x74, - 0x30, 0x02, 0x84, 0x0f, 0x70, 0xe9, 0xfc, 0x96, 0x0e, 0x42, 0xb6, 0xe6, 0x93, 0xd4, 0x85, 0x7c, - 0xed, 0x8c, 0xee, 0xe6, 0xf2, 0x6a, 0xab, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0x5a, 0x01, 0xaf, - 0xf2, 0xc4, 0x01, 0x00, 0x00, +func (x *Test) GetRxPauseFor() string { + if x != nil { + return x.RxPauseFor + } + return "" +} + +func (x *Test) GetPayloadMinBytes() int32 { + if x != nil { + return x.PayloadMinBytes + } + return 0 +} + +func (x *Test) GetPayloadMaxBytes() int32 { + if x != nil { + return x.PayloadMaxBytes + } + return 0 +} + +func (x *Test) GetLatencyFrequency() int32 { + if x != nil { + return x.LatencyFrequency + } + return 0 +} + +func (x *Test) GetTxBlockType() string { + if x != nil { + return x.TxBlockType + } + return "" +} + +func (x *Test) GetRxBlockType() string { + if x != nil { + return x.RxBlockType + } + return "" +} + +func (x *Test) GetRxSeqBlockSize() int32 { + if x != nil { + return x.RxSeqBlockSize + } + return 0 +} + +func (x *Test) GetRxPacing() string { + if x != nil { + return x.RxPacing + } + return "" +} + +func (x *Test) GetRxMaxJitter() string { + if x != nil { + return x.RxMaxJitter + } + return "" +} + +var File_loop3_proto protoreflect.FileDescriptor + +var file_loop3_proto_rawDesc = []byte{ + 0x0a, 0x0b, 0x6c, 0x6f, 0x6f, 0x70, 0x33, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x7a, + 0x69, 0x74, 0x69, 0x2e, 0x6c, 0x6f, 0x6f, 0x70, 0x33, 0x2e, 0x70, 0x62, 0x22, 0xe8, 0x04, 0x0a, + 0x04, 0x54, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x78, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x74, + 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x78, 0x50, + 0x61, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x78, 0x50, + 0x61, 0x63, 0x69, 0x6e, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x78, 0x4d, 0x61, 0x78, 0x4a, 0x69, + 0x74, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x78, 0x4d, 0x61, + 0x78, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x74, 0x78, 0x50, 0x61, 0x75, + 0x73, 0x65, 0x45, 0x76, 0x65, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x74, + 0x78, 0x50, 0x61, 0x75, 0x73, 0x65, 0x45, 0x76, 0x65, 0x72, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x74, + 0x78, 0x50, 0x61, 0x75, 0x73, 0x65, 0x46, 0x6f, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x74, 0x78, 0x50, 0x61, 0x75, 0x73, 0x65, 0x46, 0x6f, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x72, + 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x0a, 0x72, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x72, + 0x78, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, + 0x72, 0x78, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x72, 0x78, 0x50, + 0x61, 0x75, 0x73, 0x65, 0x45, 0x76, 0x65, 0x72, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x72, 0x78, 0x50, 0x61, 0x75, 0x73, 0x65, 0x45, 0x76, 0x65, 0x72, 0x79, 0x12, 0x1e, 0x0a, + 0x0a, 0x72, 0x78, 0x50, 0x61, 0x75, 0x73, 0x65, 0x46, 0x6f, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x72, 0x78, 0x50, 0x61, 0x75, 0x73, 0x65, 0x46, 0x6f, 0x72, 0x12, 0x28, 0x0a, + 0x0f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x4d, 0x69, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x4d, + 0x69, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x70, 0x61, 0x79, 0x6c, 0x6f, + 0x61, 0x64, 0x4d, 0x61, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x0f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x4d, 0x61, 0x78, 0x42, 0x79, 0x74, 0x65, + 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x46, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6c, 0x61, 0x74, + 0x65, 0x6e, 0x63, 0x79, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x12, 0x20, 0x0a, + 0x0b, 0x74, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x74, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x72, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x18, 0x0f, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x78, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x78, 0x53, 0x65, 0x71, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, + 0x69, 0x7a, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x72, 0x78, 0x53, 0x65, 0x71, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x78, 0x50, + 0x61, 0x63, 0x69, 0x6e, 0x67, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x78, 0x50, + 0x61, 0x63, 0x69, 0x6e, 0x67, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x78, 0x4d, 0x61, 0x78, 0x4a, 0x69, + 0x74, 0x74, 0x65, 0x72, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x78, 0x4d, 0x61, + 0x78, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x42, 0x44, 0x5a, 0x42, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x7a, 0x69, 0x74, 0x69, 0x2f, 0x7a, + 0x69, 0x74, 0x69, 0x2f, 0x7a, 0x69, 0x74, 0x69, 0x2d, 0x66, 0x61, 0x62, 0x72, 0x69, 0x63, 0x2d, + 0x74, 0x65, 0x73, 0x74, 0x2f, 0x73, 0x75, 0x62, 0x63, 0x6d, 0x64, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, + 0x33, 0x2f, 0x70, 0x62, 0x2f, 0x6c, 0x6f, 0x6f, 0x70, 0x33, 0x5f, 0x70, 0x62, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_loop3_proto_rawDescOnce sync.Once + file_loop3_proto_rawDescData = file_loop3_proto_rawDesc +) + +func file_loop3_proto_rawDescGZIP() []byte { + file_loop3_proto_rawDescOnce.Do(func() { + file_loop3_proto_rawDescData = protoimpl.X.CompressGZIP(file_loop3_proto_rawDescData) + }) + return file_loop3_proto_rawDescData +} + +var file_loop3_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_loop3_proto_goTypes = []interface{}{ + (*Test)(nil), // 0: ziti.loop3.pb.Test +} +var file_loop3_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_loop3_proto_init() } +func file_loop3_proto_init() { + if File_loop3_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_loop3_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Test); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_loop3_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_loop3_proto_goTypes, + DependencyIndexes: file_loop3_proto_depIdxs, + MessageInfos: file_loop3_proto_msgTypes, + }.Build() + File_loop3_proto = out.File + file_loop3_proto_rawDesc = nil + file_loop3_proto_goTypes = nil + file_loop3_proto_depIdxs = nil } diff --git a/ziti-fabric-test/subcmd/loop3/pb/loop3.proto b/ziti-fabric-test/subcmd/loop3/pb/loop3.proto index 75c74373f..f7f2d2af6 100644 --- a/ziti-fabric-test/subcmd/loop3/pb/loop3.proto +++ b/ziti-fabric-test/subcmd/loop3/pb/loop3.proto @@ -1,18 +1,27 @@ syntax = "proto3"; -package loop3.pb; +package ziti.loop3.pb; +option go_package = "github.com/openziti/ziti/ziti-fabric-test/subcmd/loop3/pb/loop3_pb"; message Test { - string name = 1; - int32 txRequests = 2; - int32 txPacing = 3; - int32 txMaxJitter = 4; - int32 rxRequests = 5; - int32 rxTimeout = 6; - int32 payloadMinBytes = 7; - int32 payloadMaxBytes = 8; - int32 latencyFrequency = 9; - string txBlockType = 10; - string rxBlockType = 11; - int32 rxSeqBlockSize = 12; + string name = 1; + int32 txRequests = 2; + string txPacing = 3; + string txMaxJitter = 4; + string txPauseEvery = 5; + string txPauseFor = 6; + + int32 rxRequests = 7; + int32 rxTimeout = 8; + string rxPauseEvery = 9; + string rxPauseFor = 10; + + int32 payloadMinBytes = 11; + int32 payloadMaxBytes = 12; + int32 latencyFrequency = 13; + string txBlockType = 14; + string rxBlockType = 15; + int32 rxSeqBlockSize = 16; + string rxPacing = 17; + string rxMaxJitter = 18; } \ No newline at end of file diff --git a/ziti-fabric-test/subcmd/loop3/protocol.go b/ziti-fabric-test/subcmd/loop3/protocol.go index fc0569858..ebd61e122 100644 --- a/ziti-fabric-test/subcmd/loop3/protocol.go +++ b/ziti-fabric-test/subcmd/loop3/protocol.go @@ -32,16 +32,24 @@ import ( ) type protocol struct { - test *loop3_pb.Test - blocks chan Block - rxSequence uint64 - peer io.ReadWriteCloser - rxBlocks chan Block - txCount int32 - rxCount int32 - lastRx int64 - latencies chan *time.Time - errors chan error + test *loop3_pb.Test + blocks chan Block + rxSequence uint64 + txPacing time.Duration + txMaxJitter time.Duration + txPauseEvery time.Duration + txPauseFor time.Duration + rxPacing time.Duration + rxMaxJitter time.Duration + rxPauseEvery time.Duration + rxPauseFor time.Duration + peer io.ReadWriteCloser + rxBlocks chan Block + txCount int32 + rxCount int32 + lastRx int64 + latencies chan *time.Time + errors chan error } var MagicHeader = []byte{0xCA, 0xFE, 0xF0, 0x0D} @@ -84,6 +92,24 @@ func (p *protocol) run(test *loop3_pb.Test) error { panic(errors.Errorf("unknown rx block type %v", test.RxBlockType)) } + parseTime := func(val string) time.Duration { + t, err := time.ParseDuration(val) + if err != nil { + panic(err) + } + return t + } + + p.txPacing = parseTime(p.test.TxPacing) + p.txMaxJitter = parseTime(p.test.TxMaxJitter) + p.txPauseEvery = parseTime(p.test.TxPauseEvery) + p.txPauseFor = parseTime(p.test.TxPauseFor) + + p.rxPacing = parseTime(p.test.RxPacing) + p.rxMaxJitter = parseTime(p.test.RxMaxJitter) + p.rxPauseEvery = parseTime(p.test.RxPauseEvery) + p.rxPauseFor = parseTime(p.test.RxPauseFor) + rxerDone := make(chan bool) go p.rxer(rxerDone, rxBlock) if p.test.RxRequests > 0 { @@ -111,18 +137,23 @@ func (p *protocol) txer(done chan bool) { defer log.Debug("complete") var lastSend time.Time + lastPause := time.Now() for p.txCount < p.test.TxRequests { + now := time.Now() + if p.txPauseEvery > 0 && now.Sub(lastPause) > p.txPauseEvery { + time.Sleep(p.txPauseFor) + lastPause = time.Now() + } select { case block := <-p.blocks: if block != nil { - if p.test.TxPacing > 0 { - jitter := 0 - if p.test.TxMaxJitter > 0 { - jitter = rand.Intn(int(p.test.TxMaxJitter)) + if p.txPacing > 0 { + jitter := time.Duration(0) + if p.txMaxJitter > 0 { + jitter = time.Duration(rand.Intn(int(p.txMaxJitter))) } - nextSend := lastSend.Add(time.Duration(int(p.test.TxPacing)+jitter) * time.Millisecond) - now := time.Now() + nextSend := lastSend.Add(p.txPacing + jitter) if nextSend.After(now) { time.Sleep(nextSend.Sub(now)) lastSend = nextSend @@ -155,7 +186,14 @@ func (p *protocol) rxer(done chan bool, rxBlock func() (Block, error)) { defer func() { done <- true }() defer log.Debug("complete") + lastRx := time.Now() + lastPause := time.Now() for p.rxCount < p.test.RxRequests { + now := time.Now() + if p.rxPauseEvery > 0 && now.Sub(lastPause) > p.rxPauseEvery { + time.Sleep(p.rxPauseFor) + lastPause = time.Now() + } block, err := rxBlock() if err != nil { p.errors <- err @@ -166,6 +204,22 @@ func (p *protocol) rxer(done chan bool, rxBlock func() (Block, error)) { atomic.AddInt32(&p.rxCount, 1) atomic.StoreInt64(&p.lastRx, info.NowInMilliseconds()) p.rxBlocks <- block + + if p.rxPacing > 0 { + jitter := time.Duration(0) + if p.rxMaxJitter > 0 { + jitter = time.Duration(rand.Intn(int(p.rxMaxJitter))) + } + + now := time.Now() + nextRx := lastRx.Add(p.rxPacing + jitter) + if nextRx.After(now) { + time.Sleep(nextRx.Sub(now)) + lastRx = nextRx + } else { + lastRx = now + } + } } close(p.rxBlocks) diff --git a/ziti-fabric-test/subcmd/loop3/scenario.go b/ziti-fabric-test/subcmd/loop3/scenario.go index 0099df316..c8e42f4a9 100644 --- a/ziti-fabric-test/subcmd/loop3/scenario.go +++ b/ziti-fabric-test/subcmd/loop3/scenario.go @@ -37,10 +37,18 @@ type Workload struct { } type Test struct { - TxRequests int32 `yaml:"txRequests"` - TxPacing int32 `yaml:"txPacing"` - TxMaxJitter int32 `yaml:"txMaxJitter"` - RxTimeout int32 `yaml:"rxTimeout"` + TxRequests int32 `yaml:"txRequests"` + TxPacing time.Duration `yaml:"txPacing"` + TxMaxJitter time.Duration `yaml:"txMaxJitter"` + TxPauseEvery time.Duration `yaml:"txPauseEvery"` + TxPauseFor time.Duration `yaml:"txPauseFor"` + + RxTimeout int32 `yaml:"rxTimeout"` + RxPacing time.Duration `yaml:"rxPacing"` + RxMaxJitter time.Duration `yaml:"rxMaxJitter"` + RxPauseEvery time.Duration `yaml:"rxPauseEvery"` + RxPauseFor time.Duration `yaml:"rxPauseFor"` + PayloadMinBytes int32 `yaml:"payloadMinBytes"` PayloadMaxBytes int32 `yaml:"payloadMaxBytes"` LatencyFrequency int32 `yaml:"latencyFrequency"` @@ -51,9 +59,15 @@ func (workload *Workload) GetTests() (*loop3_pb.Test, *loop3_pb.Test) { local := &loop3_pb.Test{ Name: workload.Name, TxRequests: workload.Dialer.TxRequests, - TxPacing: workload.Dialer.TxPacing, - TxMaxJitter: workload.Dialer.TxMaxJitter, + TxPacing: workload.Dialer.TxPacing.String(), + TxMaxJitter: workload.Dialer.TxMaxJitter.String(), + TxPauseEvery: workload.Dialer.TxPauseEvery.String(), + TxPauseFor: workload.Dialer.TxPauseFor.String(), RxRequests: workload.Listener.TxRequests, + RxPacing: workload.Dialer.RxPacing.String(), + RxMaxJitter: workload.Dialer.RxMaxJitter.String(), + RxPauseEvery: workload.Dialer.RxPauseEvery.String(), + RxPauseFor: workload.Dialer.RxPauseFor.String(), RxTimeout: workload.Dialer.RxTimeout, RxSeqBlockSize: workload.Listener.PayloadMinBytes, PayloadMinBytes: workload.Dialer.PayloadMinBytes, @@ -66,10 +80,16 @@ func (workload *Workload) GetTests() (*loop3_pb.Test, *loop3_pb.Test) { remote := &loop3_pb.Test{ Name: workload.Name, TxRequests: workload.Listener.TxRequests, - TxPacing: workload.Listener.TxPacing, - TxMaxJitter: workload.Listener.TxMaxJitter, + TxPacing: workload.Listener.TxPacing.String(), + TxMaxJitter: workload.Listener.TxMaxJitter.String(), + TxPauseEvery: workload.Listener.TxPauseEvery.String(), + TxPauseFor: workload.Listener.TxPauseFor.String(), RxRequests: workload.Dialer.TxRequests, + RxPacing: workload.Listener.RxPacing.String(), + RxMaxJitter: workload.Listener.RxMaxJitter.String(), RxTimeout: workload.Listener.RxTimeout, + RxPauseEvery: workload.Listener.RxPauseEvery.String(), + RxPauseFor: workload.Listener.RxPauseFor.String(), RxSeqBlockSize: workload.Dialer.PayloadMinBytes, PayloadMinBytes: workload.Listener.PayloadMinBytes, PayloadMaxBytes: workload.Listener.PayloadMaxBytes, diff --git a/ziti-fabric/subcmd/stream_circuits.go b/ziti-fabric/subcmd/stream_circuits.go index 583fe7536..a3d9fda82 100644 --- a/ziti-fabric/subcmd/stream_circuits.go +++ b/ziti-fabric/subcmd/stream_circuits.go @@ -18,11 +18,12 @@ package subcmd import ( "fmt" + "time" + "github.com/golang/protobuf/proto" "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" "github.com/spf13/cobra" - "time" ) func init() { @@ -83,8 +84,13 @@ func (*circuitsHandler) HandleReceive(msg *channel.Message, _ channel.Channel) { if event.EventType == mgmt_pb.StreamCircuitEventType_CircuitDeleted { fmt.Printf("%v: circuitId: %v\n", eventType, event.CircuitId) } else if event.EventType == mgmt_pb.StreamCircuitEventType_CircuitCreated { - fmt.Printf("%v: circuitId: %v, clientId: %v, serviceId: %v, path: %v\n", - eventType, event.CircuitId, event.ClientId, event.ServiceId, event.Path.CalculateDisplayPath()) + fmt.Printf("%v: circuitId: %v, clientId: %v, serviceId: %v, path: %v%s\n", + eventType, event.CircuitId, event.ClientId, event.ServiceId, event.Path.CalculateDisplayPath(), func() string { + if event.CreationTimespan == nil { + return "" + } + return fmt.Sprintf(", creationTimespan: %s", time.Duration(*event.CreationTimespan)) + }()) } else if event.EventType == mgmt_pb.StreamCircuitEventType_PathUpdated { fmt.Printf("%v: circuitId: %v, path: %v\n", eventType, event.CircuitId, event.Path.CalculateDisplayPath()) diff --git a/ziti-router/subcmd/root.go b/ziti-router/subcmd/root.go index 1b57f1488..b7b0253f5 100644 --- a/ziti-router/subcmd/root.go +++ b/ziti-router/subcmd/root.go @@ -30,7 +30,7 @@ func init() { root.PersistentFlags().StringVar(&logFormatter, "log-formatter", "", "Specify log formatter [json|pfxlog|text]") root.PersistentFlags().BoolVar(&cliAgentEnabled, "cli-agent", true, "Enable/disable CLI Agent (enabled by default)") root.PersistentFlags().StringVar(&cliAgentAddr, "cli-agent-addr", "", "Specify where CLI Agent should list (ex: unix:/tmp/myfile.sock or tcp:127.0.0.1:10001)") - root.PersistentFlags().BoolVar(&debugOpsEnabled, "debug-ops", false, "Enable/disable debug agent operations (disabled by default)") + root.PersistentFlags().BoolVar(&enableDebugOps, "debug-ops", false, "Enable/disable debug agent operations (disabled by default)") } var root = &cobra.Command{ @@ -59,7 +59,7 @@ var root = &cobra.Command{ var verbose bool var logFormatter string var cliAgentEnabled bool -var debugOpsEnabled bool +var enableDebugOps bool var cliAgentAddr string func Execute() { diff --git a/ziti-router/subcmd/run.go b/ziti-router/subcmd/run.go index 7dc5fe5f3..b3061da65 100644 --- a/ziti-router/subcmd/run.go +++ b/ziti-router/subcmd/run.go @@ -97,15 +97,17 @@ func run(cmd *cobra.Command, args []string) { if cliAgentEnabled { options := agent.Options{Addr: cliAgentAddr} - if debugOpsEnabled { - r.RegisterDefaultDebugOps() - debugops.RegisterEdgeRouterDebugOps(r, stateManager) - options.CustomOps = map[byte]func(conn net.Conn) error{ - agent.CustomOp: func(conn net.Conn) error { - return r.HandleDebug(conn) - }, - } + if config.EnableDebugOps { + enableDebugOps = true } + r.RegisterDefaultAgentOps(enableDebugOps) + debugops.RegisterEdgeRouterAgentOps(r, stateManager, enableDebugOps) + + options.CustomOps = map[byte]func(conn net.Conn) error{ + agent.CustomOp: r.HandleAgentOp, + agent.CustomOpAsync: r.HandleAgentAsyncOp, + } + if err := agent.Listen(options); err != nil { pfxlog.Logger().WithError(err).Error("unable to start CLI agent") } diff --git a/ziti/cmd/ziti/cmd/adhoc.go b/ziti/cmd/ziti/cmd/adhoc.go index 189d1acba..8ea48b62a 100644 --- a/ziti/cmd/ziti/cmd/adhoc.go +++ b/ziti/cmd/ziti/cmd/adhoc.go @@ -24,7 +24,6 @@ import ( "path/filepath" "github.com/openziti/ziti/ziti/ansible" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" ) @@ -37,12 +36,11 @@ type AdhocOptions struct { var adhocOptions = &ansible.Options{} // NewCmdAdhoc creates the command -func NewCmdAdhoc(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdAdhoc(out io.Writer, errOut io.Writer) *cobra.Command { options := &AdhocOptions{ CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } diff --git a/ziti/cmd/ziti/cmd/agent.go b/ziti/cmd/ziti/cmd/agent.go index 38dd96693..8b5fec8fe 100644 --- a/ziti/cmd/ziti/cmd/agent.go +++ b/ziti/cmd/ziti/cmd/agent.go @@ -20,9 +20,10 @@ import ( "github.com/openziti/edge/router/debugops" "github.com/openziti/fabric/controller" "github.com/openziti/fabric/router" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" - "io" ) type AgentAppId byte @@ -32,14 +33,8 @@ const ( AgentAppRouter = AgentAppId(router.AgentAppId) ) -func NewAgentCmd(out io.Writer, errOut io.Writer) *cobra.Command { - agentCmd := &cobra.Command{ - Use: "agent", - Short: "Interact with ziti processes using the the IPC agent", - Run: func(cmd *cobra.Command, args []string) { - cmdhelper.CheckErr(cmd.Help()) - }, - } +func NewAgentCmd(p common.OptionsProvider) *cobra.Command { + agentCmd := agentcli.NewAgentCmd(p) ctrlCmd := &cobra.Command{ Use: "controller", @@ -51,7 +46,7 @@ func NewAgentCmd(out io.Writer, errOut io.Writer) *cobra.Command { } agentCmd.AddCommand(ctrlCmd) - ctrlCmd.AddCommand(NewSimpleAgentCustomCmd("snapshot-db", AgentAppController, controller.AgentOpSnapshotDbSnaps, out, errOut)) + ctrlCmd.AddCommand(NewSimpleAgentCustomCmd("snapshot-db", AgentAppController, controller.AgentOpSnapshotDbSnaps, p)) routerCmd := &cobra.Command{ Use: "router", @@ -64,25 +59,13 @@ func NewAgentCmd(out io.Writer, errOut io.Writer) *cobra.Command { agentCmd.AddCommand(routerCmd) - routerCmd.AddCommand(NewCmdPsRoute(out, errOut)) - routerCmd.AddCommand(NewSimpleAgentCustomCmd("dump-routes", AgentAppRouter, router.DumpForwarderTables, out, errOut)) - routerCmd.AddCommand(NewSimpleAgentCustomCmd("disconnect", AgentAppRouter, router.CloseControlChannel, out, errOut)) - routerCmd.AddCommand(NewSimpleAgentCustomCmd("reconnect", AgentAppRouter, router.OpenControlChannel, out, errOut)) - routerCmd.AddCommand(NewSimpleAgentCustomCmd("dump-api-sessions", AgentAppRouter, debugops.DumpApiSessions, out, errOut)) - routerCmd.AddCommand(NewSimpleAgentCustomCmd("dump-links", AgentAppRouter, router.DumpLinks, out, errOut)) - - agentCmd.AddCommand(NewCmdPsGoversion(out, errOut)) - agentCmd.AddCommand(NewCmdPsGc(out, errOut)) - agentCmd.AddCommand(NewCmdPsSetgc(out, errOut)) - agentCmd.AddCommand(NewCmdPsStack(out, errOut)) - agentCmd.AddCommand(NewCmdPsMemstats(out, errOut)) - agentCmd.AddCommand(NewCmdPsStats(out, errOut)) - agentCmd.AddCommand(NewCmdPsPprofHeap(out, errOut)) - agentCmd.AddCommand(NewCmdPsPprofCpu(out, errOut)) - agentCmd.AddCommand(NewCmdPsTrace(out, errOut)) - agentCmd.AddCommand(NewCmdPsSetLogLevel(out, errOut)) - agentCmd.AddCommand(NewCmdPsSetChannelLogLevel(out, errOut)) - agentCmd.AddCommand(NewCmdPsClearChannelLogLevel(out, errOut)) + routerCmd.AddCommand(NewRouteCmd(p)) + routerCmd.AddCommand(NewSimpleAgentCustomCmd("dump-routes", AgentAppRouter, router.DumpForwarderTables, p)) + routerCmd.AddCommand(NewSimpleAgentCustomCmd("disconnect", AgentAppRouter, router.CloseControlChannel, p)) + routerCmd.AddCommand(NewSimpleAgentCustomCmd("reconnect", AgentAppRouter, router.OpenControlChannel, p)) + routerCmd.AddCommand(NewSimpleAgentCustomCmd("dump-api-sessions", AgentAppRouter, debugops.DumpApiSessions, p)) + routerCmd.AddCommand(NewSimpleAgentCustomCmd("dump-links", AgentAppRouter, router.DumpLinks, p)) + routerCmd.AddCommand(NewForgetLinkAgentCmd(p)) return agentCmd } diff --git a/ziti/cmd/ziti/cmd/agent_router_add_route.go b/ziti/cmd/ziti/cmd/agent_router_add_route.go index 19cb804a8..08260d664 100644 --- a/ziti/cmd/ziti/cmd/agent_router_add_route.go +++ b/ziti/cmd/ziti/cmd/agent_router_add_route.go @@ -22,26 +22,22 @@ import ( "github.com/openziti/fabric/pb/ctrl_pb" "github.com/openziti/fabric/router" "github.com/openziti/foundation/agent" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" - "io" "os" ) -// PsRouteOptions the options for the create spring command -type PsRouteOptions struct { - PsOptions +type AgentRouteAction struct { + agentcli.AgentOptions CtrlListener string } -// NewCmdPsRoute creates a command object for the "create" command -func NewCmdPsRoute(out io.Writer, errOut io.Writer) *cobra.Command { - options := &PsRouteOptions{ - PsOptions: PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, - }, +func NewRouteCmd(p common.OptionsProvider) *cobra.Command { + options := &AgentRouteAction{ + AgentOptions: agentcli.AgentOptions{ + CommonOptions: p(), }, } @@ -56,19 +52,17 @@ func NewCmdPsRoute(out io.Writer, errOut io.Writer) *cobra.Command { }, } - options.addCommonFlags(cmd) - return cmd } // Run implements the command -func (o *PsRouteOptions) Run() error { +func (self *AgentRouteAction) Run() error { var addr string var err error offset := 0 - if len(o.Args) == 4 { - addr, err = agent.ParseGopsAddress(o.Args) + if len(self.Args) == 4 { + addr, err = agent.ParseGopsAddress(self.Args) if err != nil { return err } @@ -76,11 +70,11 @@ func (o *PsRouteOptions) Run() error { } route := &ctrl_pb.Route{ - CircuitId: o.Args[offset], + CircuitId: self.Args[offset], Forwards: []*ctrl_pb.Route_Forward{ { - SrcAddress: o.Args[offset+1], - DstAddress: o.Args[offset+2], + SrcAddress: self.Args[offset+1], + DstAddress: self.Args[offset+2], }, }, } diff --git a/ziti/cmd/ziti/cmd/agent_router_forget_link.go b/ziti/cmd/ziti/cmd/agent_router_forget_link.go new file mode 100644 index 000000000..728e38d2b --- /dev/null +++ b/ziti/cmd/ziti/cmd/agent_router_forget_link.go @@ -0,0 +1,107 @@ +/* + 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/openziti/channel" + "github.com/openziti/fabric/pb/mgmt_pb" + "github.com/openziti/fabric/router" + "github.com/openziti/foundation/agent" + "github.com/openziti/foundation/identity/identity" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + "github.com/spf13/cobra" + "net" + "time" +) + +type ForgetLinkAgentAction struct { + agentcli.AgentOptions +} + +func NewForgetLinkAgentCmd(p common.OptionsProvider) *cobra.Command { + options := &ForgetLinkAgentAction{ + AgentOptions: agentcli.AgentOptions{ + CommonOptions: p(), + }, + } + + cmd := &cobra.Command{ + Args: cobra.RangeArgs(1, 2), + Use: "forget-link ", + Run: func(cmd *cobra.Command, args []string) { + options.Cmd = cmd + options.Args = args + err := options.Run() + cmdhelper.CheckErr(err) + }, + } + + return cmd +} + +// Run implements the command +func (self *ForgetLinkAgentAction) Run() error { + var addr string + var err error + if len(self.Args) == 2 { + addr, err = agent.ParseGopsAddress(self.Args) + if err != nil { + return err + } + } + + return agent.MakeRequestF(addr, agent.CustomOpAsync, []byte{router.AgentAppId}, self.makeRequest) +} + +func (self *ForgetLinkAgentAction) makeRequest(conn net.Conn) error { + options := channel.DefaultOptions() + options.ConnectTimeout = time.Second + dialer := channel.NewExistingConnDialer(&identity.TokenId{Token: "agent"}, conn, nil) + ch, err := channel.NewChannel("agent", dialer, nil, options) + if err != nil { + return err + } + + linkId := self.Args[0] + if len(self.Args) == 2 { + linkId = self.Args[1] + } + + msg := channel.NewMessage(int32(mgmt_pb.ContentType_RouterDebugForgetLinkRequestType), []byte(linkId)) + reply, err := msg.WithTimeout(5 * time.Second).SendForReply(ch) + if err != nil { + return err + } + if reply.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(reply) + if result.Success { + if len(result.Message) > 0 { + fmt.Printf("success: %v\n", result.Message) + } else { + fmt.Println("success") + } + } else { + fmt.Printf("error: %v\n", result.Message) + } + } else { + fmt.Printf("unexpected response type %v\n", reply.ContentType) + } + return nil +} diff --git a/ziti/cmd/ziti/cmd/agent_simple.go b/ziti/cmd/ziti/cmd/agent_simple.go index f5257f473..1a3507b98 100644 --- a/ziti/cmd/ziti/cmd/agent_simple.go +++ b/ziti/cmd/ziti/cmd/agent_simple.go @@ -18,23 +18,21 @@ package cmd import ( "github.com/openziti/foundation/agent" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" - "io" "os" ) -type SimpleAgentCmdOptions struct { - PsOptions +type SimpleAgentAction struct { + agentcli.AgentOptions } -func NewSimpleAgentCustomCmd(name string, appId AgentAppId, op byte, out io.Writer, errOut io.Writer) *cobra.Command { - options := &SimpleAgentCmdOptions{ - PsOptions: PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, - }, +func NewSimpleAgentCustomCmd(name string, appId AgentAppId, op byte, p common.OptionsProvider) *cobra.Command { + action := &SimpleAgentAction{ + AgentOptions: agentcli.AgentOptions{ + CommonOptions: p(), }, } @@ -42,21 +40,19 @@ func NewSimpleAgentCustomCmd(name string, appId AgentAppId, op byte, out io.Writ Args: cobra.MaximumNArgs(1), Use: name + " ", Run: func(cmd *cobra.Command, args []string) { - options.Cmd = cmd - options.Args = args - err := options.Run(appId, op) + action.Cmd = cmd + action.Args = args + err := action.Run(appId, op) cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) - return cmd } // Run implements the command -func (o *SimpleAgentCmdOptions) Run(appId AgentAppId, op byte) error { - addr, err := agent.ParseGopsAddress(o.Args) +func (self *SimpleAgentAction) Run(appId AgentAppId, op byte) error { + addr, err := agent.ParseGopsAddress(self.Args) if err != nil { return err } diff --git a/ziti/cmd/ziti/cmd/agentcli/agent.go b/ziti/cmd/ziti/cmd/agentcli/agent.go new file mode 100644 index 000000000..da9955e3d --- /dev/null +++ b/ziti/cmd/ziti/cmd/agentcli/agent.go @@ -0,0 +1,59 @@ +package agentcli + +import ( + "github.com/openziti/channel" + "github.com/openziti/foundation/agent" + "github.com/openziti/foundation/identity/identity" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + "github.com/spf13/cobra" + "net" + "time" +) + +func NewAgentCmd(p common.OptionsProvider) *cobra.Command { + agentCmd := &cobra.Command{ + Use: "agent", + Short: "Interact with ziti processes using the the IPC agent", + Run: func(cmd *cobra.Command, args []string) { + cmdhelper.CheckErr(cmd.Help()) + }, + } + + agentCmd.AddCommand(NewGoVersionCmd(p)) + agentCmd.AddCommand(NewGcCmd(p)) + agentCmd.AddCommand(NewSetGcCmd(p)) + agentCmd.AddCommand(NewStackCmd(p)) + agentCmd.AddCommand(NewMemstatsCmd(p)) + agentCmd.AddCommand(NewStatsCmd(p)) + agentCmd.AddCommand(NewPprofHeapCmd(p)) + agentCmd.AddCommand(NewPprofCpuCmd(p)) + agentCmd.AddCommand(NewTraceCmd(p)) + agentCmd.AddCommand(NewSetLogLevelCmd(p)) + agentCmd.AddCommand(NewSetChannelLogLevelCmd(p)) + agentCmd.AddCommand(NewClearChannelLogLevelCmd(p)) + + return agentCmd +} + +// AgentOptions contains the command line options +type AgentOptions struct { + common.CommonOptions +} + +func NewAgentChannel(conn net.Conn) (channel.Channel, error) { + options := channel.DefaultOptions() + options.ConnectTimeout = time.Second + dialer := channel.NewExistingConnDialer(&identity.TokenId{Token: "agent"}, conn, nil) + return channel.NewChannel("agent", dialer, nil, options) +} + +func MakeAgentChannelRequest(addr string, signal byte, params []byte, f func(ch channel.Channel) error) error { + return agent.MakeRequestF(addr, signal, params, func(conn net.Conn) error { + ch, err := NewAgentChannel(conn) + if err != nil { + return err + } + return f(ch) + }) +} diff --git a/ziti/cmd/ziti/cmd/ps_clear_channel_log_level.go b/ziti/cmd/ziti/cmd/agentcli/agent_clear_channel_log_level.go similarity index 71% rename from ziti/cmd/ziti/cmd/ps_clear_channel_log_level.go rename to ziti/cmd/ziti/cmd/agentcli/agent_clear_channel_log_level.go index 391dc1076..6fff36158 100644 --- a/ziti/cmd/ziti/cmd/ps_clear_channel_log_level.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_clear_channel_log_level.go @@ -14,31 +14,26 @@ limitations under the License. */ -package cmd +package agentcli import ( "bytes" "encoding/binary" "github.com/openziti/foundation/agent" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" - "io" "os" ) -type PsClearChannelLogLevelOptions struct { - PsOptions - CtrlListener string +type AgentClearChannelLogLevelAction struct { + AgentOptions } -// NewCmdPsClearChannelLogLevel creates a command object for the "create" command -func NewCmdPsClearChannelLogLevel(out io.Writer, errOut io.Writer) *cobra.Command { - options := &PsClearChannelLogLevelOptions{ - PsOptions: PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, - }, +func NewClearChannelLogLevelCmd(p common.OptionsProvider) *cobra.Command { + options := &AgentClearChannelLogLevelAction{ + AgentOptions: AgentOptions{ + CommonOptions: p(), }, } @@ -54,22 +49,20 @@ func NewCmdPsClearChannelLogLevel(out io.Writer, errOut io.Writer) *cobra.Comman }, } - options.addCommonFlags(cmd) - return cmd } // Run implements the command -func (o *PsClearChannelLogLevelOptions) Run() error { +func (self *AgentClearChannelLogLevelAction) Run() error { var addr string var err error var channelArg string - if len(o.Args) == 1 { + if len(self.Args) == 1 { addr, err = agent.ParseGopsAddress(nil) - channelArg = o.Args[0] + channelArg = self.Args[0] } else { - addr, err = agent.ParseGopsAddress(o.Args) - channelArg = o.Args[1] + addr, err = agent.ParseGopsAddress(self.Args) + channelArg = self.Args[1] } if err != nil { diff --git a/ziti/cmd/ziti/cmd/ps_gc.go b/ziti/cmd/ziti/cmd/agentcli/agent_gc.go similarity index 66% rename from ziti/cmd/ziti/cmd/ps_gc.go rename to ziti/cmd/ziti/cmd/agentcli/agent_gc.go index 3b00584b4..8f9d97de4 100644 --- a/ziti/cmd/ziti/cmd/ps_gc.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_gc.go @@ -14,30 +14,24 @@ limitations under the License. */ -package cmd +package agentcli import ( "github.com/openziti/foundation/agent" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" - "io" "os" ) -// PsGcOptions the options for the create spring command -type PsGcOptions struct { - PsOptions - CtrlListener string +type AgentGcAction struct { + AgentOptions } -// NewCmdPsGc creates a command object for the "create" command -func NewCmdPsGc(out io.Writer, errOut io.Writer) *cobra.Command { - options := &PsGcOptions{ - PsOptions: PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, - }, +func NewGcCmd(p common.OptionsProvider) *cobra.Command { + action := &AgentGcAction{ + AgentOptions: AgentOptions{ + CommonOptions: p(), }, } @@ -46,21 +40,19 @@ func NewCmdPsGc(out io.Writer, errOut io.Writer) *cobra.Command { Short: "Run garbage collection in the target application", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - options.Cmd = cmd - options.Args = args - err := options.Run() + action.Cmd = cmd + action.Args = args + err := action.Run() cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) - return cmd } // Run implements the command -func (o *PsGcOptions) Run() error { - addr, err := agent.ParseGopsAddress(o.Args) +func (self *AgentGcAction) Run() error { + addr, err := agent.ParseGopsAddress(self.Args) if err != nil { return err } diff --git a/ziti/cmd/ziti/cmd/ps_get.go b/ziti/cmd/ziti/cmd/agentcli/agent_get.go similarity index 75% rename from ziti/cmd/ziti/cmd/ps_get.go rename to ziti/cmd/ziti/cmd/agentcli/agent_get.go index 546415686..b2a5dbcd2 100644 --- a/ziti/cmd/ziti/cmd/ps_get.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_get.go @@ -14,34 +14,28 @@ limitations under the License. */ -package cmd +package agentcli import ( "fmt" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" "github.com/shirou/gopsutil/process" "github.com/spf13/cobra" - "io" "strconv" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/openziti/ziti/ziti/cmd/ziti/internal/log" ) -// PsGetOptions the options for the create spring command -type PsGetOptions struct { - PsOptions - - CtrlListener string +type AgentGetOptionsAction struct { + AgentOptions + Pid string } -// NewCmdPsGet creates a command object for the "create" command -func NewCmdPsGet(out io.Writer, errOut io.Writer) *cobra.Command { - options := &PsGetOptions{ - PsOptions: PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, - }, +func NewGetCmd(p common.OptionsProvider) *cobra.Command { + action := &AgentGetOptionsAction{ + AgentOptions: AgentOptions{ + CommonOptions: p(), }, } @@ -49,23 +43,22 @@ func NewCmdPsGet(out io.Writer, errOut io.Writer) *cobra.Command { Use: "get", Short: "Returns information about the target process", Run: func(cmd *cobra.Command, args []string) { - options.Cmd = cmd - options.Args = args - err := options.Run() + action.Cmd = cmd + action.Args = args + err := action.Run() cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) - cmd.Flags().StringVarP(&options.Flags.Pid, "pid", "", "", "pid (target of sub-cmd)") + cmd.Flags().StringVarP(&action.Pid, "pid", "", "", "pid (target of sub-cmd)") return cmd } // Run implements the command -func (o *PsGetOptions) Run() error { - pidStr := o.Args[0] - _, err := strconv.Atoi(o.Args[0]) +func (self *AgentGetOptionsAction) Run() error { + pidStr := self.Args[0] + _, err := strconv.Atoi(self.Args[0]) if err != nil { return err } diff --git a/ziti/cmd/ziti/cmd/ps_goversion.go b/ziti/cmd/ziti/cmd/agentcli/agent_go_version_action.go similarity index 66% rename from ziti/cmd/ziti/cmd/ps_goversion.go rename to ziti/cmd/ziti/cmd/agentcli/agent_go_version_action.go index c846d8e64..16a37e435 100644 --- a/ziti/cmd/ziti/cmd/ps_goversion.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_go_version_action.go @@ -14,30 +14,25 @@ limitations under the License. */ -package cmd +package agentcli import ( "github.com/openziti/foundation/agent" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" - "io" "os" ) -// PsGoversionOptions the options for the create spring command -type PsGoversionOptions struct { - PsOptions +type AgentGoVersionAction struct { + AgentOptions CtrlListener string } -// NewCmdPsGoversion creates a command object for the "create" command -func NewCmdPsGoversion(out io.Writer, errOut io.Writer) *cobra.Command { - options := &PsGoversionOptions{ - PsOptions: PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, - }, +func NewGoVersionCmd(p common.OptionsProvider) *cobra.Command { + action := &AgentGoVersionAction{ + AgentOptions: AgentOptions{ + CommonOptions: p(), }, } @@ -46,21 +41,19 @@ func NewCmdPsGoversion(out io.Writer, errOut io.Writer) *cobra.Command { Short: "Returns the golang version of the target application", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - options.Cmd = cmd - options.Args = args - err := options.Run() + action.Cmd = cmd + action.Args = args + err := action.Run() cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) - return cmd } // Run implements the command -func (o *PsGoversionOptions) Run() error { - addr, err := agent.ParseGopsAddress(o.Args) +func (self *AgentGoVersionAction) Run() error { + addr, err := agent.ParseGopsAddress(self.Args) if err != nil { return err } diff --git a/ziti/cmd/ziti/cmd/ps_memstats.go b/ziti/cmd/ziti/cmd/agentcli/agent_memstats.go similarity index 68% rename from ziti/cmd/ziti/cmd/ps_memstats.go rename to ziti/cmd/ziti/cmd/agentcli/agent_memstats.go index 733e5e3fc..9e2337a71 100644 --- a/ziti/cmd/ziti/cmd/ps_memstats.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_memstats.go @@ -14,30 +14,25 @@ limitations under the License. */ -package cmd +package agentcli import ( "github.com/openziti/foundation/agent" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" - "io" "os" ) -// PsMemstatsOptions the options for the create spring command -type PsMemstatsOptions struct { - PsOptions +type AgentMemstatsAction struct { + AgentOptions CtrlListener string } -// NewCmdPsMemstats creates a command object for the "create" command -func NewCmdPsMemstats(out io.Writer, errOut io.Writer) *cobra.Command { - options := &PsMemstatsOptions{ - PsOptions: PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, - }, +func NewMemstatsCmd(p common.OptionsProvider) *cobra.Command { + action := &AgentMemstatsAction{ + AgentOptions: AgentOptions{ + CommonOptions: p(), }, } @@ -46,20 +41,18 @@ func NewCmdPsMemstats(out io.Writer, errOut io.Writer) *cobra.Command { Short: "Returns memory use summary of the target application", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - options.Cmd = cmd - options.Args = args - err := options.Run() + action.Cmd = cmd + action.Args = args + err := action.Run() cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) - return cmd } // Run implements the command -func (o *PsMemstatsOptions) Run() error { +func (o *AgentMemstatsAction) Run() error { addr, err := agent.ParseGopsAddress(o.Args) if err != nil { return err diff --git a/ziti/cmd/ziti/cmd/ps_pprof_cpu.go b/ziti/cmd/ziti/cmd/agentcli/agent_pprof_cpu.go similarity index 65% rename from ziti/cmd/ziti/cmd/ps_pprof_cpu.go rename to ziti/cmd/ziti/cmd/agentcli/agent_pprof_cpu.go index 6abb8e9c7..46d7b2e6e 100644 --- a/ziti/cmd/ziti/cmd/ps_pprof_cpu.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_pprof_cpu.go @@ -14,30 +14,25 @@ limitations under the License. */ -package cmd +package agentcli import ( "github.com/openziti/foundation/agent" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" "io" "os" ) -// PsPprofCpuOptions the options for the create spring command -type PsPprofCpuOptions struct { - PsOptions - CtrlListener string +type AgentPprofCpuAction struct { + AgentOptions } -// NewCmdPsPprofCpu creates a command object for the "create" command -func NewCmdPsPprofCpu(out io.Writer, errOut io.Writer) *cobra.Command { - options := &PsPprofCpuOptions{ - PsOptions: PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, - }, +func NewPprofCpuCmd(p common.OptionsProvider) *cobra.Command { + action := &AgentPprofCpuAction{ + AgentOptions: AgentOptions{ + CommonOptions: p(), }, } @@ -46,28 +41,26 @@ func NewCmdPsPprofCpu(out io.Writer, errOut io.Writer) *cobra.Command { Short: "Runs and emits a 30 second pprof from the target application", Args: cobra.MaximumNArgs(2), Run: func(cmd *cobra.Command, args []string) { - options.Cmd = cmd - options.Args = args - err := options.Run() + action.Cmd = cmd + action.Args = args + err := action.Run() cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) - return cmd } // Run implements the command -func (o *PsPprofCpuOptions) Run() error { - addr, err := agent.ParseGopsAddress(o.Args) +func (self *AgentPprofCpuAction) Run() error { + addr, err := agent.ParseGopsAddress(self.Args) if err != nil { return err } var out io.WriteCloser = os.Stdout - if len(o.Args) > 1 { - out, err = os.Create(o.Args[1]) + if len(self.Args) > 1 { + out, err = os.Create(self.Args[1]) if err != nil { return err } diff --git a/ziti/cmd/ziti/cmd/ps_pprof_heap.go b/ziti/cmd/ziti/cmd/agentcli/agent_pprof_heap.go similarity index 64% rename from ziti/cmd/ziti/cmd/ps_pprof_heap.go rename to ziti/cmd/ziti/cmd/agentcli/agent_pprof_heap.go index ca7a383f3..74786676f 100644 --- a/ziti/cmd/ziti/cmd/ps_pprof_heap.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_pprof_heap.go @@ -14,29 +14,25 @@ limitations under the License. */ -package cmd +package agentcli import ( "github.com/openziti/foundation/agent" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" "io" "os" ) -// PsPprofHeapOptions the options for the create spring command -type PsPprofHeapOptions struct { - PsOptions +type AgentPprofHeapAction struct { + AgentOptions } -// NewCmdPsPprofHeap creates a command object for the "create" command -func NewCmdPsPprofHeap(out io.Writer, errOut io.Writer) *cobra.Command { - options := &PsPprofHeapOptions{ - PsOptions: PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, - }, +func NewPprofHeapCmd(p common.OptionsProvider) *cobra.Command { + action := &AgentPprofHeapAction{ + AgentOptions: AgentOptions{ + CommonOptions: p(), }, } @@ -44,28 +40,26 @@ func NewCmdPsPprofHeap(out io.Writer, errOut io.Writer) *cobra.Command { Use: "pprof-heap", Short: "Returns a memory heap pprof of the target application", Run: func(cmd *cobra.Command, args []string) { - options.Cmd = cmd - options.Args = args - err := options.Run() + action.Cmd = cmd + action.Args = args + err := action.Run() cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) - return cmd } // Run implements the command -func (o *PsPprofHeapOptions) Run() error { - addr, err := agent.ParseGopsAddress(o.Args) +func (self *AgentPprofHeapAction) Run() error { + addr, err := agent.ParseGopsAddress(self.Args) if err != nil { return err } var out io.WriteCloser = os.Stdout - if len(o.Args) > 1 { - out, err = os.Create(o.Args[1]) + if len(self.Args) > 1 { + out, err = os.Create(self.Args[1]) if err != nil { return err } diff --git a/ziti/cmd/ziti/cmd/ps_set_channel_log_level.go b/ziti/cmd/ziti/cmd/agentcli/agent_set_channel_log_level.go similarity index 72% rename from ziti/cmd/ziti/cmd/ps_set_channel_log_level.go rename to ziti/cmd/ziti/cmd/agentcli/agent_set_channel_log_level.go index d3ec563fa..1b7288cfa 100644 --- a/ziti/cmd/ziti/cmd/ps_set_channel_log_level.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_set_channel_log_level.go @@ -14,34 +14,29 @@ limitations under the License. */ -package cmd +package agentcli import ( "bytes" "encoding/binary" "github.com/openziti/foundation/agent" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "io" "os" "strings" ) -type PsSetChannelLogLevelOptions struct { - PsOptions - CtrlListener string +type AgentSetChannelLogLevelAction struct { + AgentOptions } -// NewCmdPsSetChannelLogLevel creates a command object for the "create" command -func NewCmdPsSetChannelLogLevel(out io.Writer, errOut io.Writer) *cobra.Command { - options := &PsSetChannelLogLevelOptions{ - PsOptions: PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, - }, +func NewSetChannelLogLevelCmd(p common.OptionsProvider) *cobra.Command { + action := &AgentSetChannelLogLevelAction{ + AgentOptions: AgentOptions{ + CommonOptions: p(), }, } @@ -50,32 +45,30 @@ func NewCmdPsSetChannelLogLevel(out io.Writer, errOut io.Writer) *cobra.Command Short: "Sets a channel-specific log level in the target application", Args: cobra.MinimumNArgs(2), Run: func(cmd *cobra.Command, args []string) { - options.Cmd = cmd - options.Args = args - err := options.Run() + action.Cmd = cmd + action.Args = args + err := action.Run() cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) - return cmd } // Run implements the command -func (o *PsSetChannelLogLevelOptions) Run() error { +func (self *AgentSetChannelLogLevelAction) Run() error { var addr string var err error var channelArg string var levelArg string - if len(o.Args) == 2 { + if len(self.Args) == 2 { addr, err = agent.ParseGopsAddress(nil) - channelArg = o.Args[0] - levelArg = o.Args[1] + channelArg = self.Args[0] + levelArg = self.Args[1] } else { - addr, err = agent.ParseGopsAddress(o.Args) - channelArg = o.Args[1] - levelArg = o.Args[2] + addr, err = agent.ParseGopsAddress(self.Args) + channelArg = self.Args[1] + levelArg = self.Args[2] } if err != nil { diff --git a/ziti/cmd/ziti/cmd/ps_set_log_level.go b/ziti/cmd/ziti/cmd/agentcli/agent_set_log_level.go similarity index 70% rename from ziti/cmd/ziti/cmd/ps_set_log_level.go rename to ziti/cmd/ziti/cmd/agentcli/agent_set_log_level.go index 347fdd4bc..f129592a9 100644 --- a/ziti/cmd/ziti/cmd/ps_set_log_level.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_set_log_level.go @@ -14,33 +14,27 @@ limitations under the License. */ -package cmd +package agentcli import ( "github.com/openziti/foundation/agent" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" - "io" "os" "strings" ) -// PsSetgcOptions the options for the create spring command -type PsSetLogLevelOptions struct { - PsOptions - CtrlListener string +type AgentSetLogLevelAction struct { + AgentOptions } -// NewCmdPsLogLevel creates a command object for the "create" command -func NewCmdPsSetLogLevel(out io.Writer, errOut io.Writer) *cobra.Command { - options := &PsSetLogLevelOptions{ - PsOptions: PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, - }, +func NewSetLogLevelCmd(p common.OptionsProvider) *cobra.Command { + action := &AgentSetLogLevelAction{ + AgentOptions: AgentOptions{ + CommonOptions: p(), }, } @@ -49,29 +43,27 @@ func NewCmdPsSetLogLevel(out io.Writer, errOut io.Writer) *cobra.Command { Short: "Sets the global logrus logging level in the target application", Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - options.Cmd = cmd - options.Args = args - err := options.Run() + action.Cmd = cmd + action.Args = args + err := action.Run() cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) - return cmd } // Run implements the command -func (o *PsSetLogLevelOptions) Run() error { +func (self *AgentSetLogLevelAction) Run() error { var addr string var err error var levelArg string - if len(o.Args) == 1 { + if len(self.Args) == 1 { addr, err = agent.ParseGopsAddress(nil) - levelArg = o.Args[0] + levelArg = self.Args[0] } else { - addr, err = agent.ParseGopsAddress(o.Args) - levelArg = o.Args[1] + addr, err = agent.ParseGopsAddress(self.Args) + levelArg = self.Args[1] } if err != nil { diff --git a/ziti/cmd/ziti/cmd/ps_setgc.go b/ziti/cmd/ziti/cmd/agentcli/agent_setgc.go similarity index 74% rename from ziti/cmd/ziti/cmd/ps_setgc.go rename to ziti/cmd/ziti/cmd/agentcli/agent_setgc.go index 3101cb9f8..b3e68d537 100644 --- a/ziti/cmd/ziti/cmd/ps_setgc.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_setgc.go @@ -14,32 +14,26 @@ limitations under the License. */ -package cmd +package agentcli import ( "encoding/binary" "github.com/openziti/foundation/agent" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" - "io" "os" "strconv" ) -// PsSetgcOptions the options for the create spring command -type PsSetgcOptions struct { - PsOptions - CtrlListener string +type AgentSetGcAction struct { + AgentOptions } -// NewCmdPsSetgc creates a command object for the "create" command -func NewCmdPsSetgc(out io.Writer, errOut io.Writer) *cobra.Command { - options := &PsSetgcOptions{ - PsOptions: PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, - }, +func NewSetGcCmd(p common.OptionsProvider) *cobra.Command { + action := &AgentSetGcAction{ + AgentOptions: AgentOptions{ + CommonOptions: p(), }, } @@ -48,20 +42,18 @@ func NewCmdPsSetgc(out io.Writer, errOut io.Writer) *cobra.Command { Short: "Sets the GC percentage in the target application", Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - options.Cmd = cmd - options.Args = args - err := options.Run() + action.Cmd = cmd + action.Args = args + err := action.Run() cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) - return cmd } // Run implements the command -func (o *PsSetgcOptions) Run() error { +func (o *AgentSetGcAction) Run() error { var addr string var err error var pctArg string diff --git a/ziti/cmd/ziti/cmd/ps_stack.go b/ziti/cmd/ziti/cmd/agentcli/agent_stack.go similarity index 66% rename from ziti/cmd/ziti/cmd/ps_stack.go rename to ziti/cmd/ziti/cmd/agentcli/agent_stack.go index d55ca6a36..b278aab1f 100644 --- a/ziti/cmd/ziti/cmd/ps_stack.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_stack.go @@ -14,32 +14,26 @@ limitations under the License. */ -package cmd +package agentcli import ( "github.com/openziti/foundation/agent" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" - "io" "os" "time" ) -// PsStackOptions the options for the create spring command -type PsStackOptions struct { - PsOptions - CtrlListener string +type AgentStackAction struct { + AgentOptions StackTimeout time.Duration } -// NewCmdPsStack creates a command object for the "create" command -func NewCmdPsStack(out io.Writer, errOut io.Writer) *cobra.Command { - options := &PsStackOptions{ - PsOptions: PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, - }, +func NewStackCmd(p common.OptionsProvider) *cobra.Command { + action := &AgentStackAction{ + AgentOptions: AgentOptions{ + CommonOptions: p(), }, } @@ -48,21 +42,20 @@ func NewCmdPsStack(out io.Writer, errOut io.Writer) *cobra.Command { Use: "stack []", Short: "Emits a go-routine stack dump from the target application", Run: func(cmd *cobra.Command, args []string) { - options.Cmd = cmd - options.Args = args - err := options.Run() + action.Cmd = cmd + action.Args = args + err := action.Run() cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) - cmd.Flags().DurationVar(&options.StackTimeout, "stack-timeout", 5*time.Second, "Timeout for stack operation") + cmd.Flags().DurationVar(&action.StackTimeout, "stack-timeout", 5*time.Second, "Timeout for stack operation") return cmd } // Run implements the command -func (o *PsStackOptions) Run() error { +func (o *AgentStackAction) Run() error { time.AfterFunc(o.StackTimeout, func() { os.Exit(-1) }) diff --git a/ziti/cmd/ziti/cmd/ps_stats.go b/ziti/cmd/ziti/cmd/agentcli/agent_stats.go similarity index 66% rename from ziti/cmd/ziti/cmd/ps_stats.go rename to ziti/cmd/ziti/cmd/agentcli/agent_stats.go index 485dc1a78..8116e16b7 100644 --- a/ziti/cmd/ziti/cmd/ps_stats.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_stats.go @@ -14,30 +14,24 @@ limitations under the License. */ -package cmd +package agentcli import ( "github.com/openziti/foundation/agent" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" - "io" "os" ) -// PsStatsOptions the options for the create spring command -type PsStatsOptions struct { - PsOptions - CtrlListener string +type AgentStatsAction struct { + AgentOptions } -// NewCmdPsStats creates a command object for the "create" command -func NewCmdPsStats(out io.Writer, errOut io.Writer) *cobra.Command { - options := &PsStatsOptions{ - PsOptions: PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, - }, +func NewStatsCmd(p common.OptionsProvider) *cobra.Command { + action := &AgentStatsAction{ + AgentOptions: AgentOptions{ + CommonOptions: p(), }, } @@ -46,21 +40,19 @@ func NewCmdPsStats(out io.Writer, errOut io.Writer) *cobra.Command { Short: "Emits some runtime information (# go-routines, threads, cpus, etc) from the target application", Args: cobra.MaximumNArgs(1), Run: func(cmd *cobra.Command, args []string) { - options.Cmd = cmd - options.Args = args - err := options.Run() + action.Cmd = cmd + action.Args = args + err := action.Run() cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) - return cmd } // Run implements the command -func (o *PsStatsOptions) Run() error { - addr, err := agent.ParseGopsAddress(o.Args) +func (self *AgentStatsAction) Run() error { + addr, err := agent.ParseGopsAddress(self.Args) if err != nil { return err } diff --git a/ziti/cmd/ziti/cmd/ps_trace.go b/ziti/cmd/ziti/cmd/agentcli/agent_trace.go similarity index 65% rename from ziti/cmd/ziti/cmd/ps_trace.go rename to ziti/cmd/ziti/cmd/agentcli/agent_trace.go index 885f8d5b8..09e24e491 100644 --- a/ziti/cmd/ziti/cmd/ps_trace.go +++ b/ziti/cmd/ziti/cmd/agentcli/agent_trace.go @@ -14,29 +14,24 @@ limitations under the License. */ -package cmd +package agentcli import ( "github.com/openziti/foundation/agent" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" - "io" "os" ) -// PsTraceOptions the options for the create spring command -type PsTraceOptions struct { - PsOptions +type AgentTraceAction struct { + AgentOptions } -// NewCmdPsTrace creates a command object for the "create" command -func NewCmdPsTrace(out io.Writer, errOut io.Writer) *cobra.Command { - options := &PsTraceOptions{ - PsOptions: PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, - }, +func NewTraceCmd(p common.OptionsProvider) *cobra.Command { + action := &AgentTraceAction{ + AgentOptions: AgentOptions{ + CommonOptions: p(), }, } @@ -44,21 +39,19 @@ func NewCmdPsTrace(out io.Writer, errOut io.Writer) *cobra.Command { Use: "trace", Short: "Turn tracing on for 5 seconds in the target application", Run: func(cmd *cobra.Command, args []string) { - options.Cmd = cmd - options.Args = args - err := options.Run() + action.Cmd = cmd + action.Args = args + err := action.Run() cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) - return cmd } // Run implements the command -func (o *PsTraceOptions) Run() error { - addr, err := agent.ParseGopsAddress(o.Args) +func (self *AgentTraceAction) Run() error { + addr, err := agent.ParseGopsAddress(self.Args) if err != nil { return err } diff --git a/ziti/cmd/ziti/cmd/api/delete.go b/ziti/cmd/ziti/cmd/api/delete.go index 33e47840f..5f5d73b8e 100644 --- a/ziti/cmd/ziti/cmd/api/delete.go +++ b/ziti/cmd/ziti/cmd/api/delete.go @@ -1,3 +1,19 @@ +/* + 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 api import ( diff --git a/ziti/cmd/ziti/cmd/api/json.go b/ziti/cmd/ziti/cmd/api/json.go index dcf99d538..832a2a75d 100644 --- a/ziti/cmd/ziti/cmd/api/json.go +++ b/ziti/cmd/ziti/cmd/api/json.go @@ -1,6 +1,27 @@ +/* + 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 api -import "github.com/Jeffail/gabs" +import ( + "fmt" + "github.com/Jeffail/gabs" + gabs2 "github.com/Jeffail/gabs/v2" + "strings" +) func SetJSONValue(container *gabs.Container, value interface{}, path ...string) { if _, err := container.Set(value, path...); err != nil { @@ -22,3 +43,129 @@ func GetJsonString(container *gabs.Container, path string) string { } return "" } + +func Wrap(c *gabs.Container) *GabsWrapper { + return &GabsWrapper{Container: c} +} + +func Wrap2(c *gabs2.Container) *Gabs2Wrapper { + return &Gabs2Wrapper{Container: c} +} + +type GabsWrapper struct { + *gabs.Container +} + +func (self *GabsWrapper) String(path string) string { + child := self.Path(path) + if child == nil || child.Data() == nil { + return "" + } + return self.tostring(child.Data()) +} + +func (self *GabsWrapper) Bool(path string) bool { + child := self.Path(path) + if child == nil || child.Data() == nil { + return false + } + if val, ok := child.Data().(bool); ok { + return val + } + return strings.EqualFold("true", fmt.Sprintf("%v", child.Data())) +} + +func (self *GabsWrapper) tostring(val interface{}) string { + if val, ok := val.(string); ok { + return val + } + return fmt.Sprintf("%v", val) +} + +func (self *GabsWrapper) Float64(path string) float64 { + child := self.Path(path) + if child == nil || child.Data() == nil { + return 0 + } + if val, ok := child.Data().(float64); ok { + return val + } + return 0 +} + +func (self *GabsWrapper) StringSlice(path string) []string { + child := self.Path(path) + if child == nil || child.Data() == nil { + return nil + } + if val, ok := child.Data().([]string); ok { + return val + } + if vals, ok := child.Data().([]interface{}); ok { + var result []string + for _, val := range vals { + result = append(result, self.tostring(val)) + } + return result + } + return nil +} + +type Gabs2Wrapper struct { + *gabs2.Container +} + +func (self *Gabs2Wrapper) String(path string) string { + child := self.Path(path) + if child == nil || child.Data() == nil { + return "" + } + return self.tostring(child.Data()) +} + +func (self *Gabs2Wrapper) Bool(path string) bool { + child := self.Path(path) + if child == nil || child.Data() == nil { + return false + } + if val, ok := child.Data().(bool); ok { + return val + } + return strings.EqualFold("true", fmt.Sprintf("%v", child.Data())) +} + +func (self *Gabs2Wrapper) tostring(val interface{}) string { + if val, ok := val.(string); ok { + return val + } + return fmt.Sprintf("%v", val) +} + +func (self *Gabs2Wrapper) Float64(path string) float64 { + child := self.Path(path) + if child == nil || child.Data() == nil { + return 0 + } + if val, ok := child.Data().(float64); ok { + return val + } + return 0 +} + +func (self *Gabs2Wrapper) StringSlice(path string) []string { + child := self.Path(path) + if child == nil || child.Data() == nil { + return nil + } + if val, ok := child.Data().([]string); ok { + return val + } + if vals, ok := child.Data().([]interface{}); ok { + var result []string + for _, val := range vals { + result = append(result, self.tostring(val)) + } + return result + } + return nil +} diff --git a/ziti/cmd/ziti/cmd/api/list.go b/ziti/cmd/ziti/cmd/api/list.go index 930fefc5f..dea5eba0c 100644 --- a/ziti/cmd/ziti/cmd/api/list.go +++ b/ziti/cmd/ziti/cmd/api/list.go @@ -1,8 +1,25 @@ +/* + 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 api import ( "fmt" "github.com/Jeffail/gabs" + "github.com/jedib0t/go-pretty/v6/table" "github.com/openziti/foundation/util/errorz" "github.com/openziti/ziti/ziti/cmd/ziti/util" "github.com/pkg/errors" @@ -32,16 +49,16 @@ func ListEntitiesOfType(api util.API, entityType string, params url.Values, logJ } children, err := jsonParsed.S("data").Children() - return children, getPaging(jsonParsed), err + return children, GetPaging(jsonParsed), err } -func getPaging(c *gabs.Container) *Paging { +func GetPaging(c *gabs.Container) *Paging { pagingInfo := &Paging{} pagination := c.S("meta", "pagination") if pagination != nil { - pagingInfo.limit = toInt64(pagination, "limit", pagingInfo) - pagingInfo.offset = toInt64(pagination, "offset", pagingInfo) - pagingInfo.count = toInt64(pagination, "totalCount", pagingInfo) + pagingInfo.Limit = toInt64(pagination, "limit", pagingInfo) + pagingInfo.Offset = toInt64(pagination, "offset", pagingInfo) + pagingInfo.Count = toInt64(pagination, "totalCount", pagingInfo) } else { pagingInfo.SetError(errors.New("meta.pagination section not found in result")) } @@ -49,24 +66,24 @@ func getPaging(c *gabs.Container) *Paging { } type Paging struct { - limit int64 - offset int64 - count int64 + Limit int64 + Offset int64 + Count int64 errorz.ErrorHolderImpl } func (p *Paging) Output(o *Options) { if p.HasError() { _, _ = fmt.Fprintf(o.Out, "unable to retrieve paging information: %v\n", p.Err) - } else if p.count == 0 { + } else if p.Count == 0 { _, _ = fmt.Fprintln(o.Out, "results: none") } else { - first := p.offset + 1 - last := p.offset + p.limit - if last > p.count || last < 0 { // if p.limit is maxint, last will rollover and be negative - last = p.count + first := p.Offset + 1 + last := p.Offset + p.Limit + if last > p.Count || last < 0 { // if p.Limit is maxint, last will rollover and be negative + last = p.Count } - _, _ = fmt.Fprintf(o.Out, "results: %v-%v of %v\n", first, last, p.count) + _, _ = fmt.Fprintf(o.Out, "results: %v-%v of %v\n", first, last, p.Count) } } @@ -134,3 +151,18 @@ func MapNamesToIDs(api util.API, entityType string, o *Options, list ...string) } return result, nil } + +func RenderTable(o *Options, t table.Writer, pagingInfo *Paging) { + if o.OutputCSV { + if _, err := fmt.Fprintln(o.Cmd.OutOrStdout(), t.RenderCSV()); err != nil { + panic(err) + } + } else { + if _, err := fmt.Fprintln(o.Cmd.OutOrStdout(), t.Render()); err != nil { + panic(err) + } + if pagingInfo != nil { + pagingInfo.Output(o) + } + } +} diff --git a/ziti/cmd/ziti/cmd/api/options.go b/ziti/cmd/ziti/cmd/api/options.go index 0f71878bb..8bdd96a51 100644 --- a/ziti/cmd/ziti/cmd/api/options.go +++ b/ziti/cmd/ziti/cmd/api/options.go @@ -1,3 +1,19 @@ +/* + 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 api import ( diff --git a/ziti/cmd/ziti/cmd/api/ws.go b/ziti/cmd/ziti/cmd/api/ws.go new file mode 100644 index 000000000..4256c765a --- /dev/null +++ b/ziti/cmd/ziti/cmd/api/ws.go @@ -0,0 +1,78 @@ +/* + 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 api + +import ( + "fmt" + "github.com/gorilla/websocket" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/channel" + "github.com/openziti/channel/websockets" + "github.com/openziti/foundation/identity/identity" + "github.com/openziti/ziti/ziti/cmd/ziti/util" + "io" + "net/http" + "strings" + "time" +) + +func NewWsMgmtChannel(bindHandler channel.BindHandler) (channel.Channel, error) { + log := pfxlog.Logger() + restClientIdentity, err := util.LoadSelectedIdentityForApi(util.FabricAPI) + if err != nil { + return nil, err + } + + baseUrl, err := restClientIdentity.GetBaseUrlForApi(util.FabricAPI) + if err != nil { + return nil, err + } + + wsUrl := strings.ReplaceAll(baseUrl, "http", "ws") + "/ws-api" + fmt.Println(wsUrl) + tlsConfig, err := restClientIdentity.NewTlsClientConfig() + if err != nil { + return nil, err + } + + dialer := &websocket.Dialer{ + Proxy: http.ProxyFromEnvironment, + TLSClientConfig: tlsConfig, + HandshakeTimeout: 5 * time.Second, + } + + conn, resp, err := dialer.Dial(wsUrl, restClientIdentity.NewWsHeader()) + if err != nil { + if resp != nil { + if body, rerr := io.ReadAll(resp.Body); rerr == nil { + log.WithError(err).Errorf("response body [%v]", string(body)) + } + } else { + log.WithError(err).Error("no response from websocket dial") + } + return nil, err + } + + id := &identity.TokenId{Token: "mgmt"} + underlayFactory := websockets.NewUnderlayFactory(id, conn, nil) + + ch, err := channel.NewChannel("mgmt", underlayFactory, bindHandler, nil) + if err != nil { + return nil, err + } + return ch, nil +} diff --git a/ziti/cmd/ziti/cmd/art.go b/ziti/cmd/ziti/cmd/art.go index 7aa4548bb..ff6da6cf7 100644 --- a/ziti/cmd/ziti/cmd/art.go +++ b/ziti/cmd/ziti/cmd/art.go @@ -20,7 +20,6 @@ import ( "github.com/openziti/ziti/ziti/cmd/ziti/internal/log" "io" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" @@ -32,12 +31,11 @@ type ArtOptions struct { CommonOptions } -func NewCmdArt(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdArt(out io.Writer, errOut io.Writer) *cobra.Command { options := &ArtOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -51,7 +49,7 @@ func NewCmdArt(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Comman cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/cmd.go b/ziti/cmd/ziti/cmd/cmd.go index d8e361f5d..651947158 100644 --- a/ziti/cmd/ziti/cmd/cmd.go +++ b/ziti/cmd/ziti/cmd/cmd.go @@ -20,7 +20,10 @@ import ( goflag "flag" "fmt" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/database" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/demo" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/fabric" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial" "io" "os" "path/filepath" @@ -28,7 +31,6 @@ import ( "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" "github.com/openziti/ziti/ziti/cmd/ziti/internal/log" "github.com/openziti/ziti/ziti/cmd/ziti/util" @@ -45,8 +47,6 @@ type MainOptions struct { } type RootCmd struct { - factory cmdutil.Factory - configFile string RegistryPath string @@ -83,13 +83,10 @@ func Execute() { func init() { cobra.OnInitialize(initConfig) - factory := cmdutil.NewFactory() - rootCommand.factory = factory - NewCmdRoot(factory, os.Stdin, os.Stdout, os.Stderr) - + NewCmdRoot(os.Stdin, os.Stdout, os.Stderr) } -func NewCmdRoot(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Command { +func NewCmdRoot(in io.Reader, out, err io.Writer) *cobra.Command { cmd := rootCommand.cobraCommand @@ -127,22 +124,25 @@ func NewCmdRoot(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Comm p := common.NewOptionsProvider(out, err) - initCommands := NewCmdInit(f, out, err) - createCommands := NewCmdCreate(f, out, err) - updateCommands := NewCmdUpdate(f, out, err) - executeCommands := NewCmdExecute(f, out, err) - agentCommands := NewAgentCmd(out, err) - psCommands := NewCmdPs(out, err) - pkiCommands := NewCmdPKI(f, out, err) + initCommands := NewCmdInit(out, err) + createCommands := NewCmdCreate(out, err) + updateCommands := NewCmdUpdate(out, err) + executeCommands := NewCmdExecute(out, err) + agentCommands := NewAgentCmd(p) + psCommands := NewCmdPs(p) + pkiCommands := NewCmdPKI(out, err) fabricCommand := fabric.NewFabricCmd(p) - edgeCommand := edge.NewCmdEdge(f, out, err) - logFilter := NewCmdLogFormat(f, out, err) - unwrapIdentityFileCommand := NewUnwrapIdentityFileCommand(f, out, err) + edgeCommand := edge.NewCmdEdge(out, err) + tutorialCmd := tutorial.NewTutorialCmd(p) + demoCmd := demo.NewDemoCmd(p) + logFilter := NewCmdLogFormat(out, err) + unwrapIdentityFileCommand := NewUnwrapIdentityFileCommand(out, err) + dbCommand := database.NewCmdDb(out, err) installCommands := []*cobra.Command{ - NewCmdInstall(f, out, err), - NewCmdUnInstall(f, out, err), - NewCmdUpgrade(f, out, err), + NewCmdInstall(out, err), + NewCmdUnInstall(out, err), + NewCmdUpgrade(out, err), } groups := templates.CommandGroups{ @@ -179,20 +179,28 @@ func NewCmdRoot(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Comm Message: "Utilities", Commands: []*cobra.Command{ logFilter, + dbCommand, + }, + }, + { + Message: "Learning Ziti", + Commands: []*cobra.Command{ + demoCmd, + tutorialCmd, }, }, } groups.Add(cmd) - cmd.AddCommand(NewCmdVersion(f, out, err)) + cmd.AddCommand(NewCmdVersion(out, err)) cmd.Version = version.GetVersion() cmd.SetVersionTemplate("{{printf .Version}}\n") - cmd.AddCommand(NewCmdArt(f, out, err)) - cmd.AddCommand(NewCmdPlaybook(f, out, err)) - cmd.AddCommand(NewCmdPing(f, out, err)) - cmd.AddCommand(NewCmdAdhoc(f, out, err)) - cmd.AddCommand(NewCmdUse(f, out, err)) + cmd.AddCommand(NewCmdArt(out, err)) + cmd.AddCommand(NewCmdPlaybook(out, err)) + cmd.AddCommand(NewCmdPing(out, err)) + cmd.AddCommand(NewCmdAdhoc(out, err)) + cmd.AddCommand(NewCmdUse(out, err)) return cmd } diff --git a/ziti/cmd/ziti/cmd/common.go b/ziti/cmd/ziti/cmd/common.go index a83fdbd3a..0eba1c177 100644 --- a/ziti/cmd/ziti/cmd/common.go +++ b/ziti/cmd/ziti/cmd/common.go @@ -17,18 +17,12 @@ package cmd import ( - "fmt" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" - "github.com/openziti/ziti/ziti/cmd/ziti/internal/log" "github.com/spf13/cobra" "io" - "os" - "time" ) // CommonOptions contains common options and helper methods type CommonOptions struct { - Factory cmdutil.Factory Out io.Writer Err io.Writer Cmd *cobra.Command @@ -40,30 +34,7 @@ type CommonOptions struct { Timeout int } -type ServerFlags struct { - ServerName string - ServerURL string -} - -func (f *ServerFlags) IsEmpty() bool { - return f.ServerName == "" && f.ServerURL == "" -} - -func (c *CommonOptions) Stdout() io.Writer { - if c.Out != nil { - return c.Out - } - return os.Stdout -} - -// Debugf outputs the given text to the console if verbose mode is enabled -func (c *CommonOptions) Debugf(format string, a ...interface{}) { - if c.Verbose { - log.Infof(format, a...) - } -} - -func (options *CommonOptions) addCommonFlags(cmd *cobra.Command) { +func (options *CommonOptions) AddCommonFlags(cmd *cobra.Command) { cmd.Flags().BoolVarP(&options.BatchMode, "batch-mode", "b", false, "In batch mode the command never prompts for user input") cmd.Flags().BoolVarP(&options.Verbose, "verbose", "", false, "Enable verbose logging") cmd.Flags().BoolVarP(&options.Staging, "staging", "", false, "Install/Upgrade components from the ziti-staging repo") @@ -71,92 +42,3 @@ func (options *CommonOptions) addCommonFlags(cmd *cobra.Command) { cmd.Flags().IntVarP(&options.Timeout, "timeout", "t", 5, "Timeout for REST operations (specified in seconds)") options.Cmd = cmd } - -func (o *CommonOptions) retry(attempts int, sleep time.Duration, call func() error) (err error) { - for i := 0; ; i++ { - err = call() - if err == nil { - return - } - - if i >= (attempts - 1) { - break - } - - time.Sleep(sleep) - - log.Infof("retrying after error:%s\n", err) - } - return fmt.Errorf("after %d attempts, last error: %s", attempts, err) -} - -func (o *CommonOptions) retryQuiet(attempts int, sleep time.Duration, call func() error) (err error) { - lastMessage := "" - dot := false - - for i := 0; ; i++ { - err = call() - if err == nil { - if dot { - log.Blank() - } - return - } - - if i >= (attempts - 1) { - break - } - - time.Sleep(sleep) - - message := fmt.Sprintf("retrying after error: %s", err) - if lastMessage == message { - log.Info(".") - dot = true - } else { - lastMessage = message - if dot { - dot = false - log.Blank() - } - log.Infof("%s\n", lastMessage) - } - } - return fmt.Errorf("after %d attempts, last error: %s", attempts, err) -} - -func (o *CommonOptions) retryQuietlyUntilTimeout(timeout time.Duration, sleep time.Duration, call func() error) (err error) { - timeoutTime := time.Now().Add(timeout) - - lastMessage := "" - dot := false - - for i := 0; ; i++ { - err = call() - if err == nil { - if dot { - log.Blank() - } - return - } - - if time.Now().After(timeoutTime) { - return fmt.Errorf("Timed out after %s, last error: %s", timeout.String(), err) - } - - time.Sleep(sleep) - - message := fmt.Sprintf("retrying after error: %s", err) - if lastMessage == message { - log.Info(".") - dot = true - } else { - lastMessage = message - if dot { - dot = false - log.Blank() - } - log.Infof("%s\n", lastMessage) - } - } -} diff --git a/ziti/cmd/ziti/cmd/common/options.go b/ziti/cmd/ziti/cmd/common/options.go index 6139def7a..34db5f6e1 100644 --- a/ziti/cmd/ziti/cmd/common/options.go +++ b/ziti/cmd/ziti/cmd/common/options.go @@ -19,7 +19,6 @@ package common import ( "context" "fmt" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/table" "github.com/spf13/cobra" "io" "time" @@ -30,10 +29,6 @@ type Printer interface { Println(val interface{}) } -type Factory interface { - CreateTable(out io.Writer) table.Table -} - type OptionsProvider func() CommonOptions func NewOptionsProvider(out, err io.Writer) OptionsProvider { @@ -47,7 +42,6 @@ func NewOptionsProvider(out, err io.Writer) OptionsProvider { // CommonOptions contains common options and helper methods type CommonOptions struct { - Factory Factory Out io.Writer Err io.Writer Cmd *cobra.Command @@ -66,6 +60,18 @@ func (options *CommonOptions) TimeoutContext() (context.Context, context.CancelF return context.WithTimeout(context.Background(), timeout) } +func (options *CommonOptions) GetFilter() *string { + if len(options.Args) > 0 { + return &options.Args[0] + } + return nil +} + +func (options *CommonOptions) GetContext() context.Context { + ctx, _ := context.WithTimeout(context.Background(), time.Second*time.Duration(options.Timeout)) + return ctx +} + func (options *CommonOptions) Printf(format string, args ...interface{}) { if _, err := fmt.Fprintf(options.Out, format, args...); err != nil { panic(err) diff --git a/ziti/cmd/ziti/cmd/config_templates/controller.yml b/ziti/cmd/ziti/cmd/config_templates/controller.yml index 2c1828f06..9c166c64d 100644 --- a/ziti/cmd/ziti/cmd/config_templates/controller.yml +++ b/ziti/cmd/ziti/cmd/config_templates/controller.yml @@ -15,6 +15,52 @@ identity: key: "{{ .Controller.IdentityKey }}" ca: "{{ .Controller.IdentityCA }}" +# Network Configuration +# +# Configure how the controller will establish and manage the overlay network, and routing operations on top of +# the network. +# +#network: + + # routeTimeoutSeconds controls the number of seconds the controller will wait for a route attempt to succeed. + #routeTimeoutSeconds: 10 + + # createCircuitRetries controls the number of retries that will be attempted to create a path (and terminate it) + # for new circuits. + #createCircuitRetries: 2 + + # pendingLinkTimeoutSeconds controls how long we'll wait before creating a new link between routers where + # there isn't an established link, but a link request has been sent + #pendingLinkTimeoutSeconds: 10 + + # Defines the period that the controller re-evaluates the performance of all of the circuits + # running on the network. + # + #cycleSeconds: 15 + + # Sets router minimum cost. Defaults to 10 + #minRouterCost: 10 + + # Sets how often a new control channel connection can take over for a router with an existing control channel connection + # Defaults to 1 minute + #routerConnectChurnLimit: 1m + + #smart: + # + # Defines the fractional upper limit of underperforming circuits that are candidates to be re-routed. If + # smart routing detects 100 circuits that are underperforming, and `smart.rerouteFraction` is set to `0.02`, + # then the upper limit of circuits that will be re-routed in this `cycleSeconds` period will be limited to + # 2 (2% of 100). + # + #rerouteFraction: 0.02 + # + # Defines the hard upper limit of underperforming circuits that are candidates to be re-routed. If smart + # routing detects 100 circuits that are underperforming, and `smart.rerouteCap` is set to `1`, and + # `smart.rerouteFraction` is set to `0.02`, then the upper limit of circuits that will be re-routed in this + # `cycleSeconds` period will be limited to 1. + # + #rerouteCap: 4 + # the endpoint that routers will connect to the controller over. ctrl: #options: @@ -88,14 +134,14 @@ edge: # edgeIdentity - optional # A section for identity enrollment specific settings edgeIdentity: - # durationMinutes - optional, default {{ .Controller.EdgeIdentityDuration.Minutes }}m + # duration - optional, default {{ .Controller.EdgeIdentityDuration.Minutes }}m # The length of time that a Ziti Edge Identity enrollment should remain valid. After # this duration, the enrollment will expire and no longer be usable. duration: {{ .Controller.EdgeIdentityDuration.Minutes }}m # edgeRouter - Optional # A section for edge router enrollment specific settings. edgeRouter: - # durationMinutes - optional, default {{ .Controller.EdgeRouterDuration.Minutes }}m + # duration - optional, default {{ .Controller.EdgeRouterDuration.Minutes }}m # The length of time that a Ziti Edge Router enrollment should remain valid. After # this duration, the enrollment will expire and no longer be usable. duration: {{ .Controller.EdgeRouterDuration.Minutes }}m @@ -169,4 +215,4 @@ web: - binding: edge-client options: { } - binding: fabric - options: { } \ No newline at end of file + options: { } diff --git a/ziti/cmd/ziti/cmd/create.go b/ziti/cmd/ziti/cmd/create.go index efeb310b0..d81a4a586 100644 --- a/ziti/cmd/ziti/cmd/create.go +++ b/ziti/cmd/ziti/cmd/create.go @@ -17,7 +17,6 @@ package cmd import ( - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" "github.com/spf13/cobra" "io" @@ -33,7 +32,7 @@ var ( ) // NewCmdCreate creates a command object for the "create" command -func NewCmdCreate(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdCreate(out io.Writer, errOut io.Writer) *cobra.Command { cmd := &cobra.Command{ Use: "create", Short: "Create a new resource", @@ -44,13 +43,13 @@ func NewCmdCreate(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Com } cmd.AddCommand(NewCmdCreateConfig()) - cmd.AddCommand(NewCmdCreateEnvironment(f, out, errOut)) + cmd.AddCommand(NewCmdCreateEnvironment(out, errOut)) - cmd.AddCommand(NewCmdPKICreateCA(f, out, errOut)) - cmd.AddCommand(NewCmdPKICreateIntermediate(f, out, errOut)) - cmd.AddCommand(NewCmdPKICreateServer(f, out, errOut)) - cmd.AddCommand(NewCmdPKICreateClient(f, out, errOut)) - cmd.AddCommand(NewCmdPKICreateCSR(f, out, errOut)) + cmd.AddCommand(NewCmdPKICreateCA(out, errOut)) + cmd.AddCommand(NewCmdPKICreateIntermediate(out, errOut)) + cmd.AddCommand(NewCmdPKICreateServer(out, errOut)) + cmd.AddCommand(NewCmdPKICreateClient(out, errOut)) + cmd.AddCommand(NewCmdPKICreateCSR(out, errOut)) return cmd } diff --git a/ziti/cmd/ziti/cmd/create_config_router_common.go b/ziti/cmd/ziti/cmd/create_config_router_common.go index 8ac190ee4..6bcf98596 100644 --- a/ziti/cmd/ziti/cmd/create_config_router_common.go +++ b/ziti/cmd/ziti/cmd/create_config_router_common.go @@ -29,9 +29,12 @@ func SetZitiRouterIdentity(r *RouterTemplateValues, routerName string) { SetZitiRouterIdentityKey(r, routerName) SetZitiRouterIdentityCA(r, routerName) - val := os.Getenv(constants.ZitiEdgeRouterRawNameVarName) - if val != "" { - r.Edge.Hostname = val + edgeRouterRawName := os.Getenv(constants.ZitiEdgeRouterRawNameVarName) + externalDNS := os.Getenv(constants.ExternalDNSVarName) + if externalDNS != "" { + r.Edge.Hostname = externalDNS + } else if edgeRouterRawName != "" { + r.Edge.Hostname = edgeRouterRawName } else { r.Edge.Hostname, _ = os.Hostname() } diff --git a/ziti/cmd/ziti/cmd/create_config_test.go b/ziti/cmd/ziti/cmd/create_config_test.go index 03e9f56c1..9df823841 100644 --- a/ziti/cmd/ziti/cmd/create_config_test.go +++ b/ziti/cmd/ziti/cmd/create_config_test.go @@ -21,6 +21,7 @@ func getZitiEnvironmentVariables() []string { "ZITI_EDGE_CTRL_IDENTITY_SERVER_CERT", "ZITI_EDGE_CTRL_IDENTITY_KEY", "ZITI_EDGE_CTRL_IDENTITY_CA", + "ZITI_EDGE_CONTROLLER_PORT", "ZITI_CTRL_IDENTITY_CERT", "ZITI_CTRL_IDENTITY_SERVER_CERT", "ZITI_CTRL_IDENTITY_KEY", diff --git a/ziti/cmd/ziti/cmd/create_environment.go b/ziti/cmd/ziti/cmd/create_environment.go index 0a707c3f9..8de9e05af 100644 --- a/ziti/cmd/ziti/cmd/create_environment.go +++ b/ziti/cmd/ziti/cmd/create_environment.go @@ -19,7 +19,6 @@ 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/internal/log" "github.com/openziti/ziti/ziti/cmd/ziti/util" @@ -34,12 +33,11 @@ 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 { +func NewCmdCreateEnvironment(out io.Writer, errOut io.Writer) *cobra.Command { options := &CreateEnvironmentOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } diff --git a/ziti/cmd/ziti/cmd/database/cmd.go b/ziti/cmd/ziti/cmd/database/cmd.go new file mode 100644 index 000000000..37f82f1c1 --- /dev/null +++ b/ziti/cmd/ziti/cmd/database/cmd.go @@ -0,0 +1,26 @@ +package database + +import ( + "fmt" + "github.com/openziti/ziti-db-explorer/cmd/ziti-db-explorer/zdecli" + "github.com/openziti/ziti/ziti/cmd/ziti/util" + "github.com/spf13/cobra" + "io" +) + +func NewCmdDb(_ io.Writer, errOut io.Writer) *cobra.Command { + cmd := util.NewEmptyParentCmd("db", "Interact with Ziti database files") + + exploreCmd := &cobra.Command{ + Use: "explore |help|version", + Short: "Interactive CLI to explore Ziti database files", + Run: func(cmd *cobra.Command, args []string) { + if err := zdecli.Run("ziti db explore", args[0]); err != nil { + _, _ = errOut.Write([]byte(fmt.Sprintf("Error: %s", err))) + } + }, + } + + cmd.AddCommand(exploreCmd) + return cmd +} diff --git a/ziti/cmd/ziti/cmd/demo/echo-notes.txt b/ziti/cmd/ziti/cmd/demo/echo-notes.txt new file mode 100644 index 000000000..3ad48a954 --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/echo-notes.txt @@ -0,0 +1,51 @@ +Before start + +1. reset controller +2. start controller +3. login + +Part 1 - single router, single server +1. show zcat and echo-server +2. create first edge router, mark with demo attribute +3. client setup +4. do sdk demo +5. look at terminators +6. do tunneler demo +7. look at terminators + +Part 2 - multi-router, single server +1. Add additional edge router, mark with demo attribute +2. start edge router 2 +3. Do sdk demo +4. show multiple terminators + a. stop/restart router, show terminator there, but unused. Show terminator replaced. +5. Make sure it's tunneler ready + a. make sure it's a tunneler + b. Add identity attributes: ziti edge update identity edge-router-2 -a echo,echo-host +6. Do tunneler demo +7. Show multiple terminators + +Part 3 - multi-router, multi-server, SDK hosted, HS +1. Do sdk demo +2. Show terminators + a. show updating precedence cost from inside sdk app +3. Do sdk demo again with addressable terminators +4. Show terminators + a. Because it's the initiating router, cost will be lower to terminate on the same router + +Part 4 - multi-router, multi-server, SDK hosted, HA +1. Update identity + a. ziti edge update identity echo-host-1 --service-precedences echo=required + +Part 5 - multi-router, multi-server, tunneler hosted, HS +1. Talk through config +2. Do demo +3. Show with addressable +4. Show with precedences + +Part 6 - ziti-tunnel +1. Talk through like SDK hosted + router/tunneler hosted. Need identity and configs +2. Talk about how config is different b/c tunneler is usually co-located with server app +3. Show + + diff --git a/ziti/cmd/ziti/cmd/demo/echo_server.go b/ziti/cmd/ziti/cmd/demo/echo_server.go new file mode 100644 index 000000000..ff668194c --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/echo_server.go @@ -0,0 +1,332 @@ +/* + 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 demo + +import ( + "bufio" + "fmt" + "github.com/michaelquigley/pfxlog" + "github.com/openziti/channel" + "github.com/openziti/foundation/agent" + "github.com/openziti/foundation/identity/identity" + "github.com/openziti/sdk-golang/ziti" + "github.com/openziti/sdk-golang/ziti/config" + "github.com/openziti/sdk-golang/ziti/edge" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "io" + "net" + "net/http" + "strings" + "time" +) + +const ( + EchoServerAppId = 100 + EchoServerUpdateTerminator = 1000 + EchoServerPrecedenceHeader = 1000 + EchoServerCostHeader = 1001 +) + +type echoServer struct { + port uint16 + healthCheckAddr string + verbose bool + logFormatter string + configFile string + service string + bindWithIdentity bool + zitiIdentity identity.Identity + zitiListener edge.Listener +} + +func newEchoServerCmd() *cobra.Command { + server := &echoServer{} + + cmd := &cobra.Command{ + Use: "echo-server", + Short: "Runs a simple network echo service", + Args: cobra.ExactArgs(0), + Run: server.run, + } + + // allow interspersing positional args and flags + cmd.Flags().SetInterspersed(true) + cmd.Flags().Uint16VarP(&server.port, "port", "p", 0, "Specify the port to listen on. If not specified the TCP listener won't be started") + cmd.Flags().StringVar(&server.healthCheckAddr, "health-check-addr", "", "Specify the ip:port on which to serve the health check endpoint. If not specified, a health check endpoint will not be started") + cmd.Flags().BoolVarP(&server.verbose, "verbose", "v", false, "Enable verbose logging") + cmd.Flags().StringVar(&server.logFormatter, "log-formatter", "", "Specify log formatter [json|pfxlog|text]") + cmd.Flags().StringVarP(&server.configFile, "identity", "i", "", "Specify the Ziti identity to use. If not specified the Ziti listener won't be started") + cmd.Flags().StringVarP(&server.service, "service", "s", "echo", "Ziti service to bind. Defaults to 'echo'") + cmd.Flags().BoolVar(&server.bindWithIdentity, "addressable", false, "Specify if this application should be addressable by the edge identity") + cmd.Flags().SetInterspersed(true) + + return cmd +} + +func (self *echoServer) initLogging() { + logLevel := logrus.InfoLevel + if self.verbose { + logLevel = logrus.DebugLevel + } + + options := pfxlog.DefaultOptions().SetTrimPrefix("github.com/openziti/").NoColor() + pfxlog.GlobalInit(logLevel, options) + + switch self.logFormatter { + case "pfxlog": + pfxlog.SetFormatter(pfxlog.NewFormatter(pfxlog.DefaultOptions().SetTrimPrefix("github.com/openziti/").StartingToday())) + case "json": + pfxlog.SetFormatter(&logrus.JSONFormatter{TimestampFormat: "2006-01-02T15:04:05.000Z"}) + case "text": + pfxlog.SetFormatter(&logrus.TextFormatter{}) + default: + // let logrus do its own thing + } +} + +func (self *echoServer) run(*cobra.Command, []string) { + self.initLogging() + + log := pfxlog.Logger() + + if self.port == 0 && self.configFile == "" { + log.Fatalf("No port specified and no ziti identity specified. Not starting either listener, so nothing to do. exiting.") + } + + if self.healthCheckAddr != "" { + go func() { + err := http.ListenAndServe(self.healthCheckAddr, http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + writer.WriteHeader(200) + })) + if err != nil { + log.WithError(err).Fatalf("unable to start health check endpoint on addr [%v]", self.healthCheckAddr) + } + }() + } + + if self.port > 0 { + addr := fmt.Sprintf("0.0.0.0:%v", self.port) + log.Infof("tcp: starting listener on address [%v]", addr) + listener, err := net.Listen("tcp", addr) + if err != nil { + log.WithError(err).Fatalf("unable to start TCP listener on addr [%v]", addr) + } + go self.accept("tcp", listener) + } + + if self.configFile != "" { + zitiConfig, err := config.NewFromFile(self.configFile) + if err != nil { + log.WithError(err).Fatalf("ziti: unable to load ziti identity from [%v]", self.configFile) + } + self.zitiIdentity, err = identity.LoadIdentity(zitiConfig.ID) + if err != nil { + log.WithError(err).Fatalf("ziti: unable to create ziti identity from [%v]", self.configFile) + } + + zitiContext := ziti.NewContextWithConfig(zitiConfig) + + zitiIdentity, err := zitiContext.GetCurrentIdentity() + if err != nil { + log.WithError(err).Fatal("unable to get current ziti identity from controller") + } + + listenOptions := ziti.DefaultListenOptions() + listenOptions.BindUsingEdgeIdentity = self.bindWithIdentity + listenOptions.Cost = zitiIdentity.DefaultHostingCost + listenOptions.Precedence = ziti.GetPrecedenceForLabel(zitiIdentity.DefaultHostingPrecedence) + + svc, found := zitiContext.GetService(self.service) + if !found { + log.WithError(err).Fatalf("ziti: unable to lookup service [%v]", self.service) + } + + if cost, found := zitiIdentity.ServiceHostingCosts[svc.Id]; found { + listenOptions.Cost = uint16(cost.(float64)) + } + + if precedence, found := zitiIdentity.ServiceHostingPrecedences[svc.Id]; found { + listenOptions.Precedence = ziti.GetPrecedenceForLabel(precedence.(string)) + } + + log.Infof("ziti: hosting %v with addressable=%v, cost=%v, precedence=%v", + self.service, self.bindWithIdentity, listenOptions.Cost, listenOptions.Precedence) + listener, err := zitiContext.ListenWithOptions(self.service, listenOptions) + if err != nil { + log.WithError(err).Fatalf("ziti: failed to host service [%v]", self.service) + } + + self.zitiListener = listener + + shutdownClean := false + agentOptions := agent.Options{ + ShutdownCleanup: &shutdownClean, + CustomOps: map[byte]func(conn net.Conn) error{ + agent.CustomOpAsync: self.HandleCustomAgentAsyncOp, + }, + } + + if err = agent.Listen(agentOptions); err != nil { + log.WithError(err).Warn("failed to start agent") + } + + go self.accept("ziti", listener) + } + + waitC := make(chan struct{}) + <-waitC +} + +func (self *echoServer) accept(connType string, listener net.Listener) { + log := pfxlog.Logger() + + for { + conn, err := listener.Accept() + if err != nil { + panic(err) + } + log.Infof("%v: connection received: %v", connType, conn) + go self.echo(connType, conn) + } +} + +func (self *echoServer) echo(connType string, conn io.ReadWriteCloser) { + log := pfxlog.Logger() + + defer func() { + if err := conn.Close(); err != nil { + log.WithError(err).Errorf("%v: Error while closing connection", connType) + } + log.Infof("%v: connection closed", connType) + }() + + for { + buf := make([]byte, 1024) + n, err := conn.Read(buf) + if err != nil { + if errors.Is(err, io.EOF) { + log.Infof("%v: received eof, closing connection", connType) + } else { + log.WithError(err).Errorf("%v: error while reading", connType) + } + break + } + log.Infof("%v: read %v bytes", connType, n) + writeBuf := buf[:n] + if _, err := conn.Write(writeBuf); err != nil { + log.WithError(err).Errorf("%v: error while writing", connType) + break + } + log.Infof("%v: wrote %v bytes", connType, n) + } +} + +func (self *echoServer) HandleCustomAgentAsyncOp(conn net.Conn) error { + logrus.Debug("received agent operation request") + + appIdBuf := []byte{0} + _, err := io.ReadFull(conn, appIdBuf) + if err != nil { + return err + } + appId := appIdBuf[0] + + if appId != EchoServerAppId { + logrus.WithField("appId", appId).Debug("invalid app id on agent request") + return errors.New("invalid operation for controller") + } + + options := channel.DefaultOptions() + options.ConnectTimeout = time.Second + tId := &identity.TokenId{Identity: self.zitiIdentity, Token: "echo-server"} + listener := channel.NewExistingConnListener(tId, conn, nil) + _, err = channel.NewChannel("agent", listener, channel.BindHandlerF(self.bindAgentChannel), options) + return err +} + +func (self *echoServer) bindAgentChannel(binding channel.Binding) error { + binding.AddReceiveHandlerF(EchoServerUpdateTerminator, self.HandleUpdateTerminator) + return nil +} + +func (self *echoServer) HandleUpdateTerminator(msg *channel.Message, ch channel.Channel) { + log := pfxlog.Logger() + precedenceLabel, hasPrecedence := msg.GetStringHeader(EchoServerPrecedenceHeader) + var precedence edge.Precedence + + if hasPrecedence { + if strings.EqualFold("default", precedenceLabel) { + precedence = edge.PrecedenceDefault + } else if strings.EqualFold("required", precedenceLabel) { + precedence = edge.PrecedenceRequired + } else if strings.EqualFold("failed", precedenceLabel) { + precedence = edge.PrecedenceFailed + } else { + err := errors.Errorf("invalid precedence [%v]", precedenceLabel) + self.SendOpResult(msg, ch, "update-precedence", err.Error(), false) + return + } + } + + cost, hasCost := msg.GetUint16Header(EchoServerCostHeader) + + var err error + if hasPrecedence && hasCost { + log.Infof("updating precedence=%v, cost=%v", precedenceLabel, cost) + err = self.zitiListener.UpdateCostAndPrecedence(cost, precedence) + } else if hasPrecedence { + log.Infof("updating precedence=%v", precedenceLabel) + + err = self.zitiListener.UpdatePrecedence(precedence) + } else if hasCost { + log.Infof("updating cost=%v", cost) + err = self.zitiListener.UpdateCost(cost) + } else { + err = errors.New("neither precedence nor cost provided, nothing to do") + } + + if err == nil { + self.SendOpResult(msg, ch, "update-precedence", "", true) + } else { + self.SendOpResult(msg, ch, "update-precedence", err.Error(), false) + } +} + +func (self *echoServer) SendOpResult(request *channel.Message, ch channel.Channel, op string, message string, success bool) { + log := pfxlog.ContextLogger(ch.Label()).WithField("operation", op) + if !success { + log.Errorf("%v error performing %v: (%s)", ch.LogicalName(), op, message) + } + + response := channel.NewResult(success, message) + response.ReplyTo(request) + if err := response.WithTimeout(time.Second).SendAndWaitForWire(ch); err != nil { + log.WithError(err).Error("failed to send result") + } +} + +func (self *echoServer) handleResult(err error, bconn *bufio.ReadWriter) error { + if err != nil { + return err + } + if _, err = bconn.WriteString("OK"); err != nil { + return err + } + return bconn.Flush() +} diff --git a/ziti/cmd/ziti/cmd/demo/echo_server_update_terminator.go b/ziti/cmd/ziti/cmd/demo/echo_server_update_terminator.go new file mode 100644 index 000000000..74a459834 --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/echo_server_update_terminator.go @@ -0,0 +1,101 @@ +/* + 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 demo + +import ( + "fmt" + "github.com/openziti/channel" + "github.com/openziti/foundation/agent" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + "github.com/pkg/errors" + "github.com/spf13/cobra" + "time" +) + +type AgentEchoServerUpdateTerminatorAction struct { + agentcli.AgentOptions + precedence string + cost uint16 +} + +func NewAgentEchoServerUpdateTerminatorCmd(p common.OptionsProvider) *cobra.Command { + action := &AgentEchoServerUpdateTerminatorAction{ + AgentOptions: agentcli.AgentOptions{ + CommonOptions: p(), + }, + } + + updateTerminatorCmd := &cobra.Command{ + Args: cobra.RangeArgs(0, 1), + Use: "update-terminator ", + Run: func(cmd *cobra.Command, args []string) { + action.Cmd = cmd + action.Args = args + err := action.Run() + cmdhelper.CheckErr(err) + }, + } + + updateTerminatorCmd.Flags().StringVarP(&action.precedence, "precedence", "p", "", "Target precedence [default, required, failed]") + updateTerminatorCmd.Flags().Uint16VarP(&action.cost, "cost", "c", 0, "Target cost") + + return updateTerminatorCmd +} + +// Run implements the command +func (self *AgentEchoServerUpdateTerminatorAction) Run() error { + var addr string + var err error + + if len(self.Args) == 1 { + addr, err = agent.ParseGopsAddress(self.Args) + if err != nil { + return err + } + } + + return agentcli.MakeAgentChannelRequest(addr, agent.CustomOpAsync, []byte{byte(EchoServerAppId)}, self.makeRequest) +} + +func (self *AgentEchoServerUpdateTerminatorAction) makeRequest(ch channel.Channel) error { + msg := channel.NewMessage(EchoServerUpdateTerminator, nil) + + if self.Cmd.Flag("precedence").Changed { + msg.PutStringHeader(EchoServerPrecedenceHeader, self.precedence) + } + if self.Cmd.Flag("cost").Changed { + msg.PutUint16Header(EchoServerCostHeader, self.cost) + } + + reply, err := msg.WithTimeout(5 * time.Second).SendForReply(ch) + if err != nil { + return err + } + if reply.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(reply) + if result.Success { + fmt.Println("success") + } else { + fmt.Printf("error: %v\n", result.Message) + } + } else { + return errors.Errorf("unexpected reponse type: %v", reply.ContentType) + } + return nil +} diff --git a/ziti/cmd/ziti/cmd/demo/root.go b/ziti/cmd/ziti/cmd/demo/root.go new file mode 100644 index 000000000..02d26fdb7 --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/root.go @@ -0,0 +1,82 @@ +/* + Copyright NetFoundry, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package demo + +import ( + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + "github.com/spf13/cobra" +) + +func NewDemoCmd(p common.OptionsProvider) *cobra.Command { + demoCmd := &cobra.Command{ + Use: "demo", + Short: "Demos and examples for learning about Ziti", + Run: func(cmd *cobra.Command, args []string) { + err := cmd.Help() + helpers.CheckErr(err) + }, + } + + setupCmd := &cobra.Command{ + Use: "setup", + Short: "Setup various demos/examples", + Run: func(cmd *cobra.Command, args []string) { + err := cmd.Help() + helpers.CheckErr(err) + }, + } + + echoCmd := &cobra.Command{ + Use: "echo", + Short: "Setup various echo service demos/examples", + Run: func(cmd *cobra.Command, args []string) { + err := cmd.Help() + helpers.CheckErr(err) + }, + } + + agentCmd := agentcli.NewAgentCmd(p) + echoServerAgentCmd := &cobra.Command{ + Use: "echo-server", + Short: "Interact with an echo-server process using the IPC agent", + Run: func(cmd *cobra.Command, args []string) { + helpers.CheckErr(cmd.Help()) + }, + } + + agentCmd.AddCommand(echoServerAgentCmd) + echoServerAgentCmd.AddCommand(NewAgentEchoServerUpdateTerminatorCmd(p)) + + demoCmd.AddCommand(newEchoServerCmd()) + demoCmd.AddCommand(newZcatCmd()) + demoCmd.AddCommand(agentCmd) + + demoCmd.AddCommand(setupCmd) + setupCmd.AddCommand(echoCmd) + echoCmd.AddCommand(newClientCmd(p)) + echoCmd.AddCommand(newSingleSdkHostedCmd(p)) + echoCmd.AddCommand(newMultiSdkHostedCmd(p)) + echoCmd.AddCommand(newSingleRouterTunnelerHostedCmd(p)) + echoCmd.AddCommand(newMultiRouterTunnelerHostedCmd(p)) + echoCmd.AddCommand(newMultiTunnelerHostedCmd(p)) + echoCmd.AddCommand(newUpdateConfigAddressableCmd(p)) + echoCmd.AddCommand(newUpdateConfigHACmd(p)) + + return demoCmd +} diff --git a/ziti/cmd/ziti/cmd/demo/setup-client.go b/ziti/cmd/ziti/cmd/demo/setup-client.go new file mode 100644 index 000000000..321c2b656 --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-client.go @@ -0,0 +1,85 @@ +/* + 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 demo + +import ( + _ "embed" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + tutorial2 "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial/actions" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "github.com/spf13/cobra" + "time" +) + +//go:embed setup-scripts/client.md +var clientScriptSource []byte + +type client struct { + api.Options + tutorial2.TutorialOptions + interactive bool +} + +func newClientCmd(p common.OptionsProvider) *cobra.Command { + options := &client{ + Options: api.Options{ + CommonOptions: p(), + }, + } + + cmd := &cobra.Command{ + Use: "client", + Short: "Walks you through configuration for an echo service client (zcat)", + 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.interactive, "interactive", false, "Interactive mode, waiting for user input") + options.AddCommonFlags(cmd) + + return cmd +} + +func (self *client) run() error { + t := tutorial.NewRunner() + t.NewLinePause = self.NewlinePause + t.AssumeDefault = !self.interactive + + t.RegisterActionHandler("ziti", &actions.ZitiRunnerAction{}) + t.RegisterActionHandler("ziti-login", &actions.ZitiEnsureLoggedIn{ + LoginParams: &self.TutorialOptions, + }) + t.RegisterActionHandler("keep-session-alive", &actions.KeepSessionAliveAction{}) + t.RegisterActionHandler("select-edge-router", &actions.SelectEdgeRouterAction{}) + + return t.Run(clientScriptSource) +} diff --git a/ziti/cmd/ziti/cmd/demo/setup-multi-router-tunneler-hosted-service.go b/ziti/cmd/ziti/cmd/demo/setup-multi-router-tunneler-hosted-service.go new file mode 100644 index 000000000..88b012786 --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-multi-router-tunneler-hosted-service.go @@ -0,0 +1,86 @@ +/* + 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 demo + +import ( + _ "embed" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + tutorial2 "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial/actions" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "github.com/spf13/cobra" + "time" +) + +//go:embed setup-scripts/multi-router-tunneler-hosted.md +var multiRouterTunnelerHostedScriptSource []byte + +type multiRouterTunnelerHosted struct { + api.Options + tutorial2.TutorialOptions + interactive bool +} + +func newMultiRouterTunnelerHostedCmd(p common.OptionsProvider) *cobra.Command { + options := &multiRouterTunnelerHosted{ + Options: api.Options{ + CommonOptions: p(), + }, + } + + cmd := &cobra.Command{ + Use: "multi-router-tunneler-hosted", + Short: "Walks you through hosting configuration for a simple echo service, hosted by router-embedded tunnelers and multiple applications", + 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.interactive, "interactive", false, "Interactive mode, waiting for user input") + options.AddCommonFlags(cmd) + + return cmd +} + +func (self *multiRouterTunnelerHosted) run() error { + t := tutorial.NewRunner() + t.NewLinePause = self.NewlinePause + t.AssumeDefault = !self.interactive + + t.RegisterActionHandler("ziti", &actions.ZitiRunnerAction{}) + t.RegisterActionHandler("ziti-login", &actions.ZitiEnsureLoggedIn{ + LoginParams: &self.TutorialOptions, + }) + t.RegisterActionHandler("keep-session-alive", &actions.KeepSessionAliveAction{}) + t.RegisterActionHandler("ziti-create-config", &actions.ZitiCreateConfigAction{}) + t.RegisterActionHandler("ziti-for-each", &actions.ZitiForEach{}) + + return t.Run(multiRouterTunnelerHostedScriptSource) +} diff --git a/ziti/cmd/ziti/cmd/demo/setup-multi-sdk-service.go b/ziti/cmd/ziti/cmd/demo/setup-multi-sdk-service.go new file mode 100644 index 000000000..b34fc9359 --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-multi-sdk-service.go @@ -0,0 +1,84 @@ +/* + Copyright NetFoundry, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package demo + +import ( + _ "embed" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + tutorial2 "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial/actions" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "github.com/spf13/cobra" + "time" +) + +//go:embed setup-scripts/multi-sdk-hosted.md +var multiSdkHostedScriptSource []byte + +type multiSdkHosted struct { + api.Options + tutorial2.TutorialOptions + interactive bool +} + +func newMultiSdkHostedCmd(p common.OptionsProvider) *cobra.Command { + options := &multiSdkHosted{ + Options: api.Options{ + CommonOptions: p(), + }, + } + + cmd := &cobra.Command{ + Use: "multi-sdk-hosted", + Short: "Walks you through hosting configuration for an echo service hosted by a multiple sdk applications", + 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.interactive, "interactive", false, "Interactive mode, waiting for user input") + options.AddCommonFlags(cmd) + + return cmd +} + +func (self *multiSdkHosted) run() error { + t := tutorial.NewRunner() + t.NewLinePause = self.NewlinePause + t.AssumeDefault = !self.interactive + + t.RegisterActionHandler("ziti", &actions.ZitiRunnerAction{}) + t.RegisterActionHandler("ziti-login", &actions.ZitiEnsureLoggedIn{ + LoginParams: &self.TutorialOptions, + }) + t.RegisterActionHandler("keep-session-alive", &actions.KeepSessionAliveAction{}) + + return t.Run(multiSdkHostedScriptSource) +} diff --git a/ziti/cmd/ziti/cmd/demo/setup-multi-tunneler-hosted-service.go b/ziti/cmd/ziti/cmd/demo/setup-multi-tunneler-hosted-service.go new file mode 100644 index 000000000..5b1e79c1b --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-multi-tunneler-hosted-service.go @@ -0,0 +1,86 @@ +/* + 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 demo + +import ( + _ "embed" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + tutorial2 "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial/actions" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "github.com/spf13/cobra" + "time" +) + +//go:embed setup-scripts/multi-tunneler-hosted.md +var multiTunnelerHostedScriptSource []byte + +type multiTunnelerHosted struct { + api.Options + tutorial2.TutorialOptions + interactive bool +} + +func newMultiTunnelerHostedCmd(p common.OptionsProvider) *cobra.Command { + options := &multiTunnelerHosted{ + Options: api.Options{ + CommonOptions: p(), + }, + } + + cmd := &cobra.Command{ + Use: "multi-tunneler-hosted", + Short: "Walks you through hosting configuration for a simple echo service, hosted by tunnelers and multiple applications", + 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.interactive, "interactive", false, "Interactive mode, waiting for user input") + options.AddCommonFlags(cmd) + + return cmd +} + +func (self *multiTunnelerHosted) run() error { + t := tutorial.NewRunner() + t.NewLinePause = self.NewlinePause + t.AssumeDefault = !self.interactive + + t.RegisterActionHandler("ziti", &actions.ZitiRunnerAction{}) + t.RegisterActionHandler("ziti-login", &actions.ZitiEnsureLoggedIn{ + LoginParams: &self.TutorialOptions, + }) + t.RegisterActionHandler("keep-session-alive", &actions.KeepSessionAliveAction{}) + t.RegisterActionHandler("ziti-create-config", &actions.ZitiCreateConfigAction{}) + t.RegisterActionHandler("ziti-for-each", &actions.ZitiForEach{}) + + return t.Run(multiTunnelerHostedScriptSource) +} diff --git a/ziti/cmd/ziti/cmd/demo/setup-scripts/client.md b/ziti/cmd/ziti/cmd/demo/setup-scripts/client.md new file mode 100644 index 000000000..09b4985a5 --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-scripts/client.md @@ -0,0 +1,46 @@ +# Purpose + +This script sets up the client side for an echo service + +# Prerequisites + +You need at least one controller and an edge router running. for this to work. +You can use the quick-start script found [here](https://github.com/openziti/ziti/tree/release-next/quickstart). + +# Setup + +## Ensure we're logged into the controller + +```action:ziti-login allowRetry=true +ziti edge login +``` + + + +## Remove any entities from previous runs + +```action:ziti +ziti edge delete identities zcat +ziti edge delete service-policies echo-dial +``` + +## Create and enroll the client app identity + +```action:ziti +ziti edge create identity service zcat -a echo,echo-client -o zcat.jwt +ziti edge enroll --rm zcat.jwt +``` + +## Configure a dial policy + +```action:ziti +ziti edge create service-policy echo-dial Dial --service-roles #echo --identity-roles #echo-client +``` + +## Summary + +After you've configured the service side, you should now be to run the zcat client using + +``` +ziti demo zcat -i zcat.json ziti:echo +``` diff --git a/ziti/cmd/ziti/cmd/demo/setup-scripts/multi-router-tunneler-hosted.md b/ziti/cmd/ziti/cmd/demo/setup-scripts/multi-router-tunneler-hosted.md new file mode 100644 index 000000000..76ea998a2 --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-scripts/multi-router-tunneler-hosted.md @@ -0,0 +1,110 @@ +# Purpose + +This script sets up hosting for an echo service which is hosted by multiple router-embedded tunneler and +multiple applications. + +# Prerequisites + +You need at least one controller and an edge router running. for this to work. +You can use the quick-start script found [here](https://github.com/openziti/ziti/tree/release-next/quickstart). + +# Setup + +## Ensure we're logged into the controller. + +```action:ziti-login allowRetry=true +ziti edge login +``` + + + +## Remove any entities from previous runs. + +```action:ziti +ziti edge delete service echo +ziti edge delete config echo-host +ziti edge delete identities echo-host-1 echo-host-2 +ziti edge delete service-policies echo-bind +ziti edge delete edge-router-policies echo +ziti edge delete service-edge-router-policies echo +``` + +## Create the echo-host config + +```action:ziti-create-config name=echo-host type=host.v2 +{ + "terminators" : [ + { + "address" : "localhost", + "port" : 1234, + "protocol" : "tcp", + "portChecks" : [ + { + "address" : "localhost:2234", + "interval" : "1s", + "timeout" : "100ms", + "actions" : [ + { "trigger" : "fail", "action" : "mark unhealthy" }, + { "trigger" : "pass", "action" : "mark healthy" } + ] + } + ] + }, + { + "address" : "localhost", + "port" : 1235, + "protocol" : "tcp", + "portChecks" : [ + { + "address" : "localhost:2235", + "interval" : "1s", + "timeout" : "100ms", + "actions" : [ + { "trigger" : "fail", "action" : "mark unhealthy" }, + { "trigger" : "pass", "action" : "mark healthy" } + ] + } + ] + } + ] +} +``` + +## Create the echo service + +```action:ziti +ziti edge create service echo -c echo-host -a echo +``` + +## Update edge-routers + +Make sure demo edge routers are tunneler enabled and the associated identity has the `echo-host` attribute +Only routers with the `demo` role attribute will be updated. + +```action:ziti-for-each type=edge-routers minCount=1 maxCount=2 filter='anyOf(roleAttributes)="demo"' +ziti edge update edge-router ${entityName} --tunneler-enabled +ziti edge update identity ${entityName} --role-attributes echo-host +``` + +## Configure policies + +```action:ziti +ziti edge create service-policy echo-bind Bind --service-roles @echo --identity-roles #echo-host +ziti edge create edge-router-policy echo --identity-roles #echo --edge-router-roles #all +ziti edge create service-edge-router-policy echo --service-roles @echo --edge-router-roles #all +``` + +## Summary + +You should now be to run two instances of the echo server with + +``` +ziti demo echo-server -p 1234 --health-check-addr 0.0.0.0:2234 +ziti demo echo-server -p 1235 --health-check-addr 0.0.0.0:2235 +``` + +and the zcat client using + +``` +ziti demo zcat -i zcat.json ziti:echo +``` diff --git a/ziti/cmd/ziti/cmd/demo/setup-scripts/multi-sdk-hosted.md b/ziti/cmd/ziti/cmd/demo/setup-scripts/multi-sdk-hosted.md new file mode 100644 index 000000000..8796bb93c --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-scripts/multi-sdk-hosted.md @@ -0,0 +1,70 @@ +# Purpose + +This script sets up an echo service which is hosted by two SDK applications and +is accessed by another sdk application. + +# Prerequisites + +You need at least one controller and an edge router running. for this to work. +You can use the quick-start script found [here](https://github.com/openziti/ziti/tree/release-next/quickstart). + +# Setup + +## Ensure we're logged into the controller. + +```action:ziti-login allowRetry=true +ziti edge login +``` + +```action:keep-session-alive interval=1m +If your session times out you can run ziti edge login again. +``` + +## Remove any entities from previous runs. + +```action:ziti +ziti edge delete service echo +ziti edge delete config echo-host +ziti edge delete identities echo-host-1 echo-host-2 +ziti edge delete service-policies echo-bind +ziti edge delete edge-router-policies echo +ziti edge delete service-edge-router-policies echo +``` + +## Create the echo service + +```action:ziti +ziti edge create service echo -a echo +``` + +## Create and enroll the hosting identities + +```action:ziti +ziti edge create identity service echo-host-1 -a echo,echo-host -o echo-host-1.jwt +ziti edge enroll --rm echo-host-1.jwt + +ziti edge create identity service echo-host-2 -a echo,echo-host -o echo-host-2.jwt +ziti edge enroll --rm echo-host-2.jwt +``` + +# Configure policies + +```action:ziti +ziti edge create service-policy echo-bind Bind --service-roles @echo --identity-roles #echo-host +ziti edge create edge-router-policy echo --identity-roles #echo --edge-router-roles #all +ziti edge create service-edge-router-policy echo --service-roles @echo --edge-router-roles #all +``` + +You should now be to run two instances of the echo server with: + +``` +ziti demo echo-server -i echo-host-1.json +ziti demo echo-server -i echo-host-2.json +``` + +and +the zcat client using + +``` +ziti demo zcat -i zcat.json ziti:echo +``` diff --git a/ziti/cmd/ziti/cmd/demo/setup-scripts/multi-tunneler-hosted.md b/ziti/cmd/ziti/cmd/demo/setup-scripts/multi-tunneler-hosted.md new file mode 100644 index 000000000..114ce13e8 --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-scripts/multi-tunneler-hosted.md @@ -0,0 +1,99 @@ +# Purpose + +This script sets up hosting for an echo service which is hosted by multiple router-embedded tunneler and +multiple applications. + +# Prerequisites + +You need at least one controller and an edge router running. for this to work. +You can use the quick-start script found [here](https://github.com/openziti/ziti/tree/release-next/quickstart). + +# Setup + +## Ensure we're logged into the controller. + +```action:ziti-login allowRetry=true +ziti edge login +``` + + + +## Remove any entities from previous runs. + +```action:ziti +ziti edge delete service echo +ziti edge delete config echo-host +ziti edge delete identities echo-host-1 echo-host-2 +ziti edge delete service-policies echo-bind +ziti edge delete edge-router-policies echo +ziti edge delete service-edge-router-policies echo +``` + +```action:ziti-for-each type=edge-routers minCount=1 maxCount=2 filter='anyOf(roleAttributes)="demo"' +ziti edge update edge-router ${entityName} --tunneler-enabled +ziti edge update identity ${entityName} --role-attributes not-hosting +``` + +## Create the echo-host config + +```action:ziti-create-config name=echo-host type=host.v2 +{ + "terminators" : [ + { + "address" : "localhost", + "port" : 1234, + "protocol" : "tcp", + "portChecks" : [ + { + "address" : "localhost:2234", + "interval" : "1s", + "timeout" : "100ms", + "actions" : [ + { "trigger" : "fail", "action" : "mark unhealthy" }, + { "trigger" : "pass", "action" : "mark healthy" } + ] + } + ] + } + ] +} +``` + +## Create the echo service + +```action:ziti +ziti edge create service echo -c echo-host -a echo +``` + +## Create and enroll the hosting identities + +```action:ziti +ziti edge create identity service echo-host-1 -a echo,echo-host -o echo-host-1.jwt +ziti edge enroll --rm echo-host-1.jwt + +ziti edge create identity service echo-host-2 -a echo,echo-host -o echo-host-2.jwt +ziti edge enroll --rm echo-host-2.jwt +``` + +## Configure policies + +```action:ziti +ziti edge create service-policy echo-bind Bind --service-roles @echo --identity-roles #echo-host +ziti edge create edge-router-policy echo --identity-roles #echo --edge-router-roles #all +ziti edge create service-edge-router-policy echo --service-roles @echo --edge-router-roles #all +``` + +## Summary + +You should now be to run two instances of the echo server with + +``` +ziti demo echo-server -p 1234 --health-check-addr 0.0.0.0:2234 +ziti demo echo-server -p 1235 --health-check-addr 0.0.0.0:2235 +``` + +and the zcat client using + +``` +ziti demo zcat -i zcat.json ziti:echo +``` diff --git a/ziti/cmd/ziti/cmd/demo/setup-scripts/single-router-tunneler-hosted.md b/ziti/cmd/ziti/cmd/demo/setup-scripts/single-router-tunneler-hosted.md new file mode 100644 index 000000000..f08476fa2 --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-scripts/single-router-tunneler-hosted.md @@ -0,0 +1,81 @@ +# Purpose + +This script sets up hosting for an echo service which is hosted by a router-embedded tunneler. + +# Prerequisites + +You need at least one controller and an edge router running. for this to work. +You can use the quick-start script found [here](https://github.com/openziti/ziti/tree/release-next/quickstart). + +# Setup + +## Ensure we're logged into the controller. + +```action:ziti-login allowRetry=true +ziti edge login +``` + + + +## Remove any entities from previous runs. + +```action:ziti +ziti edge delete service echo +ziti edge delete config echo-host +ziti edge delete identities echo-host-1 echo-host-2 +ziti edge delete service-policies echo-bind +ziti edge delete edge-router-policies echo +ziti edge delete service-edge-router-policies echo +``` + +## Create the echo-host config + +```action:ziti-create-config name=echo-host type=host.v2 +{ + "terminators" : [ + { + "address" : "localhost", + "port" : 1234, + "protocol" : "tcp" + } + ] +} +``` + +## Create the echo service + +```action:ziti +ziti edge create service echo -c echo-host -a echo +``` + +## Update edge-routers + +Make sure demo edge routers are tunneler enabled and the associated identity has the `echo-host` attribute. +Only routers with the `demo` role attribute will be updated. + +```action:ziti-for-each type=edge-routers minCount=1 maxCount=2 filter='anyOf(roleAttributes)="demo"' +ziti edge update edge-router ${entityName} --tunneler-enabled +ziti edge update identity ${entityName} --role-attributes echo-host +``` + +## Configure policies + +```action:ziti +ziti edge create service-policy echo-bind Bind --service-roles @echo --identity-roles #echo-host +ziti edge create edge-router-policy echo --identity-roles #echo --edge-router-roles #all +ziti edge create service-edge-router-policy echo --service-roles @echo --edge-router-roles #all +``` + +## Summary + +You should now be to run the echo server with + +``` +ziti demo echo-server -p 1234 +``` + +and the zcat client using + +``` +ziti demo zcat -i zcat.json ziti:echo +``` diff --git a/ziti/cmd/ziti/cmd/demo/setup-scripts/single-sdk-hosted.md b/ziti/cmd/ziti/cmd/demo/setup-scripts/single-sdk-hosted.md new file mode 100644 index 000000000..fa846f42b --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-scripts/single-sdk-hosted.md @@ -0,0 +1,65 @@ +# Purpose + +This script sets up an echo service which is hosted by an SDK application. + +# Prerequisites + +You need at least one controller and an edge router running. for this to work. +You can use the quick-start script found [here](https://github.com/openziti/ziti/tree/release-next/quickstart). + +# Setup + +## Ensure we're logged into the controller. + +```action:ziti-login allowRetry=true +ziti edge login +``` + +```action:keep-session-alive interval=1m +If your session times out you can run ziti edge login again. +``` + +## Remove any entities from previous runs. + +```action:ziti +ziti edge delete service echo +ziti edge delete config echo-host +ziti edge delete identities echo-host-1 echo-host-2 +ziti edge delete service-policies echo-bind +ziti edge delete edge-router-policies echo +ziti edge delete service-edge-router-policies echo +``` + +## Create the echo service + +```action:ziti +ziti edge create service echo -a echo +``` + +## Create and enroll the hosting identity + +```action:ziti +ziti edge create identity service echo-host-1 -a echo,echo-host -o echo-host-1.jwt +ziti edge enroll --rm echo-host-1.jwt +``` + +# Configure policies + +```action:ziti +ziti edge create service-policy echo-bind Bind --service-roles @echo --identity-roles #echo-host +ziti edge create edge-router-policy echo --identity-roles #echo --edge-router-roles #all +ziti edge create service-edge-router-policy echo --service-roles @echo --edge-router-roles #all +``` + +You should now be to run the echo server with + +``` +ziti demo echo-server -i echo-host-1.json +``` + +and +the zcat client using + +``` +ziti demo zcat -i zcat.json ziti:echo +``` diff --git a/ziti/cmd/ziti/cmd/demo/setup-scripts/update-config-addressable.md b/ziti/cmd/ziti/cmd/demo/setup-scripts/update-config-addressable.md new file mode 100644 index 000000000..275b00f0d --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-scripts/update-config-addressable.md @@ -0,0 +1,79 @@ +# Purpose + +This script updates the echo service hosting to allow addressing the individual servers. + +# Prerequisites + +You need at least one controller and an edge router running. for this to work. +You can use the quick-start script found [here](https://github.com/openziti/ziti/tree/release-next/quickstart). + +# Setup + +## Ensure we're logged into the controller. + +```action:ziti-login allowRetry=true +ziti edge login +``` + + + +## Update the echo-host config + +```action:ziti-update-config name=echo-host +{ + "terminators" : [ + { + "address" : "localhost", + "port" : 1234, + "protocol" : "tcp", + "portChecks" : [ + { + "address" : "localhost:2234", + "interval" : "1s", + "timeout" : "100ms", + "actions" : [ + { "trigger" : "fail", "action" : "mark unhealthy" }, + { "trigger" : "pass", "action" : "mark healthy" } + ] + } + ], + "listenOptions" : { + "identity" : "echo-host-1" + } + }, + { + "address" : "localhost", + "port" : 1235, + "protocol" : "tcp", + "portChecks" : [ + { + "address" : "localhost:2235", + "interval" : "1s", + "timeout" : "100ms", + "actions" : [ + { "trigger" : "fail", "action" : "mark unhealthy" }, + { "trigger" : "pass", "action" : "mark healthy" } + ] + } + ], + "listenOptions" : { + "identity" : "echo-host-2" + } + } + ] +} +``` + +## Summary + +You should now be to run the echo server with + +``` +ziti demo echo-server -p 1234 +``` + +and the zcat client using + +``` +ziti demo zcat -i zcat.json ziti:echo-host-1@echo +``` diff --git a/ziti/cmd/ziti/cmd/demo/setup-scripts/update-config-ha.md b/ziti/cmd/ziti/cmd/demo/setup-scripts/update-config-ha.md new file mode 100644 index 000000000..5862ae13b --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-scripts/update-config-ha.md @@ -0,0 +1,79 @@ +# Purpose + +This script updates the echo service hosting to run in a primary/failover configuration. + +# Prerequisites + +You need at least one controller and an edge router running. for this to work. +You can use the quick-start script found [here](https://github.com/openziti/ziti/tree/release-next/quickstart). + +# Setup + +## Ensure we're logged into the controller. + +```action:ziti-login allowRetry=true +ziti edge login +``` + + + +## Update the echo-host config + +```action:ziti-update-config name=echo-host +{ + "terminators" : [ + { + "address" : "localhost", + "port" : 1234, + "protocol" : "tcp", + "portChecks" : [ + { + "address" : "localhost:2234", + "interval" : "1s", + "timeout" : "100ms", + "actions" : [ + { "trigger" : "fail", "action" : "mark unhealthy" }, + { "trigger" : "pass", "action" : "mark healthy" } + ] + } + ], + "listenOptions" : { + "precedence" : "required" + } + }, + { + "address" : "localhost", + "port" : 1235, + "protocol" : "tcp", + "portChecks" : [ + { + "address" : "localhost:2235", + "interval" : "1s", + "timeout" : "100ms", + "actions" : [ + { "trigger" : "fail", "action" : "mark unhealthy" }, + { "trigger" : "pass", "action" : "mark healthy" } + ] + } + ], + "listenOptions" : { + "precedence" : "default" + } + } + ] +} +``` + +## Summary + +You should now be to run the echo server with + +``` +ziti demo echo-server -p 1234 +``` + +and the zcat client using + +``` +ziti demo zcat -i zcat.json ziti:echo +``` diff --git a/ziti/cmd/ziti/cmd/demo/setup-single-router-tunneler-hosted-service.go b/ziti/cmd/ziti/cmd/demo/setup-single-router-tunneler-hosted-service.go new file mode 100644 index 000000000..1ea6328df --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-single-router-tunneler-hosted-service.go @@ -0,0 +1,87 @@ +/* + 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 demo + +import ( + _ "embed" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + tutorial2 "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial/actions" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "github.com/spf13/cobra" + "time" +) + +//go:embed setup-scripts/single-router-tunneler-hosted.md +var singleRouterTunnelerHostedScriptSource []byte + +type singleRouterTunnelerHosted struct { + api.Options + tutorial2.TutorialOptions + interactive bool +} + +func newSingleRouterTunnelerHostedCmd(p common.OptionsProvider) *cobra.Command { + options := &singleRouterTunnelerHosted{ + Options: api.Options{ + CommonOptions: p(), + }, + } + + cmd := &cobra.Command{ + Use: "single-router-tunneler-hosted", + Short: "Walks you through hosting configuration for a simple echo service, hosted by a single router-embedded tunneler", + 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.interactive, "interactive", false, "Interactive mode, waiting for user input") + options.AddCommonFlags(cmd) + + return cmd +} + +func (self *singleRouterTunnelerHosted) run() error { + t := tutorial.NewRunner() + t.NewLinePause = self.NewlinePause + t.AssumeDefault = !self.interactive + + t.RegisterActionHandler("ziti", &actions.ZitiRunnerAction{}) + t.RegisterActionHandler("ziti-login", &actions.ZitiEnsureLoggedIn{ + LoginParams: &self.TutorialOptions, + }) + t.RegisterActionHandler("keep-session-alive", &actions.KeepSessionAliveAction{}) + t.RegisterActionHandler("ziti-create-config", &actions.ZitiCreateConfigAction{}) + t.RegisterActionHandler("select-edge-router", &actions.SelectEdgeRouterAction{}) + t.RegisterActionHandler("ziti-for-each", &actions.ZitiForEach{}) + + return t.Run(singleRouterTunnelerHostedScriptSource) +} diff --git a/ziti/cmd/ziti/cmd/demo/setup-single-sdk-service.go b/ziti/cmd/ziti/cmd/demo/setup-single-sdk-service.go new file mode 100644 index 000000000..fd1341547 --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-single-sdk-service.go @@ -0,0 +1,85 @@ +/* + 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 demo + +import ( + _ "embed" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + tutorial2 "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial/actions" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "github.com/spf13/cobra" + "time" +) + +//go:embed setup-scripts/single-sdk-hosted.md +var singleSdkHostedScriptSource []byte + +type singleSdkHosted struct { + api.Options + tutorial2.TutorialOptions + interactive bool +} + +func newSingleSdkHostedCmd(p common.OptionsProvider) *cobra.Command { + options := &singleSdkHosted{ + Options: api.Options{ + CommonOptions: p(), + }, + } + + cmd := &cobra.Command{ + Use: "single-sdk-hosted", + Short: "Walks you through hosting configuration for an echo service hosted by a single sdk application", + 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.interactive, "interactive", false, "Interactive mode, waiting for user input") + options.AddCommonFlags(cmd) + + return cmd +} + +func (self *singleSdkHosted) run() error { + t := tutorial.NewRunner() + t.NewLinePause = self.NewlinePause + t.AssumeDefault = !self.interactive + + t.RegisterActionHandler("ziti", &actions.ZitiRunnerAction{}) + t.RegisterActionHandler("ziti-login", &actions.ZitiEnsureLoggedIn{ + LoginParams: &self.TutorialOptions, + }) + t.RegisterActionHandler("keep-session-alive", &actions.KeepSessionAliveAction{}) + t.RegisterActionHandler("select-edge-router", &actions.SelectEdgeRouterAction{}) + + return t.Run(singleSdkHostedScriptSource) +} diff --git a/ziti/cmd/ziti/cmd/demo/setup-update-config-addressable.go b/ziti/cmd/ziti/cmd/demo/setup-update-config-addressable.go new file mode 100644 index 000000000..1986ee72a --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-update-config-addressable.go @@ -0,0 +1,87 @@ +/* + 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 demo + +import ( + _ "embed" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + tutorial2 "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial/actions" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "github.com/spf13/cobra" + "time" +) + +//go:embed setup-scripts/update-config-addressable.md +var updateConfigAddressableSource []byte + +type updateConfigAddressable struct { + api.Options + tutorial2.TutorialOptions + interactive bool +} + +func newUpdateConfigAddressableCmd(p common.OptionsProvider) *cobra.Command { + options := &updateConfigAddressable{ + Options: api.Options{ + CommonOptions: p(), + }, + } + + cmd := &cobra.Command{ + Use: "update-config-addressable", + Short: "Updates the echo service hosting configuration to allow addressing the individual servers", + 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.interactive, "interactive", false, "Interactive mode, waiting for user input") + options.AddCommonFlags(cmd) + + return cmd +} + +func (self *updateConfigAddressable) run() error { + t := tutorial.NewRunner() + t.NewLinePause = self.NewlinePause + t.AssumeDefault = !self.interactive + + t.RegisterActionHandler("ziti", &actions.ZitiRunnerAction{}) + t.RegisterActionHandler("ziti-login", &actions.ZitiEnsureLoggedIn{ + LoginParams: &self.TutorialOptions, + }) + t.RegisterActionHandler("keep-session-alive", &actions.KeepSessionAliveAction{}) + t.RegisterActionHandler("ziti-create-config", &actions.ZitiCreateConfigAction{}) + t.RegisterActionHandler("ziti-update-config", &actions.ZitiUpdateConfigAction{}) + t.RegisterActionHandler("ziti-for-each", &actions.ZitiForEach{}) + + return t.Run(updateConfigAddressableSource) +} diff --git a/ziti/cmd/ziti/cmd/demo/setup-update-config-ha.go b/ziti/cmd/ziti/cmd/demo/setup-update-config-ha.go new file mode 100644 index 000000000..479a7df81 --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/setup-update-config-ha.go @@ -0,0 +1,87 @@ +/* + 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 demo + +import ( + _ "embed" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + tutorial2 "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial/actions" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "github.com/spf13/cobra" + "time" +) + +//go:embed setup-scripts/update-config-ha.md +var updateConfigHASource []byte + +type updateConfigHA struct { + api.Options + tutorial2.TutorialOptions + interactive bool +} + +func newUpdateConfigHACmd(p common.OptionsProvider) *cobra.Command { + options := &updateConfigHA{ + Options: api.Options{ + CommonOptions: p(), + }, + } + + cmd := &cobra.Command{ + Use: "update-config-ha", + Short: "Updates the echo service hosting configuration to run in a primary/failover setup", + 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.interactive, "interactive", false, "Interactive mode, waiting for user input") + options.AddCommonFlags(cmd) + + return cmd +} + +func (self *updateConfigHA) run() error { + t := tutorial.NewRunner() + t.NewLinePause = self.NewlinePause + t.AssumeDefault = !self.interactive + + t.RegisterActionHandler("ziti", &actions.ZitiRunnerAction{}) + t.RegisterActionHandler("ziti-login", &actions.ZitiEnsureLoggedIn{ + LoginParams: &self.TutorialOptions, + }) + t.RegisterActionHandler("keep-session-alive", &actions.KeepSessionAliveAction{}) + t.RegisterActionHandler("ziti-create-config", &actions.ZitiCreateConfigAction{}) + t.RegisterActionHandler("ziti-update-config", &actions.ZitiUpdateConfigAction{}) + t.RegisterActionHandler("ziti-for-each", &actions.ZitiForEach{}) + + return t.Run(updateConfigHASource) +} diff --git a/ziti/cmd/ziti/cmd/demo/zcat.go b/ziti/cmd/ziti/cmd/demo/zcat.go new file mode 100644 index 000000000..7e55f0065 --- /dev/null +++ b/ziti/cmd/ziti/cmd/demo/zcat.go @@ -0,0 +1,138 @@ +/* + 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 demo + +import ( + "github.com/michaelquigley/pfxlog" + "github.com/openziti/foundation/util/info" + "github.com/openziti/sdk-golang/ziti" + "github.com/openziti/sdk-golang/ziti/config" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "io" + "net" + "os" + "strings" + "time" +) + +type zcat struct { + verbose bool + logFormatter string + configFile string +} + +func newZcatCmd() *cobra.Command { + server := &zcat{} + + cmd := &cobra.Command{ + Use: "zcat ", + Example: "ziti demo zcat tcp:localhost:1234 or ziti demo zcat -i zcat.json ziti:echo", + Short: "A simple network cat facility which can run over tcp or ziti", + Args: cobra.ExactArgs(1), + Run: server.run, + } + + // allow interspersing positional args and flags + cmd.Flags().SetInterspersed(true) + cmd.Flags().BoolVarP(&server.verbose, "verbose", "v", false, "Enable verbose logging") + cmd.Flags().StringVar(&server.logFormatter, "log-formatter", "", "Specify log formatter [json|pfxlog|text]") + cmd.Flags().StringVarP(&server.configFile, "identity", "i", "", "Specify the Ziti identity to use. If not specified the Ziti listener won't be started") + cmd.Flags().SetInterspersed(true) + + return cmd +} + +func (self *zcat) initLogging() { + logLevel := logrus.InfoLevel + if self.verbose { + logLevel = logrus.DebugLevel + } + + options := pfxlog.DefaultOptions().SetTrimPrefix("github.com/openziti/").NoColor() + pfxlog.GlobalInit(logLevel, options) + + switch self.logFormatter { + case "pfxlog": + pfxlog.SetFormatter(pfxlog.NewFormatter(pfxlog.DefaultOptions().SetTrimPrefix("github.com/openziti/").StartingToday())) + case "json": + pfxlog.SetFormatter(&logrus.JSONFormatter{TimestampFormat: "2006-01-02T15:04:05.000Z"}) + case "text": + pfxlog.SetFormatter(&logrus.TextFormatter{}) + default: + // let logrus do its own thing + } +} + +func (self *zcat) run(_ *cobra.Command, args []string) { + self.initLogging() + + log := pfxlog.Logger() + + parts := strings.Split(args[0], ":") + if len(parts) < 2 { + log.Fatalf("destination %v is invalid. destination must be of the form network:address", args[0]) + } + network := parts[0] + addr := strings.Join(parts[1:], ":") + + var conn net.Conn + var err error + + log.Debugf("dialing %v:%v", network, addr) + if network == "tcp" || network == "udp" { + conn, err = net.Dial(network, addr) + } else if network == "ziti" { + zitiConfig, cfgErr := config.NewFromFile(self.configFile) + if cfgErr != nil { + log.WithError(cfgErr).Fatalf("unable to load ziti identity from [%v]", self.configFile) + } + + dialIdentifier := "" + if atIdx := strings.IndexByte(addr, '@'); atIdx > 0 { + dialIdentifier = addr[:atIdx] + addr = addr[atIdx+1:] + } + + zitiContext := ziti.NewContextWithConfig(zitiConfig) + dialOptions := &ziti.DialOptions{ + ConnectTimeout: 5 * time.Second, + Identity: dialIdentifier, + } + conn, err = zitiContext.DialWithOptions(addr, dialOptions) + } else { + log.Fatalf("invalid network '%v'. valid values are ['ziti', 'tcp', 'udp']", network) + } + + if err != nil { + log.WithError(err).Fatalf("unable to dial %v:%v", network, addr) + } + + log.Debugf("connected to %v:%v", network, addr) + + go self.copy(conn, os.Stdin) + self.copy(os.Stdout, conn) +} + +func (self *zcat) copy(writer io.Writer, reader io.Reader) { + buf := make([]byte, info.MaxUdpPacketSize) + bytesCopied, err := io.CopyBuffer(writer, reader, buf) + pfxlog.Logger().Debugf("Copied %v bytes", bytesCopied) + if err != nil { + pfxlog.Logger().WithError(err).Error("error while copying bytes") + } +} diff --git a/ziti/cmd/ziti/cmd/edge/create.go b/ziti/cmd/ziti/cmd/edge/create.go index 533f88788..868678d73 100644 --- a/ziti/cmd/ziti/cmd/edge/create.go +++ b/ziti/cmd/ziti/cmd/edge/create.go @@ -22,13 +22,12 @@ import ( "github.com/openziti/ziti/ziti/cmd/ziti/util" "io" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" ) -// newListCmd creates a command object for the "controller list" command -func newCreateCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +// newCreateCmd creates a command object for the "list" command +func newCreateCmd(out io.Writer, errOut io.Writer) *cobra.Command { cmd := &cobra.Command{ Use: "create", Short: "creates various entities managed by the Ziti Edge Controller", @@ -38,16 +37,16 @@ func newCreateCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Com }, } - cmd.AddCommand(newCreateAuthenticatorCmd(f, out, errOut)) - cmd.AddCommand(newCreateCaCmd(f, out, errOut)) - cmd.AddCommand(newCreateConfigCmd(f, out, errOut)) - cmd.AddCommand(newCreateConfigTypeCmd(f, out, errOut)) - cmd.AddCommand(newCreateEdgeRouterCmd(f, out, errOut)) - cmd.AddCommand(newCreateEdgeRouterPolicyCmd(f, out, errOut)) - cmd.AddCommand(newCreateTerminatorCmd(f, out, errOut)) - cmd.AddCommand(newCreateIdentityCmd(f, out, errOut)) - cmd.AddCommand(newCreateServiceCmd(f, out, errOut)) - cmd.AddCommand(newCreateServiceEdgeRouterPolicyCmd(f, out, errOut)) + cmd.AddCommand(newCreateAuthenticatorCmd(out, errOut)) + cmd.AddCommand(newCreateCaCmd(out, errOut)) + cmd.AddCommand(newCreateConfigCmd(out, errOut)) + cmd.AddCommand(newCreateConfigTypeCmd(out, errOut)) + cmd.AddCommand(newCreateEdgeRouterCmd(out, errOut)) + cmd.AddCommand(newCreateEdgeRouterPolicyCmd(out, errOut)) + cmd.AddCommand(newCreateTerminatorCmd(out, errOut)) + cmd.AddCommand(newCreateIdentityCmd(out, errOut)) + cmd.AddCommand(newCreateServiceCmd(out, errOut)) + cmd.AddCommand(newCreateServiceEdgeRouterPolicyCmd(out, errOut)) cmd.AddCommand(newCreateServicePolicyCmd(out, errOut)) cmd.AddCommand(newCreatePostureCheckCmd(out, errOut)) diff --git a/ziti/cmd/ziti/cmd/edge/create_authenticator.go b/ziti/cmd/ziti/cmd/edge/create_authenticator.go index b7187d9e9..d96d0ca29 100644 --- a/ziti/cmd/ziti/cmd/edge/create_authenticator.go +++ b/ziti/cmd/ziti/cmd/edge/create_authenticator.go @@ -19,15 +19,14 @@ package edge import ( "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" "github.com/spf13/cobra" "io" ) // newCreateAuthenticatorCmd creates the 'edge controller create authenticator' command -func newCreateAuthenticatorCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newCreateAuthenticatorCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, OutputJSONResponse: false, } diff --git a/ziti/cmd/ziti/cmd/edge/create_ca.go b/ziti/cmd/ziti/cmd/edge/create_ca.go index 4fa634458..61f45b705 100644 --- a/ziti/cmd/ziti/cmd/edge/create_ca.go +++ b/ziti/cmd/ziti/cmd/edge/create_ca.go @@ -21,7 +21,6 @@ import ( "github.com/Jeffail/gabs" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" "io" @@ -42,13 +41,12 @@ type createCaOptions struct { } // newCreateCaCmd creates the 'edge controller create ca local' command for the given entity type -func newCreateCaCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newCreateCaCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &createCaOptions{ Options: api.Options{ CommonOptions: common.CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, tags: make(map[string]string), diff --git a/ziti/cmd/ziti/cmd/edge/create_config.go b/ziti/cmd/ziti/cmd/edge/create_config.go index daa6f6ad0..5e1874725 100644 --- a/ziti/cmd/ziti/cmd/edge/create_config.go +++ b/ziti/cmd/ziti/cmd/edge/create_config.go @@ -27,7 +27,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" ) @@ -38,10 +37,10 @@ type createConfigOptions struct { } // newCreateConfigCmd creates the 'edge controller create service-policy' command -func newCreateConfigCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newCreateConfigCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &createConfigOptions{ Options: api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, }, } diff --git a/ziti/cmd/ziti/cmd/edge/create_config_type.go b/ziti/cmd/ziti/cmd/edge/create_config_type.go index 4ab22ec38..50f7ed74d 100644 --- a/ziti/cmd/ziti/cmd/edge/create_config_type.go +++ b/ziti/cmd/ziti/cmd/edge/create_config_type.go @@ -27,7 +27,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" ) @@ -38,10 +37,10 @@ type createConfigTypeOptions struct { } // newCreateConfigTypeCmd creates the 'edge controller create service-policy' command -func newCreateConfigTypeCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newCreateConfigTypeCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &createConfigTypeOptions{ Options: api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, }, } diff --git a/ziti/cmd/ziti/cmd/edge/create_edge_router.go b/ziti/cmd/ziti/cmd/edge/create_edge_router.go index d3b1160e5..8a0b8343f 100644 --- a/ziti/cmd/ziti/cmd/edge/create_edge_router.go +++ b/ziti/cmd/ziti/cmd/edge/create_edge_router.go @@ -25,7 +25,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" ) @@ -41,10 +40,10 @@ type createEdgeRouterOptions struct { noTraversal bool } -func newCreateEdgeRouterCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newCreateEdgeRouterCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &createEdgeRouterOptions{ Options: api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, }, } diff --git a/ziti/cmd/ziti/cmd/edge/create_edge_router_policy.go b/ziti/cmd/ziti/cmd/edge/create_edge_router_policy.go index 445a2a8f7..5e4723fdb 100644 --- a/ziti/cmd/ziti/cmd/edge/create_edge_router_policy.go +++ b/ziti/cmd/ziti/cmd/edge/create_edge_router_policy.go @@ -22,7 +22,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" ) @@ -35,10 +34,10 @@ type createEdgeRouterPolicyOptions struct { } // newCreateEdgeRouterPolicyCmd creates the 'edge controller create edge-router-policy' command -func newCreateEdgeRouterPolicyCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newCreateEdgeRouterPolicyCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &createEdgeRouterPolicyOptions{ Options: api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, }, } diff --git a/ziti/cmd/ziti/cmd/edge/create_identity.go b/ziti/cmd/ziti/cmd/edge/create_identity.go index bc09c33a0..360eea384 100644 --- a/ziti/cmd/ziti/cmd/edge/create_identity.go +++ b/ziti/cmd/ziti/cmd/edge/create_identity.go @@ -28,7 +28,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" ) @@ -45,14 +44,15 @@ type createIdentityOptions struct { servicePrecedences map[string]string tags map[string]string appData map[string]string + externalId string } // newCreateIdentityCmd creates the 'edge controller create identity' command -func newCreateIdentityCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newCreateIdentityCmd(out io.Writer, errOut io.Writer) *cobra.Command { newOptions := func() *createIdentityOptions { return &createIdentityOptions{ Options: api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, }, } } @@ -89,6 +89,7 @@ func newCreateIdentityOfTypeCmd(idType string, options *createIdentityOptions) * cmd.Flags().SetInterspersed(true) cmd.Flags().BoolVarP(&options.isAdmin, "admin", "A", false, "Give the new identity admin privileges") cmd.Flags().StringVar(&options.username, "updb", "", "username to give the identity, will create a UPDB enrollment") + cmd.Flags().StringVar(&options.externalId, "external-id", "", "an external id to give to the identity") cmd.Flags().StringSliceVarP(&options.roleAttributes, "role-attributes", "a", nil, "Role attributes of the new identity") cmd.Flags().StringVarP(&options.jwtOutputFile, "jwt-output-file", "o", "", "File to which to output the JWT used for enrolling the identity") cmd.Flags().StringVarP(&options.defaultHostingPrecedence, "default-hosting-precedence", "p", "", "Default precedence to use when hosting services using this identity [default,required,failed]") @@ -119,6 +120,10 @@ func runCreateIdentity(idType string, o *createIdentityOptions) error { api.SetJSONValue(entityData, o.tags, "tags") api.SetJSONValue(entityData, o.appData, "appData") + if o.externalId != "" { + api.SetJSONValue(entityData, o.externalId, "externalId") + } + if o.defaultHostingPrecedence != "" { prec, err := normalizeAndValidatePrecedence(o.defaultHostingPrecedence) if err != nil { diff --git a/ziti/cmd/ziti/cmd/edge/create_service.go b/ziti/cmd/ziti/cmd/edge/create_service.go index c7ffb0ddd..cc3b2a8c6 100644 --- a/ziti/cmd/ziti/cmd/edge/create_service.go +++ b/ziti/cmd/ziti/cmd/edge/create_service.go @@ -20,7 +20,6 @@ import ( "github.com/Jeffail/gabs" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" "io" @@ -37,13 +36,12 @@ type createServiceOptions struct { } // newCreateServiceCmd creates the 'edge controller create service local' command for the given entity type -func newCreateServiceCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newCreateServiceCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &createServiceOptions{ Options: api.Options{ CommonOptions: common.CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, tags: make(map[string]string), diff --git a/ziti/cmd/ziti/cmd/edge/create_service_edge_router_policy.go b/ziti/cmd/ziti/cmd/edge/create_service_edge_router_policy.go index 5e619357e..16dacfd16 100644 --- a/ziti/cmd/ziti/cmd/edge/create_service_edge_router_policy.go +++ b/ziti/cmd/ziti/cmd/edge/create_service_edge_router_policy.go @@ -22,7 +22,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" ) @@ -35,10 +34,10 @@ type createServiceEdgeRouterPolicyOptions struct { } // newCreateServiceEdgeRouterPolicyCmd creates the 'edge controller create service-edge-router-policy' command -func newCreateServiceEdgeRouterPolicyCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newCreateServiceEdgeRouterPolicyCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &createServiceEdgeRouterPolicyOptions{ Options: api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, }, } diff --git a/ziti/cmd/ziti/cmd/edge/create_terminator.go b/ziti/cmd/ziti/cmd/edge/create_terminator.go index e920d6d80..d01129a26 100644 --- a/ziti/cmd/ziti/cmd/edge/create_terminator.go +++ b/ziti/cmd/ziti/cmd/edge/create_terminator.go @@ -23,7 +23,6 @@ import ( "github.com/openziti/foundation/util/stringz" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" "io" @@ -39,13 +38,12 @@ type createTerminatorOptions struct { } // newCreateTerminatorCmd creates the 'edge controller create Terminator local' command for the given entity type -func newCreateTerminatorCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newCreateTerminatorCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &createTerminatorOptions{ Options: api.Options{ CommonOptions: common.CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } diff --git a/ziti/cmd/ziti/cmd/edge/delete.go b/ziti/cmd/ziti/cmd/edge/delete.go index e810a9244..a4b408ca6 100644 --- a/ziti/cmd/ziti/cmd/edge/delete.go +++ b/ziti/cmd/ziti/cmd/edge/delete.go @@ -147,13 +147,13 @@ func runDeleteEntityOfTypeWhere(options *api.Options, entityType string) error { params := url.Values{} params.Add("filter", filter) - children, pageInfo, err := listEntitiesOfType(entityType, params, options.OutputJSONResponse, options.Out, options.Timeout, options.Verbose) + 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) + pageInfo.Output(options) var ids []string for _, entity := range children { diff --git a/ziti/cmd/ziti/cmd/edge/list.go b/ziti/cmd/ziti/cmd/edge/list.go index 494ee5b65..e09845cb5 100644 --- a/ziti/cmd/ziti/cmd/edge/list.go +++ b/ziti/cmd/ziti/cmd/edge/list.go @@ -17,8 +17,9 @@ package edge import ( - "encoding/json" "fmt" + "github.com/jedib0t/go-pretty/v6/table" + "github.com/jedib0t/go-pretty/v6/text" "io" "net/url" "reflect" @@ -40,9 +41,9 @@ import ( // newListCmd creates a command object for the "controller list" 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", - Long: "Lists various entities managed by the Ziti Edge Controller", + Use: "list", + Short: "Lists various entities managed by the Ziti Edge Controller", + Aliases: []string{"ls"}, Run: func(cmd *cobra.Command, args []string) { err := cmd.Help() cmdhelper.CheckErr(err) @@ -127,45 +128,23 @@ func newListCmd(out io.Writer, errOut io.Writer) *cobra.Command { return cmd } -type paging struct { - limit int64 - offset int64 - count int64 - errorz.ErrorHolderImpl -} - -func newPagingInfo(meta *rest_model.Meta) paging { +func newPagingInfo(meta *rest_model.Meta) *api.Paging { if meta != nil && meta.Pagination != nil { - pagingInfo := paging{ - limit: *meta.Pagination.Limit, - offset: *meta.Pagination.Offset, - count: *meta.Pagination.TotalCount, + pagingInfo := &api.Paging{ + Limit: *meta.Pagination.Limit, + Offset: *meta.Pagination.Offset, + Count: *meta.Pagination.TotalCount, } return pagingInfo } - return paging{} -} - -func (p *paging) output(o *api.Options) { - if p.HasError() { - _, _ = fmt.Fprintf(o.Out, "unable to retrieve paging information: %v\n", p.Err) - } else if p.count == 0 { - _, _ = fmt.Fprintln(o.Out, "results: none") - } else { - first := p.offset + 1 - last := p.offset + p.limit - if last > p.count || last < 0 { // if p.limit is maxint, last will rollover and be negative - last = p.count - } - _, _ = fmt.Fprintf(o.Out, "results: %v-%v of %v\n", first, last, p.count) - } + return &api.Paging{} } type listCommandRunner func(*api.Options) error -type outputFunction func(o *api.Options, children []*gabs.Container, pagingInfo *paging) error +type outputFunction func(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error func newEntityListRootCmd(entityType string, aliases ...string) *cobra.Command { desc := fmt.Sprintf("list entities related to a %v instance managed by the Ziti Edge Controller", entityType) @@ -186,7 +165,6 @@ func newListCmdForEntityType(entityType string, command listCommandRunner, optio cmd := &cobra.Command{ Use: entityType + " ?", Short: "lists " + entityType + " managed by the Ziti Edge Controller", - Long: "lists " + entityType + " managed by the Ziti Edge Controller", Args: cobra.MaximumNArgs(1), Aliases: aliases, Run: func(cmd *cobra.Command, args []string) { @@ -200,6 +178,7 @@ func newListCmdForEntityType(entityType string, command listCommandRunner, optio // allow interspersing positional args and flags cmd.Flags().SetInterspersed(true) + cmd.Flags().BoolVar(&options.OutputCSV, "csv", false, "Output CSV instead of a formatted table") options.AddCommonFlags(cmd) return cmd @@ -232,6 +211,7 @@ func newListServicesCmd(options *api.Options) *cobra.Command { cmd.Flags().StringSliceVar(&configTypes, "config-types", nil, "Override which config types to view on services") cmd.Flags().StringSliceVar(&roleFilters, "role-filters", nil, "Allow filtering by roles") cmd.Flags().StringVar(&roleSemantic, "role-semantic", "", "Specify which roles semantic to use ") + cmd.Flags().BoolVar(&options.OutputCSV, "csv", false, "Output CSV instead of a formatted table") options.AddCommonFlags(cmd) return cmd @@ -261,6 +241,7 @@ func newListEdgeRoutersCmd(options *api.Options) *cobra.Command { cmd.Flags().SetInterspersed(true) cmd.Flags().StringSliceVar(&roleFilters, "role-filters", nil, "Allow filtering by roles") cmd.Flags().StringVar(&roleSemantic, "role-semantic", "", "Specify which roles semantic to use ") + cmd.Flags().BoolVar(&options.OutputCSV, "csv", false, "Output CSV instead of a formatted table") options.AddCommonFlags(cmd) return cmd @@ -289,6 +270,7 @@ func newListIdentitiesCmd(options *api.Options) *cobra.Command { cmd.Flags().SetInterspersed(true) cmd.Flags().StringSliceVar(&roleFilters, "role-filters", nil, "Allow filtering by roles") cmd.Flags().StringVar(&roleSemantic, "role-semantic", "", "Specify which roles semantic to use ") + cmd.Flags().BoolVar(&options.OutputCSV, "csv", false, "Output CSV instead of a formatted table") options.AddCommonFlags(cmd) return cmd @@ -314,34 +296,35 @@ func newSubListCmdForEntityType(entityType string, subType string, outputF outpu // allow interspersing positional args and flags cmd.Flags().SetInterspersed(true) options.AddCommonFlags(cmd) + cmd.Flags().BoolVar(&options.OutputCSV, "csv", false, "Output CSV instead of a formatted table") return cmd } -// listEntitiesOfType queries the Ziti Controller for entities of the given type -func listEntitiesWithOptions(entityType string, options *api.Options) ([]*gabs.Container, *paging, error) { +// ListEntitiesOfType queries the Ziti Controller for entities of the given type +func listEntitiesWithOptions(entityType string, options *api.Options) ([]*gabs.Container, *api.Paging, error) { params := url.Values{} if len(options.Args) > 0 { params.Add("filter", options.Args[0]) } - return listEntitiesOfType(entityType, params, options.OutputJSONResponse, options.Out, options.Timeout, options.Verbose) + return ListEntitiesOfType(entityType, params, options.OutputJSONResponse, options.Out, options.Timeout, options.Verbose) } -func listEntitiesWithFilter(entityType string, filter string) ([]*gabs.Container, *paging, error) { +func ListEntitiesWithFilter(entityType string, filter string) ([]*gabs.Container, *api.Paging, error) { params := url.Values{} params.Add("filter", filter) - return listEntitiesOfType(entityType, params, false, nil, 5, false) + 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) { +func filterEntitiesOfType(entityType string, filter string, logJSON bool, out io.Writer, timeout int, verbose bool) ([]*gabs.Container, *api.Paging, error) { params := url.Values{} params.Add("filter", filter) - return listEntitiesOfType(entityType, params, logJSON, out, timeout, verbose) + return ListEntitiesOfType(entityType, params, logJSON, out, timeout, verbose) } -// listEntitiesOfType queries the Ziti Controller for entities of the given type -func listEntitiesOfType(entityType string, params url.Values, logJSON bool, out io.Writer, timeout int, verbose bool) ([]*gabs.Container, *paging, error) { +// ListEntitiesOfType queries the Ziti Controller for entities of the given type +func ListEntitiesOfType(entityType string, params url.Values, logJSON bool, out io.Writer, timeout int, verbose bool) ([]*gabs.Container, *api.Paging, error) { jsonParsed, err := util.EdgeControllerList(entityType, params, logJSON, out, timeout, verbose) if err != nil { @@ -349,7 +332,7 @@ func listEntitiesOfType(entityType string, params url.Values, logJSON bool, out } children, err := jsonParsed.S("data").Children() - return children, getPaging(jsonParsed), err + return children, api.GetPaging(jsonParsed), err } func toInt64(c *gabs.Container, path string, errorHolder errorz.ErrorHolder) int64 { @@ -366,21 +349,8 @@ func toInt64(c *gabs.Container, path string, errorHolder errorz.ErrorHolder) int return int64(val) } -func getPaging(c *gabs.Container) *paging { - pagingInfo := &paging{} - pagination := c.S("meta", "pagination") - if pagination != nil { - pagingInfo.limit = toInt64(pagination, "limit", pagingInfo) - pagingInfo.offset = toInt64(pagination, "offset", pagingInfo) - pagingInfo.count = toInt64(pagination, "totalCount", pagingInfo) - } else { - pagingInfo.SetError(errors.New("meta.pagination section not found in result")) - } - return pagingInfo -} - -// listEntitiesOfType queries the Ziti Controller for entities of the given type -func filterSubEntitiesOfType(entityType, subType, entityId, filter string, o *api.Options) ([]*gabs.Container, *paging, error) { +// ListEntitiesOfType queries the Ziti Controller for entities of the given type +func filterSubEntitiesOfType(entityType, subType, entityId, filter string, o *api.Options) ([]*gabs.Container, *api.Paging, error) { jsonParsed, err := util.EdgeControllerListSubEntities(entityType, subType, entityId, filter, o.OutputJSONResponse, o.Out, o.Timeout, o.Verbose) if err != nil { @@ -389,9 +359,9 @@ func filterSubEntitiesOfType(entityType, subType, entityId, filter string, o *ap children, err := jsonParsed.S("data").Children() if err == gabs.ErrNotObjOrArray { - return nil, getPaging(jsonParsed), nil + return nil, api.GetPaging(jsonParsed), nil } - return children, getPaging(jsonParsed), err + return children, api.GetPaging(jsonParsed), err } func runListEdgeRouters(roleFilters []string, roleSemantic string, options *api.Options) error { @@ -405,7 +375,7 @@ func runListEdgeRouters(roleFilters []string, roleSemantic string, options *api. if roleSemantic != "" { params.Add("roleSemantic", roleSemantic) } - children, paging, err := listEntitiesOfType("edge-routers", params, options.OutputJSONResponse, options.Out, options.Timeout, options.Verbose) + children, paging, err := api.ListEntitiesOfType(util.EdgeAPI, "edge-routers", params, options.OutputJSONResponse, options.Out, options.Timeout, options.Verbose) if err != nil { return err } @@ -413,23 +383,26 @@ func runListEdgeRouters(roleFilters []string, roleSemantic string, options *api. return outputEdgeRouters(options, children, paging) } -func outputEdgeRouters(o *api.Options, children []*gabs.Container, pagingInfo *paging) error { +func outputEdgeRouters(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error { if o.OutputJSONResponse { return nil } + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.AppendHeader(table.Row{"ID", "Name", "Online", "Allow Transit", "Cost", "Attributes"}) + for _, entity := range children { - id, _ := entity.Path("id").Data().(string) - name, _ := entity.Path("name").Data().(string) - isOnline, _ := entity.Path("isOnline").Data().(bool) - cost, _ := entity.Path("cost").Data().(float64) - roleAttributes := entity.Path("roleAttributes").String() - noTraversal, _ := entity.Path("noTraversal").Data().(bool) - if _, err := fmt.Fprintf(o.Out, "id: %v name: %v isOnline: %v cost: %v noTraversal: %t role attributes: %v\n", id, name, isOnline, cost, noTraversal, roleAttributes); err != nil { - return err - } + wrapper := api.Wrap(entity) + t.AppendRow(table.Row{ + wrapper.String("id"), + wrapper.String("name"), + wrapper.Bool("isOnline"), + !wrapper.Bool("noTraversal"), + wrapper.Float64("cost"), + strings.Join(wrapper.StringSlice("roleAttributes"), "\n")}) } - pagingInfo.output(o) + api.RenderTable(o, t, pagingInfo) return nil } @@ -441,15 +414,17 @@ func runListEdgeRouterPolicies(o *api.Options) error { return outputEdgeRouterPolicies(o, children, paging) } -func outputEdgeRouterPolicies(o *api.Options, children []*gabs.Container, pagingInfo *paging) error { +func outputEdgeRouterPolicies(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error { if o.OutputJSONResponse { return nil } - for _, entity := range children { - id, _ := entity.Path("id").Data().(string) - name, _ := entity.Path("name").Data().(string) + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.AppendHeader(table.Row{"ID", "Name", "Edge Router Roles", "Identity Roles"}) + for _, entity := range children { + wrapper := api.Wrap(entity) identityRoles, err := mapRoleIdsToNames(entity, "identityRoles") if err != nil { return err @@ -460,12 +435,14 @@ func outputEdgeRouterPolicies(o *api.Options, children []*gabs.Container, paging return err } - _, err = fmt.Fprintf(o.Out, "id: %v name: %v edge router roles: %v identity roles: %v\n", id, name, edgeRouterRoles, identityRoles) - if err != nil { - return err - } + t.AppendRow(table.Row{ + wrapper.String("id"), + wrapper.String("name"), + strings.Join(edgeRouterRoles, " "), + strings.Join(identityRoles, " "), + }) } - pagingInfo.output(o) + api.RenderTable(o, t, pagingInfo) return nil } @@ -477,11 +454,15 @@ func runListTerminators(o *api.Options) error { return outputTerminators(o, children, pagingInfo) } -func outputTerminators(o *api.Options, children []*gabs.Container, pagingInfo *paging) error { +func outputTerminators(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error { if o.OutputJSONResponse { return nil } + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.AppendHeader(table.Row{"ID", "Service", "Router", "Binding", "Address", "Identity", "Cost", "Precedence", "Dynamic Cost"}) + for _, entity := range children { id, _ := entity.Path("id").Data().(string) service := entity.Path("service.name").Data().(string) @@ -492,13 +473,10 @@ func outputTerminators(o *api.Options, children []*gabs.Container, pagingInfo *p staticCost := entity.Path("cost").Data().(float64) precedence := entity.Path("precedence").Data().(string) dynamicCost := entity.Path("dynamicCost").Data().(float64) - _, err := fmt.Fprintf(o.Out, "id: %v service: %v router: %v binding: %v address: %v identity: %v cost: %v precedence: %v dynamic-cost: %v\n", - id, service, router, binding, address, identity, staticCost, precedence, dynamicCost) - if err != nil { - return err - } + + t.AppendRow(table.Row{id, service, router, binding, address, identity, staticCost, precedence, dynamicCost}) } - pagingInfo.output(o) + api.RenderTable(o, t, pagingInfo) return nil } @@ -528,50 +506,56 @@ func runListServices(asIdentity string, configTypes []string, roleFilters []stri if roleSemantic != "" { params.Add("roleSemantic", roleSemantic) } - children, pagingInfo, err := listEntitiesOfType("services", params, options.OutputJSONResponse, options.Out, options.Timeout, options.Verbose) + children, pagingInfo, err := ListEntitiesOfType("services", params, options.OutputJSONResponse, options.Out, options.Timeout, options.Verbose) if err != nil { return err } return outputServices(options, children, pagingInfo) } -func outputServices(o *api.Options, children []*gabs.Container, pagingInfo *paging) error { +func outputServices(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error { if o.OutputJSONResponse { return nil } - for _, entity := range children { - id, _ := entity.Path("id").Data().(string) - name, _ := entity.Path("name").Data().(string) - encryptionRequired, _ := entity.Path("encryptionRequired").Data().(bool) - terminatorStrategy, _ := entity.Path("terminatorStrategy").Data().(string) - roleAttributes := entity.Path("roleAttributes").String() + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.AppendHeader(table.Row{"ID", "Name", "Encryption Required", "Terminator Strategy", "Attributes"}) + t.SetColumnConfigs([]table.ColumnConfig{ + {Number: 3, WidthMax: 10}, + }) - _, err := fmt.Fprintf(o.Out, "id: %v name: %v encryption required: %v terminator strategy: %v role attributes: %v\n", id, name, encryptionRequired, terminatorStrategy, roleAttributes) - if err != nil { - return err - } + for _, entity := range children { + wrapper := api.Wrap(entity) + t.AppendRow(table.Row{ + wrapper.String("id"), + wrapper.String("name"), + wrapper.Bool("encryptionRequired"), + wrapper.String("terminatorStrategy"), + strings.Join(wrapper.StringSlice("roleAttributes"), "\n")}) } - pagingInfo.output(o) + api.RenderTable(o, t, pagingInfo) + return nil } -func outputServiceConfigs(o *api.Options, children []*gabs.Container, pagingInfo *paging) error { +func outputServiceConfigs(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error { if o.OutputJSONResponse { return nil } + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.AppendHeader(table.Row{"Service Name", "Config Name"}) + for _, entity := range children { - service, _ := entity.Path("service").Data().(string) - serviceName, _ := mapIdToName("services", service, *o) - config, _ := entity.Path("config").Data().(string) - configName, _ := mapIdToName("configs", config, *o) - _, err := fmt.Fprintf(o.Out, "service: %v config: %v\n", serviceName, configName) - if err != nil { - return err - } + wrapper := api.Wrap(entity) + t.AppendRow(table.Row{ + wrapper.String("service.name"), + wrapper.String("config.name"), + }) } - pagingInfo.output(o) + api.RenderTable(o, t, pagingInfo) return nil } @@ -583,28 +567,35 @@ func runListServiceEdgeRouterPolices(o *api.Options) error { return outputServiceEdgeRouterPolicies(o, children, pagingInfo) } -func outputServiceEdgeRouterPolicies(o *api.Options, children []*gabs.Container, pagingInfo *paging) error { +func outputServiceEdgeRouterPolicies(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error { if o.OutputJSONResponse { return nil } + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.AppendHeader(table.Row{"ID", "Name", "Service Roles", "Edge Router Roles"}) + for _, entity := range children { - id, _ := entity.Path("id").Data().(string) - name, _ := entity.Path("name").Data().(string) - edgeRouterRoles, err := mapRoleIdsToNames(entity, "edgeRouterRoles") - if err != nil { - return err - } + wrapper := api.Wrap(entity) serviceRoles, err := mapRoleIdsToNames(entity, "serviceRoles") if err != nil { return err } - _, err = fmt.Fprintf(o.Out, "id: %v name: %v edge router roles: %v service roles: %v\n", id, name, edgeRouterRoles, serviceRoles) + + edgeRouterRoles, err := mapRoleIdsToNames(entity, "edgeRouterRoles") if err != nil { return err } + + t.AppendRow(table.Row{ + wrapper.String("id"), + wrapper.String("name"), + strings.Join(serviceRoles, " "), + strings.Join(edgeRouterRoles, " "), + }) } - pagingInfo.output(o) + api.RenderTable(o, t, pagingInfo) return nil } @@ -616,36 +607,43 @@ func runListServicePolices(o *api.Options) error { return outputServicePolicies(o, children, pagingInfo) } -func outputServicePolicies(o *api.Options, children []*gabs.Container, pagingInfo *paging) error { +func outputServicePolicies(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error { if o.OutputJSONResponse { return nil } + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.AppendHeader(table.Row{"ID", "Name", "Semantic", "Service Roles", "Identity Roles", "Posture Check Roles"}) + for _, entity := range children { - id, _ := entity.Path("id").Data().(string) - name, _ := entity.Path("name").Data().(string) - policyType, _ := entity.Path("type").Data().(string) + wrapper := api.Wrap(entity) + + serviceRoles, err := mapRoleIdsToNames(entity, "serviceRoles") + if err != nil { + return err + } identityRoles, err := mapRoleIdsToNames(entity, "identityRoles") if err != nil { return err } - serviceRoles, err := mapRoleIdsToNames(entity, "serviceRoles") - if err != nil { - return err - } postureCheckRoles, err := mapRoleIdsToNames(entity, "postureCheckRoles") if err != nil { return err } - _, err = fmt.Fprintf(o.Out, "id: %v name: %v type: %v service roles: %v identity roles: %v posture check roles: %v\n", id, name, policyType, serviceRoles, identityRoles, postureCheckRoles) - if err != nil { - return err - } + t.AppendRow(table.Row{ + wrapper.String("id"), + wrapper.String("name"), + wrapper.String("semantic"), + strings.Join(serviceRoles, " "), + strings.Join(identityRoles, " "), + strings.Join(postureCheckRoles, " "), + }) } - pagingInfo.output(o) + api.RenderTable(o, t, pagingInfo) return nil } @@ -697,7 +695,7 @@ func runListIdentities(roleFilters []string, roleSemantic string, options *api.O if roleSemantic != "" { params.Add("roleSemantic", roleSemantic) } - children, pagingInfo, err := listEntitiesOfType("identities", params, options.OutputJSONResponse, options.Out, options.Timeout, options.Verbose) + children, pagingInfo, err := ListEntitiesOfType("identities", params, options.OutputJSONResponse, options.Out, options.Timeout, options.Verbose) if err != nil { return err } @@ -705,21 +703,24 @@ func runListIdentities(roleFilters []string, roleSemantic string, options *api.O } // outputIdentities implements the command to list identities -func outputIdentities(o *api.Options, children []*gabs.Container, pagingInfo *paging) error { +func outputIdentities(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error { if o.OutputJSONResponse { return nil } + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.AppendHeader(table.Row{"ID", "Name", "Type", "Attributes"}) + for _, entity := range children { - id, _ := entity.Path("id").Data().(string) - name, _ := entity.Path("name").Data().(string) - typeName, _ := entity.Path("type.name").Data().(string) - roleAttributes := entity.Path("roleAttributes").String() - if _, err := fmt.Fprintf(o.Out, "id: %v name: %v type: %v role attributes: %v\n", id, name, typeName, roleAttributes); err != nil { - return err - } + wrapper := api.Wrap(entity) + t.AppendRow(table.Row{ + wrapper.String("id"), + wrapper.String("name"), + wrapper.String("type.name"), + strings.Join(wrapper.StringSlice("roleAttributes"), ",")}) } - pagingInfo.output(o) + api.RenderTable(o, t, pagingInfo) return nil } @@ -824,7 +825,7 @@ func getEllipsesStrings(values []string, lead, lag int) []string { return ret } -func outputPostureChecks(o *api.Options, children []*gabs.Container, pagingInfo *paging) error { +func outputPostureChecks(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error { if o.OutputJSONResponse { return nil } @@ -834,7 +835,7 @@ func outputPostureChecks(o *api.Options, children []*gabs.Container, pagingInfo return err } } - pagingInfo.output(o) + pagingInfo.Output(o) return nil } @@ -922,7 +923,7 @@ func runListCAs(o *api.Options) error { } pagingInfo := newPagingInfo(payload.Meta) - pagingInfo.output(o) + pagingInfo.Output(o) _, _ = fmt.Fprint(o.Out, "\nFlags: (V) Verified, (A) AutoCa Enrollment, (O) OttCA Enrollment, (E) Authentication Enabled\n\n") @@ -939,14 +940,19 @@ func runListConfigTypes(o *api.Options) error { return nil } + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.AppendHeader(table.Row{"ID", "Name", "Schema"}) + for _, entity := range children { - id, _ := entity.Path("id").Data().(string) - name, _ := entity.Path("name").Data().(string) - if _, err := fmt.Fprintf(o.Out, "id: %v name: %v\n", id, name); err != nil { - return err - } + wrapper := api.Wrap(entity) + t.AppendRow(table.Row{ + wrapper.String("id"), + wrapper.String("name"), + }) } - pagingInfo.output(o) + api.RenderTable(o, t, pagingInfo) + return nil } @@ -958,25 +964,25 @@ func runListConfigs(o *api.Options) error { return outputConfigs(o, children, pagingInfo) } -func outputConfigs(o *api.Options, children []*gabs.Container, pagingInfo *paging) error { +func outputConfigs(o *api.Options, children []*gabs.Container, pagingInfo *api.Paging) error { if o.OutputJSONResponse { return nil } + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.AppendHeader(table.Row{"ID", "Name", "Config Type"}) + for _, entity := range children { - id, _ := entity.Path("id").Data().(string) - name, _ := entity.Path("name").Data().(string) - configType, _ := entity.Path("configType.name").Data().(string) - data, _ := entity.Path("data").Data().(map[string]interface{}) - formattedData, err := json.MarshalIndent(data, " ", " ") - if err != nil { - return err - } - if _, err := fmt.Fprintf(o.Out, "id: %v\nname: %v\ntype: %v\ndata: %v\n\n", id, name, configType, string(formattedData)); err != nil { - return err - } + wrapper := api.Wrap(entity) + t.AppendRow(table.Row{ + wrapper.String("id"), + wrapper.String("name"), + wrapper.String("configType.name"), + }) } - pagingInfo.output(o) + api.RenderTable(o, t, pagingInfo) + return nil } @@ -990,16 +996,21 @@ func runListApiSessions(o *api.Options) error { return nil } + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.AppendHeader(table.Row{"ID", "Token", "Identity Name"}) + for _, entity := range children { - id, _ := entity.Path("id").Data().(string) - sessionToken, _ := entity.Path("token").Data().(string) - identityName, _ := entity.Path("identity.name").Data().(string) - if _, err = fmt.Fprintf(o.Out, "id: %v token: %v identity: %v\n", id, sessionToken, identityName); err != nil { - return err - } + wrapper := api.Wrap(entity) + t.AppendRow(table.Row{ + wrapper.String("id"), + wrapper.String("token"), + wrapper.String("identity.name"), + }) } - pagingInfo.output(o) - return err + api.RenderTable(o, t, pagingInfo) + + return nil } func runListSessions(o *api.Options) error { @@ -1013,17 +1024,22 @@ func runListSessions(o *api.Options) error { return nil } + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.AppendHeader(table.Row{"ID", "API Session ID", "Service Name", "Type"}) + for _, entity := range children { - id, _ := entity.Path("id").Data().(string) - sessionId, _ := entity.Path("apiSession.id").Data().(string) - serviceName, _ := entity.Path("service.name").Data().(string) - sessionType, _ := entity.Path("type").Data().(string) - if _, err := fmt.Fprintf(o.Out, "id: %v sessionId: %v serviceName: %v type: %v\n", id, sessionId, serviceName, sessionType); err != nil { - return err - } + wrapper := api.Wrap(entity) + t.AppendRow(table.Row{ + wrapper.String("id"), + wrapper.String("apiSession.id"), + wrapper.String("service.name"), + wrapper.String("type"), + }) } - pagingInfo.output(o) - return err + api.RenderTable(o, t, pagingInfo) + + return nil } func runListTransitRouters(o *api.Options) error { @@ -1037,15 +1053,20 @@ func runListTransitRouters(o *api.Options) error { return nil } + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.AppendHeader(table.Row{"ID", "Name"}) + for _, entity := range children { - id, _ := entity.Path("id").Data().(string) - name, _ := entity.Path("name").Data().(string) - if _, err := fmt.Fprintf(o.Out, "id: %v name: %v\n", id, name); err != nil { - return err - } + wrapper := api.Wrap(entity) + t.AppendRow(table.Row{ + wrapper.String("id"), + wrapper.String("name"), + }) } - pagingInfo.output(o) - return err + api.RenderTable(o, t, pagingInfo) + + return nil } func runListEdgeRouterRoleAttributes(o *api.Options) error { @@ -1071,13 +1092,18 @@ func runListRoleAttributes(entityType string, o *api.Options) error { return nil } + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.AppendHeader(table.Row{"Role Attribute"}) + for _, entity := range children { - if _, err := fmt.Fprintf(o.Out, "role-attribute: %v\n", entity.Data().(string)); err != nil { - return err - } + t.AppendRow(table.Row{ + fmt.Sprintf("%v", entity.Data()), + }) } - pagingInfo.output(o) - return err + api.RenderTable(o, t, pagingInfo) + + return nil } func runListChilden(parentType, childType string, o *api.Options, outputF outputFunction) error { @@ -1120,7 +1146,9 @@ func runListPostureChecks(o *api.Options) error { func runListSummary(o *api.Options) error { jsonParsed, err := util.EdgeControllerList("summary", url.Values{}, o.OutputJSONResponse, o.Out, o.Timeout, o.Verbose) - + if err != nil { + return err + } if o.OutputJSONResponse { return nil } @@ -1138,13 +1166,16 @@ func runListSummary(o *api.Options) error { sort.Strings(keys) + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.SetColumnConfigs([]table.ColumnConfig{{Number: 2, Align: text.AlignRight}}) + t.AppendHeader(table.Row{"Entity Type", "Count"}) + for _, k := range keys { v := children[k] - _, err = fmt.Fprintf(o.Out, "%v: %v\n", k, v.Data()) - if err != nil { - return err - } + t.AppendRow(table.Row{k, fmt.Sprintf("%v", v.Data())}) } + api.RenderTable(o, t, nil) return nil } @@ -1174,16 +1205,22 @@ func runListPostureCheckTypes(o *api.Options) error { return nil } + t := table.NewWriter() + t.SetStyle(table.StyleRounded) + t.AppendHeader(table.Row{"ID", "Operating Systems"}) + for _, entity := range children { - id, _ := entity.Path("id").Data().(string) + wrapper := api.Wrap(entity) operatingSystems, _ := entity.Path("operatingSystems").Children() osInfo := postureCheckOsToStrings(operatingSystems) - if _, err := fmt.Fprintf(o.Out, "id: %-8s os: %s\n", id, strings.Join(osInfo, ",")); err != nil { - return err - } + t.AppendRow(table.Row{ + wrapper.String("id"), + strings.Join(osInfo, ","), + }) } - pagingInfo.output(o) + api.RenderTable(o, t, pagingInfo) + return err } diff --git a/ziti/cmd/ziti/cmd/edge/root.go b/ziti/cmd/ziti/cmd/edge/root.go index e34cc14ba..4046c1616 100644 --- a/ziti/cmd/ziti/cmd/edge/root.go +++ b/ziti/cmd/ziti/cmd/edge/root.go @@ -18,37 +18,43 @@ package edge import ( "github.com/openziti/ziti/common/enrollment" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" "io" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" "github.com/openziti/ziti/ziti/cmd/ziti/util" "github.com/spf13/cobra" ) +var ExtraEdgeCommands []func(p common.OptionsProvider) *cobra.Command + // NewCmdEdge creates a command object for the "controller" command -func NewCmdEdge(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdEdge(out io.Writer, errOut io.Writer) *cobra.Command { cmd := util.NewEmptyParentCmd("edge", "Interact with Ziti Edge Components") - populateEdgeCommands(f, out, errOut, cmd) + populateEdgeCommands(out, errOut, cmd) return cmd } -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)) +func populateEdgeCommands(out io.Writer, errOut io.Writer, cmd *cobra.Command) *cobra.Command { + cmd.AddCommand(newCreateCmd(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(newUpdateCmd(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(out, errOut)) - cmd.AddCommand(newTutorialCmd(p)) cmd.AddCommand(newTraceRouteCmd(out, errOut)) + cmd.AddCommand(newShowCmd(out, errOut)) + + p := common.NewOptionsProvider(out, errOut) + for _, cmdF := range ExtraEdgeCommands { + cmd.AddCommand(cmdF(p)) + } + return cmd } diff --git a/ziti/cmd/ziti/cmd/edge/show.go b/ziti/cmd/ziti/cmd/edge/show.go new file mode 100644 index 000000000..ed4a46743 --- /dev/null +++ b/ziti/cmd/ziti/cmd/edge/show.go @@ -0,0 +1,155 @@ +/* + 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 ( + "encoding/json" + "fmt" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + "github.com/openziti/ziti/ziti/cmd/ziti/util" + "github.com/spf13/cobra" + "io" +) + +// newCreateCmd creates a command object for the "list" command +func newShowCmd(out io.Writer, errOut io.Writer) *cobra.Command { + showCmd := &cobra.Command{ + Use: "show", + Short: "displays various entities managed by the Ziti Edge Controller", + Run: func(cmd *cobra.Command, args []string) { + cmdhelper.CheckErr(cmd.Help()) + }, + } + + showCmd.AddCommand(newShowConfigTypeAction(out, errOut)) + showCmd.AddCommand(newShowConfigAction(out, errOut)) + return showCmd +} + +func newShowConfigAction(out io.Writer, errOut io.Writer) *cobra.Command { + action := &showConfigAction{ + Options: api.Options{ + CommonOptions: common.CommonOptions{ + Out: out, + Err: errOut, + }, + }, + } + + showConfigDefCmd := &cobra.Command{ + Use: "config ", + Short: "displays the JSON config definition for a given config", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + action.Cmd = cmd + action.Args = args + return action.run(cmd, args) + }, + } + + action.AddCommonFlags(showConfigDefCmd) + + return showConfigDefCmd +} + +type showConfigAction struct { + api.Options +} + +func (self *showConfigAction) run(_ *cobra.Command, args []string) error { + id, err := mapNameToID("configs", args[0], self.Options) + if err != nil { + return err + } + + jsonVal, err := util.ControllerDetailEntity(util.EdgeAPI, "configs", id, self.OutputJSONResponse, self.Out, self.Timeout, self.Verbose) + if err != nil { + return err + } + + if self.OutputJSONResponse { + return nil + } + + schema := jsonVal.Path("data.data") + formattedData, err := json.MarshalIndent(schema.Data(), "", " ") + if err != nil { + return err + } + + fmt.Println(string(formattedData)) + + return nil +} + +func newShowConfigTypeAction(out io.Writer, errOut io.Writer) *cobra.Command { + action := &showConfigTypeAction{ + Options: api.Options{ + CommonOptions: common.CommonOptions{ + Out: out, + Err: errOut, + }, + }, + } + + showConfigTypeSchemaCmd := &cobra.Command{ + Use: "config-type ", + Short: "displays the JSON schema for a given config type", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + action.Cmd = cmd + action.Args = args + return action.run(cmd, args) + }, + } + + action.AddCommonFlags(showConfigTypeSchemaCmd) + + return showConfigTypeSchemaCmd +} + +type showConfigTypeAction struct { + api.Options +} + +func (self *showConfigTypeAction) run(_ *cobra.Command, args []string) error { + id, err := mapNameToID("config-types", args[0], self.Options) + if err != nil { + return err + } + + jsonVal, err := util.ControllerDetailEntity(util.EdgeAPI, "config-types", id, self.OutputJSONResponse, self.Out, self.Timeout, self.Verbose) + if err != nil { + return err + } + + if self.OutputJSONResponse { + return nil + } + + schema := jsonVal.Path("data.schema") + formattedData, err := json.MarshalIndent(schema.Data(), "", " ") + if err != nil { + return err + } + + fmt.Println(string(formattedData)) + + return nil +} diff --git a/ziti/cmd/ziti/cmd/edge/traceroute.go b/ziti/cmd/ziti/cmd/edge/traceroute.go index 8c49a10e4..3f2396a88 100644 --- a/ziti/cmd/ziti/cmd/edge/traceroute.go +++ b/ziti/cmd/ziti/cmd/edge/traceroute.go @@ -95,7 +95,7 @@ func (o *traceRouteOptions) Run() error { return err } - if result.Hops > 0 { + if result.Hops > 0 && result.Error == "" { break } @@ -110,13 +110,21 @@ func (o *traceRouteOptions) Run() error { } } + hopErr := "" + if result.Error != "" { + hopErr = fmt.Sprintf("ERROR=%v", result.Error) + } + if hopLabel == "" { - fmt.Printf("%2v %25v %6v \n", currentHop, result.HopType, result.Time) + fmt.Printf("%2v %25v %6v %v\n", currentHop, result.HopType, result.Time, hopErr) } else { - fmt.Printf("%2v %25v %6v \n", currentHop, fmt.Sprintf("%v[%v]", result.HopType, hopLabel), result.Time) + fmt.Printf("%2v %25v %6v %v\n", currentHop, fmt.Sprintf("%v[%v]", result.HopType, hopLabel), result.Time, hopErr) } currentHop++ + if hopErr != "" { + break + } } if routerNameLookupsFailed { diff --git a/ziti/cmd/ziti/cmd/edge/tutorial.go b/ziti/cmd/ziti/cmd/edge/tutorial.go deleted file mode 100644 index b0a1272cd..000000000 --- a/ziti/cmd/ziti/cmd/edge/tutorial.go +++ /dev/null @@ -1,426 +0,0 @@ -package edge - -import ( - _ "embed" - "fmt" - "github.com/fatih/color" - "github.com/openziti/foundation/util/term" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" - cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" - "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" - "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 { - api.Options - tutorialOptions -} - -func newFirstServiceTutorialCmd(p common.OptionsProvider) *cobra.Command { - options := &firstServiceTutorialOptions{ - Options: api.Options{ - 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 -} diff --git a/ziti/cmd/ziti/cmd/edge/tutorial_plain_echo_client.go b/ziti/cmd/ziti/cmd/edge/tutorial_plain_echo_client.go deleted file mode 100644 index 73575f1e8..000000000 --- a/ziti/cmd/ziti/cmd/edge/tutorial_plain_echo_client.go +++ /dev/null @@ -1,27 +0,0 @@ -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 -} diff --git a/ziti/cmd/ziti/cmd/edge/update.go b/ziti/cmd/ziti/cmd/edge/update.go index 743964ad0..fc1b40220 100644 --- a/ziti/cmd/ziti/cmd/edge/update.go +++ b/ziti/cmd/ziti/cmd/edge/update.go @@ -19,7 +19,6 @@ package edge import ( "github.com/Jeffail/gabs" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/openziti/ziti/ziti/cmd/ziti/util" "github.com/spf13/cobra" @@ -28,7 +27,7 @@ import ( ) // newUpdateCmd creates a command object for the "controller update" command -func newUpdateCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newUpdateCmd(out io.Writer, errOut io.Writer) *cobra.Command { cmd := &cobra.Command{ Use: "update", Short: "updates various entities managed by the Ziti Edge Controller", @@ -39,17 +38,18 @@ func newUpdateCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Com }, } - cmd.AddCommand(newUpdateAuthenticatorCmd(f, out, errOut)) - cmd.AddCommand(newUpdateConfigCmd(f, out, errOut)) - cmd.AddCommand(newUpdateCaCmd(f, out, errOut)) - cmd.AddCommand(newUpdateEdgeRouterCmd(f, out, errOut)) - cmd.AddCommand(newUpdateEdgeRouterPolicyCmd(f, out, errOut)) - cmd.AddCommand(newUpdateIdentityCmd(f, out, errOut)) - cmd.AddCommand(newUpdateIdentityConfigsCmd(f, out, errOut)) - cmd.AddCommand(newUpdateServiceCmd(f, out, errOut)) - cmd.AddCommand(newUpdateServicePolicyCmd(f, out, errOut)) - cmd.AddCommand(newUpdateServiceEdgeRouterPolicyCmd(f, out, errOut)) - cmd.AddCommand(newUpdateTerminatorCmd(f, out, errOut)) + cmd.AddCommand(newUpdateAuthenticatorCmd(out, errOut)) + cmd.AddCommand(newUpdateConfigCmd(out, errOut)) + cmd.AddCommand(newUpdateConfigTypeCmd(out, errOut)) + cmd.AddCommand(newUpdateCaCmd(out, errOut)) + cmd.AddCommand(newUpdateEdgeRouterCmd(out, errOut)) + cmd.AddCommand(newUpdateEdgeRouterPolicyCmd(out, errOut)) + cmd.AddCommand(newUpdateIdentityCmd(out, errOut)) + cmd.AddCommand(newUpdateIdentityConfigsCmd(out, errOut)) + cmd.AddCommand(newUpdateServiceCmd(out, errOut)) + cmd.AddCommand(newUpdateServicePolicyCmd(out, errOut)) + cmd.AddCommand(newUpdateServiceEdgeRouterPolicyCmd(out, errOut)) + cmd.AddCommand(newUpdateTerminatorCmd(out, errOut)) cmd.AddCommand(newUpdatePostureCheckCmd(out, errOut)) return cmd diff --git a/ziti/cmd/ziti/cmd/edge/update_authenticator.go b/ziti/cmd/ziti/cmd/edge/update_authenticator.go index 59d0379ce..8c7e5fe9d 100644 --- a/ziti/cmd/ziti/cmd/edge/update_authenticator.go +++ b/ziti/cmd/ziti/cmd/edge/update_authenticator.go @@ -19,15 +19,14 @@ package edge import ( "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" "github.com/spf13/cobra" "io" ) // newUpdateAuthenticatorCmd creates the 'edge controller update authenticator' command -func newUpdateAuthenticatorCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newUpdateAuthenticatorCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, OutputJSONResponse: false, } diff --git a/ziti/cmd/ziti/cmd/edge/update_ca.go b/ziti/cmd/ziti/cmd/edge/update_ca.go index 94bc27d2c..e2ad20bea 100644 --- a/ziti/cmd/ziti/cmd/edge/update_ca.go +++ b/ziti/cmd/ziti/cmd/edge/update_ca.go @@ -22,7 +22,6 @@ import ( "github.com/openziti/edge/rest_model" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/openziti/ziti/ziti/cmd/ziti/util" "github.com/pkg/errors" @@ -47,10 +46,10 @@ type updateCaOptions struct { } // newUpdateAuthenticatorCmd creates the 'edge controller update authenticator' command -func newUpdateCaCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newUpdateCaCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := updateCaOptions{ Options: api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, OutputJSONResponse: false, }, verify: false, diff --git a/ziti/cmd/ziti/cmd/edge/update_config.go b/ziti/cmd/ziti/cmd/edge/update_config.go index 44697adae..fd8dbc08e 100644 --- a/ziti/cmd/ziti/cmd/edge/update_config.go +++ b/ziti/cmd/ziti/cmd/edge/update_config.go @@ -27,7 +27,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" ) @@ -40,10 +39,10 @@ type updateConfigOptions struct { } // newUpdateConfigCmd updates the 'edge controller update service-policy' command -func newUpdateConfigCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newUpdateConfigCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &updateConfigOptions{ Options: api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, }, } diff --git a/ziti/cmd/ziti/cmd/edge/update_config_type.go b/ziti/cmd/ziti/cmd/edge/update_config_type.go new file mode 100644 index 000000000..bd46a01f6 --- /dev/null +++ b/ziti/cmd/ziti/cmd/edge/update_config_type.go @@ -0,0 +1,119 @@ +/* + 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 ( + "encoding/json" + "fmt" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "io" + "io/ioutil" + + "github.com/pkg/errors" + + "github.com/Jeffail/gabs" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + "github.com/spf13/cobra" +) + +type updateConfigTypeAction struct { + api.Options + name string + data string + jsonFile string +} + +func newUpdateConfigTypeCmd(out io.Writer, errOut io.Writer) *cobra.Command { + action := &updateConfigTypeAction{ + Options: api.Options{ + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, + }, + } + + cmd := &cobra.Command{ + Use: "config-type ", + Short: "updates a config type managed by the Ziti Edge Controller", + Args: cobra.ExactArgs(1), + Run: func(cmd *cobra.Command, args []string) { + action.Cmd = cmd + action.Args = args + err := action.run() + cmdhelper.CheckErr(err) + }, + SuggestFor: []string{}, + } + + // allow interspersing positional args and flags + cmd.Flags().SetInterspersed(true) + cmd.Flags().StringVarP(&action.name, "name", "n", "", "Set the name of the config") + cmd.Flags().StringVarP(&action.data, "data", "d", "", "Set the data of the config") + cmd.Flags().StringVarP(&action.jsonFile, "json-file", "f", "", "Read config JSON from a file instead of the command line") + action.AddCommonFlags(cmd) + + return cmd +} + +// runUpdateConfigType update a new config on the Ziti Edge Controller +func (self *updateConfigTypeAction) run() error { + id, err := mapNameToID("configs", self.Args[0], self.Options) + if err != nil { + return err + } + entityData := gabs.New() + change := false + + if self.Cmd.Flags().Changed("name") { + api.SetJSONValue(entityData, self.name, "name") + change = true + } + + var jsonBytes []byte + + if self.Cmd.Flags().Changed("data") { + jsonBytes = []byte(self.data) + } + + if self.Cmd.Flags().Changed("json-file") { + if self.Cmd.Flags().Changed("data") { + return errors.New("only one of --data and --json-file is allowed") + } + var err error + if jsonBytes, err = ioutil.ReadFile(self.jsonFile); err != nil { + return fmt.Errorf("failed to read config json file %v: %w", self.jsonFile, err) + } + } + + if len(jsonBytes) > 0 { + dataMap := map[string]interface{}{} + if err := json.Unmarshal(jsonBytes, &dataMap); err != nil { + fmt.Printf("Attempted to parse: %v\n", string(jsonBytes)) + fmt.Printf("Failing parsing JSON: %+v\n", err) + return errors.Errorf("unable to parse data as json: %v", err) + } + api.SetJSONValue(entityData, dataMap, "data") + change = true + } + + if !change { + return errors.New("no change specified. must specify at least one attribute to change") + } + + _, err = patchEntityOfType(fmt.Sprintf("configs/%v", id), entityData.String(), &self.Options) + + return err +} diff --git a/ziti/cmd/ziti/cmd/edge/update_edge_router.go b/ziti/cmd/ziti/cmd/edge/update_edge_router.go index fe0ce7ae1..21399949a 100644 --- a/ziti/cmd/ziti/cmd/edge/update_edge_router.go +++ b/ziti/cmd/ziti/cmd/edge/update_edge_router.go @@ -26,7 +26,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" ) @@ -43,10 +42,10 @@ type updateEdgeRouterOptions struct { noTraversal bool } -func newUpdateEdgeRouterCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newUpdateEdgeRouterCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &updateEdgeRouterOptions{ Options: api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, }, } diff --git a/ziti/cmd/ziti/cmd/edge/update_edge_router_policy.go b/ziti/cmd/ziti/cmd/edge/update_edge_router_policy.go index 6812e92cd..ddf551df9 100644 --- a/ziti/cmd/ziti/cmd/edge/update_edge_router_policy.go +++ b/ziti/cmd/ziti/cmd/edge/update_edge_router_policy.go @@ -25,7 +25,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" ) @@ -37,10 +36,10 @@ type updateEdgeRouterPolicyOptions struct { identityRoles []string } -func newUpdateEdgeRouterPolicyCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newUpdateEdgeRouterPolicyCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &updateEdgeRouterPolicyOptions{ Options: api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, }, } diff --git a/ziti/cmd/ziti/cmd/edge/update_identity.go b/ziti/cmd/ziti/cmd/edge/update_identity.go index f45e4c04d..5e20f7080 100644 --- a/ziti/cmd/ziti/cmd/edge/update_identity.go +++ b/ziti/cmd/ziti/cmd/edge/update_identity.go @@ -28,7 +28,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" ) @@ -43,12 +42,13 @@ type updateIdentityOptions struct { servicePrecedences map[string]string tags map[string]string appData map[string]string + externalId string } -func newUpdateIdentityCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newUpdateIdentityCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &updateIdentityOptions{ Options: api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, }, } @@ -70,6 +70,7 @@ func newUpdateIdentityCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *c // allow interspersing positional args and flags cmd.Flags().SetInterspersed(true) cmd.Flags().StringVarP(&options.name, "name", "n", "", "Set the name of the identity") + cmd.Flags().StringVar(&options.externalId, "external-id", "", "an external id to give to the identity") cmd.Flags().StringSliceVarP(&options.roleAttributes, "role-attributes", "a", nil, "Set role attributes of the identity. Use --role-attributes '' to set an empty list") cmd.Flags().StringVarP(&options.defaultHostingPrecedence, "default-hosting-precedence", "p", "", "Default precedence to use when hosting services using this identity [default,required,failed]") @@ -96,6 +97,11 @@ func runUpdateIdentity(o *updateIdentityOptions) error { change = true } + if o.Cmd.Flags().Changed("external-id") { + api.SetJSONValue(entityData, o.externalId, "externalId") + change = true + } + if o.Cmd.Flags().Changed("role-attributes") { api.SetJSONValue(entityData, o.roleAttributes, "roleAttributes") change = true diff --git a/ziti/cmd/ziti/cmd/edge/update_identity_configs.go b/ziti/cmd/ziti/cmd/edge/update_identity_configs.go index 345ddce9a..c8c82f70a 100644 --- a/ziti/cmd/ziti/cmd/edge/update_identity_configs.go +++ b/ziti/cmd/ziti/cmd/edge/update_identity_configs.go @@ -23,7 +23,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" ) @@ -33,10 +32,10 @@ type updateIdentityConfigsOptions struct { remove bool } -func newUpdateIdentityConfigsCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newUpdateIdentityConfigsCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &updateIdentityConfigsOptions{ Options: api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, }, } diff --git a/ziti/cmd/ziti/cmd/edge/update_service.go b/ziti/cmd/ziti/cmd/edge/update_service.go index 12c4eb4d0..3ff02b769 100644 --- a/ziti/cmd/ziti/cmd/edge/update_service.go +++ b/ziti/cmd/ziti/cmd/edge/update_service.go @@ -25,7 +25,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 +38,10 @@ type updateServiceOptions struct { configs []string } -func newUpdateServiceCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newUpdateServiceCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &updateServiceOptions{ Options: api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, }, } diff --git a/ziti/cmd/ziti/cmd/edge/update_service_edge_router_policy.go b/ziti/cmd/ziti/cmd/edge/update_service_edge_router_policy.go index a2376dd94..8c38b0758 100644 --- a/ziti/cmd/ziti/cmd/edge/update_service_edge_router_policy.go +++ b/ziti/cmd/ziti/cmd/edge/update_service_edge_router_policy.go @@ -25,7 +25,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" ) @@ -37,10 +36,10 @@ type updateServiceEdgeRouterPolicyOptions struct { serviceRoles []string } -func newUpdateServiceEdgeRouterPolicyCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newUpdateServiceEdgeRouterPolicyCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &updateServiceEdgeRouterPolicyOptions{ Options: api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, }, } diff --git a/ziti/cmd/ziti/cmd/edge/update_service_policy.go b/ziti/cmd/ziti/cmd/edge/update_service_policy.go index 2190dd72c..1551587ba 100644 --- a/ziti/cmd/ziti/cmd/edge/update_service_policy.go +++ b/ziti/cmd/ziti/cmd/edge/update_service_policy.go @@ -25,7 +25,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" ) @@ -38,10 +37,10 @@ type updateServicePolicyOptions struct { postureCheckRoles []string } -func newUpdateServicePolicyCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newUpdateServicePolicyCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &updateServicePolicyOptions{ Options: api.Options{ - CommonOptions: common.CommonOptions{Factory: f, Out: out, Err: errOut}, + CommonOptions: common.CommonOptions{Out: out, Err: errOut}, }, } diff --git a/ziti/cmd/ziti/cmd/edge/update_terminator.go b/ziti/cmd/ziti/cmd/edge/update_terminator.go index 380b3b604..acebf3b97 100644 --- a/ziti/cmd/ziti/cmd/edge/update_terminator.go +++ b/ziti/cmd/ziti/cmd/edge/update_terminator.go @@ -23,7 +23,6 @@ import ( "github.com/openziti/foundation/util/stringz" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" errors2 "github.com/pkg/errors" "github.com/spf13/cobra" @@ -40,13 +39,12 @@ type updateTerminatorOptions struct { precedence string } -func newUpdateTerminatorCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newUpdateTerminatorCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &updateTerminatorOptions{ Options: api.Options{ CommonOptions: common.CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } diff --git a/ziti/cmd/ziti/cmd/execute.go b/ziti/cmd/ziti/cmd/execute.go index 99424956e..821ce55bc 100644 --- a/ziti/cmd/ziti/cmd/execute.go +++ b/ziti/cmd/ziti/cmd/execute.go @@ -21,7 +21,6 @@ import ( "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" ) @@ -47,12 +46,11 @@ var ( ) // NewCmdExecute Executes a command object for the "Execute" command -func NewCmdExecute(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdExecute(out io.Writer, errOut io.Writer) *cobra.Command { options := &ExecuteOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -69,7 +67,7 @@ func NewCmdExecute(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Co }, } - cmd.AddCommand(NewCmdExecuteController(f, out, errOut)) + cmd.AddCommand(NewCmdExecuteController(out, errOut)) options.addExecuteFlags(cmd) return cmd diff --git a/ziti/cmd/ziti/cmd/execute_controller.go b/ziti/cmd/ziti/cmd/execute_controller.go index 868c414e5..40455ff62 100644 --- a/ziti/cmd/ziti/cmd/execute_controller.go +++ b/ziti/cmd/ziti/cmd/execute_controller.go @@ -22,7 +22,6 @@ import ( "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" c "github.com/openziti/ziti/ziti/cmd/ziti/constants" @@ -50,13 +49,12 @@ type ExecuteControllerOptions struct { } // NewCmdExecuteController creates a command object for the "create" command -func NewCmdExecuteController(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdExecuteController(out io.Writer, errOut io.Writer) *cobra.Command { options := &ExecuteControllerOptions{ ExecuteOptions: ExecuteOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } @@ -77,7 +75,7 @@ func NewCmdExecuteController(f cmdutil.Factory, out io.Writer, errOut io.Writer) cmd.PersistentFlags().BoolVarP(&cliAgentEnabled, "cliagent", "a", false, "Enable CLI Agent (use in dev only)") - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/fabric/inspect.go b/ziti/cmd/ziti/cmd/fabric/inspect.go index c17406ddc..3e87394f6 100644 --- a/ziti/cmd/ziti/cmd/fabric/inspect.go +++ b/ziti/cmd/ziti/cmd/fabric/inspect.go @@ -10,19 +10,22 @@ import ( "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" "github.com/openziti/ziti/ziti/cmd/ziti/util" "github.com/spf13/cobra" + "sort" + "strings" ) // newListCmd creates a command object for the "controller list" command func newInspectCmd(p common.OptionsProvider) *cobra.Command { - listCmd := &ListCmd{Options: api.Options{CommonOptions: p()}} + listCmd := &InspectCmd{Options: api.Options{CommonOptions: p()}} return listCmd.newCobraCmd() } -type ListCmd struct { +type InspectCmd struct { api.Options + prettyPrint bool } -func (self *ListCmd) newCobraCmd() *cobra.Command { +func (self *InspectCmd) newCobraCmd() *cobra.Command { cmd := &cobra.Command{ Use: "inspect", Short: "Inspect runtime application values", @@ -33,7 +36,7 @@ func (self *ListCmd) newCobraCmd() *cobra.Command { return cmd } -func (self *ListCmd) run(cmd *cobra.Command, args []string) error { +func (self *InspectCmd) run(_ *cobra.Command, args []string) error { client, err := util.NewFabricManagementClient(self) if err != nil { return err @@ -60,7 +63,8 @@ func (self *ListCmd) run(cmd *cobra.Command, args []string) error { fmt.Printf("\nResults: (%d)\n", len(result.Values)) for _, value := range result.Values { fmt.Printf("%v.%v\n", stringz.OrEmpty(value.AppID), stringz.OrEmpty(value.Name)) - fmt.Printf("%+v\n\n", value.Value) + self.prettyPrintOutput(value.Value, 0) + fmt.Printf("\n") } } else { fmt.Printf("\nEncountered errors: (%d)\n", len(result.Errors)) @@ -71,3 +75,45 @@ func (self *ListCmd) run(cmd *cobra.Command, args []string) error { return nil } + +func (self *InspectCmd) prettyPrintOutput(val interface{}, indent int) { + if mapVal, ok := val.(map[string]interface{}); ok { + fmt.Printf("\n") + var sortedKeys []string + for k := range mapVal { + sortedKeys = append(sortedKeys, k) + } + sort.Strings(sortedKeys) + for _, k := range sortedKeys { + for i := 0; i < indent; i++ { + fmt.Printf(" ") + } + fmt.Printf("%v: ", k) + self.prettyPrintOutput(mapVal[k], indent+4) + } + } else if sliceVal, ok := val.([]interface{}); ok { + fmt.Println() + for _, v := range sliceVal { + for i := 0; i < indent; i++ { + fmt.Printf(" ") + } + fmt.Printf(" - ") + self.prettyPrintOutput(v, indent+6) + } + } else if strVal, ok := val.(string); ok { + if strings.IndexByte(strVal, '\n') > 0 { + lines := strings.Split(strVal, "\n") + fmt.Println(lines[0]) + for _, line := range lines[1:] { + for i := 0; i < indent; i++ { + fmt.Printf(" ") + } + fmt.Println(line) + } + } else { + fmt.Printf("%v\n", val) + } + } else { + fmt.Printf("%v\n", val) + } +} diff --git a/ziti/cmd/ziti/cmd/fabric/list.go b/ziti/cmd/ziti/cmd/fabric/list.go index 87eb7283c..9ecb3faf1 100644 --- a/ziti/cmd/ziti/cmd/fabric/list.go +++ b/ziti/cmd/ziti/cmd/fabric/list.go @@ -33,8 +33,9 @@ import ( // newListCmd creates a command object for the "controller list" command func newListCmd(p common.OptionsProvider) *cobra.Command { listCmd := &cobra.Command{ - Use: "list", - Short: "Lists various entities managed by the Ziti Controller", + Use: "list", + Short: "Lists various entities managed by the Ziti Controller", + Aliases: []string{"ls"}, Run: func(cmd *cobra.Command, args []string) { err := cmd.Help() cmdhelper.CheckErr(err) @@ -133,7 +134,7 @@ func outputCircuits(o *api.Options, children []*gabs.Container, pagingInfo *api. t.AppendRow(table.Row{id, client, service, path.String()}) } - renderTable(o, t, pagingInfo) + api.RenderTable(o, t, pagingInfo) return nil } @@ -180,15 +181,16 @@ func outputLinks(o *api.Options, children []*gabs.Container, pagingInfo *api.Pag t := table.NewWriter() t.SetStyle(table.StyleRounded) - columnConfigs := make([]table.ColumnConfig, 9) - columnConfigs[4] = table.ColumnConfig{Align: text.AlignRight} - columnConfigs[5] = table.ColumnConfig{Align: text.AlignRight} + columnConfigs := []table.ColumnConfig{ + {Number: 5, Align: text.AlignRight}, + {Number: 6, Align: text.AlignRight}, + {Number: 8, Align: text.AlignRight}, + } t.SetColumnConfigs(columnConfigs) - t.AppendHeader(table.Row{"ID", "Type", "Dialer", "Acceptor", "Static Cost", "Src Latency", "Dst Latency", "State", "Status", "Full Cost"}) + t.AppendHeader(table.Row{"ID", "Dialer", "Acceptor", "Static Cost", "Src Latency", "Dst Latency", "State", "Status", "Full Cost"}) for _, entity := range children { id := entity.Path("id").Data().(string) - linkType := entity.Path("type").Data().(string) srcRouter := entity.Path("sourceRouter.name").Data().(string) dstRouter := entity.Path("destRouter.name").Data().(string) staticCost := entity.Path("staticCost").Data().(float64) @@ -203,13 +205,13 @@ func outputLinks(o *api.Options, children []*gabs.Container, pagingInfo *api.Pag status = "down" } - t.AppendRow(table.Row{id, linkType, srcRouter, dstRouter, staticCost, - fmt.Sprintf("%.2vms", srcLatency), - fmt.Sprintf("%.2vms", dstLatency), + t.AppendRow(table.Row{id, srcRouter, dstRouter, staticCost, + fmt.Sprintf("%.1fms", srcLatency), + fmt.Sprintf("%.1fms", dstLatency), state, status, cost}) } - renderTable(o, t, pagingInfo) + api.RenderTable(o, t, pagingInfo) return nil } @@ -244,7 +246,7 @@ func outputTerminators(o *api.Options, children []*gabs.Container, pagingInfo *a t.AppendRow(table.Row{id, service, router, binding, address, identity, staticCost, precedence, dynamicCost}) } - renderTable(o, t, pagingInfo) + api.RenderTable(o, t, pagingInfo) return nil } @@ -272,7 +274,7 @@ func outputServices(o *api.Options, children []*gabs.Container, pagingInfo *api. t.AppendRow(table.Row{id, name, terminatorStrategy}) } - renderTable(o, t, pagingInfo) + api.RenderTable(o, t, pagingInfo) return nil } @@ -314,27 +316,13 @@ func outputRouters(o *api.Options, children []*gabs.Container, pagingInfo *api.P children, _ := listenerAddresses.Children() for idx, child := range children { addr := child.Path("address").Data().(string) - linkType := child.Path("type").Data().(string) - listeners = append(listeners, fmt.Sprintf("%v: %v (%v)", idx+1, addr, linkType)) + listeners = append(listeners, fmt.Sprintf("%v: %v", idx+1, addr)) } } t.AppendRow(table.Row{id, name, connected, cost, noTraversal, version, strings.Join(listeners, "\n")}) } - renderTable(o, t, pagingInfo) + api.RenderTable(o, t, pagingInfo) return nil } - -func renderTable(o *api.Options, t table.Writer, pagingInfo *api.Paging) { - if o.OutputCSV { - if _, err := fmt.Fprintln(o.Cmd.OutOrStdout(), t.RenderCSV()); err != nil { - panic(err) - } - } else { - if _, err := fmt.Fprintln(o.Cmd.OutOrStdout(), t.Render()); err != nil { - panic(err) - } - pagingInfo.Output(o) - } -} diff --git a/ziti/cmd/ziti/cmd/fabric/root.go b/ziti/cmd/ziti/cmd/fabric/root.go index 2266757c4..34224e1f1 100644 --- a/ziti/cmd/ziti/cmd/fabric/root.go +++ b/ziti/cmd/ziti/cmd/fabric/root.go @@ -34,6 +34,7 @@ func NewFabricCmd(p common.OptionsProvider) *cobra.Command { fabricCmd.AddCommand(newCreateCommand(p), newListCmd(p), newUpdateCommand(p), newDeleteCmd(p)) fabricCmd.AddCommand(newInspectCmd(p)) fabricCmd.AddCommand(newDbCmd(p)) + fabricCmd.AddCommand(newStreamCommand(p)) return fabricCmd } @@ -70,6 +71,33 @@ func newUpdateCommand(p common.OptionsProvider) *cobra.Command { return updateCmd } +func newStreamCommand(p common.OptionsProvider) *cobra.Command { + streamCmd := &cobra.Command{ + Use: "stream", + Short: "stream fabric operational data", + Run: func(cmd *cobra.Command, args []string) { + cmdhelper.CheckErr(cmd.Help()) + }, + } + + streamCmd.AddCommand(NewStreamMetricsCmd(p)) + streamCmd.AddCommand(NewStreamCircuitsCmd(p)) + streamTracesCmd := NewStreamTracesCmd(p) + streamCmd.AddCommand(streamTracesCmd) + + var toggleTracesCmd = &cobra.Command{ + Use: "toggle", + Short: "Toggle traces on or off", + Run: func(cmd *cobra.Command, args []string) { + cmdhelper.CheckErr(cmd.Help()) + }, + } + streamTracesCmd.AddCommand(toggleTracesCmd) + toggleTracesCmd.AddCommand(NewStreamTogglePipeTracesCmd(p)) + + return streamCmd +} + // createEntityOfType create an entity of the given type on the Ziti Controller func createEntityOfType(entityType string, body string, options *api.Options) (*gabs.Container, error) { return util.ControllerCreate("fabric", entityType, body, options.Out, options.OutputJSONRequest, options.OutputJSONResponse, options.Timeout, options.Verbose) diff --git a/ziti/cmd/ziti/cmd/fabric/stream_circuits.go b/ziti/cmd/ziti/cmd/fabric/stream_circuits.go new file mode 100644 index 000000000..1e62511cc --- /dev/null +++ b/ziti/cmd/ziti/cmd/fabric/stream_circuits.go @@ -0,0 +1,94 @@ +/* + Copyright NetFoundry, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package fabric + +import ( + "fmt" + "github.com/golang/protobuf/proto" + "github.com/openziti/channel" + "github.com/openziti/fabric/pb/mgmt_pb" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + "github.com/spf13/cobra" + "time" +) + +type streamCircuitsAction struct { + api.Options +} + +func NewStreamCircuitsCmd(p common.OptionsProvider) *cobra.Command { + action := streamCircuitsAction{ + Options: api.Options{ + CommonOptions: p(), + }, + } + + streamCircuitsCmd := &cobra.Command{ + Use: "circuits", + Short: "Stream circuit data as circuits are created/destroyed", + Args: cobra.MaximumNArgs(0), + Run: action.streamCircuits, + } + + action.AddCommonFlags(streamCircuitsCmd) + + return streamCircuitsCmd +} + +func (self *streamCircuitsAction) streamCircuits(*cobra.Command, []string) { + closeNotify := make(chan struct{}) + + bindHandler := func(binding channel.Binding) error { + binding.AddReceiveHandler(int32(mgmt_pb.ContentType_StreamCircuitsEventType), self) + binding.AddCloseHandler(channel.CloseHandlerF(func(ch channel.Channel) { + close(closeNotify) + })) + return nil + } + + ch, err := api.NewWsMgmtChannel(channel.BindHandlerF(bindHandler)) + if err != nil { + panic(err) + } + + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_StreamCircuitsRequestType), nil) + if err = requestMsg.WithTimeout(5 * time.Second).SendAndWaitForWire(ch); err != nil { + panic(err) + } + + <-closeNotify +} + +func (self *streamCircuitsAction) HandleReceive(msg *channel.Message, _ channel.Channel) { + event := &mgmt_pb.StreamCircuitsEvent{} + err := proto.Unmarshal(msg.Body, event) + if err != nil { + panic(err) + } + + eventType := mgmt_pb.StreamCircuitEventType_name[int32(event.EventType)] + if event.EventType == mgmt_pb.StreamCircuitEventType_CircuitDeleted { + fmt.Printf("%v: circuitId: %v\n", eventType, event.CircuitId) + } else if event.EventType == mgmt_pb.StreamCircuitEventType_CircuitCreated { + fmt.Printf("%v: circuitId: %v, clientId: %v, serviceId: %v, path: %v\n", + eventType, event.CircuitId, event.ClientId, event.ServiceId, event.Path.CalculateDisplayPath()) + } else if event.EventType == mgmt_pb.StreamCircuitEventType_PathUpdated { + fmt.Printf("%v: circuitId: %v, path: %v\n", + eventType, event.CircuitId, event.Path.CalculateDisplayPath()) + } +} diff --git a/ziti/cmd/ziti/cmd/fabric/stream_metrics.go b/ziti/cmd/ziti/cmd/fabric/stream_metrics.go new file mode 100644 index 000000000..37658c89b --- /dev/null +++ b/ziti/cmd/ziti/cmd/fabric/stream_metrics.go @@ -0,0 +1,135 @@ +/* + Copyright NetFoundry, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package fabric + +import ( + "fmt" + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/ptypes/timestamp" + "github.com/openziti/channel" + "github.com/openziti/fabric/pb/mgmt_pb" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + "github.com/spf13/cobra" + "sort" + "time" +) + +type streamMetricsAction struct { + api.Options +} + +func NewStreamMetricsCmd(p common.OptionsProvider) *cobra.Command { + action := streamMetricsAction{ + Options: api.Options{ + CommonOptions: p(), + }, + } + + streamMetricsCmd := &cobra.Command{ + Use: "metrics ", + Short: "Stream fabric metrics", + Args: cobra.MaximumNArgs(2), + Run: action.streamMetrics, + } + + action.AddCommonFlags(streamMetricsCmd) + + return streamMetricsCmd +} + +func (self *streamMetricsAction) streamMetrics(_ *cobra.Command, args []string) { + closeNotify := make(chan struct{}) + + bindHandler := func(binding channel.Binding) error { + binding.AddReceiveHandler(int32(mgmt_pb.ContentType_StreamMetricsEventType), self) + binding.AddCloseHandler(channel.CloseHandlerF(func(ch channel.Channel) { + close(closeNotify) + })) + return nil + } + + ch, err := api.NewWsMgmtChannel(channel.BindHandlerF(bindHandler)) + if err != nil { + panic(err) + } + + var matchers []*mgmt_pb.StreamMetricsRequest_MetricMatcher + + if len(args) > 0 { + matcher := &mgmt_pb.StreamMetricsRequest_MetricMatcher{NameRegex: args[0]} + if len(args) > 1 { + matcher.SourceIDRegex = args[1] + } + matchers = append(matchers, matcher) + } + + request := &mgmt_pb.StreamMetricsRequest{Matchers: matchers} + body, err := proto.Marshal(request) + if err != nil { + panic(err) + } + + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_StreamMetricsRequestType), body) + if err = requestMsg.WithTimeout(time.Duration(self.Timeout) * time.Second).SendAndWaitForWire(ch); err != nil { + panic(err) + } + + <-closeNotify +} + +func (self *streamMetricsAction) HandleReceive(msg *channel.Message, ch channel.Channel) { + response := &mgmt_pb.StreamMetricsEvent{} + err := proto.Unmarshal(msg.Body, response) + if err != nil { + panic(err) + } + + fmt.Printf("%v - source(%v)\n", self.format(response.Timestamp), response.SourceId) + fmt.Printf("\tTags: %v\n", response.Tags) + + var keys []string + var outputMap = make(map[string]string) + for name, value := range response.IntMetrics { + outputMap[name] = fmt.Sprintf("%v=%v", name, value) + keys = append(keys, name) + } + + for name, value := range response.FloatMetrics { + outputMap[name] = fmt.Sprintf("%v=%v", name, value) + keys = append(keys, name) + } + + sort.Strings(keys) + + for _, key := range keys { + fmt.Println(outputMap[key]) + } + + for _, bucket := range response.IntervalMetrics { + fmt.Printf("%v: (%v) -> (%v)\n", bucket.Name, self.format(bucket.IntervalStartUTC), self.format(bucket.IntervalEndUTC)) + for name, value := range bucket.Values { + fmt.Printf("\t%v=%v\n", name, value) + } + } + + fmt.Println() +} + +func (self *streamMetricsAction) format(protobufTS *timestamp.Timestamp) string { + return protobufTS.AsTime().Format(time.RFC3339) +} diff --git a/ziti/cmd/ziti/cmd/fabric/stream_toggle_pipe_traces.go b/ziti/cmd/ziti/cmd/fabric/stream_toggle_pipe_traces.go new file mode 100644 index 000000000..8c48d258f --- /dev/null +++ b/ziti/cmd/ziti/cmd/fabric/stream_toggle_pipe_traces.go @@ -0,0 +1,98 @@ +/* + Copyright NetFoundry, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package fabric + +import ( + "fmt" + "github.com/golang/protobuf/proto" + "github.com/openziti/channel" + "github.com/openziti/channel/trace/pb" + "github.com/openziti/fabric/pb/mgmt_pb" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + "github.com/spf13/cobra" + "time" +) + +type streamTogglePipeTracesAction struct { + api.Options +} + +func NewStreamTogglePipeTracesCmd(p common.OptionsProvider) *cobra.Command { + action := streamTogglePipeTracesAction{ + Options: api.Options{ + CommonOptions: p(), + }, + } + + streamTogglePipeTracesCmd := &cobra.Command{ + Use: "pipe [on|off] ", + Short: "Toggle trace data to be generated for applications or specific links", + Example: "pipe on", + Args: cobra.MinimumNArgs(1), + Run: action.togglePipeTraces, + } + + action.AddCommonFlags(streamTogglePipeTracesCmd) + + return streamTogglePipeTracesCmd +} + +func (self *streamTogglePipeTracesAction) togglePipeTraces(_ *cobra.Command, args []string) { + ch, err := api.NewWsMgmtChannel(nil) + if err != nil { + panic(err) + } + + enable := true + + if args[0] == "off" { + enable = false + } else if args[0] != "on" { + fmt.Println("first argument to toggle pipe must be on or off") + return + } + request := &trace_pb.TogglePipeTracesRequest{Enable: enable, Verbosity: trace_pb.TraceToggleVerbosity_ReportAll, AppRegex: ".*", PipeRegex: ".*"} + + if len(args) > 1 { + request.AppRegex = args[1] + } + if len(args) > 2 { + request.PipeRegex = args[2] + } + + if body, err := proto.Marshal(request); err == nil { + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_TogglePipeTracesRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) + if err != nil { + panic(err) + } + if responseMsg.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(responseMsg) + if result.Success { + fmt.Printf("\ntracing enabled successfully\n\n") + fmt.Println(result.Message) + } else { + fmt.Printf("\ntracing enable failured [%s]\n\n", result.Message) + } + } else { + panic(fmt.Errorf("unexpected response type %v", responseMsg.ContentType)) + } + } else { + panic(err) + } +} diff --git a/ziti/cmd/ziti/cmd/fabric/stream_traces.go b/ziti/cmd/ziti/cmd/fabric/stream_traces.go new file mode 100644 index 000000000..0e9eaf90b --- /dev/null +++ b/ziti/cmd/ziti/cmd/fabric/stream_traces.go @@ -0,0 +1,214 @@ +/* + Copyright NetFoundry, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package fabric + +import ( + "encoding/json" + "fmt" + "github.com/golang/protobuf/proto" + "github.com/openziti/channel" + "github.com/openziti/channel/trace/pb" + "github.com/openziti/fabric/pb/ctrl_pb" + "github.com/openziti/fabric/pb/mgmt_pb" + "github.com/openziti/fabric/router/xgress" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + "github.com/spf13/cobra" + "reflect" + "sort" + "time" +) + +type streamTracesAction struct { + api.Options +} + +func NewStreamTracesCmd(p common.OptionsProvider) *cobra.Command { + action := streamTracesAction{ + Options: api.Options{ + CommonOptions: p(), + }, + } + + streamTracesCmd := &cobra.Command{ + Use: "traces [message type}", + Short: "Stream trace data from systems where tracing is enabled", + Run: action.streamTraces, + } + + action.AddCommonFlags(streamTracesCmd) + + return streamTracesCmd +} + +func (self *streamTracesAction) streamTraces(_ *cobra.Command, args []string) { + startIndex := 0 + request := &mgmt_pb.StreamTracesRequest{EnabledFilter: len(args) > 0} + + if request.EnabledFilter { + request.EnabledFilter = true + request.FilterType = mgmt_pb.TraceFilterType_EXCLUDE + if len(args) == 0 || args[0] != "except" { + request.FilterType = mgmt_pb.TraceFilterType_INCLUDE + } else { + startIndex = 1 + } + + for _, filterArg := range args[startIndex:] { + contentType, err := self.getContentType(filterArg) + if err != nil { + panic(err) + } + request.ContentTypes = append(request.ContentTypes, contentType) + } + } + + closeNotify := make(chan struct{}) + + bindHandler := func(binding channel.Binding) error { + binding.AddReceiveHandler(int32(mgmt_pb.ContentType_StreamTracesEventType), self) + binding.AddCloseHandler(channel.CloseHandlerF(func(ch channel.Channel) { + close(closeNotify) + })) + return nil + } + + ch, err := api.NewWsMgmtChannel(channel.BindHandlerF(bindHandler)) + if err != nil { + panic(err) + } + + body, err := proto.Marshal(request) + if err != nil { + panic(err) + } + + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_StreamTracesRequestType), body) + + if err = requestMsg.WithTimeout(5 * time.Second).SendAndWaitForWire(ch); err != nil { + panic(err) + } + + <-closeNotify +} + +func (self *streamTracesAction) getContentType(name string) (int32, error) { + val, ok := mgmt_pb.ContentType_value[name] + if ok { + return val, nil + } + + val, ok = ctrl_pb.ContentType_value[name] + if ok { + return val, nil + } + + val, ok = xgress.ContentTypeValue[name] + if ok { + return val, nil + } + + var types []string + for key := range mgmt_pb.ContentType_value { + types = append(types, key) + } + for key := range ctrl_pb.ContentType_value { + types = append(types, key) + } + for key := range xgress.ContentTypeValue { + types = append(types, key) + } + sort.Strings(types) + fmt.Println("Valid message types:") + for idx, key := range types { + fmt.Printf("%v: %v\n", idx, key) + } + + return 0, fmt.Errorf("unknown message type %v", name) +} + +func (self *streamTracesAction) HandleReceive(msg *channel.Message, _ channel.Channel) { + event := &trace_pb.ChannelMessage{} + err := proto.Unmarshal(msg.Body, event) + if err != nil { + panic(err) + } + + flow := "->" + if event.IsRx { + flow = "<-" + } + replyFor := "" + if event.ReplyFor != -1 { + replyFor = fmt.Sprintf(">%d", event.ReplyFor) + } + meta := self.DecodeTraceAndFormat(event.Decode) + if meta == "" { + meta = fmt.Sprintf("missing decode, content-type=%v", event.ContentType) + } + fmt.Printf("%8d: %-16s %8s %s #%-5d %5s | %s\n", + event.Timestamp, event.Identity, event.Channel, flow, event.Sequence, replyFor, meta) +} + +func (self *streamTracesAction) DecodeTraceAndFormat(decode []byte) string { + if len(decode) > 0 { + meta := make(map[string]interface{}) + err := json.Unmarshal(decode, &meta) + if err != nil { + panic(err) + } + + out := fmt.Sprintf("%-24s", fmt.Sprintf("%-8s %s", meta[channel.DecoderFieldName], meta[channel.MessageFieldName])) + + if len(meta) > 2 { + keys := make([]string, 0) + for k := range meta { + if k != channel.DecoderFieldName && k != channel.MessageFieldName { + keys = append(keys, k) + } + } + sort.Strings(keys) + + out += " {" + for i := 0; i < len(keys); i++ { + k := keys[i] + if i > 0 { + out += " " + } + out += k + out += "=[" + v := meta[k] + switch v.(type) { + case string: + out += v.(string) + case float64: + out += fmt.Sprintf("%0.0f", v.(float64)) + case bool: + out += fmt.Sprintf("%t", v.(bool)) + default: + out += fmt.Sprintf("<%s>", reflect.TypeOf(v)) + } + out += "]" + } + out += "}" + } + + return out + } else { + return "" + } +} diff --git a/ziti/cmd/ziti/cmd/factory/factory.go b/ziti/cmd/ziti/cmd/factory/factory.go deleted file mode 100644 index 1b790df8d..000000000 --- a/ziti/cmd/ziti/cmd/factory/factory.go +++ /dev/null @@ -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 © -} - -func (f *factory) CreateTable(out io.Writer) table.Table { - return table.CreateTable(os.Stdout) -} diff --git a/ziti/cmd/ziti/cmd/init.go b/ziti/cmd/ziti/cmd/init.go index 4a3143433..bb17f1fe4 100644 --- a/ziti/cmd/ziti/cmd/init.go +++ b/ziti/cmd/ziti/cmd/init.go @@ -17,7 +17,6 @@ package cmd import ( - 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" @@ -46,12 +45,11 @@ var ( ) // NewCmdInit creates a command object for the generic "init" action -func NewCmdInit(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdInit(out io.Writer, errOut io.Writer) *cobra.Command { options := &InitOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -68,7 +66,7 @@ func NewCmdInit(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Comma }, } - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) options.addInitFlags(cmd) return cmd diff --git a/ziti/cmd/ziti/cmd/install.go b/ziti/cmd/ziti/cmd/install.go index 33769e9e9..39c0b810c 100644 --- a/ziti/cmd/ziti/cmd/install.go +++ b/ziti/cmd/ziti/cmd/install.go @@ -19,7 +19,6 @@ 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" "github.com/spf13/cobra" @@ -42,12 +41,11 @@ var ( ) // NewCmdInstall creates the command -func NewCmdInstall(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdInstall(out io.Writer, errOut io.Writer) *cobra.Command { options := &InstallOptions{ CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -66,20 +64,20 @@ func NewCmdInstall(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Co SuggestFor: []string{"up"}, } - cmd.AddCommand(NewCmdInstallZitiALL(f, out, errOut)) + cmd.AddCommand(NewCmdInstallZitiALL(out, errOut)) - cmd.AddCommand(NewCmdInstallZitiController(f, out, errOut)) - cmd.AddCommand(NewCmdInstallZitiFabric(f, out, errOut)) - cmd.AddCommand(NewCmdInstallZitiRouter(f, out, errOut)) - cmd.AddCommand(NewCmdInstallZitiTunnel(f, out, errOut)) - cmd.AddCommand(NewCmdInstallZitiEdgeTunnel(f, out, errOut)) - cmd.AddCommand(NewCmdInstallZitiProxC(f, out, errOut)) + cmd.AddCommand(NewCmdInstallZitiController(out, errOut)) + cmd.AddCommand(NewCmdInstallZitiFabric(out, errOut)) + cmd.AddCommand(NewCmdInstallZitiRouter(out, errOut)) + cmd.AddCommand(NewCmdInstallZitiTunnel(out, errOut)) + cmd.AddCommand(NewCmdInstallZitiEdgeTunnel(out, errOut)) + cmd.AddCommand(NewCmdInstallZitiProxC(out, errOut)) - // cmd.AddCommand(NewCmdInstallAnsible(f, out, errOut)) // Disable/hide this for now + // cmd.AddCommand(NewCmdInstallAnsible(out, errOut)) // Disable/hide this for now - cmd.AddCommand(NewCmdInstallTerraformProviderEdgeController(f, out, errOut)) + cmd.AddCommand(NewCmdInstallTerraformProviderEdgeController(out, errOut)) - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/install_ansible.go b/ziti/cmd/ziti/cmd/install_ansible.go index 5ad2a8825..ec976c9e0 100644 --- a/ziti/cmd/ziti/cmd/install_ansible.go +++ b/ziti/cmd/ziti/cmd/install_ansible.go @@ -20,7 +20,6 @@ import ( "io" "github.com/openziti/ziti/ziti/ansible" - 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/spf13/cobra" @@ -50,13 +49,12 @@ type InstallAnsibleOptions struct { var installOptions = &ansible.InstallOptions{} // NewCmdInstallAnsible defines the command -func NewCmdInstallAnsible(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdInstallAnsible(out io.Writer, errOut io.Writer) *cobra.Command { options := &InstallAnsibleOptions{ InstallOptions: InstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } diff --git a/ziti/cmd/ziti/cmd/install_terraform_provider_edge_controller.go b/ziti/cmd/ziti/cmd/install_terraform_provider_edge_controller.go index 62310eacd..8282ca71f 100644 --- a/ziti/cmd/ziti/cmd/install_terraform_provider_edge_controller.go +++ b/ziti/cmd/ziti/cmd/install_terraform_provider_edge_controller.go @@ -19,12 +19,11 @@ package cmd import ( "io" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" + "github.com/blang/semver" 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/blang/semver" "github.com/spf13/cobra" ) @@ -48,13 +47,12 @@ type InstallTerraformProviderEdgeControllerOptions struct { } // NewCmdInstallTerraformProviderEdgeController defines the command -func NewCmdInstallTerraformProviderEdgeController(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdInstallTerraformProviderEdgeController(out io.Writer, errOut io.Writer) *cobra.Command { options := &InstallTerraformProviderEdgeControllerOptions{ InstallOptions: InstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } diff --git a/ziti/cmd/ziti/cmd/install_ziti_ALL.go b/ziti/cmd/ziti/cmd/install_ziti_ALL.go index ac8f12e52..c5bf2ac34 100644 --- a/ziti/cmd/ziti/cmd/install_ziti_ALL.go +++ b/ziti/cmd/ziti/cmd/install_ziti_ALL.go @@ -21,7 +21,6 @@ import ( "github.com/blang/semver" "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" @@ -48,13 +47,12 @@ type InstallZitiALLOptions struct { } // NewCmdInstallZitiALL defines the command -func NewCmdInstallZitiALL(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdInstallZitiALL(out io.Writer, errOut io.Writer) *cobra.Command { options := &InstallZitiALLOptions{ InstallOptions: InstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } @@ -73,7 +71,7 @@ func NewCmdInstallZitiALL(f cmdutil.Factory, out io.Writer, errOut io.Writer) *c }, } cmd.Flags().StringVarP(&options.Version, "version", "v", "", "The specific version to install") - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/install_ziti_controller.go b/ziti/cmd/ziti/cmd/install_ziti_controller.go index 72097a1b2..4bd28fd36 100644 --- a/ziti/cmd/ziti/cmd/install_ziti_controller.go +++ b/ziti/cmd/ziti/cmd/install_ziti_controller.go @@ -19,13 +19,12 @@ package cmd import ( "io" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" + "github.com/blang/semver" + "github.com/openziti/ziti/common/version" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/templates" c "github.com/openziti/ziti/ziti/cmd/ziti/constants" "github.com/openziti/ziti/ziti/cmd/ziti/internal/log" - "github.com/openziti/ziti/common/version" - "github.com/blang/semver" "github.com/spf13/cobra" ) @@ -48,13 +47,12 @@ type InstallZitiControllerOptions struct { } // NewCmdInstallZitiController defines the command -func NewCmdInstallZitiController(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdInstallZitiController(out io.Writer, errOut io.Writer) *cobra.Command { options := &InstallZitiControllerOptions{ InstallOptions: InstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } @@ -73,7 +71,7 @@ func NewCmdInstallZitiController(f cmdutil.Factory, out io.Writer, errOut io.Wri }, } cmd.Flags().StringVarP(&options.Version, "version", "v", "", "The specific version to install") - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/install_ziti_edge_tunnel.go b/ziti/cmd/ziti/cmd/install_ziti_edge_tunnel.go index e5eac248d..682771e28 100644 --- a/ziti/cmd/ziti/cmd/install_ziti_edge_tunnel.go +++ b/ziti/cmd/ziti/cmd/install_ziti_edge_tunnel.go @@ -21,7 +21,6 @@ import ( "github.com/blang/semver" "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" @@ -48,13 +47,12 @@ type InstallZitiEdgeTunnelOptions struct { } // NewCmdInstallZitiEdgeTunnel defines the command -func NewCmdInstallZitiEdgeTunnel(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdInstallZitiEdgeTunnel(out io.Writer, errOut io.Writer) *cobra.Command { options := &InstallZitiEdgeTunnelOptions{ InstallOptions: InstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } @@ -73,7 +71,7 @@ func NewCmdInstallZitiEdgeTunnel(f cmdutil.Factory, out io.Writer, errOut io.Wri }, } cmd.Flags().StringVarP(&options.Version, "version", "v", "", "The specific version to install") - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/install_ziti_fabric.go b/ziti/cmd/ziti/cmd/install_ziti_fabric.go index 480351c32..9831fb01c 100644 --- a/ziti/cmd/ziti/cmd/install_ziti_fabric.go +++ b/ziti/cmd/ziti/cmd/install_ziti_fabric.go @@ -19,13 +19,12 @@ package cmd import ( "io" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" + "github.com/blang/semver" + "github.com/openziti/ziti/common/version" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/templates" c "github.com/openziti/ziti/ziti/cmd/ziti/constants" "github.com/openziti/ziti/ziti/cmd/ziti/internal/log" - "github.com/openziti/ziti/common/version" - "github.com/blang/semver" "github.com/spf13/cobra" ) @@ -48,13 +47,12 @@ type InstallZitiFabricOptions struct { } // NewCmdInstallZitiFabric defines the command -func NewCmdInstallZitiFabric(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdInstallZitiFabric(out io.Writer, errOut io.Writer) *cobra.Command { options := &InstallZitiFabricOptions{ InstallOptions: InstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } @@ -73,7 +71,7 @@ func NewCmdInstallZitiFabric(f cmdutil.Factory, out io.Writer, errOut io.Writer) }, } cmd.Flags().StringVarP(&options.Version, "version", "v", "", "The specific version to install") - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/install_ziti_prox_c.go b/ziti/cmd/ziti/cmd/install_ziti_prox_c.go index 3df9bb3ef..ec3e593f8 100644 --- a/ziti/cmd/ziti/cmd/install_ziti_prox_c.go +++ b/ziti/cmd/ziti/cmd/install_ziti_prox_c.go @@ -21,7 +21,6 @@ import ( "github.com/blang/semver" "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" @@ -48,13 +47,12 @@ type InstallZitiProxCOptions struct { } // NewCmdInstallZitiProxC defines the command -func NewCmdInstallZitiProxC(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdInstallZitiProxC(out io.Writer, errOut io.Writer) *cobra.Command { options := &InstallZitiProxCOptions{ InstallOptions: InstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } @@ -73,7 +71,7 @@ func NewCmdInstallZitiProxC(f cmdutil.Factory, out io.Writer, errOut io.Writer) }, } cmd.Flags().StringVarP(&options.Version, "version", "v", "", "The specific version to install") - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/install_ziti_router.go b/ziti/cmd/ziti/cmd/install_ziti_router.go index 39f15a26a..a54a6d3ee 100644 --- a/ziti/cmd/ziti/cmd/install_ziti_router.go +++ b/ziti/cmd/ziti/cmd/install_ziti_router.go @@ -19,13 +19,12 @@ package cmd import ( "io" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" + "github.com/blang/semver" + "github.com/openziti/ziti/common/version" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/templates" c "github.com/openziti/ziti/ziti/cmd/ziti/constants" "github.com/openziti/ziti/ziti/cmd/ziti/internal/log" - "github.com/openziti/ziti/common/version" - "github.com/blang/semver" "github.com/spf13/cobra" ) @@ -48,13 +47,12 @@ type InstallZitiRouterOptions struct { } // NewCmdInstallZitiRouter defines the command -func NewCmdInstallZitiRouter(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdInstallZitiRouter(out io.Writer, errOut io.Writer) *cobra.Command { options := &InstallZitiRouterOptions{ InstallOptions: InstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } @@ -73,7 +71,7 @@ func NewCmdInstallZitiRouter(f cmdutil.Factory, out io.Writer, errOut io.Writer) }, } cmd.Flags().StringVarP(&options.Version, "version", "v", "", "The specific version to install") - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/install_ziti_tunnel.go b/ziti/cmd/ziti/cmd/install_ziti_tunnel.go index 7098dbf2e..0509a3635 100644 --- a/ziti/cmd/ziti/cmd/install_ziti_tunnel.go +++ b/ziti/cmd/ziti/cmd/install_ziti_tunnel.go @@ -19,13 +19,12 @@ package cmd import ( "io" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" + "github.com/blang/semver" + "github.com/openziti/ziti/common/version" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/templates" c "github.com/openziti/ziti/ziti/cmd/ziti/constants" "github.com/openziti/ziti/ziti/cmd/ziti/internal/log" - "github.com/openziti/ziti/common/version" - "github.com/blang/semver" "github.com/spf13/cobra" ) @@ -48,13 +47,12 @@ type InstallZitiTunnelOptions struct { } // NewCmdInstallZitiTunnel defines the command -func NewCmdInstallZitiTunnel(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdInstallZitiTunnel(out io.Writer, errOut io.Writer) *cobra.Command { options := &InstallZitiTunnelOptions{ InstallOptions: InstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } @@ -73,7 +71,7 @@ func NewCmdInstallZitiTunnel(f cmdutil.Factory, out io.Writer, errOut io.Writer) }, } cmd.Flags().StringVarP(&options.Version, "version", "v", "", "The specific version to install") - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/lets_encrypt/create.go b/ziti/cmd/ziti/cmd/lets_encrypt/create.go index 7ac4b83a6..ba1c9c9c0 100644 --- a/ziti/cmd/ziti/cmd/lets_encrypt/create.go +++ b/ziti/cmd/ziti/cmd/lets_encrypt/create.go @@ -21,7 +21,6 @@ import ( "github.com/go-acme/lego/v4/certificate" "github.com/go-acme/lego/v4/lego" "github.com/go-acme/lego/v4/registration" - 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/internal/log" "github.com/spf13/cobra" @@ -51,7 +50,7 @@ func (u *AcmeUser) GetPrivateKey() crypto.PrivateKey { } // newCreateCmd creates the 'edge controller create ca local' command for the given entity type -func newCreateCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newCreateCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &leOptions{} cmd := &cobra.Command{ diff --git a/ziti/cmd/ziti/cmd/lets_encrypt/list.go b/ziti/cmd/ziti/cmd/lets_encrypt/list.go index 75d9ac2c4..9db17f5ad 100644 --- a/ziti/cmd/ziti/cmd/lets_encrypt/list.go +++ b/ziti/cmd/ziti/cmd/lets_encrypt/list.go @@ -26,13 +26,12 @@ import ( "strings" "github.com/go-acme/lego/v4/certcrypto" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" ) // 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 { options := &leOptions{} cmd := &cobra.Command{ diff --git a/ziti/cmd/ziti/cmd/lets_encrypt/renew.go b/ziti/cmd/ziti/cmd/lets_encrypt/renew.go index e069dbaac..83b470d43 100644 --- a/ziti/cmd/ziti/cmd/lets_encrypt/renew.go +++ b/ziti/cmd/ziti/cmd/lets_encrypt/renew.go @@ -22,7 +22,6 @@ import ( "github.com/go-acme/lego/v4/certcrypto" "github.com/go-acme/lego/v4/certificate" "github.com/go-acme/lego/v4/lego" - 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/internal/log" "github.com/spf13/cobra" @@ -38,7 +37,7 @@ const ( ) // newListCmd creates a command object for the "controller list" command -func newRenewCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newRenewCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &leOptions{} cmd := &cobra.Command{ diff --git a/ziti/cmd/ziti/cmd/lets_encrypt/revoke.go b/ziti/cmd/ziti/cmd/lets_encrypt/revoke.go index 8be0d9fe4..588377a78 100644 --- a/ziti/cmd/ziti/cmd/lets_encrypt/revoke.go +++ b/ziti/cmd/ziti/cmd/lets_encrypt/revoke.go @@ -20,13 +20,12 @@ import ( "github.com/openziti/ziti/ziti/cmd/ziti/internal/log" "io" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" "github.com/spf13/cobra" ) // newListCmd creates a command object for the "controller list" command -func newRevokeCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func newRevokeCmd(out io.Writer, errOut io.Writer) *cobra.Command { options := &leOptions{} cmd := &cobra.Command{ diff --git a/ziti/cmd/ziti/cmd/lets_encrypt/root.go b/ziti/cmd/ziti/cmd/lets_encrypt/root.go index 71658b03b..fd51e911a 100644 --- a/ziti/cmd/ziti/cmd/lets_encrypt/root.go +++ b/ziti/cmd/ziti/cmd/lets_encrypt/root.go @@ -19,15 +19,14 @@ package lets_encrypt import ( "io" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" "github.com/openziti/ziti/ziti/cmd/ziti/util" "github.com/spf13/cobra" ) // NewCmdLE creates a command object for the "le" sub-command of the "pki" cmd -func NewCmdLE(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdLE(out io.Writer, errOut io.Writer) *cobra.Command { cmd := util.NewEmptyParentCmd("le", "Interact with Let's Encrypt infra") - populateLECommands(f, out, errOut, cmd) + populateLECommands(out, errOut, cmd) return cmd } @@ -58,11 +57,10 @@ type leOptions struct { // type leFlags struct { // } -func populateLECommands(f cmdutil.Factory, out io.Writer, errOut io.Writer, cmd *cobra.Command) *cobra.Command { - - cmd.AddCommand(newCreateCmd(f, out, errOut)) - cmd.AddCommand(newRevokeCmd(f, out, errOut)) - cmd.AddCommand(newRenewCmd(f, out, errOut)) - cmd.AddCommand(newListCmd(f, out, errOut)) +func populateLECommands(out io.Writer, errOut io.Writer, cmd *cobra.Command) *cobra.Command { + cmd.AddCommand(newCreateCmd(out, errOut)) + cmd.AddCommand(newRevokeCmd(out, errOut)) + cmd.AddCommand(newRenewCmd(out, errOut)) + cmd.AddCommand(newListCmd(out, errOut)) return cmd } diff --git a/ziti/cmd/ziti/cmd/log_filter.go b/ziti/cmd/ziti/cmd/log_filter.go index 517b8124b..59457b8f0 100644 --- a/ziti/cmd/ziti/cmd/log_filter.go +++ b/ziti/cmd/ziti/cmd/log_filter.go @@ -18,14 +18,13 @@ package cmd import ( "github.com/michaelquigley/pfxlog" - 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" "os" ) -// PsOptions contains the command line options +// AgentOptions contains the command line options type LogFormatOptions struct { CommonOptions @@ -34,12 +33,11 @@ type LogFormatOptions struct { } // NewCmdLogFormat a command object for the "log-format" command -func NewCmdLogFormat(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdLogFormat(out io.Writer, errOut io.Writer) *cobra.Command { options := &LogFormatOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } diff --git a/ziti/cmd/ziti/cmd/ping.go b/ziti/cmd/ziti/cmd/ping.go index 756da9ca9..4bb17d9cb 100644 --- a/ziti/cmd/ziti/cmd/ping.go +++ b/ziti/cmd/ziti/cmd/ping.go @@ -24,7 +24,6 @@ import ( "path/filepath" "github.com/openziti/ziti/ziti/ansible" - 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/spf13/cobra" @@ -38,12 +37,11 @@ type PingOptions struct { var pingOptions = &ansible.Options{} // NewCmdPing creates the command -func NewCmdPing(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdPing(out io.Writer, errOut io.Writer) *cobra.Command { options := &PingOptions{ CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } diff --git a/ziti/cmd/ziti/cmd/pki.go b/ziti/cmd/ziti/cmd/pki.go index 83c928515..27c8f023c 100644 --- a/ziti/cmd/ziti/cmd/pki.go +++ b/ziti/cmd/ziti/cmd/pki.go @@ -20,7 +20,6 @@ import ( "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/lets_encrypt" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/templates" @@ -70,12 +69,11 @@ Provide the components needed to manage a Ziti PKI. ) // NewCmdPKI PKIs a command object for the "PKI" command -func NewCmdPKI(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdPKI(out io.Writer, errOut io.Writer) *cobra.Command { options := &PKIOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -91,9 +89,9 @@ func NewCmdPKI(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Comman }, } - cmd.AddCommand(NewCmdPKICreate(f, out, errOut)) + cmd.AddCommand(NewCmdPKICreate(out, errOut)) - cmd.AddCommand(lets_encrypt.NewCmdLE(f, out, errOut)) + cmd.AddCommand(lets_encrypt.NewCmdLE(out, errOut)) return cmd } diff --git a/ziti/cmd/ziti/cmd/pki_create.go b/ziti/cmd/ziti/cmd/pki_create.go index 110a166dd..43a93df28 100644 --- a/ziti/cmd/ziti/cmd/pki_create.go +++ b/ziti/cmd/ziti/cmd/pki_create.go @@ -29,7 +29,6 @@ import ( "strings" "time" - 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/viper" @@ -41,13 +40,12 @@ type PKICreateOptions struct { } // NewCmdPKICreate creates a command object for the "create" command -func NewCmdPKICreate(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdPKICreate(out io.Writer, errOut io.Writer) *cobra.Command { options := &PKICreateOptions{ PKIOptions: PKIOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } @@ -62,12 +60,12 @@ func NewCmdPKICreate(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra. }, } - cmd.AddCommand(NewCmdPKICreateCA(f, out, errOut)) - cmd.AddCommand(NewCmdPKICreateIntermediate(f, out, errOut)) - cmd.AddCommand(NewCmdPKICreateKey(f, out, errOut)) - cmd.AddCommand(NewCmdPKICreateServer(f, out, errOut)) - cmd.AddCommand(NewCmdPKICreateClient(f, out, errOut)) - cmd.AddCommand(NewCmdPKICreateCSR(f, out, errOut)) + cmd.AddCommand(NewCmdPKICreateCA(out, errOut)) + cmd.AddCommand(NewCmdPKICreateIntermediate(out, errOut)) + cmd.AddCommand(NewCmdPKICreateKey(out, errOut)) + cmd.AddCommand(NewCmdPKICreateServer(out, errOut)) + cmd.AddCommand(NewCmdPKICreateClient(out, errOut)) + cmd.AddCommand(NewCmdPKICreateCSR(out, errOut)) options.addPKICreateFlags(cmd) return cmd diff --git a/ziti/cmd/ziti/cmd/pki_create_ca.go b/ziti/cmd/ziti/cmd/pki_create_ca.go index 5a5b29b98..a91991627 100644 --- a/ziti/cmd/ziti/cmd/pki_create_ca.go +++ b/ziti/cmd/ziti/cmd/pki_create_ca.go @@ -21,7 +21,6 @@ import ( "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/internal/log" "github.com/openziti/ziti/ziti/pki/certificate" @@ -35,14 +34,13 @@ type PKICreateCAOptions struct { } // NewCmdPKICreateCA creates a command object for the "create" command -func NewCmdPKICreateCA(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdPKICreateCA(out io.Writer, errOut io.Writer) *cobra.Command { options := &PKICreateCAOptions{ PKICreateOptions: PKICreateOptions{ PKIOptions: PKIOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, }, diff --git a/ziti/cmd/ziti/cmd/pki_create_client.go b/ziti/cmd/ziti/cmd/pki_create_client.go index 521f53217..8b47cf8b4 100644 --- a/ziti/cmd/ziti/cmd/pki_create_client.go +++ b/ziti/cmd/ziti/cmd/pki_create_client.go @@ -21,7 +21,6 @@ import ( "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/internal/log" "github.com/openziti/ziti/ziti/pki/certificate" @@ -35,14 +34,13 @@ type PKICreateClientOptions struct { } // NewCmdPKICreateClient creates a command object for the "create" command -func NewCmdPKICreateClient(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdPKICreateClient(out io.Writer, errOut io.Writer) *cobra.Command { options := &PKICreateClientOptions{ PKICreateOptions: PKICreateOptions{ PKIOptions: PKIOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, }, diff --git a/ziti/cmd/ziti/cmd/pki_create_csr.go b/ziti/cmd/ziti/cmd/pki_create_csr.go index fe2b2677f..e8c68412a 100644 --- a/ziti/cmd/ziti/cmd/pki_create_csr.go +++ b/ziti/cmd/ziti/cmd/pki_create_csr.go @@ -21,7 +21,6 @@ import ( "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/internal/log" "github.com/openziti/ziti/ziti/pki/pki" @@ -34,14 +33,13 @@ type PKICreateCSROptions struct { } // NewCmdPKICreateCSR creates a command object for the "create" command -func NewCmdPKICreateCSR(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdPKICreateCSR(out io.Writer, errOut io.Writer) *cobra.Command { options := &PKICreateCSROptions{ PKICreateOptions: PKICreateOptions{ PKIOptions: PKIOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, }, diff --git a/ziti/cmd/ziti/cmd/pki_create_intermediate.go b/ziti/cmd/ziti/cmd/pki_create_intermediate.go index 6fec50c7d..4b64c1fcb 100644 --- a/ziti/cmd/ziti/cmd/pki_create_intermediate.go +++ b/ziti/cmd/ziti/cmd/pki_create_intermediate.go @@ -21,7 +21,6 @@ import ( "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/internal/log" "github.com/openziti/ziti/ziti/pki/certificate" @@ -35,14 +34,13 @@ type PKICreateIntermediateOptions struct { } // NewCmdPKICreateIntermediate creates a command object for the "create" command -func NewCmdPKICreateIntermediate(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdPKICreateIntermediate(out io.Writer, errOut io.Writer) *cobra.Command { options := &PKICreateIntermediateOptions{ PKICreateOptions: PKICreateOptions{ PKIOptions: PKIOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, }, diff --git a/ziti/cmd/ziti/cmd/pki_create_key.go b/ziti/cmd/ziti/cmd/pki_create_key.go index a895847c2..90e5a1522 100644 --- a/ziti/cmd/ziti/cmd/pki_create_key.go +++ b/ziti/cmd/ziti/cmd/pki_create_key.go @@ -21,7 +21,6 @@ import ( "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/internal/log" "github.com/openziti/ziti/ziti/pki/certificate" @@ -35,14 +34,13 @@ type PKICreateKeyOptions struct { } // NewCmdPKICreateKey creates a command object for the "create" command -func NewCmdPKICreateKey(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdPKICreateKey(out io.Writer, errOut io.Writer) *cobra.Command { options := &PKICreateKeyOptions{ PKICreateOptions: PKICreateOptions{ PKIOptions: PKIOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, }, diff --git a/ziti/cmd/ziti/cmd/pki_create_server.go b/ziti/cmd/ziti/cmd/pki_create_server.go index 1258acb7d..879f18ca1 100644 --- a/ziti/cmd/ziti/cmd/pki_create_server.go +++ b/ziti/cmd/ziti/cmd/pki_create_server.go @@ -21,7 +21,6 @@ import ( "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/internal/log" "github.com/openziti/ziti/ziti/pki/certificate" @@ -35,14 +34,13 @@ type PKICreateServerOptions struct { } // NewCmdPKICreateServer creates a command object for the "create" command -func NewCmdPKICreateServer(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdPKICreateServer(out io.Writer, errOut io.Writer) *cobra.Command { options := &PKICreateServerOptions{ PKICreateOptions: PKICreateOptions{ PKIOptions: PKIOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, }, diff --git a/ziti/cmd/ziti/cmd/playbook.go b/ziti/cmd/ziti/cmd/playbook.go index ea70e5c62..3e7b4d3d2 100644 --- a/ziti/cmd/ziti/cmd/playbook.go +++ b/ziti/cmd/ziti/cmd/playbook.go @@ -21,7 +21,6 @@ import ( "io" "github.com/openziti/ziti/ziti/ansible" - 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/provisioner" @@ -40,12 +39,11 @@ type PlaybookOptions struct { var playbookOptions = &ansible.Options{} var po = &provisioner.Options{} -func NewCmdPlaybook(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdPlaybook(out io.Writer, errOut io.Writer) *cobra.Command { options := &PlaybookOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -111,7 +109,7 @@ the user "root" and run in verbose mode, do this: cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) cmd.Flags().StringVarP(&playbookOptions.SSHConfigFile, "ssh-config-file", "s", "", "Path to ssh config file to use.") diff --git a/ziti/cmd/ziti/cmd/ps.go b/ziti/cmd/ziti/cmd/ps.go index f4a75a29a..4367d8ebe 100644 --- a/ziti/cmd/ziti/cmd/ps.go +++ b/ziti/cmd/ziti/cmd/ps.go @@ -19,75 +19,61 @@ package cmd import ( "bytes" "fmt" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/agentcli" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" "github.com/spf13/cobra" - "io" "os" "regexp" "strconv" "strings" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" - "github.com/openziti/ziti/ziti/cmd/ziti/cmd/templates" "github.com/openziti/ziti/ziti/goprocess" ) -// PsOptions contains the command line options -type PsOptions struct { - CommonOptions - - Flags PsFlags +type PsAction struct { + agentcli.AgentOptions } -type PsFlags struct { - Pid string -} - -var ( - psLong = templates.LongDesc(` - Show information about currently running Ziti preocesses. - `) -) - // NewCmdPs Pss a command object for the "Ps" command -func NewCmdPs(out io.Writer, errOut io.Writer) *cobra.Command { - options := &PsOptions{ - CommonOptions: CommonOptions{ - Out: out, - Err: errOut, +func NewCmdPs(p common.OptionsProvider) *cobra.Command { + action := &PsAction{ + AgentOptions: agentcli.AgentOptions{ + CommonOptions: p(), }, } cmd := &cobra.Command{ Use: "ps", Short: "Show Ziti process info", - Long: psLong, + Long: "Show information about currently running Ziti preocesses", Run: func(cmd *cobra.Command, args []string) { - options.Cmd = cmd - options.Args = args - err := options.Run() + action.Cmd = cmd + action.Args = args + err := action.Run() cmdhelper.CheckErr(err) }, } - cmd.AddCommand(NewCmdPsGet(out, errOut)) - cmd.AddCommand(NewCmdPsGoversion(out, errOut)) - cmd.AddCommand(NewCmdPsGc(out, errOut)) - cmd.AddCommand(NewCmdPsSetgc(out, errOut)) - cmd.AddCommand(NewCmdPsStack(out, errOut)) - cmd.AddCommand(NewCmdPsMemstats(out, errOut)) - cmd.AddCommand(NewCmdPsStats(out, errOut)) - cmd.AddCommand(NewCmdPsPprofHeap(out, errOut)) - cmd.AddCommand(NewCmdPsPprofCpu(out, errOut)) - cmd.AddCommand(NewCmdPsTrace(out, errOut)) - cmd.AddCommand(NewCmdPsSetLogLevel(out, errOut)) - cmd.AddCommand(NewCmdPsSetChannelLogLevel(out, errOut)) - cmd.AddCommand(NewCmdPsClearChannelLogLevel(out, errOut)) + cmd.AddCommand(agentcli.NewGetCmd(p)) + cmd.AddCommand(agentcli.NewGoVersionCmd(p)) + cmd.AddCommand(agentcli.NewGcCmd(p)) + cmd.AddCommand(agentcli.NewSetGcCmd(p)) + cmd.AddCommand(agentcli.NewStackCmd(p)) + cmd.AddCommand(agentcli.NewMemstatsCmd(p)) + cmd.AddCommand(agentcli.NewStatsCmd(p)) + cmd.AddCommand(agentcli.NewPprofHeapCmd(p)) + cmd.AddCommand(agentcli.NewPprofCpuCmd(p)) + cmd.AddCommand(agentcli.NewTraceCmd(p)) + cmd.AddCommand(agentcli.NewSetLogLevelCmd(p)) + cmd.AddCommand(agentcli.NewSetChannelLogLevelCmd(p)) + cmd.AddCommand(agentcli.NewClearChannelLogLevelCmd(p)) return cmd } // Run implements this command -func (o *PsOptions) Run() error { +func (self *PsAction) Run() error { fmt.Println("ps is running") ps := goprocess.FindAll() diff --git a/ziti/cmd/ziti/cmd/tutorial/actions/keep_session_alive.go b/ziti/cmd/ziti/cmd/tutorial/actions/keep_session_alive.go new file mode 100644 index 000000000..149fddfa9 --- /dev/null +++ b/ziti/cmd/ziti/cmd/tutorial/actions/keep_session_alive.go @@ -0,0 +1,52 @@ +/* + 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 actions + +import ( + "fmt" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/edge" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "net/url" + "strings" + "time" +) + +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 + } + } + if !strings.EqualFold("true", ctx.Headers["quiet"]) { + fmt.Printf("Running session refresh every %v\n", interval) + } + go func() { + ticker := time.NewTicker(interval) + for { + select { + case <-ticker.C: + _, _, _ = edge.ListEntitiesOfType("edge-routers", url.Values{}, false, nil, 10, false) + } + } + }() + return nil +} diff --git a/ziti/cmd/ziti/cmd/tutorial/actions/select_edge_router.go b/ziti/cmd/ziti/cmd/tutorial/actions/select_edge_router.go new file mode 100644 index 000000000..35ea88345 --- /dev/null +++ b/ziti/cmd/ziti/cmd/tutorial/actions/select_edge_router.go @@ -0,0 +1,138 @@ +/* + 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 actions + +import ( + "fmt" + "github.com/openziti/foundation/util/term" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/edge" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "github.com/pkg/errors" + "strconv" + "strings" +) + +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 := edge.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 +} diff --git a/ziti/cmd/ziti/cmd/tutorial/actions/ziti_create_config.go b/ziti/cmd/ziti/cmd/tutorial/actions/ziti_create_config.go new file mode 100644 index 000000000..eb6bfdba8 --- /dev/null +++ b/ziti/cmd/ziti/cmd/tutorial/actions/ziti_create_config.go @@ -0,0 +1,94 @@ +/* + 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 actions + +import ( + "fmt" + "github.com/fatih/color" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "github.com/pkg/errors" + "os" + "strings" +) + +// TODO: make this code more DRY +type ZitiCreateConfigAction struct{} + +func (self *ZitiCreateConfigAction) 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 + } + name := ctx.Headers["name"] + configType := ctx.Headers["type"] + + buf := &strings.Builder{} + buf.WriteString("About to execute:\n\n") + + line := fmt.Sprintf("ziti edge create config %v %v '%v'", name, configType, ctx.Body) + 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 + 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"]) + _, _ = c.Printf("$ %v\n", line) + done := false + for !done { + if err := tutorial.Exec(os.Args[0], colorStdOut, "edge", "create", "config", name, configType, ctx.Body); 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 +} diff --git a/ziti/cmd/ziti/cmd/tutorial/actions/ziti_ensure_logged_in.go b/ziti/cmd/ziti/cmd/tutorial/actions/ziti_ensure_logged_in.go new file mode 100644 index 000000000..6798378c1 --- /dev/null +++ b/ziti/cmd/ziti/cmd/tutorial/actions/ziti_ensure_logged_in.go @@ -0,0 +1,38 @@ +/* + 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 actions + +import ( + "fmt" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/edge" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "net/url" +) + +type ZitiEnsureLoggedIn struct { + LoginParams LoginParams +} + +func (self *ZitiEnsureLoggedIn) Execute(ctx *tutorial.ActionContext) error { + _, _, err := edge.ListEntitiesOfType("edge-routers", url.Values{}, false, nil, 10, false) + if err == nil { + fmt.Println("Already authenticated to Ziti Controller") + return nil + } + loginAction := &ZitiLoginAction{LoginParams: self.LoginParams} + return loginAction.Execute(ctx) +} diff --git a/ziti/cmd/ziti/cmd/tutorial/actions/ziti_for_each.go b/ziti/cmd/ziti/cmd/tutorial/actions/ziti_for_each.go new file mode 100644 index 000000000..82c75dfd8 --- /dev/null +++ b/ziti/cmd/ziti/cmd/tutorial/actions/ziti_for_each.go @@ -0,0 +1,100 @@ +/* + 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 actions + +import ( + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "github.com/openziti/ziti/ziti/cmd/ziti/util" + "github.com/pkg/errors" + "net/url" + "os" + "strconv" +) + +type ZitiForEach struct{} + +func (self *ZitiForEach) Execute(ctx *tutorial.ActionContext) error { + ctx.Headers["templatize"] = "true" + apiType, found := ctx.Headers["api"] + if !found { + apiType = string(util.EdgeAPI) + } + entityType := ctx.Headers["type"] + + params := url.Values{} + filter, found := ctx.Headers["filter"] + if found { + params.Add("filter", filter) + } + + minCount := 1 + if count, found := ctx.Headers["minCount"]; found { + val, err := strconv.Atoi(count) + if err != nil { + return errors.Wrapf(err, "couldn't parse minCount, invalid value '%v'", count) + } + if val < 0 { + return errors.Wrapf(err, "invalid minCount, invalid value '%v', must >= 0", count) + } + minCount = val + } + + maxCount := 1 + if count, found := ctx.Headers["maxCount"]; found { + val, err := strconv.Atoi(count) + if err != nil { + return errors.Wrapf(err, "couldn't parse maxCount, invalid value '%v'", count) + } + if val < minCount { + return errors.Wrapf(err, "invalid maxCount '%v', must >= minCount of %v", count, minCount) + } + maxCount = val + } + + entities, _, err := api.ListEntitiesOfType(util.API(apiType), entityType, params, false, os.Stdout, 1, false) + if err != nil { + return err + } + + if len(entities) < minCount { + return errors.Errorf("expected at least %v %v, only found %v", minCount, entityType, len(entities)) + } + + if len(entities) > maxCount { + return errors.Errorf("expected at most %v %v, only found %v", maxCount, entityType, len(entities)) + } + + runner := ZitiRunnerAction{} + originalBody := ctx.Body + for _, entity := range entities { + wrapper := api.Wrap(entity) + id := wrapper.String("id") + name := wrapper.String("name") + + ctx.Runner.AddVariable("entityId", id) + ctx.Runner.AddVariable("entityName", name) + if err := runner.Execute(ctx); err != nil { + return err + } + ctx.Runner.ClearVariable("entityId") + ctx.Runner.ClearVariable("entityName") + ctx.Body = originalBody + } + + return nil +} diff --git a/ziti/cmd/ziti/cmd/tutorial/actions/ziti_login.go b/ziti/cmd/ziti/cmd/tutorial/actions/ziti_login.go new file mode 100644 index 000000000..c4a4c00af --- /dev/null +++ b/ziti/cmd/ziti/cmd/tutorial/actions/ziti_login.go @@ -0,0 +1,44 @@ +/* + 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 actions + +import "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + +type LoginParams interface { + GetControllerUrl() string + GetUsername() string + GetPassword() string +} + +type ZitiLoginAction struct { + LoginParams LoginParams +} + +func (self *ZitiLoginAction) Execute(ctx *tutorial.ActionContext) error { + cmd := "ziti edge login --ignore-config" + if self.LoginParams.GetControllerUrl() != "" { + cmd += " " + self.LoginParams.GetControllerUrl() + } + if self.LoginParams.GetUsername() != "" { + cmd += " --username " + self.LoginParams.GetUsername() + } + if self.LoginParams.GetPassword() != "" { + cmd += " --password " + self.LoginParams.GetPassword() + } + ctx.Body = cmd + return (&ZitiRunnerAction{}).Execute(ctx) +} diff --git a/ziti/cmd/ziti/cmd/tutorial/actions/ziti_runner.go b/ziti/cmd/ziti/cmd/tutorial/actions/ziti_runner.go new file mode 100644 index 000000000..51826beb7 --- /dev/null +++ b/ziti/cmd/ziti/cmd/tutorial/actions/ziti_runner.go @@ -0,0 +1,99 @@ +/* + 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 actions + +import ( + "fmt" + "github.com/fatih/color" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "github.com/pkg/errors" + "os" + "strings" +) + +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 +} diff --git a/ziti/cmd/ziti/cmd/tutorial/actions/ziti_update_config.go b/ziti/cmd/ziti/cmd/tutorial/actions/ziti_update_config.go new file mode 100644 index 000000000..6e8d2bac2 --- /dev/null +++ b/ziti/cmd/ziti/cmd/tutorial/actions/ziti_update_config.go @@ -0,0 +1,92 @@ +/* + 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 actions + +import ( + "fmt" + "github.com/fatih/color" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "github.com/pkg/errors" + "os" + "strings" +) + +type ZitiUpdateConfigAction struct{} + +func (self *ZitiUpdateConfigAction) 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 + } + name := ctx.Headers["name"] + + buf := &strings.Builder{} + buf.WriteString("About to execute:\n\n") + + line := fmt.Sprintf("ziti edge update config %v --data '%v'", name, ctx.Body) + 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 + 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"]) + _, _ = c.Printf("$ %v\n", line) + done := false + for !done { + if err := tutorial.Exec(os.Args[0], colorStdOut, "edge", "update", "config", name, "--data", ctx.Body); 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 +} diff --git a/ziti/cmd/ziti/cmd/tutorial/first-service-tutorial.go b/ziti/cmd/ziti/cmd/tutorial/first-service-tutorial.go new file mode 100644 index 000000000..e3c8f3e7f --- /dev/null +++ b/ziti/cmd/ziti/cmd/tutorial/first-service-tutorial.go @@ -0,0 +1,181 @@ +/* + 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 tutorial + +import ( + _ "embed" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/api" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/tutorial/actions" + "github.com/openziti/ziti/ziti/cmd/ziti/tutorial" + "github.com/sirupsen/logrus" + "github.com/spf13/cobra" + "time" +) + +//go:embed tutorials/first-service.md +var firstServiceTutorialSource []byte + +//go:embed plain_echo_server.go +var plainEchoServerSource string + +//go:embed plain_echo_client.go +var plainEchoClientSource string + +//go:embed ziti_echo_client.go +var zitiEchoClientSource string + +//go:embed ziti_echo_server.go +var zitiEchoServerSource string + +type firstServiceTutorialOptions struct { + api.Options + TutorialOptions +} + +func newFirstServiceTutorialCmd(p common.OptionsProvider) *cobra.Command { + options := &firstServiceTutorialOptions{ + Options: api.Options{ + 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", &actions.ZitiRunnerAction{}) + t.RegisterActionHandler("ziti-login", &actions.ZitiLoginAction{ + LoginParams: &self.TutorialOptions, + }) + t.RegisterActionHandler("keep-session-alive", &actions.KeepSessionAliveAction{}) + t.RegisterActionHandler("select-edge-router", &actions.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("echo_server_plain.go", plainEchoServerSource) + showActionHandler.Add("plain_echo_client.go", plainEchoClientSource) + showActionHandler.Add("echo_client_ziti.go", zitiEchoClientSource) + showActionHandler.Add("echo_server_ziti.go", zitiEchoServerSource) + t.RegisterActionHandler("show", showActionHandler) + + return t.Run(firstServiceTutorialSource) +} + +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 +} diff --git a/ziti/cmd/ziti/cmd/tutorial/plain_echo_client.go b/ziti/cmd/ziti/cmd/tutorial/plain_echo_client.go new file mode 100644 index 000000000..cfe78218c --- /dev/null +++ b/ziti/cmd/ziti/cmd/tutorial/plain_echo_client.go @@ -0,0 +1,43 @@ +/* + 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 tutorial + +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 +} diff --git a/ziti/cmd/ziti/cmd/edge/tutorial_plain_echo_client_cmd.go b/ziti/cmd/ziti/cmd/tutorial/plain_echo_client_cmd.go similarity index 67% rename from ziti/cmd/ziti/cmd/edge/tutorial_plain_echo_client_cmd.go rename to ziti/cmd/ziti/cmd/tutorial/plain_echo_client_cmd.go index bc8a06006..42b86e2f0 100644 --- a/ziti/cmd/ziti/cmd/edge/tutorial_plain_echo_client_cmd.go +++ b/ziti/cmd/ziti/cmd/tutorial/plain_echo_client_cmd.go @@ -1,4 +1,20 @@ -package edge +/* + 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 tutorial import ( "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" diff --git a/ziti/cmd/ziti/cmd/edge/tutorial_plain_echo_server.go b/ziti/cmd/ziti/cmd/tutorial/plain_echo_server.go similarity index 63% rename from ziti/cmd/ziti/cmd/edge/tutorial_plain_echo_server.go rename to ziti/cmd/ziti/cmd/tutorial/plain_echo_server.go index cabba5590..cce649b93 100644 --- a/ziti/cmd/ziti/cmd/edge/tutorial_plain_echo_server.go +++ b/ziti/cmd/ziti/cmd/tutorial/plain_echo_server.go @@ -1,4 +1,20 @@ -package edge +/* + 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 tutorial import ( "fmt" diff --git a/ziti/cmd/ziti/cmd/edge/tutorial_plain_echo_server_cmd.go b/ziti/cmd/ziti/cmd/tutorial/plain_echo_server_cmd.go similarity index 66% rename from ziti/cmd/ziti/cmd/edge/tutorial_plain_echo_server_cmd.go rename to ziti/cmd/ziti/cmd/tutorial/plain_echo_server_cmd.go index c598c59c9..acc3e383a 100644 --- a/ziti/cmd/ziti/cmd/edge/tutorial_plain_echo_server_cmd.go +++ b/ziti/cmd/ziti/cmd/tutorial/plain_echo_server_cmd.go @@ -1,4 +1,20 @@ -package edge +/* + 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 tutorial import ( "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" diff --git a/ziti/cmd/ziti/cmd/tutorial/root.go b/ziti/cmd/ziti/cmd/tutorial/root.go new file mode 100644 index 000000000..0ea27d2a0 --- /dev/null +++ b/ziti/cmd/ziti/cmd/tutorial/root.go @@ -0,0 +1,68 @@ +/* + Copyright NetFoundry, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package tutorial + +import ( + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" + "github.com/openziti/ziti/ziti/cmd/ziti/cmd/edge" + cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + "github.com/spf13/cobra" + "time" +) + +func init() { + edge.ExtraEdgeCommands = append(edge.ExtraEdgeCommands, NewTutorialCmd) +} + +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 +} + +func (self *TutorialOptions) GetControllerUrl() string { + return self.ControllerUrl +} + +func (self *TutorialOptions) GetUsername() string { + return self.Username +} + +func (self *TutorialOptions) GetPassword() string { + return self.Password +} diff --git a/ziti/cmd/ziti/cmd/edge/tutorials/first-service.md b/ziti/cmd/ziti/cmd/tutorial/tutorials/first-service.md similarity index 100% rename from ziti/cmd/ziti/cmd/edge/tutorials/first-service.md rename to ziti/cmd/ziti/cmd/tutorial/tutorials/first-service.md diff --git a/ziti/cmd/ziti/cmd/edge/tutorials/more-info.md b/ziti/cmd/ziti/cmd/tutorial/tutorials/more-info.md similarity index 100% rename from ziti/cmd/ziti/cmd/edge/tutorials/more-info.md rename to ziti/cmd/ziti/cmd/tutorial/tutorials/more-info.md diff --git a/ziti/cmd/ziti/cmd/edge/tutorial_ziti_echo_client.go b/ziti/cmd/ziti/cmd/tutorial/ziti_echo_client.go similarity index 66% rename from ziti/cmd/ziti/cmd/edge/tutorial_ziti_echo_client.go rename to ziti/cmd/ziti/cmd/tutorial/ziti_echo_client.go index 7e3a392aa..0dd326afb 100644 --- a/ziti/cmd/ziti/cmd/edge/tutorial_ziti_echo_client.go +++ b/ziti/cmd/ziti/cmd/tutorial/ziti_echo_client.go @@ -1,4 +1,20 @@ -package edge +/* + 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 tutorial import ( "context" diff --git a/ziti/cmd/ziti/cmd/edge/tutorial_ziti_echo_client_cmd.go b/ziti/cmd/ziti/cmd/tutorial/ziti_echo_client_cmd.go similarity index 67% rename from ziti/cmd/ziti/cmd/edge/tutorial_ziti_echo_client_cmd.go rename to ziti/cmd/ziti/cmd/tutorial/ziti_echo_client_cmd.go index 0d9b51aef..4643271a2 100644 --- a/ziti/cmd/ziti/cmd/edge/tutorial_ziti_echo_client_cmd.go +++ b/ziti/cmd/ziti/cmd/tutorial/ziti_echo_client_cmd.go @@ -1,4 +1,20 @@ -package edge +/* + 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 tutorial import ( "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" diff --git a/ziti/cmd/ziti/cmd/edge/tutorial_ziti_echo_server.go b/ziti/cmd/ziti/cmd/tutorial/ziti_echo_server.go similarity index 66% rename from ziti/cmd/ziti/cmd/edge/tutorial_ziti_echo_server.go rename to ziti/cmd/ziti/cmd/tutorial/ziti_echo_server.go index 235471ef1..331fcf5c2 100644 --- a/ziti/cmd/ziti/cmd/edge/tutorial_ziti_echo_server.go +++ b/ziti/cmd/ziti/cmd/tutorial/ziti_echo_server.go @@ -1,4 +1,20 @@ -package edge +/* + 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 tutorial import ( "fmt" diff --git a/ziti/cmd/ziti/cmd/edge/tutorial_ziti_echo_server_cmd.go b/ziti/cmd/ziti/cmd/tutorial/ziti_echo_server_cmd.go similarity index 66% rename from ziti/cmd/ziti/cmd/edge/tutorial_ziti_echo_server_cmd.go rename to ziti/cmd/ziti/cmd/tutorial/ziti_echo_server_cmd.go index d2b5908b8..165f433e4 100644 --- a/ziti/cmd/ziti/cmd/edge/tutorial_ziti_echo_server_cmd.go +++ b/ziti/cmd/ziti/cmd/tutorial/ziti_echo_server_cmd.go @@ -1,4 +1,20 @@ -package edge +/* + 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 tutorial import ( "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" diff --git a/ziti/cmd/ziti/cmd/uninstall.go b/ziti/cmd/ziti/cmd/uninstall.go index a56f10f2e..7aa4913df 100644 --- a/ziti/cmd/ziti/cmd/uninstall.go +++ b/ziti/cmd/ziti/cmd/uninstall.go @@ -19,7 +19,6 @@ 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" "github.com/spf13/cobra" @@ -42,12 +41,11 @@ var ( ) // NewCmdUnInstall creates the command -func NewCmdUnInstall(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUnInstall(out io.Writer, errOut io.Writer) *cobra.Command { options := &UnInstallOptions{ CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -66,12 +64,12 @@ func NewCmdUnInstall(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra. SuggestFor: []string{"up"}, } - cmd.AddCommand(NewCmdUnInstallZitiController(f, out, errOut)) - cmd.AddCommand(NewCmdUnInstallZitiFabric(f, out, errOut)) - cmd.AddCommand(NewCmdUnInstallZitiRouter(f, out, errOut)) - cmd.AddCommand(NewCmdUnInstallZitiTunnel(f, out, errOut)) - cmd.AddCommand(NewCmdUnInstallZitiEdgeTunnel(f, out, errOut)) - cmd.AddCommand(NewCmdUnInstallZitiProxC(f, out, errOut)) + cmd.AddCommand(NewCmdUnInstallZitiController(out, errOut)) + cmd.AddCommand(NewCmdUnInstallZitiFabric(out, errOut)) + cmd.AddCommand(NewCmdUnInstallZitiRouter(out, errOut)) + cmd.AddCommand(NewCmdUnInstallZitiTunnel(out, errOut)) + cmd.AddCommand(NewCmdUnInstallZitiEdgeTunnel(out, errOut)) + cmd.AddCommand(NewCmdUnInstallZitiProxC(out, errOut)) return cmd } diff --git a/ziti/cmd/ziti/cmd/uninstall_ziti_controller.go b/ziti/cmd/ziti/cmd/uninstall_ziti_controller.go index 129d1fed8..517bedea6 100644 --- a/ziti/cmd/ziti/cmd/uninstall_ziti_controller.go +++ b/ziti/cmd/ziti/cmd/uninstall_ziti_controller.go @@ -19,7 +19,6 @@ 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" @@ -45,13 +44,12 @@ type UnInstallZitiControllerOptions struct { } // NewCmdUnInstallZitiController defines the command -func NewCmdUnInstallZitiController(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUnInstallZitiController(out io.Writer, errOut io.Writer) *cobra.Command { options := &UnInstallZitiControllerOptions{ UnInstallOptions: UnInstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } diff --git a/ziti/cmd/ziti/cmd/uninstall_ziti_edge_tunnel.go b/ziti/cmd/ziti/cmd/uninstall_ziti_edge_tunnel.go index 4366b5c4a..e77f721db 100644 --- a/ziti/cmd/ziti/cmd/uninstall_ziti_edge_tunnel.go +++ b/ziti/cmd/ziti/cmd/uninstall_ziti_edge_tunnel.go @@ -19,7 +19,6 @@ 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" @@ -45,13 +44,12 @@ type UnInstallZitiEdgeTunnelOptions struct { } // NewCmdUnInstallZitiEdgeTunnel defines the command -func NewCmdUnInstallZitiEdgeTunnel(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUnInstallZitiEdgeTunnel(out io.Writer, errOut io.Writer) *cobra.Command { options := &UnInstallZitiEdgeTunnelOptions{ UnInstallOptions: UnInstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } diff --git a/ziti/cmd/ziti/cmd/uninstall_ziti_fabric.go b/ziti/cmd/ziti/cmd/uninstall_ziti_fabric.go index 7600b34b7..1d9edc7cb 100644 --- a/ziti/cmd/ziti/cmd/uninstall_ziti_fabric.go +++ b/ziti/cmd/ziti/cmd/uninstall_ziti_fabric.go @@ -19,7 +19,6 @@ 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" @@ -45,13 +44,12 @@ type UnInstallZitiFabricOptions struct { } // NewCmdUnInstallZitiFabric defines the command -func NewCmdUnInstallZitiFabric(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUnInstallZitiFabric(out io.Writer, errOut io.Writer) *cobra.Command { options := &UnInstallZitiFabricOptions{ UnInstallOptions: UnInstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } diff --git a/ziti/cmd/ziti/cmd/uninstall_ziti_proxy_c.go b/ziti/cmd/ziti/cmd/uninstall_ziti_proxy_c.go index bb2442547..fdc3220aa 100644 --- a/ziti/cmd/ziti/cmd/uninstall_ziti_proxy_c.go +++ b/ziti/cmd/ziti/cmd/uninstall_ziti_proxy_c.go @@ -19,7 +19,6 @@ 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" @@ -45,13 +44,12 @@ type UnInstallZitiProxCOptions struct { } // NewCmdUnInstallZitiProxC defines the command -func NewCmdUnInstallZitiProxC(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUnInstallZitiProxC(out io.Writer, errOut io.Writer) *cobra.Command { options := &UnInstallZitiProxCOptions{ UnInstallOptions: UnInstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } diff --git a/ziti/cmd/ziti/cmd/uninstall_ziti_router.go b/ziti/cmd/ziti/cmd/uninstall_ziti_router.go index 298e153a2..2cac5b2b3 100644 --- a/ziti/cmd/ziti/cmd/uninstall_ziti_router.go +++ b/ziti/cmd/ziti/cmd/uninstall_ziti_router.go @@ -19,7 +19,6 @@ 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" @@ -45,13 +44,12 @@ type UnInstallZitiRouterOptions struct { } // NewCmdUnInstallZitiRouter defines the command -func NewCmdUnInstallZitiRouter(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUnInstallZitiRouter(out io.Writer, errOut io.Writer) *cobra.Command { options := &UnInstallZitiRouterOptions{ UnInstallOptions: UnInstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } diff --git a/ziti/cmd/ziti/cmd/uninstall_ziti_tunnel.go b/ziti/cmd/ziti/cmd/uninstall_ziti_tunnel.go index 49269b362..5fb9cc759 100644 --- a/ziti/cmd/ziti/cmd/uninstall_ziti_tunnel.go +++ b/ziti/cmd/ziti/cmd/uninstall_ziti_tunnel.go @@ -19,7 +19,6 @@ 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" @@ -45,13 +44,12 @@ type UnInstallZitiTunnelOptions struct { } // NewCmdUnInstallZitiTunnel defines the command -func NewCmdUnInstallZitiTunnel(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUnInstallZitiTunnel(out io.Writer, errOut io.Writer) *cobra.Command { options := &UnInstallZitiTunnelOptions{ UnInstallOptions: UnInstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } diff --git a/ziti/cmd/ziti/cmd/unwrap_identity.go b/ziti/cmd/ziti/cmd/unwrap_identity.go index dad38bd62..7a39c049d 100644 --- a/ziti/cmd/ziti/cmd/unwrap_identity.go +++ b/ziti/cmd/ziti/cmd/unwrap_identity.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "github.com/openziti/foundation/identity/identity" - cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" "github.com/spf13/cobra" "io" "io/ioutil" @@ -17,7 +16,7 @@ type IdentityConfigFile struct { ConfigTypes []string `json:"configTypes"` } -func NewUnwrapIdentityFileCommand(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewUnwrapIdentityFileCommand(out io.Writer, errOut io.Writer) *cobra.Command { outCertFile := "" outKeyFile := "" outCaFile := "" diff --git a/ziti/cmd/ziti/cmd/update.go b/ziti/cmd/ziti/cmd/update.go index 19e8addea..1b6c5863c 100644 --- a/ziti/cmd/ziti/cmd/update.go +++ b/ziti/cmd/ziti/cmd/update.go @@ -21,7 +21,6 @@ import ( "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" ) @@ -48,12 +47,11 @@ var ( ) // NewCmdUpdate creates a command object for the "update" command -func NewCmdUpdate(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUpdate(out io.Writer, errOut io.Writer) *cobra.Command { options := &UpdateOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } diff --git a/ziti/cmd/ziti/cmd/upgrade.go b/ziti/cmd/ziti/cmd/upgrade.go index 0a3ef2a49..437b7b33b 100644 --- a/ziti/cmd/ziti/cmd/upgrade.go +++ b/ziti/cmd/ziti/cmd/upgrade.go @@ -19,7 +19,6 @@ 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" "github.com/spf13/cobra" @@ -42,12 +41,11 @@ var ( ) // NewCmdUpgrade creates the command -func NewCmdUpgrade(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUpgrade(out io.Writer, errOut io.Writer) *cobra.Command { options := &UpgradeOptions{ CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -66,13 +64,13 @@ func NewCmdUpgrade(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Co SuggestFor: []string{"up"}, } - cmd.AddCommand(NewCmdUpgradeZiti(f, out, errOut)) - cmd.AddCommand(NewCmdUpgradeZitiController(f, out, errOut)) - cmd.AddCommand(NewCmdUpgradeZitiFabric(f, out, errOut)) - cmd.AddCommand(NewCmdUpgradeZitiRouter(f, out, errOut)) - cmd.AddCommand(NewCmdUpgradeZitiTunnel(f, out, errOut)) - cmd.AddCommand(NewCmdUpgradeZitiProxC(f, out, errOut)) - cmd.AddCommand(NewCmdUpgradeZitiEdgeTunnel(f, out, errOut)) + cmd.AddCommand(NewCmdUpgradeZiti(out, errOut)) + cmd.AddCommand(NewCmdUpgradeZitiController(out, errOut)) + cmd.AddCommand(NewCmdUpgradeZitiFabric(out, errOut)) + cmd.AddCommand(NewCmdUpgradeZitiRouter(out, errOut)) + cmd.AddCommand(NewCmdUpgradeZitiTunnel(out, errOut)) + cmd.AddCommand(NewCmdUpgradeZitiProxC(out, errOut)) + cmd.AddCommand(NewCmdUpgradeZitiEdgeTunnel(out, errOut)) return cmd } diff --git a/ziti/cmd/ziti/cmd/upgrade_ziti.go b/ziti/cmd/ziti/cmd/upgrade_ziti.go index 89db1c2ef..332526e3d 100644 --- a/ziti/cmd/ziti/cmd/upgrade_ziti.go +++ b/ziti/cmd/ziti/cmd/upgrade_ziti.go @@ -20,7 +20,6 @@ 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" @@ -46,12 +45,11 @@ type UpgradeZitiOptions struct { } // NewCmdUpgradeZiti defines the command -func NewCmdUpgradeZiti(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUpgradeZiti(out io.Writer, errOut io.Writer) *cobra.Command { options := &UpgradeZitiOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -69,7 +67,7 @@ func NewCmdUpgradeZiti(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobr }, } cmd.Flags().StringVarP(&options.Version, "version", "v", "", "The specific version to upgrade to") - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/upgrade_ziti_controller.go b/ziti/cmd/ziti/cmd/upgrade_ziti_controller.go index 9fce2e922..ed26c617a 100644 --- a/ziti/cmd/ziti/cmd/upgrade_ziti_controller.go +++ b/ziti/cmd/ziti/cmd/upgrade_ziti_controller.go @@ -20,7 +20,6 @@ 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" @@ -46,12 +45,11 @@ type UpgradeZitiControllerOptions struct { } // NewCmdUpgradeZitiController defines the command -func NewCmdUpgradeZitiController(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUpgradeZitiController(out io.Writer, errOut io.Writer) *cobra.Command { options := &UpgradeZitiControllerOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -69,7 +67,7 @@ func NewCmdUpgradeZitiController(f cmdutil.Factory, out io.Writer, errOut io.Wri }, } cmd.Flags().StringVarP(&options.Version, "version", "v", "", "The specific version to upgrade to") - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/upgrade_ziti_edge_tunnel.go b/ziti/cmd/ziti/cmd/upgrade_ziti_edge_tunnel.go index 5ef79413d..61cb7f214 100644 --- a/ziti/cmd/ziti/cmd/upgrade_ziti_edge_tunnel.go +++ b/ziti/cmd/ziti/cmd/upgrade_ziti_edge_tunnel.go @@ -20,7 +20,6 @@ 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" @@ -46,12 +45,11 @@ type UpgradeZitiEdgeTunnelOptions struct { } // NewCmdUpgradeZitiEdgeTunnel defines the command -func NewCmdUpgradeZitiEdgeTunnel(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUpgradeZitiEdgeTunnel(out io.Writer, errOut io.Writer) *cobra.Command { options := &UpgradeZitiEdgeTunnelOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -69,7 +67,7 @@ func NewCmdUpgradeZitiEdgeTunnel(f cmdutil.Factory, out io.Writer, errOut io.Wri }, } cmd.Flags().StringVarP(&options.Version, "version", "v", "", "The specific version to upgrade to") - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/upgrade_ziti_fabric.go b/ziti/cmd/ziti/cmd/upgrade_ziti_fabric.go index 47fdb597d..ad542c769 100644 --- a/ziti/cmd/ziti/cmd/upgrade_ziti_fabric.go +++ b/ziti/cmd/ziti/cmd/upgrade_ziti_fabric.go @@ -20,7 +20,6 @@ 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" @@ -46,12 +45,11 @@ type UpgradeZitiFabricOptions struct { } // NewCmdUpgradeZitiFabric defines the command -func NewCmdUpgradeZitiFabric(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUpgradeZitiFabric(out io.Writer, errOut io.Writer) *cobra.Command { options := &UpgradeZitiFabricOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -69,7 +67,7 @@ func NewCmdUpgradeZitiFabric(f cmdutil.Factory, out io.Writer, errOut io.Writer) }, } cmd.Flags().StringVarP(&options.Version, "version", "v", "", "The specific version to upgrade to") - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/upgrade_ziti_prox_c.go b/ziti/cmd/ziti/cmd/upgrade_ziti_prox_c.go index 4e91efc13..4efe92e29 100644 --- a/ziti/cmd/ziti/cmd/upgrade_ziti_prox_c.go +++ b/ziti/cmd/ziti/cmd/upgrade_ziti_prox_c.go @@ -20,7 +20,6 @@ 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" @@ -46,12 +45,11 @@ type UpgradeZitiProxCOptions struct { } // NewCmdUpgradeZitiProxC defines the command -func NewCmdUpgradeZitiProxC(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUpgradeZitiProxC(out io.Writer, errOut io.Writer) *cobra.Command { options := &UpgradeZitiProxCOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -69,7 +67,7 @@ func NewCmdUpgradeZitiProxC(f cmdutil.Factory, out io.Writer, errOut io.Writer) }, } cmd.Flags().StringVarP(&options.Version, "version", "v", "", "The specific version to upgrade to") - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/upgrade_ziti_router.go b/ziti/cmd/ziti/cmd/upgrade_ziti_router.go index 7d3569785..8a221dcfe 100644 --- a/ziti/cmd/ziti/cmd/upgrade_ziti_router.go +++ b/ziti/cmd/ziti/cmd/upgrade_ziti_router.go @@ -20,7 +20,6 @@ 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" @@ -46,12 +45,11 @@ type UpgradeZitiRouterOptions struct { } // NewCmdUpgradeZitiRouter defines the command -func NewCmdUpgradeZitiRouter(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUpgradeZitiRouter(out io.Writer, errOut io.Writer) *cobra.Command { options := &UpgradeZitiRouterOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -69,7 +67,7 @@ func NewCmdUpgradeZitiRouter(f cmdutil.Factory, out io.Writer, errOut io.Writer) }, } cmd.Flags().StringVarP(&options.Version, "version", "v", "", "The specific version to upgrade to") - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/upgrade_ziti_tunnel.go b/ziti/cmd/ziti/cmd/upgrade_ziti_tunnel.go index 364378fc7..0ea86f73e 100644 --- a/ziti/cmd/ziti/cmd/upgrade_ziti_tunnel.go +++ b/ziti/cmd/ziti/cmd/upgrade_ziti_tunnel.go @@ -20,7 +20,6 @@ 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" @@ -46,12 +45,11 @@ type UpgradeZitiTunnelOptions struct { } // NewCmdUpgradeZitiTunnel defines the command -func NewCmdUpgradeZitiTunnel(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUpgradeZitiTunnel(out io.Writer, errOut io.Writer) *cobra.Command { options := &UpgradeZitiTunnelOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -69,7 +67,7 @@ func NewCmdUpgradeZitiTunnel(f cmdutil.Factory, out io.Writer, errOut io.Writer) }, } cmd.Flags().StringVarP(&options.Version, "version", "v", "", "The specific version to upgrade to") - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) return cmd } diff --git a/ziti/cmd/ziti/cmd/use.go b/ziti/cmd/ziti/cmd/use.go index fd3719825..578b2d6e5 100644 --- a/ziti/cmd/ziti/cmd/use.go +++ b/ziti/cmd/ziti/cmd/use.go @@ -22,7 +22,6 @@ import ( "github.com/blang/semver" "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" c "github.com/openziti/ziti/ziti/cmd/ziti/constants" "github.com/openziti/ziti/ziti/cmd/ziti/internal/log" @@ -39,13 +38,12 @@ type UseOptions struct { } // NewCmdUse creates the command -func NewCmdUse(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdUse(out io.Writer, errOut io.Writer) *cobra.Command { options := &UseOptions{ InstallOptions: InstallOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, }, } diff --git a/ziti/cmd/ziti/cmd/version.go b/ziti/cmd/ziti/cmd/version.go index c8ce5a858..19f5a1946 100644 --- a/ziti/cmd/ziti/cmd/version.go +++ b/ziti/cmd/ziti/cmd/version.go @@ -27,7 +27,6 @@ import ( // "strings" "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" c "github.com/openziti/ziti/ziti/cmd/ziti/constants" "github.com/openziti/ziti/ziti/cmd/ziti/util" @@ -44,12 +43,11 @@ type VersionOptions struct { NoVersionCheck bool } -func NewCmdVersion(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { +func NewCmdVersion(out io.Writer, errOut io.Writer) *cobra.Command { options := &VersionOptions{ CommonOptions: CommonOptions{ - Factory: f, - Out: out, - Err: errOut, + Out: out, + Err: errOut, }, } @@ -64,7 +62,7 @@ func NewCmdVersion(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Co cmdhelper.CheckErr(err) }, } - options.addCommonFlags(cmd) + options.AddCommonFlags(cmd) cmd.Flags().BoolVarP(&options.NoVersionCheck, "no-update", "n", false, "disable update check") diff --git a/ziti/cmd/ziti/constants/constants.go b/ziti/cmd/ziti/constants/constants.go index 4d6e1b552..b3111008d 100644 --- a/ziti/cmd/ziti/constants/constants.go +++ b/ziti/cmd/ziti/constants/constants.go @@ -99,4 +99,5 @@ const ( ZitiEdgeCtrlAdvertisedHostPortVarDescription = "Host and port of the Ziti Edge Controller API" ZitiEdgeCtrlAdvertisedPortVarName = "ZITI_EDGE_CONTROLLER_PORT" ZitiEdgeCtrlAdvertisedPortVarDescription = "The advertised port of the edge controller" + ExternalDNSVarName = "EXTERNAL_DNS" ) diff --git a/ziti/cmd/ziti/tutorial/runner.go b/ziti/cmd/ziti/tutorial/runner.go index 43360ee85..6290e4f41 100644 --- a/ziti/cmd/ziti/tutorial/runner.go +++ b/ziti/cmd/ziti/tutorial/runner.go @@ -9,6 +9,7 @@ import ( "github.com/pkg/errors" "github.com/valyala/fasttemplate" "io" + "os" "sort" "strings" "time" @@ -22,6 +23,14 @@ const ( actionMarker = "f572d396fae9206628714fb2ce00f72e94f2258f" ) +var debug bool + +func init() { + if val, found := os.LookupEnv("DEBUG"); found && strings.EqualFold(val, "true") { + debug = true + } +} + func NewRunner() *Runner { result := &Runner{ actionHandlers: map[string]ActionHandler{}, @@ -70,6 +79,10 @@ func (self *Runner) AddVariable(name string, val interface{}) { self.variables[name] = val } +func (self *Runner) ClearVariable(name string) { + delete(self.variables, name) +} + func (self *Runner) Run(source []byte) error { markdownSource, err := self.transformSource(source) if err != nil { @@ -147,7 +160,10 @@ func (self *Runner) transformSource(source []byte) ([]byte, error) { body = strings.TrimSpace(string(actionSource[nlIndex+1 : endIndex])) } actionDef := strings.TrimSpace(actionHeader) - action, headers := self.parseAction(actionDef) + action, headers, err := self.parseAction(actionDef) + if err != nil { + return nil, err + } handler, ok := self.actionHandlers[action] if !ok { @@ -171,26 +187,74 @@ func (self *Runner) transformSource(source []byte) ([]byte, error) { } } -func (self *Runner) parseAction(s string) (string, map[string]string) { +func (self *Runner) parseAction(s string) (string, map[string]string, error) { var action string headers := map[string]string{} idx := strings.IndexByte(s, ' ') if idx < 1 { - return s, headers + return s, headers, nil } action = s[:idx] rest := s[idx+1:] - for _, kv := range strings.Split(rest, " ") { - vals := strings.Split(kv, "=") - if len(vals) < 2 { - headers[vals[0]] = "" + for len(rest) > 0 { + idx = strings.IndexByte(rest, '=') + if idx < 0 { + headers[rest] = "" + if debug { + fmt.Printf("%v: added %v=%v\n", action, rest, headers[rest]) + } + rest = "" + } else if idx == 0 { + return "", nil, errors.Errorf("unable to parse action %v, unexpected =", action) } else { - headers[vals[0]] = vals[1] + key := rest[:idx] + rest = rest[idx+1:] + if rest[0] == '\'' { + rest = rest[1:] + closingQuoteIdx := strings.IndexByte(rest, '\'') + if closingQuoteIdx < 0 { + return "", nil, errors.Errorf("unable to parse action %v, unclosed single-quote", action) + } + headers[key] = rest[:closingQuoteIdx] + if debug { + fmt.Printf("%v: added %v=%v\n", action, key, headers[key]) + } + rest = rest[closingQuoteIdx+1:] + if len(rest) > 0 { + if rest[0] != ' ' { + return "", nil, errors.Errorf("unable to parse action %v, expected space after closing singe-quote", action) + } else { + rest = rest[1:] + } + } + } else { + idx = strings.IndexByte(rest, ' ') + if idx < 0 { + headers[key] = rest + if debug { + fmt.Printf("%v: added %v=%v\n", action, key, headers[key]) + } + rest = "" + } else if idx == 0 { + headers[key] = "" + if debug { + fmt.Printf("%v: added %v=%v\n", action, key, headers[key]) + } + rest = rest[1:] + } else { + headers[key] = rest[:idx] + if debug { + fmt.Printf("%v: added %v=%v\n", action, key, headers[key]) + } + rest = rest[idx+1:] + } + } } } - return action, headers + + return action, headers, nil } func (self *Runner) actionIds() []string { diff --git a/ziti/cmd/ziti/util/identities.go b/ziti/cmd/ziti/util/identities.go index 6eba87d3a..0e61211fb 100644 --- a/ziti/cmd/ziti/util/identities.go +++ b/ziti/cmd/ziti/util/identities.go @@ -54,6 +54,7 @@ type RestClientIdentity interface { GetBaseUrlForApi(api API) (string, error) NewEdgeManagementClient(clientOpts ClientOpts) (*rest_management_api_client.ZitiEdgeManagement, error) NewFabricManagementClient(clientOpts ClientOpts) (*fabric_rest_client.ZitiFabric, error) + NewWsHeader() http.Header } func NewRequest(restClientIdentity RestClientIdentity, timeoutInSeconds int, verbose bool) (*resty.Request, error) { @@ -160,6 +161,12 @@ func (self *RestClientEdgeIdentity) NewFabricManagementClient(clientOpts ClientO return fabric_rest_client.New(clientRuntime, nil), nil } +func (self *RestClientEdgeIdentity) NewWsHeader() http.Header { + result := http.Header{} + result.Set(constants.ZitiSession, self.Token) + return result +} + type RestClientFabricIdentity struct { Url string `json:"url"` CaCert string `json:"caCert,omitempty"` @@ -227,6 +234,10 @@ func (self *RestClientFabricIdentity) NewFabricManagementClient(clientOpts Clien return fabric_rest_client.New(clientRuntime, nil), nil } +func (self *RestClientFabricIdentity) NewWsHeader() http.Header { + return http.Header{} +} + func LoadRestClientConfig() (*RestClientConfig, string, error) { config := &RestClientConfig{}