Skip to content

v0.17.6

Compare
Choose a tag to compare
@github-actions github-actions released this 20 Jan 19:40
· 6619 commits to release-next since this release

Release 0.17.6

What's New

  • Ziti executables that use JSON logging now emit timestamps that include fractional seconds.
    Timestamps remain in the RFC3339 format.
  • Authentication mechanisms now allow appId and appVersion in sdkInfo
  • Ziti executables that use JSON logging now emit timestamps that include fractional seconds.
    Timestamps remain in the RFC3339 format.
  • Improved query performance by caching antlr lexers and parsers. Testing showed 2x-10x performance
    improvement
  • Improve service list time by using indexes get related posture data
  • Improved service polling
  • Improved service policy enforcement - instead of polling this is now event based, which should
    result in slower cpu utlization on the controller
  • Fixed a bug in service policy PATCH which would trigger when the policy type wasn't sent
  • Support agent utilitiles (ziti ps) in ziti-tunnel
  • Cleanup ack handler goroutines when links shut down
  • The check-data-integrity operation may now only run a single instance at a time
    • To start the check, ziti edge db start-check-integrity
    • To check the status of a run ziti edge db check-integrity-status
  • The build date in version info spelling has been fixed from builDate to buildDate
  • A new metric has been added for timing service list requests services.list
  • A bug was fixed in the tunneler which may have lead to leaked connections
  • Default hosting precedence and cost can now be configured for identities
  • Health checks can now be configured for the go based tunneler (ziti-tunnel) using server configs
  • ziti#177 ziti-tunnel has a new host mode, if you
    are only hosting services
  • edge session events now contain a timestamp
  • Improve log output for invalid API Session Tokens used to connect to Edge Routers
  • Logs default to no color output
  • API Session Certificate Support Added

Improved Service Polling

There's a new REST endpoint /current-api-session/service-updates, which will return the last time
services were changed. If there have been no service updates since the api session was established,
the api session create date/time will be returned. This endpoint can be polled to see if services
need to be refreshed. This will save network and cpu utilization on the client and controller.

Setting precedence and cost for tunneler hosted services

When the tunneler hosts services there was previously no way to specify the precedence and cost
associated with those services.
See Ziti XT documentation
for an overview of how precedence and cost relate to HA and load balancing.

There are now two new fields on identity:

  • defaultHostingPrecedence - value values are default, required and failed. Defaults
    to default.
  • defaultHostingCost - valid values are between 0 and 65535. Defaults to 0.

When hosting a service via the tunneler, the terminator for the SDK hosted service will be created
with the precedence and cost of the identity used by the tunneler.

NOTE: This means all services hosted by an identity will have the same precedence and cost.
We'll likely add support for service specific overrides in the future if/when use cases arise which
call for it. In the meantime, a work-around is to use multiple identities if you need different
values for different services.

CLI Support

The ziti CLI supports setting the default hosting precedence and cost when creating identities

SDK API Change

The GO SDK has a new API method GetCurrentIdentity() (*edge.CurrentIdentity, error) which lets SDK
users retrieve the currently logged in identity, including the default hosting precedence and cost.
This could be used by other SDK applications which may want to use the fields for the same reason
when hosting services.

Tunneler Health Checks

The go tunneler now supports health checks. Support for health checks may be added to other
tunnelers (such as ziti-edge-tunnel) in the future, but that is not guaranteed.

Health checks can be configured in the service configuration using the ziti-tunneler-server.v1
config type. Support in the host.v1 config type will be added when support for that config type is
added to the go tunneler.

Check Types

The tunneler supports two types of health check.

Port Checks

Port checks look to see if a host/port can be dialed. This is simple check which just ensures that
something is listening on a give host/port.

Port checks have the following properties:

  • interval - how often the check is performanced
  • timeout - how long to wait before declaring the check failed
  • address - the address to dial. Should be of the form :. Example: localhost:5432
  • actions - an array of actions to perform based on health check results. Actions will be discussed
    in more detail below

HTTP Checks

Http checks a specific URL. They support the following properties:

  • interval - how often the check is performanced
  • timeout - how long to wait before declaring the check failed
  • url - the url to connect to
  • method - the HTTP method to use. Maybe one of GET, POST, PUT or PATCH. Defaults to GET
  • body - the body of the HTTP request. Defaults to an empty string
  • expectStatus - the HTTP status to expect in the response. Defaults to 200
  • expectBody - an optional string to look for in the response body.
  • actions - an array of actions to perform based on health check results. Actions will be discussed
    in more detail below

Health Check Actions

Each health check may specify actions to execute when a health check runs.

Each action may specify:

  • trigger - valid values pass or fail. Specifies if the action should run when the check is
    passing or failing
  • consecutiveEvents - specifies if the action should only run after N consecutive passes or fails
  • duration - specifies if the action should only run after the check has been passing or failing for
    some period of time
  • action - specifies what to do when the action is run. valid values are:
    • mark healthy - the terminator precedence will be set to the default hosting precedence of
      the hosting identity
    • mark unhealthy - the terminator precedence will be set to failed
    • increase cost N - the terminator cost will be increased by N. This will only happen while
      the terminator precedence is not failed. Once the terminator has failed we don't keep
      increasing cost, otherwise it will likely reach max cost and take a long time to recover after
      it goes back to healthy.
    • decrease cost N - the terminator cost will be decrease by N to a minimuim. The terminator
      cost will not go below the hosting identity's default hosting cost

Examples

