Compare commits
No commits in common. "main" and "webrtc-transport" have entirely different histories.
main
...
webrtc-tra
|
|
@ -1,3 +1,6 @@
|
||||||
|
[target.'cfg(unix)']
|
||||||
|
runner = "sudo -E"
|
||||||
|
|
||||||
[alias] # command aliases
|
[alias] # command aliases
|
||||||
rr = "run --release"
|
rr = "run --release"
|
||||||
bb = "build --release"
|
bb = "build --release"
|
||||||
|
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
name: Build Rust
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- "**"
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
rust:
|
|
||||||
name: Cargo Test
|
|
||||||
runs-on: [self-hosted, linux, x86_64, burrow-forge]
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
repo_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git"
|
|
||||||
if [ ! -d .git ]; then
|
|
||||||
git init .
|
|
||||||
fi
|
|
||||||
if git remote get-url origin >/dev/null 2>&1; then
|
|
||||||
git remote set-url origin "${repo_url}"
|
|
||||||
else
|
|
||||||
git remote add origin "${repo_url}"
|
|
||||||
fi
|
|
||||||
git fetch --force --tags origin "${GITHUB_SHA}"
|
|
||||||
git checkout --force --detach FETCH_HEAD
|
|
||||||
git clean -ffdqx
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
nix develop .#ci -c cargo test --workspace --all-features
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
name: Build Site
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- "**"
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
site:
|
|
||||||
name: Next.js Build
|
|
||||||
runs-on: [self-hosted, linux, x86_64, burrow-forge]
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
repo_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git"
|
|
||||||
if [ ! -d .git ]; then
|
|
||||||
git init .
|
|
||||||
fi
|
|
||||||
if git remote get-url origin >/dev/null 2>&1; then
|
|
||||||
git remote set-url origin "${repo_url}"
|
|
||||||
else
|
|
||||||
git remote add origin "${repo_url}"
|
|
||||||
fi
|
|
||||||
git fetch --force --tags origin "${GITHUB_SHA}"
|
|
||||||
git checkout --force --detach FETCH_HEAD
|
|
||||||
git clean -ffdqx
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
nix develop .#ci -c bash -lc 'cd site && npm ci --no-audit --no-fund && npm run build'
|
|
||||||
|
|
@ -1,38 +0,0 @@
|
||||||
name: Lint Governance
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- "**"
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
governance:
|
|
||||||
name: BEP Metadata
|
|
||||||
runs-on: [self-hosted, linux, x86_64, burrow-forge]
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
repo_url="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git"
|
|
||||||
if [ ! -d .git ]; then
|
|
||||||
git init .
|
|
||||||
fi
|
|
||||||
if git remote get-url origin >/dev/null 2>&1; then
|
|
||||||
git remote set-url origin "${repo_url}"
|
|
||||||
else
|
|
||||||
git remote add origin "${repo_url}"
|
|
||||||
fi
|
|
||||||
git fetch --force --tags origin "${GITHUB_SHA}"
|
|
||||||
git checkout --force --detach FETCH_HEAD
|
|
||||||
git clean -ffdqx
|
|
||||||
|
|
||||||
- name: Validate BEP metadata
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
python3 Scripts/check-bep-metadata.py
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
name: Release
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- "v*"
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: false
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
name: Release Build
|
|
||||||
runs-on: namespace-profile-linux-medium
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: https://code.forgejo.org/actions/checkout@v4
|
|
||||||
with:
|
|
||||||
token: ${{ github.token }}
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Bootstrap Nix
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
chmod +x Scripts/ci/ensure-nix.sh
|
|
||||||
Scripts/ci/ensure-nix.sh
|
|
||||||
|
|
||||||
- name: Build release artifacts
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
RELEASE_REF: ${{ github.ref_name }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
ref="${RELEASE_REF:-manual-${GITHUB_SHA::7}}"
|
|
||||||
export RELEASE_REF="${ref}"
|
|
||||||
chmod +x Scripts/ci/build-release-artifacts.sh
|
|
||||||
nix develop .#ci -c Scripts/ci/build-release-artifacts.sh
|
|
||||||
|
|
||||||
- name: Upload release artifacts
|
|
||||||
uses: https://code.forgejo.org/actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: burrow-release-${{ github.ref_name }}
|
|
||||||
path: dist/*
|
|
||||||
if-no-files-found: error
|
|
||||||
|
|
||||||
- name: Publish Forgejo release
|
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
RELEASE_TAG: ${{ github.ref_name }}
|
|
||||||
API_URL: ${{ github.api_url }}
|
|
||||||
REPOSITORY: ${{ github.repository }}
|
|
||||||
TOKEN: ${{ github.token }}
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
chmod +x Scripts/ci/publish-forgejo-release.sh
|
|
||||||
nix develop .#ci -c Scripts/ci/publish-forgejo-release.sh
|
|
||||||
1
.github/actions/archive/action.yml
vendored
|
|
@ -35,6 +35,7 @@ runs:
|
||||||
-authenticationKeyID ${{ inputs.app-store-key-id }} \
|
-authenticationKeyID ${{ inputs.app-store-key-id }} \
|
||||||
-authenticationKeyIssuerID ${{ inputs.app-store-key-issuer-id }} \
|
-authenticationKeyIssuerID ${{ inputs.app-store-key-issuer-id }} \
|
||||||
-authenticationKeyPath "${PWD}/AuthKey_${{ inputs.app-store-key-id }}.p8" \
|
-authenticationKeyPath "${PWD}/AuthKey_${{ inputs.app-store-key-id }}.p8" \
|
||||||
|
-onlyUsePackageVersionsFromResolvedFile \
|
||||||
-scheme '${{ inputs.scheme }}' \
|
-scheme '${{ inputs.scheme }}' \
|
||||||
-destination '${{ inputs.destination }}' \
|
-destination '${{ inputs.destination }}' \
|
||||||
-archivePath '${{ inputs.archive-path }}' \
|
-archivePath '${{ inputs.archive-path }}' \
|
||||||
|
|
|
||||||
2
.github/actions/build-for-testing/action.yml
vendored
|
|
@ -27,9 +27,7 @@ runs:
|
||||||
Apple/DerivedData
|
Apple/DerivedData
|
||||||
key: ${{ runner.os }}-${{ inputs.scheme }}-${{ hashFiles('**/Package.resolved') }}
|
key: ${{ runner.os }}-${{ inputs.scheme }}-${{ hashFiles('**/Package.resolved') }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-${{ inputs.scheme }}-${{ hashFiles('**/Package.resolved') }}
|
|
||||||
${{ runner.os }}-${{ inputs.scheme }}-
|
${{ runner.os }}-${{ inputs.scheme }}-
|
||||||
${{ runner.os }}-
|
|
||||||
- name: Build
|
- name: Build
|
||||||
shell: bash
|
shell: bash
|
||||||
working-directory: Apple
|
working-directory: Apple
|
||||||
|
|
|
||||||
30
.github/actions/download-profiles/action.yml
vendored
|
|
@ -1,30 +0,0 @@
|
||||||
name: Download Provisioning Profiles
|
|
||||||
inputs:
|
|
||||||
app-store-key:
|
|
||||||
description: App Store key in PEM PKCS#8 format
|
|
||||||
required: true
|
|
||||||
app-store-key-id:
|
|
||||||
description: App Store key ID
|
|
||||||
required: true
|
|
||||||
app-store-key-issuer-id:
|
|
||||||
description: App Store key issuer ID
|
|
||||||
required: true
|
|
||||||
runs:
|
|
||||||
using: composite
|
|
||||||
steps:
|
|
||||||
- shell: bash
|
|
||||||
env:
|
|
||||||
FASTLANE_OPT_OUT_USAGE: 'YES'
|
|
||||||
run: |
|
|
||||||
APP_STORE_KEY=$(echo "${{ inputs.app-store-key }}" | jq -sR .)
|
|
||||||
cat << EOF > api-key.json
|
|
||||||
{
|
|
||||||
"key_id": "${{ inputs.app-store-key-id }}",
|
|
||||||
"issuer_id": "${{ inputs.app-store-key-issuer-id }}",
|
|
||||||
"key": $APP_STORE_KEY
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
fastlane sigh download_all --api_key_path api-key.json
|
|
||||||
|
|
||||||
rm -rf api-key.json
|
|
||||||
10
.github/actions/export/action.yml
vendored
|
|
@ -12,8 +12,11 @@ inputs:
|
||||||
archive-path:
|
archive-path:
|
||||||
description: Xcode archive path
|
description: Xcode archive path
|
||||||
required: true
|
required: true
|
||||||
export-options:
|
destination:
|
||||||
description: The export options in JSON format
|
description: The Xcode export destination. This can either be "export" or "upload"
|
||||||
|
required: true
|
||||||
|
method:
|
||||||
|
description: The Xcode export method. This can be one of app-store, validation, ad-hoc, package, enterprise, development, developer-id, or mac-application.
|
||||||
required: true
|
required: true
|
||||||
export-path:
|
export-path:
|
||||||
description: The path to export the archive to
|
description: The path to export the archive to
|
||||||
|
|
@ -26,7 +29,8 @@ runs:
|
||||||
run: |
|
run: |
|
||||||
echo "${{ inputs.app-store-key }}" > AuthKey_${{ inputs.app-store-key-id }}.p8
|
echo "${{ inputs.app-store-key }}" > AuthKey_${{ inputs.app-store-key-id }}.p8
|
||||||
|
|
||||||
echo '${{ inputs.export-options }}' | plutil -convert xml1 -o ExportOptions.plist -
|
echo '{"destination":"${{ inputs.destination }}","method":"${{ inputs.method }}"}' \
|
||||||
|
| plutil -convert xml1 -o ExportOptions.plist -
|
||||||
|
|
||||||
xcodebuild \
|
xcodebuild \
|
||||||
-exportArchive \
|
-exportArchive \
|
||||||
|
|
|
||||||
41
.github/actions/notarize/action.yml
vendored
|
|
@ -9,6 +9,16 @@ inputs:
|
||||||
app-store-key-issuer-id:
|
app-store-key-issuer-id:
|
||||||
description: App Store key issuer ID
|
description: App Store key issuer ID
|
||||||
required: true
|
required: true
|
||||||
|
archive-path:
|
||||||
|
description: Xcode archive path
|
||||||
|
required: true
|
||||||
|
export-path:
|
||||||
|
description: The path to export the archive to
|
||||||
|
required: true
|
||||||
|
outputs:
|
||||||
|
notarized-app:
|
||||||
|
description: The compressed and notarized app
|
||||||
|
value: ${{ steps.notarize.outputs.notarized-app }}
|
||||||
runs:
|
runs:
|
||||||
using: composite
|
using: composite
|
||||||
steps:
|
steps:
|
||||||
|
|
@ -18,8 +28,31 @@ runs:
|
||||||
run: |
|
run: |
|
||||||
echo "${{ inputs.app-store-key }}" > AuthKey_${{ inputs.app-store-key-id }}.p8
|
echo "${{ inputs.app-store-key }}" > AuthKey_${{ inputs.app-store-key-id }}.p8
|
||||||
|
|
||||||
ditto -c -k --keepParent Release/Burrow.app Upload.zip
|
echo '{"destination":"upload","method":"developer-id"}' \
|
||||||
xcrun notarytool submit --wait --issuer ${{ inputs.app-store-key-issuer-id }} --key-id ${{ inputs.app-store-key-id }} --key "${PWD}/AuthKey_${{ inputs.app-store-key-id }}.p8" Upload.zip
|
| plutil -convert xml1 -o ExportOptions.plist -
|
||||||
xcrun stapler staple Release/Burrow.app
|
|
||||||
|
|
||||||
rm -rf AuthKey_${{ inputs.app-store-key-id }}.p8 Release
|
xcodebuild \
|
||||||
|
-exportArchive \
|
||||||
|
-allowProvisioningUpdates \
|
||||||
|
-allowProvisioningDeviceRegistration \
|
||||||
|
-authenticationKeyID ${{ inputs.app-store-key-id }} \
|
||||||
|
-authenticationKeyIssuerID ${{ inputs.app-store-key-issuer-id }} \
|
||||||
|
-authenticationKeyPath "${PWD}/AuthKey_${{ inputs.app-store-key-id }}.p8" \
|
||||||
|
-archivePath '${{ inputs.archive-path }}' \
|
||||||
|
-exportOptionsPlist ExportOptions.plist
|
||||||
|
|
||||||
|
until xcodebuild \
|
||||||
|
-exportNotarizedApp \
|
||||||
|
-allowProvisioningUpdates \
|
||||||
|
-allowProvisioningDeviceRegistration \
|
||||||
|
-authenticationKeyID ${{ inputs.app-store-key-id }} \
|
||||||
|
-authenticationKeyIssuerID ${{ inputs.app-store-key-issuer-id }} \
|
||||||
|
-authenticationKeyPath "${PWD}/AuthKey_${{ inputs.app-store-key-id }}.p8" \
|
||||||
|
-archivePath '${{ inputs.archive-path }}' \
|
||||||
|
-exportPath ${{ inputs.export-path }}
|
||||||
|
do
|
||||||
|
echo "Failed to export app, trying again in 10s..."
|
||||||
|
sleep 10
|
||||||
|
done
|
||||||
|
|
||||||
|
rm -rf AuthKey_${{ inputs.app-store-key-id }}.p8 ExportOptions.plist
|
||||||
|
|
|
||||||
3
.github/workflows/build-appimage.yml
vendored
|
|
@ -6,9 +6,6 @@ on:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- "*"
|
- "*"
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
jobs:
|
jobs:
|
||||||
appimage:
|
appimage:
|
||||||
name: Build AppImage
|
name: Build AppImage
|
||||||
|
|
|
||||||
11
.github/workflows/build-apple.yml
vendored
|
|
@ -1,7 +1,7 @@
|
||||||
name: Build Apple Apps
|
name: Build Apple Apps
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
|
|
@ -24,7 +24,7 @@ jobs:
|
||||||
rust-targets:
|
rust-targets:
|
||||||
- aarch64-apple-ios
|
- aarch64-apple-ios
|
||||||
- scheme: App
|
- scheme: App
|
||||||
destination: platform=iOS Simulator,OS=18.0,name=iPhone 15 Pro
|
destination: platform=iOS Simulator,OS=17.2,name=iPhone 15 Pro
|
||||||
platform: iOS Simulator
|
platform: iOS Simulator
|
||||||
sdk-name: iphonesimulator
|
sdk-name: iphonesimulator
|
||||||
rust-targets:
|
rust-targets:
|
||||||
|
|
@ -38,8 +38,7 @@ jobs:
|
||||||
- x86_64-apple-darwin
|
- x86_64-apple-darwin
|
||||||
- aarch64-apple-darwin
|
- aarch64-apple-darwin
|
||||||
env:
|
env:
|
||||||
DEVELOPER_DIR: /Applications/Xcode_16.0.app/Contents/Developer
|
DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer
|
||||||
PROTOC_PATH: /opt/homebrew/bin/protoc
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
@ -54,11 +53,7 @@ jobs:
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-toolchain@stable
|
||||||
with:
|
with:
|
||||||
toolchain: 1.85.0
|
|
||||||
targets: ${{ join(matrix.rust-targets, ', ') }}
|
targets: ${{ join(matrix.rust-targets, ', ') }}
|
||||||
- name: Install Protobuf
|
|
||||||
shell: bash
|
|
||||||
run: brew install protobuf
|
|
||||||
- name: Build
|
- name: Build
|
||||||
id: build
|
id: build
|
||||||
uses: ./.github/actions/build-for-testing
|
uses: ./.github/actions/build-for-testing
|
||||||
|
|
|
||||||
3
.github/workflows/build-docker.yml
vendored
|
|
@ -6,9 +6,6 @@ on:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- "*"
|
- "*"
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build Docker Image
|
name: Build Docker Image
|
||||||
|
|
|
||||||
2
.github/workflows/build-rpm.yml
vendored
|
|
@ -5,7 +5,7 @@ jobs:
|
||||||
name: Build RPM
|
name: Build RPM
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
- uses: Swatinem/rust-cache@v2
|
- uses: Swatinem/rust-cache@v2
|
||||||
- name: Install RPM
|
- name: Install RPM
|
||||||
run: cargo install cargo-generate-rpm
|
run: cargo install cargo-generate-rpm
|
||||||
|
|
|
||||||
30
.github/workflows/build-rust.yml
vendored
|
|
@ -6,9 +6,6 @@ on:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- "*"
|
- "*"
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build Crate (${{ matrix.platform }})
|
name: Build Crate (${{ matrix.platform }})
|
||||||
|
|
@ -24,21 +21,15 @@ jobs:
|
||||||
- x86_64-unknown-linux-gnu
|
- x86_64-unknown-linux-gnu
|
||||||
targets:
|
targets:
|
||||||
- aarch64-unknown-linux-gnu
|
- aarch64-unknown-linux-gnu
|
||||||
- os: macos-13
|
- os: macos-12
|
||||||
platform: macOS (Intel)
|
platform: macOS
|
||||||
xcode: /Applications/Xcode_15.2.app
|
|
||||||
test-targets:
|
test-targets:
|
||||||
- x86_64-apple-darwin
|
- x86_64-apple-darwin
|
||||||
targets:
|
targets:
|
||||||
- x86_64-apple-ios
|
|
||||||
- os: macos-14
|
|
||||||
platform: macOS
|
|
||||||
xcode: /Applications/Xcode_16.0.app
|
|
||||||
test-targets:
|
|
||||||
- aarch64-apple-darwin
|
- aarch64-apple-darwin
|
||||||
targets:
|
|
||||||
- aarch64-apple-ios
|
- aarch64-apple-ios
|
||||||
- aarch64-apple-ios-sim
|
- aarch64-apple-ios-sim
|
||||||
|
- x86_64-apple-ios
|
||||||
- os: windows-2022
|
- os: windows-2022
|
||||||
platform: Windows
|
platform: Windows
|
||||||
test-targets:
|
test-targets:
|
||||||
|
|
@ -47,11 +38,10 @@ jobs:
|
||||||
- aarch64-pc-windows-msvc
|
- aarch64-pc-windows-msvc
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
env:
|
||||||
DEVELOPER_DIR: ${{ matrix.xcode }}/Contents/Developer
|
DEVELOPER_DIR: /Applications/Xcode_14.2.app/Contents/Developer
|
||||||
CARGO_INCREMENTAL: 0
|
CARGO_INCREMENTAL: 0
|
||||||
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
|
CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
|
||||||
RUST_BACKTRACE: short
|
RUST_BACKTRACE: short
|
||||||
PROTOC_VERSION: 3.25.1
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
@ -64,25 +54,21 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y ${{ join(matrix.packages, ' ') }}
|
sudo apt-get install -y ${{ join(matrix.packages, ' ') }}
|
||||||
- name: Configure LLVM
|
- name: Install Windows Deps
|
||||||
if: matrix.os == 'windows-2022'
|
if: matrix.os == 'windows-2022'
|
||||||
shell: bash
|
shell: bash
|
||||||
run: echo "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin" >> $GITHUB_PATH
|
run: echo "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\Llvm\x64\bin" >> $GITHUB_PATH
|
||||||
- name: Install protoc
|
|
||||||
uses: taiki-e/install-action@v2
|
|
||||||
with:
|
|
||||||
tool: protoc@${{ env.PROTOC_VERSION }}
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-toolchain@stable
|
||||||
with:
|
with:
|
||||||
toolchain: 1.85.0
|
toolchain: stable
|
||||||
components: rustfmt
|
components: rustfmt
|
||||||
targets: ${{ join(matrix.targets, ', ') }}
|
targets: ${{ join(matrix.targets, ', ') }}
|
||||||
- name: Setup Rust Cache
|
- name: Setup Rust Cache
|
||||||
uses: Swatinem/rust-cache@v2
|
uses: Swatinem/rust-cache@v2
|
||||||
- name: Build
|
- name: Build
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cargo build --locked --verbose --workspace --all-features --target ${{ join(matrix.targets, ' --target ') }} --target ${{ join(matrix.test-targets, ' --target ') }}
|
run: cargo build --verbose --workspace --all-features --target ${{ join(matrix.targets, ' --target ') }} --target ${{ join(matrix.test-targets, ' --target ') }}
|
||||||
- name: Test
|
- name: Test
|
||||||
shell: bash
|
shell: bash
|
||||||
run: cargo test --locked --verbose --workspace --all-features --target ${{ join(matrix.test-targets, ' --target ') }}
|
run: cargo test --verbose --workspace --all-features --target ${{ join(matrix.test-targets, ' --target ') }}
|
||||||
|
|
|
||||||
23
.github/workflows/lint-governance.yml
vendored
|
|
@ -1,23 +0,0 @@
|
||||||
name: Governance Lint
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- "*"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
governance:
|
|
||||||
name: BEP Metadata
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Validate BEP metadata
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
python3 Scripts/check-bep-metadata.py
|
|
||||||
2
.github/workflows/lint-swift.yml
vendored
|
|
@ -13,4 +13,4 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Lint
|
- name: Lint
|
||||||
run: swiftlint lint --strict --reporter github-actions-logging
|
run: swiftlint lint --reporter github-actions-logging
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
name: Release (Linux)
|
name: Release (AppImage)
|
||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
types:
|
types:
|
||||||
|
|
@ -13,17 +13,17 @@ jobs:
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Build AppImage
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
docker build -t appimage-builder . -f burrow-gtk/build-aux/Dockerfile
|
docker build -t appimage-builder . -f burrow-gtk/build-aux/Dockerfile
|
||||||
docker create --name temp appimage-builder
|
docker create --name temp appimage-builder
|
||||||
docker cp temp:/app/burrow-gtk/build-appimage/Burrow-x86_64.AppImage .
|
docker cp temp:/app/burrow-gtk/build-appimage/Burrow-x86_64.AppImage .
|
||||||
docker rm temp
|
docker rm temp
|
||||||
- name: Attach Artifacts
|
- name: Upload to GitHub
|
||||||
uses: SierraSoftworks/gh-releases@v1.0.7
|
uses: SierraSoftworks/gh-releases@v1.0.7
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
release_tag: ${{ github.ref_name }}
|
release_tag: ${{ github.ref_name }}
|
||||||
overwrite: "true"
|
overwrite: 'true'
|
||||||
files: |
|
files: |
|
||||||
Burrow-x86_64.AppImage
|
Burrow-x86_64.AppImage
|
||||||
75
.github/workflows/release-apple.yml
vendored
|
|
@ -13,16 +13,17 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- platform: iOS
|
- destination: generic/platform=iOS
|
||||||
|
platform: iOS
|
||||||
rust-targets:
|
rust-targets:
|
||||||
- aarch64-apple-ios
|
- aarch64-apple-ios
|
||||||
- platform: macOS
|
- destination: generic/platform=macOS
|
||||||
|
platform: macOS
|
||||||
rust-targets:
|
rust-targets:
|
||||||
- x86_64-apple-darwin
|
- x86_64-apple-darwin
|
||||||
- aarch64-apple-darwin
|
- aarch64-apple-darwin
|
||||||
env:
|
env:
|
||||||
DEVELOPER_DIR: /Applications/Xcode_16.0.app/Contents/Developer
|
DEVELOPER_DIR: /Applications/Xcode_15.2.app/Contents/Developer
|
||||||
PROTOC_PATH: /opt/homebrew/bin/protoc
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
@ -33,57 +34,41 @@ jobs:
|
||||||
with:
|
with:
|
||||||
certificate: ${{ secrets.DEVELOPER_CERT }}
|
certificate: ${{ secrets.DEVELOPER_CERT }}
|
||||||
password: ${{ secrets.DEVELOPER_CERT_PASSWORD }}
|
password: ${{ secrets.DEVELOPER_CERT_PASSWORD }}
|
||||||
- name: Download Provisioning Profiles
|
|
||||||
uses: ./.github/actions/download-profiles
|
|
||||||
with:
|
|
||||||
app-store-key: ${{ secrets.APPSTORE_KEY }}
|
|
||||||
app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }}
|
|
||||||
app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }}
|
|
||||||
- name: Install Provisioning Profiles
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles/
|
|
||||||
cp -f Apple/Profiles/* ~/Library/MobileDevice/Provisioning\ Profiles/
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@stable
|
uses: dtolnay/rust-toolchain@stable
|
||||||
with:
|
with:
|
||||||
toolchain: 1.85.0
|
|
||||||
targets: ${{ join(matrix.rust-targets, ', ') }}
|
targets: ${{ join(matrix.rust-targets, ', ') }}
|
||||||
- name: Install Protobuf
|
|
||||||
shell: bash
|
|
||||||
run: brew install protobuf
|
|
||||||
- name: Configure Version
|
- name: Configure Version
|
||||||
id: version
|
|
||||||
shell: bash
|
shell: bash
|
||||||
run: echo "BUILD_NUMBER=$(Tools/version.sh)" >> $GITHUB_OUTPUT
|
run: Tools/version.sh
|
||||||
- name: Archive
|
- name: Archive
|
||||||
uses: ./.github/actions/archive
|
uses: ./.github/actions/archive
|
||||||
with:
|
with:
|
||||||
scheme: App
|
scheme: App
|
||||||
destination: generic/platform=${{ matrix.platform }}
|
destination: ${{ matrix.destination }}
|
||||||
app-store-key: ${{ secrets.APPSTORE_KEY }}
|
app-store-key: ${{ secrets.APPSTORE_KEY }}
|
||||||
app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }}
|
app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }}
|
||||||
app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }}
|
app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }}
|
||||||
archive-path: Burrow.xcarchive
|
archive-path: Burrow.xcarchive
|
||||||
- name: Export
|
- name: Notarize (macOS)
|
||||||
uses: ./.github/actions/export
|
|
||||||
with:
|
|
||||||
method: ${{ matrix.platform == 'macOS' && 'developer-id' || 'ad-hoc' }}
|
|
||||||
destination: export
|
|
||||||
app-store-key: ${{ secrets.APPSTORE_KEY }}
|
|
||||||
app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }}
|
|
||||||
app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }}
|
|
||||||
archive-path: Burrow.xcarchive
|
|
||||||
export-options: |
|
|
||||||
{"teamID":"P6PV2R9443","destination":"export","method":"developer-id","provisioningProfiles":{"com.hackclub.burrow":"Burrow Developer ID","com.hackclub.burrow.network":"Burrow Network Developer ID"},"signingCertificate":"Developer ID Application","signingStyle":"manual"}
|
|
||||||
export-path: Release
|
|
||||||
- name: Notarize
|
|
||||||
if: ${{ matrix.platform == 'macOS' }}
|
if: ${{ matrix.platform == 'macOS' }}
|
||||||
uses: ./.github/actions/notarize
|
uses: ./.github/actions/notarize
|
||||||
with:
|
with:
|
||||||
app-store-key: ${{ secrets.APPSTORE_KEY }}
|
app-store-key: ${{ secrets.APPSTORE_KEY }}
|
||||||
app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }}
|
app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }}
|
||||||
app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }}
|
app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }}
|
||||||
|
archive-path: Burrow.xcarchive
|
||||||
|
- name: Export IPA (iOS)
|
||||||
|
if: ${{ matrix.platform == 'iOS' }}
|
||||||
|
uses: ./.github/actions/export
|
||||||
|
with:
|
||||||
|
method: ad-hoc
|
||||||
|
destination: export
|
||||||
|
app-store-key: ${{ secrets.APPSTORE_KEY }}
|
||||||
|
app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }}
|
||||||
|
app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }}
|
||||||
|
archive-path: Burrow.xcarchive
|
||||||
|
export-path: Release
|
||||||
- name: Compress (iOS)
|
- name: Compress (iOS)
|
||||||
if: ${{ matrix.platform == 'iOS' }}
|
if: ${{ matrix.platform == 'iOS' }}
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
@ -98,23 +83,33 @@ jobs:
|
||||||
aa archive -a lzma -b 8m -d Apple/Release -subdir Burrow.app -o Burrow.app.aar
|
aa archive -a lzma -b 8m -d Apple/Release -subdir Burrow.app -o Burrow.app.aar
|
||||||
aa archive -a lzma -b 8m -d Apple -subdir Burrow.xcarchive -o Burrow-${{ matrix.platform }}.xcarchive.aar
|
aa archive -a lzma -b 8m -d Apple -subdir Burrow.xcarchive -o Burrow-${{ matrix.platform }}.xcarchive.aar
|
||||||
rm -rf Apple/Release
|
rm -rf Apple/Release
|
||||||
- name: Upload to GitHub
|
- name: Upload to GitHub (iOS)
|
||||||
|
if: ${{ matrix.platform == 'iOS' }}
|
||||||
uses: SierraSoftworks/gh-releases@v1.0.7
|
uses: SierraSoftworks/gh-releases@v1.0.7
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
release_tag: ${{ github.ref_name }}
|
release_tag: ${{ github.ref_name }}
|
||||||
overwrite: 'true'
|
overwrite: 'true'
|
||||||
files: |
|
files: |
|
||||||
${{ matrix.platform == 'macOS' && 'Burrow.aap.aar' || 'Burrow.ipa' }}
|
Burrow.ipa
|
||||||
|
Burrow-${{ matrix.platform }}.xcarchive.aar
|
||||||
|
- name: Upload to GitHub (macOS)
|
||||||
|
if: ${{ matrix.platform == 'macOS' }}
|
||||||
|
uses: SierraSoftworks/gh-releases@v1.0.7
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
release_tag: ${{ github.ref_name }}
|
||||||
|
overwrite: 'true'
|
||||||
|
files: |
|
||||||
|
Burrow.aap.aar
|
||||||
Burrow-${{ matrix.platform }}.xcarchive.aar
|
Burrow-${{ matrix.platform }}.xcarchive.aar
|
||||||
- name: Upload to App Store Connect
|
- name: Upload to App Store Connect
|
||||||
if: ${{ matrix.platform == 'iOS' }}
|
|
||||||
uses: ./.github/actions/export
|
uses: ./.github/actions/export
|
||||||
with:
|
with:
|
||||||
|
method: app-store
|
||||||
|
destination: upload
|
||||||
app-store-key: ${{ secrets.APPSTORE_KEY }}
|
app-store-key: ${{ secrets.APPSTORE_KEY }}
|
||||||
app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }}
|
app-store-key-id: ${{ secrets.APPSTORE_KEY_ID }}
|
||||||
app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }}
|
app-store-key-issuer-id: ${{ secrets.APPSTORE_KEY_ISSUER_ID }}
|
||||||
archive-path: Burrow.xcarchive
|
archive-path: Burrow.xcarchive
|
||||||
export-options: |
|
|
||||||
{"method": "app-store", "destination": "upload"}
|
|
||||||
export-path: Release
|
export-path: Release
|
||||||
|
|
|
||||||
2
.github/workflows/release-if-needed.yaml
vendored
|
|
@ -9,8 +9,6 @@ jobs:
|
||||||
create:
|
create:
|
||||||
name: Create Release If Needed
|
name: Create Release If Needed
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
|
||||||
GH_TOKEN: ${{ github.token }}
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
|
||||||
12
.gitignore
vendored
|
|
@ -1,20 +1,8 @@
|
||||||
# Xcode
|
# Xcode
|
||||||
xcuserdata
|
xcuserdata
|
||||||
Apple/build/
|
|
||||||
|
|
||||||
# Swift
|
|
||||||
Apple/Package/.swiftpm/
|
|
||||||
|
|
||||||
# Rust
|
# Rust
|
||||||
target/
|
target/
|
||||||
.env
|
|
||||||
|
|
||||||
.DS_STORE
|
.DS_STORE
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
tmp/
|
|
||||||
intake/
|
|
||||||
|
|
||||||
*.db
|
|
||||||
*.sqlite3
|
|
||||||
*.sock
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ opt_in_rules:
|
||||||
- function_default_parameter_at_end
|
- function_default_parameter_at_end
|
||||||
- ibinspectable_in_extension
|
- ibinspectable_in_extension
|
||||||
- identical_operands
|
- identical_operands
|
||||||
|
- implicitly_unwrapped_optional
|
||||||
- indentation_width
|
- indentation_width
|
||||||
- joined_default_parameter
|
- joined_default_parameter
|
||||||
- last_where
|
- last_where
|
||||||
|
|
|
||||||
42
.vscode/settings.json
vendored
|
|
@ -1,26 +1,18 @@
|
||||||
{
|
{
|
||||||
"files.autoSave": "onFocusChange",
|
"files.autoSave": "onFocusChange",
|
||||||
"files.defaultLanguage": "rust",
|
"files.defaultLanguage": "rust",
|
||||||
"editor.formatOnPaste": true,
|
"editor.formatOnPaste": true,
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"files.trimTrailingWhitespace": true,
|
"files.trimTrailingWhitespace": true,
|
||||||
"editor.suggest.preview": true,
|
"editor.suggest.preview": true,
|
||||||
"editor.acceptSuggestionOnEnter": "on",
|
"editor.acceptSuggestionOnEnter": "on",
|
||||||
"rust-analyzer.restartServerOnConfigChange": true,
|
"rust-analyzer.restartServerOnConfigChange": true,
|
||||||
"rust-analyzer.cargo.features": "all",
|
"rust-analyzer.cargo.features": "all",
|
||||||
"rust-analyzer.rustfmt.extraArgs": ["+nightly"],
|
"rust-analyzer.rustfmt.extraArgs": [
|
||||||
"[rust]": {
|
"+nightly"
|
||||||
"editor.defaultFormatter": "rust-lang.rust-analyzer"
|
],
|
||||||
},
|
"[rust]": {
|
||||||
"rust-analyzer.inlayHints.typeHints.enable": false,
|
"editor.defaultFormatter": "rust-lang.rust-analyzer",
|
||||||
"rust-analyzer.linkedProjects": [
|
},
|
||||||
"./burrow/Cargo.toml"
|
"rust-analyzer.inlayHints.typeHints.enable": false
|
||||||
],
|
}
|
||||||
"[yaml]": {
|
|
||||||
"editor.insertSpaces": true,
|
|
||||||
"editor.tabSize": 2,
|
|
||||||
"editor.autoIndent": "advanced",
|
|
||||||
"diffEditor.ignoreTrimWhitespace": false,
|
|
||||||
"editor.formatOnSave": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
14
AGENTS.md
|
|
@ -1,14 +0,0 @@
|
||||||
# instructions for agents
|
|
||||||
|
|
||||||
1. Spell the project name as `Burrow` in user-facing copy and `burrow` in code, package, and protocol identifiers unless an existing integration requires a different literal.
|
|
||||||
2. Read [CONSTITUTION.md](CONSTITUTION.md) before changing Apple clients, the daemon, the control plane, forge infrastructure, identity, or security-sensitive code.
|
|
||||||
3. Anchor non-trivial changes in a Burrow Evolution Proposal (BEP) under [evolution/](evolution/README.md) so future contributors can inherit the rationale, safeguards, and rollout shape.
|
|
||||||
4. Before touching the Apple app, daemon IPC, or Tailnet flows, review:
|
|
||||||
- [evolution/proposals/BEP-0002-control-plane-bootstrap-and-local-auth.md](evolution/proposals/BEP-0002-control-plane-bootstrap-and-local-auth.md)
|
|
||||||
- [evolution/proposals/BEP-0003-connect-ip-and-negotiation-roadmap.md](evolution/proposals/BEP-0003-connect-ip-and-negotiation-roadmap.md)
|
|
||||||
- [evolution/proposals/BEP-0005-daemon-ipc-and-apple-boundary.md](evolution/proposals/BEP-0005-daemon-ipc-and-apple-boundary.md)
|
|
||||||
- [evolution/proposals/BEP-0006-tailnet-authority-first-control-plane.md](evolution/proposals/BEP-0006-tailnet-authority-first-control-plane.md)
|
|
||||||
5. Apple clients must talk only to the daemon over gRPC. Do not add direct HTTP, control-plane, or helper-process calls from Swift UI code.
|
|
||||||
6. Treat Tailnet as one protocol family. Tailscale-managed and self-hosted Headscale-style deployments differ by authority, policy, and auth details, not by a separate user-facing protocol surface.
|
|
||||||
7. Maintain canonical identity and operator metadata in [contributors.nix](contributors.nix). If Burrow forge, Authentik, Headscale, or admin/group mappings need to change, edit that registry first and derive runtime configuration from it.
|
|
||||||
8. When process or architecture is unclear, stop and draft or update a BEP instead of improvising durable behavior in code.
|
|
||||||
|
|
@ -2,11 +2,6 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>com.apple.developer.associated-domains</key>
|
|
||||||
<array>
|
|
||||||
<string>applinks:burrow.rs?mode=developer</string>
|
|
||||||
<string>webcredentials:burrow.rs?mode=developer</string>
|
|
||||||
</array>
|
|
||||||
<key>com.apple.developer.networking.networkextension</key>
|
<key>com.apple.developer.networking.networkextension</key>
|
||||||
<array>
|
<array>
|
||||||
<string>packet-tunnel-provider</string>
|
<string>packet-tunnel-provider</string>
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,6 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>com.apple.developer.associated-domains</key>
|
|
||||||
<array>
|
|
||||||
<string>applinks:burrow.rs?mode=developer</string>
|
|
||||||
<string>webcredentials:burrow.rs?mode=developer</string>
|
|
||||||
</array>
|
|
||||||
<key>com.apple.developer.networking.networkextension</key>
|
<key>com.apple.developer.networking.networkextension</key>
|
||||||
<array>
|
<array>
|
||||||
<string>packet-tunnel-provider</string>
|
<string>packet-tunnel-provider</string>
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
import AppKit
|
import AppKit
|
||||||
import BurrowUI
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@main
|
|
||||||
@MainActor
|
@MainActor
|
||||||
|
@NSApplicationMain
|
||||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
private var windowController: NSWindowController?
|
|
||||||
|
|
||||||
private let quitItem: NSMenuItem = {
|
private let quitItem: NSMenuItem = {
|
||||||
let quitItem = NSMenuItem(
|
let quitItem = NSMenuItem(
|
||||||
title: "Quit Burrow",
|
title: "Quit Burrow",
|
||||||
|
|
@ -19,17 +16,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
return quitItem
|
return quitItem
|
||||||
}()
|
}()
|
||||||
|
|
||||||
private lazy var openItem: NSMenuItem = {
|
|
||||||
let item = NSMenuItem(
|
|
||||||
title: "Open Burrow",
|
|
||||||
action: #selector(openWindow),
|
|
||||||
keyEquivalent: "o"
|
|
||||||
)
|
|
||||||
item.target = self
|
|
||||||
item.keyEquivalentModifierMask = .command
|
|
||||||
return item
|
|
||||||
}()
|
|
||||||
|
|
||||||
private let toggleItem: NSMenuItem = {
|
private let toggleItem: NSMenuItem = {
|
||||||
let toggleView = NSHostingView(rootView: MenuItemToggleView())
|
let toggleView = NSHostingView(rootView: MenuItemToggleView())
|
||||||
toggleView.frame.size = CGSize(width: 300, height: 32)
|
toggleView.frame.size = CGSize(width: 300, height: 32)
|
||||||
|
|
@ -44,7 +30,6 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
let menu = NSMenu()
|
let menu = NSMenu()
|
||||||
menu.items = [
|
menu.items = [
|
||||||
toggleItem,
|
toggleItem,
|
||||||
openItem,
|
|
||||||
.separator(),
|
.separator(),
|
||||||
quitItem
|
quitItem
|
||||||
]
|
]
|
||||||
|
|
@ -55,7 +40,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
let statusBar = NSStatusBar.system
|
let statusBar = NSStatusBar.system
|
||||||
let statusItem = statusBar.statusItem(withLength: NSStatusItem.squareLength)
|
let statusItem = statusBar.statusItem(withLength: NSStatusItem.squareLength)
|
||||||
if let button = statusItem.button {
|
if let button = statusItem.button {
|
||||||
button.image = NSImage(systemSymbolName: "pipe.and.drop.fill", accessibilityDescription: nil)
|
button.image = NSImage(systemSymbolName: "network.badge.shield.half.filled", accessibilityDescription: nil)
|
||||||
}
|
}
|
||||||
return statusItem
|
return statusItem
|
||||||
}()
|
}()
|
||||||
|
|
@ -63,28 +48,5 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||||
func applicationDidFinishLaunching(_ notification: Notification) {
|
func applicationDidFinishLaunching(_ notification: Notification) {
|
||||||
statusItem.menu = menu
|
statusItem.menu = menu
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc
|
|
||||||
private func openWindow() {
|
|
||||||
if let window = windowController?.window {
|
|
||||||
window.makeKeyAndOrderFront(nil)
|
|
||||||
NSApplication.shared.activate(ignoringOtherApps: true)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let contentView = BurrowView()
|
|
||||||
let hostingController = NSHostingController(rootView: contentView)
|
|
||||||
let window = NSWindow(contentViewController: hostingController)
|
|
||||||
window.title = "Burrow"
|
|
||||||
window.setContentSize(NSSize(width: 820, height: 720))
|
|
||||||
window.styleMask.insert([.titled, .closable, .miniaturizable, .resizable])
|
|
||||||
window.center()
|
|
||||||
|
|
||||||
let controller = NSWindowController(window: window)
|
|
||||||
controller.shouldCascadeWindows = true
|
|
||||||
controller.showWindow(nil)
|
|
||||||
windowController = controller
|
|
||||||
NSApplication.shared.activate(ignoringOtherApps: true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 684 B After Width: | Height: | Size: 684 B |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 9.6 KiB |
|
Before Width: | Height: | Size: 927 B After Width: | Height: | Size: 927 B |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
20
Apple/App/Assets.xcassets/HackClub.colorset/Contents.json
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0x50",
|
||||||
|
"green" : "0x37",
|
||||||
|
"red" : "0xEC"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Apple/App/Assets.xcassets/HackClub.imageset/Contents.json
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "flag-standalone-wtransparent.pdf",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Apple/App/Assets.xcassets/HackClub.imageset/flag-standalone-wtransparent.pdf
vendored
Normal file
|
Before Width: | Height: | Size: 4 KiB After Width: | Height: | Size: 4 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
|
@ -1,7 +1,6 @@
|
||||||
#if !os(macOS)
|
|
||||||
import BurrowUI
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
#if !os(macOS)
|
||||||
@MainActor
|
@MainActor
|
||||||
@main
|
@main
|
||||||
struct BurrowApp: App {
|
struct BurrowApp: App {
|
||||||
|
|
|
||||||
26
Apple/App/BurrowView.swift
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct BurrowView: View {
|
||||||
|
var body: some View {
|
||||||
|
NavigationStack {
|
||||||
|
VStack {
|
||||||
|
NetworkCarouselView()
|
||||||
|
Spacer()
|
||||||
|
TunnelStatusView()
|
||||||
|
TunnelButton()
|
||||||
|
.padding(.bottom)
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.navigationTitle("Networks")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
struct NetworkView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
BurrowView()
|
||||||
|
.environment(\.tunnel, PreviewTunnel())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23091" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23091"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22689"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,11 @@
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
public struct MenuItemToggleView: View {
|
struct MenuItemToggleView: View {
|
||||||
@Environment(\.tunnel)
|
@Environment(\.tunnel)
|
||||||
var tunnel: Tunnel
|
var tunnel: Tunnel
|
||||||
|
|
||||||
public var body: some View {
|
var body: some View {
|
||||||
HStack {
|
HStack {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
Text("Burrow")
|
Text("Burrow")
|
||||||
|
|
@ -30,13 +30,10 @@ public struct MenuItemToggleView: View {
|
||||||
.padding(10)
|
.padding(10)
|
||||||
.frame(minWidth: 300, minHeight: 32, maxHeight: 32)
|
.frame(minWidth: 300, minHeight: 32, maxHeight: 32)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init() {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Tunnel {
|
extension Tunnel {
|
||||||
@MainActor fileprivate var toggleDisabled: Bool {
|
fileprivate var toggleDisabled: Bool {
|
||||||
switch status {
|
switch status {
|
||||||
case .disconnected, .permissionRequired, .connected, .disconnecting:
|
case .disconnected, .permissionRequired, .connected, .disconnecting:
|
||||||
false
|
false
|
||||||
|
|
@ -45,7 +42,7 @@ extension Tunnel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor var toggleIsOn: Binding<Bool> {
|
var toggleIsOn: Binding<Bool> {
|
||||||
Binding {
|
Binding {
|
||||||
switch status {
|
switch status {
|
||||||
case .connecting, .reasserting, .connected:
|
case .connecting, .reasserting, .connected:
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import NetworkExtension
|
import NetworkExtension
|
||||||
|
|
||||||
extension NEVPNManager: @unchecked @retroactive Sendable {
|
extension NEVPNManager {
|
||||||
func remove() async throws {
|
func remove() async throws {
|
||||||
_ = try await withUnsafeThrowingContinuation { continuation in
|
_ = try await withUnsafeThrowingContinuation { continuation in
|
||||||
removeFromPreferences(completionHandler: completion(continuation))
|
removeFromPreferences(completionHandler: completion(continuation))
|
||||||
|
|
@ -14,7 +14,7 @@ extension NEVPNManager: @unchecked @retroactive Sendable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension NETunnelProviderManager: @unchecked @retroactive Sendable {
|
extension NETunnelProviderManager {
|
||||||
class var managers: [NETunnelProviderManager] {
|
class var managers: [NETunnelProviderManager] {
|
||||||
get async throws {
|
get async throws {
|
||||||
try await withUnsafeThrowingContinuation { continuation in
|
try await withUnsafeThrowingContinuation { continuation in
|
||||||
|
|
@ -34,7 +34,7 @@ private func completion(_ continuation: UnsafeContinuation<Void, Error>) -> (Err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func completion<T: Sendable>(_ continuation: UnsafeContinuation<T, Error>) -> (T?, Error?) -> Void {
|
private func completion<T>(_ continuation: UnsafeContinuation<T, Error>) -> (T?, Error?) -> Void {
|
||||||
return { value, error in
|
return { value, error in
|
||||||
if let error {
|
if let error {
|
||||||
continuation.resume(throwing: error)
|
continuation.resume(throwing: error)
|
||||||
|
|
@ -1,23 +1,22 @@
|
||||||
import BurrowCore
|
import BurrowShared
|
||||||
import NetworkExtension
|
import NetworkExtension
|
||||||
|
|
||||||
@Observable
|
@Observable
|
||||||
public final class NetworkExtensionTunnel: Tunnel {
|
class NetworkExtensionTunnel: Tunnel {
|
||||||
@MainActor public private(set) var status: TunnelStatus = .unknown
|
@MainActor private(set) var status: TunnelStatus = .unknown
|
||||||
@MainActor private var error: NEVPNError?
|
private var error: NEVPNError?
|
||||||
|
|
||||||
private let logger = Logger.logger(for: Tunnel.self)
|
private let logger = Logger.logger(for: Tunnel.self)
|
||||||
private let bundleIdentifier: String
|
private let bundleIdentifier: String
|
||||||
private let configurationChanged: Task<Void, Error>
|
private var tasks: [Task<Void, Error>] = []
|
||||||
private let statusChanged: Task<Void, Error>
|
|
||||||
|
|
||||||
// Each manager corresponds to one entry in the Settings app.
|
// Each manager corresponds to one entry in the Settings app.
|
||||||
// Our goal is to maintain a single manager, so we create one if none exist and delete any extra.
|
// Our goal is to maintain a single manager, so we create one if none exist and delete any extra.
|
||||||
@MainActor private var managers: [NEVPNManager]? {
|
private var managers: [NEVPNManager]? {
|
||||||
didSet { Task { await updateStatus() } }
|
didSet { Task { await updateStatus() } }
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor private var currentStatus: TunnelStatus {
|
private var currentStatus: TunnelStatus {
|
||||||
guard let managers = managers else {
|
guard let managers = managers else {
|
||||||
guard let error = error else {
|
guard let error = error else {
|
||||||
return .unknown
|
return .unknown
|
||||||
|
|
@ -42,40 +41,35 @@ public final class NetworkExtensionTunnel: Tunnel {
|
||||||
return manager.connection.tunnelStatus
|
return manager.connection.tunnelStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(bundleIdentifier: String) {
|
convenience init() {
|
||||||
|
self.init(Constants.networkExtensionBundleIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
init(_ bundleIdentifier: String) {
|
||||||
self.bundleIdentifier = bundleIdentifier
|
self.bundleIdentifier = bundleIdentifier
|
||||||
|
|
||||||
let center = NotificationCenter.default
|
let center = NotificationCenter.default
|
||||||
let tunnel: OSAllocatedUnfairLock<NetworkExtensionTunnel?> = .init(initialState: .none)
|
let configurationChanged = Task { [weak self] in
|
||||||
configurationChanged = Task {
|
for try await _ in center.notifications(named: .NEVPNConfigurationChange).map({ _ in () }) {
|
||||||
for try await _ in center.notifications(named: .NEVPNConfigurationChange) {
|
await self?.update()
|
||||||
try Task.checkCancellation()
|
|
||||||
await tunnel.withLock { $0 }?.update()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
statusChanged = Task {
|
let statusChanged = Task { [weak self] in
|
||||||
for try await _ in center.notifications(named: .NEVPNStatusDidChange) {
|
for try await _ in center.notifications(named: .NEVPNStatusDidChange).map({ _ in () }) {
|
||||||
try Task.checkCancellation()
|
await self?.updateStatus()
|
||||||
await tunnel.withLock { $0 }?.updateStatus()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tunnel.withLock { $0 = self }
|
tasks = [configurationChanged, statusChanged]
|
||||||
|
|
||||||
Task { await update() }
|
Task { await update() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private func update() async {
|
private func update() async {
|
||||||
do {
|
do {
|
||||||
let result = try await NETunnelProviderManager.managers
|
managers = try await NETunnelProviderManager.managers
|
||||||
await MainActor.run {
|
|
||||||
managers = result
|
|
||||||
status = currentStatus
|
|
||||||
}
|
|
||||||
await self.updateStatus()
|
await self.updateStatus()
|
||||||
} catch let vpnError as NEVPNError {
|
} catch let vpnError as NEVPNError {
|
||||||
await MainActor.run {
|
error = vpnError
|
||||||
error = vpnError
|
|
||||||
}
|
|
||||||
} catch {
|
} catch {
|
||||||
logger.error("Failed to update VPN configurations: \(error)")
|
logger.error("Failed to update VPN configurations: \(error)")
|
||||||
}
|
}
|
||||||
|
|
@ -88,7 +82,12 @@ public final class NetworkExtensionTunnel: Tunnel {
|
||||||
}
|
}
|
||||||
|
|
||||||
func configure() async throws {
|
func configure() async throws {
|
||||||
let managers = try await NETunnelProviderManager.managers
|
if managers == nil {
|
||||||
|
await update()
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let managers = managers else { return }
|
||||||
|
|
||||||
if managers.count > 1 {
|
if managers.count > 1 {
|
||||||
try await withThrowingTaskGroup(of: Void.self, returning: Void.self) { group in
|
try await withThrowingTaskGroup(of: Void.self, returning: Void.self) { group in
|
||||||
for manager in managers.suffix(from: 1) {
|
for manager in managers.suffix(from: 1) {
|
||||||
|
|
@ -105,15 +104,15 @@ public final class NetworkExtensionTunnel: Tunnel {
|
||||||
|
|
||||||
let proto = NETunnelProviderProtocol()
|
let proto = NETunnelProviderProtocol()
|
||||||
proto.providerBundleIdentifier = bundleIdentifier
|
proto.providerBundleIdentifier = bundleIdentifier
|
||||||
proto.serverAddress = "burrow.rs"
|
proto.serverAddress = "hackclub.com"
|
||||||
|
|
||||||
manager.protocolConfiguration = proto
|
manager.protocolConfiguration = proto
|
||||||
try await manager.save()
|
try await manager.save()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func start() {
|
func start() {
|
||||||
|
guard let manager = managers?.first else { return }
|
||||||
Task {
|
Task {
|
||||||
guard let manager = try await NETunnelProviderManager.managers.first else { return }
|
|
||||||
do {
|
do {
|
||||||
if !manager.isEnabled {
|
if !manager.isEnabled {
|
||||||
manager.isEnabled = true
|
manager.isEnabled = true
|
||||||
|
|
@ -126,14 +125,12 @@ public final class NetworkExtensionTunnel: Tunnel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func stop() {
|
func stop() {
|
||||||
Task {
|
guard let manager = managers?.first else { return }
|
||||||
guard let manager = try await NETunnelProviderManager.managers.first else { return }
|
manager.connection.stopVPNTunnel()
|
||||||
manager.connection.stopVPNTunnel()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func enable() {
|
func enable() {
|
||||||
Task {
|
Task {
|
||||||
do {
|
do {
|
||||||
try await configure()
|
try await configure()
|
||||||
|
|
@ -144,8 +141,7 @@ public final class NetworkExtensionTunnel: Tunnel {
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
configurationChanged.cancel()
|
tasks.forEach { $0.cancel() }
|
||||||
statusChanged.cancel()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
88
Apple/App/NetworkView.swift
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct NetworkView<Content: View>: View {
|
||||||
|
var color: Color
|
||||||
|
var content: () -> Content
|
||||||
|
|
||||||
|
private var gradient: LinearGradient {
|
||||||
|
LinearGradient(
|
||||||
|
colors: [
|
||||||
|
color.opacity(0.8),
|
||||||
|
color
|
||||||
|
],
|
||||||
|
startPoint: .init(x: 0.2, y: 0),
|
||||||
|
endPoint: .init(x: 0.8, y: 1)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
content()
|
||||||
|
.frame(maxWidth: .infinity, minHeight: 175, maxHeight: 175)
|
||||||
|
.background(
|
||||||
|
RoundedRectangle(cornerRadius: 10)
|
||||||
|
.fill(gradient)
|
||||||
|
.background(
|
||||||
|
RoundedRectangle(cornerRadius: 10)
|
||||||
|
.fill(.white)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.shadow(color: .black.opacity(0.1), radius: 3.0, x: 0, y: 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AddNetworkView: View {
|
||||||
|
var body: some View {
|
||||||
|
Text("Add Network")
|
||||||
|
.frame(maxWidth: .infinity, minHeight: 175, maxHeight: 175)
|
||||||
|
.background(
|
||||||
|
RoundedRectangle(cornerRadius: 10)
|
||||||
|
.stroke(style: .init(lineWidth: 2, dash: [6]))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension NetworkView where Content == AnyView {
|
||||||
|
init(network: any Network) {
|
||||||
|
color = network.backgroundColor
|
||||||
|
content = { AnyView(network.label) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NetworkCarouselView: View {
|
||||||
|
var networks: [any Network] = [
|
||||||
|
HackClub(id: "1"),
|
||||||
|
HackClub(id: "2"),
|
||||||
|
WireGuard(id: "4"),
|
||||||
|
HackClub(id: "5"),
|
||||||
|
]
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
ScrollView(.horizontal) {
|
||||||
|
LazyHStack {
|
||||||
|
ForEach(networks, id: \.id) { network in
|
||||||
|
NetworkView(network: network)
|
||||||
|
.containerRelativeFrame(.horizontal, count: 10, span: 7, spacing: 0, alignment: .center)
|
||||||
|
.scrollTransition(.interactive, axis: .horizontal) { content, phase in
|
||||||
|
content
|
||||||
|
.scaleEffect(1.0 - abs(phase.value) * 0.1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AddNetworkView()
|
||||||
|
}
|
||||||
|
.scrollTargetLayout()
|
||||||
|
}
|
||||||
|
.scrollClipDisabled()
|
||||||
|
.scrollIndicators(.hidden)
|
||||||
|
.defaultScrollAnchor(.center)
|
||||||
|
.scrollTargetBehavior(.viewAligned)
|
||||||
|
.containerRelativeFrame(.horizontal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
struct NetworkCarouselView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
NetworkCarouselView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
23
Apple/App/Networks/HackClub.swift
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct HackClub: Network {
|
||||||
|
var id: String
|
||||||
|
var backgroundColor: Color { .init("HackClub") }
|
||||||
|
|
||||||
|
var label: some View {
|
||||||
|
GeometryReader { reader in
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
Image("HackClub")
|
||||||
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: .fit)
|
||||||
|
.frame(height: reader.size.height / 4)
|
||||||
|
Spacer()
|
||||||
|
Text("@conradev")
|
||||||
|
.foregroundStyle(.white)
|
||||||
|
.font(.body.monospaced())
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
Apple/App/Networks/Network.swift
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
protocol Network {
|
||||||
|
associatedtype Label: View
|
||||||
|
|
||||||
|
var id: String { get }
|
||||||
|
var backgroundColor: Color { get }
|
||||||
|
|
||||||
|
var label: Label { get }
|
||||||
|
}
|
||||||
30
Apple/App/Networks/WireGuard.swift
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct WireGuard: Network {
|
||||||
|
var id: String
|
||||||
|
var backgroundColor: Color { .init("WireGuard") }
|
||||||
|
|
||||||
|
var label: some View {
|
||||||
|
GeometryReader { reader in
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
HStack {
|
||||||
|
Image("WireGuard")
|
||||||
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: .fit)
|
||||||
|
Image("WireGuardTitle")
|
||||||
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: .fit)
|
||||||
|
.frame(width: reader.size.width / 2)
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: reader.size.height / 4)
|
||||||
|
Spacer()
|
||||||
|
Text("@conradev")
|
||||||
|
.foregroundStyle(.white)
|
||||||
|
.font(.body.monospaced())
|
||||||
|
}
|
||||||
|
.padding()
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
50
Apple/App/Tunnel.swift
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
protocol Tunnel {
|
||||||
|
var status: TunnelStatus { get }
|
||||||
|
|
||||||
|
func start()
|
||||||
|
func stop()
|
||||||
|
func enable()
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TunnelStatus: Equatable, Hashable {
|
||||||
|
case unknown
|
||||||
|
case permissionRequired
|
||||||
|
case disabled
|
||||||
|
case connecting
|
||||||
|
case connected(Date)
|
||||||
|
case disconnecting
|
||||||
|
case disconnected
|
||||||
|
case reasserting
|
||||||
|
case invalid
|
||||||
|
case configurationReadWriteFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
struct TunnelKey: EnvironmentKey {
|
||||||
|
static let defaultValue: any Tunnel = NetworkExtensionTunnel()
|
||||||
|
}
|
||||||
|
|
||||||
|
extension EnvironmentValues {
|
||||||
|
var tunnel: any Tunnel {
|
||||||
|
get { self[TunnelKey.self] }
|
||||||
|
set { self[TunnelKey.self] = newValue }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
@Observable
|
||||||
|
class PreviewTunnel: Tunnel {
|
||||||
|
var status: TunnelStatus = .permissionRequired
|
||||||
|
|
||||||
|
func start() {
|
||||||
|
status = .connected(.now)
|
||||||
|
}
|
||||||
|
func stop() {
|
||||||
|
status = .disconnected
|
||||||
|
}
|
||||||
|
func enable() {
|
||||||
|
status = .disconnected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -4,24 +4,21 @@ struct TunnelButton: View {
|
||||||
@Environment(\.tunnel)
|
@Environment(\.tunnel)
|
||||||
var tunnel: any Tunnel
|
var tunnel: any Tunnel
|
||||||
|
|
||||||
private var action: Action? { tunnel.action }
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Button {
|
if let action = tunnel.action {
|
||||||
if let action {
|
Button {
|
||||||
tunnel.perform(action)
|
tunnel.perform(action)
|
||||||
|
} label: {
|
||||||
|
Text(action.description)
|
||||||
}
|
}
|
||||||
} label: {
|
.padding(.horizontal)
|
||||||
Text(action.description)
|
.buttonStyle(.floating)
|
||||||
}
|
}
|
||||||
.disabled(action.isDisabled)
|
|
||||||
.padding(.horizontal)
|
|
||||||
.buttonStyle(.floating)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Tunnel {
|
extension Tunnel {
|
||||||
@MainActor fileprivate var action: TunnelButton.Action? {
|
fileprivate var action: TunnelButton.Action? {
|
||||||
switch status {
|
switch status {
|
||||||
case .permissionRequired, .invalid:
|
case .permissionRequired, .invalid:
|
||||||
.enable
|
.enable
|
||||||
|
|
@ -43,21 +40,12 @@ extension TunnelButton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TunnelButton.Action? {
|
extension TunnelButton.Action {
|
||||||
var description: LocalizedStringKey {
|
var description: LocalizedStringKey {
|
||||||
switch self {
|
switch self {
|
||||||
case .enable: "Enable"
|
case .enable: "Enable"
|
||||||
case .start: "Start"
|
case .start: "Start"
|
||||||
case .stop: "Stop"
|
case .stop: "Stop"
|
||||||
case .none: "Start"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var isDisabled: Bool {
|
|
||||||
if case .none = self {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -10,7 +10,7 @@ struct TunnelStatusView: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TunnelStatus: CustomStringConvertible {
|
extension TunnelStatus: CustomStringConvertible {
|
||||||
public var description: String {
|
var description: String {
|
||||||
switch self {
|
switch self {
|
||||||
case .unknown:
|
case .unknown:
|
||||||
"Unknown"
|
"Unknown"
|
||||||
|
|
@ -1,439 +0,0 @@
|
||||||
import XCTest
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
@MainActor
|
|
||||||
final class BurrowTailnetLoginUITests: XCTestCase {
|
|
||||||
private enum TailnetLoginMode: String, Decodable {
|
|
||||||
case tailscale
|
|
||||||
case discovered
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct TestConfig: Decodable {
|
|
||||||
let email: String
|
|
||||||
let username: String
|
|
||||||
let password: String
|
|
||||||
let mode: TailnetLoginMode?
|
|
||||||
}
|
|
||||||
|
|
||||||
override func setUpWithError() throws {
|
|
||||||
continueAfterFailure = false
|
|
||||||
}
|
|
||||||
|
|
||||||
func testTailnetLoginThroughAuthentikWebSession() throws {
|
|
||||||
let config = try loadTestConfig()
|
|
||||||
let email = config.email
|
|
||||||
let username = config.username
|
|
||||||
let password = config.password
|
|
||||||
let mode = config.mode ?? .tailscale
|
|
||||||
let browserIdentity = mode == .tailscale ? email : username
|
|
||||||
|
|
||||||
let app = XCUIApplication()
|
|
||||||
app.launch()
|
|
||||||
|
|
||||||
let tailnetButton = app.buttons["quick-add-tailnet"]
|
|
||||||
XCTAssertTrue(tailnetButton.waitForExistence(timeout: 15), "Tailnet add button did not appear")
|
|
||||||
tailnetButton.tap()
|
|
||||||
|
|
||||||
configureTailnetIfNeeded(in: app, mode: mode)
|
|
||||||
|
|
||||||
let discoveryField = app.textFields["tailnet-discovery-email"]
|
|
||||||
XCTAssertTrue(discoveryField.waitForExistence(timeout: 10), "Tailnet discovery email field did not appear")
|
|
||||||
replaceText(in: discoveryField, with: email)
|
|
||||||
|
|
||||||
let serverCard = app.descendants(matching: .any)
|
|
||||||
.matching(identifier: "tailnet-server-card")
|
|
||||||
.firstMatch
|
|
||||||
XCTAssertTrue(serverCard.waitForExistence(timeout: 5), "Tailnet server card did not appear")
|
|
||||||
|
|
||||||
let signInButton = app.buttons["tailnet-start-sign-in"]
|
|
||||||
XCTAssertTrue(signInButton.waitForExistence(timeout: 10), "Tailnet sign-in button did not appear")
|
|
||||||
signInButton.tap()
|
|
||||||
|
|
||||||
acceptAuthenticationPromptIfNeeded(in: app, timeout: 20)
|
|
||||||
|
|
||||||
let webSession = webAuthenticationSession()
|
|
||||||
XCTAssertTrue(webSession.waitForExistence(timeout: 20), "Safari authentication session did not appear")
|
|
||||||
|
|
||||||
signIntoAuthentik(in: webSession, username: browserIdentity, password: password)
|
|
||||||
|
|
||||||
app.activate()
|
|
||||||
XCTAssertTrue(
|
|
||||||
waitForTailnetSignedIn(in: app, timeout: 60),
|
|
||||||
"Tailnet sign-in never reached the running state"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func configureTailnetIfNeeded(in app: XCUIApplication, mode: TailnetLoginMode) {
|
|
||||||
guard mode == .discovered else { return }
|
|
||||||
|
|
||||||
openTailnetMenu(in: app)
|
|
||||||
tapMenuButton(named: "Edit Custom Server", in: app)
|
|
||||||
|
|
||||||
openTailnetMenu(in: app)
|
|
||||||
tapMenuButton(named: "Show Advanced Settings", in: app)
|
|
||||||
|
|
||||||
let authorityField = app.textFields["tailnet-authority"]
|
|
||||||
XCTAssertTrue(authorityField.waitForExistence(timeout: 10), "Tailnet authority field did not appear")
|
|
||||||
replaceText(in: authorityField, with: "")
|
|
||||||
}
|
|
||||||
|
|
||||||
private func openTailnetMenu(in app: XCUIApplication) {
|
|
||||||
let moreButton = app.buttons["More"]
|
|
||||||
XCTAssertTrue(moreButton.waitForExistence(timeout: 5), "Tailnet menu button did not appear")
|
|
||||||
moreButton.tap()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func tapMenuButton(named title: String, in app: XCUIApplication) {
|
|
||||||
let menuButton = firstExistingElement(
|
|
||||||
from: [
|
|
||||||
app.buttons[title],
|
|
||||||
app.descendants(matching: .button)[title],
|
|
||||||
],
|
|
||||||
timeout: 5
|
|
||||||
)
|
|
||||||
XCTAssertTrue(menuButton.exists, "Menu action \(title) did not appear")
|
|
||||||
menuButton.tap()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func acceptAuthenticationPromptIfNeeded(
|
|
||||||
in app: XCUIApplication,
|
|
||||||
timeout: TimeInterval
|
|
||||||
) {
|
|
||||||
let springboard = XCUIApplication(bundleIdentifier: "com.apple.springboard")
|
|
||||||
let deadline = Date().addingTimeInterval(timeout)
|
|
||||||
|
|
||||||
repeat {
|
|
||||||
let promptCandidates = [
|
|
||||||
springboard.buttons["Continue"],
|
|
||||||
springboard.buttons["Allow"],
|
|
||||||
app.buttons["Continue"],
|
|
||||||
app.buttons["Allow"],
|
|
||||||
]
|
|
||||||
|
|
||||||
for button in promptCandidates where button.exists && button.isHittable {
|
|
||||||
button.tap()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
RunLoop.current.run(until: Date().addingTimeInterval(0.25))
|
|
||||||
} while Date() < deadline
|
|
||||||
|
|
||||||
let promptCandidates = [
|
|
||||||
springboard.buttons["Continue"],
|
|
||||||
springboard.buttons["Allow"],
|
|
||||||
app.buttons["Continue"],
|
|
||||||
app.buttons["Allow"],
|
|
||||||
]
|
|
||||||
|
|
||||||
for button in promptCandidates where button.exists {
|
|
||||||
button.tap()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func webAuthenticationSession() -> XCUIApplication {
|
|
||||||
let safariViewService = XCUIApplication(bundleIdentifier: "com.apple.SafariViewService")
|
|
||||||
if safariViewService.waitForExistence(timeout: 5) {
|
|
||||||
return safariViewService
|
|
||||||
}
|
|
||||||
|
|
||||||
let safari = XCUIApplication(bundleIdentifier: "com.apple.mobilesafari")
|
|
||||||
_ = safari.waitForExistence(timeout: 5)
|
|
||||||
return safari
|
|
||||||
}
|
|
||||||
|
|
||||||
private func signIntoAuthentik(in webSession: XCUIApplication, username: String, password: String) {
|
|
||||||
followTailnetRedirectIfNeeded(in: webSession)
|
|
||||||
|
|
||||||
if !webSession.exists {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let immediatePasswordField = firstExistingSecureField(in: webSession, timeout: 2)
|
|
||||||
if immediatePasswordField.exists {
|
|
||||||
replaceSecureText(in: immediatePasswordField, within: webSession, with: password)
|
|
||||||
submitAuthenticationForm(in: webSession, focusedField: immediatePasswordField)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let usernameField = firstExistingElement(
|
|
||||||
in: webSession,
|
|
||||||
queries: [
|
|
||||||
{ $0.textFields["Username"] },
|
|
||||||
{ $0.textFields["Email or Username"] },
|
|
||||||
{ $0.textFields["Email address"] },
|
|
||||||
{ $0.textFields["Email"] },
|
|
||||||
{ $0.webViews.textFields["Username"] },
|
|
||||||
{ $0.webViews.textFields["Email or Username"] },
|
|
||||||
{ $0.descendants(matching: .textField).firstMatch },
|
|
||||||
],
|
|
||||||
timeout: 12
|
|
||||||
)
|
|
||||||
if !usernameField.exists {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
replaceText(in: usernameField, with: username)
|
|
||||||
|
|
||||||
tapFirstExistingButton(
|
|
||||||
in: webSession,
|
|
||||||
titles: ["Continue", "Next", "Sign In", "Log in", "Login"],
|
|
||||||
timeout: 5
|
|
||||||
)
|
|
||||||
|
|
||||||
let passwordField = firstExistingSecureField(in: webSession, timeout: 20)
|
|
||||||
XCTAssertTrue(passwordField.exists, "Authentik password field did not appear")
|
|
||||||
replaceSecureText(in: passwordField, within: webSession, with: password)
|
|
||||||
submitAuthenticationForm(in: webSession, focusedField: passwordField)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func followTailnetRedirectIfNeeded(in webSession: XCUIApplication) {
|
|
||||||
let redirectCandidates = [
|
|
||||||
webSession.links["Found"],
|
|
||||||
webSession.webViews.links["Found"],
|
|
||||||
webSession.buttons["Found"],
|
|
||||||
webSession.webViews.buttons["Found"],
|
|
||||||
]
|
|
||||||
|
|
||||||
let redirectLink = firstExistingElement(from: redirectCandidates, timeout: 8)
|
|
||||||
if redirectLink.exists {
|
|
||||||
redirectLink.tap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func firstExistingSecureField(in app: XCUIApplication, timeout: TimeInterval) -> XCUIElement {
|
|
||||||
let candidates = [
|
|
||||||
app.descendants(matching: .secureTextField).firstMatch,
|
|
||||||
app.secureTextFields["Password"],
|
|
||||||
app.secureTextFields["Password or Token"],
|
|
||||||
app.webViews.secureTextFields["Password"],
|
|
||||||
app.webViews.secureTextFields["Password or Token"],
|
|
||||||
]
|
|
||||||
|
|
||||||
return firstExistingElement(from: candidates, timeout: timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func tapFirstExistingButton(
|
|
||||||
in app: XCUIApplication,
|
|
||||||
titles: [String],
|
|
||||||
timeout: TimeInterval
|
|
||||||
) {
|
|
||||||
let candidates = titles.flatMap { title in
|
|
||||||
[
|
|
||||||
app.buttons[title],
|
|
||||||
app.webViews.buttons[title],
|
|
||||||
]
|
|
||||||
} + [app.descendants(matching: .button).firstMatch]
|
|
||||||
|
|
||||||
let button = firstExistingElement(from: candidates, timeout: timeout)
|
|
||||||
XCTAssertTrue(button.exists, "Expected one of \(titles.joined(separator: ", ")) to appear")
|
|
||||||
button.tap()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func submitAuthenticationForm(in app: XCUIApplication, focusedField: XCUIElement) {
|
|
||||||
focus(focusedField)
|
|
||||||
focusedField.typeText("\n")
|
|
||||||
if waitForAny(
|
|
||||||
[
|
|
||||||
{ !focusedField.exists },
|
|
||||||
{ !app.staticTexts["Burrow Tailnet Authentication"].exists },
|
|
||||||
],
|
|
||||||
timeout: 1.5
|
|
||||||
) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let keyboard = app.keyboards.firstMatch
|
|
||||||
if keyboard.waitForExistence(timeout: 2) {
|
|
||||||
let keyboardCandidates = [
|
|
||||||
"Return",
|
|
||||||
"return",
|
|
||||||
"Go",
|
|
||||||
"go",
|
|
||||||
"Continue",
|
|
||||||
"continue",
|
|
||||||
"Done",
|
|
||||||
"done",
|
|
||||||
"Join",
|
|
||||||
"join",
|
|
||||||
"Sign In",
|
|
||||||
"Log In",
|
|
||||||
"Login",
|
|
||||||
]
|
|
||||||
for title in keyboardCandidates {
|
|
||||||
let key = keyboard.buttons[title]
|
|
||||||
if key.exists && key.isHittable {
|
|
||||||
key.tap()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let lastKey = keyboard.buttons.allElementsBoundByIndex.last,
|
|
||||||
lastKey.exists,
|
|
||||||
lastKey.isHittable
|
|
||||||
{
|
|
||||||
lastKey.tap()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tapFirstExistingButton(
|
|
||||||
in: app,
|
|
||||||
titles: ["Continue", "Sign In", "Log in", "Login"],
|
|
||||||
timeout: 5
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func loadTestConfig() throws -> TestConfig {
|
|
||||||
let environment = ProcessInfo.processInfo.environment
|
|
||||||
if let email = nonEmptyEnvironment("BURROW_UI_TEST_EMAIL"),
|
|
||||||
let password = nonEmptyEnvironment("BURROW_UI_TEST_PASSWORD")
|
|
||||||
{
|
|
||||||
return TestConfig(
|
|
||||||
email: email,
|
|
||||||
username: nonEmptyEnvironment("BURROW_UI_TEST_USERNAME") ?? email,
|
|
||||||
password: password,
|
|
||||||
mode: nonEmptyEnvironment("BURROW_UI_TEST_TAILNET_MODE")
|
|
||||||
.flatMap(TailnetLoginMode.init(rawValue:))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
let configPath = environment["BURROW_UI_TEST_CONFIG_PATH"] ?? "/tmp/burrow-ui-test-config.json"
|
|
||||||
let configURL = URL(fileURLWithPath: configPath)
|
|
||||||
guard FileManager.default.fileExists(atPath: configURL.path) else {
|
|
||||||
throw XCTSkip(
|
|
||||||
"Missing UI test configuration. Expected env vars or config file at \(configURL.path)"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
let data = try Data(contentsOf: configURL)
|
|
||||||
return try JSONDecoder().decode(TestConfig.self, from: data)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func nonEmptyEnvironment(_ key: String) -> String? {
|
|
||||||
guard let value = ProcessInfo.processInfo.environment[key]?
|
|
||||||
.trimmingCharacters(in: .whitespacesAndNewlines),
|
|
||||||
!value.isEmpty
|
|
||||||
else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
private func waitForFieldValue(
|
|
||||||
_ field: XCUIElement,
|
|
||||||
containing substring: String,
|
|
||||||
timeout: TimeInterval
|
|
||||||
) -> Bool {
|
|
||||||
let predicate = NSPredicate(format: "value CONTAINS %@", substring)
|
|
||||||
let expectation = XCTNSPredicateExpectation(predicate: predicate, object: field)
|
|
||||||
return XCTWaiter.wait(for: [expectation], timeout: timeout) == .completed
|
|
||||||
}
|
|
||||||
|
|
||||||
private func waitForButtonLabel(
|
|
||||||
_ button: XCUIElement,
|
|
||||||
equals expected: String,
|
|
||||||
timeout: TimeInterval
|
|
||||||
) -> Bool {
|
|
||||||
let predicate = NSPredicate(format: "label == %@", expected)
|
|
||||||
let expectation = XCTNSPredicateExpectation(predicate: predicate, object: button)
|
|
||||||
return XCTWaiter.wait(for: [expectation], timeout: timeout) == .completed
|
|
||||||
}
|
|
||||||
|
|
||||||
private func waitForTailnetSignedIn(in app: XCUIApplication, timeout: TimeInterval) -> Bool {
|
|
||||||
let button = app.buttons["tailnet-start-sign-in"]
|
|
||||||
let deadline = Date().addingTimeInterval(timeout)
|
|
||||||
|
|
||||||
repeat {
|
|
||||||
acceptAuthenticationPromptIfNeeded(in: app, timeout: 1)
|
|
||||||
if button.exists, button.label == "Signed In" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
RunLoop.current.run(until: Date().addingTimeInterval(0.3))
|
|
||||||
} while Date() < deadline
|
|
||||||
|
|
||||||
return button.exists && button.label == "Signed In"
|
|
||||||
}
|
|
||||||
|
|
||||||
private func waitForAny(_ conditions: [() -> Bool], timeout: TimeInterval) -> Bool {
|
|
||||||
let deadline = Date().addingTimeInterval(timeout)
|
|
||||||
repeat {
|
|
||||||
if conditions.contains(where: { $0() }) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
RunLoop.current.run(until: Date().addingTimeInterval(0.2))
|
|
||||||
} while Date() < deadline
|
|
||||||
return conditions.contains(where: { $0() })
|
|
||||||
}
|
|
||||||
|
|
||||||
private func firstExistingElement(
|
|
||||||
in app: XCUIApplication,
|
|
||||||
queries: [(XCUIApplication) -> XCUIElement],
|
|
||||||
timeout: TimeInterval
|
|
||||||
) -> XCUIElement {
|
|
||||||
firstExistingElement(from: queries.map { $0(app) }, timeout: timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func firstExistingElement(from candidates: [XCUIElement], timeout: TimeInterval) -> XCUIElement {
|
|
||||||
let deadline = Date().addingTimeInterval(timeout)
|
|
||||||
repeat {
|
|
||||||
for candidate in candidates where candidate.exists {
|
|
||||||
return candidate
|
|
||||||
}
|
|
||||||
RunLoop.current.run(until: Date().addingTimeInterval(0.2))
|
|
||||||
} while Date() < deadline
|
|
||||||
|
|
||||||
return candidates[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
private func replaceText(in element: XCUIElement, with value: String) {
|
|
||||||
focus(element)
|
|
||||||
clearText(in: element)
|
|
||||||
element.typeText(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func replaceSecureText(in element: XCUIElement, within app: XCUIApplication, with value: String) {
|
|
||||||
UIPasteboard.general.string = value
|
|
||||||
focus(element)
|
|
||||||
for revealMenu in [
|
|
||||||
{ element.doubleTap() },
|
|
||||||
{ element.press(forDuration: 1.2) },
|
|
||||||
] {
|
|
||||||
revealMenu()
|
|
||||||
let pasteButton = firstExistingElement(from: pasteCandidates(in: app), timeout: 3)
|
|
||||||
if pasteButton.exists {
|
|
||||||
pasteButton.tap()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
focus(element)
|
|
||||||
element.typeText(value)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func clearText(in element: XCUIElement) {
|
|
||||||
guard let currentValue = element.value as? String, !currentValue.isEmpty else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let deleteSequence = String(repeating: XCUIKeyboardKey.delete.rawValue, count: currentValue.count)
|
|
||||||
element.typeText(deleteSequence)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func focus(_ element: XCUIElement) {
|
|
||||||
element.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5)).tap()
|
|
||||||
RunLoop.current.run(until: Date().addingTimeInterval(0.3))
|
|
||||||
}
|
|
||||||
|
|
||||||
private func pasteCandidates(in app: XCUIApplication) -> [XCUIElement] {
|
|
||||||
let pasteLabels = ["Paste", "Incolla", "Paste from Clipboard"]
|
|
||||||
return pasteLabels.flatMap { label in
|
|
||||||
[
|
|
||||||
app.menuItems[label],
|
|
||||||
app.buttons[label],
|
|
||||||
app.webViews.buttons[label],
|
|
||||||
app.descendants(matching: .button).matching(NSPredicate(format: "label == %@", label)).firstMatch,
|
|
||||||
app.descendants(matching: .menuItem).matching(NSPredicate(format: "label == %@", label)).firstMatch,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,123 +1,86 @@
|
||||||
{
|
{
|
||||||
"originHash" : "fa512b990383b7e309c5854a5279817052294a8191a6d3c55c49cfb38e88c0c3",
|
|
||||||
"pins" : [
|
"pins" : [
|
||||||
{
|
{
|
||||||
"identity" : "grpc-swift",
|
"identity" : "collectionconcurrencykit",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/grpc/grpc-swift.git",
|
"location" : "https://github.com/JohnSundell/CollectionConcurrencyKit.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "6a90b7e77e29f9bda6c2b3a4165a40d6c02cfda1",
|
"revision" : "b4f23e24b5a1bff301efc5e70871083ca029ff95",
|
||||||
"version" : "1.23.0"
|
"version" : "0.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swift-async-algorithms",
|
"identity" : "cryptoswift",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/apple/swift-async-algorithms.git",
|
"location" : "https://github.com/krzyzanowskim/CryptoSwift.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "6ae9a051f76b81cc668305ceed5b0e0a7fd93d20",
|
"revision" : "7892a123f7e8d0fe62f9f03728b17bbd4f94df5c",
|
||||||
"version" : "1.0.1"
|
"version" : "1.8.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swift-atomics",
|
"identity" : "sourcekitten",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/apple/swift-atomics.git",
|
"location" : "https://github.com/jpsim/SourceKitten.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "cd142fd2f64be2100422d658e7411e39489da985",
|
"revision" : "b6dc09ee51dfb0c66e042d2328c017483a1a5d56",
|
||||||
"version" : "1.2.0"
|
"version" : "0.34.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swift-collections",
|
"identity" : "swift-argument-parser",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/apple/swift-collections.git",
|
"location" : "https://github.com/apple/swift-argument-parser.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "9bf03ff58ce34478e66aaee630e491823326fd06",
|
"revision" : "8f4d2753f0e4778c76d5f05ad16c74f707390531",
|
||||||
"version" : "1.1.3"
|
"version" : "1.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swift-http-types",
|
"identity" : "swift-syntax",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/apple/swift-http-types",
|
"location" : "https://github.com/apple/swift-syntax.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "ae67c8178eb46944fd85e4dc6dd970e1f3ed6ccd",
|
"revision" : "64889f0c732f210a935a0ad7cda38f77f876262d",
|
||||||
"version" : "1.3.0"
|
"version" : "509.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swift-log",
|
"identity" : "swiftlint",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/apple/swift-log.git",
|
"location" : "https://github.com/realm/SwiftLint.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "9cb486020ebf03bfa5b5df985387a14a98744537",
|
"branch" : "main",
|
||||||
"version" : "1.6.1"
|
"revision" : "7595ad3fafc1a31086dc40ba01fd898bf6b42d5f"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swift-nio",
|
"identity" : "swiftytexttable",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/apple/swift-nio.git",
|
"location" : "https://github.com/scottrhoyt/SwiftyTextTable.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "9746cf80e29edfef2a39924a66731249223f42a3",
|
"revision" : "c6df6cf533d120716bff38f8ff9885e1ce2a4ac3",
|
||||||
"version" : "2.72.0"
|
"version" : "0.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swift-nio-extras",
|
"identity" : "swxmlhash",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/apple/swift-nio-extras.git",
|
"location" : "https://github.com/drmohundro/SWXMLHash.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "d1ead62745cc3269e482f1c51f27608057174379",
|
"revision" : "a853604c9e9a83ad9954c7e3d2a565273982471f",
|
||||||
"version" : "1.24.0"
|
"version" : "7.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swift-nio-http2",
|
"identity" : "yams",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/apple/swift-nio-http2.git",
|
"location" : "https://github.com/jpsim/Yams.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "b5f7062b60e4add1e8c343ba4eb8da2e324b3a94",
|
"revision" : "0d9ee7ea8c4ebd4a489ad7a73d5c6cad55d6fed3",
|
||||||
"version" : "1.34.0"
|
"version" : "5.0.6"
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identity" : "swift-nio-ssl",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/apple/swift-nio-ssl.git",
|
|
||||||
"state" : {
|
|
||||||
"revision" : "7b84abbdcef69cc3be6573ac12440220789dcd69",
|
|
||||||
"version" : "2.27.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identity" : "swift-nio-transport-services",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/apple/swift-nio-transport-services.git",
|
|
||||||
"state" : {
|
|
||||||
"revision" : "38ac8221dd20674682148d6451367f89c2652980",
|
|
||||||
"version" : "1.21.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identity" : "swift-protobuf",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/apple/swift-protobuf.git",
|
|
||||||
"state" : {
|
|
||||||
"revision" : "edb6ed4919f7756157fe02f2552b7e3850a538e5",
|
|
||||||
"version" : "1.28.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"identity" : "swift-system",
|
|
||||||
"kind" : "remoteSourceControl",
|
|
||||||
"location" : "https://github.com/apple/swift-system.git",
|
|
||||||
"state" : {
|
|
||||||
"revision" : "d2ba781702a1d8285419c15ee62fd734a9437ff5",
|
|
||||||
"version" : "1.3.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version" : 3
|
"version" : 2
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1600"
|
LastUpgradeVersion = "1520"
|
||||||
version = "1.7">
|
version = "1.7">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
buildImplicitDependencies = "YES"
|
buildImplicitDependencies = "YES">
|
||||||
buildArchitectures = "Automatic">
|
|
||||||
<BuildActionEntries>
|
<BuildActionEntries>
|
||||||
<BuildActionEntry
|
<BuildActionEntry
|
||||||
buildForTesting = "YES"
|
buildForTesting = "YES"
|
||||||
|
|
@ -28,20 +27,7 @@
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
shouldAutocreateTestPlan = "NO">
|
shouldAutocreateTestPlan = "YES">
|
||||||
<Testables>
|
|
||||||
<TestableReference
|
|
||||||
skipped = "NO"
|
|
||||||
parallelizable = "YES">
|
|
||||||
<BuildableReference
|
|
||||||
BuildableIdentifier = "primary"
|
|
||||||
BlueprintIdentifier = "D11000082F70000100112233"
|
|
||||||
BuildableName = "BurrowUITests.xctest"
|
|
||||||
BlueprintName = "BurrowUITests"
|
|
||||||
ReferencedContainer = "container:Burrow.xcodeproj">
|
|
||||||
</BuildableReference>
|
|
||||||
</TestableReference>
|
|
||||||
</Testables>
|
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Debug"
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1600"
|
LastUpgradeVersion = "1520"
|
||||||
wasCreatedForAppExtension = "YES"
|
|
||||||
version = "2.0">
|
version = "2.0">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
buildImplicitDependencies = "YES"
|
buildImplicitDependencies = "YES">
|
||||||
buildArchitectures = "Automatic">
|
|
||||||
<BuildActionEntries>
|
<BuildActionEntries>
|
||||||
<BuildActionEntry
|
<BuildActionEntry
|
||||||
buildForTesting = "YES"
|
buildForTesting = "YES"
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
LD_EXPORT_SYMBOLS = NO
|
|
||||||
SKIP_INSTALL = NO
|
SKIP_INSTALL = NO
|
||||||
|
MERGED_BINARY_TYPE = manual
|
||||||
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks
|
LD_RUNPATH_SEARCH_PATHS[sdk=iphone*] = $(inherited) @executable_path/Frameworks
|
||||||
LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = $(inherited) @executable_path/../Frameworks
|
LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = $(inherited) @executable_path/../Frameworks
|
||||||
|
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor
|
||||||
|
|
||||||
|
ENABLE_PREVIEWS = YES
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,16 @@
|
||||||
#include "Identity.xcconfig"
|
#include "Identity.xcconfig"
|
||||||
#include "Debug.xcconfig"
|
|
||||||
#include "Version.xcconfig"
|
#include "Version.xcconfig"
|
||||||
|
|
||||||
SDKROOT = auto
|
SDKROOT = auto
|
||||||
ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES
|
ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES
|
||||||
|
|
||||||
SUPPORTED_PLATFORMS = iphoneos iphonesimulator macosx
|
SUPPORTED_PLATFORMS = iphoneos iphonesimulator macosx
|
||||||
SWIFT_VERSION = 6.0
|
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 17.0
|
IPHONEOS_DEPLOYMENT_TARGET = 17.0
|
||||||
MACOSX_DEPLOYMENT_TARGET = 14.0
|
MACOSX_DEPLOYMENT_TARGET = 14.0
|
||||||
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO
|
||||||
SUPPORTS_MACCATALYST = NO
|
SUPPORTS_MACCATALYST = NO
|
||||||
|
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO
|
||||||
PRODUCT_NAME = $(TARGET_NAME:c99extidentifier)
|
PRODUCT_NAME = $(TARGET_NAME:c99extidentifier)
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = $(APP_BUNDLE_IDENTIFIER).$(PRODUCT_NAME)
|
PRODUCT_BUNDLE_IDENTIFIER = $(APP_BUNDLE_IDENTIFIER).$(PRODUCT_NAME)
|
||||||
MARKETING_VERSION = 0.1
|
MARKETING_VERSION = 0.1
|
||||||
|
|
@ -20,24 +19,43 @@ SKIP_INSTALL = YES
|
||||||
|
|
||||||
CODE_SIGN_IDENTITY = Apple Development
|
CODE_SIGN_IDENTITY = Apple Development
|
||||||
|
|
||||||
GENERATE_INFOPLIST_FILE = YES
|
|
||||||
INFOPLIST_FILE = Configuration/Info.plist
|
INFOPLIST_FILE = Configuration/Info.plist
|
||||||
|
GENERATE_INFOPLIST_FILE = YES
|
||||||
INFOPLIST_KEY_NSHumanReadableCopyright = Copyright © 2023-2024 Hack Club
|
INFOPLIST_KEY_NSHumanReadableCopyright = Copyright © 2023-2024 Hack Club
|
||||||
INFOPLIST_KEY_CFBundleDisplayName = Burrow
|
INFOPLIST_KEY_CFBundleDisplayName = Burrow
|
||||||
|
|
||||||
ENABLE_APP_SANDBOX[sdk=macosx*] = YES
|
|
||||||
|
|
||||||
ENABLE_BITCODE = NO
|
ENABLE_BITCODE = NO
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO
|
|
||||||
|
ENABLE_APP_SANDBOX[sdk=macosx*] = YES
|
||||||
|
ENABLE_HARDENED_RUNTIME[sdk=macosx*] = YES
|
||||||
COMBINE_HIDPI_IMAGES = YES
|
COMBINE_HIDPI_IMAGES = YES
|
||||||
EAGER_LINKING = YES
|
COPY_PHASE_STRIP = NO
|
||||||
|
|
||||||
FUSE_BUILD_SCRIPT_PHASES = YES
|
FUSE_BUILD_SCRIPT_PHASES = YES
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES
|
|
||||||
LOCALIZATION_PREFERS_STRING_CATALOGS = YES
|
|
||||||
ENABLE_DEBUG_DYLIB = NO
|
|
||||||
|
|
||||||
APP_GROUP_IDENTIFIER = group.$(APP_BUNDLE_IDENTIFIER)
|
APP_GROUP_IDENTIFIER = group.$(APP_BUNDLE_IDENTIFIER)
|
||||||
APP_GROUP_IDENTIFIER[sdk=macosx*] = $(DEVELOPMENT_TEAM).$(APP_BUNDLE_IDENTIFIER)
|
APP_GROUP_IDENTIFIER[sdk=macosx*] = $(DEVELOPMENT_TEAM).$(APP_BUNDLE_IDENTIFIER)
|
||||||
NETWORK_EXTENSION_BUNDLE_IDENTIFIER = $(APP_BUNDLE_IDENTIFIER).network
|
NETWORK_EXTENSION_BUNDLE_IDENTIFIER = $(APP_BUNDLE_IDENTIFIER).network
|
||||||
|
|
||||||
OTHER_SWIFT_FLAGS = $(inherited)
|
// Swift
|
||||||
|
SWIFT_VERSION = 5.0
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES
|
||||||
|
|
||||||
|
// Release
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
|
||||||
|
SWIFT_COMPILATION_MODE = wholemodule
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = -Osize
|
||||||
|
LLVM_LTO = YES
|
||||||
|
DEAD_CODE_STRIPPING = YES
|
||||||
|
VALIDATE_PRODUCT = YES
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
ONLY_ACTIVE_ARCH[config=Debug] = YES
|
||||||
|
DEBUG_INFORMATION_FORMAT[config=Debug] = dwarf
|
||||||
|
ENABLE_TESTABILITY[config=Debug] = YES
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL[config=Debug] = -Onone
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=Debug] = DEBUG
|
||||||
|
SWIFT_COMPILATION_MODE[config=Debug] = singlefile
|
||||||
|
LLVM_LTO[config=Debug] = NO
|
||||||
|
DEAD_CODE_STRIPPING[config=Debug] = NO
|
||||||
|
VALIDATE_PRODUCT[config=Debug] = NO
|
||||||
|
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
@_implementationOnly import CConstants
|
|
||||||
import Foundation
|
|
||||||
import OSLog
|
|
||||||
|
|
||||||
public enum Constants {
|
|
||||||
enum Error: Swift.Error {
|
|
||||||
case invalidAppGroupIdentifier
|
|
||||||
}
|
|
||||||
|
|
||||||
public static let bundleIdentifier = AppBundleIdentifier
|
|
||||||
public static let appGroupIdentifier = AppGroupIdentifier
|
|
||||||
public static let networkExtensionBundleIdentifier = NetworkExtensionBundleIdentifier
|
|
||||||
|
|
||||||
public static var socketURL: URL {
|
|
||||||
get throws {
|
|
||||||
try groupContainerURL.appending(component: "burrow.sock", directoryHint: .notDirectory)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static var databaseURL: URL {
|
|
||||||
get throws {
|
|
||||||
try groupContainerURL.appending(component: "burrow.db", directoryHint: .notDirectory)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static var groupContainerURL: URL {
|
|
||||||
get throws { try _groupContainerURL.get() }
|
|
||||||
}
|
|
||||||
private static let _groupContainerURL: Result<URL, Error> = {
|
|
||||||
switch FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupIdentifier) {
|
|
||||||
case .some(let url): .success(url)
|
|
||||||
case .none:
|
|
||||||
fallbackContainerURL().mapError { _ in .invalidAppGroupIdentifier }
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
private static func fallbackContainerURL() -> Result<URL, any Swift.Error> {
|
|
||||||
#if targetEnvironment(simulator)
|
|
||||||
Result {
|
|
||||||
// The simulator app's Application Support path lives inside its sandbox container,
|
|
||||||
// so the host daemon cannot reach it. Use a shared host temp location instead.
|
|
||||||
let url = URL(filePath: "/tmp", directoryHint: .isDirectory)
|
|
||||||
.appending(component: bundleIdentifier, directoryHint: .isDirectory)
|
|
||||||
.appending(component: "SimulatorFallback", directoryHint: .isDirectory)
|
|
||||||
try FileManager.default.createDirectory(at: url, withIntermediateDirectories: true)
|
|
||||||
return url
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
.failure(Error.invalidAppGroupIdentifier)
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Logger {
|
|
||||||
@_dynamicReplacement(for: subsystem)
|
|
||||||
public static var subsystem: String { Constants.bundleIdentifier }
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
// Release
|
|
||||||
DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
|
|
||||||
SWIFT_COMPILATION_MODE = wholemodule
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL = -Osize
|
|
||||||
LLVM_LTO = YES
|
|
||||||
DEAD_CODE_STRIPPING = YES
|
|
||||||
STRIP_INSTALLED_PRODUCT = YES
|
|
||||||
STRIP_SWIFT_SYMBOLS = YES
|
|
||||||
COPY_PHASE_STRIP = NO
|
|
||||||
VALIDATE_PRODUCT = YES
|
|
||||||
ENABLE_MODULE_VERIFIER = YES
|
|
||||||
|
|
||||||
// Debug
|
|
||||||
ONLY_ACTIVE_ARCH[config=Debug] = YES
|
|
||||||
DEBUG_INFORMATION_FORMAT[config=Debug] = dwarf
|
|
||||||
ENABLE_TESTABILITY[config=Debug] = YES
|
|
||||||
GCC_PREPROCESSOR_DEFINITIONS[config=Debug] = DEBUG=1 $(inherited)
|
|
||||||
SWIFT_OPTIMIZATION_LEVEL[config=Debug] = -Onone
|
|
||||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS[config=Debug] = DEBUG
|
|
||||||
SWIFT_COMPILATION_MODE[config=Debug] = singlefile
|
|
||||||
LLVM_LTO[config=Debug] = NO
|
|
||||||
DEAD_CODE_STRIPPING[config=Debug] = NO
|
|
||||||
VALIDATE_PRODUCT[config=Debug] = NO
|
|
||||||
STRIP_INSTALLED_PRODUCT[config=Debug] = NO
|
|
||||||
STRIP_SWIFT_SYMBOLS[config=Debug] = NO
|
|
||||||
ENABLE_MODULE_VERIFIER[config=Debug] = NO
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
LD_EXPORT_SYMBOLS = NO
|
MERGED_BINARY_TYPE = manual
|
||||||
|
|
||||||
OTHER_SWIFT_FLAGS = $(inherited) -Xfrontend -disable-autolink-framework -Xfrontend UIKit -Xfrontend -disable-autolink-framework -Xfrontend AppKit -Xfrontend -disable-autolink-framework -Xfrontend SwiftUI
|
|
||||||
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks @executable_path/../../Frameworks
|
LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks @executable_path/../../Frameworks
|
||||||
LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = $(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks
|
LD_RUNPATH_SEARCH_PATHS[sdk=macos*] = $(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks
|
||||||
|
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
PRODUCT_NAME = Burrow$(TARGET_NAME:c99extidentifier)
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = $(APP_BUNDLE_IDENTIFIER).$(TARGET_NAME:c99extidentifier)
|
|
||||||
APPLICATION_EXTENSION_API_ONLY = YES
|
|
||||||
SWIFT_INSTALL_OBJC_HEADER = NO
|
|
||||||
SWIFT_SKIP_AUTOLINKING_FRAMEWORKS = YES
|
|
||||||
SWIFT_SKIP_AUTOLINKING_LIBRARIES = YES
|
|
||||||
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks @loader_path/Frameworks
|
|
||||||
LD_RUNPATH_SEARCH_PATHS[sdk=macosx*] = $(inherited) @executable_path/../Frameworks @loader_path/Frameworks
|
|
||||||
|
|
||||||
DYLIB_INSTALL_NAME_BASE = @rpath
|
|
||||||
DYLIB_COMPATIBILITY_VERSION = 1
|
|
||||||
DYLIB_CURRENT_VERSION = 1
|
|
||||||
VERSIONING_SYSTEM =
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
#include "Compiler.xcconfig"
|
|
||||||
|
|
||||||
SUPPORTED_PLATFORMS = iphonesimulator iphoneos
|
|
||||||
TARGETED_DEVICE_FAMILY[sdk=iphone*] = 1,2
|
|
||||||
|
|
||||||
PRODUCT_NAME = $(TARGET_NAME)
|
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = $(APP_BUNDLE_IDENTIFIER).uitests
|
|
||||||
|
|
||||||
STRING_CATALOG_GENERATE_SYMBOLS = NO
|
|
||||||
SWIFT_EMIT_LOC_STRINGS = NO
|
|
||||||
|
|
||||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
|
|
||||||
LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/Frameworks @loader_path/Frameworks
|
|
||||||
TEST_TARGET_NAME = App
|
|
||||||
|
|
@ -1,508 +0,0 @@
|
||||||
import Foundation
|
|
||||||
import GRPC
|
|
||||||
import NIOTransportServices
|
|
||||||
import SwiftProtobuf
|
|
||||||
|
|
||||||
public typealias TunnelClient = Burrow_TunnelAsyncClient
|
|
||||||
public typealias NetworksClient = Burrow_NetworksAsyncClient
|
|
||||||
|
|
||||||
public protocol Client {
|
|
||||||
init(channel: GRPCChannel)
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Client {
|
|
||||||
public static func unix(socketURL: URL) -> Self {
|
|
||||||
let group = NIOTSEventLoopGroup()
|
|
||||||
let configuration = ClientConnection.Configuration.default(
|
|
||||||
target: .unixDomainSocket(socketURL.path),
|
|
||||||
eventLoopGroup: group
|
|
||||||
)
|
|
||||||
return Self(channel: ClientConnection(configuration: configuration))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension TunnelClient: Client {
|
|
||||||
public init(channel: any GRPCChannel) {
|
|
||||||
self.init(channel: channel, defaultCallOptions: .init(), interceptors: .none)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension NetworksClient: Client {
|
|
||||||
public init(channel: any GRPCChannel) {
|
|
||||||
self.init(channel: channel, defaultCallOptions: .init(), interceptors: .none)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_TailnetDiscoverRequest: Sendable {
|
|
||||||
public var email: String = ""
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_TailnetDiscoverResponse: Sendable {
|
|
||||||
public var domain: String = ""
|
|
||||||
public var authority: String = ""
|
|
||||||
public var oidcIssuer: String = ""
|
|
||||||
public var managed: Bool = false
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_TailnetProbeRequest: Sendable {
|
|
||||||
public var authority: String = ""
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_TailnetProbeResponse: Sendable {
|
|
||||||
public var authority: String = ""
|
|
||||||
public var statusCode: Int32 = 0
|
|
||||||
public var summary: String = ""
|
|
||||||
public var detail: String = ""
|
|
||||||
public var reachable: Bool = false
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_TailnetLoginStartRequest: Sendable {
|
|
||||||
public var accountName: String = ""
|
|
||||||
public var identityName: String = ""
|
|
||||||
public var hostname: String = ""
|
|
||||||
public var authority: String = ""
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_TailnetLoginStatusRequest: Sendable {
|
|
||||||
public var sessionID: String = ""
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_TailnetLoginCancelRequest: Sendable {
|
|
||||||
public var sessionID: String = ""
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_TailnetLoginStatusResponse: Sendable {
|
|
||||||
public var sessionID: String = ""
|
|
||||||
public var backendState: String = ""
|
|
||||||
public var authURL: String = ""
|
|
||||||
public var running: Bool = false
|
|
||||||
public var needsLogin: Bool = false
|
|
||||||
public var tailnetName: String = ""
|
|
||||||
public var magicDNSSuffix: String = ""
|
|
||||||
public var selfDNSName: String = ""
|
|
||||||
public var tailnetIPs: [String] = []
|
|
||||||
public var health: [String] = []
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_TunnelPacket: Sendable {
|
|
||||||
public var payload = Data()
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_TailnetDiscoverRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = "burrow.TailnetDiscoverRequest"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "email")
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularStringField(value: &self.email)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if !self.email.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.email, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_TailnetDiscoverResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = "burrow.TailnetDiscoverResponse"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "domain"),
|
|
||||||
2: .same(proto: "authority"),
|
|
||||||
3: .same(proto: "oidc_issuer"),
|
|
||||||
4: .same(proto: "managed"),
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularStringField(value: &self.domain)
|
|
||||||
case 2: try decoder.decodeSingularStringField(value: &self.authority)
|
|
||||||
case 3: try decoder.decodeSingularStringField(value: &self.oidcIssuer)
|
|
||||||
case 4: try decoder.decodeSingularBoolField(value: &self.managed)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if !self.domain.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.domain, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if !self.authority.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.authority, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if !self.oidcIssuer.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.oidcIssuer, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
if self.managed {
|
|
||||||
try visitor.visitSingularBoolField(value: self.managed, fieldNumber: 4)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_TailnetProbeRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = "burrow.TailnetProbeRequest"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "authority")
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularStringField(value: &self.authority)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if !self.authority.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.authority, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_TailnetProbeResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = "burrow.TailnetProbeResponse"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "authority"),
|
|
||||||
2: .same(proto: "status_code"),
|
|
||||||
3: .same(proto: "summary"),
|
|
||||||
4: .same(proto: "detail"),
|
|
||||||
5: .same(proto: "reachable"),
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularStringField(value: &self.authority)
|
|
||||||
case 2: try decoder.decodeSingularInt32Field(value: &self.statusCode)
|
|
||||||
case 3: try decoder.decodeSingularStringField(value: &self.summary)
|
|
||||||
case 4: try decoder.decodeSingularStringField(value: &self.detail)
|
|
||||||
case 5: try decoder.decodeSingularBoolField(value: &self.reachable)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if !self.authority.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.authority, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if self.statusCode != 0 {
|
|
||||||
try visitor.visitSingularInt32Field(value: self.statusCode, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if !self.summary.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.summary, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
if !self.detail.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.detail, fieldNumber: 4)
|
|
||||||
}
|
|
||||||
if self.reachable {
|
|
||||||
try visitor.visitSingularBoolField(value: self.reachable, fieldNumber: 5)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_TailnetLoginStartRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = "burrow.TailnetLoginStartRequest"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .standard(proto: "account_name"),
|
|
||||||
2: .standard(proto: "identity_name"),
|
|
||||||
3: .same(proto: "hostname"),
|
|
||||||
4: .same(proto: "authority"),
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularStringField(value: &self.accountName)
|
|
||||||
case 2: try decoder.decodeSingularStringField(value: &self.identityName)
|
|
||||||
case 3: try decoder.decodeSingularStringField(value: &self.hostname)
|
|
||||||
case 4: try decoder.decodeSingularStringField(value: &self.authority)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if !self.accountName.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.accountName, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if !self.identityName.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.identityName, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if !self.hostname.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.hostname, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
if !self.authority.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.authority, fieldNumber: 4)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_TailnetLoginStatusRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = "burrow.TailnetLoginStatusRequest"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .standard(proto: "session_id")
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularStringField(value: &self.sessionID)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if !self.sessionID.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.sessionID, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_TailnetLoginCancelRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = "burrow.TailnetLoginCancelRequest"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .standard(proto: "session_id")
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularStringField(value: &self.sessionID)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if !self.sessionID.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.sessionID, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_TailnetLoginStatusResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = "burrow.TailnetLoginStatusResponse"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .standard(proto: "session_id"),
|
|
||||||
2: .standard(proto: "backend_state"),
|
|
||||||
3: .standard(proto: "auth_url"),
|
|
||||||
4: .same(proto: "running"),
|
|
||||||
5: .standard(proto: "needs_login"),
|
|
||||||
6: .standard(proto: "tailnet_name"),
|
|
||||||
7: .standard(proto: "magic_dns_suffix"),
|
|
||||||
8: .standard(proto: "self_dns_name"),
|
|
||||||
9: .standard(proto: "tailnet_ips"),
|
|
||||||
10: .same(proto: "health"),
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularStringField(value: &self.sessionID)
|
|
||||||
case 2: try decoder.decodeSingularStringField(value: &self.backendState)
|
|
||||||
case 3: try decoder.decodeSingularStringField(value: &self.authURL)
|
|
||||||
case 4: try decoder.decodeSingularBoolField(value: &self.running)
|
|
||||||
case 5: try decoder.decodeSingularBoolField(value: &self.needsLogin)
|
|
||||||
case 6: try decoder.decodeSingularStringField(value: &self.tailnetName)
|
|
||||||
case 7: try decoder.decodeSingularStringField(value: &self.magicDNSSuffix)
|
|
||||||
case 8: try decoder.decodeSingularStringField(value: &self.selfDNSName)
|
|
||||||
case 9: try decoder.decodeRepeatedStringField(value: &self.tailnetIPs)
|
|
||||||
case 10: try decoder.decodeRepeatedStringField(value: &self.health)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if !self.sessionID.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.sessionID, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if !self.backendState.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.backendState, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if !self.authURL.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.authURL, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
if self.running {
|
|
||||||
try visitor.visitSingularBoolField(value: self.running, fieldNumber: 4)
|
|
||||||
}
|
|
||||||
if self.needsLogin {
|
|
||||||
try visitor.visitSingularBoolField(value: self.needsLogin, fieldNumber: 5)
|
|
||||||
}
|
|
||||||
if !self.tailnetName.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.tailnetName, fieldNumber: 6)
|
|
||||||
}
|
|
||||||
if !self.magicDNSSuffix.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.magicDNSSuffix, fieldNumber: 7)
|
|
||||||
}
|
|
||||||
if !self.selfDNSName.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.selfDNSName, fieldNumber: 8)
|
|
||||||
}
|
|
||||||
if !self.tailnetIPs.isEmpty {
|
|
||||||
try visitor.visitRepeatedStringField(value: self.tailnetIPs, fieldNumber: 9)
|
|
||||||
}
|
|
||||||
if !self.health.isEmpty {
|
|
||||||
try visitor.visitRepeatedStringField(value: self.health, fieldNumber: 10)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_TunnelPacket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = "burrow.TunnelPacket"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "payload")
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try decoder.decodeSingularBytesField(value: &self.payload)
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if !self.payload.isEmpty {
|
|
||||||
try visitor.visitSingularBytesField(value: self.payload, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct TailnetClient: Client, GRPCClient {
|
|
||||||
public let channel: GRPCChannel
|
|
||||||
public var defaultCallOptions: CallOptions
|
|
||||||
|
|
||||||
public init(channel: any GRPCChannel) {
|
|
||||||
self.channel = channel
|
|
||||||
self.defaultCallOptions = .init()
|
|
||||||
}
|
|
||||||
|
|
||||||
public func discover(
|
|
||||||
_ request: Burrow_TailnetDiscoverRequest,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) async throws -> Burrow_TailnetDiscoverResponse {
|
|
||||||
try await self.performAsyncUnaryCall(
|
|
||||||
path: "/burrow.TailnetControl/Discover",
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func probe(
|
|
||||||
_ request: Burrow_TailnetProbeRequest,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) async throws -> Burrow_TailnetProbeResponse {
|
|
||||||
try await self.performAsyncUnaryCall(
|
|
||||||
path: "/burrow.TailnetControl/Probe",
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func loginStart(
|
|
||||||
_ request: Burrow_TailnetLoginStartRequest,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) async throws -> Burrow_TailnetLoginStatusResponse {
|
|
||||||
try await self.performAsyncUnaryCall(
|
|
||||||
path: "/burrow.TailnetControl/LoginStart",
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func loginStatus(
|
|
||||||
_ request: Burrow_TailnetLoginStatusRequest,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) async throws -> Burrow_TailnetLoginStatusResponse {
|
|
||||||
try await self.performAsyncUnaryCall(
|
|
||||||
path: "/burrow.TailnetControl/LoginStatus",
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func loginCancel(
|
|
||||||
_ request: Burrow_TailnetLoginCancelRequest,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) async throws -> Burrow_Empty {
|
|
||||||
try await self.performAsyncUnaryCall(
|
|
||||||
path: "/burrow.TailnetControl/LoginCancel",
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct TunnelPacketClient: Client, GRPCClient {
|
|
||||||
public let channel: GRPCChannel
|
|
||||||
public var defaultCallOptions: CallOptions
|
|
||||||
|
|
||||||
public init(channel: any GRPCChannel) {
|
|
||||||
self.channel = channel
|
|
||||||
self.defaultCallOptions = .init()
|
|
||||||
}
|
|
||||||
|
|
||||||
public func makeTunnelPacketsCall(
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> GRPCAsyncBidirectionalStreamingCall<Burrow_TunnelPacket, Burrow_TunnelPacket> {
|
|
||||||
self.makeAsyncBidirectionalStreamingCall(
|
|
||||||
path: "/burrow.Tunnel/TunnelPackets",
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,761 +0,0 @@
|
||||||
//
|
|
||||||
// DO NOT EDIT.
|
|
||||||
// swift-format-ignore-file
|
|
||||||
//
|
|
||||||
// Generated by the protocol buffer compiler.
|
|
||||||
// Source: burrow.proto
|
|
||||||
//
|
|
||||||
import GRPC
|
|
||||||
import NIO
|
|
||||||
import NIOConcurrencyHelpers
|
|
||||||
import SwiftProtobuf
|
|
||||||
|
|
||||||
|
|
||||||
/// Usage: instantiate `Burrow_TunnelClient`, then call methods of this protocol to make API calls.
|
|
||||||
public protocol Burrow_TunnelClientProtocol: GRPCClient {
|
|
||||||
var serviceName: String { get }
|
|
||||||
var interceptors: Burrow_TunnelClientInterceptorFactoryProtocol? { get }
|
|
||||||
|
|
||||||
func tunnelConfiguration(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions?,
|
|
||||||
handler: @escaping (Burrow_TunnelConfigurationResponse) -> Void
|
|
||||||
) -> ServerStreamingCall<Burrow_Empty, Burrow_TunnelConfigurationResponse>
|
|
||||||
|
|
||||||
func tunnelStart(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions?
|
|
||||||
) -> UnaryCall<Burrow_Empty, Burrow_Empty>
|
|
||||||
|
|
||||||
func tunnelStop(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions?
|
|
||||||
) -> UnaryCall<Burrow_Empty, Burrow_Empty>
|
|
||||||
|
|
||||||
func tunnelStatus(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions?,
|
|
||||||
handler: @escaping (Burrow_TunnelStatusResponse) -> Void
|
|
||||||
) -> ServerStreamingCall<Burrow_Empty, Burrow_TunnelStatusResponse>
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_TunnelClientProtocol {
|
|
||||||
public var serviceName: String {
|
|
||||||
return "burrow.Tunnel"
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Server streaming call to TunnelConfiguration
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - request: Request to send to TunnelConfiguration.
|
|
||||||
/// - callOptions: Call options.
|
|
||||||
/// - handler: A closure called when each response is received from the server.
|
|
||||||
/// - Returns: A `ServerStreamingCall` with futures for the metadata and status.
|
|
||||||
public func tunnelConfiguration(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions? = nil,
|
|
||||||
handler: @escaping (Burrow_TunnelConfigurationResponse) -> Void
|
|
||||||
) -> ServerStreamingCall<Burrow_Empty, Burrow_TunnelConfigurationResponse> {
|
|
||||||
return self.makeServerStreamingCall(
|
|
||||||
path: Burrow_TunnelClientMetadata.Methods.tunnelConfiguration.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeTunnelConfigurationInterceptors() ?? [],
|
|
||||||
handler: handler
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unary call to TunnelStart
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - request: Request to send to TunnelStart.
|
|
||||||
/// - callOptions: Call options.
|
|
||||||
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
|
|
||||||
public func tunnelStart(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> UnaryCall<Burrow_Empty, Burrow_Empty> {
|
|
||||||
return self.makeUnaryCall(
|
|
||||||
path: Burrow_TunnelClientMetadata.Methods.tunnelStart.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeTunnelStartInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unary call to TunnelStop
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - request: Request to send to TunnelStop.
|
|
||||||
/// - callOptions: Call options.
|
|
||||||
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
|
|
||||||
public func tunnelStop(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> UnaryCall<Burrow_Empty, Burrow_Empty> {
|
|
||||||
return self.makeUnaryCall(
|
|
||||||
path: Burrow_TunnelClientMetadata.Methods.tunnelStop.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeTunnelStopInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Server streaming call to TunnelStatus
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - request: Request to send to TunnelStatus.
|
|
||||||
/// - callOptions: Call options.
|
|
||||||
/// - handler: A closure called when each response is received from the server.
|
|
||||||
/// - Returns: A `ServerStreamingCall` with futures for the metadata and status.
|
|
||||||
public func tunnelStatus(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions? = nil,
|
|
||||||
handler: @escaping (Burrow_TunnelStatusResponse) -> Void
|
|
||||||
) -> ServerStreamingCall<Burrow_Empty, Burrow_TunnelStatusResponse> {
|
|
||||||
return self.makeServerStreamingCall(
|
|
||||||
path: Burrow_TunnelClientMetadata.Methods.tunnelStatus.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeTunnelStatusInterceptors() ?? [],
|
|
||||||
handler: handler
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(*, deprecated)
|
|
||||||
extension Burrow_TunnelClient: @unchecked Sendable {}
|
|
||||||
|
|
||||||
@available(*, deprecated, renamed: "Burrow_TunnelNIOClient")
|
|
||||||
public final class Burrow_TunnelClient: Burrow_TunnelClientProtocol {
|
|
||||||
private let lock = Lock()
|
|
||||||
private var _defaultCallOptions: CallOptions
|
|
||||||
private var _interceptors: Burrow_TunnelClientInterceptorFactoryProtocol?
|
|
||||||
public let channel: GRPCChannel
|
|
||||||
public var defaultCallOptions: CallOptions {
|
|
||||||
get { self.lock.withLock { return self._defaultCallOptions } }
|
|
||||||
set { self.lock.withLockVoid { self._defaultCallOptions = newValue } }
|
|
||||||
}
|
|
||||||
public var interceptors: Burrow_TunnelClientInterceptorFactoryProtocol? {
|
|
||||||
get { self.lock.withLock { return self._interceptors } }
|
|
||||||
set { self.lock.withLockVoid { self._interceptors = newValue } }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a client for the burrow.Tunnel service.
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - channel: `GRPCChannel` to the service host.
|
|
||||||
/// - defaultCallOptions: Options to use for each service call if the user doesn't provide them.
|
|
||||||
/// - interceptors: A factory providing interceptors for each RPC.
|
|
||||||
public init(
|
|
||||||
channel: GRPCChannel,
|
|
||||||
defaultCallOptions: CallOptions = CallOptions(),
|
|
||||||
interceptors: Burrow_TunnelClientInterceptorFactoryProtocol? = nil
|
|
||||||
) {
|
|
||||||
self.channel = channel
|
|
||||||
self._defaultCallOptions = defaultCallOptions
|
|
||||||
self._interceptors = interceptors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_TunnelNIOClient: Burrow_TunnelClientProtocol {
|
|
||||||
public var channel: GRPCChannel
|
|
||||||
public var defaultCallOptions: CallOptions
|
|
||||||
public var interceptors: Burrow_TunnelClientInterceptorFactoryProtocol?
|
|
||||||
|
|
||||||
/// Creates a client for the burrow.Tunnel service.
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - channel: `GRPCChannel` to the service host.
|
|
||||||
/// - defaultCallOptions: Options to use for each service call if the user doesn't provide them.
|
|
||||||
/// - interceptors: A factory providing interceptors for each RPC.
|
|
||||||
public init(
|
|
||||||
channel: GRPCChannel,
|
|
||||||
defaultCallOptions: CallOptions = CallOptions(),
|
|
||||||
interceptors: Burrow_TunnelClientInterceptorFactoryProtocol? = nil
|
|
||||||
) {
|
|
||||||
self.channel = channel
|
|
||||||
self.defaultCallOptions = defaultCallOptions
|
|
||||||
self.interceptors = interceptors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
|
|
||||||
public protocol Burrow_TunnelAsyncClientProtocol: GRPCClient {
|
|
||||||
static var serviceDescriptor: GRPCServiceDescriptor { get }
|
|
||||||
var interceptors: Burrow_TunnelClientInterceptorFactoryProtocol? { get }
|
|
||||||
|
|
||||||
func makeTunnelConfigurationCall(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions?
|
|
||||||
) -> GRPCAsyncServerStreamingCall<Burrow_Empty, Burrow_TunnelConfigurationResponse>
|
|
||||||
|
|
||||||
func makeTunnelStartCall(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions?
|
|
||||||
) -> GRPCAsyncUnaryCall<Burrow_Empty, Burrow_Empty>
|
|
||||||
|
|
||||||
func makeTunnelStopCall(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions?
|
|
||||||
) -> GRPCAsyncUnaryCall<Burrow_Empty, Burrow_Empty>
|
|
||||||
|
|
||||||
func makeTunnelStatusCall(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions?
|
|
||||||
) -> GRPCAsyncServerStreamingCall<Burrow_Empty, Burrow_TunnelStatusResponse>
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
|
|
||||||
extension Burrow_TunnelAsyncClientProtocol {
|
|
||||||
public static var serviceDescriptor: GRPCServiceDescriptor {
|
|
||||||
return Burrow_TunnelClientMetadata.serviceDescriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
public var interceptors: Burrow_TunnelClientInterceptorFactoryProtocol? {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
public func makeTunnelConfigurationCall(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> GRPCAsyncServerStreamingCall<Burrow_Empty, Burrow_TunnelConfigurationResponse> {
|
|
||||||
return self.makeAsyncServerStreamingCall(
|
|
||||||
path: Burrow_TunnelClientMetadata.Methods.tunnelConfiguration.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeTunnelConfigurationInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func makeTunnelStartCall(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> GRPCAsyncUnaryCall<Burrow_Empty, Burrow_Empty> {
|
|
||||||
return self.makeAsyncUnaryCall(
|
|
||||||
path: Burrow_TunnelClientMetadata.Methods.tunnelStart.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeTunnelStartInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func makeTunnelStopCall(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> GRPCAsyncUnaryCall<Burrow_Empty, Burrow_Empty> {
|
|
||||||
return self.makeAsyncUnaryCall(
|
|
||||||
path: Burrow_TunnelClientMetadata.Methods.tunnelStop.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeTunnelStopInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func makeTunnelStatusCall(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> GRPCAsyncServerStreamingCall<Burrow_Empty, Burrow_TunnelStatusResponse> {
|
|
||||||
return self.makeAsyncServerStreamingCall(
|
|
||||||
path: Burrow_TunnelClientMetadata.Methods.tunnelStatus.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeTunnelStatusInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
|
|
||||||
extension Burrow_TunnelAsyncClientProtocol {
|
|
||||||
public func tunnelConfiguration(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> GRPCAsyncResponseStream<Burrow_TunnelConfigurationResponse> {
|
|
||||||
return self.performAsyncServerStreamingCall(
|
|
||||||
path: Burrow_TunnelClientMetadata.Methods.tunnelConfiguration.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeTunnelConfigurationInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func tunnelStart(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) async throws -> Burrow_Empty {
|
|
||||||
return try await self.performAsyncUnaryCall(
|
|
||||||
path: Burrow_TunnelClientMetadata.Methods.tunnelStart.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeTunnelStartInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func tunnelStop(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) async throws -> Burrow_Empty {
|
|
||||||
return try await self.performAsyncUnaryCall(
|
|
||||||
path: Burrow_TunnelClientMetadata.Methods.tunnelStop.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeTunnelStopInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func tunnelStatus(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> GRPCAsyncResponseStream<Burrow_TunnelStatusResponse> {
|
|
||||||
return self.performAsyncServerStreamingCall(
|
|
||||||
path: Burrow_TunnelClientMetadata.Methods.tunnelStatus.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeTunnelStatusInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
|
|
||||||
public struct Burrow_TunnelAsyncClient: Burrow_TunnelAsyncClientProtocol {
|
|
||||||
public var channel: GRPCChannel
|
|
||||||
public var defaultCallOptions: CallOptions
|
|
||||||
public var interceptors: Burrow_TunnelClientInterceptorFactoryProtocol?
|
|
||||||
|
|
||||||
public init(
|
|
||||||
channel: GRPCChannel,
|
|
||||||
defaultCallOptions: CallOptions = CallOptions(),
|
|
||||||
interceptors: Burrow_TunnelClientInterceptorFactoryProtocol? = nil
|
|
||||||
) {
|
|
||||||
self.channel = channel
|
|
||||||
self.defaultCallOptions = defaultCallOptions
|
|
||||||
self.interceptors = interceptors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public protocol Burrow_TunnelClientInterceptorFactoryProtocol: Sendable {
|
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when invoking 'tunnelConfiguration'.
|
|
||||||
func makeTunnelConfigurationInterceptors() -> [ClientInterceptor<Burrow_Empty, Burrow_TunnelConfigurationResponse>]
|
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when invoking 'tunnelStart'.
|
|
||||||
func makeTunnelStartInterceptors() -> [ClientInterceptor<Burrow_Empty, Burrow_Empty>]
|
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when invoking 'tunnelStop'.
|
|
||||||
func makeTunnelStopInterceptors() -> [ClientInterceptor<Burrow_Empty, Burrow_Empty>]
|
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when invoking 'tunnelStatus'.
|
|
||||||
func makeTunnelStatusInterceptors() -> [ClientInterceptor<Burrow_Empty, Burrow_TunnelStatusResponse>]
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Burrow_TunnelClientMetadata {
|
|
||||||
public static let serviceDescriptor = GRPCServiceDescriptor(
|
|
||||||
name: "Tunnel",
|
|
||||||
fullName: "burrow.Tunnel",
|
|
||||||
methods: [
|
|
||||||
Burrow_TunnelClientMetadata.Methods.tunnelConfiguration,
|
|
||||||
Burrow_TunnelClientMetadata.Methods.tunnelStart,
|
|
||||||
Burrow_TunnelClientMetadata.Methods.tunnelStop,
|
|
||||||
Burrow_TunnelClientMetadata.Methods.tunnelStatus,
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
public enum Methods {
|
|
||||||
public static let tunnelConfiguration = GRPCMethodDescriptor(
|
|
||||||
name: "TunnelConfiguration",
|
|
||||||
path: "/burrow.Tunnel/TunnelConfiguration",
|
|
||||||
type: GRPCCallType.serverStreaming
|
|
||||||
)
|
|
||||||
|
|
||||||
public static let tunnelStart = GRPCMethodDescriptor(
|
|
||||||
name: "TunnelStart",
|
|
||||||
path: "/burrow.Tunnel/TunnelStart",
|
|
||||||
type: GRPCCallType.unary
|
|
||||||
)
|
|
||||||
|
|
||||||
public static let tunnelStop = GRPCMethodDescriptor(
|
|
||||||
name: "TunnelStop",
|
|
||||||
path: "/burrow.Tunnel/TunnelStop",
|
|
||||||
type: GRPCCallType.unary
|
|
||||||
)
|
|
||||||
|
|
||||||
public static let tunnelStatus = GRPCMethodDescriptor(
|
|
||||||
name: "TunnelStatus",
|
|
||||||
path: "/burrow.Tunnel/TunnelStatus",
|
|
||||||
type: GRPCCallType.serverStreaming
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Usage: instantiate `Burrow_NetworksClient`, then call methods of this protocol to make API calls.
|
|
||||||
public protocol Burrow_NetworksClientProtocol: GRPCClient {
|
|
||||||
var serviceName: String { get }
|
|
||||||
var interceptors: Burrow_NetworksClientInterceptorFactoryProtocol? { get }
|
|
||||||
|
|
||||||
func networkAdd(
|
|
||||||
_ request: Burrow_Network,
|
|
||||||
callOptions: CallOptions?
|
|
||||||
) -> UnaryCall<Burrow_Network, Burrow_Empty>
|
|
||||||
|
|
||||||
func networkList(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions?,
|
|
||||||
handler: @escaping (Burrow_NetworkListResponse) -> Void
|
|
||||||
) -> ServerStreamingCall<Burrow_Empty, Burrow_NetworkListResponse>
|
|
||||||
|
|
||||||
func networkReorder(
|
|
||||||
_ request: Burrow_NetworkReorderRequest,
|
|
||||||
callOptions: CallOptions?
|
|
||||||
) -> UnaryCall<Burrow_NetworkReorderRequest, Burrow_Empty>
|
|
||||||
|
|
||||||
func networkDelete(
|
|
||||||
_ request: Burrow_NetworkDeleteRequest,
|
|
||||||
callOptions: CallOptions?
|
|
||||||
) -> UnaryCall<Burrow_NetworkDeleteRequest, Burrow_Empty>
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_NetworksClientProtocol {
|
|
||||||
public var serviceName: String {
|
|
||||||
return "burrow.Networks"
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unary call to NetworkAdd
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - request: Request to send to NetworkAdd.
|
|
||||||
/// - callOptions: Call options.
|
|
||||||
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
|
|
||||||
public func networkAdd(
|
|
||||||
_ request: Burrow_Network,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> UnaryCall<Burrow_Network, Burrow_Empty> {
|
|
||||||
return self.makeUnaryCall(
|
|
||||||
path: Burrow_NetworksClientMetadata.Methods.networkAdd.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeNetworkAddInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Server streaming call to NetworkList
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - request: Request to send to NetworkList.
|
|
||||||
/// - callOptions: Call options.
|
|
||||||
/// - handler: A closure called when each response is received from the server.
|
|
||||||
/// - Returns: A `ServerStreamingCall` with futures for the metadata and status.
|
|
||||||
public func networkList(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions? = nil,
|
|
||||||
handler: @escaping (Burrow_NetworkListResponse) -> Void
|
|
||||||
) -> ServerStreamingCall<Burrow_Empty, Burrow_NetworkListResponse> {
|
|
||||||
return self.makeServerStreamingCall(
|
|
||||||
path: Burrow_NetworksClientMetadata.Methods.networkList.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeNetworkListInterceptors() ?? [],
|
|
||||||
handler: handler
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unary call to NetworkReorder
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - request: Request to send to NetworkReorder.
|
|
||||||
/// - callOptions: Call options.
|
|
||||||
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
|
|
||||||
public func networkReorder(
|
|
||||||
_ request: Burrow_NetworkReorderRequest,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> UnaryCall<Burrow_NetworkReorderRequest, Burrow_Empty> {
|
|
||||||
return self.makeUnaryCall(
|
|
||||||
path: Burrow_NetworksClientMetadata.Methods.networkReorder.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeNetworkReorderInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unary call to NetworkDelete
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - request: Request to send to NetworkDelete.
|
|
||||||
/// - callOptions: Call options.
|
|
||||||
/// - Returns: A `UnaryCall` with futures for the metadata, status and response.
|
|
||||||
public func networkDelete(
|
|
||||||
_ request: Burrow_NetworkDeleteRequest,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> UnaryCall<Burrow_NetworkDeleteRequest, Burrow_Empty> {
|
|
||||||
return self.makeUnaryCall(
|
|
||||||
path: Burrow_NetworksClientMetadata.Methods.networkDelete.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeNetworkDeleteInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(*, deprecated)
|
|
||||||
extension Burrow_NetworksClient: @unchecked Sendable {}
|
|
||||||
|
|
||||||
@available(*, deprecated, renamed: "Burrow_NetworksNIOClient")
|
|
||||||
public final class Burrow_NetworksClient: Burrow_NetworksClientProtocol {
|
|
||||||
private let lock = Lock()
|
|
||||||
private var _defaultCallOptions: CallOptions
|
|
||||||
private var _interceptors: Burrow_NetworksClientInterceptorFactoryProtocol?
|
|
||||||
public let channel: GRPCChannel
|
|
||||||
public var defaultCallOptions: CallOptions {
|
|
||||||
get { self.lock.withLock { return self._defaultCallOptions } }
|
|
||||||
set { self.lock.withLockVoid { self._defaultCallOptions = newValue } }
|
|
||||||
}
|
|
||||||
public var interceptors: Burrow_NetworksClientInterceptorFactoryProtocol? {
|
|
||||||
get { self.lock.withLock { return self._interceptors } }
|
|
||||||
set { self.lock.withLockVoid { self._interceptors = newValue } }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a client for the burrow.Networks service.
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - channel: `GRPCChannel` to the service host.
|
|
||||||
/// - defaultCallOptions: Options to use for each service call if the user doesn't provide them.
|
|
||||||
/// - interceptors: A factory providing interceptors for each RPC.
|
|
||||||
public init(
|
|
||||||
channel: GRPCChannel,
|
|
||||||
defaultCallOptions: CallOptions = CallOptions(),
|
|
||||||
interceptors: Burrow_NetworksClientInterceptorFactoryProtocol? = nil
|
|
||||||
) {
|
|
||||||
self.channel = channel
|
|
||||||
self._defaultCallOptions = defaultCallOptions
|
|
||||||
self._interceptors = interceptors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_NetworksNIOClient: Burrow_NetworksClientProtocol {
|
|
||||||
public var channel: GRPCChannel
|
|
||||||
public var defaultCallOptions: CallOptions
|
|
||||||
public var interceptors: Burrow_NetworksClientInterceptorFactoryProtocol?
|
|
||||||
|
|
||||||
/// Creates a client for the burrow.Networks service.
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - channel: `GRPCChannel` to the service host.
|
|
||||||
/// - defaultCallOptions: Options to use for each service call if the user doesn't provide them.
|
|
||||||
/// - interceptors: A factory providing interceptors for each RPC.
|
|
||||||
public init(
|
|
||||||
channel: GRPCChannel,
|
|
||||||
defaultCallOptions: CallOptions = CallOptions(),
|
|
||||||
interceptors: Burrow_NetworksClientInterceptorFactoryProtocol? = nil
|
|
||||||
) {
|
|
||||||
self.channel = channel
|
|
||||||
self.defaultCallOptions = defaultCallOptions
|
|
||||||
self.interceptors = interceptors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
|
|
||||||
public protocol Burrow_NetworksAsyncClientProtocol: GRPCClient {
|
|
||||||
static var serviceDescriptor: GRPCServiceDescriptor { get }
|
|
||||||
var interceptors: Burrow_NetworksClientInterceptorFactoryProtocol? { get }
|
|
||||||
|
|
||||||
func makeNetworkAddCall(
|
|
||||||
_ request: Burrow_Network,
|
|
||||||
callOptions: CallOptions?
|
|
||||||
) -> GRPCAsyncUnaryCall<Burrow_Network, Burrow_Empty>
|
|
||||||
|
|
||||||
func makeNetworkListCall(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions?
|
|
||||||
) -> GRPCAsyncServerStreamingCall<Burrow_Empty, Burrow_NetworkListResponse>
|
|
||||||
|
|
||||||
func makeNetworkReorderCall(
|
|
||||||
_ request: Burrow_NetworkReorderRequest,
|
|
||||||
callOptions: CallOptions?
|
|
||||||
) -> GRPCAsyncUnaryCall<Burrow_NetworkReorderRequest, Burrow_Empty>
|
|
||||||
|
|
||||||
func makeNetworkDeleteCall(
|
|
||||||
_ request: Burrow_NetworkDeleteRequest,
|
|
||||||
callOptions: CallOptions?
|
|
||||||
) -> GRPCAsyncUnaryCall<Burrow_NetworkDeleteRequest, Burrow_Empty>
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
|
|
||||||
extension Burrow_NetworksAsyncClientProtocol {
|
|
||||||
public static var serviceDescriptor: GRPCServiceDescriptor {
|
|
||||||
return Burrow_NetworksClientMetadata.serviceDescriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
public var interceptors: Burrow_NetworksClientInterceptorFactoryProtocol? {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
public func makeNetworkAddCall(
|
|
||||||
_ request: Burrow_Network,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> GRPCAsyncUnaryCall<Burrow_Network, Burrow_Empty> {
|
|
||||||
return self.makeAsyncUnaryCall(
|
|
||||||
path: Burrow_NetworksClientMetadata.Methods.networkAdd.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeNetworkAddInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func makeNetworkListCall(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> GRPCAsyncServerStreamingCall<Burrow_Empty, Burrow_NetworkListResponse> {
|
|
||||||
return self.makeAsyncServerStreamingCall(
|
|
||||||
path: Burrow_NetworksClientMetadata.Methods.networkList.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeNetworkListInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func makeNetworkReorderCall(
|
|
||||||
_ request: Burrow_NetworkReorderRequest,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> GRPCAsyncUnaryCall<Burrow_NetworkReorderRequest, Burrow_Empty> {
|
|
||||||
return self.makeAsyncUnaryCall(
|
|
||||||
path: Burrow_NetworksClientMetadata.Methods.networkReorder.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeNetworkReorderInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func makeNetworkDeleteCall(
|
|
||||||
_ request: Burrow_NetworkDeleteRequest,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> GRPCAsyncUnaryCall<Burrow_NetworkDeleteRequest, Burrow_Empty> {
|
|
||||||
return self.makeAsyncUnaryCall(
|
|
||||||
path: Burrow_NetworksClientMetadata.Methods.networkDelete.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeNetworkDeleteInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
|
|
||||||
extension Burrow_NetworksAsyncClientProtocol {
|
|
||||||
public func networkAdd(
|
|
||||||
_ request: Burrow_Network,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) async throws -> Burrow_Empty {
|
|
||||||
return try await self.performAsyncUnaryCall(
|
|
||||||
path: Burrow_NetworksClientMetadata.Methods.networkAdd.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeNetworkAddInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func networkList(
|
|
||||||
_ request: Burrow_Empty,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) -> GRPCAsyncResponseStream<Burrow_NetworkListResponse> {
|
|
||||||
return self.performAsyncServerStreamingCall(
|
|
||||||
path: Burrow_NetworksClientMetadata.Methods.networkList.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeNetworkListInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func networkReorder(
|
|
||||||
_ request: Burrow_NetworkReorderRequest,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) async throws -> Burrow_Empty {
|
|
||||||
return try await self.performAsyncUnaryCall(
|
|
||||||
path: Burrow_NetworksClientMetadata.Methods.networkReorder.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeNetworkReorderInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public func networkDelete(
|
|
||||||
_ request: Burrow_NetworkDeleteRequest,
|
|
||||||
callOptions: CallOptions? = nil
|
|
||||||
) async throws -> Burrow_Empty {
|
|
||||||
return try await self.performAsyncUnaryCall(
|
|
||||||
path: Burrow_NetworksClientMetadata.Methods.networkDelete.path,
|
|
||||||
request: request,
|
|
||||||
callOptions: callOptions ?? self.defaultCallOptions,
|
|
||||||
interceptors: self.interceptors?.makeNetworkDeleteInterceptors() ?? []
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
|
|
||||||
public struct Burrow_NetworksAsyncClient: Burrow_NetworksAsyncClientProtocol {
|
|
||||||
public var channel: GRPCChannel
|
|
||||||
public var defaultCallOptions: CallOptions
|
|
||||||
public var interceptors: Burrow_NetworksClientInterceptorFactoryProtocol?
|
|
||||||
|
|
||||||
public init(
|
|
||||||
channel: GRPCChannel,
|
|
||||||
defaultCallOptions: CallOptions = CallOptions(),
|
|
||||||
interceptors: Burrow_NetworksClientInterceptorFactoryProtocol? = nil
|
|
||||||
) {
|
|
||||||
self.channel = channel
|
|
||||||
self.defaultCallOptions = defaultCallOptions
|
|
||||||
self.interceptors = interceptors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public protocol Burrow_NetworksClientInterceptorFactoryProtocol: Sendable {
|
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when invoking 'networkAdd'.
|
|
||||||
func makeNetworkAddInterceptors() -> [ClientInterceptor<Burrow_Network, Burrow_Empty>]
|
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when invoking 'networkList'.
|
|
||||||
func makeNetworkListInterceptors() -> [ClientInterceptor<Burrow_Empty, Burrow_NetworkListResponse>]
|
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when invoking 'networkReorder'.
|
|
||||||
func makeNetworkReorderInterceptors() -> [ClientInterceptor<Burrow_NetworkReorderRequest, Burrow_Empty>]
|
|
||||||
|
|
||||||
/// - Returns: Interceptors to use when invoking 'networkDelete'.
|
|
||||||
func makeNetworkDeleteInterceptors() -> [ClientInterceptor<Burrow_NetworkDeleteRequest, Burrow_Empty>]
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Burrow_NetworksClientMetadata {
|
|
||||||
public static let serviceDescriptor = GRPCServiceDescriptor(
|
|
||||||
name: "Networks",
|
|
||||||
fullName: "burrow.Networks",
|
|
||||||
methods: [
|
|
||||||
Burrow_NetworksClientMetadata.Methods.networkAdd,
|
|
||||||
Burrow_NetworksClientMetadata.Methods.networkList,
|
|
||||||
Burrow_NetworksClientMetadata.Methods.networkReorder,
|
|
||||||
Burrow_NetworksClientMetadata.Methods.networkDelete,
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
public enum Methods {
|
|
||||||
public static let networkAdd = GRPCMethodDescriptor(
|
|
||||||
name: "NetworkAdd",
|
|
||||||
path: "/burrow.Networks/NetworkAdd",
|
|
||||||
type: GRPCCallType.unary
|
|
||||||
)
|
|
||||||
|
|
||||||
public static let networkList = GRPCMethodDescriptor(
|
|
||||||
name: "NetworkList",
|
|
||||||
path: "/burrow.Networks/NetworkList",
|
|
||||||
type: GRPCCallType.serverStreaming
|
|
||||||
)
|
|
||||||
|
|
||||||
public static let networkReorder = GRPCMethodDescriptor(
|
|
||||||
name: "NetworkReorder",
|
|
||||||
path: "/burrow.Networks/NetworkReorder",
|
|
||||||
type: GRPCCallType.unary
|
|
||||||
)
|
|
||||||
|
|
||||||
public static let networkDelete = GRPCMethodDescriptor(
|
|
||||||
name: "NetworkDelete",
|
|
||||||
path: "/burrow.Networks/NetworkDelete",
|
|
||||||
type: GRPCCallType.unary
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1,598 +0,0 @@
|
||||||
// DO NOT EDIT.
|
|
||||||
// swift-format-ignore-file
|
|
||||||
// swiftlint:disable all
|
|
||||||
//
|
|
||||||
// Generated by the Swift generator plugin for the protocol buffer compiler.
|
|
||||||
// Source: burrow.proto
|
|
||||||
//
|
|
||||||
// For information on using the generated types, please see the documentation:
|
|
||||||
// https://github.com/apple/swift-protobuf/
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import SwiftProtobuf
|
|
||||||
|
|
||||||
// If the compiler emits an error on this type, it is because this file
|
|
||||||
// was generated by a version of the `protoc` Swift plug-in that is
|
|
||||||
// incompatible with the version of SwiftProtobuf to which you are linking.
|
|
||||||
// Please ensure that you are building against the same version of the API
|
|
||||||
// that was used to generate this file.
|
|
||||||
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
|
|
||||||
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
|
|
||||||
typealias Version = _2
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Burrow_NetworkType: SwiftProtobuf.Enum, Swift.CaseIterable {
|
|
||||||
public typealias RawValue = Int
|
|
||||||
case wireGuard // = 0
|
|
||||||
case tailnet // = 1
|
|
||||||
case UNRECOGNIZED(Int)
|
|
||||||
|
|
||||||
public init() {
|
|
||||||
self = .wireGuard
|
|
||||||
}
|
|
||||||
|
|
||||||
public init?(rawValue: Int) {
|
|
||||||
switch rawValue {
|
|
||||||
case 0: self = .wireGuard
|
|
||||||
case 1: self = .tailnet
|
|
||||||
default: self = .UNRECOGNIZED(rawValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public var rawValue: Int {
|
|
||||||
switch self {
|
|
||||||
case .wireGuard: return 0
|
|
||||||
case .tailnet: return 1
|
|
||||||
case .UNRECOGNIZED(let i): return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
|
||||||
public static let allCases: [Burrow_NetworkType] = [
|
|
||||||
.wireGuard,
|
|
||||||
.tailnet,
|
|
||||||
]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Burrow_State: SwiftProtobuf.Enum, Swift.CaseIterable {
|
|
||||||
public typealias RawValue = Int
|
|
||||||
case stopped // = 0
|
|
||||||
case running // = 1
|
|
||||||
case UNRECOGNIZED(Int)
|
|
||||||
|
|
||||||
public init() {
|
|
||||||
self = .stopped
|
|
||||||
}
|
|
||||||
|
|
||||||
public init?(rawValue: Int) {
|
|
||||||
switch rawValue {
|
|
||||||
case 0: self = .stopped
|
|
||||||
case 1: self = .running
|
|
||||||
default: self = .UNRECOGNIZED(rawValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public var rawValue: Int {
|
|
||||||
switch self {
|
|
||||||
case .stopped: return 0
|
|
||||||
case .running: return 1
|
|
||||||
case .UNRECOGNIZED(let i): return i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The compiler won't synthesize support with the UNRECOGNIZED case.
|
|
||||||
public static let allCases: [Burrow_State] = [
|
|
||||||
.stopped,
|
|
||||||
.running,
|
|
||||||
]
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_NetworkReorderRequest: Sendable {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
public var id: Int32 = 0
|
|
||||||
|
|
||||||
public var index: Int32 = 0
|
|
||||||
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_WireGuardPeer: Sendable {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
public var endpoint: String = String()
|
|
||||||
|
|
||||||
public var subnet: [String] = []
|
|
||||||
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_WireGuardNetwork: Sendable {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
public var address: String = String()
|
|
||||||
|
|
||||||
public var dns: String = String()
|
|
||||||
|
|
||||||
public var peer: [Burrow_WireGuardPeer] = []
|
|
||||||
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_NetworkDeleteRequest: Sendable {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
public var id: Int32 = 0
|
|
||||||
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_Network: @unchecked Sendable {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
public var id: Int32 = 0
|
|
||||||
|
|
||||||
public var type: Burrow_NetworkType = .wireGuard
|
|
||||||
|
|
||||||
public var payload: Data = Data()
|
|
||||||
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_NetworkListResponse: Sendable {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
public var network: [Burrow_Network] = []
|
|
||||||
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_Empty: Sendable {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_TunnelStatusResponse: Sendable {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
public var state: Burrow_State = .stopped
|
|
||||||
|
|
||||||
public var start: SwiftProtobuf.Google_Protobuf_Timestamp {
|
|
||||||
get {return _start ?? SwiftProtobuf.Google_Protobuf_Timestamp()}
|
|
||||||
set {_start = newValue}
|
|
||||||
}
|
|
||||||
/// Returns true if `start` has been explicitly set.
|
|
||||||
public var hasStart: Bool {return self._start != nil}
|
|
||||||
/// Clears the value of `start`. Subsequent reads from it will return its default value.
|
|
||||||
public mutating func clearStart() {self._start = nil}
|
|
||||||
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
|
|
||||||
fileprivate var _start: SwiftProtobuf.Google_Protobuf_Timestamp? = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct Burrow_TunnelConfigurationResponse: Sendable {
|
|
||||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
|
||||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
|
||||||
// methods supported on all messages.
|
|
||||||
|
|
||||||
public var addresses: [String] = []
|
|
||||||
|
|
||||||
public var mtu: Int32 = 0
|
|
||||||
|
|
||||||
public var routes: [String] = []
|
|
||||||
|
|
||||||
public var dnsServers: [String] = []
|
|
||||||
|
|
||||||
public var searchDomains: [String] = []
|
|
||||||
|
|
||||||
public var includeDefaultRoute: Bool = false
|
|
||||||
|
|
||||||
public var unknownFields = SwiftProtobuf.UnknownStorage()
|
|
||||||
|
|
||||||
public init() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Code below here is support for the SwiftProtobuf runtime.
|
|
||||||
|
|
||||||
fileprivate let _protobuf_package = "burrow"
|
|
||||||
|
|
||||||
extension Burrow_NetworkType: SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
0: .same(proto: "WireGuard"),
|
|
||||||
1: .same(proto: "Tailnet"),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_State: SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
0: .same(proto: "Stopped"),
|
|
||||||
1: .same(proto: "Running"),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_NetworkReorderRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = _protobuf_package + ".NetworkReorderRequest"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "id"),
|
|
||||||
2: .same(proto: "index"),
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
// The use of inline closures is to circumvent an issue where the compiler
|
|
||||||
// allocates stack space for every case branch when no optimizations are
|
|
||||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try { try decoder.decodeSingularInt32Field(value: &self.id) }()
|
|
||||||
case 2: try { try decoder.decodeSingularInt32Field(value: &self.index) }()
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if self.id != 0 {
|
|
||||||
try visitor.visitSingularInt32Field(value: self.id, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if self.index != 0 {
|
|
||||||
try visitor.visitSingularInt32Field(value: self.index, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func ==(lhs: Burrow_NetworkReorderRequest, rhs: Burrow_NetworkReorderRequest) -> Bool {
|
|
||||||
if lhs.id != rhs.id {return false}
|
|
||||||
if lhs.index != rhs.index {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_WireGuardPeer: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = _protobuf_package + ".WireGuardPeer"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "endpoint"),
|
|
||||||
2: .same(proto: "subnet"),
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
// The use of inline closures is to circumvent an issue where the compiler
|
|
||||||
// allocates stack space for every case branch when no optimizations are
|
|
||||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try { try decoder.decodeSingularStringField(value: &self.endpoint) }()
|
|
||||||
case 2: try { try decoder.decodeRepeatedStringField(value: &self.subnet) }()
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if !self.endpoint.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.endpoint, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if !self.subnet.isEmpty {
|
|
||||||
try visitor.visitRepeatedStringField(value: self.subnet, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func ==(lhs: Burrow_WireGuardPeer, rhs: Burrow_WireGuardPeer) -> Bool {
|
|
||||||
if lhs.endpoint != rhs.endpoint {return false}
|
|
||||||
if lhs.subnet != rhs.subnet {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_WireGuardNetwork: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = _protobuf_package + ".WireGuardNetwork"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "address"),
|
|
||||||
2: .same(proto: "dns"),
|
|
||||||
3: .same(proto: "peer"),
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
// The use of inline closures is to circumvent an issue where the compiler
|
|
||||||
// allocates stack space for every case branch when no optimizations are
|
|
||||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try { try decoder.decodeSingularStringField(value: &self.address) }()
|
|
||||||
case 2: try { try decoder.decodeSingularStringField(value: &self.dns) }()
|
|
||||||
case 3: try { try decoder.decodeRepeatedMessageField(value: &self.peer) }()
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if !self.address.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.address, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if !self.dns.isEmpty {
|
|
||||||
try visitor.visitSingularStringField(value: self.dns, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if !self.peer.isEmpty {
|
|
||||||
try visitor.visitRepeatedMessageField(value: self.peer, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func ==(lhs: Burrow_WireGuardNetwork, rhs: Burrow_WireGuardNetwork) -> Bool {
|
|
||||||
if lhs.address != rhs.address {return false}
|
|
||||||
if lhs.dns != rhs.dns {return false}
|
|
||||||
if lhs.peer != rhs.peer {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_NetworkDeleteRequest: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = _protobuf_package + ".NetworkDeleteRequest"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "id"),
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
// The use of inline closures is to circumvent an issue where the compiler
|
|
||||||
// allocates stack space for every case branch when no optimizations are
|
|
||||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try { try decoder.decodeSingularInt32Field(value: &self.id) }()
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if self.id != 0 {
|
|
||||||
try visitor.visitSingularInt32Field(value: self.id, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func ==(lhs: Burrow_NetworkDeleteRequest, rhs: Burrow_NetworkDeleteRequest) -> Bool {
|
|
||||||
if lhs.id != rhs.id {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_Network: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = _protobuf_package + ".Network"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "id"),
|
|
||||||
2: .same(proto: "type"),
|
|
||||||
3: .same(proto: "payload"),
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
// The use of inline closures is to circumvent an issue where the compiler
|
|
||||||
// allocates stack space for every case branch when no optimizations are
|
|
||||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try { try decoder.decodeSingularInt32Field(value: &self.id) }()
|
|
||||||
case 2: try { try decoder.decodeSingularEnumField(value: &self.type) }()
|
|
||||||
case 3: try { try decoder.decodeSingularBytesField(value: &self.payload) }()
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if self.id != 0 {
|
|
||||||
try visitor.visitSingularInt32Field(value: self.id, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if self.type != .wireGuard {
|
|
||||||
try visitor.visitSingularEnumField(value: self.type, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if !self.payload.isEmpty {
|
|
||||||
try visitor.visitSingularBytesField(value: self.payload, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func ==(lhs: Burrow_Network, rhs: Burrow_Network) -> Bool {
|
|
||||||
if lhs.id != rhs.id {return false}
|
|
||||||
if lhs.type != rhs.type {return false}
|
|
||||||
if lhs.payload != rhs.payload {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_NetworkListResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = _protobuf_package + ".NetworkListResponse"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "network"),
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
// The use of inline closures is to circumvent an issue where the compiler
|
|
||||||
// allocates stack space for every case branch when no optimizations are
|
|
||||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try { try decoder.decodeRepeatedMessageField(value: &self.network) }()
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if !self.network.isEmpty {
|
|
||||||
try visitor.visitRepeatedMessageField(value: self.network, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func ==(lhs: Burrow_NetworkListResponse, rhs: Burrow_NetworkListResponse) -> Bool {
|
|
||||||
if lhs.network != rhs.network {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_Empty: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = _protobuf_package + ".Empty"
|
|
||||||
public static let _protobuf_nameMap = SwiftProtobuf._NameMap()
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
// Load everything into unknown fields
|
|
||||||
while try decoder.nextFieldNumber() != nil {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func ==(lhs: Burrow_Empty, rhs: Burrow_Empty) -> Bool {
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_TunnelStatusResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = _protobuf_package + ".TunnelStatusResponse"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "state"),
|
|
||||||
2: .same(proto: "start"),
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
// The use of inline closures is to circumvent an issue where the compiler
|
|
||||||
// allocates stack space for every case branch when no optimizations are
|
|
||||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try { try decoder.decodeSingularEnumField(value: &self.state) }()
|
|
||||||
case 2: try { try decoder.decodeSingularMessageField(value: &self._start) }()
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
// The use of inline closures is to circumvent an issue where the compiler
|
|
||||||
// allocates stack space for every if/case branch local when no optimizations
|
|
||||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
|
||||||
// https://github.com/apple/swift-protobuf/issues/1182
|
|
||||||
if self.state != .stopped {
|
|
||||||
try visitor.visitSingularEnumField(value: self.state, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
try { if let v = self._start {
|
|
||||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
|
|
||||||
} }()
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func ==(lhs: Burrow_TunnelStatusResponse, rhs: Burrow_TunnelStatusResponse) -> Bool {
|
|
||||||
if lhs.state != rhs.state {return false}
|
|
||||||
if lhs._start != rhs._start {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension Burrow_TunnelConfigurationResponse: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
|
||||||
public static let protoMessageName: String = _protobuf_package + ".TunnelConfigurationResponse"
|
|
||||||
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
|
||||||
1: .same(proto: "addresses"),
|
|
||||||
2: .same(proto: "mtu"),
|
|
||||||
3: .same(proto: "routes"),
|
|
||||||
4: .standard(proto: "dns_servers"),
|
|
||||||
5: .standard(proto: "search_domains"),
|
|
||||||
6: .standard(proto: "include_default_route"),
|
|
||||||
]
|
|
||||||
|
|
||||||
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
|
||||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
|
||||||
// The use of inline closures is to circumvent an issue where the compiler
|
|
||||||
// allocates stack space for every case branch when no optimizations are
|
|
||||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
|
||||||
switch fieldNumber {
|
|
||||||
case 1: try { try decoder.decodeRepeatedStringField(value: &self.addresses) }()
|
|
||||||
case 2: try { try decoder.decodeSingularInt32Field(value: &self.mtu) }()
|
|
||||||
case 3: try { try decoder.decodeRepeatedStringField(value: &self.routes) }()
|
|
||||||
case 4: try { try decoder.decodeRepeatedStringField(value: &self.dnsServers) }()
|
|
||||||
case 5: try { try decoder.decodeRepeatedStringField(value: &self.searchDomains) }()
|
|
||||||
case 6: try { try decoder.decodeSingularBoolField(value: &self.includeDefaultRoute) }()
|
|
||||||
default: break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
|
||||||
if !self.addresses.isEmpty {
|
|
||||||
try visitor.visitRepeatedStringField(value: self.addresses, fieldNumber: 1)
|
|
||||||
}
|
|
||||||
if self.mtu != 0 {
|
|
||||||
try visitor.visitSingularInt32Field(value: self.mtu, fieldNumber: 2)
|
|
||||||
}
|
|
||||||
if !self.routes.isEmpty {
|
|
||||||
try visitor.visitRepeatedStringField(value: self.routes, fieldNumber: 3)
|
|
||||||
}
|
|
||||||
if !self.dnsServers.isEmpty {
|
|
||||||
try visitor.visitRepeatedStringField(value: self.dnsServers, fieldNumber: 4)
|
|
||||||
}
|
|
||||||
if !self.searchDomains.isEmpty {
|
|
||||||
try visitor.visitRepeatedStringField(value: self.searchDomains, fieldNumber: 5)
|
|
||||||
}
|
|
||||||
if self.includeDefaultRoute {
|
|
||||||
try visitor.visitSingularBoolField(value: self.includeDefaultRoute, fieldNumber: 6)
|
|
||||||
}
|
|
||||||
try unknownFields.traverse(visitor: &visitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
public static func ==(lhs: Burrow_TunnelConfigurationResponse, rhs: Burrow_TunnelConfigurationResponse) -> Bool {
|
|
||||||
if lhs.addresses != rhs.addresses {return false}
|
|
||||||
if lhs.mtu != rhs.mtu {return false}
|
|
||||||
if lhs.routes != rhs.routes {return false}
|
|
||||||
if lhs.dnsServers != rhs.dnsServers {return false}
|
|
||||||
if lhs.searchDomains != rhs.searchDomains {return false}
|
|
||||||
if lhs.includeDefaultRoute != rhs.includeDefaultRoute {return false}
|
|
||||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
../../../proto/burrow.proto
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
// Protocol Buffers - Google's data interchange format
|
|
||||||
// Copyright 2008 Google Inc. All rights reserved.
|
|
||||||
// https://developers.google.com/protocol-buffers/
|
|
||||||
//
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following disclaimer
|
|
||||||
// in the documentation and/or other materials provided with the
|
|
||||||
// distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived from
|
|
||||||
// this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
syntax = "proto3";
|
|
||||||
|
|
||||||
package google.protobuf;
|
|
||||||
|
|
||||||
option cc_enable_arenas = true;
|
|
||||||
option go_package = "google.golang.org/protobuf/types/known/timestamppb";
|
|
||||||
option java_package = "com.google.protobuf";
|
|
||||||
option java_outer_classname = "TimestampProto";
|
|
||||||
option java_multiple_files = true;
|
|
||||||
option objc_class_prefix = "GPB";
|
|
||||||
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
|
|
||||||
|
|
||||||
// A Timestamp represents a point in time independent of any time zone or local
|
|
||||||
// calendar, encoded as a count of seconds and fractions of seconds at
|
|
||||||
// nanosecond resolution. The count is relative to an epoch at UTC midnight on
|
|
||||||
// January 1, 1970, in the proleptic Gregorian calendar which extends the
|
|
||||||
// Gregorian calendar backwards to year one.
|
|
||||||
//
|
|
||||||
// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap
|
|
||||||
// second table is needed for interpretation, using a 24-hour linear smear.
|
|
||||||
//
|
|
||||||
// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By
|
|
||||||
// restricting to that range, we ensure that we can convert to and from RFC
|
|
||||||
// 3339 date strings.
|
|
||||||
message Timestamp {
|
|
||||||
// Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z.
|
|
||||||
// Must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive.
|
|
||||||
int64 seconds = 1;
|
|
||||||
|
|
||||||
// Non-negative fractions of a second at nanosecond resolution. Negative
|
|
||||||
// second values with fractions must still have non-negative nanos values
|
|
||||||
// that count forward in time. Must be from 0 to 999,999,999 inclusive.
|
|
||||||
int32 nanos = 2;
|
|
||||||
}
|
|
||||||