mirror of
https://github.com/flant/ovpn-admin.git
synced 2026-02-04 01:10:22 -08:00
Compare commits
No commits in common. "master" and "1.3" have entirely different histories.
@ -3,7 +3,7 @@
|
|||||||
*.iml
|
*.iml
|
||||||
out
|
out
|
||||||
gen
|
gen
|
||||||
.github
|
|
||||||
|
|
||||||
easyrsa
|
easyrsa
|
||||||
easyrsa_master
|
easyrsa_master
|
||||||
@ -13,14 +13,6 @@ ccd_master
|
|||||||
ccd_slave
|
ccd_slave
|
||||||
werf.yaml
|
werf.yaml
|
||||||
frontend/node_modules
|
frontend/node_modules
|
||||||
frontend/static/dist
|
|
||||||
openvpn-web-ui
|
openvpn-web-ui
|
||||||
openvpn-ui
|
openvpn-ui
|
||||||
openvpn-admin
|
openvpn-admin
|
||||||
ovpn-admin
|
|
||||||
|
|
||||||
docker-compose.yaml
|
|
||||||
docker-compose-slave.yaml
|
|
||||||
img
|
|
||||||
dashboard
|
|
||||||
.helm
|
|
||||||
|
|||||||
@ -1,24 +0,0 @@
|
|||||||
|
|
||||||
; https://editorconfig.org/
|
|
||||||
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
insert_final_newline = true
|
|
||||||
charset = utf-8
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
[{Makefile,go.mod,go.sum,*.go,.gitmodules}]
|
|
||||||
indent_style = tab
|
|
||||||
indent_size = 4
|
|
||||||
|
|
||||||
[*.md]
|
|
||||||
indent_size = 4
|
|
||||||
trim_trailing_whitespace = false
|
|
||||||
|
|
||||||
eclint_indent_style = unset
|
|
||||||
|
|
||||||
[Dockerfile]
|
|
||||||
indent_size = 4
|
|
||||||
25
.github/dependabot.yml
vendored
25
.github/dependabot.yml
vendored
@ -1,25 +0,0 @@
|
|||||||
version: 2
|
|
||||||
updates:
|
|
||||||
# Dependencies listed in go.mod
|
|
||||||
- package-ecosystem: "gomod"
|
|
||||||
directory: "/" # Location of package manifests
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
|
|
||||||
# Dependencies listed in .github/workflows/*.yml
|
|
||||||
- package-ecosystem: "github-actions"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
|
|
||||||
# Dependencies listed in Dockerfile
|
|
||||||
- package-ecosystem: "docker"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
|
|
||||||
# Dependencies listed in frontend/package.json
|
|
||||||
- package-ecosystem: "npm"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
17
.github/release.yml
vendored
17
.github/release.yml
vendored
@ -1,17 +0,0 @@
|
|||||||
changelog:
|
|
||||||
exclude:
|
|
||||||
labels:
|
|
||||||
- ignore
|
|
||||||
categories:
|
|
||||||
- title: Enhancements 🚀
|
|
||||||
labels:
|
|
||||||
- enhancement
|
|
||||||
- title: Bug Fixes 🐛
|
|
||||||
labels:
|
|
||||||
- bug
|
|
||||||
- title: Dependency Updates ⬆️
|
|
||||||
labels:
|
|
||||||
- dependencies
|
|
||||||
- title: Other Changes
|
|
||||||
labels:
|
|
||||||
- "*"
|
|
||||||
35
.github/workflows/chart-release.yml
vendored
35
.github/workflows/chart-release.yml
vendored
@ -1,35 +0,0 @@
|
|||||||
name: Release Charts
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
paths:
|
|
||||||
- 'charts/**'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
chart-release:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Configure Git
|
|
||||||
run: |
|
|
||||||
git config user.name "$GITHUB_ACTOR"
|
|
||||||
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
|
|
||||||
|
|
||||||
- name: Install Helm
|
|
||||||
uses: azure/setup-helm@v4
|
|
||||||
with:
|
|
||||||
version: v3.7.1
|
|
||||||
|
|
||||||
- name: Run chart-releaser
|
|
||||||
uses: helm/chart-releaser-action@v1.7.0
|
|
||||||
with:
|
|
||||||
charts_dir: charts
|
|
||||||
config: charts/cr.yaml
|
|
||||||
env:
|
|
||||||
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
|
||||||
107
.github/workflows/chart-test.yaml
vendored
107
.github/workflows/chart-test.yaml
vendored
@ -1,107 +0,0 @@
|
|||||||
name: Chart Test
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- v*
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
chart:
|
|
||||||
name: Chart
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
outputs:
|
|
||||||
changed: ${{ steps.changes.outputs.changed }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Set up Helm
|
|
||||||
uses: azure/setup-helm@v4
|
|
||||||
with:
|
|
||||||
version: v3.10.3
|
|
||||||
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.10"
|
|
||||||
|
|
||||||
- name: Set up chart-testing
|
|
||||||
uses: helm/chart-testing-action@v2.6.1
|
|
||||||
|
|
||||||
- name: Lint
|
|
||||||
run: ct lint
|
|
||||||
|
|
||||||
- name: Check generated docs
|
|
||||||
run: |
|
|
||||||
make docs
|
|
||||||
test "$(git diff --name-only)" == "" \
|
|
||||||
|| ( printf >&2 "\nREADME files are not up to date (run 'make docs'), differences:\n\n%s\n\n" "$(git diff)" ; exit 1 ; )
|
|
||||||
|
|
||||||
- name: Detect changes
|
|
||||||
id: changes
|
|
||||||
run: |
|
|
||||||
changed=$(ct list-changed)
|
|
||||||
if [[ -n "$changed" ]]; then
|
|
||||||
echo "changed=true" >> $GITHUB_OUTPUT
|
|
||||||
fi
|
|
||||||
|
|
||||||
chart-test:
|
|
||||||
name: Chart Test
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: chart
|
|
||||||
if: needs.chart.outputs.changed == 'true'
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
kube: ["1.25", "1.29", "1.31"]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Set up Helm
|
|
||||||
uses: azure/setup-helm@v4
|
|
||||||
with:
|
|
||||||
version: v3.10.3
|
|
||||||
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v6
|
|
||||||
with:
|
|
||||||
python-version: "3.10"
|
|
||||||
|
|
||||||
- name: Set up chart-testing
|
|
||||||
uses: helm/chart-testing-action@v2.6.1
|
|
||||||
|
|
||||||
# See https://github.com/kubernetes-sigs/kind/releases/tag/v0.17.0
|
|
||||||
- name: Determine KinD node image version
|
|
||||||
id: node_image
|
|
||||||
run: |
|
|
||||||
case ${{ matrix.kube }} in
|
|
||||||
1.25)
|
|
||||||
NODE_IMAGE=kindest/node:v1.25.3@sha256:f52781bc0d7a19fb6c405c2af83abfeb311f130707a0e219175677e366cc45d1 ;;
|
|
||||||
1.29)
|
|
||||||
NODE_IMAGE=kindest/node:v1.29.12@sha256:62c0672ba99a4afd7396512848d6fc382906b8f33349ae68fb1dbfe549f70dec ;;
|
|
||||||
1.31)
|
|
||||||
NODE_IMAGE=kindest/node:v1.31.2@sha256:0526eb5cd8d892ed79b56feb48d17eeee1f719f55d5c35cef468f053caffad32 ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
echo "image=$NODE_IMAGE" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Create KinD cluster
|
|
||||||
uses: helm/kind-action@v1.13.0
|
|
||||||
with:
|
|
||||||
version: v0.17.0
|
|
||||||
node_image: ${{ steps.node_image.outputs.image }}
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
run: ct install
|
|
||||||
59
.github/workflows/publish-tag.yaml
vendored
59
.github/workflows/publish-tag.yaml
vendored
@ -1,59 +0,0 @@
|
|||||||
name: Build and publish tags to ghcr.io
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- v*
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
env:
|
|
||||||
WERF_STAGED_DOCKERFILE_VERSION: v2
|
|
||||||
WERF_BUILDAH_MODE: auto
|
|
||||||
WERF_ENV: ${{ (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/')) && 'release' || 'pr' }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
name: build images for tag
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Install werf
|
|
||||||
uses: werf/actions/install@v2
|
|
||||||
|
|
||||||
- name: Set up QEMU
|
|
||||||
uses: docker/setup-qemu-action@v3
|
|
||||||
with:
|
|
||||||
platforms: linux/amd64, linux/arm64, linux/arm/v7, linux/arm/v8
|
|
||||||
|
|
||||||
- name: Login into ghcr.io
|
|
||||||
shell: bash
|
|
||||||
run: werf cr login -u ${{ github.actor }} -p ${{ github.token }} ghcr.io/${{ github.repository }}
|
|
||||||
|
|
||||||
- name: Extract Docker metadata
|
|
||||||
uses: docker/metadata-action@v5.10.0
|
|
||||||
with:
|
|
||||||
images: ghcr.io/${{ github.repository }}/${{ matrix.name }}
|
|
||||||
|
|
||||||
- name: Build Image
|
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
|
||||||
run: |
|
|
||||||
source "$(werf ci-env github --as-file)"
|
|
||||||
source <(jq -r '.labels | to_entries | to_entries[] | "export WERF_EXPORT_ADD_LABEL_\(.key)=\"\(.value.key)=\(.value.value)\""' <<< $DOCKER_METADATA_OUTPUT_JSON)
|
|
||||||
|
|
||||||
werf build --repo='' --final-repo='' --secondary-repo "$WERF_REPO" --env "$WERF_ENV"
|
|
||||||
|
|
||||||
- name: Build and Push Image
|
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
|
||||||
run: |
|
|
||||||
source "$(werf ci-env github --as-file)"
|
|
||||||
source <(jq -r '.labels | to_entries | to_entries[] | "export WERF_EXPORT_ADD_LABEL_\(.key)=\"\(.value.key)=\(.value.value)\""' <<< $DOCKER_METADATA_OUTPUT_JSON)
|
|
||||||
|
|
||||||
werf export --tag ghcr.io/${{ github.repository }}/%image%:${{ github.ref_name }} --env "$WERF_ENV"
|
|
||||||
29
.github/workflows/release.yaml
vendored
29
.github/workflows/release.yaml
vendored
@ -1,29 +0,0 @@
|
|||||||
name: Build and publish binaries (releases only)
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [created]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
releases-matrix:
|
|
||||||
name: Release Go Binary
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
CGO_ENABLED: 1
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
goos: [linux]
|
|
||||||
goarch: ["386", "amd64"]
|
|
||||||
steps:
|
|
||||||
- name: checkout code
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
- name: build binaries
|
|
||||||
uses: wangyoucao577/go-release-action@v1.55
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
goversion: 1.23
|
|
||||||
goos: ${{ matrix.goos }}
|
|
||||||
goarch: ${{ matrix.goarch }}
|
|
||||||
build_command: bash -ex ./build.sh
|
|
||||||
pre_command: bash -ex ./install-deps.sh
|
|
||||||
binary_name: "ovpn-admin"
|
|
||||||
asset_name: ovpn-admin-${{ matrix.goos }}-${{ matrix.goarch }}
|
|
||||||
29
.github/workflows/release_arm.yaml
vendored
29
.github/workflows/release_arm.yaml
vendored
@ -1,29 +0,0 @@
|
|||||||
name: Build and publish arm binaries (releases only)
|
|
||||||
on:
|
|
||||||
release:
|
|
||||||
types: [created]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
releases-matrix:
|
|
||||||
name: Release Go Binary
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
env:
|
|
||||||
CGO_ENABLED: 1
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
goos: [linux]
|
|
||||||
goarch: ["arm", "arm64"]
|
|
||||||
steps:
|
|
||||||
- name: checkout code
|
|
||||||
uses: actions/checkout@v6
|
|
||||||
- name: build binaries
|
|
||||||
uses: wangyoucao577/go-release-action@v1.55
|
|
||||||
with:
|
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
goversion: 1.23
|
|
||||||
goos: ${{ matrix.goos }}
|
|
||||||
goarch: ${{ matrix.goarch }}
|
|
||||||
build_command: bash -ex ./build_arm.sh
|
|
||||||
pre_command: bash -ex ./install-deps-arm.sh
|
|
||||||
binary_name: "ovpn-admin"
|
|
||||||
asset_name: ovpn-admin-${{ matrix.goos }}-${{ matrix.goarch }}
|
|
||||||
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,16 +1,14 @@
|
|||||||
bin/
|
|
||||||
|
|
||||||
easyrsa
|
easyrsa
|
||||||
easyrsa_master
|
easyrsa_master
|
||||||
easyrsa_slave
|
easyrsa_slave
|
||||||
ccd
|
ccd
|
||||||
ccd_master
|
ccd_master
|
||||||
ccd_slave
|
ccd_slave
|
||||||
|
openvpn-web-ui
|
||||||
|
openvpn-ui
|
||||||
|
openvpn-admin
|
||||||
frontend/node_modules
|
frontend/node_modules
|
||||||
|
|
||||||
main-packr.go
|
|
||||||
packrd/
|
|
||||||
|
|
||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
.idea
|
.idea
|
||||||
*.suo
|
*.suo
|
||||||
|
|||||||
43
.werffiles/configure.sh
Normal file
43
.werffiles/configure.sh
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -x
|
||||||
|
|
||||||
|
EASY_RSA_LOC="/etc/openvpn/easyrsa"
|
||||||
|
SERVER_CERT="${EASY_RSA_LOC}/pki/issued/server.crt"
|
||||||
|
cd $EASY_RSA_LOC
|
||||||
|
if [ -e "$SERVER_CERT" ]; then
|
||||||
|
echo "Found existing certs - reusing"
|
||||||
|
else
|
||||||
|
if [ ${OPVN_ROLE:-"master"} = "slave" ]; then
|
||||||
|
echo "Waiting for syncing data from master"
|
||||||
|
while [ $(wget -q localhost/api/sync/last -O - | wc -m) -lt 1 ]
|
||||||
|
do
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "Generating new certs"
|
||||||
|
easyrsa init-pki
|
||||||
|
cp -R /usr/share/easy-rsa/* $EASY_RSA_LOC/pki
|
||||||
|
echo "ca" | easyrsa build-ca nopass
|
||||||
|
easyrsa build-server-full server nopass
|
||||||
|
easyrsa gen-dh
|
||||||
|
openvpn --genkey --secret ./pki/ta.key
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
easyrsa gen-crl
|
||||||
|
|
||||||
|
iptables -t nat -A POSTROUTING -s 172.16.100.0/255.255.255.0 ! -d 172.16.100.0/255.255.255.0 -j MASQUERADE
|
||||||
|
|
||||||
|
mkdir -p /dev/net
|
||||||
|
if [ ! -c /dev/net/tun ]; then
|
||||||
|
mknod /dev/net/tun c 10 200
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp -f /etc/openvpn/setup/openvpn.conf /etc/openvpn/openvpn.conf
|
||||||
|
|
||||||
|
[ -d $EASY_RSA_LOC/pki ] && chmod 755 $EASY_RSA_LOC/pki
|
||||||
|
[ -f $EASY_RSA_LOC/pki/crl.pem ] && chmod 644 $EASY_RSA_LOC/pki/crl.pem
|
||||||
|
|
||||||
|
mkdir -p /etc/openvpn/ccd
|
||||||
|
|
||||||
|
openvpn --config /etc/openvpn/openvpn.conf --client-config-dir /etc/openvpn/ccd
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
# server 172.16.100.0 255.255.255.0
|
server 172.16.100.0 255.255.255.0
|
||||||
verb 3
|
verb 3
|
||||||
tls-server
|
tls-server
|
||||||
ca /etc/openvpn/easyrsa/pki/ca.crt
|
ca /etc/openvpn/easyrsa/pki/ca.crt
|
||||||
@ -8,16 +8,16 @@ dh /etc/openvpn/easyrsa/pki/dh.pem
|
|||||||
crl-verify /etc/openvpn/easyrsa/pki/crl.pem
|
crl-verify /etc/openvpn/easyrsa/pki/crl.pem
|
||||||
tls-auth /etc/openvpn/easyrsa/pki/ta.key
|
tls-auth /etc/openvpn/easyrsa/pki/ta.key
|
||||||
key-direction 0
|
key-direction 0
|
||||||
|
duplicate-cn
|
||||||
cipher AES-128-CBC
|
cipher AES-128-CBC
|
||||||
#management 127.0.0.1 8989
|
management 127.0.0.1 8989
|
||||||
keepalive 10 60
|
keepalive 10 60
|
||||||
persist-key
|
persist-key
|
||||||
persist-tun
|
persist-tun
|
||||||
topology subnet
|
topology subnet
|
||||||
#duplicate-cn
|
proto tcp
|
||||||
#proto tcp
|
port 1194
|
||||||
#port 1194
|
dev tun0
|
||||||
#dev tun0
|
|
||||||
status /tmp/openvpn-status.log
|
status /tmp/openvpn-status.log
|
||||||
user nobody
|
user nobody
|
||||||
group nogroup
|
group nogroup
|
||||||
19
Dockerfile
Normal file
19
Dockerfile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
FROM golang:1.14.2-alpine3.11 AS backend-builder
|
||||||
|
COPY . /app
|
||||||
|
#RUN apk --no-cache add build-base git gcc
|
||||||
|
RUN cd /app && env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags='-extldflags "-static" -s -w' -o openvpn-admin
|
||||||
|
|
||||||
|
FROM node:14.2-alpine3.11 AS frontend-builder
|
||||||
|
COPY frontend/ /app
|
||||||
|
RUN cd /app && npm install && npm run build
|
||||||
|
|
||||||
|
FROM alpine:3.11
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=backend-builder /app/openvpn-admin /app
|
||||||
|
COPY --from=frontend-builder /app/static /app/static
|
||||||
|
COPY client.conf.tpl /app/client.conf.tpl
|
||||||
|
COPY ccd.tpl /app/ccd.tpl
|
||||||
|
RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing/" >> /etc/apk/repositories && \
|
||||||
|
apk add --update bash easy-rsa && \
|
||||||
|
ln -s /usr/share/easy-rsa/easyrsa /usr/local/bin && \
|
||||||
|
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
|
||||||
@ -1,9 +1,7 @@
|
|||||||
FROM alpine:3.23
|
FROM alpine:3.11
|
||||||
ARG TARGETARCH
|
RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing/" >> /etc/apk/repositories && \
|
||||||
RUN apk add --update bash openvpn easy-rsa iptables && \
|
apk add --update bash openvpn easy-rsa && \
|
||||||
ln -s /usr/share/easy-rsa/easyrsa /usr/local/bin && \
|
ln -s /usr/share/easy-rsa/easyrsa /usr/local/bin && \
|
||||||
wget https://github.com/pashcovich/openvpn-user/releases/download/v1.0.4/openvpn-user-linux-${TARGETARCH}.tar.gz -O - | tar xz -C /usr/local/bin && \
|
|
||||||
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
|
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
|
||||||
RUN if [ -f "/usr/local/bin/openvpn-user-${TARGETARCH}" ]; then ln -s /usr/local/bin/openvpn-user-${TARGETARCH} /usr/local/bin/openvpn-user; fi
|
COPY .werffiles /etc/openvpn/setup
|
||||||
COPY setup/ /etc/openvpn/setup
|
|
||||||
RUN chmod +x /etc/openvpn/setup/configure.sh
|
RUN chmod +x /etc/openvpn/setup/configure.sh
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
FROM node:16-alpine3.15 AS frontend-builder
|
|
||||||
COPY ../frontend /app
|
|
||||||
RUN apk add --update python3 make g++ && cd /app && npm install && npm run build
|
|
||||||
|
|
||||||
FROM golang:1.24.6-bullseye AS backend-builder
|
|
||||||
RUN go install github.com/gobuffalo/packr/v2/packr2@latest
|
|
||||||
COPY --from=frontend-builder /app/static /app/frontend/static
|
|
||||||
COPY .. /app
|
|
||||||
ARG TARGETARCH
|
|
||||||
RUN cd /app && packr2 && env CGO_ENABLED=1 GOOS=linux GOARCH=${TARGETARCH} go build -a -tags netgo -ldflags '-linkmode external -extldflags -static -s -w' -o ovpn-admin && packr2 clean
|
|
||||||
|
|
||||||
FROM alpine:3.23
|
|
||||||
WORKDIR /app
|
|
||||||
COPY --from=backend-builder /app/ovpn-admin /app
|
|
||||||
ARG TARGETARCH
|
|
||||||
RUN apk add --update bash easy-rsa openssl openvpn coreutils && \
|
|
||||||
ln -s /usr/share/easy-rsa/easyrsa /usr/local/bin && \
|
|
||||||
wget https://github.com/pashcovich/openvpn-user/releases/download/v1.0.4/openvpn-user-linux-${TARGETARCH}.tar.gz -O - | tar xz -C /usr/local/bin && \
|
|
||||||
rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/*
|
|
||||||
RUN if [ -f "/usr/local/bin/openvpn-user-${TARGETARCH}" ]; then ln -s /usr/local/bin/openvpn-user-${TARGETARCH} /usr/local/bin/openvpn-user; fi
|
|
||||||
54
Makefile
54
Makefile
@ -1,54 +0,0 @@
|
|||||||
export PATH := $(abspath bin/protoc/bin/):$(abspath bin/):${PATH}
|
|
||||||
export SHELL := env PATH=$(PATH) /bin/sh
|
|
||||||
|
|
||||||
GOOS?=$(shell go env GOOS)
|
|
||||||
GOARCH?=$(shell go env GOARCH)
|
|
||||||
GOLANGCI_VERSION = 1.55.2
|
|
||||||
HELM_DOCS_VERSION = 1.11.0
|
|
||||||
|
|
||||||
ifeq ($(GOARCH),arm)
|
|
||||||
ARCH=armv7
|
|
||||||
else
|
|
||||||
ARCH=$(GOARCH)
|
|
||||||
endif
|
|
||||||
|
|
||||||
COMMIT=$(shell git rev-parse --verify HEAD)
|
|
||||||
|
|
||||||
###########
|
|
||||||
# BUILDING
|
|
||||||
###########
|
|
||||||
|
|
||||||
###########
|
|
||||||
# LINTING
|
|
||||||
###########
|
|
||||||
bin/golangci-lint: bin/golangci-lint-${GOLANGCI_VERSION}
|
|
||||||
@ln -sf golangci-lint-${GOLANGCI_VERSION} bin/golangci-lint
|
|
||||||
|
|
||||||
bin/golangci-lint-${GOLANGCI_VERSION}:
|
|
||||||
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | BINARY=golangci-lint bash -s -- v${GOLANGCI_VERSION}
|
|
||||||
@mv bin/golangci-lint $@
|
|
||||||
|
|
||||||
###########
|
|
||||||
# HELM
|
|
||||||
###########
|
|
||||||
|
|
||||||
bin/helm-docs: bin/helm-docs-${HELM_DOCS_VERSION}
|
|
||||||
@ln -sf helm-docs-${HELM_DOCS_VERSION} bin/helm-docs
|
|
||||||
bin/helm-docs-${HELM_DOCS_VERSION}:
|
|
||||||
@mkdir -p bin
|
|
||||||
curl -L https://github.com/norwoodj/helm-docs/releases/download/v${HELM_DOCS_VERSION}/helm-docs_${HELM_DOCS_VERSION}_$(shell uname)_x86_64.tar.gz | tar -zOxf - helm-docs > ./bin/helm-docs-${HELM_DOCS_VERSION} && chmod +x ./bin/helm-docs-${HELM_DOCS_VERSION}
|
|
||||||
|
|
||||||
.PHONY: lint fix
|
|
||||||
lint: bin/golangci-lint
|
|
||||||
bin/golangci-lint run
|
|
||||||
|
|
||||||
fix: bin/golangci-lint
|
|
||||||
bin/golangci-lint run --fix
|
|
||||||
|
|
||||||
.PHONY: docs
|
|
||||||
docs: bin/helm-docs
|
|
||||||
bin/helm-docs -s file -c charts/ -t README.md.gotmpl
|
|
||||||
|
|
||||||
###########
|
|
||||||
# TESTING
|
|
||||||
###########
|
|
||||||
184
README.md
184
README.md
@ -1,183 +1 @@
|
|||||||
# ovpn-admin
|
# openvpn-web-ui
|
||||||
|
|
||||||
Simple web UI to manage OpenVPN users, their certificates & routes in Linux. While backend is written in Go, frontend is based on Vue.js.
|
|
||||||
|
|
||||||
***DISCLAIMER!** This project was created for experienced users (system administrators) and private (e.g., protected by network policies) environments only. Thus, it is not implemented with security in mind (e.g., it doesn't strictly check all parameters passed by users, etc.). It also relies heavily on files and fails if required files aren't available.*
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
* Adding, deleting OpenVPN users (generating certificates for them);
|
|
||||||
* Revoking/restoring/rotating users certificates;
|
|
||||||
* Generating ready-to-user config files;
|
|
||||||
* Providing metrics for Prometheus, including certificates expiration date, number of (connected/total) users, information about connected users;
|
|
||||||
* (optionally) Specifying CCD (`client-config-dir`) for each user;
|
|
||||||
* (optionally) Operating in a master/slave mode (syncing certs & CCD with other server);
|
|
||||||
* (optionally) Specifying/changing password for additional authorization in OpenVPN;
|
|
||||||
* (optionally) Specifying the Kubernetes LoadBalancer if it's used in front of the OpenVPN server (to get an automatically defined `remote` in the `client.conf.tpl` template).
|
|
||||||
* (optionally) Storing certificates and other files in Kubernetes Secrets (**Attention, this feature is experimental!**).
|
|
||||||
|
|
||||||
### Screenshots
|
|
||||||
|
|
||||||
Managing users in ovpn-admin:
|
|
||||||

|
|
||||||
|
|
||||||
An example of dashboard made using ovpn-admin metrics:
|
|
||||||

|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
### 1. Docker
|
|
||||||
|
|
||||||
There is a ready-to-use [docker-compose.yaml](https://github.com/palark/ovpn-admin/blob/master/docker-compose.yaml), so you can just change/add values you need and start it with [start.sh](https://github.com/palark/ovpn-admin/blob/master/start.sh).
|
|
||||||
|
|
||||||
Requirements:
|
|
||||||
You need [Docker](https://docs.docker.com/get-docker/) and [docker-compose](https://docs.docker.com/compose/install/) installed.
|
|
||||||
|
|
||||||
Commands to execute:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/palark/ovpn-admin.git
|
|
||||||
cd ovpn-admin
|
|
||||||
./start.sh
|
|
||||||
```
|
|
||||||
#### 1.1
|
|
||||||
Ready docker images available on [Docker Hub](https://hub.docker.com/r/flant/ovpn-admin/tags)
|
|
||||||
. Tags are simple: `$VERSION` or `latest` for ovpn-admin and `openvpn-$VERSION` or `openvpn-latest` for openvpn-server
|
|
||||||
|
|
||||||
### 2. Building from source
|
|
||||||
|
|
||||||
Requirements. You need Linux with the following components installed:
|
|
||||||
- [golang](https://golang.org/doc/install)
|
|
||||||
- [packr2](https://github.com/gobuffalo/packr#installation)
|
|
||||||
- [nodejs/npm](https://nodejs.org/en/download/package-manager/)
|
|
||||||
|
|
||||||
Commands to execute:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/palark/ovpn-admin.git
|
|
||||||
cd ovpn-admin
|
|
||||||
./bootstrap.sh
|
|
||||||
./build.sh
|
|
||||||
./ovpn-admin
|
|
||||||
```
|
|
||||||
|
|
||||||
(Please don't forget to configure all needed params in advance.)
|
|
||||||
|
|
||||||
### 3. Prebuilt binary
|
|
||||||
|
|
||||||
You can also download and use prebuilt binaries from the [releases](https://github.com/palark/ovpn-admin/releases/latest) page — just choose a relevant tar.gz file.
|
|
||||||
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
* This tool uses external calls for `bash`, `coreutils` and `easy-rsa`, thus **Linux systems only are supported** at the moment.
|
|
||||||
* To enable additional password authentication, provide `--auth` and `--auth.db="/etc/easyrsa/pki/users.db`" flags and install [openvpn-user](https://github.com/pashcovich/openvpn-user/releases/latest). This tool should be available in your `$PATH` and its binary should be executable (`+x`).
|
|
||||||
* If you use `--ccd` and `--ccd.path="/etc/openvpn/ccd"` and plan to use static address setup for users, do not forget to provide `--ovpn.network="172.16.100.0/24"` with valid openvpn-server network.
|
|
||||||
* If you want to pass all the traffic generated by the user, you need to edit `ovpn-admin/templates/client.conf.tpl` and uncomment `redirect-gateway def1`.
|
|
||||||
* Tested with openvpn-server versions 2.4 and 2.5 and with tls-auth mode only.
|
|
||||||
* Not tested with Easy-RSA version > 3.0.8.
|
|
||||||
* Status of user connections update every 28 seconds.
|
|
||||||
* Master-replica synchronization and additional password authentication do not work with `--storage.backend=kubernetes.secrets` - **WIP**
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```
|
|
||||||
usage: ovpn-admin [<flags>]
|
|
||||||
|
|
||||||
Flags:
|
|
||||||
--help show context-sensitive help (try also --help-long and --help-man)
|
|
||||||
|
|
||||||
--listen.host="0.0.0.0" host for ovpn-admin
|
|
||||||
(or OVPN_LISTEN_HOST)
|
|
||||||
|
|
||||||
--listen.port="8080" port for ovpn-admin
|
|
||||||
(or OVPN_LISTEN_PORT)
|
|
||||||
|
|
||||||
--listen.base-url="/" base URL for ovpn-admin web files
|
|
||||||
(or $OVPN_LISTEN_BASE_URL)
|
|
||||||
|
|
||||||
--role="master" server role, master or slave
|
|
||||||
(or OVPN_ROLE)
|
|
||||||
|
|
||||||
--master.host="http://127.0.0.1"
|
|
||||||
(or OVPN_MASTER_HOST) URL for the master server
|
|
||||||
|
|
||||||
--master.basic-auth.user="" user for master server's Basic Auth
|
|
||||||
(or OVPN_MASTER_USER)
|
|
||||||
|
|
||||||
--master.basic-auth.password=""
|
|
||||||
(or OVPN_MASTER_PASSWORD) password for master server's Basic Auth
|
|
||||||
|
|
||||||
--master.sync-frequency=600 master host data sync frequency in seconds
|
|
||||||
(or OVPN_MASTER_SYNC_FREQUENCY)
|
|
||||||
|
|
||||||
--master.sync-token=TOKEN master host data sync security token
|
|
||||||
(or OVPN_MASTER_TOKEN)
|
|
||||||
|
|
||||||
--ovpn.network="172.16.100.0/24"
|
|
||||||
(or OVPN_NETWORK) NETWORK/MASK_PREFIX for OpenVPN server
|
|
||||||
|
|
||||||
--ovpn.server=HOST:PORT:PROTOCOL ...
|
|
||||||
(or OVPN_SERVER) HOST:PORT:PROTOCOL for OpenVPN server
|
|
||||||
can have multiple values
|
|
||||||
|
|
||||||
--ovpn.server.behindLB enable if your OpenVPN server is behind Kubernetes
|
|
||||||
(or OVPN_LB) Service having the LoadBalancer type
|
|
||||||
|
|
||||||
--ovpn.service="openvpn-external"
|
|
||||||
(or OVPN_LB_SERVICE) the name of Kubernetes Service having the LoadBalancer
|
|
||||||
type if your OpenVPN server is behind it
|
|
||||||
|
|
||||||
--mgmt=main=127.0.0.1:8989 ...
|
|
||||||
(or OVPN_MGMT) ALIAS=HOST:PORT for OpenVPN server mgmt interface;
|
|
||||||
can have multiple values
|
|
||||||
|
|
||||||
--metrics.path="/metrics" URL path for exposing collected metrics
|
|
||||||
(or OVPN_METRICS_PATH)
|
|
||||||
|
|
||||||
--easyrsa.path="./easyrsa/" path to easyrsa dir
|
|
||||||
(or EASYRSA_PATH)
|
|
||||||
|
|
||||||
--easyrsa.index-path="./easyrsa/pki/index.txt"
|
|
||||||
(or OVPN_INDEX_PATH) path to easyrsa index file
|
|
||||||
|
|
||||||
--ccd enable client-config-dir
|
|
||||||
(or OVPN_CCD)
|
|
||||||
|
|
||||||
--ccd.path="./ccd" path to client-config-dir
|
|
||||||
(or OVPN_CCD_PATH)
|
|
||||||
|
|
||||||
--templates.clientconfig-path=""
|
|
||||||
(or OVPN_TEMPLATES_CC_PATH) path to custom client.conf.tpl
|
|
||||||
|
|
||||||
--templates.ccd-path="" path to custom ccd.tpl
|
|
||||||
(or OVPN_TEMPLATES_CCD_PATH)
|
|
||||||
|
|
||||||
--auth.password enable additional password authorization
|
|
||||||
(or OVPN_AUTH)
|
|
||||||
|
|
||||||
--auth.db="./easyrsa/pki/users.db"
|
|
||||||
(or OVPN_AUTH_DB_PATH) database path for password authorization
|
|
||||||
|
|
||||||
--auth.db-init
|
|
||||||
(or OVPN_AUTH_DB_INIT) enable database init if user db not exists or size is 0
|
|
||||||
|
|
||||||
--log.level set log level: trace, debug, info, warn, error (default info)
|
|
||||||
(or LOG_LEVEL)
|
|
||||||
|
|
||||||
--log.format set log format: text, json (default text)
|
|
||||||
(or LOG_FORMAT)
|
|
||||||
|
|
||||||
--storage.backend storage backend: filesystem, kubernetes.secrets (default filesystem)
|
|
||||||
(or STORAGE_BACKEND)
|
|
||||||
|
|
||||||
--version show application version
|
|
||||||
```
|
|
||||||
|
|
||||||
## Authors
|
|
||||||
|
|
||||||
ovpn-admin was originally created in [Flant](https://github.com/flant/) and used internally for years.
|
|
||||||
|
|
||||||
In March 2021, it [went public](https://medium.com/flant-com/introducing-ovpn-admin-a-web-interface-to-manage-openvpn-users-d81705ad8f23) and was still developed in Flant.
|
|
||||||
Namely, [@vitaliy-sn](https://github.com/vitaliy-sn) created its first version in Python, and [@pashcovich](https://github.com/pashcovich) rewrote it in Go.
|
|
||||||
|
|
||||||
In November 2024, this project was moved to [Palark](https://github.com/palark/), which is currently responsible for its maintenance and development.
|
|
||||||
12
build.sh
12
build.sh
@ -1,11 +1,3 @@
|
|||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
PATH=$PATH:~/go/bin
|
env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags='-extldflags "-static" -s -w' -o openvpn-admin
|
||||||
|
|
||||||
cd frontend && npm install && npm run build && cd ..
|
|
||||||
|
|
||||||
packr2
|
|
||||||
|
|
||||||
CGO_ENABLED=1 GOOS=linux GOARCH=${GOARCH:-amd64} go build -a -tags netgo -ldflags "-linkmode external -extldflags -static -s -w" $@
|
|
||||||
|
|
||||||
packr2 clean
|
|
||||||
|
|||||||
18
build_arm.sh
18
build_arm.sh
@ -1,18 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
PATH=$PATH:~/go/bin
|
|
||||||
|
|
||||||
cd frontend && npm install && npm run build && cd ..
|
|
||||||
|
|
||||||
packr2
|
|
||||||
|
|
||||||
if [[ "$GOOS" == "linux" ]]; then
|
|
||||||
if [[ "$GOARCH" == "arm" ]]; then
|
|
||||||
CC=arm-linux-gnueabi-gcc CGO_ENABLED=1 GOOS=linux GOARCH=arm go build -a -tags netgo -ldflags "-linkmode external -extldflags -static -s -w" $@
|
|
||||||
fi
|
|
||||||
if [[ "$GOARCH" == "arm64" ]]; then
|
|
||||||
CC=aarch64-linux-gnu-gcc CGO_ENABLED=1 GOOS=linux GOARCH=arm64 go build -a -tags netgo -ldflags "-linkmode external -extldflags -static -s -w" $@
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
packr2 clean
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
{{- if (ne .ClientAddress "dynamic") }}
|
{{- if (ne .ClientAddress "dynamic") }}
|
||||||
ifconfig-push {{ .ClientAddress }} 255.255.255.0
|
ifconfig-push {{ .ClientAddress }} 255.255.255.255
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- range $route := .CustomRoutes }}
|
{{- range $route := .CustomRoutes }}
|
||||||
push "route {{ $route.Address }} {{ $route.Mask }}" # {{ $route.Description }}
|
push "route {{ $route.Address }} {{ $route.Mask }}" # {{ $route.Description }}
|
||||||
207
certificates.go
207
certificates.go
@ -1,207 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/x509"
|
|
||||||
"crypto/x509/pkix"
|
|
||||||
"encoding/pem"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"math/big"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// decode certificate from PEM to x509
|
|
||||||
func decodeCert(certPEMBytes []byte) (cert *x509.Certificate, err error) {
|
|
||||||
certPem, _ := pem.Decode(certPEMBytes)
|
|
||||||
certPemBytes := certPem.Bytes
|
|
||||||
|
|
||||||
cert, err = x509.ParseCertificate(certPemBytes)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// decode private key from PEM to RSA format
|
|
||||||
func decodePrivKey(privKey []byte) (key *rsa.PrivateKey, err error) {
|
|
||||||
privKeyPem, _ := pem.Decode(privKey)
|
|
||||||
key, err = x509.ParsePKCS1PrivateKey(privKeyPem.Bytes)
|
|
||||||
if err == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp, err := x509.ParsePKCS8PrivateKey(privKeyPem.Bytes)
|
|
||||||
if err != nil {
|
|
||||||
err = errors.New("error parse private key")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
key, _ = tmp.(*rsa.PrivateKey)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// return PEM encoded private key
|
|
||||||
func genPrivKey() (privKeyPEM *bytes.Buffer, err error) {
|
|
||||||
privKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
||||||
|
|
||||||
//privKeyPKCS1 := x509.MarshalPKCS1PrivateKey(privKey)
|
|
||||||
|
|
||||||
privKeyPKCS8, err := x509.MarshalPKCS8PrivateKey(privKey)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
privKeyPEM = new(bytes.Buffer)
|
|
||||||
err = pem.Encode(privKeyPEM, &pem.Block{
|
|
||||||
Type: "RSA PRIVATE KEY",
|
|
||||||
Bytes: privKeyPKCS8,
|
|
||||||
})
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// return PEM encoded certificate
|
|
||||||
func genCA(privKey *rsa.PrivateKey) (issuerPEM *bytes.Buffer, err error) {
|
|
||||||
serialNumberRange := new(big.Int).Lsh(big.NewInt(1), 128)
|
|
||||||
|
|
||||||
issuerSerial, err := rand.Int(rand.Reader, serialNumberRange)
|
|
||||||
|
|
||||||
issuerTemplate := x509.Certificate{
|
|
||||||
BasicConstraintsValid: true,
|
|
||||||
IsCA: true,
|
|
||||||
SerialNumber: issuerSerial,
|
|
||||||
Subject: pkix.Name{
|
|
||||||
CommonName: "ca",
|
|
||||||
},
|
|
||||||
|
|
||||||
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign | x509.KeyUsageCRLSign,
|
|
||||||
NotBefore: time.Now(),
|
|
||||||
NotAfter: time.Now().AddDate(10, 0, 0),
|
|
||||||
}
|
|
||||||
issuerBytes, err := x509.CreateCertificate(rand.Reader, &issuerTemplate, &issuerTemplate, &privKey.PublicKey, privKey)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
issuerPEM = new(bytes.Buffer)
|
|
||||||
_ = pem.Encode(issuerPEM, &pem.Block{
|
|
||||||
Type: "CERTIFICATE",
|
|
||||||
Bytes: issuerBytes,
|
|
||||||
})
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// return PEM encoded certificate
|
|
||||||
func genServerCert(privKey, caPrivKey *rsa.PrivateKey, ca *x509.Certificate, cn string) (issuerPEM *bytes.Buffer, err error) {
|
|
||||||
serialNumberRange := new(big.Int).Lsh(big.NewInt(1), 128)
|
|
||||||
serial, err := rand.Int(rand.Reader, serialNumberRange)
|
|
||||||
|
|
||||||
template := x509.Certificate{
|
|
||||||
BasicConstraintsValid: true,
|
|
||||||
DNSNames: []string{cn},
|
|
||||||
SerialNumber: serial,
|
|
||||||
Subject: pkix.Name{
|
|
||||||
CommonName: cn,
|
|
||||||
},
|
|
||||||
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
|
|
||||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
|
||||||
NotBefore: time.Now(),
|
|
||||||
NotAfter: ca.NotAfter,
|
|
||||||
}
|
|
||||||
|
|
||||||
issuerBytes, err := x509.CreateCertificate(rand.Reader, &template, ca, &privKey.PublicKey, caPrivKey)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
issuerPEM = new(bytes.Buffer)
|
|
||||||
_ = pem.Encode(issuerPEM, &pem.Block{
|
|
||||||
Type: "CERTIFICATE",
|
|
||||||
Bytes: issuerBytes,
|
|
||||||
})
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// return PEM encoded certificate
|
|
||||||
func genClientCert(privKey, caPrivKey *rsa.PrivateKey, ca *x509.Certificate, cn string) (issuerPEM *bytes.Buffer, err error) {
|
|
||||||
serialNumberRange := new(big.Int).Lsh(big.NewInt(1), 128)
|
|
||||||
serial, err := rand.Int(rand.Reader, serialNumberRange)
|
|
||||||
|
|
||||||
certLifetimeDays, err := strconv.Atoi(*clientCertExpirationDays)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("can't get client certificate expiration value: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
notBefore := time.Now()
|
|
||||||
notAfter := notBefore.Add(time.Duration(certLifetimeDays) * 24 * time.Hour)
|
|
||||||
if notAfter.After(ca.NotAfter) {
|
|
||||||
notAfter = ca.NotAfter
|
|
||||||
}
|
|
||||||
|
|
||||||
template := x509.Certificate{
|
|
||||||
BasicConstraintsValid: true,
|
|
||||||
DNSNames: []string{cn},
|
|
||||||
SerialNumber: serial,
|
|
||||||
Subject: pkix.Name{
|
|
||||||
CommonName: cn,
|
|
||||||
},
|
|
||||||
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
|
|
||||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
|
||||||
NotBefore: notBefore,
|
|
||||||
NotAfter: notAfter,
|
|
||||||
}
|
|
||||||
|
|
||||||
issuerBytes, err := x509.CreateCertificate(rand.Reader, &template, ca, &privKey.PublicKey, caPrivKey)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
issuerPEM = new(bytes.Buffer)
|
|
||||||
_ = pem.Encode(issuerPEM, &pem.Block{
|
|
||||||
Type: "CERTIFICATE",
|
|
||||||
Bytes: issuerBytes,
|
|
||||||
})
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// return PEM encoded CRL
|
|
||||||
func genCRL(certs []*RevokedCert, ca *x509.Certificate, caKey *rsa.PrivateKey) (crlPEM *bytes.Buffer, err error) {
|
|
||||||
var revokedCertificates []pkix.RevokedCertificate
|
|
||||||
|
|
||||||
for _, cert := range certs {
|
|
||||||
revokedCertificates = append(revokedCertificates, pkix.RevokedCertificate{SerialNumber: cert.Cert.SerialNumber, RevocationTime: cert.RevokedTime})
|
|
||||||
}
|
|
||||||
|
|
||||||
revocationList := &x509.RevocationList{
|
|
||||||
//SignatureAlgorithm: x509.SHA256WithRSA,
|
|
||||||
RevokedCertificates: revokedCertificates,
|
|
||||||
Number: big.NewInt(1),
|
|
||||||
ThisUpdate: time.Now(),
|
|
||||||
NextUpdate: time.Now().Add(180 * time.Hour * 24),
|
|
||||||
//ExtraExtensions: []pkix.Extension{},
|
|
||||||
}
|
|
||||||
|
|
||||||
crl, err := x509.CreateRevocationList(rand.Reader, revocationList, ca, caKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
crlPEM = new(bytes.Buffer)
|
|
||||||
err = pem.Encode(crlPEM, &pem.Block{
|
|
||||||
Type: "X509 CRL",
|
|
||||||
Bytes: crl,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
owner: palark
|
|
||||||
git-base-url: https://api.github.com/
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
appVersion: "2.0.2"
|
|
||||||
description: Simple web UI to manage OpenVPN users, their certificates & routes in Linux. While backend is written in Go, frontend is based on Vue.js.
|
|
||||||
name: openvpn-admin
|
|
||||||
version: "0.0.3"
|
|
||||||
kubeVersion: ">=1.14.0-0"
|
|
||||||
maintainers:
|
|
||||||
- name: nabokihms
|
|
||||||
email: max.nabokih@gmail.com
|
|
||||||
url: github.com/nabokihms
|
|
||||||
sources:
|
|
||||||
- https://github.com/palark/openvpn-admin
|
|
||||||
keywords:
|
|
||||||
- kubernetes
|
|
||||||
- openvpn
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
# openvpn-admin
|
|
||||||
|
|
||||||
 
|
|
||||||
|
|
||||||
Simple web UI to manage OpenVPN users, their certificates & routes in Linux. While backend is written in Go, frontend is based on Vue.js.
|
|
||||||
|
|
||||||
## Maintainers
|
|
||||||
|
|
||||||
| Name | Email | Url |
|
|
||||||
| ---- | ------ | --- |
|
|
||||||
| nabokihms | <max.nabokih@gmail.com> | <github.com/nabokihms> |
|
|
||||||
|
|
||||||
## Source Code
|
|
||||||
|
|
||||||
* <https://github.com/palark/openvpn-admin>
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
|
|
||||||
Kubernetes: `>=1.14.0-0`
|
|
||||||
|
|
||||||
## Values
|
|
||||||
|
|
||||||
| Key | Type | Default | Description |
|
|
||||||
|-----|------|---------|-------------|
|
|
||||||
| ovpnAdmin.repo | string | `"ghcr.io/palark/ovpn-admin/ovpn-admin"` | |
|
|
||||||
| openvpn.repo | string | `"ghcr.io/palark/ovpn-admin/openvpn"` | |
|
|
||||||
| openvpn.subnet | string | `"172.16.200.0/255.255.255.0"` | |
|
|
||||||
| openvpn.inlet | string | `"HostPort"` | |
|
|
||||||
| openvpn.hostPort | int | `1194` | |
|
|
||||||
| nodeSelector | object | `{}` | [Node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) configuration. |
|
|
||||||
| tolerations | list | `[]` | [Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) for node taints. See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) for details. |
|
|
||||||
| ingress.enabled | bool | `false` | Enable [ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/). |
|
|
||||||
| ingress.className | string | `""` | Ingress [class name](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class). |
|
|
||||||
| ingress.annotations | object | `{}` | Annotations to be added to the ingress. |
|
|
||||||
| ingress.domain | string | `"changeme"` | |
|
|
||||||
| ingress.basicAuth.user | string | `"admin"` | |
|
|
||||||
| ingress.basicAuth.password | string | `"changeme"` | |
|
|
||||||
|
|
||||||
----------------------------------------------
|
|
||||||
Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0)
|
|
||||||
@ -1,88 +0,0 @@
|
|||||||
{{ $openvpnNetwork := required "A valid .Values.openvpn.subnet entry required!" .Values.openvpn.subnet }}
|
|
||||||
{{ $openvpnNetworkAddress := index (splitList "/" $openvpnNetwork) 0 }}
|
|
||||||
{{ $openvpnNetworkNetmask := index (splitList "/" $openvpnNetwork) 1 }}
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ConfigMap
|
|
||||||
metadata:
|
|
||||||
name: openvpn
|
|
||||||
data:
|
|
||||||
openvpn.conf: |-
|
|
||||||
user nobody
|
|
||||||
group nogroup
|
|
||||||
|
|
||||||
mode server
|
|
||||||
tls-server
|
|
||||||
# dev-type tun
|
|
||||||
dev tun
|
|
||||||
proto tcp-server
|
|
||||||
port 1194
|
|
||||||
# local 127.0.0.1
|
|
||||||
management 127.0.0.1 8989
|
|
||||||
|
|
||||||
tun-mtu 1500
|
|
||||||
mssfix
|
|
||||||
# only udp
|
|
||||||
#fragment 1300
|
|
||||||
|
|
||||||
keepalive 10 60
|
|
||||||
client-to-client
|
|
||||||
persist-key
|
|
||||||
persist-tun
|
|
||||||
|
|
||||||
cipher AES-128-CBC
|
|
||||||
duplicate-cn
|
|
||||||
|
|
||||||
server {{ $openvpnNetworkAddress }} {{ $openvpnNetworkNetmask }}
|
|
||||||
|
|
||||||
topology subnet
|
|
||||||
push "topology subnet"
|
|
||||||
push "route-metric 9999"
|
|
||||||
|
|
||||||
verb 4
|
|
||||||
|
|
||||||
ifconfig-pool-persist /tmp/openvpn.ipp
|
|
||||||
status /tmp/openvpn.status
|
|
||||||
|
|
||||||
key-direction 0
|
|
||||||
|
|
||||||
ca /etc/openvpn/certs/pki/ca.crt
|
|
||||||
key /etc/openvpn/certs/pki/private/server.key
|
|
||||||
cert /etc/openvpn/certs/pki/issued/server.crt
|
|
||||||
dh /etc/openvpn/certs/pki/dh.pem
|
|
||||||
crl-verify /etc/openvpn/certs/pki/crl.pem
|
|
||||||
tls-auth /etc/openvpn/certs/pki/ta.key
|
|
||||||
client-config-dir /etc/openvpn/ccd
|
|
||||||
|
|
||||||
entrypoint.sh: |-
|
|
||||||
#!/bin/sh
|
|
||||||
set -x
|
|
||||||
|
|
||||||
iptables -t nat -A POSTROUTING -s {{ $openvpnNetworkAddress }}/{{ $openvpnNetworkNetmask }} ! -d {{ $openvpnNetworkAddress }}/{{ $openvpnNetworkNetmask }} -j MASQUERADE
|
|
||||||
|
|
||||||
mkdir -p /dev/net
|
|
||||||
if [ ! -c /dev/net/tun ]; then
|
|
||||||
mknod /dev/net/tun c 10 200
|
|
||||||
fi
|
|
||||||
|
|
||||||
wait_file() {
|
|
||||||
file_path="$1"
|
|
||||||
while true; do
|
|
||||||
if [ -f $file_path ]; then
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
echo "wait $file_path"
|
|
||||||
sleep 2
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
easyrsa_path="/etc/openvpn/certs"
|
|
||||||
|
|
||||||
wait_file "$easyrsa_path/pki/ca.crt"
|
|
||||||
wait_file "$easyrsa_path/pki/private/server.key"
|
|
||||||
wait_file "$easyrsa_path/pki/issued/server.crt"
|
|
||||||
wait_file "$easyrsa_path/pki/ta.key"
|
|
||||||
wait_file "$easyrsa_path/pki/dh.pem"
|
|
||||||
wait_file "$easyrsa_path/pki/crl.pem"
|
|
||||||
|
|
||||||
openvpn --config /etc/openvpn/openvpn.conf
|
|
||||||
@ -1,117 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: openvpn
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: openvpn
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: openvpn
|
|
||||||
spec:
|
|
||||||
{{- if .Values.nodeSelector }}
|
|
||||||
nodeSelector:
|
|
||||||
{{- .Values.nodeSelector | toYaml | indent 8 | printf "\n%s" }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.tolerations }}
|
|
||||||
tolerations:
|
|
||||||
{{- .Values.tolerations | toYaml | indent 8 | printf "\n%s" }}
|
|
||||||
{{- end }}
|
|
||||||
terminationGracePeriodSeconds: 0
|
|
||||||
serviceAccountName: openvpn
|
|
||||||
containers:
|
|
||||||
- name: ovpn-admin
|
|
||||||
image: {{ .Values.ovpnAdmin.repo }}:master
|
|
||||||
command:
|
|
||||||
- /bin/sh
|
|
||||||
- -c
|
|
||||||
- /app/ovpn-admin
|
|
||||||
--storage.backend="kubernetes.secrets"
|
|
||||||
--listen.host="0.0.0.0"
|
|
||||||
--listen.port="8000"
|
|
||||||
--role="master"
|
|
||||||
{{- if hasKey .Values.openvpn "inlet" }}
|
|
||||||
{{- if eq .Values.openvpn.inlet "LoadBalancer" }}
|
|
||||||
--ovpn.server.behindLB
|
|
||||||
--ovpn.service="openvpn-external"
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
--mgmt=main="127.0.0.1:8989"
|
|
||||||
--ccd --ccd.path="/mnt/ccd"
|
|
||||||
--easyrsa.path="/mnt/certs"
|
|
||||||
{{- $externalHost := "" }}
|
|
||||||
{{- if hasKey .Values.openvpn "inlet" }}
|
|
||||||
{{- if eq .Values.openvpn.inlet "ExternalIP" }}{{ $externalHost = .Values.openvpn.externalIP }}{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if hasKey .Values.openvpn "externalHost" }}{{ $externalHost = .Values.openvpn.externalHost }}{{- end }}
|
|
||||||
{{- if ne $externalHost "" }}
|
|
||||||
--ovpn.server="{{ $externalHost }}:{{ .Values.openvpn.externalPort | default 5416 | quote }}:tcp"
|
|
||||||
{{- end }}
|
|
||||||
ports:
|
|
||||||
- name: ovpn-admin
|
|
||||||
protocol: TCP
|
|
||||||
containerPort: 8000
|
|
||||||
volumeMounts:
|
|
||||||
- name: certs
|
|
||||||
mountPath: /mnt/certs
|
|
||||||
- name: ccd
|
|
||||||
mountPath: /mnt/ccd
|
|
||||||
- name: openvpn
|
|
||||||
image: {{ .Values.ovpnAdmin.repo }}:master
|
|
||||||
command: [ '/entrypoint.sh' ]
|
|
||||||
# imagePullPolicy: Always
|
|
||||||
securityContext:
|
|
||||||
allowPrivilegeEscalation: false
|
|
||||||
capabilities:
|
|
||||||
add:
|
|
||||||
- NET_ADMIN
|
|
||||||
- NET_RAW
|
|
||||||
- MKNOD
|
|
||||||
- SETGID
|
|
||||||
- SETUID
|
|
||||||
drop:
|
|
||||||
- ALL
|
|
||||||
ports:
|
|
||||||
- name: openvpn-tcp
|
|
||||||
protocol: TCP
|
|
||||||
containerPort: 1194
|
|
||||||
{{- if eq .Values.openvpn.inlet "HostPort" }}
|
|
||||||
hostPort: {{ .Values.openvpn.hostPort }}
|
|
||||||
{{- end }}
|
|
||||||
volumeMounts:
|
|
||||||
- name: tmp
|
|
||||||
mountPath: /tmp
|
|
||||||
- name: dev-net
|
|
||||||
mountPath: /dev/net
|
|
||||||
- name: certs
|
|
||||||
mountPath: /etc/openvpn/certs
|
|
||||||
- name: ccd
|
|
||||||
mountPath: /etc/openvpn/ccd
|
|
||||||
- name: config
|
|
||||||
mountPath: /etc/openvpn/openvpn.conf
|
|
||||||
subPath: openvpn.conf
|
|
||||||
readOnly: true
|
|
||||||
- name: entrypoint
|
|
||||||
mountPath: /entrypoint.sh
|
|
||||||
subPath: entrypoint.sh
|
|
||||||
readOnly: true
|
|
||||||
volumes:
|
|
||||||
- name: tmp
|
|
||||||
emptyDir: {}
|
|
||||||
- name: dev-net
|
|
||||||
emptyDir: {}
|
|
||||||
- name: certs
|
|
||||||
emptyDir: {}
|
|
||||||
- name: ccd
|
|
||||||
emptyDir: {}
|
|
||||||
- name: config
|
|
||||||
configMap:
|
|
||||||
name: openvpn
|
|
||||||
defaultMode: 0644
|
|
||||||
- name: entrypoint
|
|
||||||
configMap:
|
|
||||||
name: openvpn
|
|
||||||
defaultMode: 0755
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: networking.k8s.io/v1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: ovpn-admin
|
|
||||||
annotations:
|
|
||||||
nginx.ingress.kubernetes.io/backend-protocol: HTTP
|
|
||||||
nginx.ingress.kubernetes.io/auth-type: basic
|
|
||||||
nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"
|
|
||||||
nginx.ingress.kubernetes.io/auth-secret: basic-auth
|
|
||||||
{{- with .Values.ingress.annotations }}
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
{{- with .Values.ingress.className }}
|
|
||||||
ingressClassName: {{ . | quote }}
|
|
||||||
{{- end }}
|
|
||||||
tls:
|
|
||||||
- hosts:
|
|
||||||
- {{ .Values.ingress.domain }}
|
|
||||||
secretName: ingress-tls
|
|
||||||
rules:
|
|
||||||
- host: {{ .Values.ingress.domain }}
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- path: /
|
|
||||||
pathType: Prefix
|
|
||||||
backend:
|
|
||||||
service:
|
|
||||||
name: ovpn-admin
|
|
||||||
port:
|
|
||||||
name: http
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: openvpn
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: Role
|
|
||||||
metadata:
|
|
||||||
name: openvpn
|
|
||||||
rules:
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- services
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- secrets
|
|
||||||
verbs:
|
|
||||||
- "*"
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: RoleBinding
|
|
||||||
metadata:
|
|
||||||
name: openvpn
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: Role
|
|
||||||
name: openvpn
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: openvpn
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
name: basic-auth
|
|
||||||
type: Opaque
|
|
||||||
data:
|
|
||||||
auth: {{ print .Values.ingress.basicAuth.user ":{PLAIN}" .Values.ingress.basicAuth.password | b64enc | quote }}
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: ovpn-admin
|
|
||||||
spec:
|
|
||||||
clusterIP: None
|
|
||||||
ports:
|
|
||||||
- name: http
|
|
||||||
port: 8000
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: 8000
|
|
||||||
selector:
|
|
||||||
app: openvpn
|
|
||||||
---
|
|
||||||
{{- if hasKey .Values.openvpn "inlet" }}
|
|
||||||
|
|
||||||
{{- if eq .Values.openvpn.inlet "LoadBalancer" }}
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: openvpn-external
|
|
||||||
spec:
|
|
||||||
externalTrafficPolicy: Local
|
|
||||||
type: LoadBalancer
|
|
||||||
ports:
|
|
||||||
- name: openvpn-tcp
|
|
||||||
protocol: TCP
|
|
||||||
port: {{ .Values.openvpn.externalPort | default 1194 }}
|
|
||||||
targetPort: openvpn-tcp
|
|
||||||
selector:
|
|
||||||
app: openvpn
|
|
||||||
{{- else if eq .Values.openvpn.inlet "ExternalIP" }}
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: openvpn-external
|
|
||||||
spec:
|
|
||||||
type: ClusterIP
|
|
||||||
externalIPs:
|
|
||||||
- {{ .Values.openvpn.externalIP }}
|
|
||||||
ports:
|
|
||||||
- name: openvpn-tcp
|
|
||||||
port: {{ .Values.openvpn.externalPort | default 1194 }}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: openvpn-tcp
|
|
||||||
selector:
|
|
||||||
app: openvpn
|
|
||||||
{{- else if eq .Values.openvpn.inlet "HostPort" }}
|
|
||||||
---
|
|
||||||
{{- else }}
|
|
||||||
{{- cat "Unsupported inlet type" .inlet | fail }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- end }}
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
ovpnAdmin:
|
|
||||||
repo: ghcr.io/palark/ovpn-admin/ovpn-admin
|
|
||||||
|
|
||||||
openvpn:
|
|
||||||
repo: ghcr.io/palark/ovpn-admin/openvpn
|
|
||||||
subnet: 172.16.200.0/255.255.255.0
|
|
||||||
# LoadBalancer or ExternalIP or HostPort
|
|
||||||
inlet: HostPort
|
|
||||||
#
|
|
||||||
# If inlet: ExternalIP
|
|
||||||
# externalIP: 1.2.3.4
|
|
||||||
# externalPort: 1194
|
|
||||||
#
|
|
||||||
# If inlet: HostPort
|
|
||||||
hostPort: 1194
|
|
||||||
# Domain or ip for connect to OpenVPN server
|
|
||||||
# externalHost: 1.2.3.4
|
|
||||||
|
|
||||||
# -- [Node selector](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector) configuration.
|
|
||||||
nodeSelector: {}
|
|
||||||
|
|
||||||
# -- [Tolerations](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) for node taints.
|
|
||||||
# See the [API reference](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#scheduling) for details.
|
|
||||||
tolerations: []
|
|
||||||
|
|
||||||
ingress:
|
|
||||||
# -- Enable [ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/).
|
|
||||||
enabled: false
|
|
||||||
|
|
||||||
# -- Ingress [class name](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-class).
|
|
||||||
className: ""
|
|
||||||
|
|
||||||
# -- Annotations to be added to the ingress.
|
|
||||||
annotations: {}
|
|
||||||
# kubernetes.io/ingress.class: nginx
|
|
||||||
# kubernetes.io/tls-acme: "true"
|
|
||||||
|
|
||||||
domain: changeme
|
|
||||||
|
|
||||||
basicAuth:
|
|
||||||
user: admin
|
|
||||||
password: changeme
|
|
||||||
29
client.conf.tpl
Normal file
29
client.conf.tpl
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{{- range $server := .Hosts }}
|
||||||
|
remote {{ $server.Host }} {{ $server.Port }} tcp
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
verb 4
|
||||||
|
client
|
||||||
|
nobind
|
||||||
|
dev tun
|
||||||
|
cipher AES-128-CBC
|
||||||
|
key-direction 1
|
||||||
|
#redirect-gateway def1
|
||||||
|
tls-client
|
||||||
|
remote-cert-tls server
|
||||||
|
# for update resolv.conf on ubuntu
|
||||||
|
#script-security 2 system
|
||||||
|
#up /etc/openvpn/update-resolv-conf
|
||||||
|
#down /etc/openvpn/update-resolv-conf
|
||||||
|
<cert>
|
||||||
|
{{ .Cert -}}
|
||||||
|
</cert>
|
||||||
|
<key>
|
||||||
|
{{ .Key -}}
|
||||||
|
</key>
|
||||||
|
<ca>
|
||||||
|
{{ .CA -}}
|
||||||
|
</ca>
|
||||||
|
<tls-auth>
|
||||||
|
{{ .TLS -}}
|
||||||
|
</tls-auth>
|
||||||
@ -1,974 +0,0 @@
|
|||||||
{
|
|
||||||
"annotations": {
|
|
||||||
"list": [
|
|
||||||
{
|
|
||||||
"builtIn": 1,
|
|
||||||
"datasource": {
|
|
||||||
"type": "datasource",
|
|
||||||
"uid": "grafana"
|
|
||||||
},
|
|
||||||
"enable": true,
|
|
||||||
"hide": true,
|
|
||||||
"iconColor": "rgba(0, 211, 255, 1)",
|
|
||||||
"name": "Annotations & Alerts",
|
|
||||||
"target": {
|
|
||||||
"limit": 100,
|
|
||||||
"matchAny": false,
|
|
||||||
"tags": [],
|
|
||||||
"type": "dashboard"
|
|
||||||
},
|
|
||||||
"type": "dashboard"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"editable": true,
|
|
||||||
"fiscalYearStartMonth": 0,
|
|
||||||
"graphTooltip": 0,
|
|
||||||
"id": 54,
|
|
||||||
"links": [],
|
|
||||||
"liveNow": false,
|
|
||||||
"panels": [
|
|
||||||
{
|
|
||||||
"datasource": {
|
|
||||||
"type": "prometheus",
|
|
||||||
"uid": "$ds_prometheus"
|
|
||||||
},
|
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": {
|
|
||||||
"decimals": 1,
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "percentage",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green",
|
|
||||||
"value": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "red",
|
|
||||||
"value": 10
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"unit": "d"
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"gridPos": {
|
|
||||||
"h": 5,
|
|
||||||
"w": 7,
|
|
||||||
"x": 5,
|
|
||||||
"y": 0
|
|
||||||
},
|
|
||||||
"id": 2,
|
|
||||||
"options": {
|
|
||||||
"colorMode": "value",
|
|
||||||
"graphMode": "none",
|
|
||||||
"justifyMode": "center",
|
|
||||||
"orientation": "auto",
|
|
||||||
"reduceOptions": {
|
|
||||||
"calcs": [
|
|
||||||
"last"
|
|
||||||
],
|
|
||||||
"fields": "",
|
|
||||||
"values": false
|
|
||||||
},
|
|
||||||
"textMode": "auto"
|
|
||||||
},
|
|
||||||
"pluginVersion": "8.5.2",
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "ovpn_server_cert_expire",
|
|
||||||
"interval": "",
|
|
||||||
"legendFormat": "",
|
|
||||||
"refId": "A"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"title": "Server cert valid time",
|
|
||||||
"type": "stat"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"datasource": {
|
|
||||||
"type": "prometheus",
|
|
||||||
"uid": "$ds_prometheus"
|
|
||||||
},
|
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": {
|
|
||||||
"decimals": 1,
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "percentage",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green",
|
|
||||||
"value": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "red",
|
|
||||||
"value": 10
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"unit": "d"
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"gridPos": {
|
|
||||||
"h": 5,
|
|
||||||
"w": 7,
|
|
||||||
"x": 12,
|
|
||||||
"y": 0
|
|
||||||
},
|
|
||||||
"id": 3,
|
|
||||||
"options": {
|
|
||||||
"colorMode": "value",
|
|
||||||
"graphMode": "none",
|
|
||||||
"justifyMode": "center",
|
|
||||||
"orientation": "auto",
|
|
||||||
"reduceOptions": {
|
|
||||||
"calcs": [
|
|
||||||
"last"
|
|
||||||
],
|
|
||||||
"fields": "",
|
|
||||||
"values": false
|
|
||||||
},
|
|
||||||
"textMode": "auto"
|
|
||||||
},
|
|
||||||
"pluginVersion": "8.5.2",
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "ovpn_server_ca_cert_expire",
|
|
||||||
"interval": "",
|
|
||||||
"legendFormat": "",
|
|
||||||
"refId": "A"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"title": "Server CA cert valid time",
|
|
||||||
"type": "stat"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"datasource": {
|
|
||||||
"type": "prometheus",
|
|
||||||
"uid": "$ds_prometheus"
|
|
||||||
},
|
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": {
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green",
|
|
||||||
"value": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "semi-dark-orange",
|
|
||||||
"value": 200
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"gridPos": {
|
|
||||||
"h": 5,
|
|
||||||
"w": 6,
|
|
||||||
"x": 0,
|
|
||||||
"y": 5
|
|
||||||
},
|
|
||||||
"id": 4,
|
|
||||||
"options": {
|
|
||||||
"colorMode": "value",
|
|
||||||
"graphMode": "none",
|
|
||||||
"justifyMode": "center",
|
|
||||||
"orientation": "auto",
|
|
||||||
"reduceOptions": {
|
|
||||||
"calcs": [
|
|
||||||
"last"
|
|
||||||
],
|
|
||||||
"fields": "",
|
|
||||||
"values": false
|
|
||||||
},
|
|
||||||
"textMode": "auto"
|
|
||||||
},
|
|
||||||
"pluginVersion": "8.5.2",
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "ovpn_clients_total",
|
|
||||||
"interval": "",
|
|
||||||
"legendFormat": "",
|
|
||||||
"refId": "A"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"title": "Total clients",
|
|
||||||
"type": "stat"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"datasource": {
|
|
||||||
"type": "prometheus",
|
|
||||||
"uid": "$ds_prometheus"
|
|
||||||
},
|
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": {
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green",
|
|
||||||
"value": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "red",
|
|
||||||
"value": 80
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"gridPos": {
|
|
||||||
"h": 5,
|
|
||||||
"w": 6,
|
|
||||||
"x": 6,
|
|
||||||
"y": 5
|
|
||||||
},
|
|
||||||
"id": 5,
|
|
||||||
"options": {
|
|
||||||
"colorMode": "value",
|
|
||||||
"graphMode": "none",
|
|
||||||
"justifyMode": "center",
|
|
||||||
"orientation": "auto",
|
|
||||||
"reduceOptions": {
|
|
||||||
"calcs": [
|
|
||||||
"last"
|
|
||||||
],
|
|
||||||
"fields": "",
|
|
||||||
"values": false
|
|
||||||
},
|
|
||||||
"textMode": "auto"
|
|
||||||
},
|
|
||||||
"pluginVersion": "8.5.2",
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "ovpn_clients_connected",
|
|
||||||
"interval": "",
|
|
||||||
"legendFormat": "",
|
|
||||||
"refId": "A"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"title": "Connected clients",
|
|
||||||
"type": "stat"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"datasource": {
|
|
||||||
"type": "prometheus",
|
|
||||||
"uid": "$ds_prometheus"
|
|
||||||
},
|
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": {
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green",
|
|
||||||
"value": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "semi-dark-orange",
|
|
||||||
"value": 10
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"gridPos": {
|
|
||||||
"h": 5,
|
|
||||||
"w": 6,
|
|
||||||
"x": 12,
|
|
||||||
"y": 5
|
|
||||||
},
|
|
||||||
"id": 7,
|
|
||||||
"options": {
|
|
||||||
"colorMode": "value",
|
|
||||||
"graphMode": "none",
|
|
||||||
"justifyMode": "center",
|
|
||||||
"orientation": "auto",
|
|
||||||
"reduceOptions": {
|
|
||||||
"calcs": [
|
|
||||||
"last"
|
|
||||||
],
|
|
||||||
"fields": "",
|
|
||||||
"values": false
|
|
||||||
},
|
|
||||||
"textMode": "auto"
|
|
||||||
},
|
|
||||||
"pluginVersion": "8.5.13",
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "ovpn_clients_expired",
|
|
||||||
"interval": "",
|
|
||||||
"legendFormat": "",
|
|
||||||
"refId": "A"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"title": "Revoked clients",
|
|
||||||
"type": "stat"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"datasource": {
|
|
||||||
"type": "prometheus",
|
|
||||||
"uid": "$ds_prometheus"
|
|
||||||
},
|
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": {
|
|
||||||
"mappings": [],
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green",
|
|
||||||
"value": null
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "red",
|
|
||||||
"value": 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"gridPos": {
|
|
||||||
"h": 5,
|
|
||||||
"w": 6,
|
|
||||||
"x": 18,
|
|
||||||
"y": 5
|
|
||||||
},
|
|
||||||
"id": 6,
|
|
||||||
"options": {
|
|
||||||
"colorMode": "value",
|
|
||||||
"graphMode": "none",
|
|
||||||
"justifyMode": "center",
|
|
||||||
"orientation": "auto",
|
|
||||||
"reduceOptions": {
|
|
||||||
"calcs": [
|
|
||||||
"last"
|
|
||||||
],
|
|
||||||
"fields": "",
|
|
||||||
"values": false
|
|
||||||
},
|
|
||||||
"textMode": "auto"
|
|
||||||
},
|
|
||||||
"pluginVersion": "8.5.2",
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "ovpn_clients_expired",
|
|
||||||
"interval": "",
|
|
||||||
"legendFormat": "",
|
|
||||||
"refId": "A"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"title": "Expired clients",
|
|
||||||
"type": "stat"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"aliasColors": {},
|
|
||||||
"bars": false,
|
|
||||||
"dashLength": 10,
|
|
||||||
"dashes": false,
|
|
||||||
"datasource": {
|
|
||||||
"type": "prometheus",
|
|
||||||
"uid": "$ds_prometheus"
|
|
||||||
},
|
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": {
|
|
||||||
"links": []
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"fill": 2,
|
|
||||||
"fillGradient": 0,
|
|
||||||
"gridPos": {
|
|
||||||
"h": 8,
|
|
||||||
"w": 12,
|
|
||||||
"x": 0,
|
|
||||||
"y": 10
|
|
||||||
},
|
|
||||||
"hiddenSeries": false,
|
|
||||||
"id": 9,
|
|
||||||
"legend": {
|
|
||||||
"avg": false,
|
|
||||||
"current": false,
|
|
||||||
"hideEmpty": true,
|
|
||||||
"max": false,
|
|
||||||
"min": false,
|
|
||||||
"show": false,
|
|
||||||
"total": false,
|
|
||||||
"values": false
|
|
||||||
},
|
|
||||||
"lines": true,
|
|
||||||
"linewidth": 1,
|
|
||||||
"nullPointMode": "null as zero",
|
|
||||||
"options": {
|
|
||||||
"alertThreshold": true
|
|
||||||
},
|
|
||||||
"percentage": false,
|
|
||||||
"pluginVersion": "8.5.2",
|
|
||||||
"pointradius": 2,
|
|
||||||
"points": false,
|
|
||||||
"renderer": "flot",
|
|
||||||
"seriesOverrides": [],
|
|
||||||
"spaceLength": 10,
|
|
||||||
"stack": false,
|
|
||||||
"steppedLine": false,
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "ovpn_client_bytes_received",
|
|
||||||
"interval": "",
|
|
||||||
"legendFormat": "{{ client }}",
|
|
||||||
"refId": "A"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"thresholds": [],
|
|
||||||
"timeRegions": [],
|
|
||||||
"title": "Сlient bytes received",
|
|
||||||
"tooltip": {
|
|
||||||
"shared": true,
|
|
||||||
"sort": 0,
|
|
||||||
"value_type": "individual"
|
|
||||||
},
|
|
||||||
"type": "graph",
|
|
||||||
"xaxis": {
|
|
||||||
"mode": "time",
|
|
||||||
"show": true,
|
|
||||||
"values": []
|
|
||||||
},
|
|
||||||
"yaxes": [
|
|
||||||
{
|
|
||||||
"format": "decbytes",
|
|
||||||
"logBase": 1,
|
|
||||||
"show": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"format": "short",
|
|
||||||
"logBase": 1,
|
|
||||||
"show": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"yaxis": {
|
|
||||||
"align": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"aliasColors": {},
|
|
||||||
"bars": false,
|
|
||||||
"dashLength": 10,
|
|
||||||
"dashes": false,
|
|
||||||
"datasource": {
|
|
||||||
"type": "prometheus",
|
|
||||||
"uid": "$ds_prometheus"
|
|
||||||
},
|
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": {
|
|
||||||
"links": []
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"fill": 2,
|
|
||||||
"fillGradient": 0,
|
|
||||||
"gridPos": {
|
|
||||||
"h": 8,
|
|
||||||
"w": 12,
|
|
||||||
"x": 12,
|
|
||||||
"y": 10
|
|
||||||
},
|
|
||||||
"hiddenSeries": false,
|
|
||||||
"id": 10,
|
|
||||||
"legend": {
|
|
||||||
"avg": false,
|
|
||||||
"current": false,
|
|
||||||
"hideEmpty": true,
|
|
||||||
"max": false,
|
|
||||||
"min": false,
|
|
||||||
"show": false,
|
|
||||||
"total": false,
|
|
||||||
"values": false
|
|
||||||
},
|
|
||||||
"lines": true,
|
|
||||||
"linewidth": 1,
|
|
||||||
"nullPointMode": "null as zero",
|
|
||||||
"options": {
|
|
||||||
"alertThreshold": true
|
|
||||||
},
|
|
||||||
"percentage": false,
|
|
||||||
"pluginVersion": "8.5.2",
|
|
||||||
"pointradius": 2,
|
|
||||||
"points": false,
|
|
||||||
"renderer": "flot",
|
|
||||||
"seriesOverrides": [],
|
|
||||||
"spaceLength": 10,
|
|
||||||
"stack": false,
|
|
||||||
"steppedLine": false,
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "ovpn_client_bytes_sent",
|
|
||||||
"interval": "",
|
|
||||||
"legendFormat": "{{ client }}",
|
|
||||||
"refId": "A"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"thresholds": [],
|
|
||||||
"timeRegions": [],
|
|
||||||
"title": "Сlient bytes sent",
|
|
||||||
"tooltip": {
|
|
||||||
"shared": true,
|
|
||||||
"sort": 0,
|
|
||||||
"value_type": "individual"
|
|
||||||
},
|
|
||||||
"type": "graph",
|
|
||||||
"xaxis": {
|
|
||||||
"mode": "time",
|
|
||||||
"show": true,
|
|
||||||
"values": []
|
|
||||||
},
|
|
||||||
"yaxes": [
|
|
||||||
{
|
|
||||||
"format": "decbytes",
|
|
||||||
"logBase": 1,
|
|
||||||
"show": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"format": "short",
|
|
||||||
"logBase": 1,
|
|
||||||
"show": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"yaxis": {
|
|
||||||
"align": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"aliasColors": {},
|
|
||||||
"bars": false,
|
|
||||||
"dashLength": 10,
|
|
||||||
"dashes": false,
|
|
||||||
"datasource": {
|
|
||||||
"type": "prometheus",
|
|
||||||
"uid": "$ds_prometheus"
|
|
||||||
},
|
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": {
|
|
||||||
"links": []
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"fill": 1,
|
|
||||||
"fillGradient": 0,
|
|
||||||
"gridPos": {
|
|
||||||
"h": 8,
|
|
||||||
"w": 12,
|
|
||||||
"x": 0,
|
|
||||||
"y": 18
|
|
||||||
},
|
|
||||||
"hiddenSeries": false,
|
|
||||||
"id": 16,
|
|
||||||
"legend": {
|
|
||||||
"avg": false,
|
|
||||||
"current": false,
|
|
||||||
"hideEmpty": true,
|
|
||||||
"max": false,
|
|
||||||
"min": false,
|
|
||||||
"show": false,
|
|
||||||
"total": false,
|
|
||||||
"values": false
|
|
||||||
},
|
|
||||||
"lines": true,
|
|
||||||
"linewidth": 1,
|
|
||||||
"nullPointMode": "null as zero",
|
|
||||||
"options": {
|
|
||||||
"alertThreshold": true
|
|
||||||
},
|
|
||||||
"percentage": false,
|
|
||||||
"pluginVersion": "8.5.2",
|
|
||||||
"pointradius": 2,
|
|
||||||
"points": false,
|
|
||||||
"renderer": "flot",
|
|
||||||
"seriesOverrides": [],
|
|
||||||
"spaceLength": 10,
|
|
||||||
"stack": false,
|
|
||||||
"steppedLine": false,
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "rate(ovpn_client_bytes_received[1m])",
|
|
||||||
"interval": "",
|
|
||||||
"legendFormat": "{{ client }}",
|
|
||||||
"refId": "A"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"thresholds": [],
|
|
||||||
"timeRegions": [],
|
|
||||||
"title": "Clients bytes received rate",
|
|
||||||
"tooltip": {
|
|
||||||
"shared": true,
|
|
||||||
"sort": 0,
|
|
||||||
"value_type": "individual"
|
|
||||||
},
|
|
||||||
"type": "graph",
|
|
||||||
"xaxis": {
|
|
||||||
"mode": "time",
|
|
||||||
"show": true,
|
|
||||||
"values": []
|
|
||||||
},
|
|
||||||
"yaxes": [
|
|
||||||
{
|
|
||||||
"$$hashKey": "object:93",
|
|
||||||
"format": "Bps",
|
|
||||||
"logBase": 1,
|
|
||||||
"show": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"$$hashKey": "object:94",
|
|
||||||
"format": "short",
|
|
||||||
"logBase": 1,
|
|
||||||
"show": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"yaxis": {
|
|
||||||
"align": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"aliasColors": {},
|
|
||||||
"bars": false,
|
|
||||||
"dashLength": 10,
|
|
||||||
"dashes": false,
|
|
||||||
"datasource": {
|
|
||||||
"type": "prometheus",
|
|
||||||
"uid": "$ds_prometheus"
|
|
||||||
},
|
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": {
|
|
||||||
"links": []
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"fill": 1,
|
|
||||||
"fillGradient": 0,
|
|
||||||
"gridPos": {
|
|
||||||
"h": 8,
|
|
||||||
"w": 12,
|
|
||||||
"x": 12,
|
|
||||||
"y": 18
|
|
||||||
},
|
|
||||||
"hiddenSeries": false,
|
|
||||||
"id": 17,
|
|
||||||
"legend": {
|
|
||||||
"avg": false,
|
|
||||||
"current": false,
|
|
||||||
"hideEmpty": true,
|
|
||||||
"max": false,
|
|
||||||
"min": false,
|
|
||||||
"show": false,
|
|
||||||
"total": false,
|
|
||||||
"values": false
|
|
||||||
},
|
|
||||||
"lines": true,
|
|
||||||
"linewidth": 1,
|
|
||||||
"nullPointMode": "null as zero",
|
|
||||||
"options": {
|
|
||||||
"alertThreshold": true
|
|
||||||
},
|
|
||||||
"percentage": false,
|
|
||||||
"pluginVersion": "8.5.2",
|
|
||||||
"pointradius": 2,
|
|
||||||
"points": false,
|
|
||||||
"renderer": "flot",
|
|
||||||
"seriesOverrides": [],
|
|
||||||
"spaceLength": 10,
|
|
||||||
"stack": false,
|
|
||||||
"steppedLine": false,
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "rate(ovpn_client_bytes_sent[1m])",
|
|
||||||
"interval": "",
|
|
||||||
"legendFormat": "{{ client }}",
|
|
||||||
"refId": "A"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"thresholds": [],
|
|
||||||
"timeRegions": [],
|
|
||||||
"title": "Client bytes sent rate ",
|
|
||||||
"tooltip": {
|
|
||||||
"shared": true,
|
|
||||||
"sort": 0,
|
|
||||||
"value_type": "individual"
|
|
||||||
},
|
|
||||||
"type": "graph",
|
|
||||||
"xaxis": {
|
|
||||||
"mode": "time",
|
|
||||||
"show": true,
|
|
||||||
"values": []
|
|
||||||
},
|
|
||||||
"yaxes": [
|
|
||||||
{
|
|
||||||
"$$hashKey": "object:174",
|
|
||||||
"format": "Bps",
|
|
||||||
"logBase": 1,
|
|
||||||
"show": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"$$hashKey": "object:175",
|
|
||||||
"format": "short",
|
|
||||||
"logBase": 1,
|
|
||||||
"show": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"yaxis": {
|
|
||||||
"align": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"datasource": {
|
|
||||||
"type": "prometheus",
|
|
||||||
"uid": "$ds_prometheus"
|
|
||||||
},
|
|
||||||
"description": "value show last connection check time",
|
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": {
|
|
||||||
"custom": {
|
|
||||||
"align": "center",
|
|
||||||
"displayMode": "auto",
|
|
||||||
"width": 20
|
|
||||||
},
|
|
||||||
"mappings": [],
|
|
||||||
"noValue": "Currently there are no connections",
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"unit": "dateTimeAsIso"
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"gridPos": {
|
|
||||||
"h": 8,
|
|
||||||
"w": 12,
|
|
||||||
"x": 0,
|
|
||||||
"y": 26
|
|
||||||
},
|
|
||||||
"id": 12,
|
|
||||||
"maxDataPoints": 1,
|
|
||||||
"options": {
|
|
||||||
"colorMode": "value",
|
|
||||||
"graphMode": "none",
|
|
||||||
"justifyMode": "auto",
|
|
||||||
"orientation": "horizontal",
|
|
||||||
"reduceOptions": {
|
|
||||||
"calcs": [
|
|
||||||
"last"
|
|
||||||
],
|
|
||||||
"fields": "",
|
|
||||||
"values": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pluginVersion": "7.0.6",
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "ovpn_client_connection_info * 1000",
|
|
||||||
"format": "time_series",
|
|
||||||
"interval": "",
|
|
||||||
"legendFormat": "{{ client }}-{{ip}}",
|
|
||||||
"refId": "A"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"title": "Connection info",
|
|
||||||
"type": "stat"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"datasource": {
|
|
||||||
"type": "prometheus",
|
|
||||||
"uid": "$ds_prometheus"
|
|
||||||
},
|
|
||||||
"description": "value shows when connection was started",
|
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": {
|
|
||||||
"custom": {
|
|
||||||
"align": "center",
|
|
||||||
"displayMode": "auto",
|
|
||||||
"width": 20
|
|
||||||
},
|
|
||||||
"mappings": [],
|
|
||||||
"noValue": "Currently there are no connections",
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"unit": "dateTimeAsIso"
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"gridPos": {
|
|
||||||
"h": 8,
|
|
||||||
"w": 12,
|
|
||||||
"x": 12,
|
|
||||||
"y": 26
|
|
||||||
},
|
|
||||||
"id": 13,
|
|
||||||
"maxDataPoints": 1,
|
|
||||||
"options": {
|
|
||||||
"colorMode": "value",
|
|
||||||
"graphMode": "none",
|
|
||||||
"justifyMode": "auto",
|
|
||||||
"orientation": "horizontal",
|
|
||||||
"reduceOptions": {
|
|
||||||
"calcs": [
|
|
||||||
"last"
|
|
||||||
],
|
|
||||||
"fields": "",
|
|
||||||
"values": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pluginVersion": "7.0.6",
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "ovpn_client_connection_from * 1000",
|
|
||||||
"format": "time_series",
|
|
||||||
"interval": "",
|
|
||||||
"legendFormat": "{{ client }}-{{ip}}",
|
|
||||||
"refId": "A"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"title": "Connection from",
|
|
||||||
"type": "stat"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"datasource": {
|
|
||||||
"type": "prometheus",
|
|
||||||
"uid": "$ds_prometheus"
|
|
||||||
},
|
|
||||||
"fieldConfig": {
|
|
||||||
"defaults": {
|
|
||||||
"custom": {},
|
|
||||||
"mappings": [],
|
|
||||||
"min": 0,
|
|
||||||
"thresholds": {
|
|
||||||
"mode": "absolute",
|
|
||||||
"steps": [
|
|
||||||
{
|
|
||||||
"color": "green"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "red",
|
|
||||||
"value": 7
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "dark-orange",
|
|
||||||
"value": 14
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "#EAB839",
|
|
||||||
"value": 30
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"color": "green",
|
|
||||||
"value": 31
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"overrides": []
|
|
||||||
},
|
|
||||||
"gridPos": {
|
|
||||||
"h": 14,
|
|
||||||
"w": 24,
|
|
||||||
"x": 0,
|
|
||||||
"y": 34
|
|
||||||
},
|
|
||||||
"id": 19,
|
|
||||||
"options": {
|
|
||||||
"colorMode": "value",
|
|
||||||
"graphMode": "none",
|
|
||||||
"justifyMode": "center",
|
|
||||||
"orientation": "auto",
|
|
||||||
"reduceOptions": {
|
|
||||||
"calcs": [
|
|
||||||
"last"
|
|
||||||
],
|
|
||||||
"fields": "",
|
|
||||||
"values": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pluginVersion": "7.0.6",
|
|
||||||
"targets": [
|
|
||||||
{
|
|
||||||
"expr": "ovpn_client_cert_expire ",
|
|
||||||
"format": "time_series",
|
|
||||||
"interval": "",
|
|
||||||
"legendFormat": "{{ client }}",
|
|
||||||
"refId": "A"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"title": "Client cert valid days",
|
|
||||||
"type": "stat"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"refresh": false,
|
|
||||||
"schemaVersion": 36,
|
|
||||||
"style": "dark",
|
|
||||||
"tags": [],
|
|
||||||
"templating": {
|
|
||||||
"list": [
|
|
||||||
{
|
|
||||||
"current": {
|
|
||||||
"selected": false,
|
|
||||||
"text": "default",
|
|
||||||
"value": "default"
|
|
||||||
},
|
|
||||||
"hide": 0,
|
|
||||||
"includeAll": false,
|
|
||||||
"multi": false,
|
|
||||||
"label": "Prometheus",
|
|
||||||
"name": "ds_prometheus",
|
|
||||||
"options": [],
|
|
||||||
"query": "prometheus",
|
|
||||||
"refresh": 1,
|
|
||||||
"regex": "",
|
|
||||||
"skipUrlSync": false,
|
|
||||||
"type": "datasource"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"time": {
|
|
||||||
"from": "now-15m",
|
|
||||||
"to": "now"
|
|
||||||
},
|
|
||||||
"timepicker": {
|
|
||||||
"refresh_intervals": [
|
|
||||||
"10s",
|
|
||||||
"30s",
|
|
||||||
"1m",
|
|
||||||
"5m",
|
|
||||||
"15m",
|
|
||||||
"30m",
|
|
||||||
"1h",
|
|
||||||
"2h",
|
|
||||||
"1d"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"timezone": "",
|
|
||||||
"title": "Ovpn-Admin",
|
|
||||||
"uid": "Z7qmFI0Gk",
|
|
||||||
"version": 1,
|
|
||||||
"weekStart": ""
|
|
||||||
}
|
|
||||||
@ -8,22 +8,22 @@ services:
|
|||||||
image: openvpn:local
|
image: openvpn:local
|
||||||
command: /etc/openvpn/setup/configure.sh
|
command: /etc/openvpn/setup/configure.sh
|
||||||
environment:
|
environment:
|
||||||
- OVPN_ROLE=slave
|
- OPVN_ROLE=slave
|
||||||
cap_add:
|
cap_add:
|
||||||
- NET_ADMIN
|
- NET_ADMIN
|
||||||
ports:
|
ports:
|
||||||
- 7778:1194 # for openvpn
|
- 7778:1194 # for openvpn
|
||||||
- 8081:8080 # for ovpn-admin because of network_mode
|
- 8081:8080 # for openvpn-admin because of network_mode
|
||||||
volumes:
|
volumes:
|
||||||
- ./easyrsa_slave:/etc/openvpn/easyrsa
|
- ./easyrsa_slave:/etc/openvpn/easyrsa
|
||||||
- ./ccd_slave:/etc/openvpn/ccd
|
- ./ccd_slave:/etc/openvpn/ccd
|
||||||
ovpn-admin:
|
openvpn-admin:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
image: ovpn-admin:local
|
image: openvpn-admin:local
|
||||||
command: /app/ovpn-admin --debug --ovpn.network="172.16.100.0/22" --master.sync-token="TOKEN" --master.host="http://172.20.0.1:8080" --role="slave" --ovpn.server="127.0.0.1:7777:tcp" --ovpn.server="127.0.0.1:7778:tcp" --easyrsa.path="/mnt/easyrsa" --easyrsa.index-path="/mnt/easyrsa/pki/index.txt"
|
command: /app/openvpn-admin --debug --ovpn.network="172.16.100.0/22" --master.sync-token="TOKEN" --master.host="http://172.20.0.1:8080" --role="slave" --ovpn.host="127.0.0.1:7744" --ovpn.host="127.0.0.1:7778"
|
||||||
environment:
|
environment:
|
||||||
- OVPN_SLAVE=1
|
- OPVN_SLAVE=1
|
||||||
network_mode: service:openvpn
|
network_mode: service:openvpn
|
||||||
volumes:
|
volumes:
|
||||||
- ./easyrsa_slave:/mnt/easyrsa
|
- ./easyrsa_slave:/mnt/easyrsa
|
||||||
|
|||||||
@ -7,36 +7,19 @@ services:
|
|||||||
dockerfile: Dockerfile.openvpn
|
dockerfile: Dockerfile.openvpn
|
||||||
image: openvpn:local
|
image: openvpn:local
|
||||||
command: /etc/openvpn/setup/configure.sh
|
command: /etc/openvpn/setup/configure.sh
|
||||||
environment:
|
|
||||||
OVPN_SERVER_NET: "192.168.100.0"
|
|
||||||
OVPN_SERVER_MASK: "255.255.255.0"
|
|
||||||
OVPN_PASSWD_AUTH: "true"
|
|
||||||
cap_add:
|
cap_add:
|
||||||
- NET_ADMIN
|
- NET_ADMIN
|
||||||
ports:
|
ports:
|
||||||
- 7777:1194 # for openvpn
|
- 7777:1194 # for openvpn
|
||||||
- 8080:8080 # for ovpn-admin because of network_mode
|
- 8080:8080 # for openvpn-admin because of network_mode
|
||||||
volumes:
|
volumes:
|
||||||
- ./easyrsa_master:/etc/openvpn/easyrsa
|
- ./easyrsa_master:/etc/openvpn/easyrsa
|
||||||
- ./ccd_master:/etc/openvpn/ccd
|
- ./ccd_master:/etc/openvpn/ccd
|
||||||
ovpn-admin:
|
openvpn-admin:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile.ovpn-admin
|
image: openvpn-admin:local
|
||||||
image: ovpn-admin:local
|
command: /app/openvpn-admin --debug --ovpn.network="172.16.100.0/22" --master.sync-token="TOKEN"
|
||||||
command: /app/ovpn-admin
|
|
||||||
environment:
|
|
||||||
OVPN_DEBUG: "true"
|
|
||||||
OVPN_VERBOSE: "true"
|
|
||||||
OVPN_NETWORK: "192.168.100.0/24"
|
|
||||||
OVPN_CCD: "true"
|
|
||||||
OVPN_CCD_PATH: "/mnt/ccd"
|
|
||||||
EASYRSA_PATH: "/mnt/easyrsa"
|
|
||||||
OVPN_SERVER: "127.0.0.1:7777:tcp"
|
|
||||||
OVPN_INDEX_PATH: "/mnt/easyrsa/pki/index.txt"
|
|
||||||
OVPN_AUTH: "true"
|
|
||||||
OVPN_AUTH_DB_PATH: "/mnt/easyrsa/pki/users.db"
|
|
||||||
LOG_LEVEL: "debug"
|
|
||||||
network_mode: service:openvpn
|
network_mode: service:openvpn
|
||||||
volumes:
|
volumes:
|
||||||
- ./easyrsa_master:/mnt/easyrsa
|
- ./easyrsa_master:/mnt/easyrsa
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
image="node:16.13.0-alpine3.12"
|
image="node:14.2-alpine3.11"
|
||||||
uid="$(id -u $USER)"
|
uid="$(id -u $USER)"
|
||||||
|
|
||||||
docker run -u $uid -w /app -v $(pwd):/app $image npm i && \
|
docker run -u $uid -w /app -v $(pwd):/app $image npm i && \
|
||||||
|
|||||||
14538
frontend/package-lock.json
generated
14538
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "ovpn-admin",
|
"name": "openvpn-admin",
|
||||||
"description": "Vue.js admin ui for openvpn and easyrsa",
|
"description": "Vue.js admin ui for openvpn and easyrsa",
|
||||||
"version": "1.0.1a",
|
"version": "1.0.1a",
|
||||||
"author": "vitaliy.snurnitsin@gmail.com",
|
"author": "vitaliy.snurnitsin@gmail.com",
|
||||||
@ -7,18 +7,14 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "cross-env NODE_ENV=development webpack-dev-server --hot",
|
"dev": "cross-env NODE_ENV=development webpack-dev-server --hot",
|
||||||
"build": "cross-env NODE_ENV=production webpack --progress"
|
"build": "cross-env NODE_ENV=production webpack --progress --hide-modules"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.12.0",
|
"axios": "^0.19.2",
|
||||||
"bootstrap-vue": "^2.22.0",
|
"vue": "^2.6.12",
|
||||||
"normalize.css": "^8.0.1",
|
"vue-clipboard2": "^0.2.1",
|
||||||
"vue": "^2.6.14",
|
|
||||||
"vue-clipboard2": "^0.3.3",
|
|
||||||
"vue-cookies": "^1.7.4",
|
"vue-cookies": "^1.7.4",
|
||||||
"vue-good-table": "^2.21.11",
|
"vue-good-table": "^2.21.1"
|
||||||
"vue-notification": "^1.3.20",
|
|
||||||
"vue-style-loader": "^4.1.3"
|
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"> 1%",
|
"> 1%",
|
||||||
@ -26,23 +22,23 @@
|
|||||||
"not ie <= 8"
|
"not ie <= 8"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.16.5",
|
"@babel/core": "^7.8.6",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.16.7",
|
"@babel/plugin-proposal-class-properties": "^7.0.0",
|
||||||
"@babel/plugin-proposal-json-strings": "^7.16.7",
|
"@babel/plugin-proposal-json-strings": "^7.0.0",
|
||||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
|
||||||
"@babel/plugin-syntax-import-meta": "^7.10.4",
|
"@babel/plugin-syntax-import-meta": "^7.0.0",
|
||||||
"@babel/preset-env": "^7.16.5",
|
"@babel/preset-env": "^7.0.0",
|
||||||
"babel-loader": "^8.2.3",
|
"babel-loader": "^8.0.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.0",
|
||||||
"css-loader": "^6.5.1",
|
"css-loader": "^3.4.2",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^5.1.0",
|
||||||
"node-sass": "^9.0.0",
|
"node-sass": "^4.13.1",
|
||||||
"sass-loader": "^16.0.5",
|
"sass-loader": "^8.0.2",
|
||||||
"terser-webpack-plugin": "^5.3.0",
|
"terser-webpack-plugin": "^2.3.5",
|
||||||
"vue-loader": "^17.0.0",
|
"vue-loader": "^15.9.0",
|
||||||
"vue-template-compiler": "^2.6.14",
|
"vue-template-compiler": "^2.6.11",
|
||||||
"webpack": "^5.98.0",
|
"webpack": "^4.42.0",
|
||||||
"webpack-cli": "^4.9.1",
|
"webpack-cli": "^3.3.11",
|
||||||
"webpack-dev-server": "^5.2.1"
|
"webpack-dev-server": "^3.10.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,16 +1,14 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import VueCookies from 'vue-cookies'
|
import VueCookies from 'vue-cookies'
|
||||||
import BootstrapVue from 'bootstrap-vue'
|
|
||||||
import VueClipboard from 'vue-clipboard2'
|
import VueClipboard from 'vue-clipboard2'
|
||||||
import Notifications from 'vue-notification'
|
|
||||||
import VueGoodTablePlugin from 'vue-good-table'
|
import VueGoodTablePlugin from 'vue-good-table'
|
||||||
|
|
||||||
Vue.use(VueCookies)
|
import 'vue-good-table/dist/vue-good-table.css'
|
||||||
|
|
||||||
Vue.use(VueClipboard)
|
Vue.use(VueClipboard)
|
||||||
Vue.use(BootstrapVue)
|
|
||||||
Vue.use(Notifications)
|
|
||||||
Vue.use(VueGoodTablePlugin)
|
Vue.use(VueGoodTablePlugin)
|
||||||
|
Vue.use(VueCookies)
|
||||||
|
|
||||||
var axios_cfg = function(url, data='', type='form') {
|
var axios_cfg = function(url, data='', type='form') {
|
||||||
if (data == '') {
|
if (data == '') {
|
||||||
@ -56,11 +54,6 @@ new Vue({
|
|||||||
field: 'AccountStatus',
|
field: 'AccountStatus',
|
||||||
filterable: true,
|
filterable: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: 'Active Connections',
|
|
||||||
field: 'Connections',
|
|
||||||
filterable: true,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: 'Expiration Date',
|
label: 'Expiration Date',
|
||||||
field: 'ExpirationDate',
|
field: 'ExpirationDate',
|
||||||
@ -91,93 +84,41 @@ new Vue({
|
|||||||
],
|
],
|
||||||
rows: [],
|
rows: [],
|
||||||
actions: [
|
actions: [
|
||||||
{
|
|
||||||
name: 'u-change-password',
|
|
||||||
label: 'Change password',
|
|
||||||
class: 'btn-warning',
|
|
||||||
showWhenStatus: 'Active',
|
|
||||||
showForServerRole: ['master'],
|
|
||||||
showForModule: ['passwdAuth'],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: 'u-revoke',
|
name: 'u-revoke',
|
||||||
label: 'Revoke',
|
label: 'Revoke',
|
||||||
class: 'btn-warning',
|
|
||||||
showWhenStatus: 'Active',
|
showWhenStatus: 'Active',
|
||||||
showForServerRole: ['master'],
|
showForServerRole: ['master']
|
||||||
showForModule: ["core"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'u-delete',
|
|
||||||
label: 'Delete',
|
|
||||||
class: 'btn-danger',
|
|
||||||
showWhenStatus: 'Revoked',
|
|
||||||
showForServerRole: ['master'],
|
|
||||||
showForModule: ["core"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'u-delete',
|
|
||||||
label: 'Delete',
|
|
||||||
class: 'btn-danger',
|
|
||||||
showWhenStatus: 'Expired',
|
|
||||||
showForServerRole: ['master'],
|
|
||||||
showForModule: ["core"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'u-rotate',
|
|
||||||
label: 'Rotate',
|
|
||||||
class: 'btn-warning',
|
|
||||||
showWhenStatus: 'Revoked',
|
|
||||||
showForServerRole: ['master'],
|
|
||||||
showForModule: ["core"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'u-rotate',
|
|
||||||
label: 'Rotate',
|
|
||||||
class: 'btn-warning',
|
|
||||||
showWhenStatus: 'Expired',
|
|
||||||
showForServerRole: ['master'],
|
|
||||||
showForModule: ["core"],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'u-unrevoke',
|
name: 'u-unrevoke',
|
||||||
label: 'Unrevoke',
|
label: 'Unrevoke',
|
||||||
class: 'btn-primary',
|
|
||||||
showWhenStatus: 'Revoked',
|
showWhenStatus: 'Revoked',
|
||||||
showForServerRole: ['master'],
|
showForServerRole: ['master']
|
||||||
showForModule: ["core"],
|
},
|
||||||
|
{
|
||||||
|
name: 'u-show-config',
|
||||||
|
label: 'Show config',
|
||||||
|
showWhenStatus: 'Active',
|
||||||
|
showForServerRole: ['master', 'slave']
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// name: 'u-show-config',
|
|
||||||
// label: 'Show config',
|
|
||||||
// class: 'btn-primary',
|
|
||||||
// showWhenStatus: 'Active',
|
|
||||||
// showForServerRole: ['master', 'slave'],
|
|
||||||
// showForModule: ["core"],
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
name: 'u-download-config',
|
name: 'u-download-config',
|
||||||
label: 'Download config',
|
label: 'Download config',
|
||||||
class: 'btn-info',
|
|
||||||
showWhenStatus: 'Active',
|
showWhenStatus: 'Active',
|
||||||
showForServerRole: ['master', 'slave'],
|
showForServerRole: ['master', 'slave']
|
||||||
showForModule: ["core"],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'u-edit-ccd',
|
name: 'u-edit-ccd',
|
||||||
label: 'Edit routes',
|
label: 'Edit routes',
|
||||||
class: 'btn-primary',
|
|
||||||
showWhenStatus: 'Active',
|
showWhenStatus: 'Active',
|
||||||
showForServerRole: ['master'],
|
showForServerRole: ['master']
|
||||||
showForModule: ["ccd"],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'u-edit-ccd',
|
name: 'u-edit-ccd',
|
||||||
label: 'Show routes',
|
label: 'Show routes',
|
||||||
class: 'btn-primary',
|
|
||||||
showWhenStatus: 'Active',
|
showWhenStatus: 'Active',
|
||||||
showForServerRole: ['slave'],
|
showForServerRole: ['slave']
|
||||||
showForModule: ["ccd"],
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
filters: {
|
filters: {
|
||||||
@ -185,22 +126,13 @@ new Vue({
|
|||||||
},
|
},
|
||||||
serverRole: "master",
|
serverRole: "master",
|
||||||
lastSync: "unknown",
|
lastSync: "unknown",
|
||||||
modulesEnabled: [],
|
|
||||||
u: {
|
u: {
|
||||||
newUserName: '',
|
newUserName: '',
|
||||||
newUserPassword: '',
|
// newUserPassword: 'nopass',
|
||||||
newUserCreateError: '',
|
newUserCreateError: '',
|
||||||
newPassword: '',
|
|
||||||
passwordChangeStatus: '',
|
|
||||||
passwordChangeMessage: '',
|
|
||||||
rotateUserMessage: '',
|
|
||||||
deleteUserMessage: '',
|
|
||||||
modalNewUserVisible: false,
|
modalNewUserVisible: false,
|
||||||
modalShowConfigVisible: false,
|
modalShowConfigVisible: false,
|
||||||
modalShowCcdVisible: false,
|
modalShowCcdVisible: false,
|
||||||
modalChangePasswordVisible: false,
|
|
||||||
modalRotateUserVisible: false,
|
|
||||||
modalDeleteUserVisible: false,
|
|
||||||
openvpnConfig: '',
|
openvpnConfig: '',
|
||||||
ccd: {
|
ccd: {
|
||||||
Name: '',
|
Name: '',
|
||||||
@ -216,7 +148,7 @@ new Vue({
|
|||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
this.getUserData();
|
this.getUserData();
|
||||||
this.getServerSetting();
|
this.getServerRole();
|
||||||
this.filters.hideRevoked = this.$cookies.isKey('hideRevoked') ? (this.$cookies.get('hideRevoked') == "true") : false
|
this.filters.hideRevoked = this.$cookies.isKey('hideRevoked') ? (this.$cookies.get('hideRevoked') == "true") : false
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@ -228,7 +160,6 @@ new Vue({
|
|||||||
axios.request(axios_cfg('api/user/revoke', data, 'form'))
|
axios.request(axios_cfg('api/user/revoke', data, 'form'))
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
_this.getUserData();
|
_this.getUserData();
|
||||||
_this.$notify({title: 'User ' + _this.username + ' revoked!', type: 'warn'})
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
_this.$root.$on('u-unrevoke', function () {
|
_this.$root.$on('u-unrevoke', function () {
|
||||||
@ -237,19 +168,8 @@ new Vue({
|
|||||||
axios.request(axios_cfg('api/user/unrevoke', data, 'form'))
|
axios.request(axios_cfg('api/user/unrevoke', data, 'form'))
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
_this.getUserData();
|
_this.getUserData();
|
||||||
_this.$notify({title: 'User ' + _this.username + ' unrevoked!', type: 'success'})
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
_this.$root.$on('u-rotate', function () {
|
|
||||||
_this.u.modalRotateUserVisible = true;
|
|
||||||
var data = new URLSearchParams();
|
|
||||||
data.append('username', _this.username);
|
|
||||||
})
|
|
||||||
_this.$root.$on('u-delete', function () {
|
|
||||||
_this.u.modalDeleteUserVisible = true;
|
|
||||||
var data = new URLSearchParams();
|
|
||||||
data.append('username', _this.username);
|
|
||||||
})
|
|
||||||
_this.$root.$on('u-show-config', function () {
|
_this.$root.$on('u-show-config', function () {
|
||||||
_this.u.modalShowConfigVisible = true;
|
_this.u.modalShowConfigVisible = true;
|
||||||
var data = new URLSearchParams();
|
var data = new URLSearchParams();
|
||||||
@ -287,31 +207,17 @@ new Vue({
|
|||||||
data.append('username', _this.username);
|
data.append('username', _this.username);
|
||||||
axios.request(axios_cfg('api/user/disconnect', data, 'form'))
|
axios.request(axios_cfg('api/user/disconnect', data, 'form'))
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
console.log(response.data);
|
_this.u.ccd = response.data;
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
_this.$root.$on('u-change-password', function () {
|
|
||||||
_this.u.modalChangePasswordVisible = true;
|
|
||||||
var data = new URLSearchParams();
|
|
||||||
data.append('username', _this.username);
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
customAddressDynamic: function () {
|
customAddressDisabled: function () {
|
||||||
return this.u.ccd.ClientAddress == "dynamic"
|
return this.serverRole == "master" ? this.u.ccd.ClientAddress == "dynamic" : true
|
||||||
},
|
},
|
||||||
ccdApplyStatusCssClass: function () {
|
ccdApplyStatusCssClass: function () {
|
||||||
return this.u.ccdApplyStatus == 200 ? "alert-success" : "alert-danger"
|
return this.u.ccdApplyStatus == 200 ? "alert-success" : "alert-danger"
|
||||||
},
|
},
|
||||||
passwordChangeStatusCssClass: function () {
|
|
||||||
return this.u.passwordChangeStatus == 200 ? "alert-success" : "alert-danger"
|
|
||||||
},
|
|
||||||
userRotateStatusCssClass: function () {
|
|
||||||
return this.u.roatateUserStatus == 200 ? "alert-success" : "alert-danger"
|
|
||||||
},
|
|
||||||
deleteUserStatusCssClass: function () {
|
|
||||||
return this.u.deleteUserStatus == 200 ? "alert-success" : "alert-danger"
|
|
||||||
},
|
|
||||||
modalNewUserDisplay: function () {
|
modalNewUserDisplay: function () {
|
||||||
return this.u.modalNewUserVisible ? {display: 'flex'} : {}
|
return this.u.modalNewUserVisible ? {display: 'flex'} : {}
|
||||||
},
|
},
|
||||||
@ -321,15 +227,6 @@ new Vue({
|
|||||||
modalShowCcdDisplay: function () {
|
modalShowCcdDisplay: function () {
|
||||||
return this.u.modalShowCcdVisible ? {display: 'flex'} : {}
|
return this.u.modalShowCcdVisible ? {display: 'flex'} : {}
|
||||||
},
|
},
|
||||||
modalChangePasswordDisplay: function () {
|
|
||||||
return this.u.modalChangePasswordVisible ? {display: 'flex'} : {}
|
|
||||||
},
|
|
||||||
modalRotateUserDisplay: function () {
|
|
||||||
return this.u.modalRotateUserVisible ? {display: 'flex'} : {}
|
|
||||||
},
|
|
||||||
modalDeleteUserDisplay: function () {
|
|
||||||
return this.u.modalDeleteUserVisible ? {display: 'flex'} : {}
|
|
||||||
},
|
|
||||||
revokeFilterText: function() {
|
revokeFilterText: function() {
|
||||||
return this.filters.hideRevoked ? "Show revoked" : "Hide revoked"
|
return this.filters.hideRevoked ? "Show revoked" : "Hide revoked"
|
||||||
},
|
},
|
||||||
@ -346,16 +243,7 @@ new Vue({
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
rowStyleClassFn: function(row) {
|
rowStyleClassFn: function(row) {
|
||||||
if (row.ConnectionStatus == 'Connected') {
|
return row.ConnectionStatus == 'Connected' ? 'connected-user' : ''
|
||||||
return 'connected-user'
|
|
||||||
}
|
|
||||||
if (row.AccountStatus == 'Revoked') {
|
|
||||||
return 'revoked-user'
|
|
||||||
}
|
|
||||||
if (row.AccountStatus == 'Expired') {
|
|
||||||
return 'expired-user'
|
|
||||||
}
|
|
||||||
return ''
|
|
||||||
},
|
},
|
||||||
rowActionFn: function(e) {
|
rowActionFn: function(e) {
|
||||||
this.username = e.target.dataset.username;
|
this.username = e.target.dataset.username;
|
||||||
@ -365,26 +253,22 @@ new Vue({
|
|||||||
var _this = this;
|
var _this = this;
|
||||||
axios.request(axios_cfg('api/users/list'))
|
axios.request(axios_cfg('api/users/list'))
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
_this.rows = Array.isArray(response.data) ? response.data : [];
|
_this.rows = response.data;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
getServerRole: function() {
|
||||||
getServerSetting: function() {
|
|
||||||
var _this = this;
|
var _this = this;
|
||||||
axios.request(axios_cfg('api/server/settings'))
|
axios.request(axios_cfg('api/server/role'))
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
_this.serverRole = response.data.serverRole;
|
_this.serverRole = response.data.serverRole;
|
||||||
_this.modulesEnabled = response.data.modules;
|
|
||||||
|
|
||||||
if (_this.serverRole == "slave") {
|
if (_this.serverRole == "slave") {
|
||||||
axios.request(axios_cfg('api/sync/last/successful'))
|
axios.request(axios_cfg('api/sync/last'))
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
_this.lastSync = response.data;
|
_this.lastSync = response.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
createUser: function() {
|
createUser: function() {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
|
|
||||||
@ -392,25 +276,19 @@ new Vue({
|
|||||||
|
|
||||||
var data = new URLSearchParams();
|
var data = new URLSearchParams();
|
||||||
data.append('username', _this.u.newUserName);
|
data.append('username', _this.u.newUserName);
|
||||||
data.append('password', _this.u.newUserPassword);
|
// data.append('password', this.u.newUserPassword);
|
||||||
|
|
||||||
_this.username = _this.u.newUserName;
|
|
||||||
|
|
||||||
axios.request(axios_cfg('api/user/create', data, 'form'))
|
axios.request(axios_cfg('api/user/create', data, 'form'))
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
_this.$notify({title: 'New user ' + _this.username + ' created', type: 'success'})
|
_this.getUserData();
|
||||||
_this.u.modalNewUserVisible = false;
|
_this.u.modalNewUserVisible = false;
|
||||||
_this.u.newUserName = '';
|
_this.u.newUserName = '';
|
||||||
_this.u.newUserPassword = '';
|
// _this.u.newUserPassword = 'nopass';
|
||||||
_this.getUserData();
|
|
||||||
})
|
})
|
||||||
.catch(function(error) {
|
.catch(function(error) {
|
||||||
_this.u.newUserCreateError = error.response.data;
|
_this.u.newUserCreateError = error.response.data;
|
||||||
_this.$notify({title: 'New user ' + _this.username + ' creation failed.', type: 'error'})
|
|
||||||
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
ccdApply: function() {
|
ccdApply: function() {
|
||||||
var _this = this;
|
var _this = this;
|
||||||
|
|
||||||
@ -421,84 +299,11 @@ new Vue({
|
|||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
_this.u.ccdApplyStatus = 200;
|
_this.u.ccdApplyStatus = 200;
|
||||||
_this.u.ccdApplyStatusMessage = response.data;
|
_this.u.ccdApplyStatusMessage = response.data;
|
||||||
_this.$notify({title: 'Ccd for user ' + _this.username + ' applied', type: 'success'})
|
|
||||||
})
|
})
|
||||||
.catch(function(error) {
|
.catch(function(error) {
|
||||||
_this.u.ccdApplyStatus = error.response.status;
|
_this.u.ccdApplyStatus = error.response.status;
|
||||||
_this.u.ccdApplyStatusMessage = error.response.data;
|
_this.u.ccdApplyStatusMessage = error.response.data;
|
||||||
_this.$notify({title: 'Ccd for user ' + _this.username + ' apply failed ', type: 'error'})
|
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
|
||||||
changeUserPassword: function(user) {
|
|
||||||
var _this = this;
|
|
||||||
|
|
||||||
_this.u.passwordChangeMessage = "";
|
|
||||||
|
|
||||||
var data = new URLSearchParams();
|
|
||||||
data.append('username', user);
|
|
||||||
data.append('password', _this.u.newPassword);
|
|
||||||
|
|
||||||
axios.request(axios_cfg('api/user/change-password', data, 'form'))
|
|
||||||
.then(function(response) {
|
|
||||||
_this.u.passwordChangeStatus = 200;
|
|
||||||
_this.u.newPassword = '';
|
|
||||||
_this.getUserData();
|
|
||||||
_this.u.modalChangePasswordVisible = false;
|
|
||||||
_this.$notify({title: 'Password for user ' + _this.username + ' changed!', type: 'success'})
|
|
||||||
})
|
|
||||||
.catch(function(error) {
|
|
||||||
_this.u.passwordChangeStatus = error.response.status;
|
|
||||||
_this.u.passwordChangeMessage = error.response.data.message;
|
|
||||||
_this.$notify({title: 'Changing password for user ' + _this.username + ' failed!', type: 'error'})
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
rotateUser: function(user) {
|
|
||||||
var _this = this;
|
|
||||||
|
|
||||||
_this.u.rotateUserMessage = "";
|
|
||||||
|
|
||||||
var data = new URLSearchParams();
|
|
||||||
data.append('username', user);
|
|
||||||
data.append('password', _this.u.newPassword);
|
|
||||||
|
|
||||||
axios.request(axios_cfg('api/user/rotate', data, 'form'))
|
|
||||||
.then(function(response) {
|
|
||||||
_this.u.roatateUserStatus = 200;
|
|
||||||
_this.u.newPassword = '';
|
|
||||||
_this.getUserData();
|
|
||||||
_this.u.modalRotateUserVisible = false;
|
|
||||||
_this.$notify({title: 'Certificates for user ' + _this.username + ' rotated!', type: 'success'})
|
|
||||||
})
|
|
||||||
.catch(function(error) {
|
|
||||||
_this.u.roatateUserStatus = error.response.status;
|
|
||||||
_this.u.rotateUserMessage = error.response.data.message;
|
|
||||||
_this.$notify({title: 'Rotate certificates for user ' + _this.username + ' failed!', type: 'error'})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
deleteUser: function(user) {
|
|
||||||
var _this = this;
|
|
||||||
|
|
||||||
_this.u.deleteUserMessage = "";
|
|
||||||
|
|
||||||
var data = new URLSearchParams();
|
|
||||||
data.append('username', user);
|
|
||||||
|
|
||||||
axios.request(axios_cfg('api/user/delete', data, 'form'))
|
|
||||||
.then(function(response) {
|
|
||||||
_this.u.deleteUserStatus = 200;
|
|
||||||
_this.u.newPassword = '';
|
|
||||||
_this.getUserData();
|
|
||||||
_this.u.modalDeleteUserVisible = false;
|
|
||||||
_this.$notify({title: 'User ' + _this.username + ' deleted!', type: 'success'})
|
|
||||||
})
|
|
||||||
.catch(function(error) {
|
|
||||||
_this.u.deleteUserStatus = error.response.status;
|
|
||||||
_this.u.deleteUserMessage = error.response.data.message;
|
|
||||||
_this.$notify({title: 'Deleting user ' + _this.username + ' failed!', type: 'error'})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
import 'normalize.css';
|
|
||||||
import 'vue-good-table/dist/vue-good-table.css'
|
|
||||||
import 'bootstrap/dist/css/bootstrap.css'
|
|
||||||
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
|
||||||
import './style.css'
|
|
||||||
7
frontend/static/css/bootstrap.min.css
vendored
Normal file
7
frontend/static/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
frontend/static/css/bootstrap.min.css.map
Normal file
1
frontend/static/css/bootstrap.min.css.map
Normal file
File diff suppressed because one or more lines are too long
7
frontend/static/css/bootstrap.min.css_
Normal file
7
frontend/static/css/bootstrap.min.css_
Normal file
File diff suppressed because one or more lines are too long
461
frontend/static/css/normalize.css
vendored
Normal file
461
frontend/static/css/normalize.css
vendored
Normal file
@ -0,0 +1,461 @@
|
|||||||
|
/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Change the default font family in all browsers (opinionated).
|
||||||
|
* 2. Correct the line height in all browsers.
|
||||||
|
* 3. Prevent adjustments of font size after orientation changes in
|
||||||
|
* IE on Windows Phone and in iOS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Document
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-family: sans-serif; /* 1 */
|
||||||
|
line-height: 1.15; /* 2 */
|
||||||
|
-ms-text-size-adjust: 100%; /* 3 */
|
||||||
|
-webkit-text-size-adjust: 100%; /* 3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sections
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the margin in all browsers (opinionated).
|
||||||
|
*/
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 9-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
article,
|
||||||
|
aside,
|
||||||
|
footer,
|
||||||
|
header,
|
||||||
|
nav,
|
||||||
|
section {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct the font size and margin on `h1` elements within `section` and
|
||||||
|
* `article` contexts in Chrome, Firefox, and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 2em;
|
||||||
|
margin: 0.67em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grouping content
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 9-.
|
||||||
|
* 1. Add the correct display in IE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
figcaption,
|
||||||
|
figure,
|
||||||
|
main { /* 1 */
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct margin in IE 8.
|
||||||
|
*/
|
||||||
|
|
||||||
|
figure {
|
||||||
|
margin: 1em 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Add the correct box sizing in Firefox.
|
||||||
|
* 2. Show the overflow in Edge and IE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
hr {
|
||||||
|
box-sizing: content-box; /* 1 */
|
||||||
|
height: 0; /* 1 */
|
||||||
|
overflow: visible; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||||
|
* 2. Correct the odd `em` font sizing in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pre {
|
||||||
|
font-family: monospace, monospace; /* 1 */
|
||||||
|
font-size: 1em; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text-level semantics
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Remove the gray background on active links in IE 10.
|
||||||
|
* 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
|
||||||
|
*/
|
||||||
|
|
||||||
|
a {
|
||||||
|
background-color: transparent; /* 1 */
|
||||||
|
-webkit-text-decoration-skip: objects; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the outline on focused links when they are also active or hovered
|
||||||
|
* in all browsers (opinionated).
|
||||||
|
*/
|
||||||
|
|
||||||
|
a:active,
|
||||||
|
a:hover {
|
||||||
|
outline-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Remove the bottom border in Firefox 39-.
|
||||||
|
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abbr[title] {
|
||||||
|
border-bottom: none; /* 1 */
|
||||||
|
text-decoration: underline; /* 2 */
|
||||||
|
text-decoration: underline dotted; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent the duplicate application of `bolder` by the next rule in Safari 6.
|
||||||
|
*/
|
||||||
|
|
||||||
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct font weight in Chrome, Edge, and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
b,
|
||||||
|
strong {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the inheritance and scaling of font size in all browsers.
|
||||||
|
* 2. Correct the odd `em` font sizing in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
code,
|
||||||
|
kbd,
|
||||||
|
samp {
|
||||||
|
font-family: monospace, monospace; /* 1 */
|
||||||
|
font-size: 1em; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct font style in Android 4.3-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dfn {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct background and color in IE 9-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mark {
|
||||||
|
background-color: #ff0;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct font size in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
small {
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent `sub` and `sup` elements from affecting the line height in
|
||||||
|
* all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sub,
|
||||||
|
sup {
|
||||||
|
font-size: 75%;
|
||||||
|
line-height: 0;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub {
|
||||||
|
bottom: -0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
top: -0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Embedded content
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 9-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
audio,
|
||||||
|
video {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in iOS 4-7.
|
||||||
|
*/
|
||||||
|
|
||||||
|
audio:not([controls]) {
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the border on images inside links in IE 10-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
img {
|
||||||
|
border-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide the overflow in IE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
svg:not(:root) {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Forms
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Change the font styles in all browsers (opinionated).
|
||||||
|
* 2. Remove the margin in Firefox and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
input,
|
||||||
|
optgroup,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
font-family: sans-serif; /* 1 */
|
||||||
|
font-size: 100%; /* 1 */
|
||||||
|
line-height: 1.15; /* 1 */
|
||||||
|
margin: 0; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the overflow in IE.
|
||||||
|
* 1. Show the overflow in Edge.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
input { /* 1 */
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the inheritance of text transform in Edge, Firefox, and IE.
|
||||||
|
* 1. Remove the inheritance of text transform in Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
select { /* 1 */
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
|
||||||
|
* controls in Android 4.
|
||||||
|
* 2. Correct the inability to style clickable types in iOS and Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button,
|
||||||
|
html [type="button"], /* 1 */
|
||||||
|
[type="reset"],
|
||||||
|
[type="submit"] {
|
||||||
|
-webkit-appearance: button; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the inner border and padding in Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button::-moz-focus-inner,
|
||||||
|
[type="button"]::-moz-focus-inner,
|
||||||
|
[type="reset"]::-moz-focus-inner,
|
||||||
|
[type="submit"]::-moz-focus-inner {
|
||||||
|
border-style: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore the focus styles unset by the previous rule.
|
||||||
|
*/
|
||||||
|
|
||||||
|
button:-moz-focusring,
|
||||||
|
[type="button"]:-moz-focusring,
|
||||||
|
[type="reset"]:-moz-focusring,
|
||||||
|
[type="submit"]:-moz-focusring {
|
||||||
|
outline: 1px dotted ButtonText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the border, margin, and padding in all browsers (opinionated).
|
||||||
|
*/
|
||||||
|
|
||||||
|
fieldset {
|
||||||
|
border: 1px solid #c0c0c0;
|
||||||
|
margin: 0 2px;
|
||||||
|
padding: 0.35em 0.625em 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the text wrapping in Edge and IE.
|
||||||
|
* 2. Correct the color inheritance from `fieldset` elements in IE.
|
||||||
|
* 3. Remove the padding so developers are not caught out when they zero out
|
||||||
|
* `fieldset` elements in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
legend {
|
||||||
|
box-sizing: border-box; /* 1 */
|
||||||
|
color: inherit; /* 2 */
|
||||||
|
display: table; /* 1 */
|
||||||
|
max-width: 100%; /* 1 */
|
||||||
|
padding: 0; /* 3 */
|
||||||
|
white-space: normal; /* 1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Add the correct display in IE 9-.
|
||||||
|
* 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
|
||||||
|
*/
|
||||||
|
|
||||||
|
progress {
|
||||||
|
display: inline-block; /* 1 */
|
||||||
|
vertical-align: baseline; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the default vertical scrollbar in IE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Add the correct box sizing in IE 10-.
|
||||||
|
* 2. Remove the padding in IE 10-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[type="checkbox"],
|
||||||
|
[type="radio"] {
|
||||||
|
box-sizing: border-box; /* 1 */
|
||||||
|
padding: 0; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Correct the cursor style of increment and decrement buttons in Chrome.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[type="number"]::-webkit-inner-spin-button,
|
||||||
|
[type="number"]::-webkit-outer-spin-button {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the odd appearance in Chrome and Safari.
|
||||||
|
* 2. Correct the outline style in Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[type="search"] {
|
||||||
|
-webkit-appearance: textfield; /* 1 */
|
||||||
|
outline-offset: -2px; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[type="search"]::-webkit-search-cancel-button,
|
||||||
|
[type="search"]::-webkit-search-decoration {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1. Correct the inability to style clickable types in iOS and Safari.
|
||||||
|
* 2. Change font properties to `inherit` in Safari.
|
||||||
|
*/
|
||||||
|
|
||||||
|
::-webkit-file-upload-button {
|
||||||
|
-webkit-appearance: button; /* 1 */
|
||||||
|
font: inherit; /* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Interactive
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the correct display in IE 9-.
|
||||||
|
* 1. Add the correct display in Edge, IE, and Firefox.
|
||||||
|
*/
|
||||||
|
|
||||||
|
details, /* 1 */
|
||||||
|
menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the correct display in all browsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
summary {
|
||||||
|
display: list-item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scripting
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 9-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hidden
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the correct display in IE 10-.
|
||||||
|
*/
|
||||||
|
|
||||||
|
[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
@ -48,14 +48,6 @@ body {
|
|||||||
background-color: rgba(162, 245, 169, 0.5);
|
background-color: rgba(162, 245, 169, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.revoked-user {
|
|
||||||
background-color: rgba(198, 186, 186, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.expired-user {
|
|
||||||
background-color: rgba(255, 220, 127, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.new-user-btn {
|
.new-user-btn {
|
||||||
margin-right: 2rem;
|
margin-right: 2rem;
|
||||||
}
|
}
|
||||||
@ -66,7 +58,3 @@ body {
|
|||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ccd-routes {
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -2,10 +2,12 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>ovpn-admin</title>
|
<title>openvpn-admin</title>
|
||||||
|
<link rel="stylesheet" href="css/normalize.css">
|
||||||
|
<link rel="stylesheet" href="css/bootstrap.min.css">
|
||||||
|
<link rel="stylesheet" href="css/style.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script src="dist/style.min.js"></script>
|
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<vue-good-table
|
<vue-good-table
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
@ -14,7 +16,7 @@
|
|||||||
:row-style-class="rowStyleClassFn"
|
:row-style-class="rowStyleClassFn"
|
||||||
:search-options="{ enabled: true}" >
|
:search-options="{ enabled: true}" >
|
||||||
<div slot="table-actions">
|
<div slot="table-actions">
|
||||||
<button type="button" class="btn btn-sm btn-success el-square" v-show="serverRole == 'master'" v-on:click.stop="u.modalNewUserVisible=true">Add user</button>
|
<button type="button" class="btn btn-sm btn-success el-square" v-if="serverRole == 'master'" v-on:click.stop="u.modalNewUserVisible=true">Add user</button>
|
||||||
<b-badget class="btn btn-sm btn-info el-square" v-if="serverRole == 'slave'">Slave - last sync: {{ lastSync }}</b-badget>
|
<b-badget class="btn btn-sm btn-info el-square" v-if="serverRole == 'slave'">Slave - last sync: {{ lastSync }}</b-badget>
|
||||||
<button type="button" class="btn btn-sm btn-secondary el-square" v-on:click.stop="filters.hideRevoked=!filters.hideRevoked;this.$cookies.set('hideRevoked',!(this.$cookies.get('hideRevoked') == 'true'), -1);">{{ revokeFilterText }}</button>
|
<button type="button" class="btn btn-sm btn-secondary el-square" v-on:click.stop="filters.hideRevoked=!filters.hideRevoked;this.$cookies.set('hideRevoked',!(this.$cookies.get('hideRevoked') == 'true'), -1);">{{ revokeFilterText }}</button>
|
||||||
</div>
|
</div>
|
||||||
@ -26,7 +28,7 @@
|
|||||||
<template slot="table-row" slot-scope="props">
|
<template slot="table-row" slot-scope="props">
|
||||||
<span v-if="props.column.field == 'actions'">
|
<span v-if="props.column.field == 'actions'">
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm el-square modal-el-margin"
|
class="btn btn-sm btn-success el-square modal-el-margin"
|
||||||
type="button"
|
type="button"
|
||||||
:title="action.label"
|
:title="action.label"
|
||||||
:data-username="props.row.Identity"
|
:data-username="props.row.Identity"
|
||||||
@ -34,14 +36,17 @@
|
|||||||
:data-text="action.label"
|
:data-text="action.label"
|
||||||
@click.left.stop="rowActionFn"
|
@click.left.stop="rowActionFn"
|
||||||
v-for="action in actions"
|
v-for="action in actions"
|
||||||
v-bind:class="action.class"
|
v-if="action.showWhenStatus == props.row.AccountStatus && action.showForServerRole.includes(serverRole)">
|
||||||
v-if="action.showWhenStatus == props.row.AccountStatus && action.showForServerRole.includes(serverRole) && action.showForModule.some(p=> modulesEnabled.includes(p))">
|
|
||||||
{{ action.label }}
|
{{ action.label }}
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</vue-good-table>
|
</vue-good-table>
|
||||||
|
|
||||||
|
<!-- <div class="d-flex justify-content-md-end">-->
|
||||||
|
<!-- <button type="button" class="btn btn-sm btn-success el-square new-user-btn" v-on:click.stop="u.ctxVisible=false;u.modalNewUserVisible=true">Add user</button>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
|
||||||
<div class="modal-wrapper" v-if="u.modalNewUserVisible" v-bind:style="modalNewUserDisplay">
|
<div class="modal-wrapper" v-if="u.modalNewUserVisible" v-bind:style="modalNewUserDisplay">
|
||||||
<div class="modal-dialog modal-lg">
|
<div class="modal-dialog modal-lg">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
@ -50,7 +55,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<input type="text" class="form-control el-square modal-el-margin" placeholder="Username [_a-zA-Z0-9\.-]" v-model="u.newUserName">
|
<input type="text" class="form-control el-square modal-el-margin" placeholder="Username [_a-zA-Z0-9\.-]" v-model="u.newUserName">
|
||||||
<input type="password" class="form-control el-square modal-el-margin" minlength="6" autocomplete="off" placeholder="Password [_a-zA-Z0-9\.-]" v-model="u.newUserPassword" v-if="modulesEnabled.includes('passwdAuth')">
|
<!-- <input type="password" class="form-control el-square modal-el-margin" minlength="6" autocomplete="off" placeholder="Password [_a-zA-Z0-9\.-]" v-model="u.newUserPassword">-->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-footer justify-content-center" v-if="u.newUserCreateError.length > 0">
|
<div class="modal-footer justify-content-center" v-if="u.newUserCreateError.length > 0">
|
||||||
@ -59,41 +64,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-success el-square modal-el-margin" v-on:click.stop="createUser()">Create</button>
|
<button type="button" class="btn btn-success el-square modal-el-margin" v-on:click.stop="createUser();">Create</button>
|
||||||
<button type="button" class="btn btn-primary el-square d-flex justify-content-sm-end modal-el-margin" v-on:click.stop="u.newUserName='';u.newUserPassword='nopass';u.modalNewUserVisible=false">Close</button>
|
<button type="button" class="btn btn-primary el-square d-flex justify-content-sm-end modal-el-margin" v-on:click.stop="u.newUserName='';u.newUserPassword='nopass';u.modalNewUserVisible=false">Close</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-wrapper" v-if="u.modalChangePasswordVisible" v-bind:style="modalChangePasswordDisplay">
|
|
||||||
<div class="modal-dialog modal-lg">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h4>Change password for: <strong>{{ username }}</strong></h4>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<input type="password" class="form-control el-square modal-el-margin" minlength="6" autocomplete="off" placeholder="Password [_a-zA-Z0-9\.-]" v-model="u.newPassword">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-footer justify-content-center" v-if="u.passwordChangeMessage.length > 0">
|
|
||||||
<div class="alert" v-bind:class="passwordChangeStatusCssClass" role="alert" >
|
|
||||||
{{ u.passwordChangeMessage }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-success el-square modal-el-margin" v-on:click.stop="changeUserPassword(username)">Change password</button>
|
|
||||||
<button type="button" class="btn btn-primary el-square d-flex justify-content-sm-end modal-el-margin" v-on:click.stop="u.newPassword='';u.passwordChangeMessage='';u.modalChangePasswordVisible=false">Close</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-wrapper" v-if="u.modalShowConfigVisible" v-bind:style="modalShowConfigDisplay">
|
<div class="modal-wrapper" v-if="u.modalShowConfigVisible" v-bind:style="modalShowConfigDisplay">
|
||||||
<div class="modal-dialog modal-lg">
|
<div class="modal-dialog modal-lg">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h4>ovpn config for: <strong>{{ username }}</strong></h4>
|
<h4>ovpn config for {{ username }}</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
@ -114,57 +96,42 @@
|
|||||||
<div class="modal-dialog modal-lg modal-dialog-scrollable">
|
<div class="modal-dialog modal-lg modal-dialog-scrollable">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h3 class="static-address-label ">Routes table for: <strong>{{ username }}</strong></h3>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<h5 class="static-address-label ">Static address:</h5>
|
<h4 class="static-address-label ">Client "{{ username }}" static address</h4>
|
||||||
<input id="static-address" type="text" class="form-control" v-model="u.ccd.ClientAddress" placeholder="127.0.0.1">
|
<div class="input-group-prepend">
|
||||||
<div class="input-group-append">
|
<div class="input-group-text">
|
||||||
<button id="static-address-clear" class="btn btn-warning" type="button" v-on:click="u.ccd.ClientAddress = 'dynamic'" v-if="serverRole == 'master'" v-bind:disabled="customAddressDynamic">Clear</button>
|
<input id="enable-static" type="checkbox" onchange="document.getElementById('staticAddress').disabled=!this.checked;" v-if="serverRole == 'master'" v-bind:checked="customAddressDisabled">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<input id="staticAddress" type="text" class="form-control" v-model="u.ccd.ClientAddress" placeholder="127.0.0.1" v-bind:disabled="customAddressDisabled">
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="d-flex ">
|
<div class="d-flex ">
|
||||||
<table class="table table-bordered table-hover ccd-routes" >
|
<table class="table table-bordered table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">Address</th>
|
<th scope="col">Address</th>
|
||||||
<th scope="col">Mask</th>
|
<th scope="col">Mask</th>
|
||||||
<th scope="col">Description</th>
|
<th scope="col">Description</th>
|
||||||
<th scope="col" v-if="serverRole == 'master'">Action</th>
|
<th scope="col">Action</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="(customRoute, index) in u.ccd.CustomRoutes">
|
<tr v-for="(customRoute, index) in u.ccd.CustomRoutes">
|
||||||
|
<td>{{ customRoute.Address }}</td>
|
||||||
|
<td>{{ customRoute.Mask }}</td>
|
||||||
|
<td>{{ customRoute.Description }}</td>
|
||||||
<td>
|
<td>
|
||||||
<div v-if="serverRole == 'slave'">
|
<button type="button" class="btn btn-primary btn-sm el-square modal-el-margin" v-if="serverRole == 'master'" v-on:click.stop="u.ccd.CustomRoutes.splice(index, 1)">Delete</button>
|
||||||
{{ customRoute.Address }}
|
|
||||||
</div>
|
|
||||||
<input v-if="serverRole == 'master'" v-model="customRoute.Address">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div v-if="serverRole == 'slave'">
|
|
||||||
{{ customRoute.Mask }}
|
|
||||||
</div>
|
|
||||||
<input v-if="serverRole == 'master'" v-model="customRoute.Mask">
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div v-if="serverRole == 'slave'">
|
|
||||||
{{ customRoute.Description }}
|
|
||||||
</div>
|
|
||||||
<input v-if="serverRole == 'master'" v-model="customRoute.Description">
|
|
||||||
</td>
|
|
||||||
<td class="text-right" v-if="serverRole == 'master'">
|
|
||||||
<button type="button" class="btn btn-danger btn-sm el-square modal-el-margin" v-if="serverRole == 'master'" v-on:click.stop="u.ccd.CustomRoutes.splice(index, 1)">Delete</button>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-if="serverRole == 'master'">
|
<tr v-if="serverRole == 'master'">
|
||||||
<td><input type="text" v-model="u.newRoute.Address"/></td>
|
<td><input type="text" v-model="u.newRoute.Address"/></td>
|
||||||
<td><input type="text" v-model="u.newRoute.Mask"/></td>
|
<td><input type="text" v-model="u.newRoute.Mask"/></td>
|
||||||
<td><input type="text" v-model="u.newRoute.Description"/></td>
|
<td><input type="text" v-model="u.newRoute.Description"/></td>
|
||||||
<td class="text-right" v-if="serverRole == 'master'">
|
<td>
|
||||||
<button type="button" class="btn btn-success el-square modal-el-margin" v-on:click.stop="u.ccd.CustomRoutes.push(u.newRoute);u.newRoute={};">Add</button>
|
<button type="button" class="btn btn-success el-square modal-el-margin" v-on:click.stop="u.ccd.CustomRoutes.push(u.newRoute);u.newRoute={};">Add</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -185,52 +152,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal-wrapper" v-if="u.modalRotateUserVisible" v-bind:style="modalRotateUserDisplay">
|
|
||||||
<div class="modal-dialog modal-lg">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h4>Confirm rotating certificates for user: <strong>{{ username }}</strong></h4>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body" v-if="modulesEnabled.includes('passwdAuth')">
|
<script src="dist/build.js"></script>
|
||||||
<h4>Enter new password:</h4>
|
|
||||||
<input type="password" class="form-control el-square modal-el-margin" minlength="6" autocomplete="off" placeholder="Password [_a-zA-Z0-9\.-]" v-model="u.newPassword">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-footer justify-content-center" v-if="u.rotateUserMessage.length > 0">
|
|
||||||
<div class="alert" v-bind:class="userRotateStatusCssClass" role="alert" >
|
|
||||||
{{ u.rotateUserMessage }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-danger el-square modal-el-margin" v-on:click.stop="rotateUser(username)">Rotate</button>
|
|
||||||
<button type="button" class="btn btn-primary el-square d-flex justify-content-sm-end modal-el-margin" v-on:click.stop="u.newPassword='';u.rotateUserMessage='';u.modalRotateUserVisible=false">Close</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-wrapper" v-if="u.modalDeleteUserVisible" v-bind:style="modalDeleteUserDisplay">
|
|
||||||
<div class="modal-dialog modal-lg">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h4>Confirm deleting user: <strong>{{ username }}</strong></h4>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal-footer justify-content-center" v-if="u.deleteUserMessage.length > 0">
|
|
||||||
<div class="alert" v-bind:class="deleteUserStatusCssClass" role="alert" >
|
|
||||||
{{ u.deleteUserMessage }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-danger el-square modal-el-margin" v-on:click.stop="deleteUser(username)">Delete</button>
|
|
||||||
<button type="button" class="btn btn-primary el-square d-flex justify-content-sm-end modal-el-margin" v-on:click.stop="u.deleteUserMessage='';u.modalDeleteUserVisible=false">Close</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<notifications position="bottom left" :speed="900" />
|
|
||||||
</div>
|
|
||||||
<script src="dist/bundle.min.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -1,24 +1,14 @@
|
|||||||
const path = require('path');
|
var path = require('path')
|
||||||
//const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
var webpack = require('webpack')
|
||||||
|
const TerserPlugin = require('terser-webpack-plugin');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: 'production',
|
entry: './src/main.js',
|
||||||
entry: {
|
|
||||||
bundle: [
|
|
||||||
'./src/main.js',
|
|
||||||
],
|
|
||||||
style: [
|
|
||||||
'./src/style.js',
|
|
||||||
]
|
|
||||||
},
|
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, './static/dist'),
|
path: path.resolve(__dirname, './static/dist'),
|
||||||
publicPath: '/dist/',
|
publicPath: '/dist/',
|
||||||
filename: '[name].min.js'
|
filename: 'build.js'
|
||||||
},
|
},
|
||||||
plugins: [
|
|
||||||
//new BundleAnalyzerPlugin(),
|
|
||||||
],
|
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
{
|
||||||
@ -29,22 +19,88 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.js$/,
|
test: /\.scss$/,
|
||||||
//exclude: /node_modules\/(?!bootstrap-vue\/src\/)/,
|
use: [
|
||||||
exclude: /node_modules/,
|
'vue-style-loader',
|
||||||
loader: 'babel-loader',
|
'css-loader',
|
||||||
|
'sass-loader'
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.sass$/,
|
||||||
|
use: [
|
||||||
|
'vue-style-loader',
|
||||||
|
'css-loader',
|
||||||
|
'sass-loader?indentedSyntax'
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.vue$/,
|
||||||
|
loader: 'vue-loader',
|
||||||
options: {
|
options: {
|
||||||
presets: ['@babel/preset-env']
|
loaders: {
|
||||||
|
// Since sass-loader (weirdly) has SCSS as its default parse mode, we map
|
||||||
|
// the "scss" and "sass" values for the lang attribute to the right configs here.
|
||||||
|
// other preprocessors should work out of the box, no loader config like this necessary.
|
||||||
|
'scss': [
|
||||||
|
'vue-style-loader',
|
||||||
|
'css-loader',
|
||||||
|
'sass-loader'
|
||||||
|
],
|
||||||
|
'sass': [
|
||||||
|
'vue-style-loader',
|
||||||
|
'css-loader',
|
||||||
|
'sass-loader?indentedSyntax'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
// other vue-loader options go here
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
],
|
{
|
||||||
|
test: /\.js$/,
|
||||||
|
loader: 'babel-loader',
|
||||||
|
exclude: /node_modules/
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(png|jpg|gif|svg)$/,
|
||||||
|
loader: 'file-loader',
|
||||||
|
options: {
|
||||||
|
name: '[name].[ext]?[hash]'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'vue$': 'vue/dist/vue.esm.js',
|
'vue$': 'vue/dist/vue.esm.js'
|
||||||
//'bootstrap-vue$': 'bootstrap-vue/src/index.js'
|
|
||||||
},
|
},
|
||||||
extensions: ['*', '.js', '.vue', '.json']
|
extensions: ['*', '.js', '.vue', '.json']
|
||||||
},
|
},
|
||||||
|
devServer: {
|
||||||
|
historyApiFallback: true,
|
||||||
|
noInfo: true,
|
||||||
|
overlay: true
|
||||||
|
},
|
||||||
|
performance: {
|
||||||
|
hints: false
|
||||||
|
},
|
||||||
|
devtool: '#eval-source-map'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
module.exports.devtool = '#source-map'
|
||||||
|
// http://vue-loader.vuejs.org/en/workflow/production.html
|
||||||
|
module.exports.plugins = (module.exports.plugins || []).concat([
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env': {
|
||||||
|
NODE_ENV: '"production"'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new TerserPlugin({
|
||||||
|
sourceMap: true
|
||||||
|
}),
|
||||||
|
new webpack.LoaderOptionsPlugin({
|
||||||
|
minimize: true
|
||||||
|
})
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
|
||||||
mkdir -p {easyrsa,ccd}
|
mkdir -p easyrsa
|
||||||
|
|
||||||
cd easyrsa
|
cd easyrsa
|
||||||
|
|
||||||
68
go.mod
68
go.mod
@ -1,66 +1,12 @@
|
|||||||
module ovpn-admin
|
module openvpn-web-ui
|
||||||
|
|
||||||
go 1.24.0
|
go 1.14
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/gobuffalo/packr/v2 v2.8.3
|
|
||||||
github.com/google/uuid v1.6.0
|
|
||||||
github.com/prometheus/client_golang v1.23.2
|
|
||||||
github.com/sirupsen/logrus v1.9.4
|
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
|
||||||
k8s.io/api v0.34.3
|
|
||||||
k8s.io/apimachinery v0.34.3
|
|
||||||
k8s.io/client-go v0.34.3
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/Electronn/openvpn_exporter v0.0.0-20181005212047-37f639dc9c7d
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
|
||||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
|
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/prometheus/client_golang v1.8.0
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/prometheus/common v0.15.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
||||||
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
|
|
||||||
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
|
||||||
github.com/go-logr/logr v1.4.2 // indirect
|
|
||||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
|
||||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
|
||||||
github.com/go-openapi/swag v0.23.0 // indirect
|
|
||||||
github.com/gobuffalo/logger v1.0.6 // indirect
|
|
||||||
github.com/gobuffalo/packd v1.0.1 // indirect
|
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
|
||||||
github.com/google/gnostic-models v0.7.0 // indirect
|
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
|
||||||
github.com/karrick/godirwalk v1.16.1 // indirect
|
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
|
||||||
github.com/markbates/errx v1.1.0 // indirect
|
|
||||||
github.com/markbates/oncer v1.0.0 // indirect
|
|
||||||
github.com/markbates/safe v1.0.1 // indirect
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
|
||||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
|
||||||
github.com/prometheus/client_model v0.6.2 // indirect
|
|
||||||
github.com/prometheus/common v0.66.1 // indirect
|
|
||||||
github.com/prometheus/procfs v0.16.1 // indirect
|
|
||||||
github.com/x448/float16 v0.8.4 // indirect
|
|
||||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
|
||||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
|
||||||
golang.org/x/net v0.43.0 // indirect
|
|
||||||
golang.org/x/oauth2 v0.30.0 // indirect
|
|
||||||
golang.org/x/sys v0.35.0 // indirect
|
|
||||||
golang.org/x/term v0.34.0 // indirect
|
|
||||||
golang.org/x/text v0.28.0 // indirect
|
|
||||||
golang.org/x/time v0.9.0 // indirect
|
|
||||||
google.golang.org/protobuf v1.36.8 // indirect
|
|
||||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
|
||||||
k8s.io/klog/v2 v2.130.1 // indirect
|
|
||||||
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
|
|
||||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
|
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
|
|
||||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
|
|
||||||
sigs.k8s.io/yaml v1.6.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
|||||||
789
go.sum
789
go.sum
@ -1,184 +1,111 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
|
||||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
|
||||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
|
||||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
|
||||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
|
||||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
|
||||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
|
||||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
|
||||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
|
||||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
|
||||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
|
||||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
|
||||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
|
||||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
|
||||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
|
||||||
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
|
|
||||||
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
|
|
||||||
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
|
|
||||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
|
||||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
|
||||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
|
||||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
|
||||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
|
||||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
|
||||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
|
||||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
|
||||||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
|
||||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
|
||||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
|
||||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
|
||||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
|
||||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
|
||||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
|
||||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
|
||||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/Electronn/openvpn_exporter v0.0.0-20181005212047-37f639dc9c7d h1:OsbfZPacTMb2ljULx/g4Xt9mSbkVx/lfuYQQwbgkD5c=
|
||||||
|
github.com/Electronn/openvpn_exporter v0.0.0-20181005212047-37f639dc9c7d/go.mod h1:wcYOspX0l7/kR2Pd59EUppVpfzvVu/I+vBgMmDOmNH0=
|
||||||
|
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
|
||||||
|
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
|
||||||
|
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||||
|
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
|
||||||
|
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
|
||||||
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc=
|
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
|
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E=
|
||||||
|
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||||
|
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
|
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
|
||||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||||
|
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
|
||||||
|
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
|
||||||
|
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||||
|
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||||
|
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||||
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||||
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
|
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
|
||||||
|
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
|
||||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
|
||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
|
||||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
|
||||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||||
|
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||||
|
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||||
|
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||||
|
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
|
||||||
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
|
||||||
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
|
||||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
|
||||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
|
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
|
||||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
|
||||||
github.com/gobuffalo/logger v1.0.6 h1:nnZNpxYo0zx+Aj9RfMPBm+x9zAU2OayFh/xrAWi34HU=
|
|
||||||
github.com/gobuffalo/logger v1.0.6/go.mod h1:J31TBEHR1QLV2683OXTAItYIg8pv2JMHnF/quuAbMjs=
|
|
||||||
github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0=
|
|
||||||
github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY=
|
|
||||||
github.com/gobuffalo/packr/v2 v2.8.3 h1:xE1yzvnO56cUC0sTpKR3DIbxZgB54AftTFMhB2XEWlY=
|
|
||||||
github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc=
|
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
|
||||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
|
||||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
|
||||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
|
||||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
|
||||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
|
||||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
|
||||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
|
||||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
|
||||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
|
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
|
||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
|
|
||||||
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
|
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
|
||||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
|
||||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
|
||||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
|
||||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
|
||||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
|
||||||
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
|
|
||||||
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
|
||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
|
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
|
||||||
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||||
|
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
|
||||||
|
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||||
@ -189,53 +116,45 @@ github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerX
|
|||||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
|
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
|
||||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw=
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
|
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
|
||||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
|
||||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
|
||||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
|
||||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
|
||||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
|
||||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
|
||||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
|
||||||
github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI=
|
|
||||||
github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=
|
|
||||||
github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY=
|
|
||||||
github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI=
|
|
||||||
github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI=
|
|
||||||
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
|
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||||
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
@ -244,491 +163,243 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
|
|||||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
|
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
|
||||||
github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM=
|
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
|
||||||
github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||||
github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4=
|
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
|
||||||
github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
|
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||||
|
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||||
|
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||||
|
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||||
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||||
|
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
|
||||||
|
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
|
||||||
|
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
|
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||||
|
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
|
||||||
|
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||||
|
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||||
|
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||||
|
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
|
||||||
|
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
|
||||||
|
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||||
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||||
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
|
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||||
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
|
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||||
|
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||||
|
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
|
||||||
|
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||||
|
github.com/prometheus/client_golang v1.8.0 h1:zvJNkoCFAnYFNC24FV8nW4JdRJ3GIFcLbg65lL/JDcw=
|
||||||
|
github.com/prometheus/client_golang v1.8.0/go.mod h1:O9VU6huf47PktckDQfMTX0Y8tY0/7TSWwj+ITvv0TnM=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||||
|
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||||
github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
|
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
|
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
|
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
|
||||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||||
|
github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||||
|
github.com/prometheus/common v0.15.0 h1:4fgOnadei3EZvgRwxJ7RMpG1k1pOZth5Pc13tyspaKM=
|
||||||
|
github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||||
|
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||||
|
github.com/prometheus/procfs v0.2.0 h1:wH4vA7pcjKuZzjF7lM8awk4fnuJO6idemZXoKnULUx4=
|
||||||
|
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||||
|
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||||
|
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
|
||||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
|
||||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
|
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
|
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||||
|
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
|
||||||
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
|
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
|
||||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
|
||||||
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
|
||||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
|
||||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
|
||||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
|
||||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
|
||||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
|
||||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
|
||||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
|
||||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
|
||||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
|
||||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
|
||||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
|
|
||||||
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
|
||||||
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
|
||||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
|
||||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
|
||||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
|
||||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
|
||||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
|
||||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
|
||||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
|
||||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
|
||||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
|
||||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
|
||||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
|
|
||||||
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
|
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
|
||||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||||
|
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
|
||||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
|
||||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
|
||||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
|
||||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
|
||||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
|
|
||||||
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
|
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
|
||||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211 h1:9UQO31fZ+0aKQOFldThf7BKPMJTiBfWycGh/u3UoO88=
|
||||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
|
||||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
|
||||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
|
||||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
|
||||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
|
||||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
|
||||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
|
||||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
|
||||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
|
||||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
|
||||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
|
||||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
|
||||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
|
||||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
|
||||||
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
|
|
||||||
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
|
||||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
|
||||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
|
||||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
|
||||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
|
||||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
|
||||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
|
||||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
|
||||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
|
||||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
|
||||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
|
||||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
|
||||||
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
|
||||||
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
|
||||||
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
|
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
|
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
|
||||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
|
||||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
|
||||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
|
||||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
|
||||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
|
||||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
|
||||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
|
||||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
|
||||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
|
||||||
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
|
||||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
|
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
|
||||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||||
|
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
|
||||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
|
||||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
|
||||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
|
||||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
|
||||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
|
||||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
|
||||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
|
||||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
|
||||||
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
|
||||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
|
||||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
|
||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
|
||||||
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
|
|
||||||
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
|
||||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||||
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
|
||||||
k8s.io/api v0.34.3 h1:D12sTP257/jSH2vHV2EDYrb16bS7ULlHpdNdNhEw2S4=
|
|
||||||
k8s.io/api v0.34.3/go.mod h1:PyVQBF886Q5RSQZOim7DybQjAbVs8g7gwJNhGtY5MBk=
|
|
||||||
k8s.io/apimachinery v0.34.3 h1:/TB+SFEiQvN9HPldtlWOTp0hWbJ+fjU+wkxysf/aQnE=
|
|
||||||
k8s.io/apimachinery v0.34.3/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
|
||||||
k8s.io/client-go v0.34.3 h1:wtYtpzy/OPNYf7WyNBTj3iUA0XaBHVqhv4Iv3tbrF5A=
|
|
||||||
k8s.io/client-go v0.34.3/go.mod h1:OxxeYagaP9Kdf78UrKLa3YZixMCfP6bgPwPwNBQBzpM=
|
|
||||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
|
||||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
|
||||||
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA=
|
|
||||||
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=
|
|
||||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y=
|
|
||||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
|
|
||||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
|
||||||
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
|
||||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
|
|
||||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
|
||||||
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
|
||||||
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
|
||||||
|
|||||||
231
helpers.go
231
helpers.go
@ -1,43 +1,30 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/tar"
|
|
||||||
"compress/gzip"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func parseDate(layout, datetime string) time.Time {
|
func indexTxtDateToHumanReadable(datetime string) string {
|
||||||
|
layout := "060102150405Z"
|
||||||
t, err := time.Parse(layout, datetime)
|
t, err := time.Parse(layout, datetime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
return t
|
return t.Format("2006-01-02 15:04:05")
|
||||||
}
|
|
||||||
|
|
||||||
func parseDateToString(layout, datetime, format string) string {
|
|
||||||
return parseDate(layout, datetime).Format(format)
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseDateToUnix(layout, datetime string) int64 {
|
|
||||||
return parseDate(layout, datetime).Unix()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func runBash(script string) string {
|
func runBash(script string) string {
|
||||||
log.Debugln(script)
|
fmt.Println(script)
|
||||||
cmd := exec.Command("bash", "-c", script)
|
cmd := exec.Command("bash", "-c", script)
|
||||||
stdout, err := cmd.CombinedOutput()
|
stdout, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Sprint(err) + " : " + string(stdout)
|
return (fmt.Sprint(err) + " : " + string(stdout))
|
||||||
}
|
}
|
||||||
return string(stdout)
|
return string(stdout)
|
||||||
}
|
}
|
||||||
@ -48,7 +35,7 @@ func fExist(path string) bool {
|
|||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return false
|
return false
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
log.Fatalf("fExist: %s", err)
|
log.Fatal(err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,102 +45,37 @@ func fExist(path string) bool {
|
|||||||
func fRead(path string) string {
|
func fRead(path string) string {
|
||||||
content, err := ioutil.ReadFile(path)
|
content, err := ioutil.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warning(err)
|
log.Fatal(err)
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(content)
|
return string(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fCreate(path string) error {
|
func fCreate(path string) bool {
|
||||||
var _, err = os.Stat(path)
|
var _, err = os.Stat(path)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
var file, err = os.Create(path)
|
var file, err = os.Create(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln(err)
|
log.Println(err)
|
||||||
return err
|
return false
|
||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
}
|
}
|
||||||
return nil
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func fWrite(path, content string) error {
|
func fWrite(path, content string) {
|
||||||
err := ioutil.WriteFile(path, []byte(content), 0644)
|
err := ioutil.WriteFile(path, []byte(content), 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func fDelete(path string) error {
|
func fDelete(path string) {
|
||||||
err := os.Remove(path)
|
err := os.Remove(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func fCopy(src, dst string) error {
|
|
||||||
sfi, err := os.Stat(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !sfi.Mode().IsRegular() {
|
|
||||||
// cannot copy non-regular files (e.g., directories, symlinks, devices, etc.)
|
|
||||||
return fmt.Errorf("fCopy: non-regular source file %s (%q)", sfi.Name(), sfi.Mode().String())
|
|
||||||
}
|
|
||||||
dfi, err := os.Stat(dst)
|
|
||||||
if err != nil {
|
|
||||||
if !os.IsNotExist(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if !(dfi.Mode().IsRegular()) {
|
|
||||||
return fmt.Errorf("fCopy: non-regular destination file %s (%q)", dfi.Name(), dfi.Mode().String())
|
|
||||||
}
|
|
||||||
if os.SameFile(sfi, dfi) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err = os.Link(src, dst); err == nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
in, err := os.Open(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer in.Close()
|
|
||||||
out, err := os.Create(dst)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
cerr := out.Close()
|
|
||||||
if err == nil {
|
|
||||||
err = cerr
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
if _, err = io.Copy(out, in); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = out.Sync()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func fMove(src, dst string) error {
|
|
||||||
err := fCopy(src, dst)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn(err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = fDelete(src)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn(err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func fDownload(path, url string, basicAuth bool) error {
|
func fDownload(path, url string, basicAuth bool) error {
|
||||||
@ -169,7 +91,7 @@ func fDownload(path, url string, basicAuth bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
log.Warnf("WARNING: Download file operation for url %s finished with status code %d\n", url, resp.StatusCode)
|
log.Printf("WARNING: Download file operation for url %s finished with status code %d", url, resp.StatusCode )
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
@ -183,124 +105,3 @@ func fDownload(path, url string, basicAuth bool) error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createArchiveFromDir(dir, path string) error {
|
|
||||||
|
|
||||||
var files []string
|
|
||||||
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
|
|
||||||
if err != nil {
|
|
||||||
log.Warn(err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !info.IsDir() {
|
|
||||||
files = append(files, path)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
log.Warn(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
out, err := os.Create(path)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Error writing archive %s: %s", path, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer out.Close()
|
|
||||||
gw := gzip.NewWriter(out)
|
|
||||||
defer gw.Close()
|
|
||||||
tw := tar.NewWriter(gw)
|
|
||||||
defer tw.Close()
|
|
||||||
|
|
||||||
// Iterate over files and add them to the tar archive
|
|
||||||
for _, filePath := range files {
|
|
||||||
file, err := os.Open(filePath)
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("Error writing archive %s: %s", path, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get FileInfo about our file providing file size, mode, etc.
|
|
||||||
info, err := file.Stat()
|
|
||||||
if err != nil {
|
|
||||||
file.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a tar Header from the FileInfo data
|
|
||||||
header, err := tar.FileInfoHeader(info, info.Name())
|
|
||||||
if err != nil {
|
|
||||||
file.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
header.Name = strings.Replace(filePath, dir+"/", "", 1)
|
|
||||||
|
|
||||||
// Write file header to the tar archive
|
|
||||||
err = tw.WriteHeader(header)
|
|
||||||
if err != nil {
|
|
||||||
file.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy file content to tar archive
|
|
||||||
_, err = io.Copy(tw, file)
|
|
||||||
if err != nil {
|
|
||||||
file.Close()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
file.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func extractFromArchive(archive, path string) error {
|
|
||||||
// Open the file which will be written into the archive
|
|
||||||
file, err := os.Open(archive)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
// Write file header to the tar archive
|
|
||||||
uncompressedStream, err := gzip.NewReader(file)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("extractFromArchive(): NewReader failed")
|
|
||||||
}
|
|
||||||
|
|
||||||
tarReader := tar.NewReader(uncompressedStream)
|
|
||||||
|
|
||||||
for true {
|
|
||||||
header, err := tarReader.Next()
|
|
||||||
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("extractFromArchive: Next() failed: %s", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
switch header.Typeflag {
|
|
||||||
case tar.TypeDir:
|
|
||||||
if err := os.Mkdir(path+"/"+header.Name, 0755); err != nil {
|
|
||||||
log.Fatalf("extractFromArchive: Mkdir() failed: %s", err.Error())
|
|
||||||
}
|
|
||||||
case tar.TypeReg:
|
|
||||||
outFile, err := os.Create(path + "/" + header.Name)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("extractFromArchive: Create() failed: %s", err.Error())
|
|
||||||
}
|
|
||||||
if _, err := io.Copy(outFile, tarReader); err != nil {
|
|
||||||
log.Fatalf("extractFromArchive: Copy() failed: %s", err.Error())
|
|
||||||
}
|
|
||||||
outFile.Close()
|
|
||||||
|
|
||||||
default:
|
|
||||||
log.Fatalf(
|
|
||||||
"extractFromArchive: uknown type: %s in %s", header.Typeflag, header.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 179 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 54 KiB |
@ -1,12 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
apt-get update
|
|
||||||
apt-get install -y curl
|
|
||||||
apt-get install -y libc6 libc6-dev gcc-arm-linux-gnueabi gcc-aarch64-linux-gnu
|
|
||||||
|
|
||||||
curl -sL https://deb.nodesource.com/setup_16.x | bash -
|
|
||||||
apt-get install -y nodejs
|
|
||||||
|
|
||||||
PATH=$PATH:~/go/bin
|
|
||||||
|
|
||||||
go install github.com/gobuffalo/packr/v2/packr2@latest
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
apt-get update
|
|
||||||
apt-get install -y curl
|
|
||||||
apt-get install -y libc6 libc6-dev libc6-dev-i386
|
|
||||||
|
|
||||||
curl -sL https://deb.nodesource.com/setup_16.x | bash -
|
|
||||||
apt-get install -y nodejs
|
|
||||||
|
|
||||||
PATH=$PATH:~/go/bin
|
|
||||||
|
|
||||||
go install github.com/gobuffalo/packr/v2/packr2@latest
|
|
||||||
794
kubernetes.go
794
kubernetes.go
@ -1,794 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/x509"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
v1 "k8s.io/api/core/v1"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
"k8s.io/client-go/kubernetes"
|
|
||||||
"k8s.io/client-go/rest"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
secretCA = "openvpn-pki-ca"
|
|
||||||
secretServer = "openvpn-pki-server"
|
|
||||||
secretClientTmpl = "openvpn-pki-%d"
|
|
||||||
secretCRL = "openvpn-pki-crl"
|
|
||||||
secretIndexTxt = "openvpn-pki-index-txt"
|
|
||||||
secretDHandTA = "openvpn-pki-dh-and-ta"
|
|
||||||
certFileName = "tls.crt"
|
|
||||||
privKeyFileName = "tls.key"
|
|
||||||
)
|
|
||||||
|
|
||||||
// <year><month><day><hour><minute><second>Z
|
|
||||||
const indexTxtDateFormat = "060102150405Z"
|
|
||||||
|
|
||||||
var namespace = "default"
|
|
||||||
|
|
||||||
type OpenVPNPKI struct {
|
|
||||||
CAPrivKeyRSA *rsa.PrivateKey
|
|
||||||
CAPrivKeyPEM *bytes.Buffer
|
|
||||||
CACert *x509.Certificate
|
|
||||||
CACertPEM *bytes.Buffer
|
|
||||||
ServerPrivKeyRSA *rsa.PrivateKey
|
|
||||||
ServerPrivKeyPEM *bytes.Buffer
|
|
||||||
ServerCert *x509.Certificate
|
|
||||||
ServerCertPEM *bytes.Buffer
|
|
||||||
ClientCerts []ClientCert
|
|
||||||
RevokedCerts []RevokedCert
|
|
||||||
KubeClient *kubernetes.Clientset
|
|
||||||
}
|
|
||||||
|
|
||||||
type ClientCert struct {
|
|
||||||
PrivKeyRSA *rsa.PrivateKey
|
|
||||||
PrivKeyPEM *bytes.Buffer
|
|
||||||
Cert *x509.Certificate
|
|
||||||
CertPEM *bytes.Buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
type RevokedCert struct {
|
|
||||||
RevokedTime time.Time `json:"revokedTime"`
|
|
||||||
CommonName string `json:"commonName"`
|
|
||||||
Cert *x509.Certificate `json:"cert"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) run() (err error) {
|
|
||||||
if _, err := os.Stat(kubeNamespaceFilePath); err == nil {
|
|
||||||
file, err := ioutil.ReadFile(kubeNamespaceFilePath)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
namespace = string(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.initKubeClient()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.initPKI()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.indexTxtUpdate()
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.easyrsaGenCRL()
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if res, _ := openVPNPKI.secretCheckExists(secretDHandTA); !res {
|
|
||||||
err := openVPNPKI.secretGenTaKeyAndDHParam()
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.updateFilesFromSecrets()
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.updateCRLOnDisk()
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.updateIndexTxtOnDisk()
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.updateCcdOnDisk()
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) initKubeClient() (err error) {
|
|
||||||
config, _ := rest.InClusterConfig()
|
|
||||||
openVPNPKI.KubeClient, err = kubernetes.NewForConfig(config)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) initPKI() (err error) {
|
|
||||||
if res, _ := openVPNPKI.secretCheckExists(secretCA); res {
|
|
||||||
cert, err := openVPNPKI.secretGetClientCert(secretCA)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
openVPNPKI.CAPrivKeyPEM = cert.PrivKeyPEM
|
|
||||||
openVPNPKI.CAPrivKeyRSA = cert.PrivKeyRSA
|
|
||||||
openVPNPKI.CACertPEM = cert.CertPEM
|
|
||||||
openVPNPKI.CACert = cert.Cert
|
|
||||||
} else {
|
|
||||||
openVPNPKI.CAPrivKeyPEM, err = genPrivKey()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
openVPNPKI.CAPrivKeyRSA, err = decodePrivKey(openVPNPKI.CAPrivKeyPEM.Bytes())
|
|
||||||
|
|
||||||
openVPNPKI.CACertPEM, _ = genCA(openVPNPKI.CAPrivKeyRSA)
|
|
||||||
openVPNPKI.CACert, err = decodeCert(openVPNPKI.CACertPEM.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
secretMetaData := metav1.ObjectMeta{Name: secretCA}
|
|
||||||
|
|
||||||
secretData := map[string][]byte{
|
|
||||||
certFileName: openVPNPKI.CACertPEM.Bytes(),
|
|
||||||
privKeyFileName: openVPNPKI.CAPrivKeyPEM.Bytes(),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeTLS)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if res, _ := openVPNPKI.secretCheckExists(secretServer); res {
|
|
||||||
cert, err := openVPNPKI.secretGetClientCert(secretServer)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
openVPNPKI.ServerPrivKeyPEM = cert.PrivKeyPEM
|
|
||||||
openVPNPKI.ServerPrivKeyRSA = cert.PrivKeyRSA
|
|
||||||
openVPNPKI.ServerCertPEM = cert.CertPEM
|
|
||||||
openVPNPKI.ServerCert = cert.Cert
|
|
||||||
} else {
|
|
||||||
openVPNPKI.ServerPrivKeyPEM, err = genPrivKey()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
openVPNPKI.ServerPrivKeyRSA, err = decodePrivKey(openVPNPKI.ServerPrivKeyPEM.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
openVPNPKI.ServerCertPEM, _ = genServerCert(openVPNPKI.ServerPrivKeyRSA, openVPNPKI.CAPrivKeyRSA, openVPNPKI.CACert, "server")
|
|
||||||
openVPNPKI.ServerCert, err = decodeCert(openVPNPKI.ServerCertPEM.Bytes())
|
|
||||||
|
|
||||||
secretMetaData := metav1.ObjectMeta{
|
|
||||||
Name: secretServer,
|
|
||||||
Labels: map[string]string{
|
|
||||||
"index.txt": "",
|
|
||||||
"name": "server",
|
|
||||||
"type": "serverAuth",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
secretData := map[string][]byte{
|
|
||||||
certFileName: openVPNPKI.ServerCertPEM.Bytes(),
|
|
||||||
privKeyFileName: openVPNPKI.ServerPrivKeyPEM.Bytes(),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeTLS)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) indexTxtUpdate() (err error) {
|
|
||||||
secrets, err := openVPNPKI.secretsGetByLabels("index.txt=")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var indexTxt string
|
|
||||||
for _, secret := range secrets.Items {
|
|
||||||
certPEM := bytes.NewBuffer(secret.Data[certFileName])
|
|
||||||
log.Trace("indexTxtUpdate:" + secret.Name)
|
|
||||||
cert, err := decodeCert(certPEM.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Trace(cert.Subject.CommonName)
|
|
||||||
|
|
||||||
if secret.Annotations["revokedAt"] == "" {
|
|
||||||
indexTxt += fmt.Sprintf("%s\t%s\t\t%s\t%s\t%s\n", "V", cert.NotAfter.Format(indexTxtDateFormat), fmt.Sprintf("%d", cert.SerialNumber), "unknown", "/CN="+secret.Labels["name"])
|
|
||||||
} else if cert.NotAfter.Before(time.Now()) {
|
|
||||||
indexTxt += fmt.Sprintf("%s\t%s\t\t%s\t%s\t%s\n", "E", cert.NotAfter.Format(indexTxtDateFormat), fmt.Sprintf("%d", cert.SerialNumber), "unknown", "/CN="+secret.Labels["name"])
|
|
||||||
} else {
|
|
||||||
indexTxt += fmt.Sprintf("%s\t%s\t%s\t%s\t%s\t%s\n", "R", cert.NotAfter.Format(indexTxtDateFormat), secret.Annotations["revokedAt"], fmt.Sprintf("%d", cert.SerialNumber), "unknown", "/CN="+secret.Labels["name"])
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
secretMetaData := metav1.ObjectMeta{Name: secretIndexTxt}
|
|
||||||
|
|
||||||
secretData := map[string][]byte{"index.txt": []byte(indexTxt)}
|
|
||||||
|
|
||||||
if res, _ := openVPNPKI.secretCheckExists(secretIndexTxt); !res {
|
|
||||||
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeOpaque)
|
|
||||||
} else {
|
|
||||||
err = openVPNPKI.secretUpdate(secretMetaData, secretData, v1.SecretTypeOpaque)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) updateIndexTxtOnDisk() (err error) {
|
|
||||||
secret, err := openVPNPKI.secretGetByName(secretIndexTxt)
|
|
||||||
indexTxt := secret.Data["index.txt"]
|
|
||||||
err = ioutil.WriteFile(fmt.Sprintf("%s/pki/index.txt", *easyrsaDirPath), indexTxt, 0600)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) easyrsaGenCRL() (err error) {
|
|
||||||
err = openVPNPKI.indexTxtUpdate()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
secrets, err := openVPNPKI.secretsGetByLabels("index.txt=,type=clientAuth")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var revoked []*RevokedCert
|
|
||||||
|
|
||||||
for _, secret := range secrets.Items {
|
|
||||||
if secret.Annotations["revokedAt"] != "" {
|
|
||||||
revokedAt, err := time.Parse(indexTxtDateFormat, secret.Annotations["revokedAt"])
|
|
||||||
if err != nil {
|
|
||||||
log.Warning(err)
|
|
||||||
}
|
|
||||||
cert, err := decodeCert(secret.Data[certFileName])
|
|
||||||
revoked = append(revoked, &RevokedCert{RevokedTime: revokedAt, Cert: cert})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
crl, err := genCRL(revoked, openVPNPKI.CACert, openVPNPKI.CAPrivKeyRSA)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
secretMetaData := metav1.ObjectMeta{Name: secretCRL}
|
|
||||||
|
|
||||||
secretData := map[string][]byte{
|
|
||||||
"crl.pem": crl.Bytes(),
|
|
||||||
}
|
|
||||||
|
|
||||||
//err = openVPNPKI.secretCreate(secretMetaData, secretData)
|
|
||||||
|
|
||||||
if res, _ := openVPNPKI.secretCheckExists(secretCRL); !res {
|
|
||||||
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeOpaque)
|
|
||||||
} else {
|
|
||||||
err = openVPNPKI.secretUpdate(secretMetaData, secretData, v1.SecretTypeOpaque)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) easyrsaBuildClient(commonName string) (err error) {
|
|
||||||
// check certificate exists
|
|
||||||
_, err = openVPNPKI.secretGetByLabels("name=" + commonName)
|
|
||||||
if err == nil {
|
|
||||||
return errors.New(fmt.Sprintf("certificate for user (%s) already exists", commonName))
|
|
||||||
}
|
|
||||||
|
|
||||||
clientPrivKeyPEM, err := genPrivKey()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
clientPrivKeyRSA, err := decodePrivKey(clientPrivKeyPEM.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
clientCertPEM, _ := genClientCert(clientPrivKeyRSA, openVPNPKI.CAPrivKeyRSA, openVPNPKI.CACert, commonName)
|
|
||||||
clientCert, err := decodeCert(clientCertPEM.Bytes())
|
|
||||||
|
|
||||||
secretMetaData := metav1.ObjectMeta{
|
|
||||||
Name: fmt.Sprintf(secretClientTmpl, clientCert.SerialNumber),
|
|
||||||
Labels: map[string]string{
|
|
||||||
labelKeyIndexTxt: "",
|
|
||||||
labelKeyType: labelValueClientAuth,
|
|
||||||
labelKeyName: commonName,
|
|
||||||
labelKeyManagedBy: labelValueManagedByApp,
|
|
||||||
},
|
|
||||||
Annotations: map[string]string{
|
|
||||||
"commonName": commonName,
|
|
||||||
"notBefore": clientCert.NotBefore.Format(indexTxtDateFormat),
|
|
||||||
"notAfter": clientCert.NotAfter.Format(indexTxtDateFormat),
|
|
||||||
"revokedAt": "",
|
|
||||||
"serialNumber": fmt.Sprintf("%d", clientCert.SerialNumber),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
secretData := map[string][]byte{
|
|
||||||
certFileName: clientCertPEM.Bytes(),
|
|
||||||
privKeyFileName: clientPrivKeyPEM.Bytes(),
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeTLS)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.indexTxtUpdate()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.updateIndexTxtOnDisk()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) easyrsaGetCACert() string {
|
|
||||||
return openVPNPKI.CACertPEM.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) easyrsaGetClientCert(commonName string) (cert, key string) {
|
|
||||||
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cert = string(secret.Data[certFileName])
|
|
||||||
key = string(secret.Data[privKeyFileName])
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) easyrsaRevoke(commonName string) (err error) {
|
|
||||||
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if secret.Annotations["revokedAt"] != "" {
|
|
||||||
log.Warnf("user (%s) already revoked", commonName)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
secret.Annotations["revokedAt"] = time.Now().Format(indexTxtDateFormat)
|
|
||||||
|
|
||||||
_, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.indexTxtUpdate()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.updateIndexTxtOnDisk()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.easyrsaGenCRL()
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.updateCRLOnDisk()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) easyrsaUnrevoke(commonName string) (err error) {
|
|
||||||
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
secret.Annotations["revokedAt"] = ""
|
|
||||||
|
|
||||||
_, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.indexTxtUpdate()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.updateIndexTxtOnDisk()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.easyrsaGenCRL()
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.updateCRLOnDisk()
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) easyrsaRotate(commonName, newPassword string) (err error) {
|
|
||||||
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
uniqHash := strings.Replace(uuid.New().String(), "-", "", -1)
|
|
||||||
secret.Annotations["commonName"] = "REVOKED-" + commonName + "-" + uniqHash
|
|
||||||
secret.Labels["name"] = "REVOKED" + commonName
|
|
||||||
secret.Labels["revokedForever"] = "true"
|
|
||||||
|
|
||||||
_, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.easyrsaBuildClient(commonName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.transferRoutes(secret, commonName)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.indexTxtUpdate()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.updateIndexTxtOnDisk()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.easyrsaGenCRL()
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.updateCRLOnDisk()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
func (openVPNPKI *OpenVPNPKI) easyrsaDelete(commonName string) (err error) {
|
|
||||||
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
uniqHash := strings.Replace(uuid.New().String(), "-", "", -1)
|
|
||||||
secret.Annotations["commonName"] = "REVOKED-" + commonName + "-" + uniqHash
|
|
||||||
secret.Labels["name"] = "REVOKED-" + commonName + "-" + uniqHash
|
|
||||||
secret.Labels["revokedForever"] = "true"
|
|
||||||
|
|
||||||
_, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.indexTxtUpdate()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.updateIndexTxtOnDisk()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.easyrsaGenCRL()
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.updateCRLOnDisk()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) secretGetClientCert(name string) (cert ClientCert, err error) {
|
|
||||||
secret, err := openVPNPKI.secretGetByName(name)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cert.CertPEM = bytes.NewBuffer(secret.Data[certFileName])
|
|
||||||
cert.Cert, err = decodeCert(cert.CertPEM.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
cert.PrivKeyPEM = bytes.NewBuffer(secret.Data[privKeyFileName])
|
|
||||||
cert.PrivKeyRSA, err = decodePrivKey(cert.PrivKeyPEM.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) updateFilesFromSecrets() (err error) {
|
|
||||||
ca, err := openVPNPKI.secretGetClientCert(secretCA)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
server, err := openVPNPKI.secretGetClientCert(secretServer)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
secret, err := openVPNPKI.secretGetByName(secretDHandTA)
|
|
||||||
takey := secret.Data["ta.key"]
|
|
||||||
dhparam := secret.Data["dh.pem"]
|
|
||||||
|
|
||||||
if _, err := os.Stat(fmt.Sprintf("%s/pki/issued", *easyrsaDirPath)); os.IsNotExist(err) {
|
|
||||||
err = os.MkdirAll(fmt.Sprintf("%s/pki/issued", *easyrsaDirPath), 0755)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := os.Stat(fmt.Sprintf("%s/pki/private", *easyrsaDirPath)); os.IsNotExist(err) {
|
|
||||||
err = os.MkdirAll(fmt.Sprintf("%s/pki/private", *easyrsaDirPath), 0755)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ioutil.WriteFile(fmt.Sprintf("%s/pki/ca.crt", *easyrsaDirPath), ca.CertPEM.Bytes(), 0600)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ioutil.WriteFile(fmt.Sprintf("%s/pki/issued/server.crt", *easyrsaDirPath), server.CertPEM.Bytes(), 0600)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ioutil.WriteFile(fmt.Sprintf("%s/pki/private/server.key", *easyrsaDirPath), server.PrivKeyPEM.Bytes(), 0600)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ioutil.WriteFile(fmt.Sprintf("%s/pki/ta.key", *easyrsaDirPath), takey, 0600)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ioutil.WriteFile(fmt.Sprintf("%s/pki/dh.pem", *easyrsaDirPath), dhparam, 0600)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.updateCRLOnDisk()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) updateCRLOnDisk() (err error) {
|
|
||||||
secret, err := openVPNPKI.secretGetByName(secretCRL)
|
|
||||||
crl := secret.Data["crl.pem"]
|
|
||||||
err = ioutil.WriteFile(fmt.Sprintf("%s/pki/crl.pem", *easyrsaDirPath), crl, 0644)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("error write crl.pem:%s", err.Error())
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) secretGenTaKeyAndDHParam() (err error) {
|
|
||||||
taKeyPath := "/tmp/ta.key"
|
|
||||||
cmd := exec.Command("bash", "-c", fmt.Sprintf("/usr/sbin/openvpn --genkey --secret %s", taKeyPath))
|
|
||||||
stdout, err := cmd.CombinedOutput()
|
|
||||||
log.Info(fmt.Sprintf("/usr/sbin/openvpn --genkey --secret %s: %s", taKeyPath, string(stdout)))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
taKey, err := ioutil.ReadFile(taKeyPath)
|
|
||||||
|
|
||||||
dhparamPath := "/tmp/dh.pem"
|
|
||||||
cmd = exec.Command("bash", "-c", fmt.Sprintf("openssl dhparam -out %s 2048", dhparamPath))
|
|
||||||
_, err = cmd.CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
dhparam, err := ioutil.ReadFile(dhparamPath)
|
|
||||||
|
|
||||||
secretMetaData := metav1.ObjectMeta{Name: secretDHandTA}
|
|
||||||
|
|
||||||
secretData := map[string][]byte{
|
|
||||||
"ta.key": taKey,
|
|
||||||
"dh.pem": dhparam,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.secretCreate(secretMetaData, secretData, v1.SecretTypeOpaque)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// ccd
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) secretGetCcd(commonName string) (ccd string) {
|
|
||||||
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, _ := range secret.Data {
|
|
||||||
if k == "ccd" {
|
|
||||||
ccd = string(secret.Data["ccd"])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) secretUpdateCcd(commonName string, ccd []byte) {
|
|
||||||
secret, err := openVPNPKI.secretGetByLabels("name=" + commonName)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
secret.Data["ccd"] = ccd
|
|
||||||
|
|
||||||
err = openVPNPKI.secretUpdate(secret.ObjectMeta, secret.Data, v1.SecretTypeTLS)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("secret (%s) update error: %s", secret.Name, err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
err = openVPNPKI.updateCcdOnDisk()
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) updateCcdOnDisk() (err error) {
|
|
||||||
secrets, err := openVPNPKI.secretsGetByLabels("index.txt=,type=clientAuth")
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := os.Stat(*ccdDir); os.IsNotExist(err) {
|
|
||||||
err = os.MkdirAll(*ccdDir, 0755)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, secret := range secrets.Items {
|
|
||||||
ccd := secret.Data["ccd"]
|
|
||||||
if len(ccd) > 0 {
|
|
||||||
err = ioutil.WriteFile(fmt.Sprintf("%s/%s", *ccdDir, secret.Labels["name"]), ccd, 0644)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) secretCreate(objectMeta metav1.ObjectMeta, data map[string][]byte, secretType v1.SecretType) (err error) {
|
|
||||||
if objectMeta.Name == "nil" {
|
|
||||||
err = errors.New("secret name not defined")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
secret := &v1.Secret{
|
|
||||||
TypeMeta: metav1.TypeMeta{},
|
|
||||||
ObjectMeta: objectMeta,
|
|
||||||
Data: data,
|
|
||||||
Type: secretType,
|
|
||||||
}
|
|
||||||
_, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Create(context.TODO(), secret, metav1.CreateOptions{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) secretUpdate(objectMeta metav1.ObjectMeta, data map[string][]byte, secretType v1.SecretType) (err error) {
|
|
||||||
secret := &v1.Secret{
|
|
||||||
TypeMeta: metav1.TypeMeta{},
|
|
||||||
ObjectMeta: objectMeta,
|
|
||||||
Data: data,
|
|
||||||
Type: secretType,
|
|
||||||
}
|
|
||||||
_, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) secretGetByName(name string) (secret *v1.Secret, err error) {
|
|
||||||
secret, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Get(context.TODO(), name, metav1.GetOptions{})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) secretsGetByLabels(labels string) (secrets *v1.SecretList, err error) {
|
|
||||||
secrets, err = openVPNPKI.KubeClient.CoreV1().Secrets(namespace).List(context.TODO(), metav1.ListOptions{LabelSelector: labels})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(secrets.Items) == 0 {
|
|
||||||
log.Debugf("secrets with labels %s not found", labels)
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) secretGetByLabels(labels string) (secret *v1.Secret, err error) {
|
|
||||||
secrets, err := openVPNPKI.secretsGetByLabels(labels)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(secrets.Items) > 1 {
|
|
||||||
err = errors.New(fmt.Sprintf("found more than one secret with labels %s", labels))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(secrets.Items) == 0 {
|
|
||||||
err = errors.New(fmt.Sprintf("secret not found"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
secret = &secrets.Items[0]
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (openVPNPKI *OpenVPNPKI) secretCheckExists(name string) (bool, string) {
|
|
||||||
secret, err := openVPNPKI.KubeClient.CoreV1().Secrets(namespace).Get(context.TODO(), name, metav1.GetOptions{})
|
|
||||||
if err != nil {
|
|
||||||
log.Debug(err)
|
|
||||||
return false, ""
|
|
||||||
}
|
|
||||||
return true, secret.ResourceVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
// transferRoutes transfers configured routes from revoked certs to a new one
|
|
||||||
func (openVPNPKI *OpenVPNPKI) transferRoutes(revokedSecret *v1.Secret, newNameCert string) error {
|
|
||||||
ccd, ok := revokedSecret.Data["ccd"]
|
|
||||||
if !ok || len(ccd) == 0 {
|
|
||||||
log.Infof("No CCD data found in secret %s", revokedSecret.Name)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
openVPNPKI.secretUpdateCcd(newNameCert, ccd)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
#!/usr/bin/env sh
|
|
||||||
|
|
||||||
PATH=$PATH:/usr/local/bin
|
|
||||||
set -e
|
|
||||||
|
|
||||||
env
|
|
||||||
|
|
||||||
auth_usr=$(head -1 $1)
|
|
||||||
auth_passwd=$(tail -1 $1)
|
|
||||||
|
|
||||||
if [ $common_name = $auth_usr ]; then
|
|
||||||
openvpn-user auth --db.path /etc/openvpn/easyrsa/pki/users.db --user ${auth_usr} --password ${auth_passwd}
|
|
||||||
else
|
|
||||||
echo "Authorization failed"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
EASY_RSA_LOC="/etc/openvpn/easyrsa"
|
|
||||||
SERVER_CERT="${EASY_RSA_LOC}/pki/issued/server.crt"
|
|
||||||
|
|
||||||
OVPN_SRV_NET=${OVPN_SERVER_NET:-172.16.100.0}
|
|
||||||
OVPN_SRV_MASK=${OVPN_SERVER_MASK:-255.255.255.0}
|
|
||||||
|
|
||||||
|
|
||||||
cd $EASY_RSA_LOC
|
|
||||||
|
|
||||||
if [ -e "$SERVER_CERT" ]; then
|
|
||||||
echo "Found existing certs - reusing"
|
|
||||||
else
|
|
||||||
if [ ${OVPN_ROLE:-"master"} = "slave" ]; then
|
|
||||||
echo "Waiting for initial sync data from master"
|
|
||||||
while [ $(wget -q localhost/api/sync/last/try -O - | wc -m) -lt 1 ]
|
|
||||||
do
|
|
||||||
sleep 5
|
|
||||||
done
|
|
||||||
else
|
|
||||||
echo "Generating new certs"
|
|
||||||
easyrsa --batch init-pki
|
|
||||||
cp -R /usr/share/easy-rsa/* $EASY_RSA_LOC/pki
|
|
||||||
echo "ca" | easyrsa build-ca nopass
|
|
||||||
easyrsa --batch build-server-full server nopass
|
|
||||||
easyrsa gen-dh
|
|
||||||
openvpn --genkey --secret ./pki/ta.key
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
easyrsa gen-crl
|
|
||||||
|
|
||||||
iptables -t nat -D POSTROUTING -s ${OVPN_SRV_NET}/${OVPN_SRV_MASK} ! -d ${OVPN_SRV_NET}/${OVPN_SRV_MASK} -j MASQUERADE || true
|
|
||||||
iptables -t nat -A POSTROUTING -s ${OVPN_SRV_NET}/${OVPN_SRV_MASK} ! -d ${OVPN_SRV_NET}/${OVPN_SRV_MASK} -j MASQUERADE
|
|
||||||
|
|
||||||
mkdir -p /dev/net
|
|
||||||
if [ ! -c /dev/net/tun ]; then
|
|
||||||
mknod /dev/net/tun c 10 200
|
|
||||||
fi
|
|
||||||
|
|
||||||
cp -f /etc/openvpn/setup/openvpn.conf /etc/openvpn/openvpn.conf
|
|
||||||
|
|
||||||
if [ ${OVPN_PASSWD_AUTH} = "true" ]; then
|
|
||||||
mkdir -p /etc/openvpn/scripts/
|
|
||||||
cp -f /etc/openvpn/setup/auth.sh /etc/openvpn/scripts/auth.sh
|
|
||||||
chmod +x /etc/openvpn/scripts/auth.sh
|
|
||||||
echo "auth-user-pass-verify /etc/openvpn/scripts/auth.sh via-file" | tee -a /etc/openvpn/openvpn.conf
|
|
||||||
echo "script-security 2" | tee -a /etc/openvpn/openvpn.conf
|
|
||||||
echo "verify-client-cert require" | tee -a /etc/openvpn/openvpn.conf
|
|
||||||
openvpn-user db-init --db.path=$EASY_RSA_LOC/pki/users.db && openvpn-user db-migrate --db.path=$EASY_RSA_LOC/pki/users.db
|
|
||||||
fi
|
|
||||||
|
|
||||||
[ -d $EASY_RSA_LOC/pki ] && chmod 755 $EASY_RSA_LOC/pki
|
|
||||||
[ -f $EASY_RSA_LOC/pki/crl.pem ] && chmod 644 $EASY_RSA_LOC/pki/crl.pem
|
|
||||||
|
|
||||||
mkdir -p /etc/openvpn/ccd
|
|
||||||
|
|
||||||
openvpn --config /etc/openvpn/openvpn.conf --client-config-dir /etc/openvpn/ccd --port 1194 --proto tcp --management 127.0.0.1 8989 --dev tun0 --server ${OVPN_SRV_NET} ${OVPN_SRV_MASK}
|
|
||||||
4
start.sh
4
start.sh
@ -1,5 +1,3 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# About 'docker compose' and 'docker-compose'
|
docker-compose -p openvpn-master up -d --build
|
||||||
# We are using Docker Compose in plugin mode with Docker. For more details, see: https://docs.docker.com/compose/install/linux/. If you need to use the standalone Docker Compose, you can modify the command `docker compose` to `docker-compose` accordingly.
|
|
||||||
docker compose -p openvpn-master up -d --build
|
|
||||||
|
|||||||
@ -1,38 +0,0 @@
|
|||||||
{{- range $server := .Hosts }}
|
|
||||||
remote {{ $server.Host }} {{ $server.Port }} {{ $server.Protocol }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
verb 4
|
|
||||||
client
|
|
||||||
nobind
|
|
||||||
dev tun
|
|
||||||
cipher AES-128-CBC
|
|
||||||
key-direction 1
|
|
||||||
#redirect-gateway def1
|
|
||||||
tls-client
|
|
||||||
remote-cert-tls server
|
|
||||||
# uncomment below lines for use with linux
|
|
||||||
#script-security 2
|
|
||||||
# if you use resolved
|
|
||||||
#up /etc/openvpn/update-resolv-conf
|
|
||||||
#down /etc/openvpn/update-resolv-conf
|
|
||||||
# if you use systemd-resolved first install openvpn-systemd-resolved package
|
|
||||||
#up /etc/openvpn/update-systemd-resolved
|
|
||||||
#down /etc/openvpn/update-systemd-resolved
|
|
||||||
|
|
||||||
{{- if .PasswdAuth }}
|
|
||||||
auth-user-pass
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
<cert>
|
|
||||||
{{ .Cert -}}
|
|
||||||
</cert>
|
|
||||||
<key>
|
|
||||||
{{ .Key -}}
|
|
||||||
</key>
|
|
||||||
<ca>
|
|
||||||
{{ .CA -}}
|
|
||||||
</ca>
|
|
||||||
<tls-auth>
|
|
||||||
{{ .TLS -}}
|
|
||||||
</tls-auth>
|
|
||||||
131
werf.yaml
131
werf.yaml
@ -1,19 +1,120 @@
|
|||||||
project: ovpn-admin
|
project: openvpn-web-ui
|
||||||
configVersion: 1
|
configVersion: 1
|
||||||
build:
|
deploy:
|
||||||
platform:
|
helmRelease: "[[ project ]]-[[ env ]]"
|
||||||
- linux/amd64
|
namespace: "[[ project ]]-[[ env ]]"
|
||||||
{{- if eq .Env "release" }}
|
|
||||||
- linux/arm64
|
|
||||||
- linux/arm/v7
|
|
||||||
- linux/arm/v8
|
|
||||||
{{- end }}
|
|
||||||
staged: true
|
|
||||||
---
|
---
|
||||||
image: ovpn-admin
|
artifact: backend-builder
|
||||||
dockerfile: Dockerfile.ovpn-admin
|
from: golang:1.14.2-alpine3.11
|
||||||
context: .
|
git:
|
||||||
|
- add: /
|
||||||
|
to: /app
|
||||||
|
stageDependencies:
|
||||||
|
install:
|
||||||
|
- "*.go"
|
||||||
|
excludePaths:
|
||||||
|
- .helm
|
||||||
|
- .werf
|
||||||
|
- frontend
|
||||||
|
- werf.yaml
|
||||||
|
- Dockerfile
|
||||||
|
ansible:
|
||||||
|
install:
|
||||||
|
- name: Install packages
|
||||||
|
apk:
|
||||||
|
name:
|
||||||
|
- build-base
|
||||||
|
- gcc
|
||||||
|
- name: Build backend
|
||||||
|
command: go build -ldflags='-extldflags "-static" -s -w' -o openvpn-admin
|
||||||
|
environment:
|
||||||
|
CGO_ENABLED: 0
|
||||||
|
GOOS: linux
|
||||||
|
GOARCH: amd64
|
||||||
|
args:
|
||||||
|
chdir: /app
|
||||||
|
|
||||||
|
---
|
||||||
|
artifact: frontend-builder
|
||||||
|
from: node:14.2-alpine3.11
|
||||||
|
git:
|
||||||
|
- add: /frontend
|
||||||
|
to: /app
|
||||||
|
stageDependencies:
|
||||||
|
install:
|
||||||
|
- "**/*"
|
||||||
|
excludePaths:
|
||||||
|
- Dockerfile
|
||||||
|
- build.sh
|
||||||
|
- werf.yaml
|
||||||
|
ansible:
|
||||||
|
setup:
|
||||||
|
- name: install deps
|
||||||
|
command: npm install
|
||||||
|
args:
|
||||||
|
chdir: /app
|
||||||
|
- name: Build app
|
||||||
|
command: npm run build
|
||||||
|
args:
|
||||||
|
chdir: /app
|
||||||
|
|
||||||
|
---
|
||||||
|
image: openvpn-admin
|
||||||
|
from: alpine:3.11
|
||||||
|
import:
|
||||||
|
- artifact: backend-builder
|
||||||
|
add: /app/openvpn-admin
|
||||||
|
to: /usr/bin/openvpn-admin
|
||||||
|
before: setup
|
||||||
|
- artifact: frontend-builder
|
||||||
|
add: /app/static
|
||||||
|
to: /app/static
|
||||||
|
before: setup
|
||||||
|
git:
|
||||||
|
- add: /client.conf.tpl
|
||||||
|
to: /app/client.conf.tpl
|
||||||
|
stageDependencies:
|
||||||
|
setup:
|
||||||
|
- "*"
|
||||||
|
- add: /ccd.tpl
|
||||||
|
to: /app/ccd.tpl
|
||||||
|
stageDependencies:
|
||||||
|
setup:
|
||||||
|
- "*"
|
||||||
|
ansible:
|
||||||
|
install:
|
||||||
|
- name: Install packages
|
||||||
|
apk:
|
||||||
|
name:
|
||||||
|
- easy-rsa
|
||||||
|
- bash
|
||||||
|
- name: Create symbolic link for easy-rsa
|
||||||
|
file:
|
||||||
|
src: "/usr/share/easy-rsa/easyrsa"
|
||||||
|
dest: "/usr/local/bin/easyrsa"
|
||||||
|
state: link
|
||||||
|
|
||||||
---
|
---
|
||||||
image: openvpn
|
image: openvpn
|
||||||
dockerfile: Dockerfile.openvpn
|
from: alpine:3.11
|
||||||
context: .
|
git:
|
||||||
|
- add: /.werffiles/
|
||||||
|
to: /etc/openvpn/setup/
|
||||||
|
stageDependencies:
|
||||||
|
install:
|
||||||
|
- "*"
|
||||||
|
ansible:
|
||||||
|
install:
|
||||||
|
- name: Install packages
|
||||||
|
apk:
|
||||||
|
name:
|
||||||
|
- openvpn
|
||||||
|
- easy-rsa
|
||||||
|
- name: Create symbolic link for easy-rsa
|
||||||
|
file:
|
||||||
|
src: "/usr/share/easy-rsa/easyrsa"
|
||||||
|
dest: "/usr/local/bin/easyrsa"
|
||||||
|
state: link
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user