The following config defines a TCP service which can be reach at port 8171 on localhost. It has a
port check defined which runs every 5 seconds, with a timeout of 500 milliseconds. The following
actions are defined on the health check:

  1. The terminator will be marked failed after the health check has failed 10 times in a row.
  2. The terminator cost will be increased by 100 each time the health check fails while the
    terminator is not in failed state
  3. The terminator will be returned to a non-failed state if the health check is healthy for 10
    seconds
  4. Every time the health check passes the cost will be reduced by 25, until it hits the baseline
    cost defined by the hosting identity
{
    "protocol" : "tcp",
    "hostname" : "localhost",
    "port" : 8171,
    "portChecks" : [
        {
            "interval" : "5s",
            "timeout" : "500ms",
            "address" : "localhost:8171",
            "actions": [
                {
                    "action": "mark unhealthy",
                    "consecutiveEvents": 10,
                    "trigger": "fail"
                },
                {
                    "action": "increase cost 100",
                    "trigger": "fail"
                },
                {
                    "action": "mark healthy",
                    "duration": "10s",
                    "trigger": "pass"
                },
                {
                    "action": "decrease cost 25",
                    "trigger": "pass"
                }
            ]
        }
    ]
}

ziti-tunnel host command

The ziti-tunnel can now be run in a mode where it will only host services and will not intercept any
services.

Ex: ziti-tunnel host -i /path/to/identity.json

Schema Reference

For reference, here is the full, updated ziti-tunneler-server.v1 schema:

{
    "$id": "http://edge.openziti.org/schemas/ziti-tunneler-server.v1.config.json",
    "additionalProperties": false,
    "definitions": {
        "action": {
            "additionalProperties": false,
            "properties": {
                "action": {
                    "pattern": "(mark (un)?healthy|increase cost [0-9]+|decrease cost [0-9]+)",
                    "type": "string"
                },
                "consecutiveEvents": {
                    "maximum": 65535,
                    "minimum": 0,
                    "type": "integer"
                },
                "duration": {
                    "$ref": "#/definitions/duration"
                },
                "trigger": {
                    "enum": [
                        "fail",
                        "pass"
                    ],
                    "type": "string"
                }
            },
            "required": [
                "trigger",
                "action"
            ],
            "type": "object"
        },
        "actionList": {
            "items": {
                "$ref": "#/definitions/action"
            },
            "maxItems": 20,
            "minItems": 1,
            "type": "array"
        },
        "duration": {
            "pattern": "[0-9]+(h|m|s|ms)",
            "type": "string"
        },
        "httpCheck": {
            "additionalProperties": false,
            "properties": {
                "actions": {
                    "$ref": "#/definitions/actionList"
                },
                "body": {
                    "type": "string"
                },
                "expectInBody": {
                    "type": "string"
                },
                "expectStatus": {
                    "maximum": 599,
                    "minimum": 100,
                    "type": "integer"
                },
                "interval": {
                    "$ref": "#/definitions/duration"
                },
                "method": {
                    "$ref": "#/definitions/method"
                },
                "timeout": {
                    "$ref": "#/definitions/duration"
                },
                "url": {
                    "type": "string"
                }
            },
            "required": [
                "interval",
                "timeout",
                "url"
            ],
            "type": "object"
        },
        "httpCheckList": {
            "items": {
                "$ref": "#/definitions/httpCheck"
            },
            "type": "array"
        },
        "method": {
            "enum": [
                "GET",
                "POST",
                "PUT",
                "PATCH"
            ],
            "type": "string"
        },
        "portCheck": {
            "additionalProperties": false,
            "properties": {
                "actions": {
                    "$ref": "#/definitions/actionList"
                },
                "address": {
                    "type": "string"
                },
                "interval": {
                    "$ref": "#/definitions/duration"
                },
                "timeout": {
                    "$ref": "#/definitions/duration"
                }
            },
            "required": [
                "interval",
                "timeout",
                "address"
            ],
            "type": "object"
        },
        "portCheckList": {
            "items": {
                "$ref": "#/definitions/portCheck"
            },
            "type": "array"
        }
    },
    "properties": {
        "hostname": {
            "type": "string"
        },
        "httpChecks": {
            "$ref": "#/definitions/httpCheckList"
        },
        "port": {
            "maximum": 65535,
            "minimum": 0,
            "type": "integer"
        },
        "portChecks": {
            "$ref": "#/definitions/portCheckList"
        },
        "protocol": {
            "enum": [
                "tcp",
                "udp"
            ],
            "type": [
                "string",
                "null"
            ]
        }
    },
    "required": [
        "hostname",
        "port"
    ],
    "type": "object"
}

Logs default to no color output

Logs generated by Ziti components written in Go (Controller, Router, SDK) will no longer output ANSI
color control characters by default. Color logs can be enabled by setting in the environment
variable PFXLOG_USE_COLOR to any truthy value: 1, t, T, TRUE, true, True, 0, f, F, FALSE, false,
False.

API Session Certificate Support Added

All authentication mechanisms can now bootstrap key pairs via an authenticated session using API
Session Certificates. These key pairs involve authenticating, preparing an X509 Certificate Signing
Request (CSR), and then submitting the CSR for processing. The output is an ephemeral certificate
tied to that session that can be used to connect to Edge Routers for session dial/binds.

New Endpoints:

  • current-api-session/certificates
    • GET - lists current API Session Certificates
    • POST - create a new API Session Certificate (accepts a JSON payload with a csr field)
  • current-api-session/certificates/
    • GET - retrieves a specific API Session Certificate
    • DELETE - removes a specific API Session Certificate

API Session Certificates have a 12hr life span. New certificates can be created before previous ones
expire and be used for reconnection.