diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 490c07905..10fec44a1 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -89,9 +89,8 @@ jobs: fablab-smoketest: name: Fablab Smoketest + if: github.repository_owner == 'openziti' runs-on: ubuntu-20.04 - outputs: - ZITI_VERSION: ${{ steps.get_version.outputs.ZITI_VERSION }} steps: - name: Git Checkout uses: actions/checkout@v3 @@ -154,7 +153,7 @@ jobs: # END linux-build-steps publish: - name: Publish Binaries and Docker Image + name: Publish Binaries runs-on: ubuntu-20.04 needs: [ mac-os-build, windows-build, fablab-smoketest ] outputs: @@ -193,6 +192,14 @@ jobs: 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 ./... + # upload Linux artifacts so we can copy them into a container image in another workflow + - name: Upload artifacts + uses: actions/upload-artifact@v3 + with: + name: linux-release-${{ github.run_id }} + path: release/ + retention-days: 5 + - name: Download darwin release artifact uses: actions/download-artifact@v3 with: @@ -210,9 +217,9 @@ jobs: with: version: 1.51.1 - # remaining steps in job only run on the upstream repo, not forks - - name: Publish - if: github.repository_owner == 'openziti' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-v')) + - name: Publish GitHub Release + # forks need to run this step with their own GPG key because ziti-ci creates the GH release + if: env.ziti_ci_gpg_key_id != null && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-v')) env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ziti_ci_gpg_key: ${{ secrets.ZITI_CI_GPG_KEY }} @@ -255,55 +262,6 @@ jobs: JFROG_API_KEY: ${{ secrets.JFROG_API_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Set up QEMU - if: github.repository_owner == 'openziti' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-v')) - uses: docker/setup-qemu-action@v2 - with: - platforms: amd64,arm64,arm - - - name: Set up Docker BuildKit - if: github.repository_owner == 'openziti' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-v')) - id: buildx - uses: docker/setup-buildx-action@v2 - - - name: Login to Docker Hub - if: github.repository_owner == 'openziti' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-v')) - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKER_HUB_API_USER }} - password: ${{ secrets.DOCKER_HUB_API_TOKEN }} - - - name: Set up Docker image tags - if: github.repository_owner == 'openziti' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-v')) - env: - SNAPSHOT_REPO: openziti/ziti-tunnel - RELEASE_REPO: netfoundry/ziti-tunnel - ZITI_VERSION: ${{ steps.get_version.outputs.ZITI_VERSION }} - id: tagprep - run: | - # the Docker cross-build only runs on branches main or release-v* - # where ziti-ci always computes and publishes a new release tag - DOCKER_TAGS="" - for REPO in ${SNAPSHOT_REPO} ${RELEASE_REPO}; do - DOCKER_TAGS+=",${REPO}:${ZITI_VERSION},${REPO}:latest" - done - DOCKER_TAGS=${DOCKER_TAGS#,} # drop leading comma char - echo "DEBUG: DOCKER_TAGS=${DOCKER_TAGS}" - echo DOCKER_TAGS="${DOCKER_TAGS}" >> $GITHUB_OUTPUT - - - name: Build & Push Multi-Platform Container Image to Hub - if: github.repository_owner == 'openziti' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-v')) - uses: docker/build-push-action@v3 - with: - builder: ${{ steps.buildx.outputs.name }} - context: ${{ github.workspace }} # build context is workspace so we can copy artifacts from ./release - file: ${{ github.workspace }}/ziti-tunnel/docker/Dockerfile.copy # a Dockerfile that does copy instead of fetch - build-args: | # base dir for copy/add operations should be dir containing Dockerfile - DOCKER_BUILD_DIR=./ziti-tunnel/docker - platforms: linux/amd64,linux/arm/v7,linux/arm64 - push: true - tags: ${{ steps.tagprep.outputs.DOCKER_TAGS }} - jenkins-smoketest: # BEGIN smoketest-job # @@ -311,7 +269,18 @@ jobs: # needs: publish name: Call the On-Demand Smoketest Workflow + # not applicable to forks + if: github.repository_owner == 'openziti' uses: ./.github/workflows/jenkins-smoketest.yml secrets: inherit with: ziti-version: ${{ needs.publish.outputs.ZITI_VERSION }} + + call-publish-docker-images: + if: github.ref == 'refs/heads/main' + name: Publish Docker Images + needs: publish + uses: ./.github/workflows/publish-docker-images.yml + secrets: inherit + with: + ziti-version: ${{ needs.publish.outputs.ZITI_VERSION }} diff --git a/.github/workflows/mattermost-webhook.yml b/.github/workflows/mattermost-webhook.yml index a214230f6..c38096299 100644 --- a/.github/workflows/mattermost-webhook.yml +++ b/.github/workflows/mattermost-webhook.yml @@ -15,7 +15,7 @@ jobs: mattermost-ziti-webhook: runs-on: ubuntu-latest name: POST Webhook - if: github.actor != 'dependabot[bot]' + if: github.repository_owner == 'openziti' && github.actor != 'dependabot[bot]' env: ZITI_LOG: 99 ZITI_NODEJS_LOG: 99 diff --git a/.github/workflows/publish-docker-images.yml b/.github/workflows/publish-docker-images.yml new file mode 100644 index 000000000..1596cb61f --- /dev/null +++ b/.github/workflows/publish-docker-images.yml @@ -0,0 +1,134 @@ +name: CI build + +on: + workflow_call: + inputs: + ziti-version: + description: 'Ziti Release Version' + type: string + required: true + +jobs: + publish-docker-images: + runs-on: ubuntu-latest + env: + ZITI_VERSION: ${{ inputs.ziti-version || github.event.inputs.ziti-version }} + steps: + - name: Checkout Workspace + uses: actions/checkout@v3 + + - name: Download Linux Release Artifacts + uses: actions/download-artifact@v3 + with: + name: linux-release-${{ github.run_id }} + path: release/ + + - name: Set Up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: amd64,arm64 + + - name: Set Up Docker BuildKit + id: buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_HUB_API_USER }} + password: ${{ secrets.DOCKER_HUB_API_TOKEN }} + + - name: Set Up Container Image Tags for Base CLI Container + env: + RELEASE_REPO: openziti/ziti-cli + id: tagprep_cli + run: | + DOCKER_TAGS="" + DOCKER_TAGS="${RELEASE_REPO}:${ZITI_VERSION},${RELEASE_REPO}:latest" + echo "DEBUG: DOCKER_TAGS=${DOCKER_TAGS}" + echo DOCKER_TAGS="${DOCKER_TAGS}" >> $GITHUB_OUTPUT + + # this is the base image into which is stuffed the Linux binary for each + # arch that was downloaded in ./release/, hence the need to specify the + # Dockerfile and DOCKER_BUILD_DIR + - name: Build & Push Multi-Platform CLI Container Image to Hub + uses: docker/build-push-action@v3 + with: + builder: ${{ steps.buildx.outputs.name }} + context: ${{ github.workspace }}/ + file: ${{ github.workspace }}/docker-images/ziti-cli/Dockerfile + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.tagprep_cli.outputs.DOCKER_TAGS }} + build-args: | + DOCKER_BUILD_DIR=./docker-images/ziti-cli + push: true + + - name: Set Up Container Image Tags for Controller Container + env: + RELEASE_REPO: openziti/ziti-controller + id: tagprep_ctrl + run: | + DOCKER_TAGS="" + DOCKER_TAGS="${RELEASE_REPO}:${ZITI_VERSION},${RELEASE_REPO}:latest" + echo "DEBUG: DOCKER_TAGS=${DOCKER_TAGS}" + echo DOCKER_TAGS="${DOCKER_TAGS}" >> $GITHUB_OUTPUT + + # This is a use-case image based on the minimal CLI image. It needs the + # ZITI_VERSION env var so it can build from the versioned image that + # we pushed in the prior step. + - name: Build & Push Multi-Platform Controller Container Image to Hub + uses: docker/build-push-action@v3 + with: + builder: ${{ steps.buildx.outputs.name }} + context: ${{ github.workspace }}/docker-images/ziti-controller/ + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.tagprep_ctrl.outputs.DOCKER_TAGS }} + build-args: | + ZITI_VERSION=${{ env.ZITI_VERSION }} + push: true + + - name: Set Up Container Image Tags for Router Container + env: + RELEASE_REPO: openziti/ziti-router + id: tagprep_router + run: | + DOCKER_TAGS="" + DOCKER_TAGS="${RELEASE_REPO}:${ZITI_VERSION},${RELEASE_REPO}:latest" + echo "DEBUG: DOCKER_TAGS=${DOCKER_TAGS}" + echo DOCKER_TAGS="${DOCKER_TAGS}" >> $GITHUB_OUTPUT + + - name: Build & Push Multi-Platform Router Container Image to Hub + uses: docker/build-push-action@v3 + with: + builder: ${{ steps.buildx.outputs.name }} + context: ${{ github.workspace }}/docker-images/ziti-router/ + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.tagprep_router.outputs.DOCKER_TAGS }} + build-args: | + ZITI_VERSION=${{ env.ZITI_VERSION }} + push: true + + - name: Set Up Container Image Tags for Go Tunneler Container + env: + SNAPSHOT_REPO: netfoundry/ziti-tunnel + RELEASE_REPO: openziti/ziti-tunnel + id: tagprep_tun + run: | + DOCKER_TAGS="" + for REPO in ${SNAPSHOT_REPO} ${RELEASE_REPO}; do + DOCKER_TAGS+=",${REPO}:${ZITI_VERSION},${REPO}:latest" + done + DOCKER_TAGS=${DOCKER_TAGS#,} # drop leading comma char + echo "DEBUG: DOCKER_TAGS=${DOCKER_TAGS}" + echo DOCKER_TAGS="${DOCKER_TAGS}" >> $GITHUB_OUTPUT + + - name: Build & Push Multi-Platform Go Tunneler Container Image to Hub + uses: docker/build-push-action@v3 + with: + builder: ${{ steps.buildx.outputs.name }} + context: ${{ github.workspace }}/docker-images/ziti-tunnel/ + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.tagprep_tun.outputs.DOCKER_TAGS }} + build-args: | + ZITI_VERSION=${{ env.ZITI_VERSION }} + push: true diff --git a/docker-images/ziti-cli/Dockerfile b/docker-images/ziti-cli/Dockerfile new file mode 100644 index 000000000..e5b49cfdf --- /dev/null +++ b/docker-images/ziti-cli/Dockerfile @@ -0,0 +1,34 @@ +# this builds docker.io/openziti/ziti-cli +FROM registry.access.redhat.com/ubi8/ubi-minimal +# This build stage grabs artifacts that are copied into the final image. +# It uses the same base as the final image to maximize docker cache hits. + +ARG ARTIFACTS_DIR=./release +ARG DOCKER_BUILD_DIR=. +# e.g. linux +ARG TARGETOS +# e.g. arm64 +ARG TARGETARCH + +### Required OpenShift Labels +LABEL name="openziti/ziti-cli" \ + maintainer="developers@openziti.org" \ + vendor="NetFoundry" \ + summary="Run the OpenZiti CLI" \ + description="Run the OpenZiti CLI" + +USER root + +### add licenses to this directory +RUN mkdir -m0755 /licenses +COPY ./LICENSE /licenses/apache.txt + +RUN mkdir -p /usr/local/bin +COPY ${ARTIFACTS_DIR}/${TARGETARCH}/${TARGETOS}/ziti /usr/local/bin/ +RUN chmod 0755 /usr/local/bin/ziti + +COPY ${DOCKER_BUILD_DIR}/entrypoint.sh / +RUN chmod +x /entrypoint.sh +USER nobody +ENTRYPOINT [ "/entrypoint.sh" ] +CMD [ "ziti" ] diff --git a/docker-images/ziti-cli/entrypoint.sh b/docker-images/ziti-cli/entrypoint.sh new file mode 100644 index 000000000..e6d33f04c --- /dev/null +++ b/docker-images/ziti-cli/entrypoint.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -euo pipefail + +exec ziti "${@}" diff --git a/docker-images/ziti-controller/Dockerfile b/docker-images/ziti-controller/Dockerfile new file mode 100644 index 000000000..900b59ab5 --- /dev/null +++ b/docker-images/ziti-controller/Dockerfile @@ -0,0 +1,20 @@ +ARG ZITI_VERSION="latest" +# this builds docker.io/openziti/ziti-controller +FROM docker.io/openziti/ziti-cli:${ZITI_VERSION} + +# This build stage grabs artifacts that are copied into the final image. +# It uses the same base as the final image to maximize docker cache hits. + +### Required OpenShift Labels +LABEL name="openziti/ziti-controller" \ + maintainer="developers@openziti.org" \ + vendor="NetFoundry" \ + summary="Run the OpenZiti Controller" \ + description="Run the OpenZiti Controller" + +USER root +COPY ./entrypoint.sh / +RUN chmod +x /entrypoint.sh +USER nobody +ENTRYPOINT [ "/entrypoint.sh" ] +CMD [ "run" ] diff --git a/docker-images/ziti-controller/entrypoint.sh b/docker-images/ziti-controller/entrypoint.sh new file mode 100644 index 000000000..cb055cc80 --- /dev/null +++ b/docker-images/ziti-controller/entrypoint.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -euo pipefail + +exec ziti controller "${@}" diff --git a/docker-images/ziti-router/Dockerfile b/docker-images/ziti-router/Dockerfile new file mode 100644 index 000000000..5dba0585f --- /dev/null +++ b/docker-images/ziti-router/Dockerfile @@ -0,0 +1,20 @@ +ARG ZITI_VERSION="latest" +# this builds docker.io/openziti/ziti-router +FROM docker.io/openziti/ziti-cli:${ZITI_VERSION} + +# This build stage grabs artifacts that are copied into the final image. +# It uses the same base as the final image to maximize docker cache hits. + +### Required OpenShift Labels +LABEL name="openziti/ziti-router" \ + maintainer="developers@openziti.org" \ + vendor="NetFoundry" \ + summary="Run the OpenZiti Router" \ + description="Run the OpenZiti Router" + +USER root +COPY ./entrypoint.sh / +RUN chmod +x /entrypoint.sh +USER nobody +ENTRYPOINT [ "/entrypoint.sh" ] +CMD [ "run" ] diff --git a/docker-images/ziti-router/entrypoint.sh b/docker-images/ziti-router/entrypoint.sh new file mode 100644 index 000000000..8bb695e7a --- /dev/null +++ b/docker-images/ziti-router/entrypoint.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -euo pipefail + +exec ziti router "${@}" diff --git a/docker-images/ziti-tunnel/Dockerfile b/docker-images/ziti-tunnel/Dockerfile new file mode 100644 index 000000000..299c9e4b4 --- /dev/null +++ b/docker-images/ziti-tunnel/Dockerfile @@ -0,0 +1,24 @@ +ARG ZITI_VERSION="latest" +# this builds docker.io/openziti/ziti-router +FROM docker.io/openziti/ziti-cli:${ZITI_VERSION} + +# This build stage grabs artifacts that are copied into the final image. +# It uses the same base as the final image to maximize docker cache hits. + +### Required OpenShift Labels +LABEL name="openziti/ziti-tunnel" \ + maintainer="developers@openziti.org" \ + vendor="NetFoundry" \ + summary="Run the OpenZiti Go Tunneler" \ + description="Run the OpenZiti Go Tunneler" + +### Add necessary Red Hat repos and packages: "mountpoint" used by entrypoint +USER root +RUN INSTALL_PKGS="util-linux iptables" && \ + microdnf -y update --setopt=install_weak_deps=0 --setopt=tsflags=nodocs && \ + microdnf -y install --setopt=install_weak_deps=0 --setopt=tsflags=nodocs ${INSTALL_PKGS} + +COPY ./entrypoint.sh / +RUN chmod +x /entrypoint.sh +ENTRYPOINT [ "/entrypoint.sh" ] +CMD [ "run" ] diff --git a/docker-images/ziti-tunnel/entrypoint.sh b/docker-images/ziti-tunnel/entrypoint.sh new file mode 100755 index 000000000..ffae02c8d --- /dev/null +++ b/docker-images/ziti-tunnel/entrypoint.sh @@ -0,0 +1,165 @@ +#!/usr/bin/env bash + +# +# Copyright 2023 NetFoundry Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +set -e -u -o pipefail + +function alldone() { + # if successfully sent to background then send SIGTERM to trigger a cleanup + # of resolver config, tun devices and associated routes + [[ "${ZITI_TUNNEL_PID:-}" =~ ^[0-9]+$ ]] && { + kill -TERM "$ZITI_TUNNEL_PID" + # let entrypoint script exit after ziti tunnel PID + kill -0 "$ZITI_TUNNEL_PID" && wait "$ZITI_TUNNEL_PID" + } +} +trap alldone SIGTERM SIGINT EXIT + +IDENTITIES_DIR="/netfoundry" +if ! [[ -d "${IDENTITIES_DIR}" ]]; then + echo "ERROR: need directory ${IDENTITIES_DIR} to find tokens and identities" >&2 + exit 1 +fi + +if ! mountpoint "${IDENTITIES_DIR}" &>/dev/null; then + echo "WARN: the identities directory is only available inside this container because ${IDENTITIES_DIR} is not a mounted volume. Be careful to not publish this image with identity inside or lose access to the identity by removing the image prematurely." >&2 +else + if [[ -n "${ZITI_IDENTITY_JSON:-}" ]]; then + echo "WARNING: you supplied the Ziti identity as an env var and you mounted a volume on the identities dir. You may avoid this warning and future errors by not mounting a volume on ${IDENTITIES_DIR} when ZITI_IDENTITY_JSON is defined." >&2 + fi +fi + +# +## Map the preferred, Ziti var names to legacy NF names. This allows us to begin using the preferred vars right away +## while minimizing immediate differences to the main control structure. This eases code review. Later, the legacy +## names can be retired and replaced. +# +if [[ -n "${ZITI_IDENTITY_BASENAME:-}" ]]; then + echo "INFO: setting NF_REG_NAME to \${ZITI_IDENTITY_BASENAME} (${ZITI_IDENTITY_BASENAME})" + NF_REG_NAME="${ZITI_IDENTITY_BASENAME}" +fi +if [[ -n "${ZITI_ENROLL_TOKEN:-}" ]]; then + echo "INFO: setting NF_REG_TOKEN to \${ZITI_ENROLL_TOKEN} (${ZITI_ENROLL_TOKEN})" + NF_REG_TOKEN="${ZITI_ENROLL_TOKEN}" +fi +if [[ -n "${ZITI_IDENTITY_WAIT:-}" ]]; then + echo "INFO: setting NF_REG_WAIT to \${ZITI_IDENTITY_WAIT} (${ZITI_IDENTITY_WAIT})" + NF_REG_WAIT="${ZITI_IDENTITY_WAIT}" +fi + +# treat IOTEDGE_DEVICEID, a standard var assigned by Azure IoT, as an alias for NF_REG_NAME +if [[ -z "${NF_REG_NAME:-}" ]]; then + if [[ -n "${IOTEDGE_DEVICEID:-}" ]]; then + echo "INFO: setting NF_REG_NAME to \${IOTEDGE_DEVICEID} (${IOTEDGE_DEVICEID})" + NF_REG_NAME="${IOTEDGE_DEVICEID}" + fi +fi + +# if identity JSON var is defined then write to a file +if [[ -n "${ZITI_IDENTITY_JSON:-}" ]]; then + # if the basename is not defined then use a default basename to write JSON to a file + if [[ -z "${NF_REG_NAME:-}" ]]; then + NF_REG_NAME="ziti_id" + fi + if [[ -s "${IDENTITIES_DIR}/${NF_REG_NAME}.json" ]]; then + echo "ERROR: refusing to clobber non-empty Ziti identity file ${NF_REG_NAME}.json with contents of env var ZITI_IDENTITY_JSON!" >&2 + exit 1 + else + echo "${ZITI_IDENTITY_JSON}" > "${IDENTITIES_DIR}/${NF_REG_NAME}.json" + fi +fi + +typeset -a TUNNEL_OPTS +# if identity file, else multiple identities dir +if [[ -n "${NF_REG_NAME:-}" ]]; then + IDENTITY_FILE="${IDENTITIES_DIR}/${NF_REG_NAME}.json" + TUNNEL_OPTS=("--identity" "${IDENTITY_FILE}") + : ${NF_REG_WAIT:=1} + if [[ "${NF_REG_WAIT}" =~ ^[0-9]+$ ]]; then + echo "DEBUG: waiting ${NF_REG_WAIT}s for ${IDENTITY_FILE} (or token) to appear" + elif (( "${NF_REG_WAIT}" < 0 )); then + echo "DEBUG: waiting forever for ${IDENTITY_FILE} (or token) to appear" + else + echo "ERROR: need integer for NF_REG_WAIT" >&2 + exit 1 + fi + while (( $NF_REG_WAIT > 0 || $NF_REG_WAIT < 0)); do + # if non-empty identity file + if [[ -s "${IDENTITY_FILE}" ]]; then + echo "INFO: found identity file ${IDENTITY_FILE}" + break 1 + # look for enrollment token + else + echo "INFO: identity file ${IDENTITY_FILE} does not exist" + for dir in "/var/run/secrets/netfoundry.io/enrollment-token" \ + "/enrollment-token" \ + "${IDENTITIES_DIR}"; do + JWT_CANDIDATE="${dir}/${NF_REG_NAME}.jwt" + echo "INFO: looking for ${JWT_CANDIDATE}" + if [[ -s "${JWT_CANDIDATE}" ]]; then + JWT_FILE="${JWT_CANDIDATE}" + break 1 + fi + done + if [[ -n "${JWT_FILE:-}" ]]; then + echo "INFO: enrolling ${JWT_FILE}" + ziti edge enroll --jwt "${JWT_FILE}" --out "${IDENTITY_FILE}" || { + echo "ERROR: failed to enroll with token from ${JWT_FILE} ($(wc -c < "${JWT_FILE}")B)" >&2 + exit 1 + } + elif [[ -n "${NF_REG_TOKEN:-}" ]]; then + echo "INFO: attempting enrollment with NF_REG_TOKEN" + if [[ -s "${IDENTITIES_DIR}/${NF_REG_NAME}.jwt" ]]; then + echo "ERROR: refusing to clobber non-empty enrollment OTP file ${NF_REG_NAME}.jwt with contents of env var NF_REG_TOKEN!" >&2 + exit 1 + else + echo "${NF_REG_TOKEN}" > "${IDENTITIES_DIR}/${NF_REG_NAME}.jwt" + fi + ziti edge enroll --jwt "${IDENTITIES_DIR}/${NF_REG_NAME}.jwt" --out "${IDENTITY_FILE}" || { + echo "ERROR: failed to enroll with token from NF_REG_TOKEN ($(wc -c <<<"${NF_REG_TOKEN}")B)" >&2 + exit 1 + } + fi + fi + # decrement the wait seconds until zero or forever if negative + (( NF_REG_WAIT-- )) + sleep 1 + done +else + typeset -a JSON_FILES + mapfile -t JSON_FILES < <(ls -1 "${IDENTITIES_DIR}"/*.json) + if [[ ${#JSON_FILES[*]} -gt 0 ]]; then + echo "INFO: NF_REG_NAME not set, loading ${#JSON_FILES[*]} identities from ${IDENTITIES_DIR}" + TUNNEL_OPTS=("--identity-dir" "${IDENTITIES_DIR}") + else + echo "ERROR: NF_REG_NAME not set and zero identities found in ${IDENTITIES_DIR}" >&2 + exit 1 + fi +fi + +echo "DEBUG: evaluating positionals: $*" +if (( ${#} )) && [[ ${1} =~ t?proxy|host ]]; then + TUNNEL_RUN_MODE=${1} + shift +else + TUNNEL_RUN_MODE=run +fi + +echo "INFO: running \"ziti tunnel ${TUNNEL_RUN_MODE} ${TUNNEL_OPTS[*]} ${*}\"" +ziti tunnel "${TUNNEL_RUN_MODE}" "${TUNNEL_OPTS[@]}" "${@}" & +ZITI_TUNNEL_PID=$! +wait $ZITI_TUNNEL_PID diff --git a/ziti-tunnel/docker/.gitignore b/ziti-tunnel/docker/.gitignore deleted file mode 100644 index 0cf75dfd8..000000000 --- a/ziti-tunnel/docker/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -# enrollments in-use with Docker Compose -*.json -*.jwt - -# executable from fetch bins script -/ziti-tunnel diff --git a/ziti-tunnel/docker/BUILD.md b/ziti-tunnel/docker/BUILD.md deleted file mode 100644 index 95f8c9b86..000000000 --- a/ziti-tunnel/docker/BUILD.md +++ /dev/null @@ -1,112 +0,0 @@ -The Dockerfile and scripts in this directory build a `ziti-tunnel` (Go tunneler) Docker image. This procedure is highly similar to that of the `ziti-edge-tunnel` (C tunneler) Docker image [documented here](https://github.com/openziti/ziti-tunnel-sdk-c/blob/main/docker/BUILD.md). - -Ziti binaries are downloaded from https://netfoundry.artifactory.io/netfoundry/ziti-release -by default. The following build arguments are supported: - - | Build Argument | Description | - | -------------------- | ----------------------------------------------------------------- | - | ZITI_VERSION | The version of the ziti binaries to fetch from artifactory. | - | ARTIFACTORY_TOKEN | An Artifactory token with read access to the artifact repository. This is not needed if using the default ARTIFACTORY_BASE_URL / ARTIFACTORY_REPO. | - | ARTIFACTORY_BASE_URL | Defaults to "https://netfoundry.jfrog.io/netfoundry". | - | ARTIFACTORY_REPO | Defaults to "ziti-release". | - -# Building multi-platform Images - -Use this build method if you're pushing the ziti-tunnel image to a public image -registry. - -This build method creates images for the amd64 and arm/v7 platforms, but it -requires experimental Docker features and may involve more setup than you're -willing to endure. See "Building for Development" if you just want to build the -ziti-tunnel image for use on your local workstation, and don't plan on pushing -the image to a public registry. - -## Prerequisites - -1. Enable Docker Experimental Features - - See https://docs.docker.com/engine/reference/commandline/cli/#experimental-features - -2. Install & Enable qemu Emulation for Arm (Docker CE / Linux only) - - This is taken care of by Docker Desktop if you're building on macOS or Windows, - but you'll need to install qemu emulation support and register Arm binaries to - run on your (presumably) x86_64 build host if you are running Docker CE on Linux: - - $ sudo dnf install -y qemu-system-arm - $ docker run --rm --privileged docker/binfmt:66f9012c56a8316f9244ffd7622d7c21c1f6f28d - - Verify that the Arm qemu handler is registered: - - $ cat /proc/sys/fs/binfmt_misc/qemu-arm - enabled - interpreter /usr/bin/qemu-arm - ... - - Ensure that the first line of the file is "enabled". - -3. Create a Builder Instance - - $ docker buildx create --use --name=ziti-builder - -## Building - -Run `docker buildx` like this: - - $ ziti_version="0.19.11" - $ docker buildx build \ - --platform linux/amd64,linux/arm/v7,linux/aarch64 \ - --build-arg ZITI_VERSION="${ziti_version}" \ - -t "netfoundry/ziti-tunnel:${ziti_version}" . - -Notes: - -- You'll need to append "--push" to this command, and then subsequently pull the - image to be able to use the image locally. - - Unfortunately `buildx` doesn't currently support building images directly into - the local docker cache. Although the `--load` and `--output=type=docker` options - exist, the underlying capability to load a multi-platform image (OCI) will be - implemented in a future Docker release (see https://github.com/docker/buildx/issues/59). - In the meantime, you'll need to push your image builds (with the `--push` build option) - and then pull them to run the image locally when building with `buildx`. - -- The armv8 image uses armv7 (32-bit) ziti executables. The 32-bit compatibility - libraries are installed in the image, but your Arm CPU must support 32-bit emulation. - -## References: - -- -- -- -- - -# Building for Development - -This build method produces an image for the CPU that is running the build host -(typically amd64), and places the resulting image into your local Docker image -cache. - - $ git fetch --tags && git tag -l | sort -Vr | head -1 - v0.19.11 - $ ziti_version="0.19.11" \ - $ docker build \ - --build-arg ZITI_VERSION="${ziti_version}" \ - -t "netfoundry/ziti-tunnel:${ziti_version}" . - -## Shell Script for Linux - - $ ./buildx.sh -h - Usage: VARIABLES ./buildx.sh [OPTION]... - - Build multi-platform Docker container image on Linux. - - VARIABLES - ZITI_VERSION e.g. "0.16.1" corresponding to Git tag "v0.16.1" - - OPTIONS - -r REPO container image repository e.g. netfoundry/ziti-edge-tunnel - -c don't check out v${ZITI_VERSION} (use Git working copy) - - EXAMPLES - ZITI_VERSION=0.19.11 ./buildx.sh -r netfoundry/ziti-tunnel diff --git a/ziti-tunnel/docker/Dockerfile b/ziti-tunnel/docker/Dockerfile deleted file mode 100644 index 9071733db..000000000 --- a/ziti-tunnel/docker/Dockerfile +++ /dev/null @@ -1,38 +0,0 @@ -FROM debian:buster-slim as fetch-ziti-artifacts - -# This build stage grabs artifacts that are copied into the final image. -# It uses the same base as the final image to maximize docker cache hits. - -ARG ZITI_VERSION - -ARG ARTIFACTORY_TOKEN -ARG ARTIFACTORY_BASE_URL="https://netfoundry.jfrog.io/netfoundry" -# to fetch snapshots from the "feature-0.5" branch, set ZITI_REPO="ziti-snapshot/feature-0.5" -ARG ARTIFACTORY_REPO="ziti-release" - -WORKDIR /tmp - -RUN apt-get -q update && apt-get -q install -y --no-install-recommends curl ca-certificates -# workaround for `openssl rehash` not working on arm. -RUN /bin/bash -c "if ! compgen -G '/etc/ssl/certs/*.[0-9]' > /dev/null; then c_rehash /etc/ssl/certs; fi" - -COPY fetch-ziti-bins.sh . -RUN bash ./fetch-ziti-bins.sh ziti-tunnel - -################ -# -# Main Image -# -################ - -FROM debian:buster-slim - -RUN mkdir -p /usr/local/bin /etc/ssl/certs -RUN apt-get -q update && apt-get -q install -y --no-install-recommends iptables -COPY --from=fetch-ziti-artifacts /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs -COPY --from=fetch-ziti-artifacts /tmp/ziti-tunnel /usr/local/bin -COPY ./docker-entrypoint.sh / -RUN chmod +x /docker-entrypoint.sh - -ENTRYPOINT [ "/docker-entrypoint.sh" ] -CMD [ "run" ] diff --git a/ziti-tunnel/docker/Dockerfile.copy b/ziti-tunnel/docker/Dockerfile.copy deleted file mode 100644 index b75fb84ad..000000000 --- a/ziti-tunnel/docker/Dockerfile.copy +++ /dev/null @@ -1,41 +0,0 @@ -FROM debian:buster-slim as fetch-ziti-artifacts - -# This build stage grabs artifacts that are copied into the final image. -# It uses the same base as the final image to maximize docker cache hits. - -ARG ARTIFACTS_DIR=./release -# e.g. linux -ARG TARGETOS -# e.g. arm -ARG TARGETARCH -# e.g. v7 (OS variant) -# TARGETVARIANT - -WORKDIR /tmp - -RUN apt-get -q update && apt-get -q install -y --no-install-recommends curl ca-certificates -# workaround for `openssl rehash` not working on arm. -RUN /bin/bash -c "if ! compgen -G '/etc/ssl/certs/*.[0-9]' > /dev/null; then c_rehash /etc/ssl/certs; fi" - -COPY ${ARTIFACTS_DIR}/${TARGETARCH}/${TARGETOS}/ziti-tunnel . - -################ -# -# Main Image -# -################ - -FROM debian:buster-slim - -ARG DOCKER_BUILD_DIR=. -ARG ZITI_TUNNELER_BIN=ziti-tunnel - -RUN mkdir -p /usr/local/bin /etc/ssl/certs -RUN apt-get -q update && apt-get -q install -y --no-install-recommends iptables -COPY --from=fetch-ziti-artifacts /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs -COPY --from=fetch-ziti-artifacts /tmp/${ZITI_TUNNELER_BIN} /usr/local/bin -COPY ${DOCKER_BUILD_DIR}/docker-entrypoint.sh / -RUN chmod +x /docker-entrypoint.sh - -ENTRYPOINT [ "/docker-entrypoint.sh" ] -CMD [ "run" ] diff --git a/ziti-tunnel/docker/README.md b/ziti-tunnel/docker/README.md deleted file mode 100644 index 6c7481497..000000000 --- a/ziti-tunnel/docker/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Ziti-tunnel Container Image - -[Link to container tunneler docs](https://docs.openziti.io/docs/reference/tunnelers/linux/container/) diff --git a/ziti-tunnel/docker/buildx.sh b/ziti-tunnel/docker/buildx.sh deleted file mode 100755 index a36eadb02..000000000 --- a/ziti-tunnel/docker/buildx.sh +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -_usage(){ - cat >&2 <<-EOF -Usage: VARIABLES ./${BASENAME} -r REPO [OPTIONS] - -Build multi-platform Docker container image on Linux. - -VARIABLES - ZITI_VERSION e.g. "0.16.1" corresponding to Git tag "v0.16.1" - -REQUIRED - -r REPO required container image repository e.g. netfoundry/ziti-edge-tunnel - -OPTIONS - -c don't check out v\${ZITI_VERSION} (use Git working copy) - -P don't push the container image to Hub - -EXAMPLES - ZITI_VERSION=0.16.1 ./${BASENAME} -c - -REFERENCE - https://github.com/openziti/ziti-tunnel-sdk-c/blob/main/docker/BUILD.md -EOF - [[ $# -eq 1 ]] && { - return "$1" - } || { - return 0 - } -} - -BASENAME=$(basename "$0") || exit $? -DIRNAME=$(dirname "$0") || exit $? - -while getopts :chPr: OPT;do - case $OPT in - c) FLAGS+=$OPT # don't checkout vZITI_VERSION - ;; - h) _usage; exit 0 # not an error - ;; - P) FLAGS+=$OPT # don't push container image to Hub - ;; - r) CONTAINER_REPO=$OPTARG - ;; - *|\?) _usage 1 # error - ;; - esac -done -shift "$((OPTIND-1))" - -# default to latest -: "${ZITI_VERSION:=$(git fetch --quiet --tags && git tag -l|sort -Vr|head -1|sed -E 's/^v(.*)/\1/')}" - -[[ -n "${CONTAINER_REPO:-}" ]] || { - echo "ERROR: missing -r REPO option to define container image repository name for tagging the image" >&2 - _usage; exit 1 -} - -if [[ ${FLAGS:-} =~ c ]]; then - echo "WARN: not checking out Git tag v${ZITI_VERSION}" -else - git diff --exit-code # bail if unstaged differences - git fetch --tags - git checkout "v${ZITI_VERSION}" -fi - -docker run --rm --privileged linuxkit/binfmt:v0.8 -grep -E -q enabled /proc/sys/fs/binfmt_misc/qemu-arm -docker run --rm --platform arm arm32v7/alpine uname -a|grep -E -q 'armv7l Linux' -docker run --rm --platform arm64 arm64v8/alpine uname -a|grep -E -q 'aarch64 Linux' - -docker buildx create --use --name=ziti-builder 2>/dev/null || docker buildx use --default ziti-builder - -# if default then push to Hub -BUILDX_OUTPUT="--push" -if [[ ${FLAGS:-} =~ P ]]; then - # if no push then load in image cache - BUILDX_OUTPUT="" -fi - -eval docker buildx build "$DIRNAME" \ - --platform linux/amd64,linux/arm/v7,linux/arm64 \ - --build-arg "ZITI_VERSION=${ZITI_VERSION}" \ - --tag "${CONTAINER_REPO}:${ZITI_VERSION}" \ - --tag "${CONTAINER_REPO}:latest" \ - "${BUILDX_OUTPUT:-}" - -docker buildx stop ziti-builder diff --git a/ziti-tunnel/docker/docker-compose.yml b/ziti-tunnel/docker/docker-compose.yml deleted file mode 100644 index 175764512..000000000 --- a/ziti-tunnel/docker/docker-compose.yml +++ /dev/null @@ -1,54 +0,0 @@ -version: "3.9" - -x-base-service: &base-service - image: netfoundry/ziti-tunnel:latest # https://hub.docker.com/r/netfoundry/ziti-tunnel/tags?page=1&ordering=last_updated - volumes: - - .:/netfoundry # mount current dir (relative to Compose file) with identity config file - environment: - - NF_REG_NAME # NF_REG_NAME=AcmeIdentity docker-compose up ziti-host - - NF_REG_TOKEN # NF_REG_NAME=AcmeIdentity NF_REG_TOKEN=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbSI6Im90dCIsImV4cCI6MTY1MzE2NzcwOCwiaXNzIjoiaHR0cHM6Ly81MGEyMDc4Zi01MGQyLTRhZTAtYWI4Ny0wYTdjMjM1OWVjOTYucHJvZHVjdGlvbi5uZXRmb3VuZHJ5LmlvOjQ0MyIsImp0aSI6IjFiMjJkMzc2LTMzMWItNDMxNS1iZTFiLWJkOTUzYThiYWM4ZiIsInN1YiI6InRGLnZnLjdwM1kifQ.TWbk3-kjBRKwQCXMoD93sXtyQhZOMZ1iJzV73Sqft-cEOkV2kjbA4TBRwl0nuLPCdJqkhPl9Yc1WG7YaYWYXV4ghE1Hk0Gta_HlpWdNjNlB1cVrzMyxaoCXhaX5xqGnwDuqfOK7q6DItuNsKouM2G6KKZvhGOacax6TvP-sunsxFz6AdYQJizNBoL5fJ14r1_O6yczGd5GSd8x9-eP5rNMQuRdUtiu69b-rEu1gO2SXVTrADTD5p8sP9khbT_eQzIDD9jgagXoJJvOKTVdsUAWS7YKfk1On0BpxNvv30bQ6eAkliwU7GTXDR2IPW-blZYt1Wtf3sgeuTDCCtVO_7gjSn7WM7YJqpsB72V-43Xz8I7LCDa0u48baSmmpPDUSphIBDa_nksPZk8jfwx4pHoHYbSbD4r47Af_9P-JUQRT8hzNuvktG56kmcqVCfEZHT-4xgK0Lvxxp4mzqdcNyCB0VwC6kdk7OlxwqmftDWrJhNuxKMy2MtyTjG0mwHxt4P0y_fZo1ZYJZU5AzvxrE9OLTjsQ4nV5NliJ3Qxaw_taCaIWxn98BeiHfAiIc3EL7bWGjAfXz-XWvWG8-AcCmK-cxIj7Pvj0U7lIWH7bVcRmVVc0fQnXdACkeQe7ixWr4IopV5YJ607zm6Qk_am_MrERla6xyXblvroWIITN2aEUk docker-compose up ziti-host - - PFXLOG_NO_JSON=true # suppress JSON logging - network_mode: host # use the Docker host's network, not the Docker bridge - -x-iptables-capabilities: &iptables-capabilities - cap_add: - - NET_ADMIN # iptables filter - - NET_RAW # iptables mangle - -services: - ziti-tproxy: # iptables transparent interceptor with DNS - <<: *base-service - <<: *iptables-capabilities - dns: # optionally, override DNS inherited from Docker host - - 127.0.0.1 # this first NS must match the built-in nameserver's bind address, - - 1.1.1.1 # and a recursive NS is also needed e.g. 8.8.8.8 - command: - - tproxy - #- --resolver=udp://127.1.2.3:53 # override nameserver bind address (always 53/udp); default is 127.0.0.1 - #- --dnsSvcIpRange=100.64.64.0/18 # override the IP range used for DNS intercepts; default is 100.64/10 - ziti-tproxy-ip: # iptables transparent interceptor without DNS - <<: *base-service - <<: *iptables-capabilities - command: - - tproxy - - --resolver none - #- --dnsSvcIpRange=100.64.64.0/18 # override the IP range used for DNS intercepts; default is 100.64/10 - ziti-test: # docker-compose exec ziti-test bash - <<: *base-service - <<: *iptables-capabilities - entrypoint: ["sh", "-c", "while true; do sleep infinity; done"] - ziti-host: # terminate a service for a server that's reachable by the host network - <<: *base-service - command: host - ziti-bridge: # terminate a service for a server that's reachable by this Docker network (default mode is "bridge") - <<: *base-service - network_mode: bridge - command: host - ziti-proxy: # bind a named service to a container TCP port, optionally forward host TCP port to container - <<: *base-service - ports: - - "8888:8888" # optionally forward host ports to container ports listening as TCP proxy - network_mode: bridge - command: - - proxy - - '"my example service":8888' # example named service and container port to bind as TCP proxy diff --git a/ziti-tunnel/docker/docker-entrypoint.sh b/ziti-tunnel/docker/docker-entrypoint.sh deleted file mode 100755 index e820efbf6..000000000 --- a/ziti-tunnel/docker/docker-entrypoint.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -function alldone() { - # if successfully sent to background then send SIGINT to trigger a cleanup - # of iptables mangle rules and loopback assignments - [[ "${ZITI_TUNNEL_PID:-}" =~ ^[0-9]+$ ]] && { - kill -INT "$ZITI_TUNNEL_PID" - # let entrypoint script exit after ziti-tunnel PID - wait "$ZITI_TUNNEL_PID" - } -} -trap alldone exit - -# Ensure that ziti-tunnel's identity is stored on a volume -# so we don't throw away the one-time enrollment token - -IDENTITIES_DIR="/netfoundry" -if ! mountpoint "${IDENTITIES_DIR}" &>/dev/null; then - echo "ERROR: please run this container with a volume mounted on ${IDENTITIES_DIR}" >&2 - exit 1 -fi - -# IOTEDGE_DEVICEID is a standard var assigned by Azure IoT -if [[ -z "${NF_REG_NAME:-}" ]]; then - if [[ -n "${IOTEDGE_DEVICEID:-}" ]]; then - echo "DEBUG: setting NF_REG_NAME to \${IOTEDGE_DEVICEID} (${IOTEDGE_DEVICEID})" - NF_REG_NAME="${IOTEDGE_DEVICEID}" - fi -fi - -typeset -a TUNNEL_OPTS -# if identity file name, else critical error -if [[ -n "${NF_REG_NAME:-}" ]]; then - IDENTITY_FILE="${IDENTITIES_DIR}/${NF_REG_NAME}.json" - TUNNEL_OPTS=("--identity" "${IDENTITY_FILE}") - # if non-empty identity file - if [[ -s "${IDENTITY_FILE}" ]]; then - echo "DEBUG: found identity file ${IDENTITY_FILE}" - # look for enrollment token - else - echo "DEBUG: identity file ${IDENTITY_FILE} does not exist" - for dir in "/var/run/secrets/netfoundry.io/enrollment-token" \ - "/enrollment-token" \ - "${IDENTITIES_DIR}"; do - JWT_CANDIDATE="${dir}/${NF_REG_NAME}.jwt" - echo "DEBUG: looking for ${JWT_CANDIDATE}" - if [[ -s "${JWT_CANDIDATE}" ]]; then - JWT_FILE="${JWT_CANDIDATE}" - break - fi - done - if [[ -n "${JWT_FILE:-}" ]]; then - echo "DEBUG: enrolling ${JWT_FILE}" - ziti-tunnel enroll --verbose --jwt "${JWT_FILE}" --identity "${IDENTITY_FILE}" || { - echo "ERROR: failed to enroll with token from ${JWT_FILE} ($(wc -c < "${JWT_FILE}")B)" >&2 - exit 1 - } - elif [[ -n "${NF_REG_TOKEN:-}" ]]; then - echo "DEBUG: attempting enrollment with NF_REG_TOKEN" - JWT_FILE=${IDENTITIES_DIR}/${NF_REG_NAME}.jwt - echo "${NF_REG_TOKEN}" >| ${JWT_FILE} - ziti-tunnel enroll --verbose --jwt ${JWT_FILE} --identity "${IDENTITY_FILE}" || { - echo "ERROR: failed to enroll with token from NF_REG_TOKEN ($(wc -c <<<"${NF_REG_TOKEN}")B)" >&2 - exit 1 - } - elif ! [[ -t 0 ]]; then - echo "DEBUG: trying to get token from stdin" >&2 - JWT_FILE=${IDENTITIES_DIR}/${NF_REG_NAME}.jwt - while read -r; do - echo "$REPLY" >> ${JWT_FILE} - done - ziti-tunnel enroll --verbose --jwt ${JWT_FILE} --identity "${IDENTITY_FILE}" || { - echo "ERROR: failed to enroll with token from stdin, got $(wc -c < ${JWT_FILE})B" >&2 - exit 1 - } - else - echo "DEBUG: ${NF_REG_NAME}.jwt and env var \$NF_REG_TOKEN not found" >&2 - exit 1 - fi - fi -else - echo "ERROR: need NF_REG_NAME env var to save the identity file in volume mounted on ${IDENTITIES_DIR}" >&2 - exit 1 -fi - -echo "INFO: probing iptables" -if iptables -t mangle -S --wait 2>&1 | grep -q "iptables-legacy tables present"; then - for LEGACY in {ip{,6},eb,arp}tables; do - if which ${LEGACY}-legacy &>/dev/null; then - echo "INFO: updating $LEGACY alternative to ${LEGACY}-legacy" - update-alternatives --set $LEGACY "$(which ${LEGACY}-legacy)" - else - echo "WARN: not updating $LEGACY alternative to ${LEGACY}-legacy" >&2 - fi - done -fi - -# optionally run an alternative shell CMD -echo "running ziti-tunnel" -set -x -ziti-tunnel "${TUNNEL_OPTS[@]}" "${@}" & -ZITI_TUNNEL_PID=$! -wait $ZITI_TUNNEL_PID diff --git a/ziti-tunnel/docker/fetch-ziti-bins.sh b/ziti-tunnel/docker/fetch-ziti-bins.sh deleted file mode 100755 index a0ed986c1..000000000 --- a/ziti-tunnel/docker/fetch-ziti-bins.sh +++ /dev/null @@ -1,68 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -[[ $# -eq 0 ]] && { - echo "ERROR: need the base name(s) of the executable(s) to fetch e.g. \"ziti-tunnel ...\"." >&2 - exit 1 -} - -: "${ARTIFACTORY_BASE_URL:="https://netfoundry.jfrog.io/netfoundry"}" -: "${ARTIFACTORY_REPO:="ziti-release"}" -for var in ARTIFACTORY_BASE_URL ARTIFACTORY_REPO ZITI_VERSION; do - if [ -z "${!var:-}" ]; then - echo "ERROR: ${var} must be set when fetching binaries from Artifactory." >&2 - exit 1 - fi -done - -[[ "$ZITI_VERSION" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] || { - echo "ERROR: '$ZITI_VERSION' is not a semantic version like 2.0.0" >&2 - exit 1 -} - -echo "Fetching from Artifactory." - -# map host architecture/os to directories that we use in netfoundry.jfrog.io. -# (our artifact directories seem to align with Docker's TARGETARCH and TARGETOS -# build arguments, which we could rely on if we fully committed to "docker buildx" - see -# https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope) -host_arch=$(uname -m) -case "${host_arch}" in -"x86_64") artifact_arch="amd64";; -"armv7l") artifact_arch="arm";; -"aarch64") artifact_arch="arm64";; -*) echo "ERROR: ziti binaries do not exist for architecture ${host_arch}"; exit 1;; -esac - -host_os=$(uname -s) -case "${host_os}" in - "Linux") artifact_os="linux" - ;; - "Darwin") artifact_os="darwin" - ;; - "Windows") artifact_os="windows" - ;; - *) echo "ERROR: ziti binaries do not exist for os ${host_os}"; - exit 1 - ;; -esac - -for exe in "${@}"; do - url="${ARTIFACTORY_BASE_URL}/${ARTIFACTORY_REPO}/${exe}/${artifact_arch}/${artifact_os}/${ZITI_VERSION}/${exe}.tar.gz" - echo "Fetching ${exe} from ${url}" - rm -f "${exe}" "${exe}.tar.gz" "${exe}.exe" - token_header="${ARTIFACTORY_TOKEN:+X-JFrog-Art-Api:$ARTIFACTORY_TOKEN}" - if { command -v curl > /dev/null; } 2>&1; then - curl ${token_header:+-H "$token_header"} -fLsS -O "${url}" - elif { command -v wget > /dev/null; } 2>&1; then - wget ${token_header:+--header "$token_header"} "${url}" - else - echo "ERROR: need one of curl or wget to fetch the artifact." >&2 - exit 1 - fi - tar -xzf "${exe}.tar.gz" - if [ -f "${exe}" ]; then chmod 755 "${exe}"; fi - if [ -f "${exe}.exe" ]; then chmod 755 "${exe}.exe"; fi - rm "${exe}.tar.gz" -done