mirror of
https://github.com/openziti/zrok.git
synced 2025-06-23 19:22:19 +02:00
Merge branch 'v1_0_0' into canary_1
This commit is contained in:
commit
e2687e5790
5
.flake8
5
.flake8
@ -1,3 +1,6 @@
|
|||||||
[flake8]
|
[flake8]
|
||||||
max-line-length = 120
|
max-line-length = 120
|
||||||
exclude = zrok_api, build
|
exclude =
|
||||||
|
./sdk/python/sdk/zrok/zrok_api/**,
|
||||||
|
./build/**
|
||||||
|
|
||||||
|
4
.github/issue_template.md
vendored
4
.github/issue_template.md
vendored
@ -1,9 +1,9 @@
|
|||||||
Thank you for taking the time to reach out regarding zrok!
|
*** IMPORTANT: THIS ISSUE DATABASE IS NOT FOR SUPPORT ***
|
||||||
|
|
||||||
If you think you have found a bug in zrok, or you need help with a specific issue, please reach out for support on the OpenZiti Discourse group at:
|
If you think you have found a bug in zrok, or you need help with a specific issue, please reach out for support on the OpenZiti Discourse group at:
|
||||||
|
|
||||||
https://openziti.discourse.group/
|
https://openziti.discourse.group/
|
||||||
|
|
||||||
There is a zrok topic available there. The entire zrok and OpenZiti team are monitoring that forum. They're not monitoring this issue database. If you decide to open an issue here anyway, we're probably still going to guide you to the Discourse forum to assist you. Going there first will get you help faster. :-)
|
There is a zrok topic available there. You can use your GitHub credentials to log in. The entire zrok and OpenZiti team are monitoring that forum. They're not monitoring this issue database. If you decide to open an issue here anyway, we're probably still going to guide you to the Discourse forum to assist you. Going there first will get you help faster. :-)
|
||||||
|
|
||||||
This issue database is for vetted roadmap items and confirmed bugs within the core open-source portion of zrok.
|
This issue database is for vetted roadmap items and confirmed bugs within the core open-source portion of zrok.
|
42
.github/workflows/build-wheels.yml
vendored
42
.github/workflows/build-wheels.yml
vendored
@ -5,7 +5,26 @@ on:
|
|||||||
types: [released]
|
types: [released]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
enforce_stable_semver:
|
||||||
|
name: Require Stable Release Semver
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
outputs:
|
||||||
|
version: ${{ steps.parse.outputs.version }}
|
||||||
|
steps:
|
||||||
|
- name: Parse Release Version
|
||||||
|
id: parse
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
if [[ "${GITHUB_REF_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||||
|
echo "GITHUB_REF_NAME=${GITHUB_REF_NAME} is a stable release semver ref"
|
||||||
|
echo "version=${GITHUB_REF_NAME#v}" | tee -a $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "GITHUB_REF_NAME=${GITHUB_REF_NAME} is not a stable release semver ref" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
build_wheels:
|
build_wheels:
|
||||||
|
needs: enforce_stable_semver
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
working-directory: sdk/python/sdk/zrok
|
working-directory: sdk/python/sdk/zrok
|
||||||
@ -45,7 +64,7 @@ jobs:
|
|||||||
name: zrok_sdk_${{ matrix.spec.target }}
|
name: zrok_sdk_${{ matrix.spec.target }}
|
||||||
path: ${{ github.workspace }}/sdk/python/sdk/zrok/dist/*
|
path: ${{ github.workspace }}/sdk/python/sdk/zrok/dist/*
|
||||||
|
|
||||||
publish:
|
publish-testpypi:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-20.04
|
||||||
needs: [ build_wheels ]
|
needs: [ build_wheels ]
|
||||||
permissions:
|
permissions:
|
||||||
@ -54,16 +73,10 @@ jobs:
|
|||||||
- name: Download artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: ./download
|
path: ./dist
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
pattern: zrok_sdk_*
|
pattern: zrok_sdk_*
|
||||||
|
|
||||||
- name: check
|
|
||||||
run: |
|
|
||||||
ls -lR ./download/
|
|
||||||
mkdir dist
|
|
||||||
cp ./download/* ./dist/
|
|
||||||
|
|
||||||
- name: Publish wheels (TestPYPI)
|
- name: Publish wheels (TestPYPI)
|
||||||
uses: pypa/gh-action-pypi-publish@release/v1
|
uses: pypa/gh-action-pypi-publish@release/v1
|
||||||
with:
|
with:
|
||||||
@ -72,6 +85,19 @@ jobs:
|
|||||||
skip-existing: true
|
skip-existing: true
|
||||||
verbose: true
|
verbose: true
|
||||||
|
|
||||||
|
publish-pypi:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
needs: [ publish-testpypi ]
|
||||||
|
permissions:
|
||||||
|
id-token: write
|
||||||
|
steps:
|
||||||
|
- name: Download artifacts
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
path: ./dist
|
||||||
|
merge-multiple: true
|
||||||
|
pattern: zrok_sdk_*
|
||||||
|
|
||||||
- name: Publish wheels (PyPI)
|
- name: Publish wheels (PyPI)
|
||||||
uses: pypa/gh-action-pypi-publish@release/v1
|
uses: pypa/gh-action-pypi-publish@release/v1
|
||||||
with:
|
with:
|
||||||
|
14
.github/workflows/ci-build.yml
vendored
14
.github/workflows/ci-build.yml
vendored
@ -29,19 +29,29 @@ jobs:
|
|||||||
- name: setup-node
|
- name: setup-node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 18.x
|
node-version: 20.x
|
||||||
|
|
||||||
- name: install ui node modules
|
- name: install ui node modules
|
||||||
shell: bash
|
shell: bash
|
||||||
run: npm install
|
run: npm install
|
||||||
working-directory: ui
|
working-directory: ui
|
||||||
|
|
||||||
- name: build node ui
|
- name: build ui
|
||||||
shell: bash
|
shell: bash
|
||||||
run: npm run build
|
run: npm run build
|
||||||
working-directory: ui
|
working-directory: ui
|
||||||
env:
|
env:
|
||||||
CI: "true"
|
CI: "true"
|
||||||
|
|
||||||
|
- name: install agent ui node modules
|
||||||
|
shell: bash
|
||||||
|
run: npm install
|
||||||
|
working-directory: agent/agentUi
|
||||||
|
|
||||||
|
- name: build agent ui
|
||||||
|
shell: bash
|
||||||
|
run: npm run build
|
||||||
|
working-directory: agent/agentUi
|
||||||
|
|
||||||
- name: go install
|
- name: go install
|
||||||
shell: bash
|
shell: bash
|
||||||
|
19
.github/workflows/homebrew.yml
vendored
19
.github/workflows/homebrew.yml
vendored
@ -5,7 +5,26 @@ on:
|
|||||||
types: [released]
|
types: [released]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
enforce_stable_semver:
|
||||||
|
name: Require Stable Release Semver
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
outputs:
|
||||||
|
version: ${{ steps.parse.outputs.version }}
|
||||||
|
steps:
|
||||||
|
- name: Parse Release Version
|
||||||
|
id: parse
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
if [[ "${GITHUB_REF_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||||
|
echo "GITHUB_REF_NAME=${GITHUB_REF_NAME} is a stable release semver ref"
|
||||||
|
echo "version=${GITHUB_REF_NAME#v}" | tee -a $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "GITHUB_REF_NAME=${GITHUB_REF_NAME} is not a stable release semver ref" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
update-brew:
|
update-brew:
|
||||||
|
needs: enforce_stable_semver
|
||||||
if: github.repository_owner == 'openziti'
|
if: github.repository_owner == 'openziti'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
24
.github/workflows/node-sdk.yml
vendored
24
.github/workflows/node-sdk.yml
vendored
@ -2,13 +2,34 @@ name: Build/Release Node SDK
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
types: [ published ]
|
types: [ released ]
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: [ main ]
|
branches: [ main ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
|
enforce_stable_semver:
|
||||||
|
name: Require Stable Release Semver
|
||||||
|
if: github.event.action == 'released'
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
outputs:
|
||||||
|
version: ${{ steps.parse.outputs.version }}
|
||||||
|
steps:
|
||||||
|
- name: Parse Release Version
|
||||||
|
id: parse
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
if [[ "${GITHUB_REF_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||||
|
echo "GITHUB_REF_NAME=${GITHUB_REF_NAME} is a stable release semver ref"
|
||||||
|
echo "version=${GITHUB_REF_NAME#v}" | tee -a $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "GITHUB_REF_NAME=${GITHUB_REF_NAME} is not a stable release semver ref" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
build:
|
build:
|
||||||
|
needs: enforce_stable_semver
|
||||||
|
if: always()
|
||||||
name: Build for Node-${{ matrix.node_ver }} ${{ matrix.config.target }}/${{ matrix.config.arch }}
|
name: Build for Node-${{ matrix.node_ver }} ${{ matrix.config.target }}/${{ matrix.config.arch }}
|
||||||
runs-on: ${{ matrix.config.os }}
|
runs-on: ${{ matrix.config.os }}
|
||||||
|
|
||||||
@ -69,4 +90,3 @@ jobs:
|
|||||||
npm publish --access public
|
npm publish --access public
|
||||||
env:
|
env:
|
||||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
|
|
||||||
|
108
.github/workflows/promote-downstreams.yml
vendored
Normal file
108
.github/workflows/promote-downstreams.yml
vendored
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
name: Promote Downstream Releases
|
||||||
|
|
||||||
|
on:
|
||||||
|
# may be triggered manually on a release tag that represents a prerelease to promote it to a release in the downstream package repositories and Docker Hub
|
||||||
|
workflow_dispatch:
|
||||||
|
# automatically trigger if an existing GitHub release is marked "latest"
|
||||||
|
release:
|
||||||
|
types: [released] # this release event activity type excludes prereleases
|
||||||
|
|
||||||
|
# cancel older, redundant runs of same workflow on same branch
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
enforce_stable_semver:
|
||||||
|
name: Require Stable Release Semver
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
outputs:
|
||||||
|
version: ${{ steps.parse.outputs.version }}
|
||||||
|
steps:
|
||||||
|
- name: Parse Release Version
|
||||||
|
id: parse
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
if [[ "${GITHUB_REF_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||||
|
echo "GITHUB_REF_NAME=${GITHUB_REF_NAME} is a stable release semver ref"
|
||||||
|
echo "version=${GITHUB_REF_NAME#v}" | tee -a $GITHUB_OUTPUT
|
||||||
|
else
|
||||||
|
echo "GITHUB_REF_NAME=${GITHUB_REF_NAME} is not a stable release semver ref" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
promote_docker:
|
||||||
|
name: Tag Container Image ${{ matrix.image.repo }}:latest
|
||||||
|
needs: enforce_stable_semver
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
matrix:
|
||||||
|
image:
|
||||||
|
- repo: ${{ vars.ZROK_CONTAINER_IMAGE_REPO || 'docker.io/openziti/zrok' }}
|
||||||
|
steps:
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ vars.DOCKER_HUB_API_USER || secrets.DOCKER_HUB_API_USER }}
|
||||||
|
password: ${{ secrets.DOCKER_HUB_API_TOKEN }}
|
||||||
|
|
||||||
|
- name: Tag Latest
|
||||||
|
shell: bash
|
||||||
|
run: >
|
||||||
|
docker buildx imagetools create --tag
|
||||||
|
${{ matrix.image.repo }}:latest
|
||||||
|
${{ matrix.image.repo }}:${{ needs.enforce_stable_semver.outputs.version }}
|
||||||
|
|
||||||
|
promote_artifactory:
|
||||||
|
name: Promote ${{ matrix.package_name }}-${{ matrix.arch.rpm }}.${{ matrix.packager }}
|
||||||
|
needs: enforce_stable_semver
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
matrix:
|
||||||
|
package_name:
|
||||||
|
- zrok
|
||||||
|
- zrok-share
|
||||||
|
arch:
|
||||||
|
- deb: amd64
|
||||||
|
rpm: x86_64
|
||||||
|
- deb: arm64
|
||||||
|
rpm: aarch64
|
||||||
|
- deb: armhf
|
||||||
|
rpm: armv7hl
|
||||||
|
packager:
|
||||||
|
- rpm
|
||||||
|
- deb
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
env:
|
||||||
|
ZITI_DEB_TEST_REPO: ${{ vars.ZITI_DEB_TEST_REPO || 'zitipax-openziti-deb-test' }}
|
||||||
|
ZITI_RPM_TEST_REPO: ${{ vars.ZITI_RPM_TEST_REPO || 'zitipax-openziti-rpm-test' }}
|
||||||
|
ZITI_DEB_PROD_REPO: ${{ vars.ZITI_DEB_PROD_REPO || 'zitipax-openziti-deb-stable' }}
|
||||||
|
ZITI_RPM_PROD_REPO: ${{ vars.ZITI_RPM_PROD_REPO || 'zitipax-openziti-rpm-stable' }}
|
||||||
|
steps:
|
||||||
|
- name: Configure jFrog CLI
|
||||||
|
uses: jfrog/setup-jfrog-cli@v4
|
||||||
|
env:
|
||||||
|
JF_ENV_1: ${{ secrets.ZITI_ARTIFACTORY_CLI_CONFIG_PACKAGE_UPLOAD }}
|
||||||
|
|
||||||
|
- name: Copy RPM from test repo to stable repo with jFrog CLI
|
||||||
|
if: matrix.packager == 'rpm'
|
||||||
|
shell: bash
|
||||||
|
run: >
|
||||||
|
jf rt copy
|
||||||
|
--recursive=false
|
||||||
|
--flat=true
|
||||||
|
--fail-no-op=true
|
||||||
|
${{ env.ZITI_RPM_TEST_REPO }}/redhat/${{ matrix.arch.rpm }}/${{ matrix.package_name }}-${{ needs.enforce_stable_semver.outputs.version }}-1.${{ matrix.arch.rpm }}.rpm
|
||||||
|
${{ env.ZITI_RPM_PROD_REPO }}/redhat/${{ matrix.arch.rpm }}/
|
||||||
|
|
||||||
|
- name: Copy DEB from test repo to stable repo with jFrog CLI
|
||||||
|
if: matrix.packager == 'deb'
|
||||||
|
shell: bash
|
||||||
|
run: >
|
||||||
|
jf rt copy
|
||||||
|
--recursive=false
|
||||||
|
--flat=true
|
||||||
|
--fail-no-op=true
|
||||||
|
${{ env.ZITI_DEB_TEST_REPO }}/pool/${{ matrix.package_name }}/${{ matrix.arch.deb }}/${{ matrix.package_name }}_${{ needs.enforce_stable_semver.outputs.version }}-1_${{ matrix.arch.deb }}.deb
|
||||||
|
${{ env.ZITI_DEB_PROD_REPO }}/pool/${{ matrix.package_name }}/${{ matrix.arch.deb }}/
|
38
.github/workflows/publish-docker-images.yml
vendored
38
.github/workflows/publish-docker-images.yml
vendored
@ -1,55 +1,40 @@
|
|||||||
name: Publish Docker Images
|
name: Publish Docker Images
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_call:
|
||||||
inputs:
|
inputs:
|
||||||
zrok-version:
|
zrok-version:
|
||||||
description: zrok release tag to publish as a Docker image
|
description: Image tag to publish for zrok container images
|
||||||
type: string
|
type: string
|
||||||
required: true
|
required: true
|
||||||
release:
|
|
||||||
types:
|
|
||||||
- released # excludes "prereleased" which is included in "published" to
|
|
||||||
# avoid prematurely releasing semver tagged container images
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
publish-docker-images:
|
publish-docker-images:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-24.04
|
||||||
env:
|
env:
|
||||||
RELEASE_REF: ${{ inputs.zrok-version || github.ref }}
|
RELEASE_REF: ${{ inputs.zrok-version }}
|
||||||
steps:
|
steps:
|
||||||
# compose the semver string without leading "refs/tags" or "v" so we can predict the
|
# compose the semver string without leading "refs/tags" or "v" so we can predict the
|
||||||
# release artifact filename
|
# release artifact filename
|
||||||
- name: Set zrok Version Semver from Tag Ref
|
- name: Set zrok Version Semver from Tag Ref
|
||||||
id: semver
|
id: semver
|
||||||
run: |
|
run: |
|
||||||
zrok_semver=${RELEASE_REF#refs/tags/}
|
echo "zrok_semver=${RELEASE_REF#v}" | tee -a $GITHUB_OUTPUT
|
||||||
echo "zrok_semver=${zrok_semver#v}" | tee -a $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Checkout Workspace
|
- name: Checkout Workspace
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Create the Release Arch Dirs
|
|
||||||
run: |
|
|
||||||
for TGZ in dist/{amd,arm}64/linux/; do
|
|
||||||
mkdir -pv ${TGZ}
|
|
||||||
done
|
|
||||||
|
|
||||||
- name: Download Linux AMD64 Release Artifact
|
- name: Download Linux AMD64 Release Artifact
|
||||||
uses: dsaltares/fetch-gh-release-asset@1.1.2
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
version: tags/v${{ steps.semver.outputs.zrok_semver }}
|
name: release-builds-linux-amd64
|
||||||
file: zrok.*_linux_amd64.tar.gz
|
path: dist/amd64/linux
|
||||||
regex: true
|
|
||||||
target: dist/amd64/linux/zrok_linux_amd64.tar.gz
|
|
||||||
|
|
||||||
- name: Download Linux ARM64 Release Artifact
|
- name: Download Linux ARM64 Release Artifact
|
||||||
uses: dsaltares/fetch-gh-release-asset@1.1.2
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
version: tags/v${{ steps.semver.outputs.zrok_semver }}
|
name: release-builds-linux-arm64
|
||||||
file: zrok.*_linux_arm64.tar.gz
|
path: dist/arm64/linux
|
||||||
regex: true
|
|
||||||
target: dist/arm64/linux/zrok_linux_arm64.tar.gz
|
|
||||||
|
|
||||||
- name: Unpack the Release Artifacts
|
- name: Unpack the Release Artifacts
|
||||||
run: |
|
run: |
|
||||||
@ -79,7 +64,6 @@ jobs:
|
|||||||
id: tagprep_cli
|
id: tagprep_cli
|
||||||
run: |
|
run: |
|
||||||
DOCKER_TAGS="${ZROK_CONTAINER_IMAGE_REPO}:${ZROK_CONTAINER_IMAGE_TAG}"
|
DOCKER_TAGS="${ZROK_CONTAINER_IMAGE_REPO}:${ZROK_CONTAINER_IMAGE_TAG}"
|
||||||
DOCKER_TAGS+=",${ZROK_CONTAINER_IMAGE_REPO}:latest"
|
|
||||||
echo "DOCKER_TAGS=${DOCKER_TAGS}" | tee -a $GITHUB_OUTPUT
|
echo "DOCKER_TAGS=${DOCKER_TAGS}" | tee -a $GITHUB_OUTPUT
|
||||||
|
|
||||||
# this is the CLI image with the Linux binary for each
|
# this is the CLI image with the Linux binary for each
|
||||||
|
288
.github/workflows/release.yml
vendored
288
.github/workflows/release.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
name: Release
|
name: Pre-Release
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -10,16 +10,37 @@ permissions:
|
|||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
env:
|
env:
|
||||||
ZITI_DEB_PROD_REPO: ${{ vars.ZITI_DEB_PROD_REPO || 'zitipax-openziti-deb-stable' }}
|
ZITI_DEB_TEST_REPO: ${{ vars.ZITI_DEB_TEST_REPO || 'zitipax-openziti-deb-test' }}
|
||||||
ZITI_RPM_PROD_REPO: ${{ vars.ZITI_RPM_PROD_REPO || 'zitipax-openziti-rpm-stable' }}
|
ZITI_RPM_TEST_REPO: ${{ vars.ZITI_RPM_TEST_REPO || 'zitipax-openziti-rpm-test' }}
|
||||||
JFROG_CLI_VERSION: ${{ vars.JFROG_CLI_VERSION || '2.50.4' }}
|
JFROG_CLI_VERSION: ${{ vars.JFROG_CLI_VERSION || '2.50.4' }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-linux-amd64:
|
build-linux:
|
||||||
runs-on: ubuntu-20.04
|
name: build-linux-${{ matrix.arch.goreleaser }}
|
||||||
|
needs:
|
||||||
|
- build-darwin
|
||||||
|
- build-windows
|
||||||
|
runs-on: ubuntu-22.04 # oldest Docker host runner for broadest kernel, syscall, ABI support
|
||||||
|
container: openziti/ziti-builder:v2 # v2 is based on ubuntu focal 20.04 for broadest glibc support
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
arch:
|
||||||
|
- goreleaser: amd64
|
||||||
|
deb: amd64
|
||||||
|
rpm: x86_64
|
||||||
|
gcc: gcc g++
|
||||||
|
- goreleaser: arm64
|
||||||
|
deb: arm64
|
||||||
|
rpm: aarch64
|
||||||
|
gcc: gcc-aarch64-linux-gnu
|
||||||
|
- goreleaser: armhf
|
||||||
|
deb: armhf
|
||||||
|
rpm: armv7hl
|
||||||
|
gcc: gcc-arm-linux-gnueabihf
|
||||||
steps:
|
steps:
|
||||||
- run: sudo apt update
|
# skipped because ziti-builder image provides the multi-arch, multi-lib build toolchain
|
||||||
- run: sudo apt-get install gcc-multilib g++-multilib
|
# - run: apt-get update
|
||||||
|
# - run: apt-get --yes --quiet install ${{ matrix.arch.gcc }}
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
@ -44,73 +65,11 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
CI: "true"
|
CI: "true"
|
||||||
|
|
||||||
- uses: goreleaser/goreleaser-action@v6
|
|
||||||
with:
|
|
||||||
distribution: goreleaser
|
|
||||||
version: '~> v2'
|
|
||||||
args: release --skip=publish --config .goreleaser-linux-amd64.yml
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: release-builds-linux-amd64
|
|
||||||
path: ./dist/*.gz
|
|
||||||
|
|
||||||
- name: Configure jFrog CLI
|
|
||||||
uses: jfrog/setup-jfrog-cli@v4
|
|
||||||
with:
|
|
||||||
version: ${{ env.JFROG_CLI_VERSION }}
|
|
||||||
env:
|
|
||||||
JF_ENV_1: ${{ secrets.ZITI_ARTIFACTORY_CLI_CONFIG_PACKAGE_UPLOAD }}
|
|
||||||
|
|
||||||
- name: Upload RPM to Artifactory release repo
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
for RPM in ./dist/*.rpm; do
|
|
||||||
echo "INFO: Uploading $RPM"
|
|
||||||
jf rt upload --recursive=false --flat=true \
|
|
||||||
"$RPM" \
|
|
||||||
${{ env.ZITI_RPM_PROD_REPO }}/redhat/x86_64/
|
|
||||||
done
|
|
||||||
|
|
||||||
- name: Upload DEB to Artifactory release repo
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
for DEB in ./dist/*.deb; do
|
|
||||||
echo "INFO: Uploading $DEB"
|
|
||||||
jf rt upload --recursive=false --flat=true \
|
|
||||||
--deb=debian/main/amd64 \
|
|
||||||
"$DEB" \
|
|
||||||
${{ env.ZITI_DEB_PROD_REPO }}/pool/zrok/amd64/
|
|
||||||
done
|
|
||||||
|
|
||||||
build-linux-arm64:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- run: sudo apt update
|
|
||||||
- run: sudo apt-get install gcc-aarch64-linux-gnu
|
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- run: git fetch --force --tags
|
|
||||||
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: ./go.mod
|
|
||||||
cache: true
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 18.x
|
|
||||||
|
|
||||||
- run: npm install
|
- run: npm install
|
||||||
working-directory: ui
|
working-directory: agent/agentUi
|
||||||
|
|
||||||
- run: npm run build
|
- run: npm run build
|
||||||
working-directory: ui
|
working-directory: agent/agentUi
|
||||||
env:
|
env:
|
||||||
CI: "true"
|
CI: "true"
|
||||||
|
|
||||||
@ -118,13 +77,13 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
distribution: goreleaser
|
distribution: goreleaser
|
||||||
version: '~> v2'
|
version: '~> v2'
|
||||||
args: release --skip=publish --config .goreleaser-linux-arm64.yml
|
args: release --skip=publish --config .goreleaser-linux-${{ matrix.arch.goreleaser }}.yml
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: release-builds-linux-arm64
|
name: release-builds-linux-${{ matrix.arch.goreleaser }}
|
||||||
path: ./dist/*.gz
|
path: ./dist/*.gz
|
||||||
|
|
||||||
- name: Configure jFrog CLI
|
- name: Configure jFrog CLI
|
||||||
@ -134,95 +93,77 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
JF_ENV_1: ${{ secrets.ZITI_ARTIFACTORY_CLI_CONFIG_PACKAGE_UPLOAD }}
|
JF_ENV_1: ${{ secrets.ZITI_ARTIFACTORY_CLI_CONFIG_PACKAGE_UPLOAD }}
|
||||||
|
|
||||||
- name: Upload RPM to Artifactory release repo
|
- name: Upload RPM to Artifactory pre-release repo
|
||||||
shell: bash
|
shell: bash
|
||||||
|
env:
|
||||||
|
ARCH: ${{ matrix.arch.rpm }}
|
||||||
run: |
|
run: |
|
||||||
for RPM in ./dist/*.rpm; do
|
set -o xtrace
|
||||||
echo "INFO: Uploading $RPM"
|
shopt -s nullglob
|
||||||
jf rt upload --recursive=false --flat=true \
|
SEMVER=${GITHUB_REF_NAME#v}
|
||||||
"$RPM" \
|
SEMVER_CORE=${SEMVER%%-*}
|
||||||
${{ env.ZITI_RPM_PROD_REPO }}/redhat/aarch64/
|
if [[ "$SEMVER_CORE" == ${SEMVER#*-} ]]; then
|
||||||
|
SEMVER_PRE="" # no semver pre-release suffix
|
||||||
|
else
|
||||||
|
SEMVER_PRE=${SEMVER#*-}
|
||||||
|
fi
|
||||||
|
for PAX in zrok{,-share}; do
|
||||||
|
_pattern="./dist/${PAX}-${SEMVER_CORE}${SEMVER_PRE:+~${SEMVER_PRE}}*.${ARCH}.rpm"
|
||||||
|
if ! compgen -G "$_pattern" > /dev/null; then
|
||||||
|
echo "ERROR: No RPM files found matching pattern '${_pattern}'" >&2
|
||||||
|
ls -1 ./dist/
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
_rpms=( $_pattern )
|
||||||
|
if [[ ${#_rpms[@]} -ne 1 ]]; then
|
||||||
|
echo "ERROR: Failed to find exactly one RPM file, got: '${_rpms[@]}'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "INFO: Uploading ${_rpms[0]}"
|
||||||
|
jf rt upload \
|
||||||
|
--recursive=false \
|
||||||
|
--flat=true \
|
||||||
|
--fail-no-op=true \
|
||||||
|
"${_rpms[0]}" \
|
||||||
|
${{ env.ZITI_RPM_TEST_REPO }}/redhat/${ARCH}/
|
||||||
done
|
done
|
||||||
|
|
||||||
- name: Upload DEB to Artifactory release repo
|
- name: Upload DEB to Artifactory pre-release repo
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
|
||||||
for DEB in ./dist/*.deb; do
|
|
||||||
echo "INFO: Uploading $DEB"
|
|
||||||
jf rt upload --recursive=false --flat=true \
|
|
||||||
--deb=debian/main/arm64 \
|
|
||||||
"$DEB" \
|
|
||||||
${{ env.ZITI_DEB_PROD_REPO }}/pool/zrok/arm64/
|
|
||||||
done
|
|
||||||
|
|
||||||
build-linux-arm:
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- run: sudo apt update
|
|
||||||
- run: sudo apt-get install gcc-arm-linux-gnueabihf
|
|
||||||
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- run: git fetch --force --tags
|
|
||||||
|
|
||||||
- uses: actions/setup-go@v5
|
|
||||||
with:
|
|
||||||
go-version-file: ./go.mod
|
|
||||||
cache: true
|
|
||||||
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: 18.x
|
|
||||||
|
|
||||||
- run: npm install
|
|
||||||
working-directory: ui
|
|
||||||
|
|
||||||
- run: npm run build
|
|
||||||
working-directory: ui
|
|
||||||
env:
|
env:
|
||||||
CI: "true"
|
ARCH: ${{ matrix.arch.deb }}
|
||||||
|
|
||||||
- uses: goreleaser/goreleaser-action@v6
|
|
||||||
with:
|
|
||||||
distribution: goreleaser
|
|
||||||
version: '~> v2'
|
|
||||||
args: release --skip=publish --config .goreleaser-linux-armhf.yml
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: release-builds-linux-arm
|
|
||||||
path: ./dist/*.gz
|
|
||||||
|
|
||||||
- name: Configure jFrog CLI
|
|
||||||
uses: jfrog/setup-jfrog-cli@v4
|
|
||||||
with:
|
|
||||||
version: ${{ env.JFROG_CLI_VERSION }}
|
|
||||||
env:
|
|
||||||
JF_ENV_1: ${{ secrets.ZITI_ARTIFACTORY_CLI_CONFIG_PACKAGE_UPLOAD }}
|
|
||||||
|
|
||||||
- name: Upload RPM to Artifactory release repo
|
|
||||||
shell: bash
|
|
||||||
run: |
|
run: |
|
||||||
for RPM in ./dist/*.rpm; do
|
set -o xtrace
|
||||||
echo "INFO: Uploading $RPM"
|
shopt -s nullglob
|
||||||
jf rt upload --recursive=false --flat=true \
|
SEMVER=${GITHUB_REF_NAME#v}
|
||||||
"$RPM" \
|
SEMVER_CORE=${SEMVER%%-*}
|
||||||
${{ env.ZITI_RPM_PROD_REPO }}/redhat/armv7/
|
if [[ "$SEMVER_CORE" == ${SEMVER#*-} ]]; then
|
||||||
done
|
SEMVER_PRE="" # no semver pre-release suffix
|
||||||
|
else
|
||||||
|
SEMVER_PRE=${SEMVER#*-}
|
||||||
|
fi
|
||||||
|
for PAX in zrok{,-share}; do
|
||||||
|
_pattern="./dist/${PAX}_${SEMVER_CORE}${SEMVER_PRE:+~${SEMVER_PRE}}*_${ARCH}.deb"
|
||||||
|
if ! compgen -G "$_pattern" > /dev/null; then
|
||||||
|
echo "ERROR: No DEB files found matching pattern '${_pattern}'" >&2
|
||||||
|
ls -1 ./dist/
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
_debs=( $_pattern )
|
||||||
|
if [[ ${#_debs[@]} -ne 1 ]]; then
|
||||||
|
echo "ERROR: Failed to match exactly one DEB file, got: '${_debs[@]}'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Upload DEB to Artifactory release repo
|
echo "INFO: Uploading ${_debs[0]}"
|
||||||
shell: bash
|
jf rt upload \
|
||||||
run: |
|
--recursive=false \
|
||||||
for DEB in ./dist/*.deb; do
|
--flat=true \
|
||||||
echo "INFO: Uploading $DEB"
|
--fail-no-op=true \
|
||||||
jf rt upload --recursive=false --flat=true \
|
--deb=debian/main/${ARCH} \
|
||||||
--deb=debian/main/armv7 \
|
"${_debs[0]}" \
|
||||||
"$DEB" \
|
${{ env.ZITI_DEB_TEST_REPO }}/pool/${PAX}/${ARCH}/
|
||||||
${{ env.ZITI_DEB_PROD_REPO }}/pool/zrok/armv7/
|
|
||||||
done
|
done
|
||||||
|
|
||||||
build-darwin:
|
build-darwin:
|
||||||
@ -258,6 +199,14 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
CI: "true"
|
CI: "true"
|
||||||
|
|
||||||
|
- run: npm install
|
||||||
|
working-directory: agent/agentUi
|
||||||
|
|
||||||
|
- run: npm run build
|
||||||
|
working-directory: agent/agentUi
|
||||||
|
env:
|
||||||
|
CI: "true"
|
||||||
|
|
||||||
- uses: goreleaser/goreleaser-action@v6
|
- uses: goreleaser/goreleaser-action@v6
|
||||||
with:
|
with:
|
||||||
distribution: goreleaser
|
distribution: goreleaser
|
||||||
@ -303,6 +252,14 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
CI: "true"
|
CI: "true"
|
||||||
|
|
||||||
|
- run: npm install
|
||||||
|
working-directory: agent/agentUi
|
||||||
|
|
||||||
|
- run: npm run build
|
||||||
|
working-directory: agent/agentUi
|
||||||
|
env:
|
||||||
|
CI: "true"
|
||||||
|
|
||||||
- uses: goreleaser/goreleaser-action@v6
|
- uses: goreleaser/goreleaser-action@v6
|
||||||
with:
|
with:
|
||||||
distribution: goreleaser
|
distribution: goreleaser
|
||||||
@ -316,23 +273,20 @@ jobs:
|
|||||||
name: release-builds-windows
|
name: release-builds-windows
|
||||||
path: ./dist/*.gz
|
path: ./dist/*.gz
|
||||||
|
|
||||||
publish-release:
|
call-publish-docker-images:
|
||||||
# allow skipped but not failed
|
name: Publish Release Docker Images
|
||||||
if: ${{
|
|
||||||
!cancelled()
|
|
||||||
&& (needs.build-linux-amd64.result == 'success')
|
|
||||||
&& (needs.build-linux-arm.result == 'success')
|
|
||||||
&& (needs.build-linux-arm64.result == 'success')
|
|
||||||
&& (needs.build-darwin.result == 'success' || needs.build-darwin.result == 'skipped')
|
|
||||||
&& (needs.build-windows.result == 'success' || needs.build-windows.result == 'skipped')
|
|
||||||
}}
|
|
||||||
needs:
|
needs:
|
||||||
- build-linux-amd64
|
- build-linux
|
||||||
- build-linux-arm
|
|
||||||
- build-linux-arm64
|
|
||||||
- build-darwin
|
- build-darwin
|
||||||
- build-windows
|
- build-windows
|
||||||
|
uses: ./.github/workflows/publish-docker-images.yml
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
zrok-version: ${{ github.ref_name }}
|
||||||
|
|
||||||
|
draft-release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
needs: call-publish-docker-images
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
51
CHANGELOG.md
51
CHANGELOG.md
@ -1,5 +1,56 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## v1.0.0
|
||||||
|
|
||||||
|
MAJOR RELEASE: zrok reaches version 1.0.0!
|
||||||
|
|
||||||
|
FEATURE: Completely redesigned web interface ("API Console"). New implementation provides a dual-mode interface supporting an improved visual network navigator and also a "tabular" view, which provides a more traditional "data" view. New stack built using vite, React, and TypeScript (https://github.com/openziti/zrok/issues/724)
|
||||||
|
|
||||||
|
FEATURE: New "zrok Agent", a background manager process for your zrok environments, which allows you to easily manage and work with multiple `zrok share` and `zrok access` processes. New `--subordinate` flag added to `zrok share [public|private|reserved]` and `zrok access private` to operate in a mode that allows an Agent to manage shares and accesses (https://github.com/openziti/zrok/issues/463)
|
||||||
|
|
||||||
|
FEATURE: New "zrok Agent UI" a web-based user interface for the zrok Agent, which allows creating and releasing shares and accesses through a web browser. This is just an initial chunk of the new Agent UI, and is considered a "minimum viable" version of this interface (https://github.com/openziti/zrok/issues/221)
|
||||||
|
|
||||||
|
FEATURE: `zrok share [public|private|reserved]` and `zrok access private` now auto-detect if the zrok Agent is running in an environment and will automatically service share and access requests through the Agent, rather than in-process if the Agent is running. If the Agent is not running, operation remains as it was in `v0.4.x` and the share or access is handled in-process. New `--force-agent` and `--force-local` flags exist to skip Agent detection and manually select an operating mode (https://github.com/openziti/zrok/issues/751)
|
||||||
|
|
||||||
|
FEATURE `zrok access private` supports a new `--auto` mode, which can automatically find an available open address/port to bind the frontend listener on. Also includes `--auto-address`, `--auto-start-port`, and `--auto-end-port` features with sensible defaults. Supported by both the agent and local operating modes (https://github.com/openziti/zrok/issues/780)
|
||||||
|
|
||||||
|
FEATURE `zrok rebase` command allows "rebasing" an enabled environment onto a different API endpoint. This is useful for migrating already-enabled environments between endpoints supporting different zrok versions (https://github.com/openziti/zrok/issues/869)
|
||||||
|
|
||||||
|
CHANGE: Refactored API implementation. Cleanup, lint removal, additional data elements added, unused data removed (https://github.com/openziti/zrok/issues/834)
|
||||||
|
|
||||||
|
CHANGE: Deprecated the `passwords` configuration stanza. The zrok controller and API console now use a hard-coded set of (what we believe to be) reasonable assumptions about password quality (https://github.com/openziti/zrok/issues/834)
|
||||||
|
|
||||||
|
CHANGE: The protocol for determining valid client versions has been changed. Previously a zrok client would do a `GET` against the `/api/v1/version` endpoint and do a local version string comparison (as a normal precondition to any API call) to see if the controller version matched. The protocol has been amended so that any out-of-date client using the old protocol will receive a version string indicating that they need to uprade their client. New clients will do a `POST` against the `/api/v1/version` endpoint, posting their client version, and the server will check for compatibility. Does not change the security posture in any significant way, but gives more flexibility on the server side for managing client compatibility. Provides a better, cleared out-of-date error message for old clients when accessing `v1.0.0`+ (https://github.com/openziti/zrok/issues/859)
|
||||||
|
|
||||||
|
## v0.4.49
|
||||||
|
|
||||||
|
FIX: Pre-releases are no longer uploaded to the stable Linux package repo.
|
||||||
|
|
||||||
|
CHANGE: Pre-releases are uploaded to the pre-release Linux package repo and Docker Hub for testing. [RELEASING.md](./RELEASING.md) describes releaser steps and the events they trigger.
|
||||||
|
|
||||||
|
CHANGE: Linux release binaries are now built on the ziti-builder container image based on Ubuntu Focal 20.04 to preserve backward compatibility as the ubuntu-20.04 GitHub runner is end of life.
|
||||||
|
|
||||||
|
## v0.4.48
|
||||||
|
|
||||||
|
FEATURE: The controller configuration now supports a `disable_auto_migration` boolean in the `store` stanza. When set to `true`, the controller will not attempt to auto-migrate (or otherwise validate the migration state) of the underlying database. Leaving `disable_auto_migration` out, or setting it to false will retain the default behavior of auto-migrating when starting the zrok controller. The `zrok admin migrate` command will still perform a migration regardless of how this setting is configured in the controller configuration (https://github.com/openziti/zrok/issues/866)
|
||||||
|
|
||||||
|
FIX: the Python SDK erroneously assumed the enabled zrok environment contained a config.json file, and was changed to only load it if the file was present (https://github.com/openziti/zrok/pull/853/).
|
||||||
|
|
||||||
|
## v0.4.47
|
||||||
|
|
||||||
|
CHANGE: the Docker instance will wait for the ziti container healthy status (contribution from Ben Wong @bwong365 - https://github.com/openziti/zrok/pull/790)
|
||||||
|
|
||||||
|
CHANGE: Document solving the DNS propagation timeout for Docker instances that are using Caddy to manage the wildcard certificate.
|
||||||
|
|
||||||
|
CHANGE: Add usage hint in `zrok config get --help` to clarify how to list all valid `configName` and their current values by running `zrok status`.
|
||||||
|
|
||||||
|
CHANGE: The Python SDK's `Overview()` function was refactored as a class method (https://github.com/openziti/zrok/pull/846).
|
||||||
|
|
||||||
|
FEATURE: The Python SDK now includes a `ProxyShare` class providing an HTTP proxy for public and private shares and a
|
||||||
|
Jupyter notebook example (https://github.com/openziti/zrok/pull/847).
|
||||||
|
|
||||||
|
FIX: PyPi publishing was failing due to a CI issue (https://github.com/openziti/zrok/issues/849)
|
||||||
|
|
||||||
## v0.4.46
|
## v0.4.46
|
||||||
|
|
||||||
FEATURE: Linux service template for systemd user units (https://github.com/openziti/zrok/pull/818)
|
FEATURE: Linux service template for systemd user units (https://github.com/openziti/zrok/pull/818)
|
||||||
|
42
RELEASING.md
42
RELEASING.md
@ -1,17 +1,37 @@
|
|||||||
|
|
||||||
# Releasing zrok
|
# Releasing zrok
|
||||||
|
|
||||||
## Manual Steps
|
## Semantic Versioning
|
||||||
|
|
||||||
1. Create a semver Git tag on main starting with a 'v' character.
|
This project uses semantic versioning. See [here](https://semver.org/) for more information.
|
||||||
1. Push the tag to GitHub.
|
|
||||||
1. Wait for automated steps to complete.
|
|
||||||
1. In GitHub Releases, edit the draft release as needed and finalize.
|
|
||||||
|
|
||||||
## Automated Steps
|
Release tags like `v3.2.1` are eligible for promotion to stable status in GitHub and downstream distribution channels.
|
||||||
|
|
||||||
1. The Release workflow is triggered by creating the Git tag and
|
Pre-release tags like `v3.2.1-rc1` (with a semver hyphenated pre-release suffix) are published in GitHub as pre-releases, and are blocked from promotion to downstream distribution channels if they are marked "stable" by mistake and the GitHub "released" event fires.
|
||||||
1. uploads Linux packages to Artifactory and
|
|
||||||
1. drafts a release in GitHub Releases.
|
Pre-release version strings must contain exactly one hyphen, and may not contain an underscore.
|
||||||
1. The Publish Container Images workflow is triggered by the Release event and
|
|
||||||
1. pushes Docker images to Docker Hub.
|
## How to Trigger Release Automation
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Each trigger is outlined separately, but some may occur simultaneously, e.g., when a draft release is published as stable rather than first publishing it as a pre-release, or a pre-release is promoted to stable and marked as latest at the same time.
|
||||||
|
|
||||||
|
1. Push a tag to GitHub like `v*.*.*` to trigger **the pre-release workflow**. Wait for this workflow to complete before marking the release stable (`isPrerelease: false`).
|
||||||
|
1. Linux packages are uploaded to Artifactory as pre-releases.
|
||||||
|
1. Docker images are uploaded to Docker Hub as pre-releases.
|
||||||
|
1. A release is drafted in GitHub.
|
||||||
|
1. Edit the draft and publish the release as a pre-release (`isPrerelease: true`).
|
||||||
|
1. The one-time GitHub "published" event fires, and binaries are available in GitHub.
|
||||||
|
1. If the release does not have a pre-release suffix, mark it as stable by un-checking (`isPrerelease: false`).
|
||||||
|
1. The one-time GitHub "released" event fires.
|
||||||
|
1. Linux packages are promoted to "stable" in Artifactory.
|
||||||
|
1. Docker images are promoted to `:latest` in Docker Hub.
|
||||||
|
1. Homebrew formulae are built and released.
|
||||||
|
1. Python wheels are built and released to PyPi.
|
||||||
|
1. Node.js packages are built and released to NPM.
|
||||||
|
1. Edit the stable release to mark it as latest.
|
||||||
|
1. https://docs.zrok.io/docs/guides/install/ always serves the "latest" stable version via GitHub binary download URLs.
|
||||||
|
|
||||||
|
## Rolling Back Downstreams
|
||||||
|
|
||||||
|
The concepts, tools, and procedures for managing existing downstream artifacts in Artifactory and Docker Hub are identical for zrok and ziti. Here's the [RELEASING.md document for ziti](https://github.com/openziti/ziti/blob/main/RELEASING.md#rolling-back-downstreams).
|
||||||
|
10
SECURITY.md
10
SECURITY.md
@ -1,11 +1,3 @@
|
|||||||
# Security Policy
|
# Security Policy
|
||||||
|
|
||||||
## Supported Versions
|
Please refer to the [openziti-security repository](https://github.com/openziti/openziti-security) for details of the security policies and processes for this repository.
|
||||||
|
|
||||||
Until v1.0.0 or higher is reached, only the most recent version is supported. After v1.0.0 a new version support statement will be released.
|
|
||||||
|
|
||||||
## Reporting a Vulnerability
|
|
||||||
|
|
||||||
If you have an issue that is not a sensitive security issue, please submit your issue via the GitHub issue tracker on either the main repository.
|
|
||||||
|
|
||||||
If you have a sensitive security issue or are unsure if it is sensitive, please email it to: security@openziti.org
|
|
30
agent/access.go
Normal file
30
agent/access.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/michaelquigley/pfxlog"
|
||||||
|
"github.com/openziti/zrok/agent/proctree"
|
||||||
|
"github.com/openziti/zrok/cmd/zrok/subordinate"
|
||||||
|
)
|
||||||
|
|
||||||
|
type access struct {
|
||||||
|
frontendToken string
|
||||||
|
token string
|
||||||
|
bindAddress string
|
||||||
|
autoMode bool
|
||||||
|
autoAddress string
|
||||||
|
autoStartPort uint16
|
||||||
|
autoEndPort uint16
|
||||||
|
responseHeaders []string
|
||||||
|
|
||||||
|
process *proctree.Child
|
||||||
|
sub *subordinate.MessageHandler
|
||||||
|
|
||||||
|
agent *Agent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *access) monitor() {
|
||||||
|
if err := proctree.WaitChild(a.process); err != nil {
|
||||||
|
pfxlog.ChannelLogger(a.token).Error(err)
|
||||||
|
}
|
||||||
|
a.agent.rmAccess <- a
|
||||||
|
}
|
93
agent/accessPrivate.go
Normal file
93
agent/accessPrivate.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/openziti/zrok/agent/agentGrpc"
|
||||||
|
"github.com/openziti/zrok/agent/proctree"
|
||||||
|
"github.com/openziti/zrok/cmd/zrok/subordinate"
|
||||||
|
"github.com/openziti/zrok/environment"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *agentGrpcImpl) AccessPrivate(_ context.Context, req *agentGrpc.AccessPrivateRequest) (*agentGrpc.AccessPrivateResponse, error) {
|
||||||
|
root, err := environment.LoadRoot()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !root.IsEnabled() {
|
||||||
|
return nil, errors.New("unable to load environment; did you 'zrok enable'?")
|
||||||
|
}
|
||||||
|
|
||||||
|
accCmd := []string{os.Args[0], "access", "private", "--subordinate", "-b", req.BindAddress, req.Token}
|
||||||
|
if req.AutoMode {
|
||||||
|
accCmd = append(accCmd, "--auto", "--auto-address", req.AutoAddress, "--auto-start-port", fmt.Sprintf("%v", req.AutoStartPort))
|
||||||
|
accCmd = append(accCmd, "--auto-end-port", fmt.Sprintf("%v", req.AutoEndPort))
|
||||||
|
}
|
||||||
|
logrus.Info(accCmd)
|
||||||
|
|
||||||
|
acc := &access{
|
||||||
|
token: req.Token,
|
||||||
|
bindAddress: req.BindAddress,
|
||||||
|
autoMode: req.AutoMode,
|
||||||
|
autoAddress: req.AutoAddress,
|
||||||
|
autoStartPort: uint16(req.AutoStartPort),
|
||||||
|
autoEndPort: uint16(req.AutoEndPort),
|
||||||
|
responseHeaders: req.ResponseHeaders,
|
||||||
|
sub: subordinate.NewMessageHandler(),
|
||||||
|
agent: i.agent,
|
||||||
|
}
|
||||||
|
acc.sub.MessageHandler = func(msg subordinate.Message) {
|
||||||
|
logrus.Info(msg)
|
||||||
|
}
|
||||||
|
var bootErr error
|
||||||
|
acc.sub.BootHandler = func(msgType string, msg subordinate.Message) {
|
||||||
|
switch msgType {
|
||||||
|
case subordinate.BootMessage:
|
||||||
|
if v, found := msg["frontend_token"]; found {
|
||||||
|
if str, ok := v.(string); ok {
|
||||||
|
acc.frontendToken = str
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v, found := msg["bind_address"]; found {
|
||||||
|
if sr, ok := v.(string); ok {
|
||||||
|
acc.bindAddress = sr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case subordinate.ErrorMessage:
|
||||||
|
if v, found := msg[subordinate.ErrorMessage]; found {
|
||||||
|
if str, ok := v.(string); ok {
|
||||||
|
bootErr = errors.New(str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
acc.sub.MalformedHandler = func(msg subordinate.Message) {
|
||||||
|
logrus.Error(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.Infof("executing '%v'", accCmd)
|
||||||
|
|
||||||
|
acc.process, err = proctree.StartChild(acc.sub.Tail, accCmd...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
<-acc.sub.BootComplete
|
||||||
|
|
||||||
|
if bootErr == nil {
|
||||||
|
go acc.monitor()
|
||||||
|
i.agent.addAccess <- acc
|
||||||
|
return &agentGrpc.AccessPrivateResponse{FrontendToken: acc.frontendToken}, nil
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if err := proctree.WaitChild(acc.process); err != nil {
|
||||||
|
logrus.Errorf("error joining: %v", err)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unable to start access: %v", bootErr)
|
||||||
|
}
|
||||||
|
}
|
197
agent/agent.go
Normal file
197
agent/agent.go
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||||
|
"github.com/openziti/zrok/agent/agentGrpc"
|
||||||
|
"github.com/openziti/zrok/agent/agentUi"
|
||||||
|
"github.com/openziti/zrok/agent/proctree"
|
||||||
|
"github.com/openziti/zrok/environment/env_core"
|
||||||
|
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||||
|
"github.com/openziti/zrok/util"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Agent struct {
|
||||||
|
cfg *AgentConfig
|
||||||
|
httpEndpoint string
|
||||||
|
root env_core.Root
|
||||||
|
agentSocket string
|
||||||
|
shares map[string]*share
|
||||||
|
addShare chan *share
|
||||||
|
rmShare chan *share
|
||||||
|
accesses map[string]*access
|
||||||
|
addAccess chan *access
|
||||||
|
rmAccess chan *access
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAgent(cfg *AgentConfig, root env_core.Root) (*Agent, error) {
|
||||||
|
if !root.IsEnabled() {
|
||||||
|
return nil, errors.Errorf("unable to load environment; did you 'zrok enable'?")
|
||||||
|
}
|
||||||
|
return &Agent{
|
||||||
|
cfg: cfg,
|
||||||
|
root: root,
|
||||||
|
shares: make(map[string]*share),
|
||||||
|
addShare: make(chan *share),
|
||||||
|
rmShare: make(chan *share),
|
||||||
|
accesses: make(map[string]*access),
|
||||||
|
addAccess: make(chan *access),
|
||||||
|
rmAccess: make(chan *access),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Agent) Run() error {
|
||||||
|
logrus.Infof("started")
|
||||||
|
|
||||||
|
if err := proctree.Init("zrok Agent"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
agentSocket, err := a.root.AgentSocket()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
l, err := net.Listen("unix", agentSocket)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
a.agentSocket = agentSocket
|
||||||
|
|
||||||
|
go a.manager()
|
||||||
|
go a.gateway(a.cfg)
|
||||||
|
|
||||||
|
srv := grpc.NewServer()
|
||||||
|
agentGrpc.RegisterAgentServer(srv, &agentGrpcImpl{agent: a})
|
||||||
|
if err := srv.Serve(l); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Agent) Shutdown() {
|
||||||
|
logrus.Infof("stopping")
|
||||||
|
|
||||||
|
if err := os.Remove(a.agentSocket); err != nil {
|
||||||
|
logrus.Warnf("unable to remove agent socket: %v", err)
|
||||||
|
}
|
||||||
|
for _, shr := range a.shares {
|
||||||
|
logrus.Debugf("stopping share '%v'", shr.token)
|
||||||
|
a.rmShare <- shr
|
||||||
|
}
|
||||||
|
for _, acc := range a.accesses {
|
||||||
|
logrus.Debugf("stopping access '%v'", acc.token)
|
||||||
|
a.rmAccess <- acc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Agent) Config() *AgentConfig {
|
||||||
|
return a.cfg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Agent) gateway(cfg *AgentConfig) {
|
||||||
|
logrus.Info("started")
|
||||||
|
defer logrus.Warn("exited")
|
||||||
|
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
mux := runtime.NewServeMux()
|
||||||
|
opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
|
||||||
|
endpoint := "unix:" + a.agentSocket
|
||||||
|
logrus.Debugf("endpoint: '%v'", endpoint)
|
||||||
|
if err := agentGrpc.RegisterAgentHandlerFromEndpoint(ctx, mux, "unix:"+a.agentSocket, opts); err != nil {
|
||||||
|
logrus.Fatalf("unable to register gateway: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
listener, err := util.AutoListener("tcp", cfg.ConsoleAddress, cfg.ConsoleStartPort, cfg.ConsoleEndPort)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatalf("unable to create a listener: %v", err)
|
||||||
|
}
|
||||||
|
a.httpEndpoint = listener.Addr().String()
|
||||||
|
|
||||||
|
if err := http.Serve(listener, agentUi.Middleware(mux)); err != nil {
|
||||||
|
logrus.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Agent) manager() {
|
||||||
|
logrus.Info("started")
|
||||||
|
defer logrus.Warn("exited")
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case inShare := <-a.addShare:
|
||||||
|
logrus.Infof("adding new share '%v'", inShare.token)
|
||||||
|
a.shares[inShare.token] = inShare
|
||||||
|
|
||||||
|
case outShare := <-a.rmShare:
|
||||||
|
if shr, found := a.shares[outShare.token]; found {
|
||||||
|
logrus.Infof("removing share '%v'", shr.token)
|
||||||
|
if err := proctree.StopChild(shr.process); err != nil {
|
||||||
|
logrus.Errorf("error stopping share '%v': %v", shr.token, err)
|
||||||
|
}
|
||||||
|
if err := proctree.WaitChild(shr.process); err != nil {
|
||||||
|
logrus.Errorf("error joining share '%v': %v", shr.token, err)
|
||||||
|
}
|
||||||
|
if !shr.reserved {
|
||||||
|
if err := a.deleteShare(shr.token); err != nil {
|
||||||
|
logrus.Errorf("error deleting share '%v': %v", shr.token, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete(a.shares, shr.token)
|
||||||
|
} else {
|
||||||
|
logrus.Debug("skipping unidentified (orphaned) share removal")
|
||||||
|
}
|
||||||
|
|
||||||
|
case inAccess := <-a.addAccess:
|
||||||
|
logrus.Infof("adding new access '%v'", inAccess.frontendToken)
|
||||||
|
a.accesses[inAccess.frontendToken] = inAccess
|
||||||
|
|
||||||
|
case outAccess := <-a.rmAccess:
|
||||||
|
if acc, found := a.accesses[outAccess.frontendToken]; found {
|
||||||
|
logrus.Infof("removing access '%v'", acc.frontendToken)
|
||||||
|
if err := proctree.StopChild(acc.process); err != nil {
|
||||||
|
logrus.Errorf("error stopping access '%v': %v", acc.frontendToken, err)
|
||||||
|
}
|
||||||
|
if err := proctree.WaitChild(acc.process); err != nil {
|
||||||
|
logrus.Errorf("error joining access '%v': %v", acc.frontendToken, err)
|
||||||
|
}
|
||||||
|
if err := a.deleteAccess(acc.token, acc.frontendToken); err != nil {
|
||||||
|
logrus.Errorf("error deleting access '%v': %v", acc.frontendToken, err)
|
||||||
|
}
|
||||||
|
delete(a.accesses, acc.frontendToken)
|
||||||
|
} else {
|
||||||
|
logrus.Debug("skipping unidentified (orphaned) access removal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Agent) deleteShare(token string) error {
|
||||||
|
logrus.Debugf("deleting share '%v'", token)
|
||||||
|
if err := sdk.DeleteShare(a.root, &sdk.Share{Token: token}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Agent) deleteAccess(token, frontendToken string) error {
|
||||||
|
logrus.Debugf("deleting access '%v'", frontendToken)
|
||||||
|
if err := sdk.DeleteAccess(a.root, &sdk.Access{Token: frontendToken, ShareToken: token}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type agentGrpcImpl struct {
|
||||||
|
agentGrpc.UnimplementedAgentServer
|
||||||
|
agent *Agent
|
||||||
|
}
|
51
agent/agentClient/agentClient.go
Normal file
51
agent/agentClient/agentClient.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package agentClient
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/openziti/zrok/agent/agentGrpc"
|
||||||
|
"github.com/openziti/zrok/build"
|
||||||
|
"github.com/openziti/zrok/environment/env_core"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
|
"google.golang.org/grpc/resolver"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewClient(root env_core.Root) (client agentGrpc.AgentClient, conn *grpc.ClientConn, err error) {
|
||||||
|
agentSocket, err := root.AgentSocket()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := []grpc.DialOption{
|
||||||
|
grpc.WithContextDialer(func(_ context.Context, addr string) (net.Conn, error) {
|
||||||
|
return net.Dial("unix", addr)
|
||||||
|
}),
|
||||||
|
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||||
|
}
|
||||||
|
resolver.SetDefaultScheme("passthrough")
|
||||||
|
conn, err = grpc.NewClient(agentSocket, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return agentGrpc.NewAgentClient(conn), conn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsAgentRunning(root env_core.Root) (bool, error) {
|
||||||
|
client, conn, err := NewClient(root)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
defer func() { _ = conn.Close() }()
|
||||||
|
resp, err := client.Version(context.Background(), &agentGrpc.VersionRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(resp.GetV(), build.Series) {
|
||||||
|
return false, errors.Errorf("agent reported version '%v'; we expected version '%v'", resp.GetV(), build.Series)
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
1625
agent/agentGrpc/agent.pb.go
Normal file
1625
agent/agentGrpc/agent.pb.go
Normal file
File diff suppressed because it is too large
Load Diff
659
agent/agentGrpc/agent.pb.gw.go
Normal file
659
agent/agentGrpc/agent.pb.gw.go
Normal file
@ -0,0 +1,659 @@
|
|||||||
|
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
|
||||||
|
// source: agent/agentGrpc/agent.proto
|
||||||
|
|
||||||
|
/*
|
||||||
|
Package agentGrpc is a reverse proxy.
|
||||||
|
|
||||||
|
It translates gRPC into RESTful JSON APIs.
|
||||||
|
*/
|
||||||
|
package agentGrpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||||
|
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/grpclog"
|
||||||
|
"google.golang.org/grpc/metadata"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Suppress "imported and not used" errors
|
||||||
|
var _ codes.Code
|
||||||
|
var _ io.Reader
|
||||||
|
var _ status.Status
|
||||||
|
var _ = runtime.String
|
||||||
|
var _ = utilities.NewDoubleArray
|
||||||
|
var _ = metadata.Join
|
||||||
|
|
||||||
|
var (
|
||||||
|
filter_Agent_AccessPrivate_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||||
|
)
|
||||||
|
|
||||||
|
func request_Agent_AccessPrivate_0(ctx context.Context, marshaler runtime.Marshaler, client AgentClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq AccessPrivateRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_AccessPrivate_0); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := client.AccessPrivate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func local_request_Agent_AccessPrivate_0(ctx context.Context, marshaler runtime.Marshaler, server AgentServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq AccessPrivateRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_AccessPrivate_0); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := server.AccessPrivate(ctx, &protoReq)
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
filter_Agent_ReleaseAccess_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||||
|
)
|
||||||
|
|
||||||
|
func request_Agent_ReleaseAccess_0(ctx context.Context, marshaler runtime.Marshaler, client AgentClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq ReleaseAccessRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_ReleaseAccess_0); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := client.ReleaseAccess(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func local_request_Agent_ReleaseAccess_0(ctx context.Context, marshaler runtime.Marshaler, server AgentServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq ReleaseAccessRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_ReleaseAccess_0); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := server.ReleaseAccess(ctx, &protoReq)
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
filter_Agent_ReleaseShare_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||||
|
)
|
||||||
|
|
||||||
|
func request_Agent_ReleaseShare_0(ctx context.Context, marshaler runtime.Marshaler, client AgentClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq ReleaseShareRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_ReleaseShare_0); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := client.ReleaseShare(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func local_request_Agent_ReleaseShare_0(ctx context.Context, marshaler runtime.Marshaler, server AgentServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq ReleaseShareRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_ReleaseShare_0); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := server.ReleaseShare(ctx, &protoReq)
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
filter_Agent_SharePrivate_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||||
|
)
|
||||||
|
|
||||||
|
func request_Agent_SharePrivate_0(ctx context.Context, marshaler runtime.Marshaler, client AgentClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq SharePrivateRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_SharePrivate_0); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := client.SharePrivate(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func local_request_Agent_SharePrivate_0(ctx context.Context, marshaler runtime.Marshaler, server AgentServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq SharePrivateRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_SharePrivate_0); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := server.SharePrivate(ctx, &protoReq)
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
filter_Agent_SharePublic_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
|
||||||
|
)
|
||||||
|
|
||||||
|
func request_Agent_SharePublic_0(ctx context.Context, marshaler runtime.Marshaler, client AgentClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq SharePublicRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_SharePublic_0); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := client.SharePublic(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func local_request_Agent_SharePublic_0(ctx context.Context, marshaler runtime.Marshaler, server AgentServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq SharePublicRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
if err := req.ParseForm(); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Agent_SharePublic_0); err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := server.SharePublic(ctx, &protoReq)
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func request_Agent_Status_0(ctx context.Context, marshaler runtime.Marshaler, client AgentClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq StatusRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
msg, err := client.Status(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func local_request_Agent_Status_0(ctx context.Context, marshaler runtime.Marshaler, server AgentServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq StatusRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
msg, err := server.Status(ctx, &protoReq)
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func request_Agent_Version_0(ctx context.Context, marshaler runtime.Marshaler, client AgentClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq VersionRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
msg, err := client.Version(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func local_request_Agent_Version_0(ctx context.Context, marshaler runtime.Marshaler, server AgentServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq VersionRequest
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
msg, err := server.Version(ctx, &protoReq)
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterAgentHandlerServer registers the http handlers for service Agent to "mux".
|
||||||
|
// UnaryRPC :call AgentServer directly.
|
||||||
|
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
|
||||||
|
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterAgentHandlerFromEndpoint instead.
|
||||||
|
func RegisterAgentHandlerServer(ctx context.Context, mux *runtime.ServeMux, server AgentServer) error {
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Agent_AccessPrivate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
var stream runtime.ServerTransportStream
|
||||||
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Agent/AccessPrivate", runtime.WithHTTPPathPattern("/v1/agent/accessPrivate"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := local_request_Agent_AccessPrivate_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||||
|
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Agent_AccessPrivate_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Agent_ReleaseAccess_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
var stream runtime.ServerTransportStream
|
||||||
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Agent/ReleaseAccess", runtime.WithHTTPPathPattern("/v1/agent/releaseAccess"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := local_request_Agent_ReleaseAccess_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||||
|
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Agent_ReleaseAccess_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Agent_ReleaseShare_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
var stream runtime.ServerTransportStream
|
||||||
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Agent/ReleaseShare", runtime.WithHTTPPathPattern("/v1/agent/releaseShare"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := local_request_Agent_ReleaseShare_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||||
|
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Agent_ReleaseShare_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Agent_SharePrivate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
var stream runtime.ServerTransportStream
|
||||||
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Agent/SharePrivate", runtime.WithHTTPPathPattern("/v1/agent/sharePrivate"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := local_request_Agent_SharePrivate_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||||
|
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Agent_SharePrivate_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Agent_SharePublic_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
var stream runtime.ServerTransportStream
|
||||||
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Agent/SharePublic", runtime.WithHTTPPathPattern("/v1/agent/sharePublic"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := local_request_Agent_SharePublic_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||||
|
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Agent_SharePublic_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.Handle("GET", pattern_Agent_Status_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
var stream runtime.ServerTransportStream
|
||||||
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Agent/Status", runtime.WithHTTPPathPattern("/v1/agent/status"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := local_request_Agent_Status_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||||
|
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Agent_Status_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.Handle("GET", pattern_Agent_Version_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
var stream runtime.ServerTransportStream
|
||||||
|
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/.Agent/Version", runtime.WithHTTPPathPattern("/v1/agent/version"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := local_request_Agent_Version_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||||
|
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Agent_Version_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterAgentHandlerFromEndpoint is same as RegisterAgentHandler but
|
||||||
|
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
|
||||||
|
func RegisterAgentHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
|
||||||
|
conn, err := grpc.DialContext(ctx, endpoint, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
if cerr := conn.Close(); cerr != nil {
|
||||||
|
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
<-ctx.Done()
|
||||||
|
if cerr := conn.Close(); cerr != nil {
|
||||||
|
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}()
|
||||||
|
|
||||||
|
return RegisterAgentHandler(ctx, mux, conn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterAgentHandler registers the http handlers for service Agent to "mux".
|
||||||
|
// The handlers forward requests to the grpc endpoint over "conn".
|
||||||
|
func RegisterAgentHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
|
||||||
|
return RegisterAgentHandlerClient(ctx, mux, NewAgentClient(conn))
|
||||||
|
}
|
||||||
|
|
||||||
|
// RegisterAgentHandlerClient registers the http handlers for service Agent
|
||||||
|
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "AgentClient".
|
||||||
|
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AgentClient"
|
||||||
|
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
|
||||||
|
// "AgentClient" to call the correct interceptors.
|
||||||
|
func RegisterAgentHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AgentClient) error {
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Agent_AccessPrivate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Agent/AccessPrivate", runtime.WithHTTPPathPattern("/v1/agent/accessPrivate"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := request_Agent_AccessPrivate_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Agent_AccessPrivate_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Agent_ReleaseAccess_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Agent/ReleaseAccess", runtime.WithHTTPPathPattern("/v1/agent/releaseAccess"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := request_Agent_ReleaseAccess_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Agent_ReleaseAccess_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Agent_ReleaseShare_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Agent/ReleaseShare", runtime.WithHTTPPathPattern("/v1/agent/releaseShare"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := request_Agent_ReleaseShare_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Agent_ReleaseShare_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Agent_SharePrivate_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Agent/SharePrivate", runtime.WithHTTPPathPattern("/v1/agent/sharePrivate"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := request_Agent_SharePrivate_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Agent_SharePrivate_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.Handle("POST", pattern_Agent_SharePublic_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Agent/SharePublic", runtime.WithHTTPPathPattern("/v1/agent/sharePublic"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := request_Agent_SharePublic_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Agent_SharePublic_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.Handle("GET", pattern_Agent_Status_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Agent/Status", runtime.WithHTTPPathPattern("/v1/agent/status"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := request_Agent_Status_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Agent_Status_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
mux.Handle("GET", pattern_Agent_Version_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
var err error
|
||||||
|
var annotatedContext context.Context
|
||||||
|
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/.Agent/Version", runtime.WithHTTPPathPattern("/v1/agent/version"))
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := request_Agent_Version_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||||
|
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_Agent_Version_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
pattern_Agent_AccessPrivate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "agent", "accessPrivate"}, ""))
|
||||||
|
|
||||||
|
pattern_Agent_ReleaseAccess_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "agent", "releaseAccess"}, ""))
|
||||||
|
|
||||||
|
pattern_Agent_ReleaseShare_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "agent", "releaseShare"}, ""))
|
||||||
|
|
||||||
|
pattern_Agent_SharePrivate_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "agent", "sharePrivate"}, ""))
|
||||||
|
|
||||||
|
pattern_Agent_SharePublic_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "agent", "sharePublic"}, ""))
|
||||||
|
|
||||||
|
pattern_Agent_Status_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "agent", "status"}, ""))
|
||||||
|
|
||||||
|
pattern_Agent_Version_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "agent", "version"}, ""))
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
forward_Agent_AccessPrivate_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
|
forward_Agent_ReleaseAccess_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
|
forward_Agent_ReleaseShare_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
|
forward_Agent_SharePrivate_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
|
forward_Agent_SharePublic_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
|
forward_Agent_Status_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
|
forward_Agent_Version_0 = runtime.ForwardResponseMessage
|
||||||
|
)
|
150
agent/agentGrpc/agent.proto
Normal file
150
agent/agentGrpc/agent.proto
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
option go_package = "github.com/openziti/zrok/agent/agentGrpc";
|
||||||
|
|
||||||
|
import "google/api/annotations.proto";
|
||||||
|
|
||||||
|
service Agent {
|
||||||
|
rpc AccessPrivate(AccessPrivateRequest) returns (AccessPrivateResponse) {
|
||||||
|
option(google.api.http) = {
|
||||||
|
post: "/v1/agent/accessPrivate"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
rpc ReleaseAccess(ReleaseAccessRequest) returns (ReleaseAccessResponse) {
|
||||||
|
option(google.api.http) = {
|
||||||
|
post: "/v1/agent/releaseAccess"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
rpc ReleaseShare(ReleaseShareRequest) returns (ReleaseShareResponse) {
|
||||||
|
option(google.api.http) = {
|
||||||
|
post: "/v1/agent/releaseShare"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
rpc ShareReserved(ShareReservedRequest) returns (ShareReservedResponse) {}
|
||||||
|
rpc SharePrivate(SharePrivateRequest) returns (SharePrivateResponse) {
|
||||||
|
option(google.api.http) = {
|
||||||
|
post: "/v1/agent/sharePrivate"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
rpc SharePublic(SharePublicRequest) returns (SharePublicResponse) {
|
||||||
|
option(google.api.http) = {
|
||||||
|
post: "/v1/agent/sharePublic"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
rpc Status(StatusRequest) returns (StatusResponse) {
|
||||||
|
option(google.api.http) = {
|
||||||
|
get: "/v1/agent/status"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
rpc Version(VersionRequest) returns (VersionResponse) {
|
||||||
|
option(google.api.http) = {
|
||||||
|
get: "/v1/agent/version"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message AccessDetail {
|
||||||
|
string frontendToken = 1;
|
||||||
|
string token = 2;
|
||||||
|
string bindAddress = 3;
|
||||||
|
repeated string responseHeaders = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AccessPrivateResponse{
|
||||||
|
string frontendToken = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AccessPrivateRequest{
|
||||||
|
string token = 1;
|
||||||
|
string bindAddress = 2;
|
||||||
|
bool autoMode = 3;
|
||||||
|
string autoAddress = 4;
|
||||||
|
uint32 autoStartPort = 5;
|
||||||
|
uint32 autoEndPort = 6;
|
||||||
|
repeated string responseHeaders = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReleaseAccessRequest {
|
||||||
|
string frontendToken = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReleaseAccessResponse {
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReleaseShareRequest {
|
||||||
|
string token = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ReleaseShareResponse {
|
||||||
|
}
|
||||||
|
|
||||||
|
message ShareDetail {
|
||||||
|
string token = 1;
|
||||||
|
string shareMode = 2;
|
||||||
|
string backendMode = 3;
|
||||||
|
bool reserved = 4;
|
||||||
|
repeated string frontendEndpoint = 5;
|
||||||
|
string backendEndpoint = 6;
|
||||||
|
bool closed = 7;
|
||||||
|
string status = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SharePrivateRequest {
|
||||||
|
string target = 1;
|
||||||
|
string backendMode = 2;
|
||||||
|
bool insecure = 3;
|
||||||
|
bool closed = 4;
|
||||||
|
repeated string accessGrants = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SharePrivateResponse {
|
||||||
|
string token = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SharePublicRequest {
|
||||||
|
string target = 1;
|
||||||
|
repeated string basicAuth = 2;
|
||||||
|
repeated string frontendSelection = 3;
|
||||||
|
string backendMode = 4;
|
||||||
|
bool insecure = 5;
|
||||||
|
string oauthProvider = 6;
|
||||||
|
repeated string oauthEmailAddressPatterns = 7;
|
||||||
|
string oauthCheckInterval = 8;
|
||||||
|
bool closed = 9;
|
||||||
|
repeated string accessGrants = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message SharePublicResponse {
|
||||||
|
string token = 1;
|
||||||
|
repeated string frontendEndpoints = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ShareReservedRequest {
|
||||||
|
string token = 1;
|
||||||
|
string overrideEndpoint = 2;
|
||||||
|
bool insecure = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ShareReservedResponse {
|
||||||
|
string token = 1;
|
||||||
|
string backendMode = 2;
|
||||||
|
string shareMode = 3;
|
||||||
|
repeated string frontendEndpoints = 4;
|
||||||
|
string target = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message StatusRequest {
|
||||||
|
}
|
||||||
|
|
||||||
|
message StatusResponse {
|
||||||
|
repeated AccessDetail accesses = 1;
|
||||||
|
repeated ShareDetail shares = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message VersionRequest {
|
||||||
|
}
|
||||||
|
|
||||||
|
message VersionResponse {
|
||||||
|
string v = 1;
|
||||||
|
string consoleEndpoint = 2;
|
||||||
|
}
|
525
agent/agentGrpc/agent.swagger.json
Normal file
525
agent/agentGrpc/agent.swagger.json
Normal file
@ -0,0 +1,525 @@
|
|||||||
|
{
|
||||||
|
"swagger": "2.0",
|
||||||
|
"info": {
|
||||||
|
"title": "agent/agentGrpc/agent.proto",
|
||||||
|
"version": "version not set"
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
{
|
||||||
|
"name": "Agent"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/v1/agent/accessPrivate": {
|
||||||
|
"post": {
|
||||||
|
"operationId": "Agent_AccessPrivate",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/AccessPrivateResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "An unexpected error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/rpcStatus"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "token",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "bindAddress",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "autoMode",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "autoAddress",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "autoStartPort",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "autoEndPort",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "responseHeaders",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"collectionFormat": "multi"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Agent"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/v1/agent/releaseAccess": {
|
||||||
|
"post": {
|
||||||
|
"operationId": "Agent_ReleaseAccess",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ReleaseAccessResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "An unexpected error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/rpcStatus"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "frontendToken",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Agent"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/v1/agent/releaseShare": {
|
||||||
|
"post": {
|
||||||
|
"operationId": "Agent_ReleaseShare",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/ReleaseShareResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "An unexpected error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/rpcStatus"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "token",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Agent"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/v1/agent/sharePrivate": {
|
||||||
|
"post": {
|
||||||
|
"operationId": "Agent_SharePrivate",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/SharePrivateResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "An unexpected error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/rpcStatus"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "target",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "backendMode",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "insecure",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "closed",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "accessGrants",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"collectionFormat": "multi"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Agent"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/v1/agent/sharePublic": {
|
||||||
|
"post": {
|
||||||
|
"operationId": "Agent_SharePublic",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/SharePublicResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "An unexpected error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/rpcStatus"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "target",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "basicAuth",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"collectionFormat": "multi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "frontendSelection",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"collectionFormat": "multi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "backendMode",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "insecure",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "oauthProvider",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "oauthEmailAddressPatterns",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"collectionFormat": "multi"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "oauthCheckInterval",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "closed",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "accessGrants",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"collectionFormat": "multi"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"Agent"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/v1/agent/status": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "Agent_Status",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/StatusResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "An unexpected error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/rpcStatus"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"Agent"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/v1/agent/version": {
|
||||||
|
"get": {
|
||||||
|
"operationId": "Agent_Version",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/VersionResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"default": {
|
||||||
|
"description": "An unexpected error response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/rpcStatus"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tags": [
|
||||||
|
"Agent"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"definitions": {
|
||||||
|
"AccessDetail": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"frontendToken": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"bindAddress": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"responseHeaders": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AccessPrivateResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"frontendToken": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ReleaseAccessResponse": {
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"ReleaseShareResponse": {
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"ShareDetail": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"token": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"shareMode": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"backendMode": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"reserved": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"frontendEndpoint": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"backendEndpoint": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"closed": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SharePrivateResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"token": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SharePublicResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"token": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"frontendEndpoints": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ShareReservedResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"token": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"backendMode": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"shareMode": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"frontendEndpoints": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"target": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"StatusResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"accesses": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/AccessDetail"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"shares": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/ShareDetail"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"VersionResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"v": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"consoleEndpoint": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"protobufAny": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"@type": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": {}
|
||||||
|
},
|
||||||
|
"rpcStatus": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"code": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"details": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"$ref": "#/definitions/protobufAny"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
387
agent/agentGrpc/agent_grpc.pb.go
Normal file
387
agent/agentGrpc/agent_grpc.pb.go
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// - protoc-gen-go-grpc v1.5.1
|
||||||
|
// - protoc v5.27.3
|
||||||
|
// source: agent/agentGrpc/agent.proto
|
||||||
|
|
||||||
|
package agentGrpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
context "context"
|
||||||
|
grpc "google.golang.org/grpc"
|
||||||
|
codes "google.golang.org/grpc/codes"
|
||||||
|
status "google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This is a compile-time assertion to ensure that this generated file
|
||||||
|
// is compatible with the grpc package it is being compiled against.
|
||||||
|
// Requires gRPC-Go v1.64.0 or later.
|
||||||
|
const _ = grpc.SupportPackageIsVersion9
|
||||||
|
|
||||||
|
const (
|
||||||
|
Agent_AccessPrivate_FullMethodName = "/Agent/AccessPrivate"
|
||||||
|
Agent_ReleaseAccess_FullMethodName = "/Agent/ReleaseAccess"
|
||||||
|
Agent_ReleaseShare_FullMethodName = "/Agent/ReleaseShare"
|
||||||
|
Agent_ShareReserved_FullMethodName = "/Agent/ShareReserved"
|
||||||
|
Agent_SharePrivate_FullMethodName = "/Agent/SharePrivate"
|
||||||
|
Agent_SharePublic_FullMethodName = "/Agent/SharePublic"
|
||||||
|
Agent_Status_FullMethodName = "/Agent/Status"
|
||||||
|
Agent_Version_FullMethodName = "/Agent/Version"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AgentClient is the client API for Agent service.
|
||||||
|
//
|
||||||
|
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||||
|
type AgentClient interface {
|
||||||
|
AccessPrivate(ctx context.Context, in *AccessPrivateRequest, opts ...grpc.CallOption) (*AccessPrivateResponse, error)
|
||||||
|
ReleaseAccess(ctx context.Context, in *ReleaseAccessRequest, opts ...grpc.CallOption) (*ReleaseAccessResponse, error)
|
||||||
|
ReleaseShare(ctx context.Context, in *ReleaseShareRequest, opts ...grpc.CallOption) (*ReleaseShareResponse, error)
|
||||||
|
ShareReserved(ctx context.Context, in *ShareReservedRequest, opts ...grpc.CallOption) (*ShareReservedResponse, error)
|
||||||
|
SharePrivate(ctx context.Context, in *SharePrivateRequest, opts ...grpc.CallOption) (*SharePrivateResponse, error)
|
||||||
|
SharePublic(ctx context.Context, in *SharePublicRequest, opts ...grpc.CallOption) (*SharePublicResponse, error)
|
||||||
|
Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error)
|
||||||
|
Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionResponse, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type agentClient struct {
|
||||||
|
cc grpc.ClientConnInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAgentClient(cc grpc.ClientConnInterface) AgentClient {
|
||||||
|
return &agentClient{cc}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *agentClient) AccessPrivate(ctx context.Context, in *AccessPrivateRequest, opts ...grpc.CallOption) (*AccessPrivateResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(AccessPrivateResponse)
|
||||||
|
err := c.cc.Invoke(ctx, Agent_AccessPrivate_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *agentClient) ReleaseAccess(ctx context.Context, in *ReleaseAccessRequest, opts ...grpc.CallOption) (*ReleaseAccessResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(ReleaseAccessResponse)
|
||||||
|
err := c.cc.Invoke(ctx, Agent_ReleaseAccess_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *agentClient) ReleaseShare(ctx context.Context, in *ReleaseShareRequest, opts ...grpc.CallOption) (*ReleaseShareResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(ReleaseShareResponse)
|
||||||
|
err := c.cc.Invoke(ctx, Agent_ReleaseShare_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *agentClient) ShareReserved(ctx context.Context, in *ShareReservedRequest, opts ...grpc.CallOption) (*ShareReservedResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(ShareReservedResponse)
|
||||||
|
err := c.cc.Invoke(ctx, Agent_ShareReserved_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *agentClient) SharePrivate(ctx context.Context, in *SharePrivateRequest, opts ...grpc.CallOption) (*SharePrivateResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(SharePrivateResponse)
|
||||||
|
err := c.cc.Invoke(ctx, Agent_SharePrivate_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *agentClient) SharePublic(ctx context.Context, in *SharePublicRequest, opts ...grpc.CallOption) (*SharePublicResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(SharePublicResponse)
|
||||||
|
err := c.cc.Invoke(ctx, Agent_SharePublic_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *agentClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(StatusResponse)
|
||||||
|
err := c.cc.Invoke(ctx, Agent_Status_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *agentClient) Version(ctx context.Context, in *VersionRequest, opts ...grpc.CallOption) (*VersionResponse, error) {
|
||||||
|
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
|
||||||
|
out := new(VersionResponse)
|
||||||
|
err := c.cc.Invoke(ctx, Agent_Version_FullMethodName, in, out, cOpts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AgentServer is the server API for Agent service.
|
||||||
|
// All implementations must embed UnimplementedAgentServer
|
||||||
|
// for forward compatibility.
|
||||||
|
type AgentServer interface {
|
||||||
|
AccessPrivate(context.Context, *AccessPrivateRequest) (*AccessPrivateResponse, error)
|
||||||
|
ReleaseAccess(context.Context, *ReleaseAccessRequest) (*ReleaseAccessResponse, error)
|
||||||
|
ReleaseShare(context.Context, *ReleaseShareRequest) (*ReleaseShareResponse, error)
|
||||||
|
ShareReserved(context.Context, *ShareReservedRequest) (*ShareReservedResponse, error)
|
||||||
|
SharePrivate(context.Context, *SharePrivateRequest) (*SharePrivateResponse, error)
|
||||||
|
SharePublic(context.Context, *SharePublicRequest) (*SharePublicResponse, error)
|
||||||
|
Status(context.Context, *StatusRequest) (*StatusResponse, error)
|
||||||
|
Version(context.Context, *VersionRequest) (*VersionResponse, error)
|
||||||
|
mustEmbedUnimplementedAgentServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnimplementedAgentServer must be embedded to have
|
||||||
|
// forward compatible implementations.
|
||||||
|
//
|
||||||
|
// NOTE: this should be embedded by value instead of pointer to avoid a nil
|
||||||
|
// pointer dereference when methods are called.
|
||||||
|
type UnimplementedAgentServer struct{}
|
||||||
|
|
||||||
|
func (UnimplementedAgentServer) AccessPrivate(context.Context, *AccessPrivateRequest) (*AccessPrivateResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method AccessPrivate not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedAgentServer) ReleaseAccess(context.Context, *ReleaseAccessRequest) (*ReleaseAccessResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method ReleaseAccess not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedAgentServer) ReleaseShare(context.Context, *ReleaseShareRequest) (*ReleaseShareResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method ReleaseShare not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedAgentServer) ShareReserved(context.Context, *ShareReservedRequest) (*ShareReservedResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method ShareReserved not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedAgentServer) SharePrivate(context.Context, *SharePrivateRequest) (*SharePrivateResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method SharePrivate not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedAgentServer) SharePublic(context.Context, *SharePublicRequest) (*SharePublicResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method SharePublic not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedAgentServer) Status(context.Context, *StatusRequest) (*StatusResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method Status not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedAgentServer) Version(context.Context, *VersionRequest) (*VersionResponse, error) {
|
||||||
|
return nil, status.Errorf(codes.Unimplemented, "method Version not implemented")
|
||||||
|
}
|
||||||
|
func (UnimplementedAgentServer) mustEmbedUnimplementedAgentServer() {}
|
||||||
|
func (UnimplementedAgentServer) testEmbeddedByValue() {}
|
||||||
|
|
||||||
|
// UnsafeAgentServer may be embedded to opt out of forward compatibility for this service.
|
||||||
|
// Use of this interface is not recommended, as added methods to AgentServer will
|
||||||
|
// result in compilation errors.
|
||||||
|
type UnsafeAgentServer interface {
|
||||||
|
mustEmbedUnimplementedAgentServer()
|
||||||
|
}
|
||||||
|
|
||||||
|
func RegisterAgentServer(s grpc.ServiceRegistrar, srv AgentServer) {
|
||||||
|
// If the following call pancis, it indicates UnimplementedAgentServer was
|
||||||
|
// embedded by pointer and is nil. This will cause panics if an
|
||||||
|
// unimplemented method is ever invoked, so we test this at initialization
|
||||||
|
// time to prevent it from happening at runtime later due to I/O.
|
||||||
|
if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
|
||||||
|
t.testEmbeddedByValue()
|
||||||
|
}
|
||||||
|
s.RegisterService(&Agent_ServiceDesc, srv)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _Agent_AccessPrivate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(AccessPrivateRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(AgentServer).AccessPrivate(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: Agent_AccessPrivate_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(AgentServer).AccessPrivate(ctx, req.(*AccessPrivateRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _Agent_ReleaseAccess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(ReleaseAccessRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(AgentServer).ReleaseAccess(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: Agent_ReleaseAccess_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(AgentServer).ReleaseAccess(ctx, req.(*ReleaseAccessRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _Agent_ReleaseShare_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(ReleaseShareRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(AgentServer).ReleaseShare(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: Agent_ReleaseShare_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(AgentServer).ReleaseShare(ctx, req.(*ReleaseShareRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _Agent_ShareReserved_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(ShareReservedRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(AgentServer).ShareReserved(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: Agent_ShareReserved_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(AgentServer).ShareReserved(ctx, req.(*ShareReservedRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _Agent_SharePrivate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(SharePrivateRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(AgentServer).SharePrivate(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: Agent_SharePrivate_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(AgentServer).SharePrivate(ctx, req.(*SharePrivateRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _Agent_SharePublic_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(SharePublicRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(AgentServer).SharePublic(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: Agent_SharePublic_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(AgentServer).SharePublic(ctx, req.(*SharePublicRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _Agent_Status_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(StatusRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(AgentServer).Status(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: Agent_Status_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(AgentServer).Status(ctx, req.(*StatusRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _Agent_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||||
|
in := new(VersionRequest)
|
||||||
|
if err := dec(in); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if interceptor == nil {
|
||||||
|
return srv.(AgentServer).Version(ctx, in)
|
||||||
|
}
|
||||||
|
info := &grpc.UnaryServerInfo{
|
||||||
|
Server: srv,
|
||||||
|
FullMethod: Agent_Version_FullMethodName,
|
||||||
|
}
|
||||||
|
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||||
|
return srv.(AgentServer).Version(ctx, req.(*VersionRequest))
|
||||||
|
}
|
||||||
|
return interceptor(ctx, in, info, handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Agent_ServiceDesc is the grpc.ServiceDesc for Agent service.
|
||||||
|
// It's only intended for direct use with grpc.RegisterService,
|
||||||
|
// and not to be introspected or modified (even as a copy)
|
||||||
|
var Agent_ServiceDesc = grpc.ServiceDesc{
|
||||||
|
ServiceName: "Agent",
|
||||||
|
HandlerType: (*AgentServer)(nil),
|
||||||
|
Methods: []grpc.MethodDesc{
|
||||||
|
{
|
||||||
|
MethodName: "AccessPrivate",
|
||||||
|
Handler: _Agent_AccessPrivate_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "ReleaseAccess",
|
||||||
|
Handler: _Agent_ReleaseAccess_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "ReleaseShare",
|
||||||
|
Handler: _Agent_ReleaseShare_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "ShareReserved",
|
||||||
|
Handler: _Agent_ShareReserved_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "SharePrivate",
|
||||||
|
Handler: _Agent_SharePrivate_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "SharePublic",
|
||||||
|
Handler: _Agent_SharePublic_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "Status",
|
||||||
|
Handler: _Agent_Status_Handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MethodName: "Version",
|
||||||
|
Handler: _Agent_Version_Handler,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Streams: []grpc.StreamDesc{},
|
||||||
|
Metadata: "agent/agentGrpc/agent.proto",
|
||||||
|
}
|
10
agent/agentGrpc/tools.go
Normal file
10
agent/agentGrpc/tools.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
//go:build tools
|
||||||
|
|
||||||
|
package agentGrpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway"
|
||||||
|
_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2"
|
||||||
|
_ "google.golang.org/grpc/cmd/protoc-gen-go-grpc"
|
||||||
|
_ "google.golang.org/protobuf/cmd/protoc-gen-go"
|
||||||
|
)
|
24
agent/agentUi/.gitignore
vendored
Normal file
24
agent/agentUi/.gitignore
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
50
agent/agentUi/README.md
Normal file
50
agent/agentUi/README.md
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# React + TypeScript + Vite
|
||||||
|
|
||||||
|
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||||
|
|
||||||
|
Currently, two official plugins are available:
|
||||||
|
|
||||||
|
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
|
||||||
|
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
||||||
|
|
||||||
|
## Expanding the ESLint configuration
|
||||||
|
|
||||||
|
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
|
||||||
|
|
||||||
|
- Configure the top-level `parserOptions` property like this:
|
||||||
|
|
||||||
|
```js
|
||||||
|
export default tseslint.config({
|
||||||
|
languageOptions: {
|
||||||
|
// other options...
|
||||||
|
parserOptions: {
|
||||||
|
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
||||||
|
tsconfigRootDir: import.meta.dirname,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
|
||||||
|
- Optionally add `...tseslint.configs.stylisticTypeChecked`
|
||||||
|
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:
|
||||||
|
|
||||||
|
```js
|
||||||
|
// eslint.config.js
|
||||||
|
import react from 'eslint-plugin-react'
|
||||||
|
|
||||||
|
export default tseslint.config({
|
||||||
|
// Set the react version
|
||||||
|
settings: { react: { version: '18.3' } },
|
||||||
|
plugins: {
|
||||||
|
// Add the react plugin
|
||||||
|
react,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
// other rules...
|
||||||
|
// Enable its recommended rules
|
||||||
|
...react.configs.recommended.rules,
|
||||||
|
...react.configs['jsx-runtime'].rules,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
```
|
6
agent/agentUi/embed.go
Normal file
6
agent/agentUi/embed.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package agentUi
|
||||||
|
|
||||||
|
import "embed"
|
||||||
|
|
||||||
|
//go:embed dist
|
||||||
|
var FS embed.FS
|
28
agent/agentUi/eslint.config.js
Normal file
28
agent/agentUi/eslint.config.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import js from '@eslint/js'
|
||||||
|
import globals from 'globals'
|
||||||
|
import reactHooks from 'eslint-plugin-react-hooks'
|
||||||
|
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||||
|
import tseslint from 'typescript-eslint'
|
||||||
|
|
||||||
|
export default tseslint.config(
|
||||||
|
{ ignores: ['dist'] },
|
||||||
|
{
|
||||||
|
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
||||||
|
files: ['**/*.{ts,tsx}'],
|
||||||
|
languageOptions: {
|
||||||
|
ecmaVersion: 2020,
|
||||||
|
globals: globals.browser,
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
'react-hooks': reactHooks,
|
||||||
|
'react-refresh': reactRefresh,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...reactHooks.configs.recommended.rules,
|
||||||
|
'react-refresh/only-export-components': [
|
||||||
|
'warn',
|
||||||
|
{ allowConstantExport: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
17
agent/agentUi/index.html
Normal file
17
agent/agentUi/index.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/zrok.png" />
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono&display=swap" rel="stylesheet">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>zrok Agent Console</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
53
agent/agentUi/middleware.go
Normal file
53
agent/agentUi/middleware.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package agentUi
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"io/fs"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const staticPath = "dist"
|
||||||
|
|
||||||
|
func Middleware(handler http.Handler) http.Handler {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if strings.HasPrefix(r.URL.Path, "/v1") {
|
||||||
|
handler.ServeHTTP(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
path := filepath.ToSlash(filepath.Join(staticPath, r.URL.Path))
|
||||||
|
logrus.Debugf("path = %v", path)
|
||||||
|
|
||||||
|
f, err := FS.Open(path)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
// file does not exist, serve index.gohtml
|
||||||
|
index, err := FS.ReadFile(filepath.ToSlash(filepath.Join(staticPath, "index.html")))
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
|
w.WriteHeader(http.StatusAccepted)
|
||||||
|
_, _ = w.Write(index)
|
||||||
|
return
|
||||||
|
|
||||||
|
} else if err != nil {
|
||||||
|
// if we got an error (that wasn't that the file doesn't exist) stating the
|
||||||
|
// file, return a 500 internal server error and stop
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer func() { _ = f.Close() }()
|
||||||
|
|
||||||
|
// get the subdirectory of the static dir
|
||||||
|
if statics, err := fs.Sub(FS, staticPath); err == nil {
|
||||||
|
// otherwise, use http.FileServer to serve the static dir
|
||||||
|
http.FileServer(http.FS(statics)).ServeHTTP(w, r)
|
||||||
|
} else {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
3931
agent/agentUi/package-lock.json
generated
Normal file
3931
agent/agentUi/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
33
agent/agentUi/package.json
Normal file
33
agent/agentUi/package.json
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"name": "agentui",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@emotion/react": "^11.13.3",
|
||||||
|
"@emotion/styled": "^11.13.0",
|
||||||
|
"@mui/icons-material": "^6.1.7",
|
||||||
|
"@mui/material": "^6.1.7",
|
||||||
|
"formik": "^2.4.6",
|
||||||
|
"react": "^18.3.1",
|
||||||
|
"react-dom": "^18.3.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.13.0",
|
||||||
|
"@types/react": "^18.3.12",
|
||||||
|
"@types/react-dom": "^18.3.1",
|
||||||
|
"@vitejs/plugin-react": "^4.3.3",
|
||||||
|
"eslint": "^9.13.0",
|
||||||
|
"eslint-plugin-react-hooks": "^5.0.0",
|
||||||
|
"eslint-plugin-react-refresh": "^0.4.14",
|
||||||
|
"globals": "^15.11.0",
|
||||||
|
"typescript-eslint": "^8.15.0",
|
||||||
|
"vite": "^5.4.10"
|
||||||
|
}
|
||||||
|
}
|
BIN
agent/agentUi/public/zrok.png
Normal file
BIN
agent/agentUi/public/zrok.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
53
agent/agentUi/src/AccessCard.tsx
Normal file
53
agent/agentUi/src/AccessCard.tsx
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import {AgentObject} from "./model/overview.ts";
|
||||||
|
import {AppBar, Box, Button, Card, Chip, Grid2, Toolbar, Typography} from "@mui/material";
|
||||||
|
import LanIcon from "@mui/icons-material/Lan";
|
||||||
|
import {AccessDetail} from "./api";
|
||||||
|
import DeleteIcon from "@mui/icons-material/Delete";
|
||||||
|
import {GetAgentApi} from "./model/api.ts";
|
||||||
|
|
||||||
|
interface AccessCardProps {
|
||||||
|
accessObject: AgentObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AccessCard = ({ accessObject }: AccessCardProps) => {
|
||||||
|
let access = (accessObject.v as AccessDetail);
|
||||||
|
|
||||||
|
const releaseAccess = () => {
|
||||||
|
GetAgentApi().agentReleaseAccess({frontendToken: access.frontendToken})
|
||||||
|
.catch(e => {
|
||||||
|
console.log("error releasing access", e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<AppBar position="sticky">
|
||||||
|
<Toolbar variant="dense">
|
||||||
|
<LanIcon />
|
||||||
|
<Grid2 container sx={{ flexGrow: 1 }}>
|
||||||
|
<Grid2 display="flex" justifyContent="center" size="grow">
|
||||||
|
<Typography variant="h6" component="div" style={{ color: "#9bf316" }}>{access.frontendToken}</Typography>
|
||||||
|
</Grid2>
|
||||||
|
</Grid2>
|
||||||
|
<Grid2 container>
|
||||||
|
<Grid2 display="flex" justifyContent="right">
|
||||||
|
<Chip label="private" size="small" style={{ backgroundColor: "#9bf316" }} />
|
||||||
|
</Grid2>
|
||||||
|
</Grid2>
|
||||||
|
</Toolbar>
|
||||||
|
</AppBar>
|
||||||
|
<Box sx={{ p: 2, textAlign: "center" }}>
|
||||||
|
<Typography variant="h6" component="div">
|
||||||
|
{access.token} → {access.bindAddress}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Grid2 container sx={{ flexGrow: 1 }}>
|
||||||
|
<Grid2 display="flex" justifyContent="right" size="grow">
|
||||||
|
<Button variant="contained" onClick={releaseAccess}><DeleteIcon /></Button>
|
||||||
|
</Grid2>
|
||||||
|
</Grid2>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AccessCard;
|
69
agent/agentUi/src/AgentUi.tsx
Normal file
69
agent/agentUi/src/AgentUi.tsx
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import {GetAgentApi} from "./model/api.ts";
|
||||||
|
import NavBar from "./NavBar.tsx";
|
||||||
|
import {AgentObject, buildOverview} from "./model/overview.ts";
|
||||||
|
import Overview from "./Overview.tsx";
|
||||||
|
import NewShareModal from "./NewShareModal.tsx";
|
||||||
|
import NewAccessModal from "./NewAccessModal.tsx";
|
||||||
|
|
||||||
|
const AgentUi = () => {
|
||||||
|
const [version, setVersion] = useState("unset");
|
||||||
|
const [overview, setOverview] = useState(new Array<AgentObject>());
|
||||||
|
const [newShareOpen, setNewShareOpen] = useState(false);
|
||||||
|
const [newAccessOpen, setNewAccessOpen] = useState(false);
|
||||||
|
|
||||||
|
const openNewShare = () => {
|
||||||
|
setNewShareOpen(true);
|
||||||
|
}
|
||||||
|
const closeNewShare = () => {
|
||||||
|
setNewShareOpen(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const openNewAccess = () => {
|
||||||
|
setNewAccessOpen(true);
|
||||||
|
}
|
||||||
|
const closeNewAccess = () => {
|
||||||
|
setNewAccessOpen(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
GetAgentApi().agentVersion()
|
||||||
|
.then(r => {
|
||||||
|
if(r.v) {
|
||||||
|
setVersion(r.v);
|
||||||
|
} else {
|
||||||
|
console.log("unexpected", r);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
console.log(e);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let interval = setInterval(() => {
|
||||||
|
GetAgentApi().agentStatus()
|
||||||
|
.then(r => {
|
||||||
|
setOverview(buildOverview(r));
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
console.log(e);
|
||||||
|
})
|
||||||
|
}, 1000);
|
||||||
|
return () => {
|
||||||
|
clearInterval(interval);
|
||||||
|
setOverview(new Array<AgentObject>());
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<NavBar shareClick={openNewShare} accessClick={openNewAccess} />
|
||||||
|
<Overview overview={overview} shareClick={openNewShare} accessClick={openNewAccess} />
|
||||||
|
<NewShareModal isOpen={newShareOpen} close={closeNewShare} />
|
||||||
|
<NewAccessModal isOpen={newAccessOpen} close={closeNewAccess} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AgentUi;
|
40
agent/agentUi/src/NavBar.tsx
Normal file
40
agent/agentUi/src/NavBar.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import {AppBar, Box, Button, Grid2, Toolbar, Typography} from "@mui/material";
|
||||||
|
import LanIcon from "@mui/icons-material/Lan";
|
||||||
|
import ShareIcon from "@mui/icons-material/Share";
|
||||||
|
import zrokLogo from "./assets/zrok-1.0.0-rocket-green.svg";
|
||||||
|
|
||||||
|
interface NavBarProps {
|
||||||
|
shareClick: () => void;
|
||||||
|
accessClick: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NavBar = ({ shareClick, accessClick }: NavBarProps) => {
|
||||||
|
return (
|
||||||
|
<Box ssx={{ flexGrow: 1 }}>
|
||||||
|
<AppBar position="static">
|
||||||
|
<Toolbar>
|
||||||
|
<Typography variant="h6" sx={{ flexGrow: 1 }}>
|
||||||
|
<Grid2 container sx={{ flexGrow: 1 }}>
|
||||||
|
<Grid2 display="flex" justifyContent="left">
|
||||||
|
<img src={zrokLogo} height="30" />
|
||||||
|
</Grid2>
|
||||||
|
<Grid2 display="flex" justifyContent="left" size="grow" sx={{ ml: 3 }} color="#9bf316">
|
||||||
|
<strong>z r o k Agent</strong>
|
||||||
|
</Grid2>
|
||||||
|
</Grid2>
|
||||||
|
</Typography>
|
||||||
|
<Grid2 container sx={{ flexGrow: 1 }}>
|
||||||
|
<Grid2 display="flex" justifyContent="right" size="grow">
|
||||||
|
<Button color="inherit" onClick={shareClick}><ShareIcon /></Button>
|
||||||
|
</Grid2>
|
||||||
|
<Grid2 display="flex" justifyContent="right">
|
||||||
|
<Button color="inherit" onClick={accessClick}><LanIcon /></Button>
|
||||||
|
</Grid2>
|
||||||
|
</Grid2>
|
||||||
|
</Toolbar>
|
||||||
|
</AppBar>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NavBar
|
69
agent/agentUi/src/NewAccessModal.tsx
Normal file
69
agent/agentUi/src/NewAccessModal.tsx
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
import {useState} from "react";
|
||||||
|
import {useFormik} from "formik";
|
||||||
|
import {GetAgentApi} from "./model/api.ts";
|
||||||
|
import {Box, Button, Modal, TextField, Typography} from "@mui/material";
|
||||||
|
import {modalStyle} from "./model/theme.ts";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
interface NewAccessModalProps {
|
||||||
|
close: () => void;
|
||||||
|
isOpen: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NewAccessModal = ({ close, isOpen }: NewAccessModalProps) => {
|
||||||
|
const [errorMessage, setErrorMessage] = useState(null as React.JSX.Element);
|
||||||
|
|
||||||
|
const newAccessForm = useFormik({
|
||||||
|
initialValues: {
|
||||||
|
token: "",
|
||||||
|
bindAddress: "",
|
||||||
|
},
|
||||||
|
onSubmit: v => {
|
||||||
|
setErrorMessage(null as React.JSX.Element);
|
||||||
|
GetAgentApi().agentAccessPrivate(v)
|
||||||
|
.then(r => {
|
||||||
|
close();
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
e.response.json().then(ex => {
|
||||||
|
setErrorMessage(<span>{ex.message}</span>);
|
||||||
|
console.log(ex.message);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal open={isOpen} onClose={close}>
|
||||||
|
<Box sx={{...modalStyle}}>
|
||||||
|
<Typography><h2>Access...</h2></Typography>
|
||||||
|
<Typography color="red"><h3>{errorMessage}</h3></Typography>
|
||||||
|
<form onSubmit={newAccessForm.handleSubmit}>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
id="token"
|
||||||
|
name="token"
|
||||||
|
label="Share Token"
|
||||||
|
value={newAccessForm.values.token}
|
||||||
|
onChange={newAccessForm.handleChange}
|
||||||
|
onBlur={newAccessForm.handleBlur}
|
||||||
|
sx={{mt: 2}}
|
||||||
|
/>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
id="bindAddress"
|
||||||
|
name="bindAddress"
|
||||||
|
label="Bind Address"
|
||||||
|
value={newAccessForm.values.bindAddress}
|
||||||
|
onChange={newAccessForm.handleChange}
|
||||||
|
onBlur={newAccessForm.handleBlur}
|
||||||
|
sx={{mt: 2}}
|
||||||
|
/>
|
||||||
|
<Button color="primary" variant="contained" type="submit" sx={{mt: 2}}>Create Access</Button>
|
||||||
|
</form>
|
||||||
|
</Box>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NewAccessModal;
|
146
agent/agentUi/src/NewShareModal.tsx
Normal file
146
agent/agentUi/src/NewShareModal.tsx
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
import {useFormik} from "formik";
|
||||||
|
import {GetAgentApi} from "./model/api.ts";
|
||||||
|
import {useState} from "react";
|
||||||
|
import {Box, Button, Checkbox, FormControlLabel, MenuItem, Modal, TextField, Typography} from "@mui/material";
|
||||||
|
import {modalStyle} from "./model/theme.ts";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
interface NewShareModalProps {
|
||||||
|
close: () => void;
|
||||||
|
isOpen: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NewShareModal = ({ close, isOpen }: NewShareModalProps) => {
|
||||||
|
const [errorMessage, setErrorMessage] = useState(null as React.JSX.Element);
|
||||||
|
|
||||||
|
const form = useFormik({
|
||||||
|
initialValues: {
|
||||||
|
shareMode: "public",
|
||||||
|
backendMode: "proxy",
|
||||||
|
target: "",
|
||||||
|
insecure: false,
|
||||||
|
},
|
||||||
|
onSubmit: v => {
|
||||||
|
setErrorMessage(null as React.JSX.Element);
|
||||||
|
switch(v.shareMode) {
|
||||||
|
case "public":
|
||||||
|
GetAgentApi().agentSharePublic(v)
|
||||||
|
.then(r => {
|
||||||
|
close();
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
e.response.json().then(ex => {
|
||||||
|
setErrorMessage(<span>{ex.message}</span>);
|
||||||
|
console.log(ex.message);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "private":
|
||||||
|
GetAgentApi().agentSharePrivate(v)
|
||||||
|
.then(r => {
|
||||||
|
close();
|
||||||
|
})
|
||||||
|
.catch(e => {
|
||||||
|
e.response().json().then(ex => {
|
||||||
|
setErrorMessage(<span>{ex.message}</span>);
|
||||||
|
console.log(ex.message);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal open={isOpen} onClose={close}>
|
||||||
|
<Box sx={{ ...modalStyle }}>
|
||||||
|
<Typography><h2>Share...</h2></Typography>
|
||||||
|
<Typography color="red"><h3>{errorMessage}</h3></Typography>
|
||||||
|
<form onSubmit={form.handleSubmit}>
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
select
|
||||||
|
id="shareMode"
|
||||||
|
name="shareMode"
|
||||||
|
label="Share Mode"
|
||||||
|
value={form.values.shareMode}
|
||||||
|
onChange={form.handleChange}
|
||||||
|
onBlur={form.handleBlur}
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
>
|
||||||
|
<MenuItem value="public">public</MenuItem>
|
||||||
|
<MenuItem value="private">private</MenuItem>
|
||||||
|
</TextField>
|
||||||
|
{form.values.shareMode === "public" && (
|
||||||
|
<TextField
|
||||||
|
fullWidth select
|
||||||
|
id="backendMode"
|
||||||
|
name="backendMode"
|
||||||
|
label="Backend Mode"
|
||||||
|
value={form.values.backendMode}
|
||||||
|
onChange={form.handleChange}
|
||||||
|
onBlur={form.handleBlur}
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
>
|
||||||
|
<MenuItem value="proxy">proxy</MenuItem>
|
||||||
|
<MenuItem value="web">web</MenuItem>
|
||||||
|
<MenuItem value="caddy">caddy</MenuItem>
|
||||||
|
<MenuItem value="drive">drive</MenuItem>
|
||||||
|
</TextField>
|
||||||
|
)}
|
||||||
|
{form.values.shareMode === "private" && (
|
||||||
|
<TextField
|
||||||
|
fullWidth select
|
||||||
|
id="backendMode"
|
||||||
|
name="backendMode"
|
||||||
|
label="Backend Mode"
|
||||||
|
value={form.values.backendMode}
|
||||||
|
onChange={form.handleChange}
|
||||||
|
onBlur={form.handleBlur}
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
>
|
||||||
|
<MenuItem value="proxy">proxy</MenuItem>
|
||||||
|
<MenuItem value="web">web</MenuItem>
|
||||||
|
<MenuItem value="tcpTunnel">tcpTunnel</MenuItem>
|
||||||
|
<MenuItem value="udpTunnel">udpTunnel</MenuItem>
|
||||||
|
<MenuItem value="caddy">caddy</MenuItem>
|
||||||
|
<MenuItem value="drive">drive</MenuItem>
|
||||||
|
<MenuItem value="socks">socks</MenuItem>
|
||||||
|
<MenuItem value="vpn">vpn</MenuItem>
|
||||||
|
</TextField>
|
||||||
|
)}
|
||||||
|
<TextField
|
||||||
|
fullWidth
|
||||||
|
id="target"
|
||||||
|
name="target"
|
||||||
|
label="Target"
|
||||||
|
value={form.values.target}
|
||||||
|
onChange={form.handleChange}
|
||||||
|
onBlur={form.handleBlur}
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
/>
|
||||||
|
{form.values.backendMode === "proxy" && (
|
||||||
|
<Box>
|
||||||
|
<FormControlLabel
|
||||||
|
control={<Checkbox
|
||||||
|
id="insecure"
|
||||||
|
name="insecure"
|
||||||
|
label="Insecure"
|
||||||
|
checked={form.values.insecure}
|
||||||
|
onChange={form.handleChange}
|
||||||
|
onBlur={form.handleBlur}
|
||||||
|
/>}
|
||||||
|
label="Insecure"
|
||||||
|
sx={{ mt: 2 }}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
<Button color="primary" variant="contained" type="submit" sx={{ mt: 2 }}>Create Share</Button>
|
||||||
|
</form>
|
||||||
|
</Box>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NewShareModal;
|
47
agent/agentUi/src/Overview.tsx
Normal file
47
agent/agentUi/src/Overview.tsx
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import {AgentObject} from "./model/overview.ts";
|
||||||
|
import {Box, Card, Grid2, Typography} from "@mui/material";
|
||||||
|
import ShareIcon from "@mui/icons-material/Share";
|
||||||
|
import LanIcon from "@mui/icons-material/Lan";
|
||||||
|
import ShareCard from "./ShareCard.tsx";
|
||||||
|
import AccessCard from "./AccessCard.tsx";
|
||||||
|
|
||||||
|
interface OverviewProps {
|
||||||
|
overview: Array<AgentObject>;
|
||||||
|
shareClick: () => void;
|
||||||
|
accessClick: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Overview = ({ overview, shareClick, accessClick }: OverviewProps) => {
|
||||||
|
let cards = [];
|
||||||
|
if(overview.length > 0) {
|
||||||
|
overview.forEach(row => {
|
||||||
|
switch(row.type) {
|
||||||
|
case "access":
|
||||||
|
cards.push(<Grid2 size={{ xs: 12, md: 6 }}><AccessCard accessObject={row} /></Grid2>);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "share":
|
||||||
|
cards.push(<Grid2 size={{ xs: 12, md: 6 }}><ShareCard shareObject={row} /></Grid2>);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
cards.push(<Grid2 size={{ xs: 12 }}>
|
||||||
|
<Card key="empty">
|
||||||
|
<Box sx={{ p: 2, textAlign: "center" }}>
|
||||||
|
<Typography variant="h6" component="div">
|
||||||
|
zrok Agent is empty! Add a <a href={"#"} onClick={shareClick}>share <ShareIcon/></a> or <a
|
||||||
|
href={"#"} onClick={accessClick}>access <LanIcon/></a> share to get started.
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
</Card>
|
||||||
|
</Grid2>);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Grid2 container spacing={2}>
|
||||||
|
{cards}
|
||||||
|
</Grid2>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Overview;
|
59
agent/agentUi/src/ShareCard.tsx
Normal file
59
agent/agentUi/src/ShareCard.tsx
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import {AgentObject} from "./model/overview.ts";
|
||||||
|
import {ShareDetail} from "./api";
|
||||||
|
import {AppBar, Box, Button, Card, Chip, Grid2, Toolbar, Typography} from "@mui/material";
|
||||||
|
import ShareIcon from "@mui/icons-material/Share";
|
||||||
|
import DeleteIcon from "@mui/icons-material/Delete";
|
||||||
|
import {GetAgentApi} from "./model/api.ts";
|
||||||
|
|
||||||
|
interface ShareCardProps {
|
||||||
|
shareObject: AgentObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ShareCard = ({ shareObject }: ShareCardProps) => {
|
||||||
|
let frontends = new Array<React.JSX.Element>();
|
||||||
|
let share = (shareObject.v as ShareDetail);
|
||||||
|
share.frontendEndpoint!.map(fe => {
|
||||||
|
frontends.push(<a key={share.token} href={fe} target="_">{fe}</a>);
|
||||||
|
});
|
||||||
|
|
||||||
|
const releaseShare = () => {
|
||||||
|
GetAgentApi().agentReleaseShare({token: share.token})
|
||||||
|
.catch(e => {
|
||||||
|
console.log(e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<AppBar position="sticky">
|
||||||
|
<Toolbar variant="dense">
|
||||||
|
<ShareIcon />
|
||||||
|
<Grid2 container sx={{ flexGrow: 1 }}>
|
||||||
|
<Grid2 display="flex" justifyContent="center" size="grow">
|
||||||
|
<Typography variant="h6" component="div" style={{ color: "#9bf316" }}>{share.token}</Typography>
|
||||||
|
</Grid2>
|
||||||
|
</Grid2>
|
||||||
|
<Grid2 container>
|
||||||
|
<Grid2 display="flex" justifyContent="right">
|
||||||
|
<Chip label={share.shareMode} size="small" style={{ backgroundColor: "#9bf316" }} sx={{ mr: 1}} />
|
||||||
|
<Chip label={share.backendMode} size="small" style={{ backgroundColor: "#9bf316" }} />
|
||||||
|
</Grid2>
|
||||||
|
</Grid2>
|
||||||
|
</Toolbar>
|
||||||
|
</AppBar>
|
||||||
|
<Box sx={{ p: 2, textAlign: "center" }}>
|
||||||
|
<Typography variant="h6" component="div">
|
||||||
|
{share.backendEndpoint} → {frontends} <br/>
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
<Grid2 container sx={{ flexGrow: 1 }}>
|
||||||
|
<Grid2 display="flex" justifyContent="right" size="grow">
|
||||||
|
<Button variant="contained" onClick={releaseShare}><DeleteIcon /></Button>
|
||||||
|
</Grid2>
|
||||||
|
</Grid2>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ShareCard;
|
23
agent/agentUi/src/api/.openapi-generator-ignore
Normal file
23
agent/agentUi/src/api/.openapi-generator-ignore
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# OpenAPI Generator Ignore
|
||||||
|
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||||
|
|
||||||
|
# Use this file to prevent files from being overwritten by the generator.
|
||||||
|
# The patterns follow closely to .gitignore or .dockerignore.
|
||||||
|
|
||||||
|
# As an example, the C# client generator defines ApiClient.cs.
|
||||||
|
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
||||||
|
#ApiClient.cs
|
||||||
|
|
||||||
|
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||||
|
#foo/*/qux
|
||||||
|
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||||
|
|
||||||
|
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||||
|
#foo/**/qux
|
||||||
|
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||||
|
|
||||||
|
# You can also negate patterns with an exclamation (!).
|
||||||
|
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||||
|
#docs/*.md
|
||||||
|
# Then explicitly reverse the ignore rule for a single file:
|
||||||
|
#!docs/README.md
|
16
agent/agentUi/src/api/.openapi-generator/FILES
Normal file
16
agent/agentUi/src/api/.openapi-generator/FILES
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
.openapi-generator-ignore
|
||||||
|
apis/AgentApi.ts
|
||||||
|
apis/index.ts
|
||||||
|
index.ts
|
||||||
|
models/AccessDetail.ts
|
||||||
|
models/AccessPrivateResponse.ts
|
||||||
|
models/ProtobufAny.ts
|
||||||
|
models/RpcStatus.ts
|
||||||
|
models/ShareDetail.ts
|
||||||
|
models/SharePrivateResponse.ts
|
||||||
|
models/SharePublicResponse.ts
|
||||||
|
models/ShareReservedResponse.ts
|
||||||
|
models/StatusResponse.ts
|
||||||
|
models/VersionResponse.ts
|
||||||
|
models/index.ts
|
||||||
|
runtime.ts
|
1
agent/agentUi/src/api/.openapi-generator/VERSION
Normal file
1
agent/agentUi/src/api/.openapi-generator/VERSION
Normal file
@ -0,0 +1 @@
|
|||||||
|
7.7.0
|
348
agent/agentUi/src/api/apis/AgentApi.ts
Normal file
348
agent/agentUi/src/api/apis/AgentApi.ts
Normal file
@ -0,0 +1,348 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* agent/agentGrpc/agent.proto
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: version not set
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
import * as runtime from '../runtime';
|
||||||
|
import type {
|
||||||
|
AccessPrivateResponse,
|
||||||
|
RpcStatus,
|
||||||
|
SharePrivateResponse,
|
||||||
|
SharePublicResponse,
|
||||||
|
StatusResponse,
|
||||||
|
VersionResponse,
|
||||||
|
} from '../models/index';
|
||||||
|
import {
|
||||||
|
AccessPrivateResponseFromJSON,
|
||||||
|
AccessPrivateResponseToJSON,
|
||||||
|
RpcStatusFromJSON,
|
||||||
|
RpcStatusToJSON,
|
||||||
|
SharePrivateResponseFromJSON,
|
||||||
|
SharePrivateResponseToJSON,
|
||||||
|
SharePublicResponseFromJSON,
|
||||||
|
SharePublicResponseToJSON,
|
||||||
|
StatusResponseFromJSON,
|
||||||
|
StatusResponseToJSON,
|
||||||
|
VersionResponseFromJSON,
|
||||||
|
VersionResponseToJSON,
|
||||||
|
} from '../models/index';
|
||||||
|
|
||||||
|
export interface AgentAccessPrivateRequest {
|
||||||
|
token?: string;
|
||||||
|
bindAddress?: string;
|
||||||
|
autoMode?: boolean;
|
||||||
|
autoAddress?: string;
|
||||||
|
autoStartPort?: number;
|
||||||
|
autoEndPort?: number;
|
||||||
|
responseHeaders?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AgentReleaseAccessRequest {
|
||||||
|
frontendToken?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AgentReleaseShareRequest {
|
||||||
|
token?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AgentSharePrivateRequest {
|
||||||
|
target?: string;
|
||||||
|
backendMode?: string;
|
||||||
|
insecure?: boolean;
|
||||||
|
closed?: boolean;
|
||||||
|
accessGrants?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AgentSharePublicRequest {
|
||||||
|
target?: string;
|
||||||
|
basicAuth?: Array<string>;
|
||||||
|
frontendSelection?: Array<string>;
|
||||||
|
backendMode?: string;
|
||||||
|
insecure?: boolean;
|
||||||
|
oauthProvider?: string;
|
||||||
|
oauthEmailAddressPatterns?: Array<string>;
|
||||||
|
oauthCheckInterval?: string;
|
||||||
|
closed?: boolean;
|
||||||
|
accessGrants?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export class AgentApi extends runtime.BaseAPI {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async agentAccessPrivateRaw(requestParameters: AgentAccessPrivateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<AccessPrivateResponse>> {
|
||||||
|
const queryParameters: any = {};
|
||||||
|
|
||||||
|
if (requestParameters['token'] != null) {
|
||||||
|
queryParameters['token'] = requestParameters['token'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['bindAddress'] != null) {
|
||||||
|
queryParameters['bindAddress'] = requestParameters['bindAddress'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['autoMode'] != null) {
|
||||||
|
queryParameters['autoMode'] = requestParameters['autoMode'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['autoAddress'] != null) {
|
||||||
|
queryParameters['autoAddress'] = requestParameters['autoAddress'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['autoStartPort'] != null) {
|
||||||
|
queryParameters['autoStartPort'] = requestParameters['autoStartPort'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['autoEndPort'] != null) {
|
||||||
|
queryParameters['autoEndPort'] = requestParameters['autoEndPort'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['responseHeaders'] != null) {
|
||||||
|
queryParameters['responseHeaders'] = requestParameters['responseHeaders'];
|
||||||
|
}
|
||||||
|
|
||||||
|
const headerParameters: runtime.HTTPHeaders = {};
|
||||||
|
|
||||||
|
const response = await this.request({
|
||||||
|
path: `/v1/agent/accessPrivate`,
|
||||||
|
method: 'POST',
|
||||||
|
headers: headerParameters,
|
||||||
|
query: queryParameters,
|
||||||
|
}, initOverrides);
|
||||||
|
|
||||||
|
return new runtime.JSONApiResponse(response, (jsonValue) => AccessPrivateResponseFromJSON(jsonValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async agentAccessPrivate(requestParameters: AgentAccessPrivateRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<AccessPrivateResponse> {
|
||||||
|
const response = await this.agentAccessPrivateRaw(requestParameters, initOverrides);
|
||||||
|
return await response.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async agentReleaseAccessRaw(requestParameters: AgentReleaseAccessRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<object>> {
|
||||||
|
const queryParameters: any = {};
|
||||||
|
|
||||||
|
if (requestParameters['frontendToken'] != null) {
|
||||||
|
queryParameters['frontendToken'] = requestParameters['frontendToken'];
|
||||||
|
}
|
||||||
|
|
||||||
|
const headerParameters: runtime.HTTPHeaders = {};
|
||||||
|
|
||||||
|
const response = await this.request({
|
||||||
|
path: `/v1/agent/releaseAccess`,
|
||||||
|
method: 'POST',
|
||||||
|
headers: headerParameters,
|
||||||
|
query: queryParameters,
|
||||||
|
}, initOverrides);
|
||||||
|
|
||||||
|
return new runtime.JSONApiResponse<any>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async agentReleaseAccess(requestParameters: AgentReleaseAccessRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<object> {
|
||||||
|
const response = await this.agentReleaseAccessRaw(requestParameters, initOverrides);
|
||||||
|
return await response.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async agentReleaseShareRaw(requestParameters: AgentReleaseShareRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<object>> {
|
||||||
|
const queryParameters: any = {};
|
||||||
|
|
||||||
|
if (requestParameters['token'] != null) {
|
||||||
|
queryParameters['token'] = requestParameters['token'];
|
||||||
|
}
|
||||||
|
|
||||||
|
const headerParameters: runtime.HTTPHeaders = {};
|
||||||
|
|
||||||
|
const response = await this.request({
|
||||||
|
path: `/v1/agent/releaseShare`,
|
||||||
|
method: 'POST',
|
||||||
|
headers: headerParameters,
|
||||||
|
query: queryParameters,
|
||||||
|
}, initOverrides);
|
||||||
|
|
||||||
|
return new runtime.JSONApiResponse<any>(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async agentReleaseShare(requestParameters: AgentReleaseShareRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<object> {
|
||||||
|
const response = await this.agentReleaseShareRaw(requestParameters, initOverrides);
|
||||||
|
return await response.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async agentSharePrivateRaw(requestParameters: AgentSharePrivateRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<SharePrivateResponse>> {
|
||||||
|
const queryParameters: any = {};
|
||||||
|
|
||||||
|
if (requestParameters['target'] != null) {
|
||||||
|
queryParameters['target'] = requestParameters['target'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['backendMode'] != null) {
|
||||||
|
queryParameters['backendMode'] = requestParameters['backendMode'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['insecure'] != null) {
|
||||||
|
queryParameters['insecure'] = requestParameters['insecure'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['closed'] != null) {
|
||||||
|
queryParameters['closed'] = requestParameters['closed'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['accessGrants'] != null) {
|
||||||
|
queryParameters['accessGrants'] = requestParameters['accessGrants'];
|
||||||
|
}
|
||||||
|
|
||||||
|
const headerParameters: runtime.HTTPHeaders = {};
|
||||||
|
|
||||||
|
const response = await this.request({
|
||||||
|
path: `/v1/agent/sharePrivate`,
|
||||||
|
method: 'POST',
|
||||||
|
headers: headerParameters,
|
||||||
|
query: queryParameters,
|
||||||
|
}, initOverrides);
|
||||||
|
|
||||||
|
return new runtime.JSONApiResponse(response, (jsonValue) => SharePrivateResponseFromJSON(jsonValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async agentSharePrivate(requestParameters: AgentSharePrivateRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<SharePrivateResponse> {
|
||||||
|
const response = await this.agentSharePrivateRaw(requestParameters, initOverrides);
|
||||||
|
return await response.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async agentSharePublicRaw(requestParameters: AgentSharePublicRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<SharePublicResponse>> {
|
||||||
|
const queryParameters: any = {};
|
||||||
|
|
||||||
|
if (requestParameters['target'] != null) {
|
||||||
|
queryParameters['target'] = requestParameters['target'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['basicAuth'] != null) {
|
||||||
|
queryParameters['basicAuth'] = requestParameters['basicAuth'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['frontendSelection'] != null) {
|
||||||
|
queryParameters['frontendSelection'] = requestParameters['frontendSelection'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['backendMode'] != null) {
|
||||||
|
queryParameters['backendMode'] = requestParameters['backendMode'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['insecure'] != null) {
|
||||||
|
queryParameters['insecure'] = requestParameters['insecure'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['oauthProvider'] != null) {
|
||||||
|
queryParameters['oauthProvider'] = requestParameters['oauthProvider'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['oauthEmailAddressPatterns'] != null) {
|
||||||
|
queryParameters['oauthEmailAddressPatterns'] = requestParameters['oauthEmailAddressPatterns'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['oauthCheckInterval'] != null) {
|
||||||
|
queryParameters['oauthCheckInterval'] = requestParameters['oauthCheckInterval'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['closed'] != null) {
|
||||||
|
queryParameters['closed'] = requestParameters['closed'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestParameters['accessGrants'] != null) {
|
||||||
|
queryParameters['accessGrants'] = requestParameters['accessGrants'];
|
||||||
|
}
|
||||||
|
|
||||||
|
const headerParameters: runtime.HTTPHeaders = {};
|
||||||
|
|
||||||
|
const response = await this.request({
|
||||||
|
path: `/v1/agent/sharePublic`,
|
||||||
|
method: 'POST',
|
||||||
|
headers: headerParameters,
|
||||||
|
query: queryParameters,
|
||||||
|
}, initOverrides);
|
||||||
|
|
||||||
|
return new runtime.JSONApiResponse(response, (jsonValue) => SharePublicResponseFromJSON(jsonValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async agentSharePublic(requestParameters: AgentSharePublicRequest = {}, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<SharePublicResponse> {
|
||||||
|
const response = await this.agentSharePublicRaw(requestParameters, initOverrides);
|
||||||
|
return await response.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async agentStatusRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<StatusResponse>> {
|
||||||
|
const queryParameters: any = {};
|
||||||
|
|
||||||
|
const headerParameters: runtime.HTTPHeaders = {};
|
||||||
|
|
||||||
|
const response = await this.request({
|
||||||
|
path: `/v1/agent/status`,
|
||||||
|
method: 'GET',
|
||||||
|
headers: headerParameters,
|
||||||
|
query: queryParameters,
|
||||||
|
}, initOverrides);
|
||||||
|
|
||||||
|
return new runtime.JSONApiResponse(response, (jsonValue) => StatusResponseFromJSON(jsonValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async agentStatus(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<StatusResponse> {
|
||||||
|
const response = await this.agentStatusRaw(initOverrides);
|
||||||
|
return await response.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async agentVersionRaw(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<VersionResponse>> {
|
||||||
|
const queryParameters: any = {};
|
||||||
|
|
||||||
|
const headerParameters: runtime.HTTPHeaders = {};
|
||||||
|
|
||||||
|
const response = await this.request({
|
||||||
|
path: `/v1/agent/version`,
|
||||||
|
method: 'GET',
|
||||||
|
headers: headerParameters,
|
||||||
|
query: queryParameters,
|
||||||
|
}, initOverrides);
|
||||||
|
|
||||||
|
return new runtime.JSONApiResponse(response, (jsonValue) => VersionResponseFromJSON(jsonValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
async agentVersion(initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<VersionResponse> {
|
||||||
|
const response = await this.agentVersionRaw(initOverrides);
|
||||||
|
return await response.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
3
agent/agentUi/src/api/apis/index.ts
Normal file
3
agent/agentUi/src/api/apis/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export * from './AgentApi';
|
84
agent/agentUi/src/api/models/AccessDetail.ts
Normal file
84
agent/agentUi/src/api/models/AccessDetail.ts
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* agent/agentGrpc/agent.proto
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: version not set
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from '../runtime';
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface AccessDetail
|
||||||
|
*/
|
||||||
|
export interface AccessDetail {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof AccessDetail
|
||||||
|
*/
|
||||||
|
frontendToken?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof AccessDetail
|
||||||
|
*/
|
||||||
|
token?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof AccessDetail
|
||||||
|
*/
|
||||||
|
bindAddress?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Array<string>}
|
||||||
|
* @memberof AccessDetail
|
||||||
|
*/
|
||||||
|
responseHeaders?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given object implements the AccessDetail interface.
|
||||||
|
*/
|
||||||
|
export function instanceOfAccessDetail(value: object): value is AccessDetail {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AccessDetailFromJSON(json: any): AccessDetail {
|
||||||
|
return AccessDetailFromJSONTyped(json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AccessDetailFromJSONTyped(json: any, ignoreDiscriminator: boolean): AccessDetail {
|
||||||
|
if (json == null) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'frontendToken': json['frontendToken'] == null ? undefined : json['frontendToken'],
|
||||||
|
'token': json['token'] == null ? undefined : json['token'],
|
||||||
|
'bindAddress': json['bindAddress'] == null ? undefined : json['bindAddress'],
|
||||||
|
'responseHeaders': json['responseHeaders'] == null ? undefined : json['responseHeaders'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AccessDetailToJSON(value?: AccessDetail | null): any {
|
||||||
|
if (value == null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'frontendToken': value['frontendToken'],
|
||||||
|
'token': value['token'],
|
||||||
|
'bindAddress': value['bindAddress'],
|
||||||
|
'responseHeaders': value['responseHeaders'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
60
agent/agentUi/src/api/models/AccessPrivateResponse.ts
Normal file
60
agent/agentUi/src/api/models/AccessPrivateResponse.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* agent/agentGrpc/agent.proto
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: version not set
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from '../runtime';
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface AccessPrivateResponse
|
||||||
|
*/
|
||||||
|
export interface AccessPrivateResponse {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof AccessPrivateResponse
|
||||||
|
*/
|
||||||
|
frontendToken?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given object implements the AccessPrivateResponse interface.
|
||||||
|
*/
|
||||||
|
export function instanceOfAccessPrivateResponse(value: object): value is AccessPrivateResponse {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AccessPrivateResponseFromJSON(json: any): AccessPrivateResponse {
|
||||||
|
return AccessPrivateResponseFromJSONTyped(json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AccessPrivateResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): AccessPrivateResponse {
|
||||||
|
if (json == null) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'frontendToken': json['frontendToken'] == null ? undefined : json['frontendToken'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AccessPrivateResponseToJSON(value?: AccessPrivateResponse | null): any {
|
||||||
|
if (value == null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'frontendToken': value['frontendToken'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
63
agent/agentUi/src/api/models/ProtobufAny.ts
Normal file
63
agent/agentUi/src/api/models/ProtobufAny.ts
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* agent/agentGrpc/agent.proto
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: version not set
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from '../runtime';
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface ProtobufAny
|
||||||
|
*/
|
||||||
|
export interface ProtobufAny {
|
||||||
|
[key: string]: object | any;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ProtobufAny
|
||||||
|
*/
|
||||||
|
type?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given object implements the ProtobufAny interface.
|
||||||
|
*/
|
||||||
|
export function instanceOfProtobufAny(value: object): value is ProtobufAny {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ProtobufAnyFromJSON(json: any): ProtobufAny {
|
||||||
|
return ProtobufAnyFromJSONTyped(json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ProtobufAnyFromJSONTyped(json: any, ignoreDiscriminator: boolean): ProtobufAny {
|
||||||
|
if (json == null) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
...json,
|
||||||
|
'type': json['@type'] == null ? undefined : json['@type'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ProtobufAnyToJSON(value?: ProtobufAny | null): any {
|
||||||
|
if (value == null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
...value,
|
||||||
|
'@type': value['type'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
83
agent/agentUi/src/api/models/RpcStatus.ts
Normal file
83
agent/agentUi/src/api/models/RpcStatus.ts
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* agent/agentGrpc/agent.proto
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: version not set
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from '../runtime';
|
||||||
|
import type { ProtobufAny } from './ProtobufAny';
|
||||||
|
import {
|
||||||
|
ProtobufAnyFromJSON,
|
||||||
|
ProtobufAnyFromJSONTyped,
|
||||||
|
ProtobufAnyToJSON,
|
||||||
|
} from './ProtobufAny';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface RpcStatus
|
||||||
|
*/
|
||||||
|
export interface RpcStatus {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {number}
|
||||||
|
* @memberof RpcStatus
|
||||||
|
*/
|
||||||
|
code?: number;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof RpcStatus
|
||||||
|
*/
|
||||||
|
message?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Array<ProtobufAny>}
|
||||||
|
* @memberof RpcStatus
|
||||||
|
*/
|
||||||
|
details?: Array<ProtobufAny>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given object implements the RpcStatus interface.
|
||||||
|
*/
|
||||||
|
export function instanceOfRpcStatus(value: object): value is RpcStatus {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RpcStatusFromJSON(json: any): RpcStatus {
|
||||||
|
return RpcStatusFromJSONTyped(json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RpcStatusFromJSONTyped(json: any, ignoreDiscriminator: boolean): RpcStatus {
|
||||||
|
if (json == null) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'code': json['code'] == null ? undefined : json['code'],
|
||||||
|
'message': json['message'] == null ? undefined : json['message'],
|
||||||
|
'details': json['details'] == null ? undefined : ((json['details'] as Array<any>).map(ProtobufAnyFromJSON)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function RpcStatusToJSON(value?: RpcStatus | null): any {
|
||||||
|
if (value == null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'code': value['code'],
|
||||||
|
'message': value['message'],
|
||||||
|
'details': value['details'] == null ? undefined : ((value['details'] as Array<any>).map(ProtobufAnyToJSON)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
116
agent/agentUi/src/api/models/ShareDetail.ts
Normal file
116
agent/agentUi/src/api/models/ShareDetail.ts
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* agent/agentGrpc/agent.proto
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: version not set
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from '../runtime';
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface ShareDetail
|
||||||
|
*/
|
||||||
|
export interface ShareDetail {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ShareDetail
|
||||||
|
*/
|
||||||
|
token?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ShareDetail
|
||||||
|
*/
|
||||||
|
shareMode?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ShareDetail
|
||||||
|
*/
|
||||||
|
backendMode?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof ShareDetail
|
||||||
|
*/
|
||||||
|
reserved?: boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Array<string>}
|
||||||
|
* @memberof ShareDetail
|
||||||
|
*/
|
||||||
|
frontendEndpoint?: Array<string>;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ShareDetail
|
||||||
|
*/
|
||||||
|
backendEndpoint?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {boolean}
|
||||||
|
* @memberof ShareDetail
|
||||||
|
*/
|
||||||
|
closed?: boolean;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ShareDetail
|
||||||
|
*/
|
||||||
|
status?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given object implements the ShareDetail interface.
|
||||||
|
*/
|
||||||
|
export function instanceOfShareDetail(value: object): value is ShareDetail {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ShareDetailFromJSON(json: any): ShareDetail {
|
||||||
|
return ShareDetailFromJSONTyped(json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ShareDetailFromJSONTyped(json: any, ignoreDiscriminator: boolean): ShareDetail {
|
||||||
|
if (json == null) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'token': json['token'] == null ? undefined : json['token'],
|
||||||
|
'shareMode': json['shareMode'] == null ? undefined : json['shareMode'],
|
||||||
|
'backendMode': json['backendMode'] == null ? undefined : json['backendMode'],
|
||||||
|
'reserved': json['reserved'] == null ? undefined : json['reserved'],
|
||||||
|
'frontendEndpoint': json['frontendEndpoint'] == null ? undefined : json['frontendEndpoint'],
|
||||||
|
'backendEndpoint': json['backendEndpoint'] == null ? undefined : json['backendEndpoint'],
|
||||||
|
'closed': json['closed'] == null ? undefined : json['closed'],
|
||||||
|
'status': json['status'] == null ? undefined : json['status'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ShareDetailToJSON(value?: ShareDetail | null): any {
|
||||||
|
if (value == null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'token': value['token'],
|
||||||
|
'shareMode': value['shareMode'],
|
||||||
|
'backendMode': value['backendMode'],
|
||||||
|
'reserved': value['reserved'],
|
||||||
|
'frontendEndpoint': value['frontendEndpoint'],
|
||||||
|
'backendEndpoint': value['backendEndpoint'],
|
||||||
|
'closed': value['closed'],
|
||||||
|
'status': value['status'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
60
agent/agentUi/src/api/models/SharePrivateResponse.ts
Normal file
60
agent/agentUi/src/api/models/SharePrivateResponse.ts
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* agent/agentGrpc/agent.proto
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: version not set
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from '../runtime';
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface SharePrivateResponse
|
||||||
|
*/
|
||||||
|
export interface SharePrivateResponse {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof SharePrivateResponse
|
||||||
|
*/
|
||||||
|
token?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given object implements the SharePrivateResponse interface.
|
||||||
|
*/
|
||||||
|
export function instanceOfSharePrivateResponse(value: object): value is SharePrivateResponse {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SharePrivateResponseFromJSON(json: any): SharePrivateResponse {
|
||||||
|
return SharePrivateResponseFromJSONTyped(json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SharePrivateResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): SharePrivateResponse {
|
||||||
|
if (json == null) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'token': json['token'] == null ? undefined : json['token'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SharePrivateResponseToJSON(value?: SharePrivateResponse | null): any {
|
||||||
|
if (value == null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'token': value['token'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
68
agent/agentUi/src/api/models/SharePublicResponse.ts
Normal file
68
agent/agentUi/src/api/models/SharePublicResponse.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* agent/agentGrpc/agent.proto
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: version not set
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from '../runtime';
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface SharePublicResponse
|
||||||
|
*/
|
||||||
|
export interface SharePublicResponse {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof SharePublicResponse
|
||||||
|
*/
|
||||||
|
token?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Array<string>}
|
||||||
|
* @memberof SharePublicResponse
|
||||||
|
*/
|
||||||
|
frontendEndpoints?: Array<string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given object implements the SharePublicResponse interface.
|
||||||
|
*/
|
||||||
|
export function instanceOfSharePublicResponse(value: object): value is SharePublicResponse {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SharePublicResponseFromJSON(json: any): SharePublicResponse {
|
||||||
|
return SharePublicResponseFromJSONTyped(json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SharePublicResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): SharePublicResponse {
|
||||||
|
if (json == null) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'token': json['token'] == null ? undefined : json['token'],
|
||||||
|
'frontendEndpoints': json['frontendEndpoints'] == null ? undefined : json['frontendEndpoints'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SharePublicResponseToJSON(value?: SharePublicResponse | null): any {
|
||||||
|
if (value == null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'token': value['token'],
|
||||||
|
'frontendEndpoints': value['frontendEndpoints'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
92
agent/agentUi/src/api/models/ShareReservedResponse.ts
Normal file
92
agent/agentUi/src/api/models/ShareReservedResponse.ts
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* agent/agentGrpc/agent.proto
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: version not set
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from '../runtime';
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface ShareReservedResponse
|
||||||
|
*/
|
||||||
|
export interface ShareReservedResponse {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ShareReservedResponse
|
||||||
|
*/
|
||||||
|
token?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ShareReservedResponse
|
||||||
|
*/
|
||||||
|
backendMode?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ShareReservedResponse
|
||||||
|
*/
|
||||||
|
shareMode?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Array<string>}
|
||||||
|
* @memberof ShareReservedResponse
|
||||||
|
*/
|
||||||
|
frontendEndpoints?: Array<string>;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ShareReservedResponse
|
||||||
|
*/
|
||||||
|
target?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given object implements the ShareReservedResponse interface.
|
||||||
|
*/
|
||||||
|
export function instanceOfShareReservedResponse(value: object): value is ShareReservedResponse {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ShareReservedResponseFromJSON(json: any): ShareReservedResponse {
|
||||||
|
return ShareReservedResponseFromJSONTyped(json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ShareReservedResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): ShareReservedResponse {
|
||||||
|
if (json == null) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'token': json['token'] == null ? undefined : json['token'],
|
||||||
|
'backendMode': json['backendMode'] == null ? undefined : json['backendMode'],
|
||||||
|
'shareMode': json['shareMode'] == null ? undefined : json['shareMode'],
|
||||||
|
'frontendEndpoints': json['frontendEndpoints'] == null ? undefined : json['frontendEndpoints'],
|
||||||
|
'target': json['target'] == null ? undefined : json['target'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ShareReservedResponseToJSON(value?: ShareReservedResponse | null): any {
|
||||||
|
if (value == null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'token': value['token'],
|
||||||
|
'backendMode': value['backendMode'],
|
||||||
|
'shareMode': value['shareMode'],
|
||||||
|
'frontendEndpoints': value['frontendEndpoints'],
|
||||||
|
'target': value['target'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
81
agent/agentUi/src/api/models/StatusResponse.ts
Normal file
81
agent/agentUi/src/api/models/StatusResponse.ts
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* agent/agentGrpc/agent.proto
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: version not set
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from '../runtime';
|
||||||
|
import type { AccessDetail } from './AccessDetail';
|
||||||
|
import {
|
||||||
|
AccessDetailFromJSON,
|
||||||
|
AccessDetailFromJSONTyped,
|
||||||
|
AccessDetailToJSON,
|
||||||
|
} from './AccessDetail';
|
||||||
|
import type { ShareDetail } from './ShareDetail';
|
||||||
|
import {
|
||||||
|
ShareDetailFromJSON,
|
||||||
|
ShareDetailFromJSONTyped,
|
||||||
|
ShareDetailToJSON,
|
||||||
|
} from './ShareDetail';
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface StatusResponse
|
||||||
|
*/
|
||||||
|
export interface StatusResponse {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Array<AccessDetail>}
|
||||||
|
* @memberof StatusResponse
|
||||||
|
*/
|
||||||
|
accesses?: Array<AccessDetail>;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Array<ShareDetail>}
|
||||||
|
* @memberof StatusResponse
|
||||||
|
*/
|
||||||
|
shares?: Array<ShareDetail>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given object implements the StatusResponse interface.
|
||||||
|
*/
|
||||||
|
export function instanceOfStatusResponse(value: object): value is StatusResponse {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function StatusResponseFromJSON(json: any): StatusResponse {
|
||||||
|
return StatusResponseFromJSONTyped(json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function StatusResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): StatusResponse {
|
||||||
|
if (json == null) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'accesses': json['accesses'] == null ? undefined : ((json['accesses'] as Array<any>).map(AccessDetailFromJSON)),
|
||||||
|
'shares': json['shares'] == null ? undefined : ((json['shares'] as Array<any>).map(ShareDetailFromJSON)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function StatusResponseToJSON(value?: StatusResponse | null): any {
|
||||||
|
if (value == null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'accesses': value['accesses'] == null ? undefined : ((value['accesses'] as Array<any>).map(AccessDetailToJSON)),
|
||||||
|
'shares': value['shares'] == null ? undefined : ((value['shares'] as Array<any>).map(ShareDetailToJSON)),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
68
agent/agentUi/src/api/models/VersionResponse.ts
Normal file
68
agent/agentUi/src/api/models/VersionResponse.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* agent/agentGrpc/agent.proto
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: version not set
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { mapValues } from '../runtime';
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface VersionResponse
|
||||||
|
*/
|
||||||
|
export interface VersionResponse {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof VersionResponse
|
||||||
|
*/
|
||||||
|
v?: string;
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof VersionResponse
|
||||||
|
*/
|
||||||
|
consoleEndpoint?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given object implements the VersionResponse interface.
|
||||||
|
*/
|
||||||
|
export function instanceOfVersionResponse(value: object): value is VersionResponse {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function VersionResponseFromJSON(json: any): VersionResponse {
|
||||||
|
return VersionResponseFromJSONTyped(json, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function VersionResponseFromJSONTyped(json: any, ignoreDiscriminator: boolean): VersionResponse {
|
||||||
|
if (json == null) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'v': json['v'] == null ? undefined : json['v'],
|
||||||
|
'consoleEndpoint': json['consoleEndpoint'] == null ? undefined : json['consoleEndpoint'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function VersionResponseToJSON(value?: VersionResponse | null): any {
|
||||||
|
if (value == null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
|
||||||
|
'v': value['v'],
|
||||||
|
'consoleEndpoint': value['consoleEndpoint'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
12
agent/agentUi/src/api/models/index.ts
Normal file
12
agent/agentUi/src/api/models/index.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export * from './AccessDetail';
|
||||||
|
export * from './AccessPrivateResponse';
|
||||||
|
export * from './ProtobufAny';
|
||||||
|
export * from './RpcStatus';
|
||||||
|
export * from './ShareDetail';
|
||||||
|
export * from './SharePrivateResponse';
|
||||||
|
export * from './SharePublicResponse';
|
||||||
|
export * from './ShareReservedResponse';
|
||||||
|
export * from './StatusResponse';
|
||||||
|
export * from './VersionResponse';
|
426
agent/agentUi/src/api/runtime.ts
Normal file
426
agent/agentUi/src/api/runtime.ts
Normal file
@ -0,0 +1,426 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
* agent/agentGrpc/agent.proto
|
||||||
|
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||||
|
*
|
||||||
|
* The version of the OpenAPI document: version not set
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
||||||
|
* https://openapi-generator.tech
|
||||||
|
* Do not edit the class manually.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
export const BASE_PATH = "http://localhost".replace(/\/+$/, "");
|
||||||
|
|
||||||
|
export interface ConfigurationParameters {
|
||||||
|
basePath?: string; // override base path
|
||||||
|
fetchApi?: FetchAPI; // override for fetch implementation
|
||||||
|
middleware?: Middleware[]; // middleware to apply before/after fetch requests
|
||||||
|
queryParamsStringify?: (params: HTTPQuery) => string; // stringify function for query strings
|
||||||
|
username?: string; // parameter for basic security
|
||||||
|
password?: string; // parameter for basic security
|
||||||
|
apiKey?: string | Promise<string> | ((name: string) => string | Promise<string>); // parameter for apiKey security
|
||||||
|
accessToken?: string | Promise<string> | ((name?: string, scopes?: string[]) => string | Promise<string>); // parameter for oauth2 security
|
||||||
|
headers?: HTTPHeaders; //header params we want to use on every request
|
||||||
|
credentials?: RequestCredentials; //value for the credentials param we want to use on each request
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Configuration {
|
||||||
|
constructor(private configuration: ConfigurationParameters = {}) {}
|
||||||
|
|
||||||
|
set config(configuration: Configuration) {
|
||||||
|
this.configuration = configuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
get basePath(): string {
|
||||||
|
return this.configuration.basePath != null ? this.configuration.basePath : BASE_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
get fetchApi(): FetchAPI | undefined {
|
||||||
|
return this.configuration.fetchApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
get middleware(): Middleware[] {
|
||||||
|
return this.configuration.middleware || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
get queryParamsStringify(): (params: HTTPQuery) => string {
|
||||||
|
return this.configuration.queryParamsStringify || querystring;
|
||||||
|
}
|
||||||
|
|
||||||
|
get username(): string | undefined {
|
||||||
|
return this.configuration.username;
|
||||||
|
}
|
||||||
|
|
||||||
|
get password(): string | undefined {
|
||||||
|
return this.configuration.password;
|
||||||
|
}
|
||||||
|
|
||||||
|
get apiKey(): ((name: string) => string | Promise<string>) | undefined {
|
||||||
|
const apiKey = this.configuration.apiKey;
|
||||||
|
if (apiKey) {
|
||||||
|
return typeof apiKey === 'function' ? apiKey : () => apiKey;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
get accessToken(): ((name?: string, scopes?: string[]) => string | Promise<string>) | undefined {
|
||||||
|
const accessToken = this.configuration.accessToken;
|
||||||
|
if (accessToken) {
|
||||||
|
return typeof accessToken === 'function' ? accessToken : async () => accessToken;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
get headers(): HTTPHeaders | undefined {
|
||||||
|
return this.configuration.headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
get credentials(): RequestCredentials | undefined {
|
||||||
|
return this.configuration.credentials;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DefaultConfig = new Configuration();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the base class for all generated API classes.
|
||||||
|
*/
|
||||||
|
export class BaseAPI {
|
||||||
|
|
||||||
|
private static readonly jsonRegex = new RegExp('^(:?application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(:?;.*)?$', 'i');
|
||||||
|
private middleware: Middleware[];
|
||||||
|
|
||||||
|
constructor(protected configuration = DefaultConfig) {
|
||||||
|
this.middleware = configuration.middleware;
|
||||||
|
}
|
||||||
|
|
||||||
|
withMiddleware<T extends BaseAPI>(this: T, ...middlewares: Middleware[]) {
|
||||||
|
const next = this.clone<T>();
|
||||||
|
next.middleware = next.middleware.concat(...middlewares);
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
withPreMiddleware<T extends BaseAPI>(this: T, ...preMiddlewares: Array<Middleware['pre']>) {
|
||||||
|
const middlewares = preMiddlewares.map((pre) => ({ pre }));
|
||||||
|
return this.withMiddleware<T>(...middlewares);
|
||||||
|
}
|
||||||
|
|
||||||
|
withPostMiddleware<T extends BaseAPI>(this: T, ...postMiddlewares: Array<Middleware['post']>) {
|
||||||
|
const middlewares = postMiddlewares.map((post) => ({ post }));
|
||||||
|
return this.withMiddleware<T>(...middlewares);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given MIME is a JSON MIME.
|
||||||
|
* JSON MIME examples:
|
||||||
|
* application/json
|
||||||
|
* application/json; charset=UTF8
|
||||||
|
* APPLICATION/JSON
|
||||||
|
* application/vnd.company+json
|
||||||
|
* @param mime - MIME (Multipurpose Internet Mail Extensions)
|
||||||
|
* @return True if the given MIME is JSON, false otherwise.
|
||||||
|
*/
|
||||||
|
protected isJsonMime(mime: string | null | undefined): boolean {
|
||||||
|
if (!mime) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return BaseAPI.jsonRegex.test(mime);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async request(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction): Promise<Response> {
|
||||||
|
const { url, init } = await this.createFetchParams(context, initOverrides);
|
||||||
|
const response = await this.fetchApi(url, init);
|
||||||
|
if (response && (response.status >= 200 && response.status < 300)) {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
throw new ResponseError(response, 'Response returned an error code');
|
||||||
|
}
|
||||||
|
|
||||||
|
private async createFetchParams(context: RequestOpts, initOverrides?: RequestInit | InitOverrideFunction) {
|
||||||
|
let url = this.configuration.basePath + context.path;
|
||||||
|
if (context.query !== undefined && Object.keys(context.query).length !== 0) {
|
||||||
|
// only add the querystring to the URL if there are query parameters.
|
||||||
|
// this is done to avoid urls ending with a "?" character which buggy webservers
|
||||||
|
// do not handle correctly sometimes.
|
||||||
|
url += '?' + this.configuration.queryParamsStringify(context.query);
|
||||||
|
}
|
||||||
|
|
||||||
|
const headers = Object.assign({}, this.configuration.headers, context.headers);
|
||||||
|
Object.keys(headers).forEach(key => headers[key] === undefined ? delete headers[key] : {});
|
||||||
|
|
||||||
|
const initOverrideFn =
|
||||||
|
typeof initOverrides === "function"
|
||||||
|
? initOverrides
|
||||||
|
: async () => initOverrides;
|
||||||
|
|
||||||
|
const initParams = {
|
||||||
|
method: context.method,
|
||||||
|
headers,
|
||||||
|
body: context.body,
|
||||||
|
credentials: this.configuration.credentials,
|
||||||
|
};
|
||||||
|
|
||||||
|
const overriddenInit: RequestInit = {
|
||||||
|
...initParams,
|
||||||
|
...(await initOverrideFn({
|
||||||
|
init: initParams,
|
||||||
|
context,
|
||||||
|
}))
|
||||||
|
};
|
||||||
|
|
||||||
|
let body: any;
|
||||||
|
if (isFormData(overriddenInit.body)
|
||||||
|
|| (overriddenInit.body instanceof URLSearchParams)
|
||||||
|
|| isBlob(overriddenInit.body)) {
|
||||||
|
body = overriddenInit.body;
|
||||||
|
} else if (this.isJsonMime(headers['Content-Type'])) {
|
||||||
|
body = JSON.stringify(overriddenInit.body);
|
||||||
|
} else {
|
||||||
|
body = overriddenInit.body;
|
||||||
|
}
|
||||||
|
|
||||||
|
const init: RequestInit = {
|
||||||
|
...overriddenInit,
|
||||||
|
body
|
||||||
|
};
|
||||||
|
|
||||||
|
return { url, init };
|
||||||
|
}
|
||||||
|
|
||||||
|
private fetchApi = async (url: string, init: RequestInit) => {
|
||||||
|
let fetchParams = { url, init };
|
||||||
|
for (const middleware of this.middleware) {
|
||||||
|
if (middleware.pre) {
|
||||||
|
fetchParams = await middleware.pre({
|
||||||
|
fetch: this.fetchApi,
|
||||||
|
...fetchParams,
|
||||||
|
}) || fetchParams;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let response: Response | undefined = undefined;
|
||||||
|
try {
|
||||||
|
response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init);
|
||||||
|
} catch (e) {
|
||||||
|
for (const middleware of this.middleware) {
|
||||||
|
if (middleware.onError) {
|
||||||
|
response = await middleware.onError({
|
||||||
|
fetch: this.fetchApi,
|
||||||
|
url: fetchParams.url,
|
||||||
|
init: fetchParams.init,
|
||||||
|
error: e,
|
||||||
|
response: response ? response.clone() : undefined,
|
||||||
|
}) || response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (response === undefined) {
|
||||||
|
if (e instanceof Error) {
|
||||||
|
throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response');
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const middleware of this.middleware) {
|
||||||
|
if (middleware.post) {
|
||||||
|
response = await middleware.post({
|
||||||
|
fetch: this.fetchApi,
|
||||||
|
url: fetchParams.url,
|
||||||
|
init: fetchParams.init,
|
||||||
|
response: response.clone(),
|
||||||
|
}) || response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a shallow clone of `this` by constructing a new instance
|
||||||
|
* and then shallow cloning data members.
|
||||||
|
*/
|
||||||
|
private clone<T extends BaseAPI>(this: T): T {
|
||||||
|
const constructor = this.constructor as any;
|
||||||
|
const next = new constructor(this.configuration);
|
||||||
|
next.middleware = this.middleware.slice();
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function isBlob(value: any): value is Blob {
|
||||||
|
return typeof Blob !== 'undefined' && value instanceof Blob;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isFormData(value: any): value is FormData {
|
||||||
|
return typeof FormData !== "undefined" && value instanceof FormData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ResponseError extends Error {
|
||||||
|
override name: "ResponseError" = "ResponseError";
|
||||||
|
constructor(public response: Response, msg?: string) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class FetchError extends Error {
|
||||||
|
override name: "FetchError" = "FetchError";
|
||||||
|
constructor(public cause: Error, msg?: string) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RequiredError extends Error {
|
||||||
|
override name: "RequiredError" = "RequiredError";
|
||||||
|
constructor(public field: string, msg?: string) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const COLLECTION_FORMATS = {
|
||||||
|
csv: ",",
|
||||||
|
ssv: " ",
|
||||||
|
tsv: "\t",
|
||||||
|
pipes: "|",
|
||||||
|
};
|
||||||
|
|
||||||
|
export type FetchAPI = WindowOrWorkerGlobalScope['fetch'];
|
||||||
|
|
||||||
|
export type Json = any;
|
||||||
|
export type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'OPTIONS' | 'HEAD';
|
||||||
|
export type HTTPHeaders = { [key: string]: string };
|
||||||
|
export type HTTPQuery = { [key: string]: string | number | null | boolean | Array<string | number | null | boolean> | Set<string | number | null | boolean> | HTTPQuery };
|
||||||
|
export type HTTPBody = Json | FormData | URLSearchParams;
|
||||||
|
export type HTTPRequestInit = { headers?: HTTPHeaders; method: HTTPMethod; credentials?: RequestCredentials; body?: HTTPBody };
|
||||||
|
export type ModelPropertyNaming = 'camelCase' | 'snake_case' | 'PascalCase' | 'original';
|
||||||
|
|
||||||
|
export type InitOverrideFunction = (requestContext: { init: HTTPRequestInit, context: RequestOpts }) => Promise<RequestInit>
|
||||||
|
|
||||||
|
export interface FetchParams {
|
||||||
|
url: string;
|
||||||
|
init: RequestInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RequestOpts {
|
||||||
|
path: string;
|
||||||
|
method: HTTPMethod;
|
||||||
|
headers: HTTPHeaders;
|
||||||
|
query?: HTTPQuery;
|
||||||
|
body?: HTTPBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function querystring(params: HTTPQuery, prefix: string = ''): string {
|
||||||
|
return Object.keys(params)
|
||||||
|
.map(key => querystringSingleKey(key, params[key], prefix))
|
||||||
|
.filter(part => part.length > 0)
|
||||||
|
.join('&');
|
||||||
|
}
|
||||||
|
|
||||||
|
function querystringSingleKey(key: string, value: string | number | null | undefined | boolean | Array<string | number | null | boolean> | Set<string | number | null | boolean> | HTTPQuery, keyPrefix: string = ''): string {
|
||||||
|
const fullKey = keyPrefix + (keyPrefix.length ? `[${key}]` : key);
|
||||||
|
if (value instanceof Array) {
|
||||||
|
const multiValue = value.map(singleValue => encodeURIComponent(String(singleValue)))
|
||||||
|
.join(`&${encodeURIComponent(fullKey)}=`);
|
||||||
|
return `${encodeURIComponent(fullKey)}=${multiValue}`;
|
||||||
|
}
|
||||||
|
if (value instanceof Set) {
|
||||||
|
const valueAsArray = Array.from(value);
|
||||||
|
return querystringSingleKey(key, valueAsArray, keyPrefix);
|
||||||
|
}
|
||||||
|
if (value instanceof Date) {
|
||||||
|
return `${encodeURIComponent(fullKey)}=${encodeURIComponent(value.toISOString())}`;
|
||||||
|
}
|
||||||
|
if (value instanceof Object) {
|
||||||
|
return querystring(value as HTTPQuery, fullKey);
|
||||||
|
}
|
||||||
|
return `${encodeURIComponent(fullKey)}=${encodeURIComponent(String(value))}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapValues(data: any, fn: (item: any) => any) {
|
||||||
|
return Object.keys(data).reduce(
|
||||||
|
(acc, key) => ({ ...acc, [key]: fn(data[key]) }),
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function canConsumeForm(consumes: Consume[]): boolean {
|
||||||
|
for (const consume of consumes) {
|
||||||
|
if ('multipart/form-data' === consume.contentType) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Consume {
|
||||||
|
contentType: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RequestContext {
|
||||||
|
fetch: FetchAPI;
|
||||||
|
url: string;
|
||||||
|
init: RequestInit;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResponseContext {
|
||||||
|
fetch: FetchAPI;
|
||||||
|
url: string;
|
||||||
|
init: RequestInit;
|
||||||
|
response: Response;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ErrorContext {
|
||||||
|
fetch: FetchAPI;
|
||||||
|
url: string;
|
||||||
|
init: RequestInit;
|
||||||
|
error: unknown;
|
||||||
|
response?: Response;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Middleware {
|
||||||
|
pre?(context: RequestContext): Promise<FetchParams | void>;
|
||||||
|
post?(context: ResponseContext): Promise<Response | void>;
|
||||||
|
onError?(context: ErrorContext): Promise<Response | void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiResponse<T> {
|
||||||
|
raw: Response;
|
||||||
|
value(): Promise<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ResponseTransformer<T> {
|
||||||
|
(json: any): T;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class JSONApiResponse<T> {
|
||||||
|
constructor(public raw: Response, private transformer: ResponseTransformer<T> = (jsonValue: any) => jsonValue) {}
|
||||||
|
|
||||||
|
async value(): Promise<T> {
|
||||||
|
return this.transformer(await this.raw.json());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class VoidApiResponse {
|
||||||
|
constructor(public raw: Response) {}
|
||||||
|
|
||||||
|
async value(): Promise<void> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BlobApiResponse {
|
||||||
|
constructor(public raw: Response) {}
|
||||||
|
|
||||||
|
async value(): Promise<Blob> {
|
||||||
|
return await this.raw.blob();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export class TextApiResponse {
|
||||||
|
constructor(public raw: Response) {}
|
||||||
|
|
||||||
|
async value(): Promise<string> {
|
||||||
|
return await this.raw.text();
|
||||||
|
};
|
||||||
|
}
|
53
agent/agentUi/src/assets/zrok-1.0.0-rocket-green.svg
Normal file
53
agent/agentUi/src/assets/zrok-1.0.0-rocket-green.svg
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="125.797mm"
|
||||||
|
height="166.26598mm"
|
||||||
|
viewBox="0 0 125.797 166.26598"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
xml:space="preserve"
|
||||||
|
inkscape:version="1.4 (e7c3feb, 2024-10-09)"
|
||||||
|
sodipodi:docname="zrok-1.0.0-rocket-white.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showguides="false"
|
||||||
|
inkscape:zoom="0.85634716"
|
||||||
|
inkscape:cx="560.52034"
|
||||||
|
inkscape:cy="509.72318"
|
||||||
|
inkscape:window-width="1952"
|
||||||
|
inkscape:window-height="1304"
|
||||||
|
inkscape:window-x="1311"
|
||||||
|
inkscape:window-y="48"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="layer1"><inkscape:page
|
||||||
|
x="0"
|
||||||
|
y="-4.4822158e-22"
|
||||||
|
width="125.797"
|
||||||
|
height="166.26598"
|
||||||
|
id="page2"
|
||||||
|
margin="0"
|
||||||
|
bleed="0" /></sodipodi:namedview><defs
|
||||||
|
id="defs1" /><g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-41.620475,-64.027978)"><path
|
||||||
|
id="path2"
|
||||||
|
style="fill:#9bf316;fill-opacity:1;stroke-width:0.865487"
|
||||||
|
d="m 104.52059,64.027974 c 0,0 -12.300998,16.684095 -17.163248,24.964306 -4.8623,8.28022 -7.86765,12.84754 -10.59501,26.3339 -2.72736,13.48636 -1.27406,42.21319 -1.27406,42.21319 l -18.58752,20.04004 -15.280273,49.9615 40.422833,-6.79427 a 22.714797,11.567473 0 0 0 22.320548,9.54731 22.714797,11.567473 0 0 0 22.32712,-9.55945 l 40.72649,6.84277 -15.28027,-49.95979 -18.58916,-20.04001 c 0,0 1.45496,-28.72857 -1.2724,-42.21493 -2.72736,-13.48636 -5.73437,-18.05368 -10.59667,-26.3339 -4.8608,-8.277646 -17.14905,-24.947062 -17.15668,-24.957378 z m -0.0151,14.741718 c 0.52421,0.860497 14.76063,18.300498 18.34492,32.586238 3.65093,14.55125 3.25036,30.16797 2.29067,46.75483 -0.68395,11.82081 -5.48912,37.13724 -8.2384,50.97445 a 22.714797,11.567473 0 0 0 -12.54073,-1.9254 22.714797,11.567473 0 0 0 -12.237098,1.84921 c -2.75047,-13.84452 -7.55003,-39.12307 -8.23343,-50.93462 -0.95969,-16.58687 -1.36026,-32.20531 2.29067,-46.75656 3.57561,-14.25109 17.733538,-31.579359 18.323398,-32.548148 z m -27.999198,95.069708 6.36686,35.53319 -30.30472,9.08328 10.94985,-35.7998 z m 56.021568,0.0351 12.988,8.81667 10.9482,35.80155 -30.30311,-9.08504 z"
|
||||||
|
inkscape:export-filename="zrok-1.0.0-rocket-white.svg"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96" /></g></svg>
|
After Width: | Height: | Size: 2.8 KiB |
55
agent/agentUi/src/index.css
Normal file
55
agent/agentUi/src/index.css
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
min-width: 320px;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-family: 'JetBrains Mono', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #241775;
|
||||||
|
text-decoration: inherit;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #9bf316;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 3.2em;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
padding: 0.6em 1.2em;
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: 500;
|
||||||
|
font-family: inherit;
|
||||||
|
background-color: #1a1a1a;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: border-color 0.25s;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
border-color: #646cff;
|
||||||
|
}
|
||||||
|
button:focus,
|
||||||
|
button:focus-visible {
|
||||||
|
outline: 4px auto -webkit-focus-ring-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
#root {
|
||||||
|
max-width: 1280px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer {
|
||||||
|
text-align: center;
|
||||||
|
}
|
14
agent/agentUi/src/main.tsx
Normal file
14
agent/agentUi/src/main.tsx
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import "./index.css";
|
||||||
|
import {StrictMode} from "react";
|
||||||
|
import {createRoot} from "react-dom/client";
|
||||||
|
import {ThemeProvider} from "@mui/material";
|
||||||
|
import {theme} from "./model/theme.ts";
|
||||||
|
import AgentUi from "./AgentUi.tsx";
|
||||||
|
|
||||||
|
createRoot(document.getElementById('root')!).render(
|
||||||
|
<StrictMode>
|
||||||
|
<ThemeProvider theme={theme}>
|
||||||
|
<AgentUi />
|
||||||
|
</ThemeProvider>
|
||||||
|
</StrictMode>
|
||||||
|
);
|
5
agent/agentUi/src/model/api.ts
Normal file
5
agent/agentUi/src/model/api.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import {AgentApi, Configuration} from "../api";
|
||||||
|
|
||||||
|
export const GetAgentApi = () => {
|
||||||
|
return new AgentApi(new Configuration({basePath: window.location.origin}));
|
||||||
|
}
|
36
agent/agentUi/src/model/overview.ts
Normal file
36
agent/agentUi/src/model/overview.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import {AccessDetail, ShareDetail, StatusResponse} from "../api";
|
||||||
|
|
||||||
|
export class AgentObject {
|
||||||
|
type: string;
|
||||||
|
id: string;
|
||||||
|
v: (ShareDetail|AccessDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildOverview(status: StatusResponse): Array<AgentObject> {
|
||||||
|
let out = new Array<AgentObject>();
|
||||||
|
if(status) {
|
||||||
|
if(status.accesses) {
|
||||||
|
status.accesses.forEach(acc => {
|
||||||
|
let accObj = new AgentObject();
|
||||||
|
accObj.type = "access";
|
||||||
|
accObj.id = acc.frontendToken!;
|
||||||
|
accObj.v = acc;
|
||||||
|
out.push(accObj);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(status.shares) {
|
||||||
|
status.shares.forEach(shr => {
|
||||||
|
let shrObj = new AgentObject();
|
||||||
|
shrObj.type = "share";
|
||||||
|
shrObj.id = shr.token!;
|
||||||
|
shrObj.v = shr;
|
||||||
|
out.push(shrObj);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
out.sort((a, b) => {
|
||||||
|
if(a.id < b.id) return -1;
|
||||||
|
if(a.id > b.id) return 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
47
agent/agentUi/src/model/theme.ts
Normal file
47
agent/agentUi/src/model/theme.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import {createTheme} from "@mui/material";
|
||||||
|
|
||||||
|
const componentOptions = {
|
||||||
|
MuiCard: {
|
||||||
|
styleOverrides: {
|
||||||
|
root: ({theme}) => theme.unstable_sx({
|
||||||
|
mt: 5,
|
||||||
|
p: 1,
|
||||||
|
borderRadius: 3,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
MuiAppBar: {
|
||||||
|
styleOverrides: {
|
||||||
|
root : ({theme}) => theme.unstable_sx({
|
||||||
|
borderRadius: 3,
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const theme = createTheme({
|
||||||
|
components: componentOptions,
|
||||||
|
palette: {
|
||||||
|
mode: 'light',
|
||||||
|
primary: {
|
||||||
|
main: '#241775',
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
main: '#9bf316',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
typography: {
|
||||||
|
fontFamily: 'Poppins',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const modalStyle = {
|
||||||
|
position: 'absolute',
|
||||||
|
top: '25%',
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translate(-50%, -50%)',
|
||||||
|
width: 600,
|
||||||
|
bgcolor: 'background.paper',
|
||||||
|
boxShadow: 24,
|
||||||
|
p: 4,
|
||||||
|
};
|
1
agent/agentUi/src/vite-env.d.ts
vendored
Normal file
1
agent/agentUi/src/vite-env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/// <reference types="vite/client" />
|
26
agent/agentUi/tsconfig.app.json
Normal file
26
agent/agentUi/tsconfig.app.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||||
|
"target": "ES2020",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||||
|
"module": "ESNext",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedSideEffectImports": true
|
||||||
|
},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
7
agent/agentUi/tsconfig.json
Normal file
7
agent/agentUi/tsconfig.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"files": [],
|
||||||
|
"references": [
|
||||||
|
{ "path": "./tsconfig.app.json" },
|
||||||
|
{ "path": "./tsconfig.node.json" }
|
||||||
|
]
|
||||||
|
}
|
24
agent/agentUi/tsconfig.node.json
Normal file
24
agent/agentUi/tsconfig.node.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
||||||
|
"target": "ES2022",
|
||||||
|
"lib": ["ES2023"],
|
||||||
|
"module": "ESNext",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "Bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"noEmit": true,
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"noUncheckedSideEffectImports": true
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
15
agent/agentUi/vite.config.ts
Normal file
15
agent/agentUi/vite.config.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import react from '@vitejs/plugin-react'
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [react()],
|
||||||
|
server: {
|
||||||
|
proxy: {
|
||||||
|
'/v1': {
|
||||||
|
target: 'http://localhost:8888',
|
||||||
|
changeOrigin: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
15
agent/config.go
Normal file
15
agent/config.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
type AgentConfig struct {
|
||||||
|
ConsoleAddress string
|
||||||
|
ConsoleStartPort uint16
|
||||||
|
ConsoleEndPort uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
func DefaultConfig() *AgentConfig {
|
||||||
|
return &AgentConfig{
|
||||||
|
ConsoleAddress: "127.0.0.1",
|
||||||
|
ConsoleStartPort: 8080,
|
||||||
|
ConsoleEndPort: 8181,
|
||||||
|
}
|
||||||
|
}
|
59
agent/proctree/impl_posix.go
Normal file
59
agent/proctree/impl_posix.go
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
//go:build !windows
|
||||||
|
|
||||||
|
package proctree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os/exec"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Init(_ string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func StartChild(tail TailFunction, args ...string) (*Child, error) {
|
||||||
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
|
|
||||||
|
cld := &Child{
|
||||||
|
TailFunction: tail,
|
||||||
|
cmd: cmd,
|
||||||
|
outStream: make(chan []byte),
|
||||||
|
errStream: make(chan []byte),
|
||||||
|
wg: new(sync.WaitGroup),
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout, err := cmd.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
stderr, err := cmd.StderrPipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cld.wg.Add(3)
|
||||||
|
go reader(stdout, cld.outStream, cld.wg)
|
||||||
|
go reader(stderr, cld.errStream, cld.wg)
|
||||||
|
go cld.combiner(cld.wg)
|
||||||
|
|
||||||
|
return cld, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func WaitChild(c *Child) error {
|
||||||
|
c.wg.Wait()
|
||||||
|
if err := c.cmd.Wait(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func StopChild(c *Child) error {
|
||||||
|
if err := c.cmd.Process.Kill(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
79
agent/proctree/impl_windows.go
Executable file
79
agent/proctree/impl_windows.go
Executable file
@ -0,0 +1,79 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package proctree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kolesnikovae/go-winjob"
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
"os/exec"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
var job *winjob.JobObject
|
||||||
|
|
||||||
|
func Init(name string) error {
|
||||||
|
var err error
|
||||||
|
if job == nil {
|
||||||
|
job, err = winjob.Create(name, winjob.LimitKillOnJobClose, winjob.LimitBreakawayOK)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func StartChild(tail TailFunction, args ...string) (*Child, error) {
|
||||||
|
cmd := exec.Command(args[0], args[1:]...)
|
||||||
|
cmd.SysProcAttr = &windows.SysProcAttr{CreationFlags: windows.CREATE_SUSPENDED}
|
||||||
|
|
||||||
|
cld := &Child{
|
||||||
|
TailFunction: tail,
|
||||||
|
cmd: cmd,
|
||||||
|
outStream: make(chan []byte),
|
||||||
|
errStream: make(chan []byte),
|
||||||
|
wg: new(sync.WaitGroup),
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout, err := cmd.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
stderr, err := cmd.StderrPipe()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := job.Assign(cmd.Process); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := winjob.ResumeProcess(cmd.Process.Pid); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cld.wg.Add(3)
|
||||||
|
go reader(stdout, cld.outStream, cld.wg)
|
||||||
|
go reader(stderr, cld.errStream, cld.wg)
|
||||||
|
go cld.combiner(cld.wg)
|
||||||
|
|
||||||
|
return cld, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func WaitChild(c *Child) error {
|
||||||
|
c.wg.Wait()
|
||||||
|
if err := c.cmd.Wait(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func StopChild(c *Child) error {
|
||||||
|
if err := c.cmd.Process.Kill(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
67
agent/proctree/proctree.go
Executable file
67
agent/proctree/proctree.go
Executable file
@ -0,0 +1,67 @@
|
|||||||
|
package proctree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
_ "github.com/kolesnikovae/go-winjob"
|
||||||
|
"io"
|
||||||
|
"os/exec"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Child struct {
|
||||||
|
TailFunction TailFunction
|
||||||
|
cmd *exec.Cmd
|
||||||
|
outStream chan []byte
|
||||||
|
errStream chan []byte
|
||||||
|
wg *sync.WaitGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
type TailFunction func(data []byte)
|
||||||
|
|
||||||
|
func (c *Child) combiner(wg *sync.WaitGroup) {
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
outDone := false
|
||||||
|
errDone := false
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case data := <-c.outStream:
|
||||||
|
if data != nil {
|
||||||
|
if c.TailFunction != nil {
|
||||||
|
c.TailFunction(data)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
outDone = true
|
||||||
|
}
|
||||||
|
case data := <-c.errStream:
|
||||||
|
if data != nil {
|
||||||
|
if c.TailFunction != nil {
|
||||||
|
c.TailFunction(data)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
errDone = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if outDone && errDone {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func reader(r io.ReadCloser, o chan []byte, wg *sync.WaitGroup) {
|
||||||
|
defer close(o)
|
||||||
|
defer wg.Done()
|
||||||
|
|
||||||
|
buf := make([]byte, 64*1024)
|
||||||
|
for {
|
||||||
|
n, err := r.Read(buf)
|
||||||
|
if err != nil {
|
||||||
|
if err == io.EOF {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("error reading: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
o <- buf[:n]
|
||||||
|
}
|
||||||
|
}
|
19
agent/releaseAccess.go
Normal file
19
agent/releaseAccess.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/openziti/zrok/agent/agentGrpc"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *agentGrpcImpl) ReleaseAccess(_ context.Context, req *agentGrpc.ReleaseAccessRequest) (*agentGrpc.ReleaseAccessResponse, error) {
|
||||||
|
if acc, found := i.agent.accesses[req.FrontendToken]; found {
|
||||||
|
i.agent.rmAccess <- acc
|
||||||
|
logrus.Infof("released access '%v'", acc.frontendToken)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return nil, errors.Errorf("agent has no access with frontend token '%v'", req.FrontendToken)
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
19
agent/releaseShare.go
Executable file
19
agent/releaseShare.go
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/openziti/zrok/agent/agentGrpc"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *agentGrpcImpl) ReleaseShare(_ context.Context, req *agentGrpc.ReleaseShareRequest) (*agentGrpc.ReleaseShareResponse, error) {
|
||||||
|
if shr, found := i.agent.shares[req.Token]; found {
|
||||||
|
i.agent.rmShare <- shr
|
||||||
|
logrus.Infof("released share '%v'", shr.token)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return nil, errors.Errorf("agent has no share with token '%v'", req.Token)
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
83
agent/share.go
Normal file
83
agent/share.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/michaelquigley/pfxlog"
|
||||||
|
"github.com/openziti/zrok/agent/proctree"
|
||||||
|
"github.com/openziti/zrok/cmd/zrok/subordinate"
|
||||||
|
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type share struct {
|
||||||
|
token string
|
||||||
|
frontendEndpoints []string
|
||||||
|
target string
|
||||||
|
basicAuth []string
|
||||||
|
frontendSelection []string
|
||||||
|
shareMode sdk.ShareMode
|
||||||
|
backendMode sdk.BackendMode
|
||||||
|
reserved bool
|
||||||
|
insecure bool
|
||||||
|
oauthProvider string
|
||||||
|
oauthEmailAddressPatterns []string
|
||||||
|
oauthCheckInterval time.Duration
|
||||||
|
closed bool
|
||||||
|
accessGrants []string
|
||||||
|
|
||||||
|
process *proctree.Child
|
||||||
|
sub *subordinate.MessageHandler
|
||||||
|
|
||||||
|
agent *Agent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *share) monitor() {
|
||||||
|
if err := proctree.WaitChild(s.process); err != nil {
|
||||||
|
pfxlog.ChannelLogger(s.token).Error(err)
|
||||||
|
}
|
||||||
|
s.agent.rmShare <- s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *share) bootHandler(msgType string, msg subordinate.Message) error {
|
||||||
|
switch msgType {
|
||||||
|
case subordinate.BootMessage:
|
||||||
|
if v, found := msg["token"]; found {
|
||||||
|
if str, ok := v.(string); ok {
|
||||||
|
s.token = str
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v, found := msg["backend_mode"]; found {
|
||||||
|
if str, ok := v.(string); ok {
|
||||||
|
s.backendMode = sdk.BackendMode(str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v, found := msg["share_mode"]; found {
|
||||||
|
if str, ok := v.(string); ok {
|
||||||
|
s.shareMode = sdk.ShareMode(str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v, found := msg["frontend_endpoints"]; found {
|
||||||
|
if vArr, ok := v.([]interface{}); ok {
|
||||||
|
for _, v := range vArr {
|
||||||
|
if str, ok := v.(string); ok {
|
||||||
|
s.frontendEndpoints = append(s.frontendEndpoints, str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if v, found := msg["target"]; found {
|
||||||
|
if str, ok := v.(string); ok {
|
||||||
|
s.target = str
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case subordinate.ErrorMessage:
|
||||||
|
if v, found := msg[subordinate.ErrorMessage]; found {
|
||||||
|
if str, ok := v.(string); ok {
|
||||||
|
return errors.New(str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
82
agent/sharePrivate.go
Normal file
82
agent/sharePrivate.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/openziti/zrok/agent/agentGrpc"
|
||||||
|
"github.com/openziti/zrok/agent/proctree"
|
||||||
|
"github.com/openziti/zrok/cmd/zrok/subordinate"
|
||||||
|
"github.com/openziti/zrok/environment"
|
||||||
|
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *agentGrpcImpl) SharePrivate(_ context.Context, req *agentGrpc.SharePrivateRequest) (*agentGrpc.SharePrivateResponse, error) {
|
||||||
|
root, err := environment.LoadRoot()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !root.IsEnabled() {
|
||||||
|
return nil, errors.New("unable to load environment; did you 'zrok enable'?")
|
||||||
|
}
|
||||||
|
|
||||||
|
shrCmd := []string{os.Args[0], "share", "private", "--subordinate", "-b", req.BackendMode}
|
||||||
|
shr := &share{
|
||||||
|
shareMode: sdk.PrivateShareMode,
|
||||||
|
backendMode: sdk.BackendMode(req.BackendMode),
|
||||||
|
sub: subordinate.NewMessageHandler(),
|
||||||
|
agent: i.agent,
|
||||||
|
}
|
||||||
|
shr.sub.MessageHandler = func(msg subordinate.Message) {
|
||||||
|
logrus.Info(msg)
|
||||||
|
}
|
||||||
|
var bootErr error
|
||||||
|
shr.sub.BootHandler = func(msgType string, msg subordinate.Message) {
|
||||||
|
bootErr = shr.bootHandler(msgType, msg)
|
||||||
|
}
|
||||||
|
shr.sub.MalformedHandler = func(msg subordinate.Message) {
|
||||||
|
logrus.Error(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Insecure {
|
||||||
|
shrCmd = append(shrCmd, "--insecure")
|
||||||
|
}
|
||||||
|
shr.insecure = req.Insecure
|
||||||
|
|
||||||
|
if req.Closed {
|
||||||
|
shrCmd = append(shrCmd, "--closed")
|
||||||
|
}
|
||||||
|
shr.closed = req.Closed
|
||||||
|
|
||||||
|
for _, grant := range req.AccessGrants {
|
||||||
|
shrCmd = append(shrCmd, "--access-grant", grant)
|
||||||
|
}
|
||||||
|
shr.accessGrants = req.AccessGrants
|
||||||
|
|
||||||
|
shrCmd = append(shrCmd, req.Target)
|
||||||
|
shr.target = req.Target
|
||||||
|
|
||||||
|
logrus.Infof("executing '%v'", shrCmd)
|
||||||
|
|
||||||
|
shr.process, err = proctree.StartChild(shr.sub.Tail, shrCmd...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
<-shr.sub.BootComplete
|
||||||
|
|
||||||
|
if bootErr == nil {
|
||||||
|
go shr.monitor()
|
||||||
|
i.agent.addShare <- shr
|
||||||
|
return &agentGrpc.SharePrivateResponse{Token: shr.token}, nil
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if err := proctree.WaitChild(shr.process); err != nil {
|
||||||
|
logrus.Errorf("error joining: %v", err)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unable to start share: %v", bootErr)
|
||||||
|
}
|
||||||
|
}
|
109
agent/sharePublic.go
Normal file
109
agent/sharePublic.go
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/openziti/zrok/agent/agentGrpc"
|
||||||
|
"github.com/openziti/zrok/agent/proctree"
|
||||||
|
"github.com/openziti/zrok/cmd/zrok/subordinate"
|
||||||
|
"github.com/openziti/zrok/environment"
|
||||||
|
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *agentGrpcImpl) SharePublic(_ context.Context, req *agentGrpc.SharePublicRequest) (*agentGrpc.SharePublicResponse, error) {
|
||||||
|
root, err := environment.LoadRoot()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !root.IsEnabled() {
|
||||||
|
return nil, errors.New("unable to load environment; did you 'zrok enable'?")
|
||||||
|
}
|
||||||
|
|
||||||
|
shrCmd := []string{os.Args[0], "share", "public", "--subordinate", "-b", req.BackendMode}
|
||||||
|
shr := &share{
|
||||||
|
shareMode: sdk.PublicShareMode,
|
||||||
|
backendMode: sdk.BackendMode(req.BackendMode),
|
||||||
|
sub: subordinate.NewMessageHandler(),
|
||||||
|
agent: i.agent,
|
||||||
|
}
|
||||||
|
shr.sub.MessageHandler = func(msg subordinate.Message) {
|
||||||
|
logrus.Info(msg)
|
||||||
|
}
|
||||||
|
var bootErr error
|
||||||
|
shr.sub.BootHandler = func(msgType string, msg subordinate.Message) {
|
||||||
|
bootErr = shr.bootHandler(msgType, msg)
|
||||||
|
}
|
||||||
|
shr.sub.MalformedHandler = func(msg subordinate.Message) {
|
||||||
|
logrus.Error(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, basicAuth := range req.BasicAuth {
|
||||||
|
shrCmd = append(shrCmd, "--basic-auth", basicAuth)
|
||||||
|
}
|
||||||
|
shr.basicAuth = req.BasicAuth
|
||||||
|
|
||||||
|
for _, frontendSelection := range req.FrontendSelection {
|
||||||
|
shrCmd = append(shrCmd, "--frontend", frontendSelection)
|
||||||
|
}
|
||||||
|
shr.frontendSelection = req.FrontendSelection
|
||||||
|
|
||||||
|
if req.Insecure {
|
||||||
|
shrCmd = append(shrCmd, "--insecure")
|
||||||
|
}
|
||||||
|
shr.insecure = req.Insecure
|
||||||
|
|
||||||
|
if req.OauthProvider != "" {
|
||||||
|
shrCmd = append(shrCmd, "--oauth-provider", req.OauthProvider)
|
||||||
|
}
|
||||||
|
shr.oauthProvider = req.OauthProvider
|
||||||
|
|
||||||
|
for _, pattern := range req.OauthEmailAddressPatterns {
|
||||||
|
shrCmd = append(shrCmd, "--oauth-email-address-patterns", pattern)
|
||||||
|
}
|
||||||
|
shr.oauthEmailAddressPatterns = req.OauthEmailAddressPatterns
|
||||||
|
|
||||||
|
if req.OauthCheckInterval != "" {
|
||||||
|
shrCmd = append(shrCmd, "--oauth-check-interval", req.OauthCheckInterval)
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Closed {
|
||||||
|
shrCmd = append(shrCmd, "--closed")
|
||||||
|
}
|
||||||
|
shr.closed = req.Closed
|
||||||
|
|
||||||
|
for _, grant := range req.AccessGrants {
|
||||||
|
shrCmd = append(shrCmd, "--access-grant", grant)
|
||||||
|
}
|
||||||
|
shr.accessGrants = req.AccessGrants
|
||||||
|
|
||||||
|
shrCmd = append(shrCmd, req.Target)
|
||||||
|
shr.target = req.Target
|
||||||
|
|
||||||
|
logrus.Infof("executing '%v'", shrCmd)
|
||||||
|
|
||||||
|
shr.process, err = proctree.StartChild(shr.sub.Tail, shrCmd...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
<-shr.sub.BootComplete
|
||||||
|
|
||||||
|
if bootErr == nil {
|
||||||
|
go shr.monitor()
|
||||||
|
i.agent.addShare <- shr
|
||||||
|
return &agentGrpc.SharePublicResponse{
|
||||||
|
Token: shr.token,
|
||||||
|
FrontendEndpoints: shr.frontendEndpoints,
|
||||||
|
}, nil
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if err := proctree.WaitChild(shr.process); err != nil {
|
||||||
|
logrus.Errorf("error joining: %v", err)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unable to start share: %v", bootErr)
|
||||||
|
}
|
||||||
|
}
|
78
agent/shareReserved.go
Normal file
78
agent/shareReserved.go
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/openziti/zrok/agent/agentGrpc"
|
||||||
|
"github.com/openziti/zrok/agent/proctree"
|
||||||
|
"github.com/openziti/zrok/cmd/zrok/subordinate"
|
||||||
|
"github.com/openziti/zrok/environment"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *agentGrpcImpl) ShareReserved(_ context.Context, req *agentGrpc.ShareReservedRequest) (*agentGrpc.ShareReservedResponse, error) {
|
||||||
|
root, err := environment.LoadRoot()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !root.IsEnabled() {
|
||||||
|
return nil, errors.New("unable to load environment; did you 'zrok enable'?")
|
||||||
|
}
|
||||||
|
|
||||||
|
shrCmd := []string{os.Args[0], "share", "reserved", "--subordinate"}
|
||||||
|
shr := &share{
|
||||||
|
reserved: true,
|
||||||
|
sub: subordinate.NewMessageHandler(),
|
||||||
|
agent: i.agent,
|
||||||
|
}
|
||||||
|
shr.sub.MessageHandler = func(msg subordinate.Message) {
|
||||||
|
logrus.Info(msg)
|
||||||
|
}
|
||||||
|
var bootErr error
|
||||||
|
shr.sub.BootHandler = func(msgType string, msg subordinate.Message) {
|
||||||
|
bootErr = shr.bootHandler(msgType, msg)
|
||||||
|
}
|
||||||
|
shr.sub.MalformedHandler = func(msg subordinate.Message) {
|
||||||
|
logrus.Error(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.OverrideEndpoint != "" {
|
||||||
|
shrCmd = append(shrCmd, "--override-endpoint", req.OverrideEndpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
if req.Insecure {
|
||||||
|
shrCmd = append(shrCmd, "--insecure")
|
||||||
|
}
|
||||||
|
shr.insecure = req.Insecure
|
||||||
|
|
||||||
|
shrCmd = append(shrCmd, req.Token)
|
||||||
|
shr.token = req.Token
|
||||||
|
|
||||||
|
shr.process, err = proctree.StartChild(shr.sub.Tail, shrCmd...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
<-shr.sub.BootComplete
|
||||||
|
|
||||||
|
if bootErr == nil {
|
||||||
|
go shr.monitor()
|
||||||
|
i.agent.addShare <- shr
|
||||||
|
return &agentGrpc.ShareReservedResponse{
|
||||||
|
Token: shr.token,
|
||||||
|
BackendMode: string(shr.backendMode),
|
||||||
|
ShareMode: string(shr.shareMode),
|
||||||
|
FrontendEndpoints: shr.frontendEndpoints,
|
||||||
|
Target: shr.target,
|
||||||
|
}, nil
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if err := proctree.WaitChild(shr.process); err != nil {
|
||||||
|
logrus.Errorf("error joining: %v", err)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unable to start share: %v", bootErr)
|
||||||
|
}
|
||||||
|
}
|
40
agent/status.go
Normal file
40
agent/status.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/openziti/zrok/agent/agentGrpc"
|
||||||
|
"sort"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *agentGrpcImpl) Status(_ context.Context, _ *agentGrpc.StatusRequest) (*agentGrpc.StatusResponse, error) {
|
||||||
|
var accesses []*agentGrpc.AccessDetail
|
||||||
|
for feToken, acc := range i.agent.accesses {
|
||||||
|
accesses = append(accesses, &agentGrpc.AccessDetail{
|
||||||
|
FrontendToken: feToken,
|
||||||
|
Token: acc.token,
|
||||||
|
BindAddress: acc.bindAddress,
|
||||||
|
ResponseHeaders: acc.responseHeaders,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
sort.Slice(accesses, func(i, j int) bool {
|
||||||
|
return accesses[i].FrontendToken < accesses[j].FrontendToken
|
||||||
|
})
|
||||||
|
|
||||||
|
var shares []*agentGrpc.ShareDetail
|
||||||
|
for token, shr := range i.agent.shares {
|
||||||
|
shares = append(shares, &agentGrpc.ShareDetail{
|
||||||
|
Token: token,
|
||||||
|
ShareMode: string(shr.shareMode),
|
||||||
|
BackendMode: string(shr.backendMode),
|
||||||
|
Reserved: shr.reserved,
|
||||||
|
FrontendEndpoint: shr.frontendEndpoints,
|
||||||
|
BackendEndpoint: shr.target,
|
||||||
|
Closed: shr.closed,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
sort.Slice(shares, func(i, j int) bool {
|
||||||
|
return shares[i].Token < shares[j].Token
|
||||||
|
})
|
||||||
|
|
||||||
|
return &agentGrpc.StatusResponse{Accesses: accesses, Shares: shares}, nil
|
||||||
|
}
|
17
agent/version.go
Normal file
17
agent/version.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/openziti/zrok/agent/agentGrpc"
|
||||||
|
"github.com/openziti/zrok/build"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (i *agentGrpcImpl) Version(_ context.Context, _ *agentGrpc.VersionRequest) (*agentGrpc.VersionResponse, error) {
|
||||||
|
v := build.String()
|
||||||
|
logrus.Debugf("responding to version inquiry with '%v'", v)
|
||||||
|
return &agentGrpc.VersionResponse{
|
||||||
|
V: v,
|
||||||
|
ConsoleEndpoint: i.agent.httpEndpoint,
|
||||||
|
}, nil
|
||||||
|
}
|
14
bin/generate_pb.sh
Executable file
14
bin/generate_pb.sh
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
go install \
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2 \
|
||||||
|
google.golang.org/protobuf/cmd/protoc-gen-go \
|
||||||
|
google.golang.org/grpc/cmd/protoc-gen-go-grpc
|
||||||
|
|
||||||
|
protoc --go_out=. --go_opt=paths=source_relative \
|
||||||
|
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
|
||||||
|
--grpc-gateway_out=. --grpc-gateway_opt=paths=source_relative \
|
||||||
|
--openapiv2_out=. \
|
||||||
|
agent/agentGrpc/agent.proto
|
||||||
|
|
@ -7,11 +7,6 @@ command -v swagger >/dev/null 2>&1 || {
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
command -v openapi >/dev/null 2>&1 || {
|
|
||||||
echo >&2 "command 'openapi' not installed. see: https://www.npmjs.com/package/openapi-client for installation"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
command -v swagger-codegen 2>&1 || {
|
command -v swagger-codegen 2>&1 || {
|
||||||
echo >&2 "command 'swagger-codegen' not installed. see: https://github.com/swagger-api/swagger-codegen for installation"
|
echo >&2 "command 'swagger-codegen' not installed. see: https://github.com/swagger-api/swagger-codegen for installation"
|
||||||
exit 1
|
exit 1
|
||||||
@ -42,13 +37,16 @@ swagger generate server -P rest_model_zrok.Principal -f "$zrokSpec" -s rest_serv
|
|||||||
echo "...generating zrok client"
|
echo "...generating zrok client"
|
||||||
swagger generate client -P rest_model_zrok.Principal -f "$zrokSpec" -c rest_client_zrok -t "$zrokDir" -m "rest_model_zrok"
|
swagger generate client -P rest_model_zrok.Principal -f "$zrokSpec" -c rest_client_zrok -t "$zrokDir" -m "rest_model_zrok"
|
||||||
|
|
||||||
echo "...generating js client"
|
echo "...generating api console ts client"
|
||||||
openapi -s specs/zrok.yml -o ui/src/api -l js
|
openapi-generator-cli generate -i specs/zrok.yml -o ui/src/api -g typescript-fetch
|
||||||
|
|
||||||
echo "...generating ts client"
|
echo "...generating agent console ts client"
|
||||||
|
openapi-generator-cli generate -i agent/agentGrpc/agent.swagger.json -o agent/agentUi/src/api -g typescript-fetch
|
||||||
|
|
||||||
|
echo "...generating nodejs sdk ts client"
|
||||||
openapi-generator-cli generate -i specs/zrok.yml -o sdk/nodejs/sdk/src/zrok/api -g typescript-node
|
openapi-generator-cli generate -i specs/zrok.yml -o sdk/nodejs/sdk/src/zrok/api -g typescript-node
|
||||||
|
|
||||||
echo "...generating python client"
|
echo "...generating python sdk client"
|
||||||
swagger-codegen generate -i specs/zrok.yml -o sdk/python/sdk/zrok -c $pythonConfig -l python
|
swagger-codegen generate -i specs/zrok.yml -o sdk/python/sdk/zrok -c $pythonConfig -l python
|
||||||
|
|
||||||
git checkout rest_server_zrok/configure_zrok.go
|
git checkout rest_server_zrok/configure_zrok.go
|
@ -5,7 +5,7 @@ import "fmt"
|
|||||||
var Version string
|
var Version string
|
||||||
var Hash string
|
var Hash string
|
||||||
|
|
||||||
const Series = "v0.4"
|
const Series = "v1.0"
|
||||||
|
|
||||||
func String() string {
|
func String() string {
|
||||||
if Version != "" {
|
if Version != "" {
|
||||||
|
@ -1,19 +1,27 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
tea "github.com/charmbracelet/bubbletea"
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
"github.com/go-openapi/runtime"
|
"github.com/go-openapi/runtime"
|
||||||
httptransport "github.com/go-openapi/runtime/client"
|
httptransport "github.com/go-openapi/runtime/client"
|
||||||
|
"github.com/openziti/zrok/agent/agentClient"
|
||||||
|
"github.com/openziti/zrok/agent/agentGrpc"
|
||||||
|
"github.com/openziti/zrok/cmd/zrok/subordinate"
|
||||||
"github.com/openziti/zrok/endpoints"
|
"github.com/openziti/zrok/endpoints"
|
||||||
"github.com/openziti/zrok/endpoints/proxy"
|
"github.com/openziti/zrok/endpoints/proxy"
|
||||||
"github.com/openziti/zrok/endpoints/tcpTunnel"
|
"github.com/openziti/zrok/endpoints/tcpTunnel"
|
||||||
"github.com/openziti/zrok/endpoints/udpTunnel"
|
"github.com/openziti/zrok/endpoints/udpTunnel"
|
||||||
"github.com/openziti/zrok/endpoints/vpn"
|
"github.com/openziti/zrok/endpoints/vpn"
|
||||||
"github.com/openziti/zrok/environment"
|
"github.com/openziti/zrok/environment"
|
||||||
|
"github.com/openziti/zrok/environment/env_core"
|
||||||
"github.com/openziti/zrok/rest_client_zrok"
|
"github.com/openziti/zrok/rest_client_zrok"
|
||||||
"github.com/openziti/zrok/rest_client_zrok/share"
|
"github.com/openziti/zrok/rest_client_zrok/share"
|
||||||
"github.com/openziti/zrok/rest_model_zrok"
|
|
||||||
"github.com/openziti/zrok/tui"
|
"github.com/openziti/zrok/tui"
|
||||||
|
"github.com/openziti/zrok/util"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -29,7 +37,14 @@ func init() {
|
|||||||
|
|
||||||
type accessPrivateCommand struct {
|
type accessPrivateCommand struct {
|
||||||
bindAddress string
|
bindAddress string
|
||||||
|
autoMode bool
|
||||||
|
autoAddress string
|
||||||
|
autoStartPort uint16
|
||||||
|
autoEndPort uint16
|
||||||
headless bool
|
headless bool
|
||||||
|
subordinate bool
|
||||||
|
forceLocal bool
|
||||||
|
forceAgent bool
|
||||||
responseHeaders []string
|
responseHeaders []string
|
||||||
cmd *cobra.Command
|
cmd *cobra.Command
|
||||||
}
|
}
|
||||||
@ -41,47 +56,98 @@ func newAccessPrivateCommand() *accessPrivateCommand {
|
|||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
}
|
}
|
||||||
command := &accessPrivateCommand{cmd: cmd}
|
command := &accessPrivateCommand{cmd: cmd}
|
||||||
cmd.Flags().BoolVar(&command.headless, "headless", false, "Disable TUI and run headless")
|
headless := false
|
||||||
cmd.Flags().StringVarP(&command.bindAddress, "bind", "b", "127.0.0.1:9191", "The address to bind the private frontend")
|
if root, err := environment.LoadRoot(); err == nil {
|
||||||
|
headless, _ = root.Headless()
|
||||||
|
}
|
||||||
|
cmd.Flags().BoolVar(&command.headless, "headless", headless, "Disable TUI and run headless")
|
||||||
|
cmd.Flags().BoolVar(&command.subordinate, "subordinate", false, "Enable subordinate mode")
|
||||||
|
cmd.MarkFlagsMutuallyExclusive("headless", "subordinate")
|
||||||
|
cmd.Flags().BoolVar(&command.forceLocal, "force-local", false, "Skip agent detection and force local mode")
|
||||||
|
cmd.Flags().BoolVar(&command.forceAgent, "force-agent", false, "Skip agent detection and force agent mode")
|
||||||
|
cmd.MarkFlagsMutuallyExclusive("force-local", "force-agent")
|
||||||
|
cmd.Flags().StringVarP(&command.bindAddress, "bind", "b", "127.0.0.1:9191", "The address to bind the private frontend (ignored when using '--auto')")
|
||||||
|
cmd.Flags().BoolVar(&command.autoMode, "auto", false, "Enable automatic port detection")
|
||||||
|
cmd.Flags().StringVar(&command.autoAddress, "auto-address", "127.0.0.1", "The address to use for automatic port detection")
|
||||||
|
cmd.Flags().Uint16Var(&command.autoStartPort, "auto-start-port", 8080, "The starting port to use for automatic port detection")
|
||||||
|
cmd.Flags().Uint16Var(&command.autoEndPort, "auto-end-port", 8888, "The ending port to use for automatic port detection")
|
||||||
cmd.Flags().StringArrayVar(&command.responseHeaders, "response-header", []string{}, "Add a response header ('key:value')")
|
cmd.Flags().StringArrayVar(&command.responseHeaders, "response-header", []string{}, "Add a response header ('key:value')")
|
||||||
cmd.Run = command.run
|
cmd.Run = command.run
|
||||||
return command
|
return command
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) {
|
func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) {
|
||||||
shrToken := args[0]
|
if cmd.subordinate {
|
||||||
|
logrus.SetFormatter(&logrus.JSONFormatter{TimestampFormat: time.RFC3339Nano})
|
||||||
env, err := environment.LoadRoot()
|
|
||||||
if err != nil {
|
|
||||||
tui.Error("error loading environment", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !env.IsEnabled() {
|
root, err := environment.LoadRoot()
|
||||||
|
if err != nil {
|
||||||
|
cmd.error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !root.IsEnabled() {
|
||||||
tui.Error("unable to load environment; did you 'zrok enable'?", nil)
|
tui.Error("unable to load environment; did you 'zrok enable'?", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
zrok, err := env.Client()
|
if cmd.subordinate || cmd.forceLocal {
|
||||||
if err != nil {
|
cmd.accessLocal(args, root)
|
||||||
if !panicInstead {
|
} else {
|
||||||
tui.Error("unable to create zrok client", err)
|
agent := cmd.forceAgent
|
||||||
|
if !cmd.forceAgent {
|
||||||
|
agent, err = agentClient.IsAgentRunning(root)
|
||||||
|
if err != nil {
|
||||||
|
tui.Error("error checking if agent is running", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
panic(err)
|
if agent {
|
||||||
|
cmd.accessAgent(args, root)
|
||||||
|
} else {
|
||||||
|
cmd.accessLocal(args, root)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *accessPrivateCommand) accessLocal(args []string, root env_core.Root) {
|
||||||
|
shrToken := args[0]
|
||||||
|
|
||||||
|
zrok, err := root.Client()
|
||||||
|
if err != nil {
|
||||||
|
cmd.error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
auth := httptransport.APIKeyAuth("X-TOKEN", "header", env.Environment().Token)
|
auth := httptransport.APIKeyAuth("X-TOKEN", "header", root.Environment().Token)
|
||||||
req := share.NewAccessParams()
|
req := share.NewAccessParams()
|
||||||
req.Body = &rest_model_zrok.AccessRequest{
|
req.Body.ShareToken = shrToken
|
||||||
ShrToken: shrToken,
|
req.Body.EnvZID = root.Environment().ZitiIdentity
|
||||||
EnvZID: env.Environment().ZitiIdentity,
|
|
||||||
}
|
|
||||||
accessResp, err := zrok.Share.Access(req, auth)
|
accessResp, err := zrok.Share.Access(req, auth)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !panicInstead {
|
cmd.error(err)
|
||||||
tui.Error("unable to access", err)
|
}
|
||||||
}
|
|
||||||
panic(err)
|
bindAddress := cmd.bindAddress
|
||||||
|
if cmd.autoMode {
|
||||||
|
if accessResp.Payload.BackendMode == "udpTunnel" {
|
||||||
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
|
cmd.error(errors.New("auto-addressing is not compatible with the 'udpTunnel' backend mode"))
|
||||||
|
}
|
||||||
|
autoAddress, err := util.AutoListenerAddress("tcp", cmd.autoAddress, cmd.autoStartPort, cmd.autoEndPort)
|
||||||
|
if err != nil {
|
||||||
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
|
cmd.error(err)
|
||||||
|
}
|
||||||
|
bindAddress = autoAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
upReq := share.NewUpdateAccessParams()
|
||||||
|
upReq.Body.FrontendToken = accessResp.Payload.FrontendToken
|
||||||
|
upReq.Body.BindAddress = bindAddress
|
||||||
|
_, err = zrok.Share.UpdateAccess(upReq, auth)
|
||||||
|
if err != nil {
|
||||||
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
|
cmd.error(err)
|
||||||
}
|
}
|
||||||
logrus.Infof("allocated frontend '%v'", accessResp.Payload.FrontendToken)
|
|
||||||
|
|
||||||
protocol := "http://"
|
protocol := "http://"
|
||||||
switch accessResp.Payload.BackendMode {
|
switch accessResp.Payload.BackendMode {
|
||||||
@ -91,80 +157,66 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) {
|
|||||||
protocol = "udp://"
|
protocol = "udp://"
|
||||||
}
|
}
|
||||||
|
|
||||||
endpointUrl, err := url.Parse(protocol + cmd.bindAddress)
|
endpointUrl, err := url.Parse(protocol + bindAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !panicInstead {
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
tui.Error("invalid endpoint address", err)
|
cmd.error(err)
|
||||||
}
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
requests := make(chan *endpoints.Request, 1024)
|
requests := make(chan *endpoints.Request, 1024)
|
||||||
switch accessResp.Payload.BackendMode {
|
switch accessResp.Payload.BackendMode {
|
||||||
case "tcpTunnel":
|
case "tcpTunnel":
|
||||||
fe, err := tcpTunnel.NewFrontend(&tcpTunnel.FrontendConfig{
|
fe, err := tcpTunnel.NewFrontend(&tcpTunnel.FrontendConfig{
|
||||||
BindAddress: cmd.bindAddress,
|
BindAddress: bindAddress,
|
||||||
IdentityName: env.EnvironmentIdentityName(),
|
IdentityName: root.EnvironmentIdentityName(),
|
||||||
ShrToken: args[0],
|
ShrToken: args[0],
|
||||||
RequestsChan: requests,
|
RequestsChan: requests,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !panicInstead {
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
tui.Error("unable to create private access", err)
|
cmd.error(err)
|
||||||
}
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
if err := fe.Run(); err != nil {
|
if err := fe.Run(); err != nil {
|
||||||
if !panicInstead {
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
tui.Error("error starting access", err)
|
cmd.error(err)
|
||||||
}
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
case "udpTunnel":
|
case "udpTunnel":
|
||||||
fe, err := udpTunnel.NewFrontend(&udpTunnel.FrontendConfig{
|
fe, err := udpTunnel.NewFrontend(&udpTunnel.FrontendConfig{
|
||||||
BindAddress: cmd.bindAddress,
|
BindAddress: cmd.bindAddress,
|
||||||
IdentityName: env.EnvironmentIdentityName(),
|
IdentityName: root.EnvironmentIdentityName(),
|
||||||
ShrToken: args[0],
|
ShrToken: args[0],
|
||||||
RequestsChan: requests,
|
RequestsChan: requests,
|
||||||
IdleTime: time.Minute,
|
IdleTime: time.Minute,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !panicInstead {
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
tui.Error("unable to create private frontend", err)
|
cmd.error(err)
|
||||||
}
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
if err := fe.Run(); err != nil {
|
if err := fe.Run(); err != nil {
|
||||||
if !panicInstead {
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
tui.Error("error starting frontend", err)
|
cmd.error(err)
|
||||||
}
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
case "socks":
|
case "socks":
|
||||||
fe, err := tcpTunnel.NewFrontend(&tcpTunnel.FrontendConfig{
|
fe, err := tcpTunnel.NewFrontend(&tcpTunnel.FrontendConfig{
|
||||||
BindAddress: cmd.bindAddress,
|
BindAddress: bindAddress,
|
||||||
IdentityName: env.EnvironmentIdentityName(),
|
IdentityName: root.EnvironmentIdentityName(),
|
||||||
ShrToken: args[0],
|
ShrToken: args[0],
|
||||||
RequestsChan: requests,
|
RequestsChan: requests,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !panicInstead {
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
tui.Error("unable to create private access", err)
|
cmd.error(err)
|
||||||
}
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
if err := fe.Run(); err != nil {
|
if err := fe.Run(); err != nil {
|
||||||
if !panicInstead {
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
tui.Error("error starting access", err)
|
cmd.error(err)
|
||||||
}
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -173,55 +225,60 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) {
|
|||||||
Scheme: "VPN",
|
Scheme: "VPN",
|
||||||
}
|
}
|
||||||
fe, err := vpn.NewFrontend(&vpn.FrontendConfig{
|
fe, err := vpn.NewFrontend(&vpn.FrontendConfig{
|
||||||
IdentityName: env.EnvironmentIdentityName(),
|
IdentityName: root.EnvironmentIdentityName(),
|
||||||
ShrToken: args[0],
|
ShrToken: args[0],
|
||||||
RequestsChan: requests,
|
RequestsChan: requests,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !panicInstead {
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
tui.Error("unable to create private access", err)
|
cmd.error(err)
|
||||||
}
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
if err := fe.Run(); err != nil {
|
if err := fe.Run(); err != nil {
|
||||||
if !panicInstead {
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
tui.Error("error starting access", err)
|
cmd.error(err)
|
||||||
}
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
default:
|
default:
|
||||||
cfg := proxy.DefaultFrontendConfig(env.EnvironmentIdentityName())
|
cfg := proxy.DefaultFrontendConfig(root.EnvironmentIdentityName())
|
||||||
cfg.ShrToken = shrToken
|
cfg.ShrToken = shrToken
|
||||||
cfg.Address = cmd.bindAddress
|
cfg.Address = bindAddress
|
||||||
cfg.ResponseHeaders = cmd.responseHeaders
|
cfg.ResponseHeaders = cmd.responseHeaders
|
||||||
cfg.RequestsChan = requests
|
cfg.RequestsChan = requests
|
||||||
fe, err := proxy.NewFrontend(cfg)
|
fe, err := proxy.NewFrontend(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !panicInstead {
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
tui.Error("unable to create private frontend", err)
|
cmd.error(err)
|
||||||
}
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
go func() {
|
go func() {
|
||||||
if err := fe.Run(); err != nil {
|
if err := fe.Run(); err != nil {
|
||||||
if !panicInstead {
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
tui.Error("unable to run frontend", err)
|
cmd.error(err)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
c := make(chan os.Signal)
|
c := make(chan os.Signal)
|
||||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(c, os.Interrupt, os.Kill, syscall.SIGHUP, syscall.SIGTERM, syscall.SIGKILL, syscall.SIGQUIT)
|
||||||
go func() {
|
go func() {
|
||||||
<-c
|
<-c
|
||||||
cmd.destroy(accessResp.Payload.FrontendToken, env.Environment().ZitiIdentity, shrToken, zrok, auth)
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
if cmd.subordinate {
|
||||||
|
data := make(map[string]interface{})
|
||||||
|
data[subordinate.MessageKey] = subordinate.BootMessage
|
||||||
|
data["frontend_token"] = accessResp.Payload.FrontendToken
|
||||||
|
data["bind_address"] = bindAddress
|
||||||
|
jsonData, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
subordinateError(err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(jsonData))
|
||||||
|
}
|
||||||
|
|
||||||
if cmd.headless {
|
if cmd.headless {
|
||||||
logrus.Infof("access the zrok share at the following endpoint: %v", endpointUrl.String())
|
logrus.Infof("access the zrok share at the following endpoint: %v", endpointUrl.String())
|
||||||
for {
|
for {
|
||||||
@ -230,7 +287,22 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) {
|
|||||||
logrus.Infof("%v -> %v %v", req.RemoteAddr, req.Method, req.Path)
|
logrus.Infof("%v -> %v %v", req.RemoteAddr, req.Method, req.Path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if cmd.subordinate {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case req := <-requests:
|
||||||
|
data := make(map[string]interface{})
|
||||||
|
data[subordinate.MessageKey] = "access"
|
||||||
|
data["remote-address"] = req.RemoteAddr
|
||||||
|
data["method"] = req.Method
|
||||||
|
data["path"] = req.Path
|
||||||
|
jsonData, err := json.Marshal(data)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
fmt.Println(string(jsonData))
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mdl := newAccessModel(shrToken, endpointUrl.String())
|
mdl := newAccessModel(shrToken, endpointUrl.String())
|
||||||
logrus.SetOutput(mdl)
|
logrus.SetOutput(mdl)
|
||||||
@ -253,21 +325,56 @@ func (cmd *accessPrivateCommand) run(_ *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
close(requests)
|
close(requests)
|
||||||
cmd.destroy(accessResp.Payload.FrontendToken, env.Environment().ZitiIdentity, shrToken, zrok, auth)
|
cmd.shutdown(accessResp.Payload.FrontendToken, root.Environment().ZitiIdentity, shrToken, zrok, auth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *accessPrivateCommand) destroy(frontendName, envZId, shrToken string, zrok *rest_client_zrok.Zrok, auth runtime.ClientAuthInfoWriter) {
|
func (cmd *accessPrivateCommand) error(err error) {
|
||||||
logrus.Debugf("shutting down '%v'", shrToken)
|
if cmd.subordinate {
|
||||||
req := share.NewUnaccessParams()
|
subordinateError(err)
|
||||||
req.Body = &rest_model_zrok.UnaccessRequest{
|
|
||||||
FrontendToken: frontendName,
|
|
||||||
ShrToken: shrToken,
|
|
||||||
EnvZID: envZId,
|
|
||||||
}
|
}
|
||||||
|
if !panicInstead {
|
||||||
|
tui.Error("unable to create private access", err)
|
||||||
|
}
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *accessPrivateCommand) shutdown(frontendToken, envZId, shrToken string, zrok *rest_client_zrok.Zrok, auth runtime.ClientAuthInfoWriter) {
|
||||||
|
logrus.Infof("shutting down '%v'", shrToken)
|
||||||
|
req := share.NewUnaccessParams()
|
||||||
|
req.Body.FrontendToken = frontendToken
|
||||||
|
req.Body.ShareToken = shrToken
|
||||||
|
req.Body.EnvZID = envZId
|
||||||
if _, err := zrok.Share.Unaccess(req, auth); err == nil {
|
if _, err := zrok.Share.Unaccess(req, auth); err == nil {
|
||||||
logrus.Debugf("shutdown complete")
|
logrus.Debugf("shutdown complete")
|
||||||
} else {
|
} else {
|
||||||
logrus.Errorf("error shutting down: %v", err)
|
logrus.Errorf("error shutting down: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cmd *accessPrivateCommand) accessAgent(args []string, root env_core.Root) {
|
||||||
|
client, conn, err := agentClient.NewClient(root)
|
||||||
|
if err != nil {
|
||||||
|
tui.Error("error connecting to agent", err)
|
||||||
|
}
|
||||||
|
defer func() { _ = conn.Close() }()
|
||||||
|
|
||||||
|
req := &agentGrpc.AccessPrivateRequest{
|
||||||
|
Token: args[0],
|
||||||
|
BindAddress: cmd.bindAddress,
|
||||||
|
ResponseHeaders: cmd.responseHeaders,
|
||||||
|
}
|
||||||
|
if cmd.autoMode {
|
||||||
|
req.AutoMode = true
|
||||||
|
req.AutoAddress = cmd.autoAddress
|
||||||
|
req.AutoStartPort = uint32(cmd.autoStartPort)
|
||||||
|
req.AutoEndPort = uint32(cmd.autoEndPort)
|
||||||
|
}
|
||||||
|
|
||||||
|
acc, err := client.AccessPrivate(context.Background(), req)
|
||||||
|
if err != nil {
|
||||||
|
tui.Error("error creating access", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(acc)
|
||||||
|
}
|
||||||
|
@ -46,5 +46,5 @@ func (cmd *adminCreateAccount) run(_ *cobra.Command, args []string) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(resp.GetPayload().Token)
|
fmt.Println(resp.GetPayload().AccountToken)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openziti/zrok/environment"
|
"github.com/openziti/zrok/environment"
|
||||||
"github.com/openziti/zrok/rest_client_zrok/admin"
|
"github.com/openziti/zrok/rest_client_zrok/admin"
|
||||||
"github.com/openziti/zrok/rest_model_zrok"
|
|
||||||
"github.com/openziti/zrok/sdk/golang/sdk"
|
"github.com/openziti/zrok/sdk/golang/sdk"
|
||||||
"github.com/openziti/zrok/tui"
|
"github.com/openziti/zrok/tui"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -52,12 +51,10 @@ func (cmd *adminCreateFrontendCommand) run(_ *cobra.Command, args []string) {
|
|||||||
permissionMode = sdk.ClosedPermissionMode
|
permissionMode = sdk.ClosedPermissionMode
|
||||||
}
|
}
|
||||||
req := admin.NewCreateFrontendParams()
|
req := admin.NewCreateFrontendParams()
|
||||||
req.Body = &rest_model_zrok.CreateFrontendRequest{
|
req.Body.ZID = zId
|
||||||
ZID: zId,
|
req.Body.PublicName = publicName
|
||||||
PublicName: publicName,
|
req.Body.URLTemplate = urlTemplate
|
||||||
URLTemplate: urlTemplate,
|
req.Body.PermissionMode = string(permissionMode)
|
||||||
PermissionMode: string(permissionMode),
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := zrok.Admin.CreateFrontend(req, mustGetAdminAuth())
|
resp, err := zrok.Admin.CreateFrontend(req, mustGetAdminAuth())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -71,5 +68,5 @@ func (cmd *adminCreateFrontendCommand) run(_ *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Infof("created global public frontend '%v'", resp.Payload.Token)
|
logrus.Infof("created global public frontend '%v'", resp.Payload.FrontendToken)
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ func (cmd *adminCreateOrgMemberCommand) run(_ *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
req := admin.NewAddOrganizationMemberParams()
|
req := admin.NewAddOrganizationMemberParams()
|
||||||
req.Body.Token = args[0]
|
req.Body.OrganizationToken = args[0]
|
||||||
req.Body.Email = args[1]
|
req.Body.Email = args[1]
|
||||||
req.Body.Admin = cmd.admin
|
req.Body.Admin = cmd.admin
|
||||||
|
|
||||||
|
@ -48,5 +48,5 @@ func (cmd *adminCreateOrganizationCommand) run(_ *cobra.Command, _ []string) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Infof("created new organization with token '%v'", resp.Payload.Token)
|
logrus.Infof("created new organization with organization token '%v'", resp.Payload.OrganizationToken)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openziti/zrok/environment"
|
"github.com/openziti/zrok/environment"
|
||||||
"github.com/openziti/zrok/rest_client_zrok/admin"
|
"github.com/openziti/zrok/rest_client_zrok/admin"
|
||||||
"github.com/openziti/zrok/rest_model_zrok"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@ -41,7 +40,7 @@ func (cmd *adminDeleteFrontendCommand) run(_ *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
req := admin.NewDeleteFrontendParams()
|
req := admin.NewDeleteFrontendParams()
|
||||||
req.Body = &rest_model_zrok.DeleteFrontendRequest{FrontendToken: feToken}
|
req.Body.FrontendToken = feToken
|
||||||
|
|
||||||
_, err = zrok.Admin.DeleteFrontend(req, mustGetAdminAuth())
|
_, err = zrok.Admin.DeleteFrontend(req, mustGetAdminAuth())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -39,7 +39,7 @@ func (cmd *adminDeleteOrgMemberCommand) run(_ *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
req := admin.NewRemoveOrganizationMemberParams()
|
req := admin.NewRemoveOrganizationMemberParams()
|
||||||
req.Body.Token = args[0]
|
req.Body.OrganizationToken = args[0]
|
||||||
req.Body.Email = args[1]
|
req.Body.Email = args[1]
|
||||||
|
|
||||||
_, err = zrok.Admin.RemoveOrganizationMember(req, mustGetAdminAuth())
|
_, err = zrok.Admin.RemoveOrganizationMember(req, mustGetAdminAuth())
|
||||||
|
@ -39,7 +39,7 @@ func (cmd *adminDeleteOrganizationCommand) run(_ *cobra.Command, args []string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
req := admin.NewDeleteOrganizationParams()
|
req := admin.NewDeleteOrganizationParams()
|
||||||
req.Body.Token = args[0]
|
req.Body.OrganizationToken = args[0]
|
||||||
|
|
||||||
_, err = zrok.Admin.DeleteOrganization(req, mustGetAdminAuth())
|
_, err = zrok.Admin.DeleteOrganization(req, mustGetAdminAuth())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"github.com/jaevor/go-nanoid"
|
"github.com/jaevor/go-nanoid"
|
||||||
"github.com/openziti/zrok/environment"
|
"github.com/openziti/zrok/environment"
|
||||||
"github.com/openziti/zrok/rest_client_zrok/admin"
|
"github.com/openziti/zrok/rest_client_zrok/admin"
|
||||||
"github.com/openziti/zrok/rest_model_zrok"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@ -54,9 +53,8 @@ func (cmd *adminGenerateCommand) run(_ *cobra.Command, args []string) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
req := admin.NewInviteTokenGenerateParams()
|
req := admin.NewInviteTokenGenerateParams()
|
||||||
req.Body = &rest_model_zrok.InviteTokenGenerateRequest{
|
req.Body.InviteTokens = tokens
|
||||||
Tokens: tokens,
|
|
||||||
}
|
|
||||||
_, err = zrok.Admin.InviteTokenGenerate(req, mustGetAdminAuth())
|
_, err = zrok.Admin.InviteTokenGenerate(req, mustGetAdminAuth())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !panicInstead {
|
if !panicInstead {
|
||||||
|
@ -54,7 +54,7 @@ func (cmd *adminListFrontendsCommand) run(_ *cobra.Command, _ []string) {
|
|||||||
t.AppendHeader(table.Row{"Token", "zId", "Public Name", "Url Template", "Created At", "Updated At"})
|
t.AppendHeader(table.Row{"Token", "zId", "Public Name", "Url Template", "Created At", "Updated At"})
|
||||||
for _, pfe := range resp.Payload {
|
for _, pfe := range resp.Payload {
|
||||||
t.AppendRow(table.Row{
|
t.AppendRow(table.Row{
|
||||||
pfe.Token,
|
pfe.FrontendToken,
|
||||||
pfe.ZID,
|
pfe.ZID,
|
||||||
pfe.PublicName,
|
pfe.PublicName,
|
||||||
pfe.URLTemplate,
|
pfe.URLTemplate,
|
||||||
|
@ -41,7 +41,7 @@ func (cmd *adminListOrgMembersCommand) run(_ *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
req := admin.NewListOrganizationMembersParams()
|
req := admin.NewListOrganizationMembersParams()
|
||||||
req.Body.Token = args[0]
|
req.Body.OrganizationToken = args[0]
|
||||||
|
|
||||||
resp, err := zrok.Admin.ListOrganizationMembers(req, mustGetAdminAuth())
|
resp, err := zrok.Admin.ListOrganizationMembers(req, mustGetAdminAuth())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -52,7 +52,7 @@ func (c *adminListOrganizationsCommand) run(_ *cobra.Command, _ []string) {
|
|||||||
t.SetStyle(table.StyleColoredDark)
|
t.SetStyle(table.StyleColoredDark)
|
||||||
t.AppendHeader(table.Row{"Organization Token", "Description"})
|
t.AppendHeader(table.Row{"Organization Token", "Description"})
|
||||||
for _, org := range resp.Payload.Organizations {
|
for _, org := range resp.Payload.Organizations {
|
||||||
t.AppendRow(table.Row{org.Token, org.Description})
|
t.AppendRow(table.Row{org.OrganizationToken, org.Description})
|
||||||
}
|
}
|
||||||
t.Render()
|
t.Render()
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
|
@ -33,7 +33,12 @@ func (cmd *adminMigrate) run(_ *cobra.Command, args []string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
logrus.Info(cf.Dump(inCfg, cf.DefaultOptions()))
|
logrus.Info(cf.Dump(inCfg, cf.DefaultOptions()))
|
||||||
|
|
||||||
|
// override the 'disable_auto_migration' setting... the user is requesting a migration here.
|
||||||
|
inCfg.Store.DisableAutoMigration = false
|
||||||
|
|
||||||
if _, err := store.Open(inCfg.Store); err != nil {
|
if _, err := store.Open(inCfg.Store); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"github.com/openziti/zrok/environment"
|
"github.com/openziti/zrok/environment"
|
||||||
"github.com/openziti/zrok/rest_client_zrok/admin"
|
"github.com/openziti/zrok/rest_client_zrok/admin"
|
||||||
"github.com/openziti/zrok/rest_model_zrok"
|
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@ -49,11 +48,9 @@ func (cmd *adminUpdateFrontendCommand) run(_ *cobra.Command, args []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
req := admin.NewUpdateFrontendParams()
|
req := admin.NewUpdateFrontendParams()
|
||||||
req.Body = &rest_model_zrok.UpdateFrontendRequest{
|
req.Body.FrontendToken = feToken
|
||||||
FrontendToken: feToken,
|
req.Body.PublicName = cmd.newPublicName
|
||||||
PublicName: cmd.newPublicName,
|
req.Body.URLTemplate = cmd.newUrlTemplate
|
||||||
URLTemplate: cmd.newUrlTemplate,
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = zrok.Admin.UpdateFrontend(req, mustGetAdminAuth())
|
_, err = zrok.Admin.UpdateFrontend(req, mustGetAdminAuth())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
52
cmd/zrok/agentConsole.go
Normal file
52
cmd/zrok/agentConsole.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/openziti/zrok/agent/agentClient"
|
||||||
|
"github.com/openziti/zrok/agent/agentGrpc"
|
||||||
|
"github.com/openziti/zrok/environment"
|
||||||
|
"github.com/openziti/zrok/tui"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
agentCmd.AddCommand(newAgentConsoleCommand().cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
type agentConsoleCommand struct {
|
||||||
|
cmd *cobra.Command
|
||||||
|
}
|
||||||
|
|
||||||
|
func newAgentConsoleCommand() *agentConsoleCommand {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "console",
|
||||||
|
Short: "Open the Agent console",
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
}
|
||||||
|
command := &agentConsoleCommand{cmd}
|
||||||
|
cmd.Run = command.run
|
||||||
|
return command
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *agentConsoleCommand) run(_ *cobra.Command, _ []string) {
|
||||||
|
root, err := environment.LoadRoot()
|
||||||
|
if err != nil {
|
||||||
|
tui.Error("error loading zrokdir", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client, conn, err := agentClient.NewClient(root)
|
||||||
|
if err != nil {
|
||||||
|
tui.Error("error connecting to agent", err)
|
||||||
|
}
|
||||||
|
defer func() { _ = conn.Close() }()
|
||||||
|
|
||||||
|
v, err := client.Version(context.Background(), &agentGrpc.VersionRequest{})
|
||||||
|
if err != nil {
|
||||||
|
tui.Error("error getting agent version", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := openBrowser("http://" + v.ConsoleEndpoint); err != nil {
|
||||||
|
tui.Error(fmt.Sprintf("unable to open agent console at 'http://%v'", v.ConsoleEndpoint), err)
|
||||||
|
}
|
||||||
|
}
|
55
cmd/zrok/agentReleaseAccess.go
Normal file
55
cmd/zrok/agentReleaseAccess.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/openziti/zrok/agent/agentClient"
|
||||||
|
"github.com/openziti/zrok/agent/agentGrpc"
|
||||||
|
"github.com/openziti/zrok/environment"
|
||||||
|
"github.com/openziti/zrok/tui"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
agentReleaseCmd.AddCommand(newAgentReleaseAccessCommand().cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
type agentReleaseAccessCommand struct {
|
||||||
|
cmd *cobra.Command
|
||||||
|
}
|
||||||
|
|
||||||
|
func newAgentReleaseAccessCommand() *agentReleaseAccessCommand {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "access <frontendToken>",
|
||||||
|
Short: "Unbind an access from the zrok Agent",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
}
|
||||||
|
command := &agentReleaseAccessCommand{cmd: cmd}
|
||||||
|
cmd.Run = command.run
|
||||||
|
return command
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *agentReleaseAccessCommand) run(_ *cobra.Command, args []string) {
|
||||||
|
root, err := environment.LoadRoot()
|
||||||
|
if err != nil {
|
||||||
|
if !panicInstead {
|
||||||
|
tui.Error("unable to load environment", err)
|
||||||
|
}
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client, conn, err := agentClient.NewClient(root)
|
||||||
|
if err != nil {
|
||||||
|
tui.Error("error connecting to agent", err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
_, err = client.ReleaseAccess(context.Background(), &agentGrpc.ReleaseAccessRequest{
|
||||||
|
FrontendToken: args[0],
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
tui.Error("error releasing access", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("success.")
|
||||||
|
}
|
55
cmd/zrok/agentReleaseShare.go
Executable file
55
cmd/zrok/agentReleaseShare.go
Executable file
@ -0,0 +1,55 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/openziti/zrok/agent/agentClient"
|
||||||
|
"github.com/openziti/zrok/agent/agentGrpc"
|
||||||
|
"github.com/openziti/zrok/environment"
|
||||||
|
"github.com/openziti/zrok/tui"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
agentReleaseCmd.AddCommand(newAgentReleaseShareCommand().cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
type agentReleaseShareCommand struct {
|
||||||
|
cmd *cobra.Command
|
||||||
|
}
|
||||||
|
|
||||||
|
func newAgentReleaseShareCommand() *agentReleaseShareCommand {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "share <token>",
|
||||||
|
Short: "Release a share from the zrok Agent",
|
||||||
|
Args: cobra.ExactArgs(1),
|
||||||
|
}
|
||||||
|
command := &agentReleaseShareCommand{cmd: cmd}
|
||||||
|
cmd.Run = command.run
|
||||||
|
return command
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *agentReleaseShareCommand) run(_ *cobra.Command, args []string) {
|
||||||
|
root, err := environment.LoadRoot()
|
||||||
|
if err != nil {
|
||||||
|
if !panicInstead {
|
||||||
|
tui.Error("unable to load environment", err)
|
||||||
|
}
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client, conn, err := agentClient.NewClient(root)
|
||||||
|
if err != nil {
|
||||||
|
tui.Error("error connecting to agent", err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
_, err = client.ReleaseShare(context.Background(), &agentGrpc.ReleaseShareRequest{
|
||||||
|
Token: args[0],
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
tui.Error("error releasing share", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("success.")
|
||||||
|
}
|
72
cmd/zrok/agentStart.go
Normal file
72
cmd/zrok/agentStart.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/openziti/zrok/agent"
|
||||||
|
"github.com/openziti/zrok/environment"
|
||||||
|
"github.com/openziti/zrok/tui"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
agentCmd.AddCommand(newAgentStartCommand().cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
type agentStartCommand struct {
|
||||||
|
cmd *cobra.Command
|
||||||
|
consoleAddress string
|
||||||
|
consoleStartPort uint16
|
||||||
|
consoleEndPort uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
func newAgentStartCommand() *agentStartCommand {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "start",
|
||||||
|
Short: "Start a zrok agent",
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
}
|
||||||
|
command := &agentStartCommand{cmd: cmd}
|
||||||
|
cmd.Run = command.run
|
||||||
|
cmd.Flags().StringVar(&command.consoleAddress, "console-address", "127.0.0.1", "gRPC gateway address")
|
||||||
|
cmd.Flags().Uint16Var(&command.consoleStartPort, "console-start-port", 8888, "gRPC gateway starting port")
|
||||||
|
cmd.Flags().Uint16Var(&command.consoleEndPort, "console-end-port", 8988, "gRPC gateway ending port")
|
||||||
|
return command
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *agentStartCommand) run(_ *cobra.Command, _ []string) {
|
||||||
|
root, err := environment.LoadRoot()
|
||||||
|
if err != nil {
|
||||||
|
tui.Error("error loading zrokdir", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !root.IsEnabled() {
|
||||||
|
tui.Error("unable to load environment; did you 'zrok enable'?", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg := agent.DefaultConfig()
|
||||||
|
cfg.ConsoleAddress = cmd.consoleAddress
|
||||||
|
cfg.ConsoleStartPort = cmd.consoleStartPort
|
||||||
|
cfg.ConsoleEndPort = cmd.consoleEndPort
|
||||||
|
a, err := agent.NewAgent(cfg, root)
|
||||||
|
if err != nil {
|
||||||
|
tui.Error("error creating agent", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c := make(chan os.Signal)
|
||||||
|
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||||
|
go func() {
|
||||||
|
<-c
|
||||||
|
cmd.shutdown(a)
|
||||||
|
os.Exit(0)
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err := a.Run(); err != nil {
|
||||||
|
tui.Error("agent aborted", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cmd *agentStartCommand) shutdown(a *agent.Agent) {
|
||||||
|
a.Shutdown()
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user