diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c7444f65..25af62dfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +# Release 0.20.3 + +## What's New + +* Bug fix: Update of identity appData wasn't working +* Bug fix: Terminator updates failed if cost wasn't specified +* Bug fix: Control channel handler routines were exiting on error instead of just closing peer and continuing + +# Release 0.20.2 + +## 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 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.) + # Release 0.20.1 ## What's New diff --git a/go.mod b/go.mod index 92579bf1c..17bbfe16a 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,8 @@ require ( github.com/blang/semver v3.5.1+incompatible github.com/fatih/color v1.7.0 github.com/go-acme/lego/v4 v4.2.0 + github.com/go-openapi/runtime v0.19.28 + github.com/go-openapi/strfmt v0.20.1 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/protobuf v1.5.2 github.com/google/go-cmp v0.5.5 @@ -27,10 +29,10 @@ require ( github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d github.com/keybase/go-ps v0.0.0-20190827175125-91aafc93ba19 github.com/michaelquigley/pfxlog v0.3.7 - github.com/openziti/edge v0.19.113 - github.com/openziti/fabric v0.16.62 - github.com/openziti/foundation v0.15.51 - github.com/openziti/sdk-golang v0.15.49 + github.com/openziti/edge v0.19.117 + github.com/openziti/fabric v0.16.63 + github.com/openziti/foundation v0.15.52 + github.com/openziti/sdk-golang v0.15.50 github.com/pborman/uuid v1.2.0 github.com/pkg/errors v0.9.1 github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 diff --git a/go.sum b/go.sum index 4bfe4e2c7..f6e46f89b 100644 --- a/go.sum +++ b/go.sum @@ -614,14 +614,16 @@ github.com/openziti/bbolt v1.3.6-0.20210317142109-547da822475e h1:ST9+54UtCr96S5 github.com/openziti/bbolt v1.3.6-0.20210317142109-547da822475e/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= github.com/openziti/dilithium v0.3.3 h1:PLgQ6PMNLSTzCFbX/h98cmudgz/cU6TmjdSv5NAPD8k= github.com/openziti/dilithium v0.3.3/go.mod h1:vsCjI2AU/hon9e+dLhUFbCNGesJDj2ASgkySOcpmvjo= -github.com/openziti/edge v0.19.113 h1:1oHcIFsB8YGUGb6baXNL+C6rdpgvlBkbaAhEHmgwtTk= -github.com/openziti/edge v0.19.113/go.mod h1:9LJisB1t2/YPlQzAX7wb/iF0RmVmJ1Tj244dUtZc0ak= -github.com/openziti/fabric v0.16.62 h1:feIKQCSkK7+/q0JyUtMwyBZ8my3yhtlOObTBaSTumCM= -github.com/openziti/fabric v0.16.62/go.mod h1:Z43VUQMrSga1N44rD837guAqLdcFlpLMK50kM1WGDAs= -github.com/openziti/foundation v0.15.51 h1:iu+vKDusU6QvW+KBTe4bhTzIOQmRxhBvAsqYxKTSCYk= +github.com/openziti/edge v0.19.117 h1:BSgmTIVbTMonBX4FjTj73yPKAqUbXcEF4HJM8MjcaGc= +github.com/openziti/edge v0.19.117/go.mod h1:qwGLmc2DWsAnTo0qMadnGgca/QkTm58fa+lwlek5FRU= +github.com/openziti/fabric v0.16.63 h1:anhP9UkGPRTQw40C8ekPHorxHShQxvkhqpBp6AcEvHM= +github.com/openziti/fabric v0.16.63/go.mod h1:VgFw5FPeS4+rDatw08wClKsoUa+W7QIvk/Ur6RfvrlY= github.com/openziti/foundation v0.15.51/go.mod h1:NnSBTp9ZkcYsv6nYxZR0/NzoHfkIo6tjpBHDvBsPFqw= -github.com/openziti/sdk-golang v0.15.49 h1:ZlpufEJzE8XUi6hAHKx0+WxWD8aBgcsocmlrnmNZXJs= +github.com/openziti/foundation v0.15.52 h1:S+znS7PfsUrF1TpUWq2XZMlIJr9GsMiFG9wbc80Figo= +github.com/openziti/foundation v0.15.52/go.mod h1:NnSBTp9ZkcYsv6nYxZR0/NzoHfkIo6tjpBHDvBsPFqw= github.com/openziti/sdk-golang v0.15.49/go.mod h1:/8xH6hV9g8bsJNfM6FYhPC6SU4qKs2UGXh3CsQ5sIu4= +github.com/openziti/sdk-golang v0.15.50 h1:BeKlp17UpQHGFDUvXn/Yn+q9r/wxSdhCs0TubQOp4Es= +github.com/openziti/sdk-golang v0.15.50/go.mod h1:nA/ik6YZPTcLNdiq5tKjIPjjLCTtOEsfFYVl8NpAF2Q= 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= diff --git a/quickstart/aws.md b/quickstart/aws.md index 9fcd993c5..ed0624e8b 100644 --- a/quickstart/aws.md +++ b/quickstart/aws.md @@ -10,39 +10,123 @@ This quickstart is a barebones guide to running a full developer environment in 1. At the bottom of the screen - click the "Review and Launch" button 1. In AWS "Step 7. Review Instance Launch", find the "Security Groups" row and expand it if necessary 1. Click "Edit security groups" -1. Click "Add Rule" and select "Custom TCP Rule" and enter Port Range:"8441" Source: "0.0.0.0/0" -1. Click "Add Rule" and select "Custom TCP Rule" and enter Port Range:"8442" Source: "0.0.0.0/0" -1. Click "Add Rule" and select "Custom TCP Rule" and enter Port Range:"8443" Source: "0.0.0.0/0" +1. Click "Add Rule" and select "Custom TCP Rule" and enter Port Range:"8441" Source: "0.0.0.0/0", Description: "Ziti Controller Port" +1. Click "Add Rule" and select "Custom TCP Rule" and enter Port Range:"8442" Source: "0.0.0.0/0", Description: "Ziti Edge Router Port" +1. Click "Add Rule" and select "Custom TCP Rule" and enter Port Range:"8443" Source: "0.0.0.0/0", Description: "Ziti Console TLS Port" 1. Your console should look like this: - ![img.png](img.png) + ![security-groups.png](security-groups.png) 1. click "Review and Launch" and then "Launch" 1. Select your keypair and choose "Launch Instances" ## SSH to the Server -1. After ssh'ing to the new ubuntu machine - run: sudo apt update && sudo apt install jq -y -1. Clone the public github repos: git clone https://github.com/openziti/ziti.git -1. Set a whole bunch of environment variables. You will need to know the public ip address as well as public dns name. Replace "____EXTERNAL___IP____" and "____EXTERNAL___DNS____" with the proper values: +1. After ssh'ing to the new ubuntu machine - run: `sudo apt update && sudo apt install jq -y` +1. Set some environment variables which are used to establish a PKI as well as the necessary configuration files. You will need to know the public IPv4 DNS name assigned to this machine. Replace "____EXTERNAL___DNS____" with the proper values. (**IMPORTANT** make sure the name is correct): - export EXTERNAL_IP="____EXTERNAL___IP____"export EXTERNAL_DNS="____EXTERNAL___DNS____" + export EXTERNAL_DNS="____EXTERNAL___DNS______FILLIN example: ec2-3-129-206-186.us-east-2.compute.amazonaws.com" + + export EXTERNAL_IP="$(curl -s eth0.me)" export ZITI_EDGE_CONTROLLER_IP_OVERRIDE="${EXTERNAL_IP}" export ZITI_EDGE_ROUTER_IP_OVERRIDE="${EXTERNAL_IP}" export ZITI_EDGE_CONTROLLER_HOSTNAME="${EXTERNAL_DNS}" export ZITI_EDGE_ROUTER_HOSTNAME="${EXTERNAL_DNS}" export ZITI_EDGE_CONTROLLER_PORT=8441 export ZITI_EDGE_ROUTER_PORT=8442 -1. Start the Ziti Controller and Ziti Edge Router by using the "express" script: + +1. Run this single command to download and bootstrap the ziti-controller and ziti-router (feel free to read the bash script before running if you like): - ~/ziti/quickstart/local/express/express-dev-env.sh -1. Test the script worked properly by using a curl statement: + source <(wget -qO- https://raw.githubusercontent.com/openziti/ziti/release-next/quickstart/docker/image/ziti-cli-functions.sh); expressInstall - curl -k "https://${EXTERNAL_DNS}:${ZITI_EDGE_CONTROLLER_PORT}/version" +1. At this point the controller and router are running and can be accessed from anywhere. Confirm both are running by running: + + ps -ef | grep ziti + root 2520 1 0 May19 ? 00:00:15 /home/ubuntu/.ziti/quickstart/ip-172-31-22-212/ziti-bin/ziti-v0.20.2/ziti-controller run /home/ubuntu/.ziti/quickstart/ip-172-31-22-212/controller.yaml + root 2547 1 0 May19 ? 00:00:10 /home/ubuntu/.ziti/quickstart/ip-172-31-22-212/ziti-bin/ziti-v0.20.2/ziti-router run /home/ubuntu/.ziti/quickstart/ip-172-31-22-212/ip-172-31-22-212-edge-router.yaml + +1. You can also issue this statement from the server and you will see a similar response to this: + + curl -sk "https://${ZITI_EDGE_CONTROLLER_HOSTNAME}:${ZITI_EDGE_CONTROLLER_PORT}/version" {"data":{"apiVersions":{"edge":{"v1":{"path":"/edge/v1"}}},"buildDate":"2021-05-05 20:59:40","revision":"73dd1db42bf4","runtimeVersion":"go1.16.3","version":"v0.19.13"},"meta":{}} +## Setting up Ziti Controller and Router as a service + +1. Stop ziti-controller and ziti-router if they are running: + + killall ziti-controller ziti-router +1. copy the two systemd files and refresh systemd + + sudo cp "${ZITI_HOME}/ziti-controller.service" /etc/systemd/system + sudo cp "${ZITI_HOME}/ziti-router-${ZITI_EDGE_ROUTER_RAWNAME}.service" /etc/systemd/system/ziti-router.service + sudo systemctl daemon-reload + sudo systemctl start ziti-controller + sudo systemctl start ziti-router +1. Allow 5 to 10 seconds for the ziti-controller and router to start completely. Run these two commands to verify ziti-controller and ziti-router are running: + + sudo systemctl -q status ziti-controller --lines=0 --no-pager + sudo systemctl -q status ziti-router --lines=0 --no-pager + + #sample output: + ubuntu@ip-172-31-22-212:~$ sudo systemctl -q status ziti-controller --lines=0 --no-pager + ● ziti-controller.service - Ziti-Controller + Loaded: loaded (/etc/systemd/system/ziti-controller.service; disabled; vendor preset: enabled) + Active: active (running) since Thu 2021-05-20 11:24:40 UTC; 5min ago + Main PID: 26848 (ziti-controller) + Tasks: 7 (limit: 1160) + Memory: 50.5M + CGroup: /system.slice/ziti-controller.service + └─26848 /home/ubuntu/.ziti/quickstart/ip-172-31-22-212/ziti-bin/ziti-v0.20.2/ziti-controller run /home/ubu… + + ubuntu@ip-172-31-22-212:~$ sudo systemctl -q status ziti-router --lines=0 --no-pager + ● ziti-router.service - Ziti-Router for ip-172-31-22-212-edge-router + Loaded: loaded (/etc/systemd/system/ziti-router.service; disabled; vendor preset: enabled) + Active: active (running) since Thu 2021-05-20 11:24:42 UTC; 5min ago + Main PID: 26864 (ziti-router) + Tasks: 7 (limit: 1160) + Memory: 28.4M + CGroup: /system.slice/ziti-router.service + └─26864 /home/ubuntu/.ziti/quickstart/ip-172-31-22-212/ziti-bin/ziti-v0.20.2/ziti-router run /home/ubuntu/… + ubuntu@ip-172-31-22-212:~$ + ## Setting up the Ziti Admin Console -1. Install docker on the machine. I followed these instructions https://linuxize.com/post/how-to-install-and-use-docker-on-ubuntu-20-04/ but we'll condense them here for you to copy/paste: +### By Cloning from Github + +1. clone the ziti-console repo from github: + + git clone https://github.com/openziti/ziti-console.git "${ZITI_HOME}/ziti-console" +1. Install node and npm and get the server ready + + cd "${ZITI_HOME}/ziti-console" + sudo apt install npm nodejs -y + npm install +1. Use the ziti-controller certificates for the Ziti Console: + + ln -s "${ZITI_PKI}/${ZITI_EDGE_CONTROLLER_HOSTNAME}-intermediate/certs/${ZITI_EDGE_CONTROLLER_HOSTNAME}-server.chain.pem" "${ZITI_HOME}/ziti-console/server.chain.pem" + ln -s "${ZITI_PKI}/${ZITI_EDGE_CONTROLLER_HOSTNAME}-intermediate/keys/${ZITI_EDGE_CONTROLLER_HOSTNAME}-server.key" "${ZITI_HOME}/ziti-console/server.key" +1. Emit the Ziti Console systemd file and update systemd to start the Ziti Console + + createZacSystemdFile + sudo cp "${ZITI_HOME}/ziti-console.service" /etc/systemd/system + sudo systemctl daemon-reload + sudo systemctl start ziti-console +1. Verify the Ziti Console is running + sudo systemctl status ziti-console --lines=0 --no-pager + + #sample output of the command: + ubuntu@ip-172-31-22-212:~$ sudo systemctl status ziti-console --lines=0 --no-pager + ● ziti-console.service - Ziti-Console + Loaded: loaded (/etc/systemd/system/ziti-console.service; disabled; vendor preset: enabled) + Active: active (running) since Wed 2021-05-19 22:04:44 UTC; 13h ago + Main PID: 13458 (node) + Tasks: 11 (limit: 1160) + Memory: 33.4M + CGroup: /system.slice/ziti-console.service + └─13458 /usr/bin/node /home/ubuntu/.ziti/quickstart/ip-172-31-22-212/ziti-console/server.js + +### By Using Docker + +1. If needed, install docker on the machine. I followed these instructions https://linuxize.com/post/how-to-install-and-use-docker-on-ubuntu-20-04/ but we'll condense them here for you to copy/paste: sudo apt update sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common -y @@ -54,12 +138,14 @@ This quickstart is a barebones guide to running a full developer environment in 1. Copy/paste this command to start the Ziti Admin Console in TLS mode: docker run -d \ - --name zac \ - -p 8443:8443 \ - -v "/home/ubuntu/.ziti/quickstart/$(hostname)/pki/$(hostname)-intermediate/keys/$(hostname)-server.key":/usr/src/app/server.key \ - -v "/home/ubuntu/.ziti/quickstart/$(hostname)/pki/$(hostname)-intermediate/certs/$(hostname)-server.chain.pem":/usr/src/app/server.chain.pem \ - openziti/zac -1. At this point you should be able to navigate to both: https://external-dns-name:8443 as well as https://external-ip:8443 and see the ZAC login screen. (The TLS warnings your browser will show you are normal - it's because these steps use a self-signed certificate generated in the install process) + --name zac \ + -p 8443:8443 \ + -v "${ZITI_PKI}/${ZITI_EDGE_CONTROLLER_HOSTNAME}-intermediate/keys/${ZITI_EDGE_CONTROLLER_HOSTNAME}-server.key":/usr/src/app/server.key \ + -v "${ZITI_PKI}/${ZITI_EDGE_CONTROLLER_HOSTNAME}-intermediate/certs/${ZITI_EDGE_CONTROLLER_HOSTNAME}-server.chain.pem":/usr/src/app/server.chain.pem \ + openziti/zac + +## Login and use the Ziti Console +1. At this point you should be able to navigate to both: https://${ZITI_EDGE_CONTROLLER_HOSTNAME}:8443 as well as https://$(curl -s eth0.me):8443 and see the ZAC login screen. (The TLS warnings your browser will show you are normal - it's because these steps use a self-signed certificate generated in the install process) 1. Set the controller as shown: ![img_1.png](img_1.png) @@ -69,4 +155,17 @@ This quickstart is a barebones guide to running a full developer environment in 1. **IMPORTANT!!!** Edit your profile and change the password - ![img_3.png](img_3.png) \ No newline at end of file + ![img_3.png](img_3.png) + +## Adding Environment Variables Back to the Shell + +If you log out and log back in again you can source the '.env' file located at: `. ~/.ziti/quickstart/$(hostname)/$(hostname).env`. Below is an example of logging in, not having ZITI_HOME set, sourcing the .env file and then showing ZITI_HOME set: + + Last login: Thu May 20 11:36:25 2021 from 67.246.244.61 + ubuntu@ip-172-31-22-212:~$ echo $ZITI_HOME + + ubuntu@ip-172-31-22-212:~$ . ~/.ziti/quickstart/$(hostname)/$(hostname).env + + adding /home/ubuntu/.ziti/quickstart/ip-172-31-22-212/ziti-bin/ziti-v0.20.2 to the path + ubuntu@ip-172-31-22-212:~$ echo $ZITI_HOME + /home/ubuntu/.ziti/quickstart/ip-172-31-22-212 diff --git a/quickstart/docker/image/Dockerfile b/quickstart/docker/image/Dockerfile index a90173261..eacecb1e5 100644 --- a/quickstart/docker/image/Dockerfile +++ b/quickstart/docker/image/Dockerfile @@ -13,19 +13,16 @@ WORKDIR /openziti ENV ZITI_HOME=/openziti ENV ZITI_BIN_DIR="${ZITI_HOME}/ziti-bin" - -# copy the ziti binaries to a directory already on the path -#COPY --chown=ziti ziti.ignore /usr/local/bin/ -COPY --chown=ziti ziti.ignore "${ZITI_BIN_DIR}" -COPY --chown=ziti *.sh ./scripts/ - -#ENV ZITI_HOME=/openziti -#ENV ZITI_BIN_DIR="${ZITI_HOME}/ziti-bin" -ENV ZITI_SHARED=${ZITI_HOME}/shared -ENV ZITI_SCRIPTS=${ZITI_HOME}/scripts -ENV ENV_FILE=${ZITI_HOME}/ziti.env +ENV ZITI_SHARED="${ZITI_HOME}/shared" +ENV ZITI_SCRIPTS="${ZITI_HOME}/scripts" +ENV ENV_FILE="${ZITI_HOME}/ziti.env" ENV ZITI_NETWORK=ziti -RUN ${ZITI_SCRIPTS}/env.sh && \ - echo "source ${ZITI_HOME}/ziti.env" >> ~/.bashrc +RUN mkdir -p "${ZITI_SCRIPTS}" + +# copy the ziti binaries to a directory already on the path +COPY --chown=ziti ziti.ignore "${ZITI_BIN_DIR}" +COPY --chown=ziti *.sh "${ZITI_SCRIPTS}/" + +RUN /bin/bash -c "source ${ZITI_SCRIPTS}/ziti-cli-functions.sh; ziti_createEnvFile; echo source ${ZITI_HOME}/ziti.env >> ~/.bashrc" diff --git a/quickstart/docker/image/create-controller-config.sh b/quickstart/docker/image/create-controller-config.sh deleted file mode 100755 index f96bf3e91..000000000 --- a/quickstart/docker/image/create-controller-config.sh +++ /dev/null @@ -1,147 +0,0 @@ -#!/bin/bash -cat > ${ZITI_HOME}/controller.yaml < ${ZITI_HOME}/${ZITI_EDGE_ROUTER_RAWNAME}.yaml < ${ZITI_HOME}/${ZITI_EDGE_ROUTER_RAWNAME}.yaml < ${ZITI_HOME}/identities.yml < ${ZITI_HOME}/${ZITI_EDGE_ROUTER_RAWNAME}.yaml < ${ZITI_HOME}/${ZITI_EDGE_ROUTER_RAWNAME}.yaml < "${ENV_FILE}" -for zEnvVar in $(set -o posix ; set | grep ZITI_ | sort); do echo "export ${zEnvVar}" >> "${ENV_FILE}"; done - -export PFXLOG_NO_JSON=true -echo "export PFXLOG_NO_JSON=true" >> "${ENV_FILE}" - -echo "alias zec='ziti edge controller'" >> "${ENV_FILE}" -echo "alias zlogin='ziti edge controller login \"${ZITI_EDGE_CONTROLLER_API}\" -u \"${ZITI_USER}\" -p \"${ZITI_PWD}\" -c \"${ZITI_PKI}/${ZITI_EDGE_CONTROLLER_INTERMEDIATE_NAME}/certs/${ZITI_EDGE_CONTROLLER_INTERMEDIATE_NAME}.cert\"'" >> "${ENV_FILE}" -echo "alias psz='ps -ef | grep ziti'" >> "${ENV_FILE}" - -#when sourcing the emitted file add the bin folder to the path -tee -a "${ENV_FILE}" > /dev/null <<'heredoc' -echo " " -if [[ ! "$(echo "$PATH"|grep -q "${ZITI_BIN_DIR}" && echo "yes")" == "yes" ]]; then - echo "adding ${ZITI_BIN_DIR} to the path" - export PATH=$PATH:"${ZITI_BIN_DIR}" -else -echo " ziti binaries are located at: ${ZITI_BIN_DIR}" -echo -e 'add this to your path if you want by executing: export PATH=$PATH:'"${ZITI_BIN_DIR}" -fi -heredoc diff --git a/quickstart/docker/image/pki-functions.sh b/quickstart/docker/image/pki-functions.sh deleted file mode 100644 index 473d36ef3..000000000 --- a/quickstart/docker/image/pki-functions.sh +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env bash - -function pki_client_server { - name_local=$1 - ZITI_CA_NAME_local=$2 - ip_local=$3 - - if [[ "${ip_local}" == "" ]]; then - ip_local="127.0.0.1" - fi - - if ! test -f "${ZITI_PKI}/${ZITI_CA_NAME_local}/keys/${name_local}-server.key"; then - echo "Creating server cert from ca: ${ZITI_CA_NAME_local} for ${name_local}" - "${ZITI_BIN_DIR}/ziti" pki create server --pki-root="${ZITI_PKI}" --ca-name "${ZITI_CA_NAME_local}" \ - --server-file "${name_local}-server" \ - --dns "${name_local},localhost" --ip "${ip_local}" \ - --server-name "${name_local} server certificate" - else - echo "Creating server cert from ca: ${ZITI_CA_NAME_local} for ${name_local}" - echo "key exists" - fi - - if ! test -f "${ZITI_PKI}/${ZITI_CA_NAME_local}/keys/${name_local}-client.key"; then - echo "Creating client cert from ca: ${ZITI_CA_NAME_local} for ${name_local}" - "${ZITI_BIN_DIR}/ziti" pki create client --pki-root="${ZITI_PKI}" --ca-name "${ZITI_CA_NAME_local}" \ - --client-file "${name_local}-client" \ - --key-file "${name_local}-server" \ - --client-name "${name_local}" - else - echo "Creating client cert from ca: ${ZITI_CA_NAME_local} for ${name_local}" - echo "key exists" - fi - echo " " -} - -function pki_create_ca { - if ! test -f "${ZITI_PKI}/${1}/keys/${1}.key"; then - echo "Creating CA: ${1}" - "${ZITI_BIN_DIR}/ziti" pki create ca --pki-root="${ZITI_PKI}" --ca-file="${1}" --ca-name="${1} Root CA" - else - echo "Creating CA: ${1}" - echo "key exists" - fi - echo " " -} - -function pki_create_intermediate { - if ! test -f "${ZITI_PKI}/${2}/keys/${2}.key"; then - echo "Creating intermediate: ${1} ${2} ${3}" - "${ZITI_BIN_DIR}/ziti" pki create intermediate --pki-root "${ZITI_PKI}" --ca-name "${1}" \ - --intermediate-name "${2}" \ - --intermediate-file "${2}" --max-path-len ${3} - else - echo "Creating intermediate: ${1} ${2} ${3}" - echo "key exists" - fi - echo " " -} -function yaml2json() -{ - ruby -ryaml -rjson -e 'puts JSON.pretty_generate(YAML.load(ARGF))' $* -} - -function printUsage() -{ - echo "Usage: $1 [cert to test] [ca pool to use]" -} - -function verifyCertAgainstPool() -{ - if [[ "" == "$1" ]] - then - printUsage "verifyCertAgainstPool" - return 1 - fi - - if [[ "" == "$2" ]] - then - printUsage "verifyCertAgainstPool" - return 1 - fi - - echo " Verifying that this certificate:" - echo " - $1" - echo " is valid for this ca pool:" - echo " - $2" - echo "" - openssl verify -partial_chain -CAfile "$2" "$1" - if [ $? -eq 0 ]; then - echo "" - echo "============ SUCCESS! ============" - else - echo "" - echo "============ FAILED TO VALIDATE ============" - fi -} - -function showIssuerAndSubjectForPEM() -{ - echo "Displaying Issuer and Subject for cert pool:" - echo " $1" - openssl crl2pkcs7 -nocrl -certfile $1 | openssl pkcs7 -print_certs -text -noout | grep -E "(Subject|Issuer)" -} diff --git a/quickstart/docker/image/run-controller.sh b/quickstart/docker/image/run-controller.sh index c83911706..e3c9ed38d 100755 --- a/quickstart/docker/image/run-controller.sh +++ b/quickstart/docker/image/run-controller.sh @@ -1,14 +1,15 @@ #!/bin/bash -. ${ZITI_SCRIPTS}/env.sh +. "${ZITI_SCRIPTS}/ziti-cli-functions.sh" + +ziti_createEnvFile . ${ZITI_HOME}/ziti.env -"${ZITI_SCRIPTS}/create-pki.sh" - # create pki +createPki # generates the config file for the controller -"${ZITI_SCRIPTS}/create-controller-config.sh" +createControllerConfig # initialize the database with the admin user: "${ZITI_BIN_DIR}/ziti-controller" edge init "${ZITI_HOME}/controller.yaml" -u "${ZITI_USER}" -p "${ZITI_PWD}" @@ -16,8 +17,9 @@ # create a place for the internal db mkdir -p $ZITI_HOME/db -"${ZITI_SCRIPTS}/create-fabric-identity.sh" +#"${ZITI_SCRIPTS}/create-fabric-identity.sh" +createFabricIdentity "${ZITI_BIN_DIR}/ziti-controller" run "${ZITI_HOME}/controller.yaml" -${ZITI_HOME}/pki/ziti-controller-intermediate/keys/ziti-dotzeet.key \ No newline at end of file +${ZITI_HOME}/pki/ziti-controller-intermediate/keys/ziti-dotzeet.key diff --git a/quickstart/docker/image/run-edge-router.sh b/quickstart/docker/image/run-edge-router.sh index 0a92d1911..b5ed8b10c 100755 --- a/quickstart/docker/image/run-edge-router.sh +++ b/quickstart/docker/image/run-edge-router.sh @@ -1,6 +1,8 @@ #!/bin/bash -. ${ZITI_SCRIPTS}/env.sh +. "${ZITI_SCRIPTS}/ziti-cli-functions.sh" + +ziti_createEnvFile . ${ZITI_HOME}/ziti.env until $(curl -s -o /dev/null --fail -k "https://${ZITI_EDGE_CONTROLLER_API}"); do @@ -11,26 +13,26 @@ done if [[ "${ZITI_EDGE_ROUTER_HOSTNAME}" == "" ]]; then export ZITI_EDGE_ROUTER_HOSTNAME="${ZITI_EDGE_ROUTER_RAWNAME}${ZITI_DOMAIN_SUFFIX}"; fi if [[ "${ZITI_EDGE_ROUTER_PORT}" == "" ]]; then export ZITI_EDGE_ROUTER_PORT="3022"; fi -"${ZITI_SCRIPTS}/create-router-pki.sh" +createRouterPki echo "logging into ziti controller: ${ZITI_EDGE_API_HOSTNAME}" "${ZITI_BIN_DIR}/ziti" edge login "${ZITI_EDGE_CONTROLLER_API}" -u "${ZITI_USER}" -p "${ZITI_PWD}" -c "${ZITI_PKI}/${ZITI_EDGE_CONTROLLER_ROOTCA_NAME}/certs/${ZITI_EDGE_CONTROLLER_INTERMEDIATE_NAME}.cert" if [[ "$1" == "edge" ]]; then echo "CREATING EDGE ROUTER CONFIG" - "${ZITI_SCRIPTS}/create-edge-router-config.sh" + createEdgeRouterConfig fi if [[ "$1" == "wss" ]]; then echo "CREATING EDGE ROUTER WSS CONFIG" - "${ZITI_SCRIPTS}/create-edge-router-wss-config.sh" + createEdgeRouterWssConfig fi if [[ "$1" == "fabric" ]]; then echo "CREATING FABRIC ROUTER CONFIG" - "${ZITI_SCRIPTS}/create-fabric-router-config.sh" + createFabricRouterConfig fi if [[ "$1" == "private" ]]; then echo "CREATING PRIVATE ROUTER CONFIG" - "${ZITI_SCRIPTS}/create-private-router-config.sh" + createPrivateRouterConfig fi echo "---------- Creating edge-router ${ZITI_EDGE_ROUTER_HOSTNAME}...." diff --git a/quickstart/docker/image/ziti-cli-functions.sh b/quickstart/docker/image/ziti-cli-functions.sh new file mode 100644 index 000000000..546130a16 --- /dev/null +++ b/quickstart/docker/image/ziti-cli-functions.sh @@ -0,0 +1,1274 @@ +#!/bin/bash + +set -uo pipefail + +# shellcheck disable=SC2155 +export DEFAULT_ZITI_HOME_LOCATION="${HOME}/.ziti/quickstart/$(hostname)" + +# shellcheck disable=SC2155 +export ZITI_QUICKSTART_SCRIPT_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +export ZITI_QUICKSTART_ENVROOT="${HOME}/.ziti/quickstart" + +ASCI_WHITE='\033[01;37m' +ASCI_RESTORE='\033[0m' +ASCI_RED='\033[00;31m' +ASCI_GREEN='\033[00;32m' +ASCI_YELLOW='\033[00;33m' +ASCI_BLUE='\033[00;34m' +#ASCI_MAGENTA='\033[00;35m' +#ASCI_PURPLE='\033[00;35m' +#ASCI_CYAN='\033[00;36m' +#ASCI_LIGHTGRAY='\033[00;37m' +#ASCI_LRED='\033[01;31m' +#ASCI_LGREEN='\033[01;32m' +#ASCI_LYELLOW='\033[01;33m' +#ASCI_LBLUE='\033[01;34m' +#ASCI_LMAGENTA='\033[01;35m' +#ASCI_LPURPLE='\033[01;35m' +#ASCI_LCYAN='\033[01;36m' + +function WHITE { + echo "${ASCI_WHITE}${1-}${ASCI_RESTORE}" +} +function RED { + echo "${ASCI_RED}${1-}${ASCI_RESTORE}" +} +function GREEN { + echo "${ASCI_GREEN}${1-}${ASCI_RESTORE}" +} +function YELLOW { + echo "${ASCI_YELLOW}${1-}${ASCI_RESTORE}" +} +function BLUE { + echo "${ASCI_BLUE}${1-}${ASCI_RESTORE}" +} + +function zitiLogin { + unused=$("${ZITI_BIN_DIR-}/ziti" edge login "${ZITI_EDGE_CONTROLLER_API}" -u "${ZITI_USER-}" -p "${ZITI_PWD}" -c "${ZITI_PKI}/${ZITI_EDGE_CONTROLLER_ROOTCA_NAME}/certs/${ZITI_EDGE_CONTROLLER_INTERMEDIATE_NAME}.cert") +} +function cleanZitiController { + ziti_home="${ZITI_HOME-}" + if [[ "${ziti_home}" == "" ]]; then + echo -e " * ERROR: $(RED "ZITI_HOME is not set") " + return 1 + fi + rm -rf "${ziti_home}/db" + mkdir "${ziti_home}/db" + initializeController +} +function initializeController { + "${ZITI_BIN_DIR-}/ziti-controller" edge init "${ZITI_HOME-}/controller.yaml" -u "${ZITI_USER-}" -p "${ZITI_PWD}" &> "${ZITI_HOME-}/controller-init.log" + echo -e "ziti-controller initialized. see $(BLUE "${ZITI_HOME-}/controller-init.log") for details" +} +function startZitiController { + # shellcheck disable=SC2034 + unused=$("${ZITI_BIN_DIR-}/ziti-controller" run "${ZITI_HOME-}/controller.yaml" > "${ZITI_HOME-}/ziti-edge-controller.log" 2>&1 &) + echo -e "ziti-controller started. log located at: $(BLUE "${ZITI_HOME-}/ziti-edge-controller.log")" +} +function stopZitiController { + killall ziti-controller +} +function checkHostsFile { + ctrlexists=$(grep -c "${ZITI_CONTROLLER_HOSTNAME}" /etc/hosts) + edgectrlexists=$(grep -c "${ZITI_EDGE_CONTROLLER_HOSTNAME}" /etc/hosts) + erexists=$(grep -c "${ZITI_EDGE_ROUTER_HOSTNAME}" /etc/hosts) + + if [[ "0" = "${ctrlexists}" ]] || [[ "0" = "${edgectrlexists}" ]] || [[ "0" = "${erexists}" ]]; then + echo " " + echo -e "$(YELLOW "Ziti is generally used to create an overlay network. Generally speaking this will involve more than one host")" + echo -e "$(YELLOW "Since this is a script geared towards setting up a very minimal development environment it needs to make some")" + echo -e "$(YELLOW "assumptions. One of these assumptions is that the three specific entries are entered onto your hosts file.")" + echo -e "$(YELLOW "One or more of these are missing:")" + echo " " + if [[ "0" == "${ctrlexists}" ]]; then + echo -e " * $(RED "MISSING: ${ZITI_EDGE_CONTROLLER_HOSTNAME}") " + else + echo -e " * $(GREEN " FOUND: ${ZITI_EDGE_CONTROLLER_HOSTNAME}") " + fi + if [[ "0" == "${edgectrlexists}" ]]; then + echo -e " * $(RED "MISSING: ${ZITI_EDGE_CONTROLLER_HOSTNAME}") " + else + echo -e " * $(GREEN " FOUND: ${ZITI_EDGE_CONTROLLER_HOSTNAME}") " + fi + if [[ "0" == "${erexists}" ]]; then + echo -e " * $(RED "MISSING: ${ZITI_EDGE_ROUTER_HOSTNAME}") " + else + echo -e " * $(GREEN " FOUND: ${ZITI_EDGE_ROUTER_HOSTNAME}") " + fi + + echo " " + echo "The easiest way to correct this is to run the following command:" + echo " echo \"127.0.0.1 ${ZITI_CONTROLLER_HOSTNAME} ${ZITI_EDGE_CONTROLLER_HOSTNAME} ${ZITI_EDGE_ROUTER_HOSTNAME}\" | sudo tee -a /etc/hosts" + echo " " + echo "add these entries to your hosts file, and rerun the script when ready" + return 1 + fi +} + +function getLatestZitiVersion { + if [[ "${ZITI_BINARIES_VERSION-}" == "" ]]; then + zitilatest=$(curl -s https://api.github.com/repos/openziti/ziti/releases/latest) + echo "${zitilatest}" > /mnt/v/temp/a.txt + # shellcheck disable=SC2155 + export ZITI_BINARIES_TARFILE=$(echo "${zitilatest}" | jq -r '.assets[] | select(.name | startswith("ziti-linux-amd")) | .name') + # shellcheck disable=SC2155 + export ZITI_BINARIES_VERSION=$(echo "${zitilatest}" | jq -r '.tag_name') + fi + #echo -e 'Ziti tar.gz: '"$(BLUE "${ZITI_BINARIES_TARFILE}")" + #echo -e 'Latest ziti is: '"$(BLUE "${ZITI_BINARIES_VERSION}")" +} + +function getLatestZiti { + if [[ "${ZITI_HOME-}" == "" ]]; then + echo "ERROR: ZITI_HOME is not set!" + return 1 + fi + + ziti_bin_root="${ZITI_BIN_ROOT-}" + if [[ "${ziti_bin_root}" == "" ]]; then + ziti_bin_root="${ZITI_HOME-}/ziti-bin" + fi + export ZITI_BIN_ROOT="${ziti_bin_root}/ziti-bin" + + mkdir -p "${ziti_bin_root}" + getLatestZitiVersion + + ziti_bin_ver="${ZITI_BINARIES_VERSION-}" + if [[ "${ziti_bin_ver}" == "" ]]; then + echo "ERROR: ZITI_HOME is not set!" + return 1 + fi + export ZITI_BIN_DIR="${ziti_bin_root}/ziti-${ziti_bin_ver}" + + ZITI_BINARIES_TARFILE_ABSPATH="${ZITI_HOME-}/ziti-bin/${ZITI_BINARIES_TARFILE}" + if ! test -f "${ZITI_BINARIES_TARFILE_ABSPATH}"; then + echo -e 'Downloading '"$(BLUE "${ZITI_BINARIES_TARFILE}")"' to '"$(BLUE "${ZITI_BINARIES_TARFILE_ABSPATH}")" + zitidl="https://github.com/openziti/ziti/releases/download/${ZITI_BINARIES_VERSION-}/${ZITI_BINARIES_TARFILE}" + wget -q "${zitidl}" -O "${ZITI_BINARIES_TARFILE_ABSPATH}" + else + echo -e "$(YELLOW 'Already Downloaded ')""$(BLUE "${ZITI_BINARIES_TARFILE}")"' at: '"${ZITI_BINARIES_TARFILE_ABSPATH}" + fi + + echo -e 'UNZIPPING '"$(BLUE "${ZITI_BINARIES_TARFILE_ABSPATH}")"' into: '"$(GREEN "${ZITI_BIN_DIR-}")" + rm -rf "${ziti_bin_root}/ziti-${ZITI_BINARIES_VERSION-}" + tar -xf "${ZITI_BINARIES_TARFILE_ABSPATH}" --directory "${ziti_bin_root}" + mv "${ziti_bin_root}/ziti" "${ZITI_BIN_DIR-}" + + if [[ "${1-}" == "yes" ]]; then + echo "Adding ${ZITI_BIN_DIR-} to the path if necessary:" + if [[ "$(echo "$PATH"|grep -q "${ZITI_BIN_DIR-}" && echo "yes")" == "yes" ]]; then + echo -e "$(GREEN "${ZITI_BIN_DIR-}") is already on the path" + else + echo -e "adding $(RED "${ZITI_BIN_DIR-}") to the path" + export PATH=$PATH:"${ZITI_BIN_DIR-}" + fi + fi +} + +function checkPrereqs { + commands_to_test=(curl jq wget) + missing_requirements="" + # verify all the commands required in the automation exist before trying to run the full suite + for cmd in "${commands_to_test[@]}" + do + # checking all commands are on the path before continuing... + if ! [[ -x "$(command -v "${cmd}")" ]]; then + missing_requirements="${missing_requirements} * ${cmd}\n" + fi + done + # are requirements ? if yes, stop here and help 'em out + if ! [[ "" = "${missing_requirements}" ]]; then + echo " " + echo "You're missing one or more commands that are used in this script." + echo "Please ensure the commands listed are on the path and then try again." + printf "%s\n", "${missing_requirements}" + echo " " + echo " " + return 1 + fi + echo "Let's get stated creating your local development network!" + echo "" + echo "" +} + +function checkControllerName { + if [[ ${ZITI_EDGE_CONTROLLER_HOSTNAME} == *['!'@#\$%^\&*()_+]* ]]; then + echo -e "$(RED " - The provided Network name contains an invalid character: '!'@#\$%^\&*()_+")" + return 1 + fi + return 0 +} + +function unsetZitiEnv { + for zEnvVar in $(set -o posix ; set | grep -e "^ZITI_" | sort); do envvar="$(echo "${zEnvVar}" | cut -d '=' -f1)"; echo unsetting "[${envvar}]${zEnvVar}"; unset "${envvar}"; done +} + +function issueGreeting { + #echo "-------------------------------------------------------------" + echo " " + echo " _ _ _" + echo " ____ (_) | |_ (_)" + echo " |_ / | | | __| | |" + echo " / / | | | |_ | |" + echo " /___| |_| \__| |_|" + echo "-------------------------------------------------------------" + echo " " + echo "This script will make it trivial to setup a very simple environment locally which will allow you to start" + echo "learning ziti. This environment is suitable for development work only and is not a decent representation of" + echo "a fully redundant production-caliber network." + echo "" + echo "Please note that this script will write files to your home directory into a directory named .ziti." + echo -n "For you this location will be: " + echo -e "$(BLUE "${ZITI_QUICKSTART_ENVROOT}")" + echo " " +} + +function setupZitiNetwork { + if [[ "${1-}" == "" ]]; then + echo " " + echo "Creating a controller is effectively creating a network. The name of the network will be used when writing" + echo "configuration files locally. Choose the name of your network now. The format of the network name should resemble" + echo -n "what a hostname looks like. A good choice is to actually use your system's hostname: " + echo -e "$(BLUE "$(hostname)")" + echo " " + read -rp "$(echo -ne "Network Name [$(BLUE "$(hostname)")]: ")" ZITI_NETWORK + echo " " + if checkControllerName; then + : #clear to continue + if [[ "${ZITI_NETWORK-}" == "" ]]; then + ZITI_NETWORK="$(hostname)" + fi + echo "name: ${ZITI_NETWORK-}" + else + echo " " + echo "nah bro" + return 1 + fi + echo " " + else + ZITI_NETWORK="${1-}" + fi +} + +function setupZitiHome { + export ZITI_HOME="${HOME}/.ziti/quickstart/${ZITI_NETWORK-}" +} + +function generateEnvFile { + + echo -e "Generating new network with name: $(BLUE "${ZITI_NETWORK-}")" + + if [[ "${ZITI_CONTROLLER_RAWNAME-}" == "" ]]; then export export ZITI_CONTROLLER_RAWNAME="${ZITI_NETWORK-}-controller"; fi + if [[ "${ZITI_CONTROLLER_HOSTNAME-}" == "" ]]; then export export ZITI_CONTROLLER_HOSTNAME="${ZITI_NETWORK-}"; fi + if [[ "${ZITI_EDGE_CONTROLLER_RAWNAME-}" == "" ]]; then export export ZITI_EDGE_CONTROLLER_RAWNAME="${ZITI_NETWORK-}-edge-controller"; fi + if [[ "${ZITI_EDGE_CONTROLLER_HOSTNAME-}" == "" ]]; then export export ZITI_EDGE_CONTROLLER_HOSTNAME="${ZITI_NETWORK-}"; fi + if [[ "${ZITI_ZAC_RAWNAME-}" == "" ]]; then export export ZITI_ZAC_RAWNAME="${ZITI_NETWORK-}"; fi + if [[ "${ZITI_ZAC_HOSTNAME-}" == "" ]]; then export export ZITI_ZAC_HOSTNAME="${ZITI_NETWORK-}"; fi + if [[ "${ZITI_EDGE_ROUTER_RAWNAME-}" == "" ]]; then export export ZITI_EDGE_ROUTER_RAWNAME="${ZITI_NETWORK-}-edge-router"; fi + if [[ "${ZITI_EDGE_ROUTER_HOSTNAME-}" == "" ]]; then export export ZITI_EDGE_ROUTER_HOSTNAME="${ZITI_NETWORK-}"; fi + if [[ "${ZITI_EDGE_ROUTER_PORT-}" == "" ]]; then export ZITI_EDGE_ROUTER_PORT="3022"; fi + + if [[ "${ZITI_BIN_ROOT-}" == "" ]]; then + export ZITI_BIN_ROOT="${ZITI_HOME-}/ziti-bin" + fi + + # shellcheck disable=SC2155 + export ZITI_SCRIPTS="$(realpath "${ZITI_SCRIPT_DIR}/..")" + + if ! ziti_createEnvFile; then + return 1 + fi + + export ENV_FILE="${ZITI_HOME-}/${ZITI_NETWORK-}.env" + + echo -e "environment file created and sourced from: $(BLUE "${ENV_FILE}")" + # shellcheck disable=SC1090 + source "${ENV_FILE}" +} + +function ziti_expressConfiguration { + echo " " + echo "___________ _______________________________________^__" + echo " ___ ___ ||| ___ ___ ___ ___ ___ | __ ,----\ " + echo "| | | |||| | | | | | | | | | | | | |_____\ " + echo "|___| |___|||| |___| |___| |___| | O | O | | | | \ " + echo " ||| ===== EXPRESS ==== |___|___| | |__| )" + echo "___________|||______________________________|______________/" + echo " ||| /--------" + echo "-----------'''---------------------------------------'" + echo "" + + if [[ "${1-}" == "" ]]; then + nw="$(hostname)" + else + nw="${1-}" + fi + + setupZitiNetwork "${nw}" + setupZitiHome + + if ! getLatestZiti "no"; then + echo -e "$(RED "getLatestZiti failed")" + return 1 + fi + if ! generateEnvFile; then + echo "Exiting as env file was not generated" + return 1 + fi + #checkHostsFile + + createPki + createControllerConfig + createControllerSystemdFile + initializeController + startZitiController + echo "starting the ziti controller to enroll the edge router" + waitForController + + zitiLogin + + echo -e "---------- Creating an edge router policy allowing all identities to connect to routers with a $(GREEN "#public") attribute" + unused=$("${ZITI_BIN_DIR-}/ziti" edge delete edge-router-policy allEdgeRouters) + unused=$("${ZITI_BIN_DIR-}/ziti" edge create edge-router-policy allEdgeRouters --edge-router-roles '#public' --identity-roles '#all' ) + + echo -e "---------- Creating a service edge router policy allowing all services to use $(GREEN "#public") edge routers" + unused=$("${ZITI_BIN_DIR-}/ziti" edge delete service-edge-router-policy allSvcPublicRouters) + unused=$("${ZITI_BIN_DIR-}/ziti" edge create service-edge-router-policy allSvcPublicRouters --edge-router-roles '#public' --service-roles '#all') + + createRouterPki + createEdgeRouterConfig "${ZITI_EDGE_ROUTER_RAWNAME}" + createRouterSystemdFile "${ZITI_EDGE_ROUTER_RAWNAME}" + + echo "---------- Creating edge-router ${ZITI_EDGE_ROUTER_RAWNAME}...." + unused=$("${ZITI_BIN_DIR-}/ziti" edge delete edge-router "${ZITI_EDGE_ROUTER_RAWNAME}") + unused=$("${ZITI_BIN_DIR-}/ziti" edge create edge-router "${ZITI_EDGE_ROUTER_RAWNAME}" -o "${ZITI_HOME-}/${ZITI_EDGE_ROUTER_RAWNAME}.jwt" -t) + sleep 1 + echo "---------- Enrolling edge-router ${ZITI_EDGE_ROUTER_RAWNAME}...." + + unused=$("${ZITI_BIN_DIR-}/ziti-router" enroll "${ZITI_HOME-}/${ZITI_EDGE_ROUTER_RAWNAME}.yaml" --jwt "${ZITI_HOME-}/${ZITI_EDGE_ROUTER_RAWNAME}.jwt" &> "${ZITI_HOME-}/${ZITI_EDGE_ROUTER_RAWNAME}.enrollment.log") + echo "" + sleep 1 + # shellcheck disable=SC2034 + unused=$("${ZITI_BIN_DIR-}/ziti-router" run "${ZITI_HOME-}/${ZITI_EDGE_ROUTER_RAWNAME}.yaml" > "${ZITI_HOME-}/${ZITI_EDGE_ROUTER_RAWNAME}.log" 2>&1 &) + + echo "Express setup complete!" +} + +function decideToUseDefaultZitiHome { + yn="" + while true + do + echo "ZITI_HOME has not been set. Do you want to use the default ZITI_HOME: ${DEFAULT_ZITI_HOME_LOCATION}" + echo " " + read -rp "Select an action: " yn + case $yn in + [yY]* ) + break;; + [Nn]* ) + echo "" + return 1;; + * ) + echo " " + echo "Answer $yn is not valid. Please answer yes or no. (y/n [yes/NO])";; + esac + yn= + done + echo " " +} + +function decideOperation { + yn="${1-}" + while true + do + if [[ "${yn}" == "" ]]; then + echo "What sort of operation are you looking to perform?" + echo " 1.) Express configuration - a simple overlay will be spawned containing one controller and two edge routers" + echo " 2.) Create Controller configuration - answer a few questions and a controller config will be emitted" + echo " 3.) Create Edge Router configuration - answer a few questions and an edge router config will be emitted" + echo " 4.) Start a network with the provided name" + echo " " + read -rp "Select an action: " yn + fi + case $yn in + [1]* ) + ziti_expressConfiguration "$2" + break;; + [2]* ) + generateEnvFile + + ;; + [3]* ) + echo "333 has been chosen" + echo " " + ;; + [4]* ) + echo "4444 has been chosen" + echo " " + ;; + [yYqQeE]* ) + break + ;; + [Nn]* ) + echo ""; echo "Ok - come back when you're ready." + exit;; + * ) echo "Please answer yes or no. (yes/NO)";; + esac + yn= + done + echo " " +} + +function expressInstall { + #greet the user with the banner and quick blurb about what to expect + issueGreeting + + #make sure the user has all the necessary commands to be successful + checkPrereqs + + #prompt the user for input and do what they want/need + decideOperation 1 "${1-}" +} + +function pki_client_server { + name_local=${1-} + ZITI_CA_NAME_local=$2 + ip_local=$3 + + if [[ "${ip_local}" == "" ]]; then + ip_local="127.0.0.1" + fi + + if ! test -f "${ZITI_PKI}/${ZITI_CA_NAME_local}/keys/${name_local}-server.key"; then + echo "Creating server cert from ca: ${ZITI_CA_NAME_local} for ${name_local}" + "${ZITI_BIN_DIR-}/ziti" pki create server --pki-root="${ZITI_PKI}" --ca-name "${ZITI_CA_NAME_local}" \ + --server-file "${name_local}-server" \ + --dns "${name_local},localhost" --ip "${ip_local}" \ + --server-name "${name_local} server certificate" + else + echo "Creating server cert from ca: ${ZITI_CA_NAME_local} for ${name_local}" + echo "key exists" + fi + + if ! test -f "${ZITI_PKI}/${ZITI_CA_NAME_local}/keys/${name_local}-client.key"; then + echo "Creating client cert from ca: ${ZITI_CA_NAME_local} for ${name_local}" + "${ZITI_BIN_DIR-}/ziti" pki create client --pki-root="${ZITI_PKI}" --ca-name "${ZITI_CA_NAME_local}" \ + --client-file "${name_local}-client" \ + --key-file "${name_local}-server" \ + --client-name "${name_local}" + else + echo "Creating client cert from ca: ${ZITI_CA_NAME_local} for ${name_local}" + echo "key exists" + fi + echo " " +} + +function pki_create_ca { + if ! test -f "${ZITI_PKI}/${1}/keys/${1}.key"; then + echo "Creating CA: ${1}" + "${ZITI_BIN_DIR-}/ziti" pki create ca --pki-root="${ZITI_PKI}" --ca-file="${1}" --ca-name="${1} Root CA" + else + echo "Creating CA: ${1}" + echo "key exists" + fi + echo " " +} + +function pki_create_intermediate { + if ! test -f "${ZITI_PKI}/${2}/keys/${2}.key"; then + echo "Creating intermediate: ${1} ${2} ${3}" + "${ZITI_BIN_DIR-}/ziti" pki create intermediate --pki-root "${ZITI_PKI}" --ca-name "${1}" \ + --intermediate-name "${2}" \ + --intermediate-file "${2}" --max-path-len "${3}" + else + echo "Creating intermediate: ${1} ${2} ${3}" + echo "key exists" + fi + echo " " +} +function printUsage() +{ + echo "Usage: ${1-} [cert to test] [ca pool to use]" +} + +function verifyCertAgainstPool() +{ + if [[ "" == "${1-}" ]] + then + printUsage "verifyCertAgainstPool" + return 1 + fi + + if [[ "" == "$2" ]] + then + printUsage "verifyCertAgainstPool" + return 1 + fi + + echo " Verifying that this certificate:" + echo " - ${1-}" + echo " is valid for this ca pool:" + echo " - $2" + echo "" + openssl verify -partial_chain -CAfile "$2" "${1-}" + # shellcheck disable=SC2181 + if [ $? -eq 0 ]; then + echo "" + echo "============ SUCCESS! ============" + else + echo "" + echo "============ FAILED TO VALIDATE ============" + fi +} + +function showIssuerAndSubjectForPEM() +{ + echo "Displaying Issuer and Subject for cert pool:" + echo " ${1-}" + openssl crl2pkcs7 -nocrl -certfile "${1-}" | openssl pkcs7 -print_certs -text -noout | grep -E "(Subject|Issuer)" +} + +function createRouterPki { +pki_client_server "${ZITI_EDGE_ROUTER_RAWNAME}" "${ZITI_CONTROLLER_INTERMEDIATE_NAME}" "${ZITI_EDGE_ROUTER_IP_OVERRIDE-}" +} + +function createPrivateRouterConfig { +cat > "${ZITI_HOME-}/${ZITI_EDGE_ROUTER_RAWNAME}.yaml" < "${ZITI_HOME-}/${ZITI_EDGE_ROUTER_RAWNAME}.yaml" < "${ZITI_HOME-}/${router_name}.yaml" < "${ziti_home}/${router_name}.yaml" < "${ZITI_HOME-}/identities.yml" < "${ziti_home}/controller.yaml" < "${ENV_FILE}" + for zEnvVar in $(set -o posix ; set | grep ZITI_ | sort); do envvar="$(echo "${zEnvVar}" | cut -d '=' -f1)"; envval="$(echo "${zEnvVar}" | cut -d '=' -f2-100)"; echo "export ${envvar}=\"${envval}\"" >> "${ENV_FILE}"; done + + export PFXLOG_NO_JSON=true + # shellcheck disable=SC2129 + echo "export PFXLOG_NO_JSON=true" >> "${ENV_FILE}" + + echo "alias zec='ziti edge controller'" >> "${ENV_FILE}" + echo "alias zlogin='ziti edge controller login \"${ZITI_EDGE_CONTROLLER_API}\" -u \"${ZITI_USER-}\" -p \"${ZITI_PWD}\" -c \"${ZITI_PKI}/${ZITI_EDGE_CONTROLLER_INTERMEDIATE_NAME}/certs/${ZITI_EDGE_CONTROLLER_INTERMEDIATE_NAME}.cert\"'" >> "${ENV_FILE}" + echo "alias psz='ps -ef | grep ziti'" >> "${ENV_FILE}" + + #when sourcing the emitted file add the bin folder to the path + tee -a "${ENV_FILE}" > /dev/null <<'heredoc' +echo " " +if [[ ! "$(echo "$PATH"|grep -q "${ZITI_BIN_DIR}" && echo "yes")" == "yes" ]]; then + echo "adding ${ZITI_BIN_DIR} to the path" + export PATH=$PATH:"${ZITI_BIN_DIR}" +else +echo " ziti binaries are located at: ${ZITI_BIN_DIR}" +echo -e 'add this to your path if you want by executing: export PATH=$PATH:'"${ZITI_BIN_DIR}" +fi +heredoc + +} + +function waitForController { + # shellcheck disable=SC2091 + until $(curl -s -o /dev/null --fail -k "https://${ZITI_EDGE_CONTROLLER_API}"); do + echo "waiting for https://${ZITI_EDGE_CONTROLLER_API}" + sleep 2 + done +} + +function createControllerSystemdFile { + ziti_home="${ZITI_HOME-}" + if [[ "${ziti_home}" == "" ]]; then + echo -e " * ERROR: $(RED "ZITI_HOME is not set") " + return 1 + fi + + ziti_bin_dir="${ZITI_BIN_DIR-}" + if [[ "${ziti_bin_dir}" == "" ]]; then + echo -e " * ERROR: $(RED "ZITI_BIN_DIR is not set") " + return 1 + fi + + ziti_ctrl_name="${ZITI_CONTROLLER_RAWNAME-}" + if [[ "${ziti_ctrl_name}" == "" ]]; then + echo -e " * ERROR: $(RED "ZITI_CONTROLLER_RAWNAME is not set") " + return 1 + fi + +systemd_file="${ziti_home}/ziti-controller.service" +cat > "${systemd_file}" < "${systemd_file}" < "${systemd_file}" </dev/null 2>&1 && pwd )" + +set +uo pipefail \ No newline at end of file diff --git a/quickstart/docker/pushLatestDocker.sh b/quickstart/docker/pushLatestDocker.sh index 2427f7607..42f62fd9e 100755 --- a/quickstart/docker/pushLatestDocker.sh +++ b/quickstart/docker/pushLatestDocker.sh @@ -26,9 +26,9 @@ if [ -d "${ZITI_BIN_ROOT}/image/ziti.ignore" ]; then fi docker run --rm -it openziti/quickstart /openziti/ziti-bin/ziti version -if [ -f "${ZITI_BIN_ROOT}/ziti-*tar.gz" ]; then - rm "${ZITI_BIN_ROOT}/ziti-*tar.gz" -fi +#if [ -f "${ZITI_BIN_ROOT}/ziti-*tar.gz" ]; then +# rm "${ZITI_BIN_ROOT}/ziti-*tar.gz" +#fi if [ -d "${ZITI_BIN_ROOT}/ziti-bin" ]; then rm -rf "${ZITI_BIN_ROOT}/ziti-bin" fi diff --git a/quickstart/img.png b/quickstart/img.png deleted file mode 100644 index ea95d23c9..000000000 Binary files a/quickstart/img.png and /dev/null differ diff --git a/quickstart/kubernetes/sidecar-tunnel/kubernetes-sidecar-tunnel-quickstart.md b/quickstart/kubernetes/sidecar-tunnel/kubernetes-sidecar-tunnel-quickstart.md index 303259d68..0c7d8de0c 100644 --- a/quickstart/kubernetes/sidecar-tunnel/kubernetes-sidecar-tunnel-quickstart.md +++ b/quickstart/kubernetes/sidecar-tunnel/kubernetes-sidecar-tunnel-quickstart.md @@ -101,8 +101,8 @@ Save the following yaml to a file named tunnel-sidecar-demo.yaml mountPath: /netfoundry securityContext: capabilities: - add: - - NET_ADMIN + add: + - NET_ADMIN dnsPolicy: "None" dnsConfig: nameservers: diff --git a/quickstart/local/create-controller-config.sh b/quickstart/local/create-controller-config.sh deleted file mode 120000 index 674b9b65a..000000000 --- a/quickstart/local/create-controller-config.sh +++ /dev/null @@ -1 +0,0 @@ -../docker/image/create-controller-config.sh \ No newline at end of file diff --git a/quickstart/local/create-edge-router-config.sh b/quickstart/local/create-edge-router-config.sh deleted file mode 120000 index be35e7a7f..000000000 --- a/quickstart/local/create-edge-router-config.sh +++ /dev/null @@ -1 +0,0 @@ -../docker/image/create-edge-router-config.sh \ No newline at end of file diff --git a/quickstart/local/create-pki.sh b/quickstart/local/create-pki.sh deleted file mode 120000 index 0f78118d4..000000000 --- a/quickstart/local/create-pki.sh +++ /dev/null @@ -1 +0,0 @@ -../docker/image/create-pki.sh \ No newline at end of file diff --git a/quickstart/local/create-router-pki.sh b/quickstart/local/create-router-pki.sh deleted file mode 120000 index e91745423..000000000 --- a/quickstart/local/create-router-pki.sh +++ /dev/null @@ -1 +0,0 @@ -../docker/image/create-router-pki.sh \ No newline at end of file diff --git a/quickstart/local/express/README.md b/quickstart/local/express/README.md deleted file mode 100644 index b61649f23..000000000 --- a/quickstart/local/express/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Express Dev Env - -This script is meant to provide a very quick method of deploying an absolute minimum ziti setup: one controller, one edge-router. - -This environment is entirely suitable for local development against the ziti apis. This is not a recommended configuration production configuration. diff --git a/quickstart/local/express/express-dev-env.sh b/quickstart/local/express/express-dev-env.sh deleted file mode 100755 index 55d3a3011..000000000 --- a/quickstart/local/express/express-dev-env.sh +++ /dev/null @@ -1,194 +0,0 @@ -#!/bin/bash - -ZITI_SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -ZITI_QUICKSTART_ENVROOT="${HOME}/.ziti/quickstart" -ZITI_QUICKSTART_SCRIPT_ROOT="$(realpath "${ZITI_SCRIPT_DIR}/../../")" -. "${ZITI_QUICKSTART_SCRIPT_ROOT}/ziti-cli-functions.sh" - -function issueGreeting { - #echo "-------------------------------------------------------------" - echo " " - echo " _ _ _" - echo " ____ (_) | |_ (_)" - echo " |_ / | | | __| | |" - echo " / / | | | |_ | |" - echo " /___| |_| \__| |_|" - echo "-------------------------------------------------------------" - echo " " - echo "This script will make it trivial to setup a very simple environment locally which will allow you to start" - echo "learning ziti. This environment is suitable for development work only and is not a decent representation of" - echo "a fully redundant production-caliber network." - echo "" - echo "Please note that this script will write files to your home directory into a directory named .ziti." - echo -n "For you this location will be: " - echo -e "$(BLUE "${ZITI_QUICKSTART_ENVROOT}")" - echo " " -} - -function setupZitiNetwork { - if [[ "$1" == "" ]]; then - echo " " - echo "Creating a controller is effectively creating a network. The name of the network will be used when writing" - echo "configuration files locally. Choose the name of your network now. The format of the network name should resemble" - echo -n "what a hostname looks like. A good choice is to actually use your system's hostname: " - echo -e "$(BLUE $(hostname))" - echo " " - read -p "$(echo -ne "Network Name [$(BLUE $(hostname))]: ")" ZITI_NETWORK - echo " " - if checkControllerName; then - : #clear to continue - if [[ "ZITI_NETWORK" == "" ]]; then - ZITI_NETWORK="$(hostname)" - fi - echo "name: ${ZITI_NETWORK}" - else - echo " " - echo "nah bro" - return 1 - fi - echo " " - else - ZITI_NETWORK="$1" - fi -} - -function setupZitiHome { - export ZITI_HOME="${HOME}/.ziti/quickstart/${ZITI_NETWORK}" -} - -function generateEnvFile { - - echo -e "Generating new network with name: $(BLUE "${ZITI_NETWORK}")" - - if [[ "${ZITI_CONTROLLER_RAWNAME}" == "" ]]; then export export ZITI_CONTROLLER_RAWNAME="${ZITI_NETWORK}-controller"; fi - if [[ "${ZITI_CONTROLLER_HOSTNAME}" == "" ]]; then export export ZITI_CONTROLLER_HOSTNAME="${ZITI_NETWORK}"; fi - if [[ "${ZITI_EDGE_CONTROLLER_RAWNAME}" == "" ]]; then export export ZITI_EDGE_CONTROLLER_RAWNAME="${ZITI_NETWORK}-edge-controller"; fi - if [[ "${ZITI_EDGE_CONTROLLER_HOSTNAME}" == "" ]]; then export export ZITI_EDGE_CONTROLLER_HOSTNAME="${ZITI_NETWORK}"; fi - if [[ "${ZITI_ZAC_RAWNAME}" == "" ]]; then export export ZITI_ZAC_RAWNAME="${ZITI_NETWORK}"; fi - if [[ "${ZITI_ZAC_HOSTNAME}" == "" ]]; then export export ZITI_ZAC_HOSTNAME="${ZITI_NETWORK}"; fi - if [[ "${ZITI_EDGE_ROUTER_RAWNAME}" == "" ]]; then export export ZITI_EDGE_ROUTER_RAWNAME="${ZITI_NETWORK}-edge-router"; fi - if [[ "${ZITI_EDGE_ROUTER_HOSTNAME}" == "" ]]; then export export ZITI_EDGE_ROUTER_HOSTNAME="${ZITI_NETWORK}"; fi - if [[ "${ZITI_EDGE_ROUTER_PORT}" == "" ]]; then export ZITI_EDGE_ROUTER_PORT="3022"; fi - - if [[ "${ZITI_BIN_ROOT}" == "" ]]; then - export ZITI_BIN_ROOT="${ZITI_HOME}/ziti-bin" - fi - - export ZITI_SCRIPTS="$(realpath "${ZITI_SCRIPT_DIR}/..")" - export ZITI_SHARED=${ZITI_HOME} - export ENV_FILE="${ZITI_HOME}/${ZITI_NETWORK}.env" - "${ZITI_QUICKSTART_SCRIPT_ROOT}/docker/image/env.sh" - echo -e "environment file created and sourced from: $(BLUE "${ENV_FILE}")" - source "${ENV_FILE}" -} - -function expressConfiguration { - echo " " - echo "___________ _______________________________________^__" - echo " ___ ___ ||| ___ ___ ___ ___ ___ | __ ,----\ " - echo "| | | |||| | | | | | | | | | | | | |_____\ " - echo "|___| |___|||| |___| |___| |___| | O | O | | | | \ " - echo " ||| ===== EXPRESS ==== |___|___| | |__| )" - echo "___________|||______________________________|______________/" - echo " ||| /--------" - echo "-----------'''---------------------------------------'" - echo "" - - if [[ "$1" == "" ]]; then - nw="$(hostname)" - else - nw="$1" - fi - - setupZitiNetwork "${nw}" - setupZitiHome - - getLatestZiti "no" - generateEnvFile - #checkHostsFile - - generatePki - generateControllerConfig - initializeController - startZitiController - echo "starting the ziti controller to enroll the edge router" - sleep 2 - - zitiLogin - - echo -e "---------- Creating an edge router policy allowing all identities to connect to routers with a $(GREEN "#public") attribute" - unused=$("${ZITI_BIN_DIR}/ziti" edge delete edge-router-policy allEdgeRouters) - unused=$("${ZITI_BIN_DIR}/ziti" edge create edge-router-policy allEdgeRouters --edge-router-roles '#public' --identity-roles '#all' ) - - echo -e "---------- Creating a service edge router policy allowing all services to use $(GREEN "#public") edge routers" - unused=$("${ZITI_BIN_DIR}/ziti" edge delete service-edge-router-policy allSvcPublicRouters) - unused=$("${ZITI_BIN_DIR}/ziti" edge create service-edge-router-policy allSvcPublicRouters --edge-router-roles '#public' --service-roles '#all') - - "${ZITI_SCRIPTS}/create-router-pki.sh" - generateEdgeRouterConfig - - echo "---------- Creating edge-router ${ZITI_EDGE_ROUTER_RAWNAME}...." - unused=$("${ZITI_BIN_DIR}/ziti" edge delete edge-router "${ZITI_EDGE_ROUTER_RAWNAME}") - unused=$("${ZITI_BIN_DIR}/ziti" edge create edge-router "${ZITI_EDGE_ROUTER_RAWNAME}" -o "${ZITI_HOME}/${ZITI_EDGE_ROUTER_RAWNAME}.jwt" -t) - sleep 1 - echo "---------- Enrolling edge-router ${ZITI_EDGE_ROUTER_RAWNAME}...." - - unused=$("${ZITI_BIN_DIR}/ziti-router" enroll "${ZITI_HOME}/${ZITI_EDGE_ROUTER_RAWNAME}.yaml" --jwt "${ZITI_HOME}/${ZITI_EDGE_ROUTER_RAWNAME}.jwt" &> "${ZITI_HOME}/${ZITI_EDGE_ROUTER_RAWNAME}.enrollment.log") - echo "" - sleep 1 - unused=$("${ZITI_BIN_DIR}/ziti-router" run "${ZITI_HOME}/${ZITI_EDGE_ROUTER_RAWNAME}.yaml" > "${ZITI_HOME}/${ZITI_EDGE_ROUTER_RAWNAME}.log" 2>&1 &) -} - -function decideOperation { - if [[ "$1" != "" ]]; then - yn=$1 - fi - while true - do - if [[ "${yn}" == "" ]]; then - echo "What sort of operation are you looking to perform?" - echo " 1.) Express configuration - a simple overlay will be spawned containing one controller and two edge routers" - echo " 2.) Create Controller configuration - answer a few questions and a controller config will be emitted" - echo " 3.) Create Edge Router configuration - answer a few questions and an edge router config will be emitted" - echo " 4.) Start a network with the provided name" - echo " " - read -p "Select an action: " yn - fi - case $yn in - [1]* ) - expressConfiguration "$2" - break;; - [2]* ) - generateEnvFile - - ;; - [3]* ) - echo "333 has been chosen" - echo " " - ;; - [4]* ) - echo "4444 has been chosen" - echo " " - ;; - [yYqQeE]* ) - break - ;; - [Nn]* ) - echo ""; echo "Ok - come back when you're ready." - exit;; - * ) echo "Please answer yes or no. (yes/NO)";; - esac - yn= - done - echo " " -} - -#greet the user with the banner and quick blurb about what to expect -issueGreeting - -#make sure the user has all the necessary commands to be successful -checkPrereqs - -#prompt the user for input and do what they want/need -decideOperation 1 "$1" - diff --git a/quickstart/local/pki-functions.sh b/quickstart/local/pki-functions.sh deleted file mode 120000 index 6d7173816..000000000 --- a/quickstart/local/pki-functions.sh +++ /dev/null @@ -1 +0,0 @@ -../docker/image/pki-functions.sh \ No newline at end of file diff --git a/quickstart/local/restart-ziti.sh b/quickstart/local/restart-ziti.sh index c934fd7bf..21dfb963e 100755 --- a/quickstart/local/restart-ziti.sh +++ b/quickstart/local/restart-ziti.sh @@ -9,7 +9,7 @@ else export network_name="${USER}" fi -source ${curdir}/env.sh +ziti_createEnvFile DIRNAME=$(dirname $0) [[ ${USE_DNSMASQ:-} -eq 1 ]] && source ${DIRNAME}/run-dns.sh diff --git a/quickstart/security-groups.png b/quickstart/security-groups.png new file mode 100644 index 000000000..242053ced Binary files /dev/null and b/quickstart/security-groups.png differ diff --git a/quickstart/ziti-cli-functions.sh b/quickstart/ziti-cli-functions.sh deleted file mode 100644 index 01524790b..000000000 --- a/quickstart/ziti-cli-functions.sh +++ /dev/null @@ -1,197 +0,0 @@ -#!/bin/bash - -export ZITI_QUICKSTART_SCRIPT_ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" -export ZITI_QUICKSTART_ENVROOT="${HOME}/.ziti/quickstart" - -ASCI_WHITE='\033[01;37m' -ASCI_RESTORE='\033[0m' -ASCI_RED='\033[00;31m' -ASCI_GREEN='\033[00;32m' -ASCI_YELLOW='\033[00;33m' -ASCI_BLUE='\033[00;34m' -ASCI_MAGENTA='\033[00;35m' -ASCI_PURPLE='\033[00;35m' -ASCI_CYAN='\033[00;36m' -ASCI_LIGHTGRAY='\033[00;37m' -ASCI_LRED='\033[01;31m' -ASCI_LGREEN='\033[01;32m' -ASCI_LYELLOW='\033[01;33m' -ASCI_LBLUE='\033[01;34m' -ASCI_LMAGENTA='\033[01;35m' -ASCI_LPURPLE='\033[01;35m' -ASCI_LCYAN='\033[01;36m' - -function WHITE { - echo "${ASCI_WHITE}$1${ASCI_RESTORE}" -} -function RED { - echo "${ASCI_RED}$1${ASCI_RESTORE}" -} -function GREEN { - echo "${ASCI_GREEN}$1${ASCI_RESTORE}" -} -function YELLOW { - echo "${ASCI_YELLOW}$1${ASCI_RESTORE}" -} -function BLUE { - echo "${ASCI_BLUE}$1${ASCI_RESTORE}" -} - -function zitiLogin { - unused=$("${ZITI_BIN_DIR}/ziti" edge login "${ZITI_EDGE_CONTROLLER_API}" -u "${ZITI_USER}" -p "${ZITI_PWD}" -c "${ZITI_PKI}/${ZITI_EDGE_CONTROLLER_ROOTCA_NAME}/certs/${ZITI_EDGE_CONTROLLER_INTERMEDIATE_NAME}.cert") -} -function reinitializeZitiController { - cleanZitiController -} -function cleanZitiController { - rm -rf "${ZITI_HOME}/db" - mkdir "${ZITI_HOME}/db" - initializeController -} -function generateControllerConfig { - "${ZITI_QUICKSTART_SCRIPT_ROOT}/docker/image/create-controller-config.sh" -} -function generateEdgeRouterConfig { - echo "RUNNING: ${ZITI_QUICKSTART_SCRIPT_ROOT}/docker/image/create-edge-router-config.sh" - "${ZITI_QUICKSTART_SCRIPT_ROOT}/docker/image/create-edge-router-config.sh" -} -function initializeController { - "${ZITI_BIN_DIR}/ziti-controller" edge init "${ZITI_HOME}/controller.yaml" -u "${ZITI_USER}" -p "${ZITI_PWD}" &> "${ZITI_HOME}/controller-init.log" - echo -e "ziti-controller initialized. see $(BLUE ${ZITI_HOME}/controller-init.log) for details" -} -function startZitiController { - # shellcheck disable=SC2034 - unused=$("${ZITI_BIN_DIR}/ziti-controller" run "${ZITI_HOME}/controller.yaml" > "${ZITI_HOME}/ziti-edge-controller.log" 2>&1 &) - echo -e "ziti-controller started. log located at: $(BLUE ${ZITI_HOME}/ziti-edge-controller.log)" -} -function stopZitiController { - killall ziti-controller -} -function checkHostsFile { - ctrlexists=$(grep -c ${ZITI_CONTROLLER_HOSTNAME} /etc/hosts) - edgectrlexists=$(grep -c ${ZITI_EDGE_CONTROLLER_HOSTNAME} /etc/hosts) - erexists=$(grep -c ${ZITI_EDGE_ROUTER_HOSTNAME} /etc/hosts) - - if [[ "0" = "${ctrlexists}" ]] || [[ "0" = "${edgectrlexists}" ]] || [[ "0" = "${erexists}" ]]; then - echo " " - echo -e "$(YELLOW "Ziti is generally used to create an overlay network. Generally speaking this will involve more than one host")" - echo -e "$(YELLOW "Since this is a script geared towards setting up a very minimal development environment it needs to make some")" - echo -e "$(YELLOW "assumptions. One of these assumptions is that the three specific entries are entered onto your hosts file.")" - echo -e "$(YELLOW "One or more of these are missing:")" - echo " " - if [[ "0" == "${ctrlexists}" ]]; then - echo -e " * $(RED "MISSING: ${ZITI_EDGE_CONTROLLER_HOSTNAME}") " - else - echo -e " * $(GREEN " FOUND: ${ZITI_EDGE_CONTROLLER_HOSTNAME}") " - fi - if [[ "0" == "${edgectrlexists}" ]]; then - echo -e " * $(RED "MISSING: ${ZITI_EDGE_CONTROLLER_HOSTNAME}") " - else - echo -e " * $(GREEN " FOUND: ${ZITI_EDGE_CONTROLLER_HOSTNAME}") " - fi - if [[ "0" == "${erexists}" ]]; then - echo -e " * $(RED "MISSING: ${ZITI_EDGE_ROUTER_HOSTNAME}") " - else - echo -e " * $(GREEN " FOUND: ${ZITI_EDGE_ROUTER_HOSTNAME}") " - fi - - echo " " - echo "The easiest way to correct this is to run the following command:" - echo " echo \"127.0.0.1 ${ZITI_CONTROLLER_HOSTNAME} ${ZITI_EDGE_CONTROLLER_HOSTNAME} ${ZITI_EDGE_ROUTER_HOSTNAME}\" | sudo tee -a /etc/hosts" - echo " " - echo "add these entries to your hosts file, and rerun the script when ready" - return - fi -} - -function getLatestZitiVersion { - if [[ "${ZITI_BINARIES_VERSION}" == "" ]]; then - zitilatest=$(curl -s https://api.github.com/repos/openziti/ziti/releases/latest) - echo ${zitilatest} > /mnt/v/temp/a.txt - export ZITI_BINARIES_TARFILE=$(echo "${zitilatest}" | jq -r '.assets[] | select(.name | startswith("ziti-linux-amd")) | .name') - # shellcheck disable=SC2155 - export ZITI_BINARIES_VERSION=$(echo "${zitilatest}" | jq -r '.tag_name') - fi - #echo -e 'Ziti tar.gz: '"$(BLUE "${ZITI_BINARIES_TARFILE}")" - #echo -e 'Latest ziti is: '"$(BLUE "${ZITI_BINARIES_VERSION}")" -} - -function getLatestZiti { - if [[ "${ZITI_HOME}" == "" ]]; then - echo "ERROR: ZITI_HOME is not set!" - return - fi - if [[ "${ZITI_BIN_ROOT}" == "" ]]; then - export ZITI_BIN_ROOT="${ZITI_HOME}/ziti-bin" - fi - mkdir -p "${ZITI_BIN_ROOT}" - getLatestZitiVersion - export ZITI_BIN_DIR="${ZITI_BIN_ROOT}/ziti-${ZITI_BINARIES_VERSION}" - - ZITI_BINARIES_TARFILE_ABSPATH="${ZITI_HOME}/ziti-bin/${ZITI_BINARIES_TARFILE}" - if ! test -f "${ZITI_BINARIES_TARFILE_ABSPATH}"; then - echo -e 'Downloading '"$(BLUE "${ZITI_BINARIES_TARFILE}")"' to '"$(BLUE "${ZITI_BINARIES_TARFILE_ABSPATH}")" - zitidl="https://github.com/openziti/ziti/releases/download/${ZITI_BINARIES_VERSION}/${ZITI_BINARIES_TARFILE}" - wget -q "${zitidl}" -O "${ZITI_BINARIES_TARFILE_ABSPATH}" - else - echo -e "$(YELLOW 'Already Downloaded ')""$(BLUE "${ZITI_BINARIES_TARFILE}")"' at: '"${ZITI_BINARIES_TARFILE_ABSPATH}" - fi - - echo -e 'UNZIPPING '"$(BLUE "${ZITI_BINARIES_TARFILE_ABSPATH}")"' into: '"$(GREEN ${ZITI_BIN_DIR})" - rm -rf "${ZITI_BIN_ROOT}/ziti-${ZITI_BINARIES_VERSION}" - tar -xf "${ZITI_BINARIES_TARFILE_ABSPATH}" --directory "${ZITI_BIN_ROOT}" - mv "${ZITI_BIN_ROOT}/ziti" "${ZITI_BIN_DIR}" - - if [[ "$1" == "yes" ]]; then - echo "Adding ${ZITI_BIN_DIR} to the path if necessary:" - if [[ "$(echo "$PATH"|grep -q "${ZITI_BIN_DIR}" && echo "yes")" == "yes" ]]; then - echo -e "$(GREEN "${ZITI_BIN_DIR}") is already on the path" - else - echo -e "adding $(RED "${ZITI_BIN_DIR}") to the path" - export PATH=$PATH:"${ZITI_BIN_DIR}" - fi - fi -} - -function generatePki { - echo "Generating PKI" - "${ZITI_QUICKSTART_SCRIPT_ROOT}/docker/image/create-pki.sh" -} - -function checkPrereqs { - commands_to_test=(curl jq wget) - - # verify all the commands required in the automation exist before trying to run the full suite - for cmd in "${commands_to_test[@]}" - do - # checking all commands are on the path before continuing... - if ! [[ -x "$(command -v ${cmd})" ]]; then - missing_requirements="${missing_requirements} * ${cmd}\n" - fi - done - # are requirements ? if yes, stop here and help 'em out - if ! [[ "" = "${missing_requirements}" ]]; then - echo " " - echo "You're missing one or more commands that are used in this script." - echo "Please ensure the commands listed are on the path and then try again." - printf "\n${missing_requirements}" - echo " " - echo " " - return - fi - echo "Let's get stated creating your local development network!" - echo "" - echo "" -} - -function checkControllerName { - if [[ ${ZITI_EDGE_CONTROLLER_HOSTNAME} == *['!'@#\$%^\&*()_+]* ]]; then - echo -e "$(RED " - The provided Network name contains an invalid character: '!'@#\$%^\&*()_+")" - return 1 - fi - return 0 -} - -function unsetZitiEnv { - for zEnvVar in $(set -o posix ; set | grep -e "^ZITI_" | sort); do envvar="$(echo "${zEnvVar}" | cut -d '=' -f1)"; echo unsetting "[${envvar}]${zEnvVar}"; unset "${envvar}"; done -} \ No newline at end of file diff --git a/quickstart/ziti-cli-functions.sh b/quickstart/ziti-cli-functions.sh new file mode 120000 index 000000000..50707f689 --- /dev/null +++ b/quickstart/ziti-cli-functions.sh @@ -0,0 +1 @@ +docker/image/ziti-cli-functions.sh \ No newline at end of file diff --git a/ziti/cmd/ziti/cmd/edge_controller/create_posture_check.go b/ziti/cmd/ziti/cmd/edge_controller/create_posture_check.go index 3eebac855..388e39c15 100644 --- a/ziti/cmd/ziti/cmd/edge_controller/create_posture_check.go +++ b/ziti/cmd/ziti/cmd/edge_controller/create_posture_check.go @@ -19,9 +19,12 @@ package edge_controller import ( "fmt" "github.com/Jeffail/gabs" + "github.com/openziti/edge/rest_management_api_client/posture_checks" + "github.com/openziti/edge/rest_model" "github.com/openziti/ziti/ziti/cmd/ziti/cmd/common" cmdutil "github.com/openziti/ziti/ziti/cmd/ziti/cmd/factory" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" + "github.com/openziti/ziti/ziti/cmd/ziti/util" "github.com/spf13/cobra" "io" "regexp" @@ -39,6 +42,7 @@ func newCreatePostureCheckCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer cmd.AddCommand(newCreatePostureCheckProcessCmd(f, out, errOut)) cmd.AddCommand(newCreatePostureCheckOsCmd(f, out, errOut)) cmd.AddCommand(newCreatePostureCheckMfaCmd(f, out, errOut)) + cmd.AddCommand(newCreatePostureCheckProcessMultiCmd(f, out, errOut)) return cmd } @@ -67,12 +71,26 @@ type createPostureCheckOsOptions struct { type createPostureCheckProcessOptions struct { createPostureCheckOptions - hash []string + hashes []string signer string normalizedOs string path string } +type createPostureCheckProcessMultiOptions struct { + createPostureCheckOptions + rawBinaryFileHashes []string //csv per process then by pipe delimited, flags parses the CSV + binaryFileHashes [][]string + + rawBinarySigners []string //csv per process then by pipe delimited, flags parses the CSV + binarySigners [][]string + + semantic string + osTypes []string + paths []string + name string +} + func (options *createPostureCheckOptions) addPostureFlags(cmd *cobra.Command) { // allow interspersing positional args and flags cmd.Flags().SetInterspersed(true) @@ -172,7 +190,7 @@ func newCreatePostureCheckProcessCmd(f cmdutil.Factory, out io.Writer, errOut io }, tags: make(map[string]string), }, - hash: nil, + hashes: nil, signer: "", } @@ -208,12 +226,103 @@ func newCreatePostureCheckProcessCmd(f cmdutil.Factory, out io.Writer, errOut io options.AddCommonFlags(cmd) options.createPostureCheckOptions.addPostureFlags(cmd) - cmd.Flags().StringSliceVarP(&options.hash, "hash-sig", "s", nil, "One or more sha512 hashes separated by commas of valid binaries") + cmd.Flags().StringSliceVarP(&options.hashes, "hash-sigs", "s", nil, "One or more sha512 hashes separated by commas of valid binaries") cmd.Flags().StringVarP(&options.signer, "signer-fingerprint", "f", "", "The sha1 hash of a signer certificate") return cmd } +func newCreatePostureCheckProcessMultiCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { + options := &createPostureCheckProcessMultiOptions{ + createPostureCheckOptions: createPostureCheckOptions{ + edgeOptions: edgeOptions{ + CommonOptions: common.CommonOptions{ + Factory: f, + Out: out, + Err: errOut, + }, + }, + tags: make(map[string]string), + }, + rawBinaryFileHashes: nil, + rawBinarySigners: nil, + } + + cmd := &cobra.Command{ + Use: fmt.Sprintf("process-multi ", OsLinux, OsMacOs, OsWindows, OsWindowsServer), + Short: "creates a posture check multi for an OS specific process. Provide os and paths as comma separated values", + Args: func(cmd *cobra.Command, args []string) error { + if err := cobra.ExactArgs(4)(cmd, args); err != nil { + return err + } + + options.name = args[0] + options.semantic = args[1] + + if options.semantic != string(rest_model.SemanticAllOf) && options.semantic != string(rest_model.SemanticAnyOf) { + return fmt.Errorf("invalid semantic [%s]: expected %s|%s", options.semantic, rest_model.SemanticAnyOf, rest_model.SemanticAllOf) + } + + oses := strings.Split(args[2], ",") + for _, os := range oses { + os = normalizeOsType(os) + if os == "" || os == OsAndroid || os == OsIOS { + return fmt.Errorf("invalid os type [%s]: expected %s|%s|%s|%s", args[1], OsLinux, OsMacOs, OsWindows, OsWindowsServer) + } + + options.osTypes = append(options.osTypes, os) + } + + options.paths = strings.Split(args[3], ",") + + if len(options.paths) != len(options.osTypes) { + return fmt.Errorf("number of paths supplied does not match number of os types supplied") + } + + for _, rawHash := range options.rawBinaryFileHashes { + hashes := strings.Split(rawHash, "|") + cleanHashes, err := cleanSha512s(hashes) + if err != nil { + return err + } + + options.binaryFileHashes = append(options.binaryFileHashes, cleanHashes) + } + + for _, rawSigner := range options.rawBinarySigners { + signers := strings.Split(rawSigner, "|") + cleanedSigners, err := cleanSha1s(signers) + + if err != nil { + return err + } + options.binarySigners = append(options.binarySigners, cleanedSigners) + } + + return nil + + }, + Run: func(cmd *cobra.Command, args []string) { + options.Cmd = cmd + options.Args = args + + err := runCreatePostureCheckProcessMulti(options) + cmdhelper.CheckErr(err) + }, + SuggestFor: []string{}, + } + + // allow interspersing positional args and flags + cmd.Flags().SetInterspersed(true) + options.AddCommonFlags(cmd) + options.createPostureCheckOptions.addPostureFlags(cmd) + + cmd.Flags().StringSliceVarP(&options.rawBinaryFileHashes, "hash-sigs", "s", nil, "One or more sha512 hashes of valid binaries separated by pipe and by comma for processes") + cmd.Flags().StringSliceVarP(&options.rawBinarySigners, "signer-fingerprints", "f", nil, "One or more sha1 hash of a valid signer certificate separated by pipe and by comma for processes") + + return cmd +} + const ( OsAndroid = "Android" OsWindows = "Windows" @@ -226,7 +335,7 @@ const ( PostureCheckTypeProcess = "PROCESS" PostureCheckTypeMAC = "MAC" PostureCheckTypeOS = "OS" - PostureCheckTypeMFA = "MFA" + PostureCheckTypeMFA = "MFA" ) // Returns the normalized Edge API value or empty string @@ -255,13 +364,18 @@ func cleanHexString(in string) string { return hexClean.ReplaceAllString(strings.ToLower(in), "") } -func cleanSha512(in []string) ([]string, error) { +func cleanSha512s(in []string) ([]string, error) { hashMap := map[string]struct{}{} for _, hash := range in { + hash = strings.TrimSpace(hash) + + if len(hash) == 0 { + continue + } cleanHash := cleanHexString(hash) - if len(cleanHash) < 64 { + if len(cleanHash) != 64 { return nil, fmt.Errorf("sha512 hash must be 64 hex characters, given [%s], cleaned [%s] with a length of %d", hash, cleanHash, len(cleanHash)) } @@ -279,13 +393,38 @@ func cleanSha512(in []string) ([]string, error) { func cleanSha1(in string) (string, error) { cleanSig := cleanHexString(in) - if len(cleanSig) < 20 { + if len(cleanSig) != 40 { return "", fmt.Errorf("sha1 hash must be 20 hex characters, given [%s], cleaned [%s] with a length of %d", in, cleanSig, len(cleanSig)) } return cleanSig, nil } +func cleanSha1s(in []string) ([]string, error) { + hashMap := map[string]struct{}{} + for _, hash := range in { + hash = strings.TrimSpace(hash) + + if len(hash) == 0 { + continue + } + cleanHash, err := cleanSha1(hash) + + if err != nil { + return nil, err + } + + hashMap[cleanHash] = struct{}{} + } + + var cleanHashes []string + for hash := range hashMap { + cleanHashes = append(cleanHashes, hash) + } + + return cleanHashes, nil +} + func runCreatePostureCheckProcess(o *createPostureCheckProcessOptions) error { entityData := gabs.New() setPostureCheckEntityValues(entityData, &o.createPostureCheckOptions, PostureCheckTypeProcess) @@ -293,7 +432,7 @@ func runCreatePostureCheckProcess(o *createPostureCheckProcessOptions) error { setJSONValue(entityData, o.normalizedOs, "process", "osType") setJSONValue(entityData, o.path, "process", "path") - hashes, err := cleanSha512(o.hash) + hashes, err := cleanSha512s(o.hashes) if err != nil { return err @@ -328,6 +467,56 @@ func runCreatePostureCheckProcess(o *createPostureCheckProcessOptions) error { return err } +func runCreatePostureCheckProcessMulti(options *createPostureCheckProcessMultiOptions) error { + managementClient, err := util.DefaultEdgeManagementClient() + + if err != nil { + return err + } + var processes []*rest_model.ProcessMulti + + for i, osType := range options.osTypes { + newOsType := rest_model.OsType(osType) + process := &rest_model.ProcessMulti{ + OsType: &newOsType, + Path: &options.paths[i], + } + + if len(options.binarySigners) > i { + process.SignerFingerprints = options.binarySigners[i] + } + + if len(options.binaryFileHashes) > i { + process.Hashes = options.binaryFileHashes[i] + } + + processes = append(processes, process) + } + + semantic := rest_model.Semantic(options.semantic) + params := posture_checks.NewCreatePostureCheckParams() + params.PostureCheck = &rest_model.PostureCheckProcessMultiCreate{ + Processes: processes, + Semantic: &semantic, + } + params.PostureCheck.SetRoleAttributes(options.roleAttributes) + params.PostureCheck.SetName(&options.name) + + resp, err := managementClient.PostureChecks.CreatePostureCheck(params, nil) + + if err != nil { + panic(err) + } + + checkId := resp.GetPayload().Data.ID + + if _, err = fmt.Fprintf(options.Out, "%v\n", checkId); err != nil { + panic(err) + } + + return err +} + func setPostureCheckEntityValues(entity *gabs.Container, options *createPostureCheckOptions, typeId string) { setJSONValue(entity, options.Args[0], "name") setJSONValue(entity, options.roleAttributes, "roleAttributes") @@ -541,7 +730,6 @@ func parseOsSpec(osSpecStr string) (*osSpec, error) { }, nil } - func newCreatePostureCheckMfaCmd(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Command { options := createPostureCheckOptions{ edgeOptions: edgeOptions{ @@ -598,4 +786,4 @@ func runCreatePostureCheckMfa(o *createPostureCheckOptions) error { } return nil -} \ No newline at end of file +} diff --git a/ziti/cmd/ziti/cmd/edge_controller/list.go b/ziti/cmd/ziti/cmd/edge_controller/list.go index 9c05f376c..b4db5e80c 100644 --- a/ziti/cmd/ziti/cmd/edge_controller/list.go +++ b/ziti/cmd/ziti/cmd/edge_controller/list.go @@ -19,6 +19,7 @@ package edge_controller import ( "encoding/json" "fmt" + "github.com/openziti/edge/rest_model" "github.com/openziti/foundation/util/errorz" "github.com/pkg/errors" "io" @@ -705,6 +706,26 @@ func outputPostureCheck(o *edgeOptions, entity *gabs.Container) error { case "OS": operatingSystems, _ := entity.Path("operatingSystems").Children() config = strings.Join(postureCheckOsToStrings(operatingSystems), ",") + case "PROCESS_MULTI": + postureCheck := rest_model.PostureCheckProcessMultiDetail{} + if err := postureCheck.UnmarshalJSON(entity.Bytes()); err != nil { + return err + } + + baseConfig := fmt.Sprintf("(SEMANTIC: %s)", *postureCheck.Semantic) + + if _, err := fmt.Fprintf(o.Out, "id: %-10v type: %-10v name: %-15v role attributes: %-10s param: %v\n", id, typeId, name, roleAttributes, baseConfig); err != nil { + return err + } + + for _, process := range postureCheck.Processes { + process.SignerFingerprints = getEllipsesStrings(process.SignerFingerprints, 4, 2) + process.Hashes = getEllipsesStrings(process.Hashes, 4, 2) + _, _ = fmt.Fprintf(o.Out, "\t(OS: %s, PATH: %s, HASHES: %s, SIGNER: %s)\n", *process.OsType, *process.Path, strings.Join(process.Hashes, ","), strings.Join(process.SignerFingerprints, ", ")) + } + + return nil + case "PROCESS": process := entity.Path("process") @@ -717,17 +738,13 @@ func outputPostureCheck(o *edgeOptions, entity *gabs.Container) error { for _, hash := range hashes { hashStr := hash.(string) - if hashStr != "" { - hashStr = hashStr[0:4] + "..." + hashStr[len(hashStr)-2:] - hashStrings = append(hashStrings, hashStr) - } - + hashStrings = append(hashStrings, getEllipsesString(hashStr, 4, 2)) } } signerFingerprint := "N/A" if val := process.Path("signerFingerprint").Data(); val != nil { if valStr := val.(string); valStr != "" { - signerFingerprint = valStr[0:4] + "..." + valStr[len(valStr)-2:] + signerFingerprint = getEllipsesString(valStr, 4, 2) } } @@ -735,7 +752,7 @@ func outputPostureCheck(o *edgeOptions, entity *gabs.Container) error { hashStrings = append(hashStrings, "N/A") } - config = fmt.Sprintf("(OS: %s, PATH: %s, HASHES: %s, SIGNER: %s)", os, path, strings.Join(hashStrings, ","), signerFingerprint) + config = fmt.Sprintf("\n\t(OS: %s, PATH: %s, HASHES: %s, SIGNER: %s)", os, path, strings.Join(hashStrings, ","), signerFingerprint) } if _, err := fmt.Fprintf(o.Out, "id: %-10v type: %-10v name: %-15v role attributes: %-10s param: %v\n", id, typeId, name, roleAttributes, config); err != nil { @@ -745,6 +762,25 @@ func outputPostureCheck(o *edgeOptions, entity *gabs.Container) error { return nil } +func getEllipsesString(val string, lead, lag int) string { + total := lead + lag + 3 + + if len(val) <= total { + return val + } + + return val[0:lead] + "..." + val[len(val)-lag:] +} + +func getEllipsesStrings(values []string, lead, lag int) []string { + var ret []string + for _, val := range values { + ret = append(ret, getEllipsesString(val, lead, lag)) + } + + return ret +} + func outputPostureChecks(o *edgeOptions, children []*gabs.Container, pagingInfo *paging) error { if o.OutputJSONResponse { return nil diff --git a/ziti/cmd/ziti/cmd/edge_controller/update_posture_check.go b/ziti/cmd/ziti/cmd/edge_controller/update_posture_check.go index 6d9406a0c..f8c2d69af 100644 --- a/ziti/cmd/ziti/cmd/edge_controller/update_posture_check.go +++ b/ziti/cmd/ziti/cmd/edge_controller/update_posture_check.go @@ -279,7 +279,7 @@ func runUpdatePostureCheckProcess(o *updatePostureCheckProcessOptions) error { } if o.Cmd.Flags().Changed("hash-sigs") { - o.hashes, err = cleanSha512(o.hashes) + o.hashes, err = cleanSha512s(o.hashes) if err != nil { return err diff --git a/ziti/cmd/ziti/util/rest.go b/ziti/cmd/ziti/util/rest.go index 9ec5d1f51..bbdd09dd4 100644 --- a/ziti/cmd/ziti/util/rest.go +++ b/ziti/cmd/ziti/util/rest.go @@ -21,16 +21,25 @@ import ( "archive/zip" "bytes" "compress/gzip" + "crypto/tls" + "crypto/x509" "encoding/json" "fmt" "github.com/Jeffail/gabs" "github.com/blang/semver" + openApiRuntime "github.com/go-openapi/runtime" + httptransport "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" + "github.com/openziti/edge/rest_management_api_client" "github.com/openziti/foundation/common/constants" "github.com/openziti/ziti/common/version" cmdhelper "github.com/openziti/ziti/ziti/cmd/ziti/cmd/helpers" c "github.com/openziti/ziti/ziti/cmd/ziti/constants" + "github.com/pkg/errors" "gopkg.in/resty.v1" "io" + "io/ioutil" + "net" "net/http" "net/url" "os" @@ -685,6 +694,79 @@ func EdgeControllerList(path string, params url.Values, logJSON bool, out io.Wri return jsonParsed, nil } +func NewEdgeManagementClient(session *Session) (*rest_management_api_client.ZitiEdgeManagement, error) { + httpClientTransport := &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: 10 * time.Second, + KeepAlive: 10 * time.Second, + + }).DialContext, + ForceAttemptHTTP2: true, + MaxIdleConns: 10, + IdleConnTimeout: 10 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + + } + + rootCaPool := x509.NewCertPool() + + rootPemData, err := ioutil.ReadFile(session.Cert) + if err != nil { + return nil, errors.Errorf("could not read session certificates [%s]: %v", session.Cert, err) + } + + rootCaPool.AppendCertsFromPEM(rootPemData) + + httpClientTransport.TLSClientConfig = &tls.Config{ + RootCAs: rootCaPool, + } + + httpClient := &http.Client{ + Transport: httpClientTransport, + Timeout: 10 * time.Second, + } + parsedHost, err := url.Parse(session.Host) + if err != nil { + return nil, err + } + + transport := httptransport.NewWithClient(parsedHost.Host, rest_management_api_client.DefaultBasePath, rest_management_api_client.DefaultSchemes, httpClient) + + transport.DefaultAuthentication = &EdgeManagementAuth{ + Token: session.Token, + } + return rest_management_api_client.New(transport, nil), nil +} + +var defaultEdgeManagementClient *rest_management_api_client.ZitiEdgeManagement + +func DefaultEdgeManagementClient() (*rest_management_api_client.ZitiEdgeManagement, error) { + if defaultEdgeManagementClient == nil { + session := &Session{} + if err := session.Load(); err != nil { + return nil, err + } + + if client, err := NewEdgeManagementClient(session); err != nil { + return nil, err + } else { + defaultEdgeManagementClient = client + } + } + + return defaultEdgeManagementClient, nil +} + +type EdgeManagementAuth struct { + Token string +} + +func (e EdgeManagementAuth) AuthenticateRequest(request openApiRuntime.ClientRequest, registry strfmt.Registry) error { + return request.SetHeaderParam("zt-session", e.Token) +} + // EdgeControllerCreate will create entities of the given type in the given Edge Controller func EdgeControllerCreate(entityType string, body string, out io.Writer, logJSON bool, timeout int, verbose bool) (*gabs.Container, error) { session := &Session{}