diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..a2406ca96 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +/release/ diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bc03f0fab..79d30579f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,7 +5,6 @@ on: branches: - main - release-v* - - builx-action # TODO: prune after initial testing pull_request: workflow_dispatch: @@ -105,9 +104,11 @@ jobs: $(go env GOPATH)/bin/ziti-ci configure-git $(go env GOPATH)/bin/ziti-ci generate-build-info common/version/info_generated.go version go install github.com/mitchellh/gox@latest - CGO_ENABLED=true $(go env GOPATH)/bin/gox -os=linux -arch=amd64 -output=$GOX_OUTPUT ./... - CC=arm-linux-gnueabihf-gcc CGO_ENABLED=true gox -cgo -os=linux -arch=arm -output=$GOX_OUTPUT ./... - CC=aarch64-linux-gnu-gcc CGO_ENABLED=true gox -cgo -os=linux -arch=arm64 -output=$GOX_OUTPUT ./... + $(go env GOPATH)/bin/gox -cgo -os=linux -arch=amd64 -output=${GOX_OUTPUT} ./... + CC=arm-linux-gnueabihf-gcc \ + $(go env GOPATH)/bin/gox -cgo -os=linux -arch=arm -output=${GOX_OUTPUT} ./... + CC=aarch64-linux-gnu-gcc \ + $(go env GOPATH)/bin/gox -cgo -os=linux -arch=arm64 -output=${GOX_OUTPUT} ./... aws s3 sync --no-progress s3://ziti-cmd-build-tmp/${{ github.run_id }} release/ aws s3 rm --recursive s3://ziti-cmd-build-tmp/${{ github.run_id }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a5fb6c13..a14f05b30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,227 @@ +# Release 0.24.5 + +* Enhancement: Durable Eventual Events +* Enhancement: API Session/Service Policy Enforcer Metrics +* Enhancement: Support Controller Address Changes +* Enhancement: Control Channel Metrics Split +* Enhancement: Metrics Output Size Reduction +* Enhancement: Channel Library Updates + +## Durable Eventual Events + +The controller now supports internal events to delay the processing cost of operations that do not need to resolve +immediately, but must resolve at some point. Events in the controller may pile up at increased load time and that load +level can be seen in a new gauge metric `eventual.events`. + +- `eventual.events` - The count of outstanding eventual events + +## API Session/Service Policy Enforcer Metrics + +New metrics have been added to track internal processes of the controller that enforces API Sessions and Service +Policies. + +- `api.session.enforcer.run` - a timer metric of run time of the API Session enforcer +- `api.session.enforcer.delete` - a meter metric of the number of API Sessions deleted +- `service.policy.enforcer.run` - a timer metric of run time of the Service Policy enforcer +- `service.policy.enforcer.event` - a timer metric of the run time for discrete enforcer events +- `service.policy.enforcer.event.deletes` - a meter of the number of signaling delete events processed +- `service.policy.enforcer.run.deletes` - a meter of the number of actual session deletes processed + +## Support Controller Address Changes + +The Ziti controller now supports additional address fields which can be used to signal endpoint software and routers to +update their configured controller address. The settings are useful in scenarios where moving between IP/hostnames is +desired. Use of these settings has security concerns that must be met in order to maintain connectivity and trust +between endpoint software and routers. + +### Security Requirements + +These are true for all REST API and control channel addresses. + +1) The old IP/hostname and the new IP/hostname must be present on the certificate defined by the `cert` field before + starting the transition +2) Adding the new IP/hostname to the SANs of an existing controller will require the generating and signing of a new + certificate +3) The newly generated and signed certificate must still validate with the CAs provided to routers and endpoints +4) The old IP/hostname can only be removed after all in-use routers/endpoints have connected and upgraded addresses + +### Process Outline + +1) Generate new server certificates with additional SANs for the new IP/hostname - transitional server certificate +2) Update the controller configure to use the new transitional server certificate for the desired listeners ( + control/REST APIs) +3) Restart the controller +4) Upgrade all routers to v0.24.5 or later +5) Upgrade all SDK clients to versions that support controller address changes +6) Verify existing routers and REST API clients can still connect with the old IP/hostname +7) Define the new settings required for the REST APIs (`newAddress`) and/or control channel (`newListener`), see below +8) Restart the controller +9) Verify existing routers and REST API clients configuration files have updated +10) After all clients/routers have updated their addresses, transition the `newAddress` and `newListener` values to the + default `address` and `listener` fields. +11) Remove the `newAddress` and `newListener` fields. +12) Restart the controller +13) Optionally generate a new server certificate without the old IP/hostname SANs and verify clients/routers can connect + +Notes: + +- This process may take days, weeks, or months depending on the size of the nework and how often the router/clients are + run +- It is imperative that all clients/routers that will remain in use after the IP/hostname move connect at least once + after `newAddress` and `newListener` values are configured and in use +- Clients/routers that do not receive the new address will need to be manually reconfigured by finding their + configuration file and updating the controller address + +### Control Channel Setting + +The controller listener defined in the `ctrl` section now supports a `newListener` option which must be a supported +address format (generally in the form of `::`). + +Once `newListener` is set, the controller will start to send out the new listener address to connecting routers after +the controller is restarted. All security concerns listed above must be met or routers will not be able to connect to +the controller. + +``` +ctrl: + listener: tls:127.0.0.1:6262 + options: + # (optional) settings + # ... + + # A listener address which will be sent to connecting routers in order to change their configured controller + # address. If defined, routers will update address configuration to immediately use the new address for future + # connections. The value of newListener must be resolvable both via DNS and validate via certificates + #newListener: tls:localhost:6262 +``` + +### REST API Setting + +REST APIs addresses are defined in the `web` section of the controller configuration. The `web` sections +contains `bindPoint`s that define which network interfaces the REST API server will listen on via the +`interface` field. The external address used to access that `bindPoint` is defined by the `address` field. An +additional `newAddress` field can optionally be set. + +Once `newAddress` is set, the controller will start to send out the new address to all clients via the HTTP +header `ziti-ctrl-address`. The header will be present on all responses from the controller for the specific +`bindPoint`. All security concerns listed above must be met or client will not be able to connect to the controller. + +``` +web: + # name - required + # Provides a name for this listener, used for logging output. Not required to be unique, but is highly suggested. + - name: all-apis-localhost + # bindPoints - required + # One or more bind points are required. A bind point specifies an interface (interface:port string) that defines + # where on the host machine the webListener will listen and the address (host:port) that should be used to + # publicly address the webListener(i.e. mydomain.com, localhost, 127.0.0.1). This public address may be used for + # incoming address resolution as well as used in responses in the API. + bindPoints: + #interface - required + # A host:port string on which network interface to listen on. 0.0.0.0 will listen on all interfaces + - interface: 127.0.0.1:1280 + + # address - required + # The public address that external incoming requests will be able to resolve. Used in request processing and + # response content that requires full host:port/path addresses. + address: 127.0.0.1:1280 + + # newAddress - optional + # A host:port string which will be sent out as an HTTP header "ziti-new-address" if specified. If the header + # is present, clients should update location configuration to immediately use the new address for future + # connections. The value of newAddress must be resolvable both via DNS and validate via certificates + newAddress: localhost:1280 +``` + +## Control Channel Latency Metrics Changes + +The control channel metrics have been broken into two separate metrics. Previously the metric measured how long it took for the message to be enqueued, sent and a reply received. Now the time to write to wire has been broken out. + +* `ctrl.latency` - This now measures the time from wire send to response received +* `ctrl.queue_time` - This measure the time from when the send is requested to when it actually is written to the wire + +## Metrics Output Size Reduction + +If using the JSON metrics events output, the output has changed. + +A metrics entry which previously would have looked like: + +``` +{ + "metric": "ctrl.tx.bytesrate", + "metrics": { + "ctrl.tx.bytesrate.count": 222, + "ctrl.tx.bytesrate.m15_rate": 0.37625904063382576, + "ctrl.tx.bytesrate.m1_rate": 0.12238911649077193, + "ctrl.tx.bytesrate.m5_rate": 0.13784280219782497, + "ctrl.tx.bytesrate.mean_rate": 0.1373326200238093 + }, + "namespace": "metrics", + "source_entity_id": "z7ZmJux8a7", + "source_event_id": "7b77ac53-c017-409e-afcc-fd0e1878a301", + "source_id": "ctrl_client", + "timestamp": "2022-01-26T21:46:45.866133131Z" +} +``` + +will now look like: + +``` +{ + "metric": "ctrl.tx.bytesrate", + "metrics": { + "count": 222, + "m15_rate": 0.37625904063382576, + "m1_rate": 0.12238911649077193, + "m5_rate": 0.13784280219782497, + "mean_rate": 0.1373326200238093 + }, + "namespace": "metrics", + "source_entity_id": "z7ZmJux8a7", + "source_event_id": "7b77ac53-c017-409e-afcc-fd0e1878a301", + "source_id": "ctrl_client", + "timestamp": "2022-01-26T21:46:45.866133131Z", + "version" : 2 +} +``` + +Note that the metric keys no longer have the metric name as a prefix. Also, the emitted metric has a new `version` field which is set to 2. + +Metrics with a single key, which previously looked like: + +``` +{ + "metric": "xgress.acks.queue_size", + "metrics": { + "xgress.acks.queue_size": 0 + }, + "namespace": "metrics", + "source_event_id": "6eb30de2-55de-49d5-828f-4268a3707512", + "source_id": "z7ZmJux8a7", + "timestamp": "2022-01-26T22:06:33.242933687Z", + "version": 2 +} +``` + +now look like: + +``` +{ + "metric": "xgress.acks.queue_size", + "metrics": { + "value": 0 + }, + "namespace": "metrics", + "source_event_id": "6eb30de2-55de-49d5-828f-4268a3707512", + "source_id": "z7ZmJux8a7", + "timestamp": "2022-01-26T22:06:33.242933687Z", + "version": 2 +} +``` + +## Channel Library Updates + +The channel library, which is used by edge communications, control channel, links and management channel, has been refactored. It now does a better job handling canceled messaged through the send process. If a message send times out before it is sent, the message will now no longer be sent when it gets to the head of the queue. Channels can now be instrumented to allow better metrics gathering, as seen above the the split out control channel latency metrics. Channel internals have also been refactored so that initialization is better defined, leading to better concurrency characteristics. + # Release 0.24.4 ## What's New @@ -11,7 +235,9 @@ ## Control Channel Timeouts -The controller config file now allows setting a write timeout for control channel connections. If a control channel write times out, because the connection is in a bad state or because a router is in a bad state, the control channel will be closed. This will allow the router to reconnect. +The controller config file now allows setting a write timeout for control channel connections. If a control channel +write times out, because the connection is in a bad state or because a router is in a bad state, the control channel +will be closed. This will allow the router to reconnect. ``` ctrl: @@ -27,8 +253,10 @@ ctrl: * Enhancement: API Session delete events now include the related identity id * Enhancement: controller and router start up messages now include the component id -* Enhancement: New metric `identity.refresh` which counts how often an identity should have to refresh the service list because of a service, config or policy change -* Enhancement: Edge REST services will now set the content-length on response, which will prevent response from being chunked +* Enhancement: New metric `identity.refresh` which counts how often an identity should have to refresh the service list + because of a service, config or policy change +* Enhancement: Edge REST services will now set the content-length on response, which will prevent response from being + chunked * Enhancement: Edge REST API calls will now show in metrics in the format of . * Bug fix: fix controller panic during circuit creation if router is unexpectedly deleted during routing @@ -42,20 +270,21 @@ ctrl: * Enhancement: Improve logging around links in routers. Ensure we close both channels when closing a split link * Enhancement: Add support for inspect in `ziti fabric`. Works the same as `ziti-fabric inspect` - # Release 0.24.1 ## What's New * Bug Fix: Very first time using ziti cli to login with `ziti edge login` would panic -* Security: When using new fabric REST API in fabric only mode, certs weren't being properly checked. Regression exists only in 0.24.0 +* Security: When using new fabric REST API in fabric only mode, certs weren't being properly checked. Regression exists + only in 0.24.0 # Release 0.24.0 ## Breaking Changes * ziti-fabric-gw has been removed since the fabric now has its own REST API -* ziti-fabric-test is no longer being built by default and won't be included in future release bundles. Use `go build --tags all ./...` to build it +* ziti-fabric-test is no longer being built by default and won't be included in future release bundles. + Use `go build --tags all ./...` to build it * ziti-fabric has been deprecated. Most of its features are now available in the `ziti` CLI under `ziti fabric` ## What's New @@ -67,7 +296,8 @@ ctrl: ## Fabric REST API -The fabric now has a REST API in addition to the channel2 management API. To enable it, add the fabric binding to the apis section off the xweb config, as follows: +The fabric now has a REST API in addition to the channel2 management API. To enable it, add the fabric binding to the +apis section off the xweb config, as follows: ``` apis: @@ -77,11 +307,13 @@ The fabric now has a REST API in addition to the channel2 management API. To ena - binding: fabric ``` -If running without the edge, the fabric API uses client certificates for authorization, much like the existing channel2 mgmt based API does. If running with the edge, the edge provides authentication/authorization for the fabric REST APIs. +If running without the edge, the fabric API uses client certificates for authorization, much like the existing channel2 +mgmt based API does. If running with the edge, the edge provides authentication/authorization for the fabric REST APIs. ### Supported Operations -These operations are supported in the REST API. The ziti CLI has been updated to use this in the new `ziti fabric` sub-command. +These operations are supported in the REST API. The ziti CLI has been updated to use this in the new `ziti fabric` +sub-command. * Services: create/read/update/delete * Routers: create/read/update/delete @@ -112,16 +344,18 @@ Some operations from ziti-fabric aren't get supported: ## What's New * Bug fix: Fix panic in router when router is shutdown before control channel is established -* Enhancement: Add source/target router ids on link metrics. +* Enhancement: Add source/target router ids on link metrics. * Security: Fabric management channel wasn't properly validating certs against the server cert chain * Security: Router link listeners weren't properly validating certs against the server cert chain -* Security: Link listeners now validate incoming links to ensure that the link was requested by the controller and the correct router dialed +* Security: Link listeners now validate incoming links to ensure that the link was requested by the controller and the + correct router dialed * Security: Don't allow link forwarding entries to be overriden, as link ids should be unique * Security: Validate ctrl channel clients against controller cert chain in addition to checking cert fingerprint ## Breaking Changes -The link validation required a controller side and router side component. The controller will continue to work with earlier routers, but the routers with version >= 0.23.0 will need a controller with version >= 0.23.0. +The link validation required a controller side and router side component. The controller will continue to work with +earlier routers, but the routers with version >= 0.23.0 will need a controller with version >= 0.23.0. ## Link Metrics Router Ids @@ -156,7 +390,8 @@ The link router ids will now be included as tags on the metrics. } ``` -Note that this information is injected into the metric in the controller. If the controller doesn't know about the link, because of a controller restart, the information can't be added. +Note that this information is injected into the metric in the controller. If the controller doesn't know about the link, +because of a controller restart, the information can't be added. # Release 0.22.11 @@ -166,7 +401,8 @@ Note that this information is injected into the metric in the controller. If the ## API Session Events -API Session events can now be configured by adding `edge.apiSessions` under event subscriptions. The events may be of type `created` and `deleted`. The event type can be filtered by adding an `include:` block, similar to edge sessions. +API Session events can now be configured by adding `edge.apiSessions` under event subscriptions. The events may be of +type `created` and `deleted`. The event type can be filtered by adding an `include:` block, similar to edge sessions. The JSON output looks like: @@ -185,10 +421,11 @@ The JSON output looks like: # Release 0.22.10 # What's New + * Bug fix: address client certificate changes altered by library changes * Bug fix: fixes a panic on session read in some situations -* Enhancement: Certificate Authentication Extension provides the ability to extend certificate expiration dates in the Edge Client and Management APIs - +* Enhancement: Certificate Authentication Extension provides the ability to extend certificate expiration dates in the + Edge Client and Management APIs ## Certificate Authentication Extension @@ -227,12 +464,15 @@ Output responses include: # Release 0.22.9 # What's New + * Build: This release adds an arm64 build and improved docker build process # Release 0.22.8 # What's New -* Bug fix: Workaround bbolt bug where cursor next sometimes skip when current is deleted. Use skip instead of next. Fixes orphan session issue. + +* Bug fix: Workaround bbolt bug where cursor next sometimes skip when current is deleted. Use skip instead of next. + Fixes orphan session issue. * Bug fix: If read fails on reconnecting channel, close peer before trying to reconnect * Bug fix: Don't log every UDP datagram at info level in tunneler * Change: Build with -trimpath to aid in plugin compatibility @@ -240,6 +480,7 @@ Output responses include: # Release 0.22.7 # What's New + * Bug fix: Router automatic certificate enrollments will no longer require a restart of the router * Enhancement: foundation Identity implementations now support reloading of tls.Config certificates for CAs * Enhancement: foundation Identity library brought more in-line with golang idioms @@ -247,10 +488,11 @@ Output responses include: * Bug fix: Fix controller panic when router/tunnel tries to host invalid service ## PARSEC integration (experimental) -Ziti can now use keys backed by PARSEC service for identity. -see https://parallaxsecond.github.io/parsec-book/index.html + +Ziti can now use keys backed by PARSEC service for identity. see https://parallaxsecond.github.io/parsec-book/index.html example usage during enrollment (assuming `my-identity-key` exists in PARSEC service): + ``` $ ziti-tunnel enroll -j my-identity.jwt --key parsec:my-identity-key ``` @@ -259,15 +501,18 @@ $ ziti-tunnel enroll -j my-identity.jwt --key parsec:my-identity-key # What's New -* Enhancement: Add terminator_id and version to service events. If a service event relates to a terminator, the terminator_id will now be included. Service events now also have a version field, which is set to 2. -* Enhancement: Don't let identity/service/edge router role attributes start with a hashtag or at-symbol to prevent confusion. +* Enhancement: Add terminator_id and version to service events. If a service event relates to a terminator, the + terminator_id will now be included. Service events now also have a version field, which is set to 2. +* Enhancement: Don't let identity/service/edge router role attributes start with a hashtag or at-symbol to prevent + confusion. * Bug fix: Timeout remaining for onWake/onUnlock will properly report as non-zero after MFA submission * Enhancement: traceroute support * Enhancement: add initial support for UDP links ## Traceroute -The Ziti cli and Ziti Golang SDK now support traceroute style operations. In order for this to work the SDK and routers must be at version 0.22.6 or greater. This is currently only supported in the Golang SDK. +The Ziti cli and Ziti Golang SDK now support traceroute style operations. In order for this to work the SDK and routers +must be at version 0.22.6 or greater. This is currently only supported in the Golang SDK. The SDK can perform a traceroute as follows: @@ -286,7 +531,9 @@ type TraceRouteResult struct { HopId string } ``` -Increasing numbers of hops can be requested until the hops returned is greater than zero, indicating that additional hops weren't available. This functionality is available in the Ziti CLI. + +Increasing numbers of hops can be requested until the hops returned is greater than zero, indicating that additional +hops weren't available. This functionality is available in the Ziti CLI. ``` $ ziti edge traceroute simple -c ./simple-client.json @@ -315,7 +562,8 @@ plorenz@carrot:~/work/nf$ ziti edge traceroute simple -c ./simple-client.json * Bug fix: Ziti CLI creating a CA now has the missing `--identity-name-format` / `-f` option * Bug fix: Edge router/tunneler wasn't getting per-service precedence/cost defined on identity -* Cleanup: The HA terminator strategy has been removed. The implementation was incomplete on its own. Use health checks instead of active/passive setups +* Cleanup: The HA terminator strategy has been removed. The implementation was incomplete on its own. Use health checks + instead of active/passive setups # Release 0.22.3 @@ -329,8 +577,10 @@ plorenz@carrot:~/work/nf$ ziti edge traceroute simple -c ./simple-client.json ## What's New -* Bug fix: Upgrading a controller from 0.22.0 or earlier to 0.22.2 will no longer leave old sessions w/o identityId properties. Workaround for previous versions is to use `ziti-controller delete-sessions` -* Bug fix: If a router/tunneler loses connectivity with the controller long enough for the api session to time out, the router will now restablish any terminators for hosted services +* Bug fix: Upgrading a controller from 0.22.0 or earlier to 0.22.2 will no longer leave old sessions w/o identityId + properties. Workaround for previous versions is to use `ziti-controller delete-sessions` +* Bug fix: If a router/tunneler loses connectivity with the controller long enough for the api session to time out, the + router will now restablish any terminators for hosted services * Enhancement: Add some short aliases for the CLI * edge-router -> er * service-policy -> sp @@ -343,11 +593,13 @@ plorenz@carrot:~/work/nf$ ziti edge traceroute simple -c ./simple-client.json ## What's New -* Bug fix: Fabric v0.16.93 fixes `xgress.GetCircuit` to provide a `ctrl not ready` error response when requests arrive before the router is fully online. +* Bug fix: Fabric v0.16.93 fixes `xgress.GetCircuit` to provide a `ctrl not ready` error response when requests arrive + before the router is fully online. * Bug fix: Ziti CLI will no longer truncate paths on logins with explicit URLs * Bug fix: Ziti CLI will now correctly check the proper lengths of sha512 hashes in hex format * Bug fix: MFA Posture Check timeout will no longer be half their set value -* Bug fix: MFA Posture Checks w/ a timeout configured to 0 will be treated as having no timeout (-1) instead of always being timed out +* Bug fix: MFA Posture Checks w/ a timeout configured to 0 will be treated as having no timeout (-1) instead of always + being timed out * Bug fix: MFA Posture Checks will no longer cause an usually high frequency of session updates * Bug fix: MFA Posture Checks during subsequent MFA submissions will no longer 401 * Bug fix: Listing sessions via `GET /sessions` will no longer report an error in certain data states @@ -355,14 +607,20 @@ plorenz@carrot:~/work/nf$ ziti edge traceroute simple -c ./simple-client.json * Feature: Ziti CLI `unwrap` command for identity json files will now default the output file names * Feature: Ziti CLI improvements * New interactive tutorial covering creating your first service. Run using: `ziti edge tutorial first-service` - * You can now delete multiple entities at once, by providing multiple ids. Ex: `ziti edge delete services one two` or `ziti edge delete service one two` will both work. - * You can now delete multiple entities at once, by providing a filter. Ex: `ziti edge delete services where 'name contains "foo"` + * You can now delete multiple entities at once, by providing multiple ids. Ex: `ziti edge delete services one two` + or `ziti edge delete service one two` will both work. + * You can now delete multiple entities at once, by providing a filter. + Ex: `ziti edge delete services where 'name contains "foo"` * Create and delete output now has additional context. -* Feature: Terminators can now be filtered by service and router name: Ex: `ziti edge list terminators 'service.name = "echo"'` +* Feature: Terminators can now be filtered by service and router name: + Ex: `ziti edge list terminators 'service.name = "echo"'` * Feature: New event type `edge.entityCounts` ## Entity Count Events -The Ziti Controller can now generate events with a summary of how many of each entity type are currently in the data store. It can be configured with an interval for how often the event will be generated. The default interval is five minutes. + +The Ziti Controller can now generate events with a summary of how many of each entity type are currently in the data +store. It can be configured with an interval for how often the event will be generated. The default interval is five +minutes. ``` events: @@ -414,22 +672,27 @@ Here is an example of the JSON output of the event: * Feature: Enhanced `ziti` CLI login functionality (has breaking changes to CLI options) * Feature: new `ziti edge list summary` command, which shows database entity counts * Bug fix: ziti-fabric didn't always report an error to the OS when it had an error -* Refactor: All protobuf packages have been prefixed with `ziti.` to help prevent namespace clashes. Should not be a breaking change. +* Refactor: All protobuf packages have been prefixed with `ziti.` to help prevent namespace clashes. Should not be a + breaking change. * Feature: Selective debug logging by identity for path selection and circuit establishment * `ziti edge trace identity ` will turn on debug logging for selecting paths and establishing circuits - * Addition context for these operations including circuitId, sessionid and apiSessionId should now be in log messages regardless of whether tracing is enabled + * Addition context for these operations including circuitId, sessionid and apiSessionId should now be in log + messages regardless of whether tracing is enabled * Tracing is enabled for a given duration, which defaults to 10 minutes ## Breaking Changes + Fabric sessions renamed to circuits. External integrators may be impacted by changes to events. See below for details. ### Ziti CLI -Commands under `ziti edge` now reserve the `-i` flag for specifying client identity. -Any command line argumet which previously had a `-i` short version now only has a long version. + +Commands under `ziti edge` now reserve the `-i` flag for specifying client identity. Any command line argumet which +previously had a `-i` short version now only has a long version. For consistency, policy roles parameters must all be specified in long form This includes the following flags: + * ziti edge create edge-router-policy --identity-roles --edge-router-roles * ziti edge update edge-router-policy --identity-roles --edge-router-roles * ziti edge create service-policy --identity-roles --service-roles @@ -441,14 +704,16 @@ This includes the following flags: * ziti edge update authenticator updb --identity * ziti egde update ca --identity-atributes (now -a) -The `ziti edge` commands now store session credentials in a new location and new format. Existing sessions will be ignored. +The `ziti edge` commands now store session credentials in a new location and new format. Existing sessions will be +ignored. -The `ziti edge controller` command was previously deprecated and has now been removed. All commands that were previously available -under `ziti edge controller` are available under `ziti edge`. +The `ziti edge controller` command was previously deprecated and has now been removed. All commands that were previously +available under `ziti edge controller` are available under `ziti edge`. ## Fabric Sessions renamed to Circuits -Previously we had three separate entities named session: fabric sessions, edge sessions and edge API sessions. In order to reduce confusion, fabric sessions -have been renamed to circuits. This has the following impacts: + +Previously we had three separate entities named session: fabric sessions, edge sessions and edge API sessions. In order +to reduce confusion, fabric sessions have been renamed to circuits. This has the following impacts: * ziti-fabric CLI * `list sessions` renamed to `list circuits` @@ -460,11 +725,13 @@ have been renamed to circuits. This has the following impacts: * In the router config, under xgress dialer/listener options, `sessionStartTimeout` is now `circuitStartTimeout` * In the router, under `forwarder`, `idleSessionTimeout` is now `idleCircuitTimeout` -In the context of the fabric there was an existing construct call `Circuit` which has now been renamed to `Path`. This may be visible in a few `ziti-fabric` CLI outputs +In the context of the fabric there was an existing construct call `Circuit` which has now been renamed to `Path`. This +may be visible in a few `ziti-fabric` CLI outputs ### Event changes -Previously the fabric had session events. It now has circuit events instead. These events have the `fabric.circuits` namespace. The `circuitUpdated` event type -is now the `pathUpdated` event. + +Previously the fabric had session events. It now has circuit events instead. These events have the `fabric.circuits` +namespace. The `circuitUpdated` event type is now the `pathUpdated` event. ``` type CircuitEvent struct { @@ -478,32 +745,44 @@ type CircuitEvent struct { } ``` -Additionally the Usage events now have `circuit_id` instead of `session_id`. The usage events also have a new `version` field, which is set to 2. - +Additionally the Usage events now have `circuit_id` instead of `session_id`. The usage events also have a new `version` +field, which is set to 2. # Pending Link Timeout -Previously whenever a router connected we'd look for new links possiblities and create new links between routers where any were missing. -If lots of routers connected at the same time, we might create duplicate links because the links hadn't been reported as established yet. -Now we'll checking for links in Pending state, and if they haven't hit a configurable timeout, we won't create another link. -The new config property is `pendingLinkTimeoutSeconds` in the controller config file under `network`, and defaults to 10 seconds. +Previously whenever a router connected we'd look for new links possiblities and create new links between routers where +any were missing. If lots of routers connected at the same time, we might create duplicate links because the links +hadn't been reported as established yet. Now we'll checking for links in Pending state, and if they haven't hit a +configurable timeout, we won't create another link. + +The new config property is `pendingLinkTimeoutSeconds` in the controller config file under `network`, and defaults to 10 +seconds. ## Enhanced CLI Login Functionality -### Server Trust -#### Untrusted Servers -If you don't provide a certificates file when logging in, the server's well known certificates will now be pulled from the server and you will be prompted if you want to use them. -If certs for the host have previously been retrieved they will be used. Certs stored locally will be checked against the certs on the server when logging in. -If a difference is found, the user will be notified and asked if they want to update the local certificate cache. -If you provide certificates during login, the server's certificates will not be checked or downloaded. Locally cached certificates for that host will not be used. +### Server Trust + +#### Untrusted Servers + +If you don't provide a certificates file when logging in, the server's well known certificates will now be pulled from +the server and you will be prompted if you want to use them. If certs for the host have previously been retrieved they +will be used. Certs stored locally will be checked against the certs on the server when logging in. If a difference is +found, the user will be notified and asked if they want to update the local certificate cache. + +If you provide certificates during login, the server's certificates will not be checked or downloaded. Locally cached +certificates for that host will not be used. #### Trusted Servers -If working with a server which is using certs that your OS already recognizes, nothing will change. No cert needs to be provided and the server's well known certs will not be downloaded. + +If working with a server which is using certs that your OS already recognizes, nothing will change. No cert needs to be +provided and the server's well known certs will not be downloaded. ### Identities + The Ziti CLI now suports multiple identities. An identity can be specified using `--cli-identity` or `-i`. Example commands: + ``` $ ziti edge login -i dev localhost:1280 Enter username: admin @@ -516,12 +795,14 @@ id: -JucPW0kGR name: ssh encryption required: true terminator strategy: results: 1-1 of 1 ``` -If no identity is specified, a default will be used. The default identity is `default`. +If no identity is specified, a default will be used. The default identity is `default`. #### Switching Default Identity + The default identity can be changed with the `ziti edge use` command. The above example could also be accomplished as follows: + ``` $ ziti edge use dev Settting identity 'dev' as default in ~/.config/ziti/ziti-cli.json @@ -549,6 +830,7 @@ id: cust1 | current: false | read-only: false | urL: https://customer1.co ``` #### Logout + You can now also clear locally stored credentials using `ziti edge logout` ``` @@ -557,8 +839,9 @@ Removing identity 'cust1' from ~/.config/ziti/ziti-cli.json ``` #### Read-Only Mode -When logging in one can mark the identity as read-only. This is a client side enforced flag which will attempt to make sure only -read operations are performed by this session. + +When logging in one can mark the identity as read-only. This is a client side enforced flag which will attempt to make +sure only read operations are performed by this session. ``` $ ziti edge login --read-only localhost:1280 @@ -575,14 +858,15 @@ $ ziti edge create service test error: this login is marked read-only, only GET operations are allowed ``` -NOTE: This is not guaranteed to prevent database changes. It is meant to help prevent accidental changes, if the wrong profile -is accidentally used. Caution should always be exercised when working with sensitive data! +NOTE: This is not guaranteed to prevent database changes. It is meant to help prevent accidental changes, if the wrong +profile is accidentally used. Caution should always be exercised when working with sensitive data! #### Login via Token + If you already have an API session token, you can use that to create a client identity using the new `--token` flag. -When using `--token` the saved identity will be marked as read-only unless `--read-only=false` is specified. This -is because if you only have a token and not full credentials, it's more likely that you're inspecting a system to -which you have limited privileges. +When using `--token` the saved identity will be marked as read-only unless `--read-only=false` is specified. This is +because if you only have a token and not full credentials, it's more likely that you're inspecting a system to which you +have limited privileges. ``` $ ziti edge login localhost:1280 --token c9f37575-f660-409b-b731-5a256d74a931 @@ -590,22 +874,25 @@ NOTE: When using --token the saved identity will be marked as read-only unless - Saving identity 'default' to ~/.config/ziti/ziti-cli.json ``` -Using this option will still check the server certificates to see if they need to be downloaded and/or compare them with locally -cached certificates. +Using this option will still check the server certificates to see if they need to be downloaded and/or compare them with +locally cached certificates. # Release 0.21.0 ## Semantic now Required for policies (BREAKING CHANGE) -Previouxly semantic was optional when creating or updating policies (POST or PUT), defaulting to `AllOf` when not specified. It is now required. + +Previouxly semantic was optional when creating or updating policies (POST or PUT), defaulting to `AllOf` when not +specified. It is now required. ## What's New -* Bug fix: Using PUT for policies without including the semantic would cause them to be evaluated using the AllOf semantic +* Bug fix: Using PUT for policies without including the semantic would cause them to be evaluated using the AllOf + semantic * Bug fix: Additional concurrency fix in posture data * Feature: Ziti CLI now supports a comprehensive set of `ca` and `cas` options * Feature: `ziti ps` now supports `set-channel-log-level` and `clear-channel-log-level` operations -* Change: Previouxly semantic was optional when creating or updating policies (POST or PUT), defaulting to `AllOf` when not specified. It is now required. - +* Change: Previouxly semantic was optional when creating or updating policies (POST or PUT), defaulting to `AllOf` when + not specified. It is now required. # Release 0.20.14 @@ -622,47 +909,58 @@ Previouxly semantic was optional when creating or updating policies (POST or PUT ## What's New * Bug fix: [edge#712](https://github.com/openziti/edge/issues/712) - * NF-INTERCEPT chain was getting deleted when any intercept was stopped, not when all intercepts were stopped - * IP address could get re-used across DNS entries. Added DNS cache flush on startup to avoid this - * IP address cleanup was broken as all services would see last assigned IP + * NF-INTERCEPT chain was getting deleted when any intercept was stopped, not when all intercepts were stopped + * IP address could get re-used across DNS entries. Added DNS cache flush on startup to avoid this + * IP address cleanup was broken as all services would see last assigned IP * Bug fix: Introduce delay when closing xgress peer after receiving unroute if end of session not yet received * Feature: Can now search relevant entities by role attributes - * Services, edge routers and identities can be search by role attribute. Ex: `ziti edge list services 'anyOf(roleAttributes) = "one"'` - * Polices can be searched by roles. Ex: `ziti edge list service-policies 'anyOf(identityRoles) = "#all"'` + * Services, edge routers and identities can be search by role attribute. + Ex: `ziti edge list services 'anyOf(roleAttributes) = "one"'` + * Polices can be searched by roles. Ex: `ziti edge list service-policies 'anyOf(identityRoles) = "#all"'` # Release 0.20.12 ## What's New -* Bug fix: [edge#641](https://github.com/openziti/edge/issues/641)Management and Client API nested resources now support `limit` and `offset` outside of `filter` as query params +* Bug fix: [edge#641](https://github.com/openziti/edge/issues/641)Management and Client API nested resources now + support `limit` and `offset` outside of `filter` as query params * Feature: MFA Timeout Options ## MFA Timeout Options The MFA posture check now supports three options: -* `timeoutSeconds` - the number of seconds before an MFA TOTP will need to be provided before the posture check begins to fail (optional) -* `promptOnWake` - reduces the current timeout to 5m (if not less than already) when an endpoint reports a "wake" event (optional) -* `promptOnUnlock` - reduces the current timeout to 5m (if not less than already) when an endpoint reports an "unlock" event (optional) -* `ignoreLegacyEndpoints` - forces all other options to be ignored for legacy clients that do not support event state (optional) +* `timeoutSeconds` - the number of seconds before an MFA TOTP will need to be provided before the posture check begins + to fail (optional) +* `promptOnWake` - reduces the current timeout to 5m (if not less than already) when an endpoint reports a "wake" + event (optional) +* `promptOnUnlock` - reduces the current timeout to 5m (if not less than already) when an endpoint reports an "unlock" + event (optional) +* `ignoreLegacyEndpoints` - forces all other options to be ignored for legacy clients that do not support event state ( + optional) -Event states, `promptOnWake` and `promptOnUnlock` are only supported in Ziti C SDK v0.20.0 and later. Individual ZDE/ZME clients -may take time to update. If older endpoint are used with the new MFA options `ignoreLegacyEndpoints` allows administrators to decide -how those clients should be treated. If `ignoreLegacyEndpoints` is `true`, they will not be subject to timeout or wake events. +Event states, `promptOnWake` and `promptOnUnlock` are only supported in Ziti C SDK v0.20.0 and later. Individual ZDE/ZME +clients may take time to update. If older endpoint are used with the new MFA options `ignoreLegacyEndpoints` allows +administrators to decide how those clients should be treated. If `ignoreLegacyEndpoints` is `true`, they will not be +subject to timeout or wake events. # Release 0.20.11 * Bug fix: CLI Admin create/update/delete for UPDB authenticators now function properly -* Maintenance: better logging [sdk-golang#161](https://github.com/openziti/sdk-golang/pull/161) and [edge#700](https://github.com/openziti/edge/pull/700) -* Bug fix: [sdk-golang#162](https://github.com/openziti/sdk-golang/pull/162) fix race condition on close of ziti connections +* Maintenance: better logging [sdk-golang#161](https://github.com/openziti/sdk-golang/pull/161) + and [edge#700](https://github.com/openziti/edge/pull/700) +* Bug fix: [sdk-golang#162](https://github.com/openziti/sdk-golang/pull/162) fix race condition on close of ziti + connections # Release 0.20.10 ## What's New * Bug fix: patch for process multi would clear information -* Bug fix: [ziti#420](https://github.com/openziti/ziti/issues/420) fix ziti-tunnel failover with multiple interfaces when once becomes unavailable -* Bug fix: [edge#670](https://github.com/openziti/edge/issues/670) fix ziti-tunnel issue where address were left assigned to loopback after clean shutdown +* Bug fix: [ziti#420](https://github.com/openziti/ziti/issues/420) fix ziti-tunnel failover with multiple interfaces + when once becomes unavailable +* Bug fix: [edge#670](https://github.com/openziti/edge/issues/670) fix ziti-tunnel issue where address were left + assigned to loopback after clean shutdown * Bug fix: race condition in edge session sync could cause router panic. Regression since 0.20.9 * Bug fix: terminator updates and deletes from the combined router/tunneler weren't working * Feature: Router health checks @@ -670,7 +968,8 @@ how those clients should be treated. If `ignoreLegacyEndpoints` is `true`, they ## Router Health Checks -Routers can now enable an HTTP health check endpoint. The health check is configured in the router config file with the new `healthChecks` section. +Routers can now enable an HTTP health check endpoint. The health check is configured in the router config file with the +new `healthChecks` section. ``` healthChecks: @@ -683,7 +982,8 @@ healthChecks: initialDelay: 15s ``` -The health check endpoint is configured via XWeb, same as in the controller. As section like the following can be added to the router config to enable the endpoint. +The health check endpoint is configured via XWeb, same as in the controller. As section like the following can be added +to the router config to enable the endpoint. ``` web: @@ -719,7 +1019,9 @@ $ curl -k https://localhost:8081/health-checks The endpoint will return a 200 if the health checks are passing and 503 if they are not. # Controller Health Check -Routers can now enable an HTTP health check endpoint. The health check is configured in the router config file with the new `healthChecks` section. + +Routers can now enable an HTTP health check endpoint. The health check is configured in the router config file with the +new `healthChecks` section. ``` healthChecks: @@ -732,7 +1034,8 @@ healthChecks: initialDelay: 15s ``` -The health check endpoint is configured via XWeb. In order to enable the health check endpoint, add it **first** to the list of apis. +The health check endpoint is configured via XWeb. In order to enable the health check endpoint, add it **first** to the +list of apis. ``` apis: @@ -796,7 +1099,8 @@ $ curl -k https://localhost:1280/health-checks ## What's New * Xlink now supports to a boolean `split` option to enable/disable separated payload and ack channels. -* Router identity now propagated through the link establishment plumbing. Will facilitate router-directed `transport.Configuration` profiles in a future release. +* Router identity now propagated through the link establishment plumbing. Will facilitate + router-directed `transport.Configuration` profiles in a future release. * Bug fix: tunneler identity appData wasn't propagated to tunneler/router * Bug fix: API session updates were only being sent to one router (regression since 0.20.4) * Bug fix: API session enforcer wasn't being started (regression since 0.20.0) @@ -804,7 +1108,8 @@ $ curl -k https://localhost:1280/health-checks ### Split Xlink Payload/Ack Channels -Split payload and ack channels are enabled by default, preserving the behavior of previous releases. To disable split channels, merge the following stanza into your router configuration: +Split payload and ack channels are enabled by default, preserving the behavior of previous releases. To disable split +channels, merge the following stanza into your router configuration: ``` link: @@ -846,16 +1151,19 @@ link: ## What's New * ziti-router will now emit a stackdump before exiting when it receives a SIGQUIT -* ziti ps stack now takes a --stack-timeout and will quit after the specified timeout if the stack dump hasn't completed yet +* ziti ps stack now takes a --stack-timeout and will quit after the specified timeout if the stack dump hasn't completed + yet * ziti now supports posture check types of process multi -* Fixes a bug in Ziti Management API where posture checks of type process multi were missing their base entity information (createdAt, updatedAt, etc.) +* Fixes a bug in Ziti Management API where posture checks of type process multi were missing their base entity + information (createdAt, updatedAt, etc.) # Release 0.20.1 ## What's New * Fixes a bug in the GO sdk which could cause panic by return nil connection and nil error -* [ziti#170](https://github.com/openziti/ziti/issues/170) Fixes the service poll refresh default for ziti-tunnel host mode +* [ziti#170](https://github.com/openziti/ziti/issues/170) Fixes the service poll refresh default for ziti-tunnel host + mode * Fixes a deadlock in control channel reconnect logic triggerable when network path to controller is unreliable # Release 0.20.0 @@ -870,189 +1178,187 @@ link: ### Historical Changelog Split -Changelogs for previous minor versions are now split into their own files -under `/changelogs`. +Changelogs for previous minor versions are now split into their own files under `/changelogs`. ### Edge Management REST API Transit Router Deprecation -The endpoint `/transit-routers` is now `/routers`. Use of the former name -is considered deprecated. This endpoint only affects the new Edge Management API. +The endpoint `/transit-routers` is now `/routers`. Use of the former name is considered deprecated. This endpoint only +affects the new Edge Management API. ### Edge REST API Split -The Edge REST API has now been split into two APIs: The Edge Client API and the Edge Management API. -There are now two Open API 2.0 specifications present in the `edge` repository under `/specs/client.yml` -and `/specs/management.yml`. These two files are generated (see the scripts in `/scripts/`) from decomposed -YAML source files present in `/specs/source`. +The Edge REST API has now been split into two APIs: The Edge Client API and the Edge Management API. There are now two +Open API 2.0 specifications present in the `edge` repository under `/specs/client.yml` +and `/specs/management.yml`. These two files are generated (see the scripts in `/scripts/`) from decomposed YAML source +files present in `/specs/source`. The APIs are now hosted on separate URL paths: - Client API: `/edge/client/v1` - Management API: `/edge/management/v1` -Legacy path support is present for the Client API only. The Management API does not support legacy -URL paths. The Client API Legacy paths that are supported are as follows: +Legacy path support is present for the Client API only. The Management API does not support legacy URL paths. The Client +API Legacy paths that are supported are as follows: - No Prefix: `/*` - Edge Prefix: `/edge/v1/*` -This support is only expected to last until all Ziti SDKs move to using the new prefixed paths and versions -that do not reach the end of their lifecycle. After that time, support will be removed. It is highly +This support is only expected to last until all Ziti SDKs move to using the new prefixed paths and versions that do not +reach the end of their lifecycle. After that time, support will be removed. It is highly suggested that URL path prefixes be updated or dynamically looked up via the `/version` endpoint (see below) #### Client and Management API Capabilities -The Client API represents only functionality required by and endpoint to -connected to and use services. This API services Ziti SDKs. +The Client API represents only functionality required by and endpoint to connected to and use services. This API +services Ziti SDKs. -The Management API represents all administrative configuration capabilities. -The Management API is meant to be used by the Ziti Admin Console (ZAC) or -other administrative integrations. +The Management API represents all administrative configuration capabilities. The Management API is meant to be used by +the Ziti Admin Console (ZAC) or other administrative integrations. *Client API Endpoints* - - `/edge/client/v1/` - - `/edge/client/v1/.well-known/est/cacerts` - - `/edge/client/v1/authenticate` - - `/edge/client/v1/authenticate/mfa` - - `/edge/client/v1/current-api-session` - - `/edge/client/v1/current-api-session/certificates` - - `/edge/client/v1/current-api-session/certificates/{id}` - - `/edge/client/v1/current-api-session/service-updates` - - `/edge/client/v1/current-identity` - - `/edge/client/v1/current-identity/authenticators` - - `/edge/client/v1/current-identity/authenticators/{id}` - - `/edge/client/v1/current-identity/edge-routers` - - `/edge/client/v1/current-identity/mfa` - - `/edge/client/v1/current-identity/mfa/qr-code` - - `/edge/client/v1/current-identity/mfa/verify` - - `/edge/client/v1/current-identity/mfa/recovery-codes` - - `/edge/client/v1/enroll` - - `/edge/client/v1/enroll/ca` - - `/edge/client/v1/enroll/ott` - - `/edge/client/v1/enroll/ottca` - - `/edge/client/v1/enroll/updb` - - `/edge/client/v1/enroll/erott` - - `/edge/client/v1/enroll/extend/router` - - `/edge/client/v1/posture-response` - - `/edge/client/v1/posture-response-bulk` - - `/edge/client/v1/protocols` - - `/edge/client/v1/services` - - `/edge/client/v1/services/{id}` - - `/edge/client/v1/services/{id}/terminators` - - `/edge/client/v1/sessions` - - `/edge/client/v1/sessions/{id}` - - `/edge/client/v1/specs` - - `/edge/client/v1/specs/{id}` - - `/edge/client/v1/specs/{id}/spec` - - `/edge/client/v1/version` + +- `/edge/client/v1/` +- `/edge/client/v1/.well-known/est/cacerts` +- `/edge/client/v1/authenticate` +- `/edge/client/v1/authenticate/mfa` +- `/edge/client/v1/current-api-session` +- `/edge/client/v1/current-api-session/certificates` +- `/edge/client/v1/current-api-session/certificates/{id}` +- `/edge/client/v1/current-api-session/service-updates` +- `/edge/client/v1/current-identity` +- `/edge/client/v1/current-identity/authenticators` +- `/edge/client/v1/current-identity/authenticators/{id}` +- `/edge/client/v1/current-identity/edge-routers` +- `/edge/client/v1/current-identity/mfa` +- `/edge/client/v1/current-identity/mfa/qr-code` +- `/edge/client/v1/current-identity/mfa/verify` +- `/edge/client/v1/current-identity/mfa/recovery-codes` +- `/edge/client/v1/enroll` +- `/edge/client/v1/enroll/ca` +- `/edge/client/v1/enroll/ott` +- `/edge/client/v1/enroll/ottca` +- `/edge/client/v1/enroll/updb` +- `/edge/client/v1/enroll/erott` +- `/edge/client/v1/enroll/extend/router` +- `/edge/client/v1/posture-response` +- `/edge/client/v1/posture-response-bulk` +- `/edge/client/v1/protocols` +- `/edge/client/v1/services` +- `/edge/client/v1/services/{id}` +- `/edge/client/v1/services/{id}/terminators` +- `/edge/client/v1/sessions` +- `/edge/client/v1/sessions/{id}` +- `/edge/client/v1/specs` +- `/edge/client/v1/specs/{id}` +- `/edge/client/v1/specs/{id}/spec` +- `/edge/client/v1/version` *Management API Endpoints* - - `/edge/management/v1/` - - `/edge/management/v1/api-sessions` - - `/edge/management/v1/api-sessions/{id}` - - `/edge/management/v1/authenticate` - - `/edge/management/v1/authenticate/mfa` - - `/edge/management/v1/authenticators` - - `/edge/management/v1/authenticators/{id}` - - `/edge/management/v1/cas` - - `/edge/management/v1/cas/{id}` - - `/edge/management/v1/cas/{id}/jwt` - - `/edge/management/v1/cas/{id}/verify` - - `/edge/management/v1/config-types` - - `/edge/management/v1/config-types/{id}` - - `/edge/management/v1/config-types/{id}/configs` - - `/edge/management/v1/configs` - - `/edge/management/v1/configs/{id}` - - `/edge/management/v1/current-api-session` - - `/edge/management/v1/current-identity` - - `/edge/management/v1/current-identity/authenticators` - - `/edge/management/v1/current-identity/authenticators/{id}` - - `/edge/management/v1/current-identity/mfa` - - `/edge/management/v1/current-identity/mfa/qr-code` - - `/edge/management/v1/current-identity/mfa/verify` - - `/edge/management/v1/current-identity/mfa/recovery-codes` - - `/edge/management/v1/database/snapshot` - - `/edge/management/v1/database/check-data-integrity` - - `/edge/management/v1/database/fix-data-integrity` - - `/edge/management/v1/database/data-integrity-results` - - `/edge/management/v1/edge-router-role-attributes` - - `/edge/management/v1/edge-routers` - - `/edge/management/v1/edge-routers/{id}` - - `/edge/management/v1/edge-routers/{id}/edge-router-policies` - - `/edge/management/v1/edge-routers/{id}/identities` - - `/edge/management/v1/edge-routers/{id}/service-edge-router-policies` - - `/edge/management/v1/edge-routers/{id}/services` - - `/edge/management/v1/edge-router-policies` - - `/edge/management/v1/edge-router-policies/{id}` - - `/edge/management/v1/edge-router-policies/{id}/edge-routers` - - `/edge/management/v1/edge-router-policies/{id}/identities` - - `/edge/management/v1/enrollments` - - `/edge/management/v1/enrollments/{id}` - - `/edge/management/v1/identities` - - `/edge/management/v1/identities/{id}` - - `/edge/management/v1/identities/{id}/edge-router-policies` - - `/edge/management/v1/identities/{id}/service-configs` - - `/edge/management/v1/identities/{id}/service-policies` - - `/edge/management/v1/identities/{id}/edge-routers` - - `/edge/management/v1/identities/{id}/services` - - `/edge/management/v1/identities/{id}/policy-advice/{serviceId}` - - `/edge/management/v1/identities/{id}/posture-data` - - `/edge/management/v1/identities/{id}/failed-service-requests` - - `/edge/management/v1/identities/{id}/mfa` - - `/edge/management/v1/identity-role-attributes` - - `/edge/management/v1/identity-types` - - `/edge/management/v1/identity-types/{id}` - - `/edge/management/v1/posture-checks` - - `/edge/management/v1/posture-checks/{id}` - - `/edge/management/v1/posture-check-types` - - `/edge/management/v1/posture-check-types/{id}` - - `/edge/management/v1/service-edge-router-policies` - - `/edge/management/v1/service-edge-router-policies/{id}` - - `/edge/management/v1/service-edge-router-policies/{id}/edge-routers` - - `/edge/management/v1/service-edge-router-policies/{id}/services` - - `/edge/management/v1/service-role-attributes` - - `/edge/management/v1/service-policies` - - `/edge/management/v1/service-policies/{id}` - - `/edge/management/v1/service-policies/{id}/identities` - - `/edge/management/v1/service-policies/{id}/services` - - `/edge/management/v1/service-policies/{id}/posture-checks` - - `/edge/management/v1/services` - - `/edge/management/v1/services/{id}` - - `/edge/management/v1/services/{id}/configs` - - `/edge/management/v1/services/{id}/service-edge-router-policies` - - `/edge/management/v1/services/{id}/service-policies` - - `/edge/management/v1/services/{id}/identities` - - `/edge/management/v1/services/{id}/edge-routers` - - `/edge/management/v1/services/{id}/terminators` - - `/edge/management/v1/sessions` - - `/edge/management/v1/sessions/{id}` - - `/edge/management/v1/sessions/{id}/route-path` - - `/edge/management/v1/specs` - - `/edge/management/v1/specs/{id}` - - `/edge/management/v1/specs/{id}/spec` - - `/edge/management/v1/summary` - - `/edge/management/v1/terminators` - - `/edge/management/v1/terminators/{id}` - - `/edge/management/v1/routers` - - `/edge/management/v1/transit-routers` - - `/edge/management/v1/routers/{id}` - - `/edge/management/v1/transit-routers/{id}` - - `/edge/management/v1/version` +- `/edge/management/v1/` +- `/edge/management/v1/api-sessions` +- `/edge/management/v1/api-sessions/{id}` +- `/edge/management/v1/authenticate` +- `/edge/management/v1/authenticate/mfa` +- `/edge/management/v1/authenticators` +- `/edge/management/v1/authenticators/{id}` +- `/edge/management/v1/cas` +- `/edge/management/v1/cas/{id}` +- `/edge/management/v1/cas/{id}/jwt` +- `/edge/management/v1/cas/{id}/verify` +- `/edge/management/v1/config-types` +- `/edge/management/v1/config-types/{id}` +- `/edge/management/v1/config-types/{id}/configs` +- `/edge/management/v1/configs` +- `/edge/management/v1/configs/{id}` +- `/edge/management/v1/current-api-session` +- `/edge/management/v1/current-identity` +- `/edge/management/v1/current-identity/authenticators` +- `/edge/management/v1/current-identity/authenticators/{id}` +- `/edge/management/v1/current-identity/mfa` +- `/edge/management/v1/current-identity/mfa/qr-code` +- `/edge/management/v1/current-identity/mfa/verify` +- `/edge/management/v1/current-identity/mfa/recovery-codes` +- `/edge/management/v1/database/snapshot` +- `/edge/management/v1/database/check-data-integrity` +- `/edge/management/v1/database/fix-data-integrity` +- `/edge/management/v1/database/data-integrity-results` +- `/edge/management/v1/edge-router-role-attributes` +- `/edge/management/v1/edge-routers` +- `/edge/management/v1/edge-routers/{id}` +- `/edge/management/v1/edge-routers/{id}/edge-router-policies` +- `/edge/management/v1/edge-routers/{id}/identities` +- `/edge/management/v1/edge-routers/{id}/service-edge-router-policies` +- `/edge/management/v1/edge-routers/{id}/services` +- `/edge/management/v1/edge-router-policies` +- `/edge/management/v1/edge-router-policies/{id}` +- `/edge/management/v1/edge-router-policies/{id}/edge-routers` +- `/edge/management/v1/edge-router-policies/{id}/identities` +- `/edge/management/v1/enrollments` +- `/edge/management/v1/enrollments/{id}` +- `/edge/management/v1/identities` +- `/edge/management/v1/identities/{id}` +- `/edge/management/v1/identities/{id}/edge-router-policies` +- `/edge/management/v1/identities/{id}/service-configs` +- `/edge/management/v1/identities/{id}/service-policies` +- `/edge/management/v1/identities/{id}/edge-routers` +- `/edge/management/v1/identities/{id}/services` +- `/edge/management/v1/identities/{id}/policy-advice/{serviceId}` +- `/edge/management/v1/identities/{id}/posture-data` +- `/edge/management/v1/identities/{id}/failed-service-requests` +- `/edge/management/v1/identities/{id}/mfa` +- `/edge/management/v1/identity-role-attributes` +- `/edge/management/v1/identity-types` +- `/edge/management/v1/identity-types/{id}` +- `/edge/management/v1/posture-checks` +- `/edge/management/v1/posture-checks/{id}` +- `/edge/management/v1/posture-check-types` +- `/edge/management/v1/posture-check-types/{id}` +- `/edge/management/v1/service-edge-router-policies` +- `/edge/management/v1/service-edge-router-policies/{id}` +- `/edge/management/v1/service-edge-router-policies/{id}/edge-routers` +- `/edge/management/v1/service-edge-router-policies/{id}/services` +- `/edge/management/v1/service-role-attributes` +- `/edge/management/v1/service-policies` +- `/edge/management/v1/service-policies/{id}` +- `/edge/management/v1/service-policies/{id}/identities` +- `/edge/management/v1/service-policies/{id}/services` +- `/edge/management/v1/service-policies/{id}/posture-checks` +- `/edge/management/v1/services` +- `/edge/management/v1/services/{id}` +- `/edge/management/v1/services/{id}/configs` +- `/edge/management/v1/services/{id}/service-edge-router-policies` +- `/edge/management/v1/services/{id}/service-policies` +- `/edge/management/v1/services/{id}/identities` +- `/edge/management/v1/services/{id}/edge-routers` +- `/edge/management/v1/services/{id}/terminators` +- `/edge/management/v1/sessions` +- `/edge/management/v1/sessions/{id}` +- `/edge/management/v1/sessions/{id}/route-path` +- `/edge/management/v1/specs` +- `/edge/management/v1/specs/{id}` +- `/edge/management/v1/specs/{id}/spec` +- `/edge/management/v1/summary` +- `/edge/management/v1/terminators` +- `/edge/management/v1/terminators/{id}` +- `/edge/management/v1/routers` +- `/edge/management/v1/transit-routers` +- `/edge/management/v1/routers/{id}` +- `/edge/management/v1/transit-routers/{id}` +- `/edge/management/v1/version` #### XWeb Support & Configuration Changes -The underlying framework used to host the Edge REST API has been moved into a new library -that can be found in the `fabric` repository under the module name `xweb`. XWeb allows arbitrary -APIs and website capabilities to be hosted on one or more http servers bound to any number of -network interfaces and ports. +The underlying framework used to host the Edge REST API has been moved into a new library that can be found in +the `fabric` repository under the module name `xweb`. XWeb allows arbitrary APIs and website capabilities to be hosted +on one or more http servers bound to any number of network interfaces and ports. -The main result of this is that the Edge Client and Management APIs can be hosted on separate ports or -even on separate network interfaces if desired. This allows for configurations where the Edge Management -API is not accessible outside of localhost or is only presented to network interfaces that are inwardly facing. +The main result of this is that the Edge Client and Management APIs can be hosted on separate ports or even on separate +network interfaces if desired. This allows for configurations where the Edge Management API is not accessible outside of +localhost or is only presented to network interfaces that are inwardly facing. -The introduction of XWeb has necessitated changes to the controller configuration. For a full documented example -see the file `/etc/ctrl.with.edge.yml` in this repository. +The introduction of XWeb has necessitated changes to the controller configuration. For a full documented example see the +file `/etc/ctrl.with.edge.yml` in this repository. ##### Controller Configuration: Edge Section @@ -1110,15 +1416,14 @@ edge: ``` ##### Controller Configuration: Web Section -The `web` section now allows Ziti APIs to be configured on various network interfaces and -ports according to deployment requirements. The `web` section is an array of configuration -that defines `WebListener`s. Each `WebListener` has its own HTTP configuration, `BindPoint`s, -identity override, and `API`s which are referenced by `binding` name. + +The `web` section now allows Ziti APIs to be configured on various network interfaces and ports according to deployment +requirements. The `web` section is an array of configuration that defines `WebListener`s. Each `WebListener` has its own +HTTP configuration, `BindPoint`s, identity override, and `API`s which are referenced by `binding` name. Each `WebListener` maps to at least one HTTP server that will be bound on at least one `BindPoint` -(network interface/port combination and external address) and will host one or more `API`s defined -in the `api` section. `API`s are configured by `binding` name. The following `binding` names -are currently supported: +(network interface/port combination and external address) and will host one or more `API`s defined in the `api` +section. `API`s are configured by `binding` name. The following `binding` names are currently supported: - Edge Client API: `edge-client` - Edge Management API: `edge-management` @@ -1207,8 +1512,8 @@ web: options: { } ``` -All optional values are defaulted. The smallest configuration possible that places the Edge Client -and Managements APIs on the same `BindPoint` would be: +All optional values are defaulted. The smallest configuration possible that places the Edge Client and Managements APIs +on the same `BindPoint` would be: ``` web: @@ -1224,8 +1529,8 @@ web: options: { } ``` -The following examples places the Management API on localhost and the Client API on all available interface -and advertised as `client.api.ziti.dev:1280`: +The following examples places the Management API on localhost and the Client API on all available interface and +advertised as `client.api.ziti.dev:1280`: ``` web: @@ -1249,17 +1554,16 @@ web: #### Version Endpoint Updates -All Edge APIs support the `/version` endpoint and report all the APIs supported by the controller. -Each API now has a `binding` (string name) which is a global handle for that API's capabilities. See -the current list below +All Edge APIs support the `/version` endpoint and report all the APIs supported by the controller. Each API now has +a `binding` (string name) which is a global handle for that API's capabilities. See the current list below - Client API: `edge-client`, `edge` - Management API: `edge-management` Note: `edge` is an alias of `edge-client` for the `/version` endpoint only. It is considered deprecated. -These `bind names` can be used to parse the information returned by the `/version` endpoint to obtain the -most correct URL path for each API and version present. At a future date, other APIs with new `binding`s +These `bind names` can be used to parse the information returned by the `/version` endpoint to obtain the most correct +URL path for each API and version present. At a future date, other APIs with new `binding`s (e.g. 'fabric-management` or 'fabric') or new versions may be added to this endpoint. Versions prior to 0.20 of the Edge Controller reported the following: @@ -1282,6 +1586,7 @@ Versions prior to 0.20 of the Edge Controller reported the following: "meta": {} } ``` + Note: `/edge/v1` is deprecated Version 0.20 and later report: diff --git a/Dockerfile.linux-build b/Dockerfile.linux-build index b269bbf79..6fc175583 100644 --- a/Dockerfile.linux-build +++ b/Dockerfile.linux-build @@ -1,70 +1,32 @@ -FROM ubuntu:18.04 +FROM debian:bullseye-slim # # this file mirrors the build params used in the GitHub Actions and enables -# reproducible builds for downstream forks and Ziti contributors +# reproducible builds for downstream forks for Ziti contributors # ARG latest_golang=1.17.2 ARG go_distribution_file=go${latest_golang}.linux-amd64.tar.gz -ARG GOPATH=/root/go -ARG GOROOT=/usr/local/go -RUN apt-get update -RUN apt-get -yq install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf gcc-aarch64-linux-gnu -RUN apt-get -yq install wget build-essential -RUN wget -q https://golang.org/dl/${go_distribution_file} +ARG go_path=/usr/share/go +ARG go_root=/usr/local/go +ARG go_cache=/usr/share/go_cache +ARG uid=1000 +ARG gid=1000 +RUN apt-get -y update +RUN apt-get -y install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf gcc-aarch64-linux-gnu +RUN apt-get -y install wget build-essential + +RUN wget -q https://go.dev/dl/${go_distribution_file} RUN tar -xzf ${go_distribution_file} -C /usr/local/ -RUN mkdir ${GOPATH} -ENV GOPATH=${GOPATH} -ENV GOROOT=${GOROOT} -ENV PATH=$GOPATH/bin:$GOROOT/bin:$PATH + +RUN mkdir ${go_path} ${go_cache} +RUN chown -R ${uid}:${gid} ${go_path} ${go_cache} + +USER ${uid}:${gid} +ENV GOPATH=${go_path} +ENV GOROOT=${go_root} +ENV GOCACHE=${go_cache} +ENV PATH=${go_path}/bin:${go_root}/bin:$PATH RUN go install github.com/mitchellh/gox@latest WORKDIR /mnt -CMD ["./linux-build.sh"] +ENTRYPOINT ["./linux-build.sh"] -## -# build this Dockerfile -## -# -# MINIMUM_GOLANG=$(grep -Po '^go\s+\K\d+\.\d+(\.\d+)?$' go.mod) -# LATEST_GOLANG=$(curl -sSf "https://golang.org/VERSION?m=text" | /bin/grep -Po '^go(\s+)?\K\d+\.\d+\.\d+$') -# docker build --tag=zitibuilder --file=Dockerfile.linux-build --build-arg latest_golang=${LATEST_GOLANG} . - -## -# build Ziti -## -# docker run --rm --name=zitibuilder --volume=$PWD:/mnt zitibuilder - -# $ tree ./release -# ./release -# ├── amd64 -# │   └── linux -# │   ├── ziti -# │   ├── ziti-controller -# │   ├── ziti-fabric -# │   ├── ziti-fabric-gw -# │   ├── ziti-fabric-test -# │   ├── ziti-probe -# │   ├── ziti-router -# │   └── ziti-tunnel -# ├── arm -# │   └── linux -# │   ├── ziti -# │   ├── ziti-controller -# │   ├── ziti-fabric -# │   ├── ziti-fabric-gw -# │   ├── ziti-fabric-test -# │   ├── ziti-probe -# │   ├── ziti-router -# │   └── ziti-tunnel -# └── arm64 -# └── linux -# ├── ziti -# ├── ziti-controller -# ├── ziti-fabric -# ├── ziti-fabric-gw -# ├── ziti-fabric-test -# ├── ziti-probe -# ├── ziti-router -# └── ziti-tunnel - -# 6 directories, 24 files diff --git a/doc/002-local-dev.md b/doc/002-local-dev.md index a86ec8491..8881718cf 100644 --- a/doc/002-local-dev.md +++ b/doc/002-local-dev.md @@ -5,7 +5,12 @@ configuration files that are maintained with the source code as well as Docker t ## Dependencies -- Go 1.12+ +You may verify the currently-required version of Go with this command, or by peeking inside the file named `go.mod`. + +```bash +$ /bin/grep -Po '^go\s+\K\d+\.\d+$' go.mod +1.17 +``` ## Debugging @@ -19,8 +24,86 @@ This guide can be used to run all of the Ziti applications via command line or i - `git clone https://github.com/openziti/ziti.git` 2. Change into the `ziti` dirrectory - `cd ziti` -3. Build +3. Build all commands - `go install ./...` +4. Build one command + + ```bash + ZITI_CMD=ziti-tunnel + rm -f ./build/${ZITI_CMD} \ + && mkdir -p ./build \ + && go build -o ./build/${ZITI_CMD} ./${ZITI_CMD}/cmd/${ZITI_CMD}/ \ + && ls -lARh ./build/${ZITI_CMD} + ``` + +### Multi-Platform Linux Builder Container + +The purpose of this container is to document the process of building locally the Linux executables in the same way as the GitHub Actions workflow (CI) which automation is not accessible to downstream contributors. By default, this produces three executables for each Ziti component, one for each platform architecture: amd64, arm, arm64. You may instead build for one or more of these by specifying the architecture as a parameter to the `docker run` command as shown below. + +#### Build the Container Image + +You only need to build the container image once unless you change the Dockerfile or `./linux-build.sh` (the container's entrypoint). + +```bash +# find the latest Go distribution's semver +LATEST_GOLANG=$(curl -sSfL "https://go.dev/VERSION?m=text" | /bin/grep -Po '^go(\s+)?\K\d+\.\d+\.\d+$') +# build a container image named "zitibuilder" with the Dockerfile in the top-level of this repo +docker build \ + --tag=zitibuilder \ + --file=Dockerfile.linux-build \ + --build-arg latest_golang=${LATEST_GOLANG} \ + --build-arg uid=$UID \ + --build-arg gid=$GID . +``` + +#### Run the Container to Build Executables for the Desired Architectures + +Executing the following `docker run` command will: +1. Mount the top-level of this repo on the container's `/mnt` +2. Run `./linux-build.sh ${@}` inside the container +3. Deposit built executables in `./release` + +```bash +# build for all three architectures: amd64 arm arm64 +docker run \ + --rm \ + --name=zitibuilder \ + --volume=$PWD:/mnt \ + zitibuilder + +# build only amd64 +docker run \ + --rm \ + --name=zitibuilder \ + --volume=$PWD:/mnt \ + zitibuilder \ + amd64 +``` + +You will find the built artifacts in `./release`. + +```bash +$ tree ./release +./release +├── amd64 +│   └── linux +│   ├── ziti +│   ├── ziti-controller +│   ├── ziti-router +│   └── ziti-tunnel +├── arm +│   └── linux +│   ├── ziti +│   ├── ziti-controller +│   ├── ziti-router +│   └── ziti-tunnel +└── arm64 + └── linux + ├── ziti + ├── ziti-controller + ├── ziti-router + └── ziti-tunnel +``` ### Initializing the Controller Before you can run the controller you have to initialize it's database with an administrative user. Assuming you want to run with the edge enabled, this can be done using as follows: diff --git a/etc/ctrl.with.edge.yml b/etc/ctrl.with.edge.yml index c25035882..8c892d5a3 100644 --- a/etc/ctrl.with.edge.yml +++ b/etc/ctrl.with.edge.yml @@ -20,16 +20,24 @@ identity: # the endpoint that routers will connect to the controller over. ctrl: listener: tls:127.0.0.1:6262 - # options: - # (optional) settings - # set the maximum number of connect requests that are buffered and waiting to be acknowledged (1 to 5000, default 1000) - #maxQueuedConnects: 50 - # the maximum number of connects that have begun hello synchronization (1 to 1000, default 16) - #maxOutstandingConnects: 100 - # the number of milliseconds to wait before a hello synchronization fails and closes the connection (30ms to 60000ms, default: 1000ms) - #connectTimeoutMs: 3000 - # Sets the control channel write timeout. A write timeout will close the control channel, so the router will reconnect - #writeTimeout: 15s + options: + # (optional) settings + # set the maximum number of connect requests that are buffered and waiting to be acknowledged (1 to 5000, default 1000) + #maxQueuedConnects: 50 + + # the maximum number of connects that have begun hello synchronization (1 to 1000, default 16) + #maxOutstandingConnects: 100 + + # the number of milliseconds to wait before a hello synchronization fails and closes the connection (30ms to 60000ms, default: 1000ms) + #connectTimeoutMs: 3000 + + # Sets the control channel write timeout. A write timeout will close the control channel, so the router will reconnect + #writeTimeout: 15s + + # A listener address which will be sent to connecting routers in order to change their configured controller + # address. If defined, routers will update address configuration to immediately use the new address for future + # connections. The value of newListener must be resolvable both via DNS and validate via certificates + #newListener: tls:localhost:6262 # the endpoint that management tools connect to the controller over. mgmt: @@ -37,13 +45,13 @@ mgmt: #options: # (optional) settings # set the maximum number of connect requests that are buffered and waiting to be acknowledged (1 to 5000, default 1000) - #maxQueuedConnects: 50 - # the maximum number of connects that have begun hello synchronization (1 to 1000, default 16) - #maxOutstandingConnects: 100 - # the number of milliseconds to wait before a hello synchronization fails and closes the connection (30ms to 60000ms, default: 1000ms) - #connectTimeoutMs: 3000 + #maxQueuedConnects: 50 + # the maximum number of connects that have begun hello synchronization (1 to 1000, default 16) + #maxOutstandingConnects: 100 + # the number of milliseconds to wait before a hello synchronization fails and closes the connection (30ms to 60000ms, default: 1000ms) + #connectTimeoutMs: 3000 -#metrics: + #metrics: #file: #path: /tmp/ziti-controller-metrics.log #maxsizemb: 100:wq @@ -153,10 +161,17 @@ web: #interface - required # A host:port string on which network interface to listen on. 0.0.0.0 will listen on all interfaces - interface: 127.0.0.1:1280 + # address - required # The public address that external incoming requests will be able to resolve. Used in request processing and # response content that requires full host:port/path addresses. address: 127.0.0.1:1280 + + # newAddress - optional + # A host:port string which will be sent out as an HTTP header "ziti-new-address" if specified. If the header + # is present, clients should update location configuration to immediately use the new address for future + # connections. The value of newAddress must be resolvable both via DNS and validate via certificates + newAddress: localhost:1280 # identity - optional # Allows the webListener to have a specific identity instead of defaulting to the root `identity` section. # identity: @@ -173,21 +188,26 @@ web: # can cause resources on the host to be consumed as clients remain connected and idle. Lowering this value # will cause clients to reconnect on subsequent HTTPs requests. idleTimeout: 5000ms #http timeouts, new + # readTimeout - optional, default 5000ms # The maximum amount of time in milliseconds http servers will wait to read the first incoming requests. A higher # value risks consuming resources on the host with clients that are acting bad faith or suffering from high latency # or packet loss. A lower value can risk losing connections to high latency/packet loss clients. + readTimeout: 5000ms # writeTimeout - optional, default 10000ms # The total maximum time in milliseconds that the http server will wait for a single requests to be received and # responded too. A higher value can allow long running requests to consume resources on the host. A lower value # can risk ending requests before the server has a chance to respond. + writeTimeout: 100000ms # minTLSVersion - optional, default TSL1.2 # The minimum version of TSL to support + minTLSVersion: TLS1.2 # maxTLSVersion - optional, default TSL1.3 # The maximum version of TSL to support + maxTLSVersion: TLS1.3 # apis - required # Allows one or more APIs to be bound to this webListener diff --git a/etc/ctrl.yml b/etc/ctrl.yml index f70f9d0f9..9d54fd146 100644 --- a/etc/ctrl.yml +++ b/etc/ctrl.yml @@ -108,7 +108,10 @@ ctrl: #connectTimeoutMs: 3000 # Sets the control channel write timeout. A write timeout will close the control channel, so the router will reconnect #writeTimeout: 15s - + # A listener address which will be sent to connecting routers in order to change their configured controller + # address. If defined, routers will update address configuration to immediately use the new address for future + # connections. The value of newListener must be resolvable both via DNS and validate via certificates + #newListener: tls:localhost:6262 # Management Channel Configuration # diff --git a/go.mod b/go.mod index 98c7eff88..eba44ccc0 100644 --- a/go.mod +++ b/go.mod @@ -25,18 +25,18 @@ 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.21.0 + github.com/go-openapi/runtime v0.21.1 github.com/go-openapi/strfmt v0.21.1 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/protobuf v1.5.2 - github.com/google/go-cmp v0.5.6 + github.com/google/go-cmp v0.5.7 github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19 github.com/michaelquigley/pfxlog v0.6.3 - github.com/openziti/edge v0.21.50 - github.com/openziti/fabric v0.17.19 - github.com/openziti/foundation v0.16.14 - github.com/openziti/sdk-golang v0.15.131 + github.com/openziti/edge v0.21.70 + github.com/openziti/fabric v0.17.34 + github.com/openziti/foundation v0.17.0 + github.com/openziti/sdk-golang v0.16.0 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 +57,8 @@ require ( rsc.io/goversion v1.2.0 ) +require github.com/openziti/channel v0.18.4 + require ( github.com/AppsFlyer/go-sundheit v0.5.0 // indirect github.com/BurntSushi/toml v0.4.1 // indirect @@ -82,7 +84,7 @@ require ( github.com/fsnotify/fsnotify v1.5.1 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-openapi/analysis v0.20.1 // indirect - github.com/go-openapi/errors v0.20.1 // 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/loads v0.21.0 // indirect @@ -101,11 +103,12 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jessevdk/go-flags v1.5.0 // indirect - github.com/jinzhu/copier v0.3.4 // indirect + github.com/jinzhu/copier v0.3.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/josharian/native v0.0.0-20200817173448-b6b71def0850 // indirect github.com/kataras/go-events v0.0.3-0.20201007151548-c411dc70c0a6 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect + github.com/kr/pty v1.1.8 // indirect github.com/kyokomi/emoji/v2 v2.2.8 // indirect github.com/lucas-clemente/quic-go v0.23.0 // indirect github.com/lucasb-eyer/go-colorful v1.0.3 // indirect @@ -132,7 +135,7 @@ require ( github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/openziti/dilithium v0.3.3 // indirect github.com/orcaman/concurrent-map v0.0.0-20210106121528-16402b402231 // indirect - github.com/parallaxsecond/parsec-client-go v0.0.0-20210416104105-e2d188152601 // indirect + github.com/parallaxsecond/parsec-client-go v0.0.0-20220111122524-cb78842db373 // indirect github.com/pelletier/go-toml v1.9.4 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect @@ -151,12 +154,12 @@ require ( github.com/yusufpapurcu/wmi v1.2.2 // indirect go.mongodb.org/mongo-driver v1.7.5 // indirect go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 // indirect - golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect + golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 // 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-20211210111614-af8b64212486 // indirect - golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect + golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // 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 diff --git a/go.sum b/go.sum index d864e83c0..26dbba18d 100644 --- a/go.sum +++ b/go.sum @@ -304,8 +304,9 @@ github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpX 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 h1:j23mMDtRxMwIobkpId7sWh7Ddcx4ivaoqUbfXx5P+a8= 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= @@ -337,8 +338,9 @@ github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29g github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= -github.com/go-openapi/runtime v0.21.0 h1:giZ8eT26R+/rx6RX2MkYjZPY8vPYVKDhP/mOazrQHzM= github.com/go-openapi/runtime v0.21.0/go.mod h1:aQg+kaIQEn+A2CRSY1TxbM8+sT9g2V3aLc1FbIAnbbs= +github.com/go-openapi/runtime v0.21.1 h1:/KIG00BzA2x2HRStX2tnhbqbQdPcFlkgsYCiNY20FZs= +github.com/go-openapi/runtime v0.21.1/go.mod h1:aQg+kaIQEn+A2CRSY1TxbM8+sT9g2V3aLc1FbIAnbbs= 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= @@ -480,8 +482,9 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= 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-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= @@ -590,7 +593,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.6.0/go.mod h1:Y/0W1+TZir7ypoQZYd2IrnVOKB3Tq6oegAQeSVN/+EU= +github.com/influxdata/influxdb-client-go/v2 v2.7.0/go.mod h1:Y/0W1+TZir7ypoQZYd2IrnVOKB3Tq6oegAQeSVN/+EU= 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= @@ -602,8 +605,8 @@ github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0 github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= -github.com/jinzhu/copier v0.3.4 h1:mfU6jI9PtCeUjkjQ322dlff9ELjGDu975C2p/nrubVI= -github.com/jinzhu/copier v0.3.4/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +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= @@ -836,16 +839,21 @@ 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.3/go.mod h1:wmpGSNQranDE7jsiT+Cv31UzOO3z+m69JxE2tzYwkyY= +github.com/openziti/channel v0.18.4 h1:TXQcqJjT+cZYt6uk4Ri+4lGsKCNtkj5wpn6GbX0MIkY= +github.com/openziti/channel v0.18.4/go.mod h1:wmpGSNQranDE7jsiT+Cv31UzOO3z+m69JxE2tzYwkyY= 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.50 h1:LNvaM2m1+YOqM+Ugo6ONSXrbjSS+634BFFraw8AngNM= -github.com/openziti/edge v0.21.50/go.mod h1:V8LL5CwPFohqRfrnE7eig8856edn1L28tfBkduoi+M0= -github.com/openziti/fabric v0.17.19 h1:aynMWpxsPPNREuFPxYcxmrgpQlgeaBqEzdXU52NRm1Y= -github.com/openziti/fabric v0.17.19/go.mod h1:HIquY6ph5+yC9vL38EQh2n5qWSeu5y81Pgc1YPhtPVQ= -github.com/openziti/foundation v0.16.14 h1:fwiQK7bdhs+z9idFVpEfWHzk7p0DGIvbrFbYJ6UcU8c= -github.com/openziti/foundation v0.16.14/go.mod h1:SHG4x9kLP+M7sn0BJpoc/RbSIh1Hm1BxwBPHFmCf7qE= -github.com/openziti/sdk-golang v0.15.131 h1:6i3Z2T8xcLu75VHtFhuYSNuEV7lDUphGbapZHBEjeI8= -github.com/openziti/sdk-golang v0.15.131/go.mod h1:X9YCsI4POO58WjXyKf9a16ujteJyjYBsQQ956cj8O7k= +github.com/openziti/edge v0.21.70 h1:pzv1f6P0QSIHUwVNYlP4a11EZtRy6bMAT3wzkHOg7Q0= +github.com/openziti/edge v0.21.70/go.mod h1:Jh7/RTvgxS3gTETnKQV5eITom9qa0TQTHOf0SqFqARs= +github.com/openziti/fabric v0.17.34 h1:A2P2aeJg8UmsXY81SVAKcc2UFoVxkWjvYAOWNoDGFNo= +github.com/openziti/fabric v0.17.34/go.mod h1:ZOuDngcSa0VJCNHRdYw6xCD0Tr/peZrc+Uqi8Gqc25U= +github.com/openziti/foundation v0.16.17/go.mod h1:D8IchItaO2SvK/fc/JpX9yF0vNymmOw2gzeNqwHz4+g= +github.com/openziti/foundation v0.16.18/go.mod h1:D8IchItaO2SvK/fc/JpX9yF0vNymmOw2gzeNqwHz4+g= +github.com/openziti/foundation v0.17.0 h1:frhZqq9f6l+BBgYNYpnvo36T1CQsN/7DtKJPWDOQpHI= +github.com/openziti/foundation v0.17.0/go.mod h1:D8IchItaO2SvK/fc/JpX9yF0vNymmOw2gzeNqwHz4+g= +github.com/openziti/sdk-golang v0.16.0 h1:Wq4P17btCYeh6nJsFVQpMzC4xgXBTYcKHOJr7Qb484w= +github.com/openziti/sdk-golang v0.16.0/go.mod h1:Bxmfwgn89gIaIkdQ/3PENo7pLu5Yw1Eyiu2taP3Vqow= 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= @@ -856,8 +864,9 @@ github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6 github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/ovh/go-ovh v1.1.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA= -github.com/parallaxsecond/parsec-client-go v0.0.0-20210416104105-e2d188152601 h1:1YdmkuR6lJ+mDvdkI8cBDKOljRWL4kdPFSu3qRAEf6g= github.com/parallaxsecond/parsec-client-go v0.0.0-20210416104105-e2d188152601/go.mod h1:iFrEMRwLidGESW7mwIhRWDD7m5ktzKeCX2XNCyAFtNk= +github.com/parallaxsecond/parsec-client-go v0.0.0-20220111122524-cb78842db373 h1:CUvH4JL/8OVy023LMER3dB/MerNQ6OIz4QV3E/JQ3UY= +github.com/parallaxsecond/parsec-client-go v0.0.0-20220111122524-cb78842db373/go.mod h1:gLH27qo/dvMhLTVVyMELpe3Tut7sOfkiDg7ZpeqKwsw= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= @@ -1141,8 +1150,9 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 h1:71vQrMauZZhcTVK6KdYM+rklehEEwb3E+ZhaE5jrPrE= +golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/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= @@ -1255,6 +1265,7 @@ golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211209124913-491a49abca63 h1:iocB37TsdFuN6IBRZ+ry36wrkoV51/tl5vOWqkcPGvY= golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1401,11 +1412,13 @@ golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486 h1:5hpz5aRr+W1erYCL5JRhSUBJRph7l9XkNveoExlrKYk= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 h1:XDXtA5hveEEV8JB2l7nhMTp3t3cHp9ZpwcdjqyEWLlo= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/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 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= 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/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= diff --git a/linux-build.sh b/linux-build.sh index 05383a33d..4d51bdfa7 100755 --- a/linux-build.sh +++ b/linux-build.sh @@ -2,11 +2,71 @@ # # build the Linux artifacts for amd64, arm, arm64 # -# see instructions to run reproducible build with Docker in ./Dockerfile.linux-build +# runs one background job per desired architecture unless there are too few CPUs # +# + set -o pipefail -e -u +# if no architectures supplied then default list of three +if (( ${#} )); then + typeset -a JOBS=(${@}) +else + typeset -a JOBS=(amd64 arm arm64) +fi + +# specify the Go template used by Gox to save the artifacts GOX_OUTPUT="release/{{.Arch}}/{{.OS}}/{{.Dir}}" -CGO_ENABLED=true gox -os=linux -arch=amd64 -output=${GOX_OUTPUT} ./... -CC=arm-linux-gnueabihf-gcc CGO_ENABLED=true gox -cgo -os=linux -arch=arm -output=${GOX_OUTPUT} ./... -CC=aarch64-linux-gnu-gcc CGO_ENABLED=true gox -cgo -os=linux -arch=arm64 -output=$GOX_OUTPUT ./... +# count the number of available CPUs for time-efficient parallelism +PROC_COUNT=$(nproc --all) +# compute the number of processors available for each job, rounded down to integer +PROCS_PER_JOB=$((PROC_COUNT / ${#JOBS[@]})) +# if multiple jobs and at least one processor for each job then background, else foreground with all available CPUs-1 (gox default) +if (( ${#JOBS[@]} > 1 && ${PROCS_PER_JOB} )); then + BACKGROUND="&" + # initialize an associative array in which to map background PIDs to the ARCH being built + typeset -A BUILDS +else + BACKGROUND="" # run normally in foreground + PROCS_PER_JOB=0 # invokes gox default to use all CPUs-1 +fi + +for ARCH in ${JOBS[@]}; do + GOX_CMD=" + gox \ + -cgo \ + -os=linux \ + -arch=${ARCH} \ + -output=${GOX_OUTPUT} \ + -parallel=${PROCS_PER_JOB} \ + ./... + " +case ${ARCH} in + amd64) eval ${GOX_CMD} ${BACKGROUND} + (( ${PROCS_PER_JOB} )) && BUILDS[${!}]=${ARCH} # if greater than zero procs per job then map background pid->arch + ;; + arm) eval CC=arm-linux-gnueabihf-gcc ${GOX_CMD} ${BACKGROUND} + (( ${PROCS_PER_JOB} )) && BUILDS[${!}]=${ARCH} + ;; + arm64) eval CC=aarch64-linux-gnu-gcc ${GOX_CMD} ${BACKGROUND} + (( ${PROCS_PER_JOB} )) && BUILDS[${!}]=${ARCH} + ;; + *) echo "ERROR: invalid architecture '${ARCH}', must be one of amd64, arm, arm64" >&2 + exit 1 + ;; + esac +done + +# if not background in parallel then exit now with well earned success +[[ -z "${BACKGROUND:-}" ]] || exit 0 + +# Wait for builds in the background and exit with an error if any fail +EXIT=0 +while true; do + # "wait -p" requires BASH >=5.1 which is present in Ubuntu 20.10 and Debian Bullseye + wait -n -p JOB_PID; JOB_RESULT=$? + echo "Building for ${BUILDS[$JOB_PID]} finished with result ${JOB_RESULT}" + (( ${JOB_RESULT} )) && EXIT=1 +done + +exit ${EXIT} diff --git a/ziti-fabric-test/main.go b/ziti-fabric-test/main.go index e095e4f12..431992a1a 100644 --- a/ziti-fabric-test/main.go +++ b/ziti-fabric-test/main.go @@ -19,6 +19,8 @@ package main import ( + "math/rand" + "github.com/michaelquigley/pfxlog" "github.com/openziti/foundation/transport" "github.com/openziti/foundation/transport/quic" @@ -33,7 +35,6 @@ import ( _ "github.com/openziti/ziti/ziti-fabric-test/subcmd/loop2" _ "github.com/openziti/ziti/ziti-fabric-test/subcmd/loop3" "github.com/sirupsen/logrus" - "math/rand" ) func init() { diff --git a/ziti-fabric/main.go b/ziti-fabric/main.go index f64783cac..cd5fa5eb1 100644 --- a/ziti-fabric/main.go +++ b/ziti-fabric/main.go @@ -18,6 +18,7 @@ package main import ( "fmt" + "github.com/michaelquigley/pfxlog" "github.com/openziti/foundation/transport" "github.com/openziti/foundation/transport/quic" diff --git a/ziti-fabric/subcmd/client.go b/ziti-fabric/subcmd/client.go index 7e51bc95c..e5e747416 100644 --- a/ziti-fabric/subcmd/client.go +++ b/ziti-fabric/subcmd/client.go @@ -17,7 +17,7 @@ package subcmd import ( - "github.com/openziti/foundation/channel2" + "github.com/openziti/channel" "github.com/openziti/foundation/identity/dotziti" "github.com/openziti/foundation/identity/identity" "github.com/openziti/foundation/transport" @@ -37,7 +37,11 @@ func NewMgmtClient(cmd *cobra.Command) *mgmtClient { return client } -func (c *mgmtClient) Connect() (channel2.Channel, error) { +func (c *mgmtClient) Connect() (channel.Channel, error) { + return c.ConnectAndBind(nil) +} + +func (c *mgmtClient) ConnectAndBind(bindHandler channel.BindHandler) (channel.Channel, error) { if endpoint, id, err := dotziti.LoadIdentity(c.idName); err == nil { c.id = id endpointStr := endpoint @@ -45,8 +49,8 @@ func (c *mgmtClient) Connect() (channel2.Channel, error) { endpointStr = c.mgmtEndpoint } if mgmtAddress, err := transport.ParseAddress(endpointStr); err == nil { - dialer := channel2.NewClassicDialer(c.id, mgmtAddress, nil) - if ch, err := channel2.NewChannel("mgmt", dialer, nil); err == nil { + dialer := channel.NewClassicDialer(c.id, mgmtAddress, nil) + if ch, err := channel.NewChannel("mgmt", dialer, bindHandler, nil); err == nil { return ch, nil } else { return nil, err diff --git a/ziti-fabric/subcmd/create_router.go b/ziti-fabric/subcmd/create_router.go index 7ac4f6ae1..f49825db2 100644 --- a/ziti-fabric/subcmd/create_router.go +++ b/ziti-fabric/subcmd/create_router.go @@ -18,11 +18,10 @@ package subcmd import ( "crypto/sha1" - "errors" "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/foundation/channel2" "github.com/openziti/foundation/identity/certtools" "github.com/spf13/cobra" "time" @@ -51,25 +50,20 @@ var createRouter = &cobra.Command{ }, } if body, err := proto.Marshal(request); err == nil { - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_CreateRouterRequestType), body) - waitCh, err := ch.SendAndWait(requestMsg) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_CreateRouterRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } - select { - case responseMsg := <-waitCh: - if responseMsg.ContentType == channel2.ContentTypeResultType { - result := channel2.UnmarshalResult(responseMsg) - if result.Success { - fmt.Printf("\nsuccess\n\n") - } else { - fmt.Printf("\nfailure [%s]\n\n", result.Message) - } + if responseMsg.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(responseMsg) + if result.Success { + fmt.Printf("\nsuccess\n\n") } else { - panic(fmt.Errorf("unexpected response type %v", responseMsg.ContentType)) + fmt.Printf("\nfailure [%s]\n\n", result.Message) } - case <-time.After(5 * time.Second): - panic(errors.New("timeout")) + } else { + panic(fmt.Errorf("unexpected response type %v", responseMsg.ContentType)) } } else { panic(err) diff --git a/ziti-fabric/subcmd/create_service.go b/ziti-fabric/subcmd/create_service.go index 9b2ca9583..8eed14afa 100644 --- a/ziti-fabric/subcmd/create_service.go +++ b/ziti-fabric/subcmd/create_service.go @@ -19,8 +19,8 @@ package subcmd import ( "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/foundation/channel2" "github.com/spf13/cobra" "time" ) @@ -53,13 +53,13 @@ var createService = &cobra.Command{ if err != nil { panic(err) } - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_CreateServiceRequestType), body) - responseMsg, err := ch.SendAndWaitWithTimeout(requestMsg, 5*time.Second) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_CreateServiceRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } - if responseMsg.ContentType == channel2.ContentTypeResultType { - result := channel2.UnmarshalResult(responseMsg) + if responseMsg.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(responseMsg) if result.Success { fmt.Printf("\nsuccess\n\n") } else { diff --git a/ziti-fabric/subcmd/create_terminator.go b/ziti-fabric/subcmd/create_terminator.go index 2b94dd779..295e48483 100644 --- a/ziti-fabric/subcmd/create_terminator.go +++ b/ziti-fabric/subcmd/create_terminator.go @@ -19,8 +19,8 @@ package subcmd import ( "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/foundation/channel2" "github.com/openziti/foundation/util/stringz" "github.com/spf13/cobra" "time" @@ -81,13 +81,13 @@ var createTerminator = &cobra.Command{ if err != nil { panic(err) } - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_CreateTerminatorRequestType), body) - responseMsg, err := ch.SendAndWaitWithTimeout(requestMsg, 5*time.Second) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_CreateTerminatorRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } - if responseMsg.ContentType == channel2.ContentTypeResultType { - result := channel2.UnmarshalResult(responseMsg) + if responseMsg.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(responseMsg) if result.Success { fmt.Printf("\nsuccess\n\n") } else { diff --git a/ziti-fabric/subcmd/get_service.go b/ziti-fabric/subcmd/get_service.go index 9c690a77c..e4ec06079 100644 --- a/ziti-fabric/subcmd/get_service.go +++ b/ziti-fabric/subcmd/get_service.go @@ -19,8 +19,8 @@ package subcmd import ( "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/foundation/channel2" "github.com/spf13/cobra" "time" ) @@ -43,8 +43,8 @@ var getService = &cobra.Command{ if err != nil { panic(err) } - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_GetServiceRequestType), body) - responseMsg, err := ch.SendAndWaitWithTimeout(requestMsg, 5*time.Second) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_GetServiceRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } @@ -65,8 +65,8 @@ var getService = &cobra.Command{ } else { fmt.Printf("Id not found\n") } - } else if responseMsg.ContentType == channel2.ContentTypeResultType { - result := channel2.UnmarshalResult(responseMsg) + } else if responseMsg.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(responseMsg) if result.Success { fmt.Printf("\nsuccess\n\n") } else { diff --git a/ziti-fabric/subcmd/get_terminator.go b/ziti-fabric/subcmd/get_terminator.go index d5675d2ac..7c8e937cb 100644 --- a/ziti-fabric/subcmd/get_terminator.go +++ b/ziti-fabric/subcmd/get_terminator.go @@ -19,8 +19,8 @@ package subcmd import ( "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/foundation/channel2" "github.com/spf13/cobra" "time" ) @@ -43,8 +43,8 @@ var getTerminator = &cobra.Command{ if err != nil { panic(err) } - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_GetTerminatorRequestType), body) - responseMsg, err := ch.SendAndWaitWithTimeout(requestMsg, 5*time.Second) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_GetTerminatorRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } @@ -59,8 +59,8 @@ var getTerminator = &cobra.Command{ } else { fmt.Printf("Id not found\n") } - } else if responseMsg.ContentType == channel2.ContentTypeResultType { - result := channel2.UnmarshalResult(responseMsg) + } else if responseMsg.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(responseMsg) if result.Success { fmt.Printf("\nsuccess\n\n") } else { diff --git a/ziti-fabric/subcmd/inspect.go b/ziti-fabric/subcmd/inspect.go index d4364bbcd..ac34ae64e 100644 --- a/ziti-fabric/subcmd/inspect.go +++ b/ziti-fabric/subcmd/inspect.go @@ -17,11 +17,11 @@ package subcmd import ( - "github.com/openziti/foundation/channel2" - "github.com/openziti/fabric/pb/mgmt_pb" "errors" "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" + "github.com/openziti/fabric/pb/mgmt_pb" "github.com/spf13/cobra" "time" ) @@ -49,36 +49,31 @@ func inspect(cmd *cobra.Command, args []string) { if err != nil { panic(err) } - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_InspectRequestType), body) - waitCh, err := ch.SendAndWait(requestMsg) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_InspectRequestType), body) + responseMsg, err := requestMsg.WithTimeout(10 * time.Second).SendForReply(ch) if err != nil { panic(err) } - select { - case responseMsg := <-waitCh: - if responseMsg.ContentType == int32(mgmt_pb.ContentType_InspectResponseType) { - response := &mgmt_pb.InspectResponse{} - err := proto.Unmarshal(responseMsg.Body, response) - if err != nil { - panic(err) - } - if response.Success { - fmt.Printf("\nResults: (%d)\n", len(response.Values)) - for _, value := range response.Values { - fmt.Printf("%v.%v\n", value.AppId, value.Name) - fmt.Printf("%v\n\n", value.Value) - } - } else { - fmt.Printf("\nEncountered errors: (%d)\n", len(response.Errors)) - for _, err := range response.Errors { - fmt.Printf("\t%v\n", err) - } + if responseMsg.ContentType == int32(mgmt_pb.ContentType_InspectResponseType) { + response := &mgmt_pb.InspectResponse{} + err := proto.Unmarshal(responseMsg.Body, response) + if err != nil { + panic(err) + } + if response.Success { + fmt.Printf("\nResults: (%d)\n", len(response.Values)) + for _, value := range response.Values { + fmt.Printf("%v.%v\n", value.AppId, value.Name) + fmt.Printf("%v\n\n", value.Value) } } else { - panic(errors.New("unexpected response")) + fmt.Printf("\nEncountered errors: (%d)\n", len(response.Errors)) + for _, err := range response.Errors { + fmt.Printf("\t%v\n", err) + } } - case <-time.After(10 * time.Second): - panic(errors.New("timeout")) + } else { + panic(errors.New("unexpected response")) } } else { panic(err) diff --git a/ziti-fabric/subcmd/list_circuits.go b/ziti-fabric/subcmd/list_circuits.go index 4413cda3e..f98ea0f3d 100644 --- a/ziti-fabric/subcmd/list_circuits.go +++ b/ziti-fabric/subcmd/list_circuits.go @@ -20,8 +20,8 @@ import ( "errors" "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/foundation/channel2" "github.com/spf13/cobra" "sort" "time" @@ -46,40 +46,34 @@ func listCircuits(cmd *cobra.Command, args []string) { if err != nil { panic(err) } - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_ListCircuitsRequestType), body) - waitCh, err := ch.SendAndWait(requestMsg) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_ListCircuitsRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } - select { - case responseMsg := <-waitCh: - if responseMsg.ContentType == int32(mgmt_pb.ContentType_ListCircuitsResponseType) { - response := &mgmt_pb.ListCircuitsResponse{} - err := proto.Unmarshal(responseMsg.Body, response) - if err == nil { - out := fmt.Sprintf("\nCircuits: (%d)\n\n", len(response.Circuits)) - out += fmt.Sprintf("%-12s | %-12s | %-12s | %s\n", "Id", "Client", "Service", "Path") - sort.Slice(response.Circuits, func(i, j int) bool { - if response.Circuits[i].ServiceId == response.Circuits[j].ServiceId { - return response.Circuits[i].Id < response.Circuits[j].Id - } - return response.Circuits[i].ServiceId < response.Circuits[j].ServiceId - }) - for _, s := range response.Circuits { - out += fmt.Sprintf("%-12s | %-12s | %-12s | %s", s.Id, s.ClientId, s.ServiceId, s.Path.CalculateDisplayPath()) + if responseMsg.ContentType == int32(mgmt_pb.ContentType_ListCircuitsResponseType) { + response := &mgmt_pb.ListCircuitsResponse{} + err := proto.Unmarshal(responseMsg.Body, response) + if err == nil { + out := fmt.Sprintf("\nCircuits: (%d)\n\n", len(response.Circuits)) + out += fmt.Sprintf("%-12s | %-12s | %-12s | %s\n", "Id", "Client", "Service", "Path") + sort.Slice(response.Circuits, func(i, j int) bool { + if response.Circuits[i].ServiceId == response.Circuits[j].ServiceId { + return response.Circuits[i].Id < response.Circuits[j].Id } - out += "\n" - fmt.Print(out) - - } else { - panic(err) + return response.Circuits[i].ServiceId < response.Circuits[j].ServiceId + }) + for _, s := range response.Circuits { + out += fmt.Sprintf("%-12s | %-12s | %-12s | %s", s.Id, s.ClientId, s.ServiceId, s.Path.CalculateDisplayPath()) } - } else { - panic(errors.New("unexpected response")) - } + out += "\n" + fmt.Print(out) - case <-time.After(5 * time.Second): - panic(errors.New("timeout")) + } else { + panic(err) + } + } else { + panic(errors.New("unexpected response")) } } else { panic(err) diff --git a/ziti-fabric/subcmd/list_links.go b/ziti-fabric/subcmd/list_links.go index a4c0b1b9c..3d31aafb3 100644 --- a/ziti-fabric/subcmd/list_links.go +++ b/ziti-fabric/subcmd/list_links.go @@ -20,8 +20,8 @@ import ( "errors" "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/foundation/channel2" "github.com/spf13/cobra" "sort" "time" @@ -46,49 +46,43 @@ func listLinks(cmd *cobra.Command, args []string) { if err != nil { panic(err) } - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_ListLinksRequestType), body) - waitCh, err := ch.SendAndWait(requestMsg) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_ListLinksRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } - select { - case responseMsg := <-waitCh: - if responseMsg.ContentType == int32(mgmt_pb.ContentType_ListLinksResponseType) { - response := &mgmt_pb.ListLinksResponse{} - err := proto.Unmarshal(responseMsg.Body, response) - if err == nil { - out := fmt.Sprintf("\nLinks: (%d)\n\n", len(response.Links)) - out += fmt.Sprintf("%-6s | %-24s -> %-24s | %-12s | %-4s | %-13s | %-12s | %-6s\n", "Id", "Src", "Dst", "State", "Cost", "Latency", "Full Cost", "Status") - sort.Slice(response.Links, func(i, j int) bool { - if response.Links[i].Src == response.Links[j].Src { - return response.Links[i].Dst < response.Links[j].Dst - } - return response.Links[i].Src < response.Links[j].Src - }) - for _, l := range response.Links { - status := "up" - if l.Down { - status = "down" - } - // Convert nanoseconds to fractional seconds - srcLatency := float64(l.SrcLatency) / 1_000_000_000.0 - dstLatency := float64(l.DstLatency) / 1_000_000_000.0 - cost := (l.SrcLatency / 1_000_000) + (l.DstLatency / 1_000_000) + int64(l.Cost) - out += fmt.Sprintf("%-6s | %-24s -> %-24s | %-12s | %-4d | %-0.4f %-0.4f | %-12v | %-6v\n", l.Id, l.Src, l.Dst, l.State, l.Cost, srcLatency, dstLatency, - cost, status) + if responseMsg.ContentType == int32(mgmt_pb.ContentType_ListLinksResponseType) { + response := &mgmt_pb.ListLinksResponse{} + err := proto.Unmarshal(responseMsg.Body, response) + if err == nil { + out := fmt.Sprintf("\nLinks: (%d)\n\n", len(response.Links)) + out += fmt.Sprintf("%-6s | %-24s -> %-24s | %-12s | %-4s | %-13s | %-12s | %-6s\n", "Id", "Src", "Dst", "State", "Cost", "Latency", "Full Cost", "Status") + sort.Slice(response.Links, func(i, j int) bool { + if response.Links[i].Src == response.Links[j].Src { + return response.Links[i].Dst < response.Links[j].Dst } - out += "\n" - fmt.Print(out) - - } else { - panic(err) + return response.Links[i].Src < response.Links[j].Src + }) + for _, l := range response.Links { + status := "up" + if l.Down { + status = "down" + } + // Convert nanoseconds to fractional seconds + srcLatency := float64(l.SrcLatency) / 1_000_000_000.0 + dstLatency := float64(l.DstLatency) / 1_000_000_000.0 + cost := (l.SrcLatency / 1_000_000) + (l.DstLatency / 1_000_000) + int64(l.Cost) + out += fmt.Sprintf("%-6s | %-24s -> %-24s | %-12s | %-4d | %-0.4f %-0.4f | %-12v | %-6v\n", l.Id, l.Src, l.Dst, l.State, l.Cost, srcLatency, dstLatency, + cost, status) } - } else { - panic(errors.New("unexpected response")) - } + out += "\n" + fmt.Print(out) - case <-time.After(5 * time.Second): - panic(errors.New("timeout")) + } else { + panic(err) + } + } else { + panic(errors.New("unexpected response")) } } else { panic(err) diff --git a/ziti-fabric/subcmd/list_routers.go b/ziti-fabric/subcmd/list_routers.go index 063ab66c6..593e7762a 100644 --- a/ziti-fabric/subcmd/list_routers.go +++ b/ziti-fabric/subcmd/list_routers.go @@ -20,8 +20,8 @@ import ( "errors" "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/foundation/channel2" "github.com/spf13/cobra" "time" ) @@ -47,42 +47,36 @@ var listRouters = &cobra.Command{ if err != nil { panic(err) } - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_ListRoutersRequestType), body) - waitCh, err := ch.SendAndWait(requestMsg) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_ListRoutersRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } - select { - case responseMsg := <-waitCh: - if responseMsg.ContentType == int32(mgmt_pb.ContentType_ListRoutersResponseType) { - response := &mgmt_pb.ListRoutersResponse{} - err := proto.Unmarshal(responseMsg.Body, response) - if err == nil { - out := fmt.Sprintf("\nRouters: (%d)\n\n", len(response.Routers)) - out += fmt.Sprintf("%-12s | %-30s | %-40s | %-9s | %s\n", "Id", "Name", "Fingerprint", "Status", "Version") - for _, r := range response.Routers { - status := "" - if r.Connected { - status += "Connected" - } - if r.ListenerAddress != "" { - status += " (" + r.ListenerAddress + ")" - } - out += fmt.Sprintf("%-12s | %-30s | %-40s | %-9s | %s\n", r.Id, r.Name, r.Fingerprint, status, r.Version) + if responseMsg.ContentType == int32(mgmt_pb.ContentType_ListRoutersResponseType) { + response := &mgmt_pb.ListRoutersResponse{} + err := proto.Unmarshal(responseMsg.Body, response) + if err == nil { + out := fmt.Sprintf("\nRouters: (%d)\n\n", len(response.Routers)) + out += fmt.Sprintf("%-12s | %-30s | %-40s | %-9s | %s\n", "Id", "Name", "Fingerprint", "Status", "Version") + for _, r := range response.Routers { + status := "" + if r.Connected { + status += "Connected" } - out += "\n" - fmt.Print(out) - - } else { - panic(err) + if r.ListenerAddress != "" { + status += " (" + r.ListenerAddress + ")" + } + out += fmt.Sprintf("%-12s | %-30s | %-40s | %-9s | %s\n", r.Id, r.Name, r.Fingerprint, status, r.Version) } - } else { - panic(errors.New("unexpected response")) - } - case <-time.After(5 * time.Second): - panic(errors.New("timeout")) - } + out += "\n" + fmt.Print(out) + } else { + panic(err) + } + } else { + panic(errors.New("unexpected response")) + } } else { panic(err) } diff --git a/ziti-fabric/subcmd/list_services.go b/ziti-fabric/subcmd/list_services.go index e8d847cf0..90a17e3e7 100644 --- a/ziti-fabric/subcmd/list_services.go +++ b/ziti-fabric/subcmd/list_services.go @@ -20,8 +20,8 @@ import ( "errors" "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/foundation/channel2" "github.com/spf13/cobra" "time" ) @@ -47,8 +47,8 @@ var listServices = &cobra.Command{ if err != nil { panic(err) } - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_ListServicesRequestType), body) - responseMsg, err := ch.SendAndWaitWithTimeout(requestMsg, 5*time.Second) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_ListServicesRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } diff --git a/ziti-fabric/subcmd/list_terminators.go b/ziti-fabric/subcmd/list_terminators.go index 82a8e5379..85d87973a 100644 --- a/ziti-fabric/subcmd/list_terminators.go +++ b/ziti-fabric/subcmd/list_terminators.go @@ -20,8 +20,8 @@ import ( "errors" "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/foundation/channel2" "github.com/spf13/cobra" "time" ) @@ -47,8 +47,8 @@ var listTerminators = &cobra.Command{ if err != nil { panic(err) } - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_ListTerminatorsRequestType), body) - responseMsg, err := ch.SendAndWaitWithTimeout(requestMsg, 5*time.Second) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_ListTerminatorsRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } diff --git a/ziti-fabric/subcmd/remove_circuit.go b/ziti-fabric/subcmd/remove_circuit.go index 17e4eecaf..a2286be6f 100644 --- a/ziti-fabric/subcmd/remove_circuit.go +++ b/ziti-fabric/subcmd/remove_circuit.go @@ -17,11 +17,10 @@ package subcmd import ( - "errors" "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/foundation/channel2" "github.com/spf13/cobra" "time" ) @@ -52,26 +51,20 @@ func removeCircuit(cmd *cobra.Command, args []string) { if err != nil { panic(err) } - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_RemoveCircuitRequestType), body) - waitCh, err := ch.SendAndWait(requestMsg) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_RemoveCircuitRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } - select { - case responseMsg := <-waitCh: - if responseMsg.ContentType == channel2.ContentTypeResultType { - result := channel2.UnmarshalResult(responseMsg) - if result.Success { - fmt.Printf("\nsuccess\n\n") - } else { - fmt.Printf("\nfailure [%s]\n\n", result.Message) - } + if responseMsg.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(responseMsg) + if result.Success { + fmt.Printf("\nsuccess\n\n") } else { - panic(fmt.Errorf("unexpected response type %v", responseMsg.ContentType)) + fmt.Printf("\nfailure [%s]\n\n", result.Message) } - - case <-time.After(5 * time.Second): - panic(errors.New("timeout")) + } else { + panic(fmt.Errorf("unexpected response type %v", responseMsg.ContentType)) } } } diff --git a/ziti-fabric/subcmd/remove_router.go b/ziti-fabric/subcmd/remove_router.go index 459956c98..a855d4c39 100644 --- a/ziti-fabric/subcmd/remove_router.go +++ b/ziti-fabric/subcmd/remove_router.go @@ -17,11 +17,10 @@ package subcmd import ( - "github.com/openziti/foundation/channel2" - "github.com/openziti/fabric/pb/mgmt_pb" - "errors" "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" + "github.com/openziti/fabric/pb/mgmt_pb" "github.com/spf13/cobra" "time" ) @@ -41,25 +40,20 @@ var removeRouter = &cobra.Command{ RouterId: args[0], } if body, err := proto.Marshal(request); err == nil { - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_RemoveRouterRequestType), body) - waitCh, err := ch.SendAndWait(requestMsg) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_RemoveRouterRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } - select { - case responseMsg := <-waitCh: - if responseMsg.ContentType == channel2.ContentTypeResultType { - result := channel2.UnmarshalResult(responseMsg) - if result.Success { - fmt.Printf("\nsuccess\n\n") - } else { - fmt.Printf("\nfailure [%s]\n\n", result.Message) - } + if responseMsg.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(responseMsg) + if result.Success { + fmt.Printf("\nsuccess\n\n") } else { - panic(fmt.Errorf("unexpected response type %v", responseMsg.ContentType)) + fmt.Printf("\nfailure [%s]\n\n", result.Message) } - case <-time.After(5 * time.Second): - panic(errors.New("timeout")) + } else { + panic(fmt.Errorf("unexpected response type %v", responseMsg.ContentType)) } } else { panic(err) diff --git a/ziti-fabric/subcmd/remove_service.go b/ziti-fabric/subcmd/remove_service.go index 5fcedba15..15b2c6666 100644 --- a/ziti-fabric/subcmd/remove_service.go +++ b/ziti-fabric/subcmd/remove_service.go @@ -19,8 +19,8 @@ package subcmd import ( "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/foundation/channel2" "github.com/spf13/cobra" "time" ) @@ -43,13 +43,13 @@ var removeService = &cobra.Command{ if err != nil { panic(err) } - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_RemoveServiceRequestType), body) - responseMsg, err := ch.SendAndWaitWithTimeout(requestMsg, 5*time.Second) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_RemoveServiceRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } - if responseMsg.ContentType == channel2.ContentTypeResultType { - result := channel2.UnmarshalResult(responseMsg) + if responseMsg.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(responseMsg) if result.Success { fmt.Printf("\nsuccess\n\n") } else { diff --git a/ziti-fabric/subcmd/remove_terminator.go b/ziti-fabric/subcmd/remove_terminator.go index 9db0b2263..b578f7f9c 100644 --- a/ziti-fabric/subcmd/remove_terminator.go +++ b/ziti-fabric/subcmd/remove_terminator.go @@ -19,8 +19,8 @@ package subcmd import ( "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/foundation/channel2" "github.com/spf13/cobra" "time" ) @@ -43,13 +43,13 @@ var removeTerminator = &cobra.Command{ if err != nil { panic(err) } - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_RemoveTerminatorRequestType), body) - responseMsg, err := ch.SendAndWaitWithTimeout(requestMsg, 5*time.Second) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_RemoveTerminatorRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } - if responseMsg.ContentType == channel2.ContentTypeResultType { - result := channel2.UnmarshalResult(responseMsg) + if responseMsg.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(responseMsg) if result.Success { fmt.Printf("\nsuccess\n\n") } else { diff --git a/ziti-fabric/subcmd/set_link_cost.go b/ziti-fabric/subcmd/set_link_cost.go index 8a615206b..1a1ce1f5c 100644 --- a/ziti-fabric/subcmd/set_link_cost.go +++ b/ziti-fabric/subcmd/set_link_cost.go @@ -17,11 +17,10 @@ package subcmd import ( - "github.com/openziti/foundation/channel2" - "github.com/openziti/fabric/pb/mgmt_pb" - "errors" "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" + "github.com/openziti/fabric/pb/mgmt_pb" "github.com/spf13/cobra" "strconv" "time" @@ -44,30 +43,24 @@ func setLinkCost(cmd *cobra.Command, args []string) { if ch, err := setLinkCostClient.Connect(); err == nil { if cost, err := strconv.Atoi(args[1]); err == nil { request := &mgmt_pb.SetLinkCostRequest{ - LinkId: args[0], - Cost: int32(cost), + LinkId: args[0], + Cost: int32(cost), } if body, err := proto.Marshal(request); err == nil { - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_SetLinkCostRequestType), body) - waitCh, err := ch.SendAndWait(requestMsg) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_SetLinkCostRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } - select { - case responseMsg := <-waitCh: - if responseMsg.ContentType == channel2.ContentTypeResultType { - result := channel2.UnmarshalResult(responseMsg) - if result.Success { - fmt.Printf("\nsuccess\n\n") - } else { - fmt.Printf("\nfailure [%s]\n\n", result.Message) - } + if responseMsg.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(responseMsg) + if result.Success { + fmt.Printf("\nsuccess\n\n") } else { - panic(fmt.Errorf("unexpected response type %v", responseMsg.ContentType)) + fmt.Printf("\nfailure [%s]\n\n", result.Message) } - - case <-time.After(5 * time.Second): - panic(errors.New("timeout")) + } else { + panic(fmt.Errorf("unexpected response type %v", responseMsg.ContentType)) } } else { panic(err) diff --git a/ziti-fabric/subcmd/set_link_down.go b/ziti-fabric/subcmd/set_link_down.go index 0f80ddb06..d80c1fc76 100644 --- a/ziti-fabric/subcmd/set_link_down.go +++ b/ziti-fabric/subcmd/set_link_down.go @@ -17,11 +17,10 @@ package subcmd import ( - "github.com/openziti/foundation/channel2" - "github.com/openziti/fabric/pb/mgmt_pb" - "errors" "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" + "github.com/openziti/fabric/pb/mgmt_pb" "github.com/spf13/cobra" "strconv" "time" @@ -48,26 +47,20 @@ func setLinkDown(cmd *cobra.Command, args []string) { Down: down, } if body, err := proto.Marshal(request); err == nil { - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_SetLinkDownRequestType), body) - waitCh, err := ch.SendAndWait(requestMsg) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_SetLinkDownRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } - select { - case responseMsg := <-waitCh: - if responseMsg.ContentType == channel2.ContentTypeResultType { - result := channel2.UnmarshalResult(responseMsg) - if result.Success { - fmt.Printf("\nsuccess\n\n") - } else { - fmt.Printf("\nfailure [%s]\n\n", result.Message) - } + if responseMsg.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(responseMsg) + if result.Success { + fmt.Printf("\nsuccess\n\n") } else { - panic(fmt.Errorf("unexpected response type %v", responseMsg.ContentType)) + fmt.Printf("\nfailure [%s]\n\n", result.Message) } - - case <-time.After(5 * time.Second): - panic(errors.New("timeout")) + } else { + panic(fmt.Errorf("unexpected response type %v", responseMsg.ContentType)) } } } else { diff --git a/ziti-fabric/subcmd/snapshot_db.go b/ziti-fabric/subcmd/snapshot_db.go index 54c6fa20d..a46e44889 100644 --- a/ziti-fabric/subcmd/snapshot_db.go +++ b/ziti-fabric/subcmd/snapshot_db.go @@ -18,8 +18,8 @@ package subcmd import ( "fmt" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/foundation/channel2" "github.com/spf13/cobra" "time" ) @@ -42,13 +42,13 @@ func snapshotDb(cmd *cobra.Command, args []string) { panic(err) } - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_SnapshotDbRequestType), nil) - responseMsg, err := ch.SendAndWaitWithTimeout(requestMsg, 5*time.Second) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_SnapshotDbRequestType), nil) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } - if responseMsg.ContentType == channel2.ContentTypeResultType { - result := channel2.UnmarshalResult(responseMsg) + if responseMsg.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(responseMsg) if result.Success { fmt.Printf("\nsuccess\n\n") } else { diff --git a/ziti-fabric/subcmd/stream_circuits.go b/ziti-fabric/subcmd/stream_circuits.go index 8fb3f8b33..583fe7536 100644 --- a/ziti-fabric/subcmd/stream_circuits.go +++ b/ziti-fabric/subcmd/stream_circuits.go @@ -17,11 +17,10 @@ package subcmd import ( - "errors" "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/mgmt_pb" - "github.com/openziti/foundation/channel2" "github.com/spf13/cobra" "time" ) @@ -39,7 +38,16 @@ var streamCircuitsCmd = &cobra.Command{ var streamCircuitsClient *mgmtClient func streamCircuits(*cobra.Command, []string) { - ch, err := streamCircuitsClient.Connect() + cw := newCloseWatcher() + + bindHandler := func(binding channel.Binding) error { + binding.AddTypedReceiveHandler(&circuitsHandler{}) + binding.AddCloseHandler(cw) + return nil + } + + ch, err := streamCircuitsClient.ConnectAndBind(channel.BindHandlerF(bindHandler)) + if err != nil { panic(err) } @@ -50,23 +58,12 @@ func streamCircuits(*cobra.Command, []string) { panic(err) } - ch.AddReceiveHandler(&circuitsHandler{}) - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_StreamCircuitsRequestType), body) - - waitCh, err := ch.SendAndSync(requestMsg) - if err != nil { + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_StreamCircuitsRequestType), body) + if err = requestMsg.WithTimeout(5 * time.Second).SendAndWaitForWire(ch); err != nil { panic(err) } - select { - case err := <-waitCh: - if err != nil { - panic(err) - } - case <-time.After(5 * time.Second): - panic(errors.New("timeout")) - } - waitForChannelClose(ch) + cw.waitForChannelClose() } type circuitsHandler struct{} @@ -75,7 +72,7 @@ func (*circuitsHandler) ContentType() int32 { return int32(mgmt_pb.ContentType_StreamCircuitsEventType) } -func (*circuitsHandler) HandleReceive(msg *channel2.Message, _ channel2.Channel) { +func (*circuitsHandler) HandleReceive(msg *channel.Message, _ channel.Channel) { event := &mgmt_pb.StreamCircuitsEvent{} err := proto.Unmarshal(msg.Body, event) if err != nil { diff --git a/ziti-fabric/subcmd/stream_helpers.go b/ziti-fabric/subcmd/stream_helpers.go index 113f67995..78af44012 100644 --- a/ziti-fabric/subcmd/stream_helpers.go +++ b/ziti-fabric/subcmd/stream_helpers.go @@ -17,25 +17,28 @@ package subcmd import ( - "github.com/openziti/foundation/channel2" "github.com/michaelquigley/pfxlog" + "github.com/openziti/channel" "sync" ) -func waitForChannelClose(ch channel2.Channel) { +func newCloseWatcher() *closeWatcher { waitGroup := &sync.WaitGroup{} waitGroup.Add(1) - - ch.AddCloseHandler(&closeWatcher{waitGroup}) - - waitGroup.Wait() + return &closeWatcher{ + waitGroup: waitGroup, + } } type closeWatcher struct { waitGroup *sync.WaitGroup } -func (watcher *closeWatcher) HandleClose(ch channel2.Channel) { +func (self *closeWatcher) HandleClose(ch channel.Channel) { pfxlog.Logger().Info("Management channel to controller closed. Shutting down.") - watcher.waitGroup.Done() + self.waitGroup.Done() +} + +func (self *closeWatcher) waitForChannelClose() { + self.waitGroup.Wait() } diff --git a/ziti-fabric/subcmd/stream_metrics.go b/ziti-fabric/subcmd/stream_metrics.go index 6d94a62f0..dbea3c5d0 100644 --- a/ziti-fabric/subcmd/stream_metrics.go +++ b/ziti-fabric/subcmd/stream_metrics.go @@ -17,13 +17,12 @@ package subcmd import ( - "github.com/openziti/foundation/channel2" - "github.com/openziti/fabric/pb/mgmt_pb" - "errors" "fmt" "github.com/golang/protobuf/proto" "github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes/timestamp" + "github.com/openziti/channel" + "github.com/openziti/fabric/pb/mgmt_pb" "github.com/spf13/cobra" "sort" "time" @@ -43,7 +42,15 @@ var streamMetricsCmd = &cobra.Command{ var streamMetricsClient *mgmtClient func streamMetrics(cmd *cobra.Command, args []string) { - ch, err := streamMetricsClient.Connect() + cw := newCloseWatcher() + + bindHandler := func(binding channel.Binding) error { + binding.AddTypedReceiveHandler(&metricsHandler{}) + binding.AddCloseHandler(cw) + return nil + } + + ch, err := streamCircuitsClient.ConnectAndBind(channel.BindHandlerF(bindHandler)) if err != nil { panic(err) } @@ -64,23 +71,12 @@ func streamMetrics(cmd *cobra.Command, args []string) { panic(err) } - ch.AddReceiveHandler(&metricsHandler{}) - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_StreamMetricsRequestType), body) - - waitCh, err := ch.SendAndSync(requestMsg) - if err != nil { + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_StreamMetricsRequestType), body) + if err = requestMsg.WithTimeout(5 * time.Second).SendAndWaitForWire(ch); err != nil { panic(err) } - select { - case err := <-waitCh: - if err != nil { - panic(err) - } - case <-time.After(5 * time.Second): - panic(errors.New("timeout")) - } - waitForChannelClose(ch) + cw.waitForChannelClose() } type metricsHandler struct{} @@ -89,7 +85,7 @@ func (*metricsHandler) ContentType() int32 { return int32(mgmt_pb.ContentType_StreamMetricsEventType) } -func (*metricsHandler) HandleReceive(msg *channel2.Message, ch channel2.Channel) { +func (*metricsHandler) HandleReceive(msg *channel.Message, ch channel.Channel) { response := &mgmt_pb.StreamMetricsEvent{} err := proto.Unmarshal(msg.Body, response) if err != nil { diff --git a/ziti-fabric/subcmd/stream_toggle_pipe_traces.go b/ziti-fabric/subcmd/stream_toggle_pipe_traces.go index b8e2ffe33..246746c21 100644 --- a/ziti-fabric/subcmd/stream_toggle_pipe_traces.go +++ b/ziti-fabric/subcmd/stream_toggle_pipe_traces.go @@ -17,12 +17,11 @@ package subcmd import ( - "github.com/openziti/foundation/channel2" - "github.com/openziti/fabric/pb/mgmt_pb" - trace_pb "github.com/openziti/foundation/trace/pb" - "errors" "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" + "github.com/openziti/fabric/pb/mgmt_pb" + trace_pb "github.com/openziti/foundation/trace/pb" "github.com/spf13/cobra" "time" ) @@ -65,26 +64,21 @@ func togglePipeTraces(cmd *cobra.Command, args []string) { } if body, err := proto.Marshal(request); err == nil { - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_TogglePipeTracesRequestType), body) - waitCh, err := ch.SendAndWait(requestMsg) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_TogglePipeTracesRequestType), body) + responseMsg, err := requestMsg.WithTimeout(5 * time.Second).SendForReply(ch) if err != nil { panic(err) } - select { - case responseMsg := <-waitCh: - if responseMsg.ContentType == channel2.ContentTypeResultType { - result := channel2.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) - } + if responseMsg.ContentType == channel.ContentTypeResultType { + result := channel.UnmarshalResult(responseMsg) + if result.Success { + fmt.Printf("\ntracing enabled successfully\n\n") + fmt.Println(result.Message) } else { - panic(fmt.Errorf("unexpected response type %v", responseMsg.ContentType)) + fmt.Printf("\ntracing enable failured [%s]\n\n", result.Message) } - case <-time.After(5 * time.Second): - panic(errors.New("timeout")) + } else { + panic(fmt.Errorf("unexpected response type %v", responseMsg.ContentType)) } } else { panic(err) diff --git a/ziti-fabric/subcmd/stream_traces.go b/ziti-fabric/subcmd/stream_traces.go index f10654d2e..17df18a9f 100644 --- a/ziti-fabric/subcmd/stream_traces.go +++ b/ziti-fabric/subcmd/stream_traces.go @@ -17,15 +17,16 @@ package subcmd import ( - "errors" + "encoding/json" "fmt" "github.com/golang/protobuf/proto" + "github.com/openziti/channel" "github.com/openziti/fabric/pb/ctrl_pb" "github.com/openziti/fabric/pb/mgmt_pb" "github.com/openziti/fabric/router/xgress" - "github.com/openziti/foundation/channel2" "github.com/openziti/foundation/trace/pb" "github.com/spf13/cobra" + "reflect" "sort" "time" ) @@ -72,7 +73,15 @@ func streamTraces(_ *cobra.Command, args []string) { } } - ch, err := streamTracesClient.Connect() + cw := newCloseWatcher() + + bindHandler := func(binding channel.Binding) error { + binding.AddTypedReceiveHandler(&traceHandler{}) + binding.AddCloseHandler(cw) + return nil + } + + ch, err := streamCircuitsClient.ConnectAndBind(channel.BindHandlerF(bindHandler)) if err != nil { panic(err) } @@ -82,22 +91,13 @@ func streamTraces(_ *cobra.Command, args []string) { panic(err) } - ch.AddReceiveHandler(&traceHandler{}) - requestMsg := channel2.NewMessage(int32(mgmt_pb.ContentType_StreamTracesRequestType), body) + requestMsg := channel.NewMessage(int32(mgmt_pb.ContentType_StreamTracesRequestType), body) - waitCh, err := ch.SendAndSync(requestMsg) - if err != nil { + if err = requestMsg.WithTimeout(5 * time.Second).SendAndWaitForWire(ch); err != nil { panic(err) } - select { - case err := <-waitCh: - if err != nil { - panic(err) - } - case <-time.After(5 * time.Second): - panic(errors.New("timeout")) - } - waitForChannelClose(ch) + + cw.waitForChannelClose() } func getContentType(name string) (int32, error) { @@ -141,7 +141,7 @@ func (*traceHandler) ContentType() int32 { return int32(mgmt_pb.ContentType_StreamTracesEventType) } -func (*traceHandler) HandleReceive(msg *channel2.Message, ch channel2.Channel) { +func (*traceHandler) HandleReceive(msg *channel.Message, _ channel.Channel) { event := &trace_pb.ChannelMessage{} err := proto.Unmarshal(msg.Body, event) if err != nil { @@ -156,10 +156,59 @@ func (*traceHandler) HandleReceive(msg *channel2.Message, ch channel2.Channel) { if event.ReplyFor != -1 { replyFor = fmt.Sprintf(">%d", event.ReplyFor) } - meta := channel2.DecodeTraceAndFormat(event.Decode) + meta := 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 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-fabric/subcmd/trace/dump.go b/ziti-fabric/subcmd/trace/dump.go index 2289ee67b..83ab4a27f 100644 --- a/ziti-fabric/subcmd/trace/dump.go +++ b/ziti-fabric/subcmd/trace/dump.go @@ -17,12 +17,13 @@ package trace import ( - "github.com/openziti/foundation/channel2" - "github.com/openziti/foundation/trace" - "github.com/openziti/foundation/trace/pb" "encoding/json" "errors" "fmt" + "github.com/openziti/channel" + "github.com/openziti/foundation/trace" + "github.com/openziti/foundation/trace/pb" + "github.com/openziti/ziti/ziti-fabric/subcmd" "github.com/spf13/cobra" ) @@ -80,7 +81,7 @@ func (h *dumpHandler) Handle(msg interface{}) error { if t.ReplyFor != -1 { replyFor = fmt.Sprintf(">%d", t.ReplyFor) } - fmt.Printf("%8s: %-16s %8s %s #%-5d %5s | %s\n", h.formatTimestamp(t.Timestamp), t.Identity, t.Channel, flow, t.Sequence, replyFor, channel2.DecodeTraceAndFormat(t.Decode)) + fmt.Printf("%8s: %-16s %8s %s #%-5d %5s | %s\n", h.formatTimestamp(t.Timestamp), t.Identity, t.Channel, flow, t.Sequence, replyFor, subcmd.DecodeTraceAndFormat(t.Decode)) } else { h.formatTimestamp(t.Timestamp) @@ -99,7 +100,7 @@ func (h *dumpHandler) formatTimestamp(timestamp int64) string { h.lastTimestamp = timestamp return "0" } - out := fmt.Sprintf("%d", (timestamp - h.lastTimestamp) / 1000) + out := fmt.Sprintf("%d", (timestamp-h.lastTimestamp)/1000) h.lastTimestamp = timestamp return out } @@ -115,13 +116,13 @@ func filterMatch(trace *trace_pb.ChannelMessage) (bool, error) { channelMatch := true if dumpCmdDecoderFilter != "" { - channelMatch = dumpCmdDecoderFilter == meta[channel2.DecoderFieldName] + channelMatch = dumpCmdDecoderFilter == meta[channel.DecoderFieldName] } messageMatch := true if dumpCmdMessageFilter != "" { - messageMatch = dumpCmdMessageFilter == meta[channel2.MessageFieldName] + messageMatch = dumpCmdMessageFilter == meta[channel.MessageFieldName] } return channelMatch && messageMatch, nil -} \ No newline at end of file +}