mirror of
https://github.com/openfaas/faas.git
synced 2025-06-08 16:26:47 +00:00
Compare commits
71 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7803ea1861 | ||
|
bff2724824 | ||
|
452fde08ad | ||
|
b2a378fea4 | ||
|
16834ccbf4 | ||
|
4e20249bc0 | ||
|
4bd07e24d9 | ||
|
349c58e084 | ||
|
2fb748e03d | ||
|
ab2c34bb34 | ||
|
cfcd4f05ad | ||
|
49053feac7 | ||
|
cf8741acca | ||
|
37c02fde72 | ||
|
4e80b96d19 | ||
|
1379805240 | ||
|
546bfee9dc | ||
|
637b0b045f | ||
|
32b4117aea | ||
|
3826262779 | ||
|
3d2808354d | ||
|
65d37f2856 | ||
|
5f0fa69c2c | ||
|
b22cb639fe | ||
|
667577f3ce | ||
|
8d5dcdfa4c | ||
|
609b43b07c | ||
|
1ab3f32356 | ||
|
5c13f1f01c | ||
|
4679f27804 | ||
|
02205b8b19 | ||
|
9ba4a73d5d | ||
|
479285caf6 | ||
|
4cf5fb8369 | ||
|
ed5bd7546e | ||
|
4f4e3d288a | ||
|
d0eec5fbbf | ||
|
25e44f0b57 | ||
|
6a9ece3cc1 | ||
|
0036d6ac78 | ||
|
2a88b5d2f7 | ||
|
55776acc0d | ||
|
c3800da6fa | ||
|
472291b40b | ||
|
128b450a88 | ||
|
5c851cdf31 | ||
|
9e6f814f6f | ||
|
68ec0f59d6 | ||
|
c0d710c97f | ||
|
373a79256f | ||
|
06ade37420 | ||
|
910b8dae1b | ||
|
00613347f8 | ||
|
e0144b0573 | ||
|
4315101191 | ||
|
b4b7e2d450 | ||
|
0972fa6093 | ||
|
e44448c5dc | ||
|
bf63bbf88f | ||
|
a128df471f | ||
|
c26ec5221e | ||
|
8e1c34e222 | ||
|
21a8f0cec1 | ||
|
8d38b4befe | ||
|
1fc7bbce4e | ||
|
231e3ed426 | ||
|
fbc0ebdf4a | ||
|
4f9c61b5d2 | ||
|
a7d486eee6 | ||
|
b1ef4b49b7 | ||
|
f9245ebbb3 |
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@ -1 +1,2 @@
|
|||||||
@alexellis
|
@alexellis
|
||||||
|
@welteki
|
52
.github/workflows/build.yml
vendored
52
.github/workflows/build.yml
vendored
@ -9,20 +9,16 @@ on:
|
|||||||
- '*'
|
- '*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
build:
|
||||||
build-gateway:
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
go-version: [1.19.x]
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@master
|
||||||
with:
|
with:
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v1
|
uses: docker/setup-qemu-action@v3
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v1
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Get git commit
|
- name: Get git commit
|
||||||
id: get_git_commit
|
id: get_git_commit
|
||||||
@ -35,53 +31,15 @@ jobs:
|
|||||||
run: echo "REPO_OWNER=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" > $GITHUB_ENV
|
run: echo "REPO_OWNER=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" > $GITHUB_ENV
|
||||||
|
|
||||||
- name: Build ${{ matrix.svc }}
|
- name: Build ${{ matrix.svc }}
|
||||||
uses: docker/build-push-action@v2
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: ./gateway
|
context: ./gateway
|
||||||
file: ./gateway/Dockerfile
|
file: ./gateway/Dockerfile
|
||||||
outputs: "type=image,push=false"
|
outputs: "type=image,push=false"
|
||||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
build-args: |
|
build-args: |
|
||||||
VERSION=${{ env.TAG }}
|
VERSION=${{ env.TAG }}
|
||||||
GIT_COMMIT=${{ github.sha }}
|
GIT_COMMIT=${{ github.sha }}
|
||||||
tags: |
|
tags: |
|
||||||
ghcr.io/${{ env.REPO_OWNER }}/gateway:${{ github.sha }}
|
ghcr.io/${{ env.REPO_OWNER }}/gateway:${{ github.sha }}
|
||||||
ghcr.io/${{ env.REPO_OWNER }}/gateway:latest
|
ghcr.io/${{ env.REPO_OWNER }}/gateway:latest
|
||||||
|
|
||||||
build-auth-plugins:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
go-version: [1.19.x]
|
|
||||||
svc: [
|
|
||||||
basic-auth
|
|
||||||
]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@master
|
|
||||||
with:
|
|
||||||
fetch-depth: 1
|
|
||||||
- name: Set up QEMU
|
|
||||||
uses: docker/setup-qemu-action@v1
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v1
|
|
||||||
|
|
||||||
- name: Get git commit
|
|
||||||
id: get_git_commit
|
|
||||||
run: echo "GIT_COMMIT=$(git rev-parse HEAD)" >> $GITHUB_ENV
|
|
||||||
- name: Get version
|
|
||||||
id: get_version
|
|
||||||
run: echo "VERSION=$(git describe --tags --dirty)" >> $GITHUB_ENV
|
|
||||||
- name: Get Repo Owner
|
|
||||||
id: get_repo_owner
|
|
||||||
run: echo "REPO_OWNER=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" > $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Build ${{ matrix.svc }}
|
|
||||||
uses: docker/build-push-action@v2
|
|
||||||
with:
|
|
||||||
context: ./auth/${{ matrix.svc }}
|
|
||||||
file: ./auth/${{ matrix.svc }}/Dockerfile
|
|
||||||
outputs: "type=image,push=false"
|
|
||||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
|
||||||
tags: |
|
|
||||||
ghcr.io/${{ env.REPO_OWNER }}/${{ matrix.svc }}:${{ github.sha }}
|
|
||||||
ghcr.io/${{ env.REPO_OWNER }}/${{ matrix.svc }}:latest
|
|
||||||
|
74
.github/workflows/publish.yml
vendored
74
.github/workflows/publish.yml
vendored
@ -6,22 +6,27 @@ on:
|
|||||||
- '*'
|
- '*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
publish:
|
||||||
publish-gateway:
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
permissions:
|
||||||
matrix:
|
actions: read
|
||||||
go-version: [1.19.x]
|
checks: write
|
||||||
|
issues: read
|
||||||
|
packages: write
|
||||||
|
pull-requests: read
|
||||||
|
repository-projects: read
|
||||||
|
statuses: read
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@master
|
- uses: actions/checkout@master
|
||||||
with:
|
with:
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v1
|
uses: docker/setup-qemu-action@v3
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v1
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: Login to Docker Registry
|
- name: Login to Docker Registry
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
username: ${{ github.repository_owner }}
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@ -42,12 +47,12 @@ jobs:
|
|||||||
run: echo "REPO_OWNER=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" > $GITHUB_ENV
|
run: echo "REPO_OWNER=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" > $GITHUB_ENV
|
||||||
|
|
||||||
- name: Publish ${{ matrix.svc }}
|
- name: Publish ${{ matrix.svc }}
|
||||||
uses: docker/build-push-action@v2
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: ./gateway
|
context: ./gateway
|
||||||
file: ./gateway/Dockerfile
|
file: ./gateway/Dockerfile
|
||||||
outputs: "type=registry,push=true"
|
outputs: "type=registry,push=true"
|
||||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
build-args: |
|
build-args: |
|
||||||
VERSION=${{ env.TAG }}
|
VERSION=${{ env.TAG }}
|
||||||
GIT_COMMIT=${{ github.sha }}
|
GIT_COMMIT=${{ github.sha }}
|
||||||
@ -55,52 +60,3 @@ jobs:
|
|||||||
ghcr.io/${{ env.REPO_OWNER }}/gateway:${{ github.sha }}
|
ghcr.io/${{ env.REPO_OWNER }}/gateway:${{ github.sha }}
|
||||||
ghcr.io/${{ env.REPO_OWNER }}/gateway:${{ env.TAG }}
|
ghcr.io/${{ env.REPO_OWNER }}/gateway:${{ env.TAG }}
|
||||||
ghcr.io/${{ env.REPO_OWNER }}/gateway:latest
|
ghcr.io/${{ env.REPO_OWNER }}/gateway:latest
|
||||||
|
|
||||||
publish-auth-plugins:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
go-version: [1.19.x]
|
|
||||||
svc: [
|
|
||||||
basic-auth
|
|
||||||
]
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@master
|
|
||||||
with:
|
|
||||||
fetch-depth: 1
|
|
||||||
- name: Set up QEMU
|
|
||||||
uses: docker/setup-qemu-action@v1
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v1
|
|
||||||
- name: Login to Docker Registry
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
|
||||||
username: ${{ github.repository_owner }}
|
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
registry: ghcr.io
|
|
||||||
|
|
||||||
- name: Get TAG
|
|
||||||
id: get_tag
|
|
||||||
run: echo TAG=${GITHUB_REF#refs/tags/} >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Get git commit
|
|
||||||
id: get_git_commit
|
|
||||||
run: echo "GIT_COMMIT=$(git rev-parse HEAD)" >> $GITHUB_ENV
|
|
||||||
- name: Get version
|
|
||||||
id: get_version
|
|
||||||
run: echo "VERSION=$(git describe --tags --dirty)" >> $GITHUB_ENV
|
|
||||||
- name: Get Repo Owner
|
|
||||||
id: get_repo_owner
|
|
||||||
run: echo "REPO_OWNER=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" > $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Publish ${{ matrix.svc }}
|
|
||||||
uses: docker/build-push-action@v2
|
|
||||||
with:
|
|
||||||
context: ./auth/${{ matrix.svc }}
|
|
||||||
file: ./auth/${{ matrix.svc }}/Dockerfile
|
|
||||||
outputs: "type=registry,push=true"
|
|
||||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
|
||||||
tags: |
|
|
||||||
ghcr.io/${{ env.REPO_OWNER }}/${{ matrix.svc }}:${{ github.sha }}
|
|
||||||
ghcr.io/${{ env.REPO_OWNER }}/${{ matrix.svc }}:${{ env.TAG }}
|
|
||||||
ghcr.io/${{ env.REPO_OWNER }}/${{ matrix.svc }}:latest
|
|
||||||
|
87
ADOPTERS.md
87
ADOPTERS.md
@ -32,28 +32,40 @@ Tell us more:
|
|||||||
|
|
||||||
## Adopters list (alphabetical)
|
## Adopters list (alphabetical)
|
||||||
|
|
||||||
|
* [3fs](https://3fs.si) - 3fs is using OpenFaaS for automating repetitive development tasks like automatic rebasing, vendoring of dependencies on merge requests and many other things that make our developers lives easier
|
||||||
|
|
||||||
* [911 Security](https://www.911security.com/) - "We migrated our Python functions from AWS Lambda using automation, and now run them in airgapped environments for customers using OpenFaaS and arkade" - Scott Creager
|
* [911 Security](https://www.911security.com/) - "We migrated our Python functions from AWS Lambda using automation, and now run them in airgapped environments for customers using OpenFaaS and arkade" - Scott Creager
|
||||||
|
|
||||||
|
* [Altair Engineering](https://altair.com/) - OpenFaaS powers the customer functions capability of the IoT SaaS platform, and separately each private on-prem installation of the product.
|
||||||
|
|
||||||
* [Axa France](https://www.axa.fr) - Axa uses OpenFaaS for inference and predictions at scale using ML models - Pierre-Henri Gache
|
* [Axa France](https://www.axa.fr) - Axa uses OpenFaaS for inference and predictions at scale using ML models - Pierre-Henri Gache
|
||||||
|
|
||||||
* [3fs](https://3fs.si) - 3fs is using OpenFaaS for automating repetitive development tasks like automatic rebasing, vendoring of dependencies on merge requests and many other things that make our developers lives easier
|
|
||||||
|
|
||||||
* [Baidu](https://baidu.com) - A team within Baidu provides ML models to customers which are hosted on OpenFaaS - He Sun.
|
* [Baidu](https://baidu.com) - A team within Baidu provides ML models to customers which are hosted on OpenFaaS - He Sun.
|
||||||
|
|
||||||
* [BT](https://www.bt.com) - BT are using OpenFaaS to enable collaboration between data-scientists and developers. The teams are going from 3-years to build and deliver a PoC, to 3 months. See: [KubeCon video](https://www.youtube.com/watch?v=y77HlN2Fa-w)
|
* [BCubed Engineering](https://bcubed-corp.com) - "We use OpenFaaS to provide a serverless platform for our customers to run their code on."
|
||||||
|
|
||||||
|
* [Black.ai](https://black.ai) - video encoding, transcoding - object detection for CCTV using AI.
|
||||||
|
|
||||||
* [Breu](https://breu.io) - Breu is using OpenFaaS to build an end user monitoring solution for hybrid cloud.
|
* [Breu](https://breu.io) - Breu is using OpenFaaS to build an end user monitoring solution for hybrid cloud.
|
||||||
|
|
||||||
|
* [BT](https://www.bt.com) - BT are using OpenFaaS to enable collaboration between data-scientists and developers. The teams are going from 3-years to build and deliver a PoC, to 3 months. See: [KubeCon video](https://www.youtube.com/watch?v=y77HlN2Fa-w)
|
||||||
|
|
||||||
* [BulletProof](https://www.bulletproof.co.uk/) - Bulletproof are using OpenFaaS to build an on demand and scalable Vulnerability Scanning (VA) engine. Using OpenFaaS allows us to use compute resource efficiently yet maintain the ability to grow to meet customer scanning demands. We also like the ability to use pure docker containers to compose multiple scanning tools with different technologies into a single, coherent interface. This has reduced the time need to add new tools to the platform.
|
* [BulletProof](https://www.bulletproof.co.uk/) - Bulletproof are using OpenFaaS to build an on demand and scalable Vulnerability Scanning (VA) engine. Using OpenFaaS allows us to use compute resource efficiently yet maintain the ability to grow to meet customer scanning demands. We also like the ability to use pure docker containers to compose multiple scanning tools with different technologies into a single, coherent interface. This has reduced the time need to add new tools to the platform.
|
||||||
|
|
||||||
|
* [CDATA](https://cdata.com) - Used for background jobs and tasks such as backing up and exchanging data between systems.
|
||||||
|
|
||||||
* [Citrix](https://www.citrix.com/en-gb/) - Citrix built out a closed-source multi-tenant functions platform and UI using OpenFaaS. It is used for testing hardware devices and for automated QA testing.
|
* [Citrix](https://www.citrix.com/en-gb/) - Citrix built out a closed-source multi-tenant functions platform and UI using OpenFaaS. It is used for testing hardware devices and for automated QA testing.
|
||||||
|
|
||||||
* [Civo](https://www.civo.com) - Civo Cloud provide a 1-click Kubernetes marketplace application for OpenFaaS
|
* [Civo](https://www.civo.com) - Civo Cloud provide a 1-click Kubernetes marketplace application for OpenFaaS
|
||||||
|
|
||||||
|
* [Cloud Initiatives](https://cloudinitiatives.com) - Used for customer installations for custom functionality, and for main product providing educational course metrics.
|
||||||
|
|
||||||
* [Cognite](https://www.cognite.com) - Cognite targets heavy asset industries such as oil and gas, shipping and energy sector. They provide data integration tools that help you extract, import, and transform data from siloed source systems, and OpenFaaS is used to provide a cloud function service for heavy tasks.
|
* [Cognite](https://www.cognite.com) - Cognite targets heavy asset industries such as oil and gas, shipping and energy sector. They provide data integration tools that help you extract, import, and transform data from siloed source systems, and OpenFaaS is used to provide a cloud function service for heavy tasks.
|
||||||
|
|
||||||
* [Contiamo](https://www.contiamo.com) - data-science platform hosting jupyter notebooks and functions for multiple tenants.
|
* [Contiamo](https://www.contiamo.com) - data-science platform hosting jupyter notebooks and functions for multiple tenants.
|
||||||
|
|
||||||
|
* [Corva.ai](https://corva.ai) - "Corva is an information-sharing, collaboration-driving, and productivity-powering solution for your Drilling, Completions, Geoscience, and Sustainability teams."
|
||||||
|
|
||||||
* [DB2 Limited](https://db2.io) - mobile and web development company in Ukraine. Our internal projects using OpenFaaS functions to run customers code in Kubernetes cluster.
|
* [DB2 Limited](https://db2.io) - mobile and web development company in Ukraine. Our internal projects using OpenFaaS functions to run customers code in Kubernetes cluster.
|
||||||
|
|
||||||
* [DigitalOcean](https://www.digitalocean.com) - DigitalOcean provide a one-click droplet and a 1-click Kubernetes marketplace application for OpenFaaS
|
* [DigitalOcean](https://www.digitalocean.com) - DigitalOcean provide a one-click droplet and a 1-click Kubernetes marketplace application for OpenFaaS
|
||||||
@ -62,7 +74,7 @@ Tell us more:
|
|||||||
|
|
||||||
* [Dragonchain](https://dragonchain.com/) - "At Dragonchain, we focus on creating a hybrid blockchain-as-a-service product, with integrations of OpenFaaS as our 'smart contract' platform, to be able to automatically run customer code based on interactions that occur on the blockchain. This allows us to be extremely flexible, as customers only have to create a docker container and give it to us in order to create a 'smart contract' which can have deep integrations with our blockchain itself.". Blog: [Dragonchain & OpenFaaS](https://dragonchain.com/blog/blockchain-as-a-service-at-scale-for-enterprise)
|
* [Dragonchain](https://dragonchain.com/) - "At Dragonchain, we focus on creating a hybrid blockchain-as-a-service product, with integrations of OpenFaaS as our 'smart contract' platform, to be able to automatically run customer code based on interactions that occur on the blockchain. This allows us to be extremely flexible, as customers only have to create a docker container and give it to us in order to create a 'smart contract' which can have deep integrations with our blockchain itself.". Blog: [Dragonchain & OpenFaaS](https://dragonchain.com/blog/blockchain-as-a-service-at-scale-for-enterprise)
|
||||||
|
|
||||||
* [Edge Delta](https://www.edgedelta.com/) - "OpenFaaS powers parts of the "edge observability platform"
|
* [Edge Delta](https://www.edgedelta.com/) - "OpenFaaS powers parts of our "edge observability platform""
|
||||||
|
|
||||||
* [First Baptist Church Carrollton](https://www.fbcc.us) - "We use faasd as the backend for a Slack bot connected to our internal Slack workspace. The bot was initially created to facilitate remote question and answer sessions at our church by allowing viewers of our live stream to text or email questions in, have a staff member ask their question in the room, and then allow the staff member to send a response back to the sender. The texting is facilitated by Twilio while the email is done by interacting with a Gmail account via IMAP and SMTP."
|
* [First Baptist Church Carrollton](https://www.fbcc.us) - "We use faasd as the backend for a Slack bot connected to our internal Slack workspace. The bot was initially created to facilitate remote question and answer sessions at our church by allowing viewers of our live stream to text or email questions in, have a staff member ask their question in the room, and then allow the staff member to send a response back to the sender. The texting is facilitated by Twilio while the email is done by interacting with a Gmail account via IMAP and SMTP."
|
||||||
|
|
||||||
@ -72,42 +84,58 @@ Tell us more:
|
|||||||
|
|
||||||
* [GalaxyCard](https://www.galaxycard.in/) - "GalaxyCard is a happy user of OpenFaaS"
|
* [GalaxyCard](https://www.galaxycard.in/) - "GalaxyCard is a happy user of OpenFaaS"
|
||||||
|
|
||||||
|
* [GH Electronic GmbH](https://gselectronic.com/) - "We've been using OpenFaaS in production for over 5 years and have 30 C# functions which are used in our manufacturing process."
|
||||||
|
|
||||||
* [GMO Internet](https://www.gmo.jp/en/)
|
* [GMO Internet](https://www.gmo.jp/en/)
|
||||||
|
|
||||||
* [HelloSafe](https://hellosafe.ca/en/) - "HelloSafe is one of the leading website of financial products comparison in Canada. We're using OpenFaas on our production applications."
|
* [HelloSafe](https://hellosafe.ca/en/) - "HelloSafe is one of the leading website of financial products comparison in Canada. We're using OpenFaas on our production applications."
|
||||||
|
|
||||||
* [HPE](https://www.hpe.com/) - HPE Ezmeral is a purpose-built, hybrid cloud platform for data science and analytics workloads.
|
|
||||||
|
|
||||||
* [HM Planning Inspectorate](http://www.planninginspectorate.gov.uk) - HM Planning Inspectorate is the UK Government body responsible for dealing with planning appeals, national infrastructure planning applications, examinations of local plans and other specialist casework in England and Wales. OpenFaaS eased the communication between the new planning appeals website and the monolithic back-office application and allowed easy retries in the event of network failure.
|
* [HM Planning Inspectorate](http://www.planninginspectorate.gov.uk) - HM Planning Inspectorate is the UK Government body responsible for dealing with planning appeals, national infrastructure planning applications, examinations of local plans and other specialist casework in England and Wales. OpenFaaS eased the communication between the new planning appeals website and the monolithic back-office application and allowed easy retries in the event of network failure.
|
||||||
|
|
||||||
|
* [HPE](https://www.hpe.com/) - HPE Ezmeral is a purpose-built, hybrid cloud platform for data science and analytics workloads.
|
||||||
|
|
||||||
* [Iconscout](https://iconscout.com) - e-commerce site for stock photography and icons. OpenFaaS is used to resize images and to bundle assets for customers.
|
* [Iconscout](https://iconscout.com) - e-commerce site for stock photography and icons. OpenFaaS is used to resize images and to bundle assets for customers.
|
||||||
|
|
||||||
|
* [Infotechpartners](www.infotechpartners.be)
|
||||||
|
|
||||||
* [Ingrooves](https://ingrooves.com) - Ingrooves is a global music distribution, tech & marketing company, and OpenFaaS is a key component in its finance system for report generation, event publishing, and data ingestion.
|
* [Ingrooves](https://ingrooves.com) - Ingrooves is a global music distribution, tech & marketing company, and OpenFaaS is a key component in its finance system for report generation, event publishing, and data ingestion.
|
||||||
|
|
||||||
* [Infotechpartners](www.infotechpartners.be)
|
* [Intel.com](https://intel.com) - OpenFaaS is used within a commercial service and within the Open Source group for AI model serving.
|
||||||
|
|
||||||
* [Intraffic](https://www.intraffic.nl/) - "Using OpenFaaS for integration and callable AI/ML models for asset management."
|
* [Intraffic](https://www.intraffic.nl/) - "Using OpenFaaS for integration and callable AI/ML models for asset management."
|
||||||
|
|
||||||
* [Klar MX](https://klar.mx) - "Cuenta con Klar" - Klar provides access to credit cards in Mexico for those who have issues with credit history.
|
* [Klar MX](https://klar.mx) - "Cuenta con Klar" - Klar provides access to credit cards in Mexico for those who have issues with credit history.
|
||||||
|
|
||||||
|
* [Kubiya.ai](https://kubiya.ai) - ChatGPT-like DevOps Virtual Assistant that runs OpenFaaS functions for custom infrastructure automation and management.
|
||||||
|
|
||||||
* [LivePerson](https://www.liveperson.com/) - LivePerson extended their chat platform by allowing customers to write functions to execute in client chat flows. See [KubeCon video](https://www.youtube.com/watch?v=bt06Z28uzPA)
|
* [LivePerson](https://www.liveperson.com/) - LivePerson extended their chat platform by allowing customers to write functions to execute in client chat flows. See [KubeCon video](https://www.youtube.com/watch?v=bt06Z28uzPA)
|
||||||
|
|
||||||
|
* [Live Time Value (LTV) Co.](https://www.ltvco.com) - "Data is at the heart of what we do" - the data-science team at LTV use OpenFaaS to provide a scalable and cost-effective way to run their models in production.
|
||||||
|
|
||||||
|
* [Mercedes Benz Tech Innovation](https://mercedes-benz.com) - "We are currently using OpenFaaS as a communicative API between the vehicle app and the backend. In the future we plan to offer a service in the company, which every app developer can host an API on the OpenFaaS platform at short notice"
|
||||||
|
|
||||||
* [metaspan](https://metaspan.com) - "End-to-end blockchain solutions". metaspan ported all api endpoints from monolith express.js/sails.js to openfaas micro-functions.
|
* [metaspan](https://metaspan.com) - "End-to-end blockchain solutions". metaspan ported all api endpoints from monolith express.js/sails.js to openfaas micro-functions.
|
||||||
|
|
||||||
* [MoneyLion](https://www.moneylion.com/)
|
* [MoneyLion](https://www.moneylion.com/)
|
||||||
|
|
||||||
* [Naamio](https://naamio.cloud/) - "Naamio are providing an event-based serverless API to developers to enable rapid development of decentralized applications on the cloud. By providing progressive enhancement within the developer tools, OpenFaaS has enabled Naamio to go from clustered Docker container deployments with REST APIs using Kubernetes, to load balanced deployable functions over an open event queue interface. It was key to enabling a standard multilingual development kit across cloud providers."
|
* [Naamio](https://naamio.cloud/) - "Naamio are providing an event-based serverless API to developers to enable rapid development of decentralized applications on the cloud. By providing progressive enhancement within the developer tools, OpenFaaS has enabled Naamio to go from clustered Docker container deployments with REST APIs using Kubernetes, to load balanced deployable functions over an open event queue interface. It was key to enabling a standard multilingual development kit across cloud providers."
|
||||||
|
|
||||||
* [Neoskop](https://www.neoskop.de) - Neoskop is using OpenFAAS in production to provide our developers with a self-service platform for backend functionality and thereby our customers agile and rapid feature development.
|
* [Neoskop](https://www.neoskop.de) - Neoskop is using OpenFaaS in production to provide our developers with a self-service platform for backend functionality and thereby our customers agile and rapid feature development.
|
||||||
|
|
||||||
* [Nexylan](nexylan.com/) - "We are a French professional hoster that use OpenFaaS in dev and production inside our private extranet. We use OpenFaaS to split our historic monolith project and then simplify development/maintainability and speed up development times."
|
* [Nexylan](nexylan.com/) - "We are a French professional host that use OpenFaaS in dev and production inside our private extranet. We use OpenFaaS to split our historic monolith project and then simplify development/maintainability and speed up development times."
|
||||||
|
|
||||||
* [NGC](https://www.ngcsoftware.com/)
|
* [NGC](https://www.ngcsoftware.com/)
|
||||||
|
|
||||||
* [Northwestern Mutual](https://www.northwesternmutual.com/) - "OpenFaaS is a great platform and Alex and team are a great resource. They will work very diligently with your team to help you get the most out of OpenFaaS, and he will always be able to provide valuable insight into issues that a team might face while developing software for the cloud." Kieran Gordon
|
* [Northwestern Mutual](https://www.northwesternmutual.com/) - "OpenFaaS is a great platform and Alex and team are a great resource. They will work very diligently with your team to help you get the most out of OpenFaaS, and he will always be able to provide valuable insight into issues that a team might face while developing software for the cloud." Kieran Gordon
|
||||||
|
|
||||||
|
* [Optiv](https://optiv.com) - Cyber Security Solutions
|
||||||
|
|
||||||
|
* [Outsystems](https://outsystems.com) - "In my team, we're using OpenFaaS to help the orchestration of our CD pipelines. From a high-level perspective, we have a NATS cluster and the OpenFaaS functions subscribing to NATS topics and reacting to them. Our functions are doing some work related to the pipeline, like saving data to the database, sending Slack messages, or just returning something from the database." (Marco Alves)
|
||||||
|
|
||||||
* [P. A. Media Group](https://pamediagroup.com/) - "We use OpenFaaS to orchestrate Terraform and Jenkins jobs for our internal infrastructure provisioning" - Rob Stonham
|
* [P. A. Media Group](https://pamediagroup.com/) - "We use OpenFaaS to orchestrate Terraform and Jenkins jobs for our internal infrastructure provisioning" - Rob Stonham
|
||||||
|
|
||||||
|
* [Patchworks Integration Limited](https://www.wearepatchworks.com) - Ecommerce integrations made easy - functions provide custom enrichment for data and integrations with third-party APIs. Customers can provide their own PHP code to execute in a sandboxed environment.
|
||||||
|
|
||||||
* [PathfinderZA](https://www.pathfinderza.com) - PathfinderZA is an IOT security firm selling underground sensors that transmits warnings to users if a person or vehicle goes past it. We're using OpenFaas, with Dockerised functions written in Java (Quarkus) and Rust (Actix/Rocket-RS).
|
* [PathfinderZA](https://www.pathfinderza.com) - PathfinderZA is an IOT security firm selling underground sensors that transmits warnings to users if a person or vehicle goes past it. We're using OpenFaas, with Dockerised functions written in Java (Quarkus) and Rust (Actix/Rocket-RS).
|
||||||
|
|
||||||
* [Pentium Network](https://www.pentium.network/)
|
* [Pentium Network](https://www.pentium.network/)
|
||||||
@ -120,11 +148,13 @@ Tell us more:
|
|||||||
|
|
||||||
* [Pypestream](https://www.pypestream.com) - "We have just migrated 50 of our customers from Kubeless, which is now deprecated to OpenFaaS" - Antoine Hamon
|
* [Pypestream](https://www.pypestream.com) - "We have just migrated 50 of our customers from Kubeless, which is now deprecated to OpenFaaS" - Antoine Hamon
|
||||||
|
|
||||||
* [Outsystems](https://outsystems.com) - "In my team, we're using OpenFaaS to help the orchestration of our CD pipelines. From a high-level perspective, we have a NATS cluster and the OpenFaaS functions subscribing to NATS topics and reacting to them. Our functions are doing some work related to the pipeline, like saving data to the database, sending Slack messages, or just returning something from the database." (Marco Alves)
|
* [Rapid Circle](https://www.rapidcircle.com) is using OpenFaaS within a Azure Kubernetes cluster to host a large amount of micro-services aiming at automating core activities of their Microsoft 365 Cloud Managed Services offering. Robustness, speed, scalable and simplicity have been major reasons to favor OpenFaaS over Azure Functions.
|
||||||
|
|
||||||
* [Ratehub](https://www.ratehub.ca) - Ratehub is Canada's leading personal finance comparison site. We're breaking apart our monolithic PHP and Java codebases into Node, PHP and Java OpenFaaS functions; there's not much that we don't plan on moving to FaaS!
|
* [Ratehub](https://www.ratehub.ca) - Ratehub is Canada's leading personal finance comparison site. We're breaking apart our monolithic PHP and Java codebases into Node, PHP and Java OpenFaaS functions; there's not much that we don't plan on moving to FaaS!
|
||||||
|
|
||||||
* [Rapid Circle](https://www.rapidcircle.com) is using OpenFaaS within a Azure Kubernetes cluster to host a large amount of micro-services aiming at automating core activities of their Microsoft 365 Cloud Managed Services offering. Robustness, speed, scalable and simplicity have been major reasons to favor OpenFaaS over Azure Functions.
|
* [skyslope.com](https://skyslope.com) - "We process millions of documents per day and moved from AWS Lambda to Kubernetes. We estimate that OpenFaaS has saved us 60,000 USD each year over the past three years that we've been running it in our business" - Derrick Martinez
|
||||||
|
|
||||||
|
* [smashHit](https://smashhit.eu) - smashHit is a project funded by the European Union's Horizon 2020 research and innovation programme under grant agreement No. 871477. The objective of smashHit is to assure trusted and secure sharing of data streams from both personal and industrial platforms, needed to build sectorial and cross-sectorial services, by establishing a Framework for processing of data owner consent and legal rules (GDPR) and effective contracting, as well as joint security and privacy-preserving mechanisms. We are utilising OpenFaaS to support the need for scalable processing through the use of functions.
|
||||||
|
|
||||||
* [Sprucee](https://spruce.casa) - We use [faasd](https://github.com/openfaas/faasd) as part of our base Encryption as a Service platform which were manually managed docker containers. As NATS based platform we were able to scale to every size we want, but deployment takes many labor time as we need to deal with OS level and customer limitations. Now we can use "faas install/up" to accomplish 80% of deployment effort.
|
* [Sprucee](https://spruce.casa) - We use [faasd](https://github.com/openfaas/faasd) as part of our base Encryption as a Service platform which were manually managed docker containers. As NATS based platform we were able to scale to every size we want, but deployment takes many labor time as we need to deal with OS level and customer limitations. Now we can use "faas install/up" to accomplish 80% of deployment effort.
|
||||||
|
|
||||||
@ -132,33 +162,54 @@ Tell us more:
|
|||||||
|
|
||||||
* [SURFsara IoT Platform for Sensemakers](https://github.com/sensemakersamsterdam/sensemakers-iot-platform) - The SURFsara IoT Platform for Sensemakers is a platform for storing, monitoring, visualising and analyzing sensor data. It is a collaboration platform designed to host multiple projects carried by the Sensemakers community. In addition, there is a project dedicated to experimentation, available for everyone to use. All data within the platform is shared. OpenFaaS serverless functions give access to the platform through an HTTP entry point, take care of the metadata extraction and enable custom event-driven actions.
|
* [SURFsara IoT Platform for Sensemakers](https://github.com/sensemakersamsterdam/sensemakers-iot-platform) - The SURFsara IoT Platform for Sensemakers is a platform for storing, monitoring, visualising and analyzing sensor data. It is a collaboration platform designed to host multiple projects carried by the Sensemakers community. In addition, there is a project dedicated to experimentation, available for everyone to use. All data within the platform is shared. OpenFaaS serverless functions give access to the platform through an HTTP entry point, take care of the metadata extraction and enable custom event-driven actions.
|
||||||
|
|
||||||
* [skyslope.com](https://skyslope.com) - "We process millions of documents per day and moved from AWS Lambda to Kubernetes. We estimate that OpenFaaS has saved us 60,000 USD each year over the past three years that we've been running it in our business" - Derrick Martinez
|
* [Surge](https://www.workwithsurge.com) - Lending Platform and Salesforce integrations
|
||||||
|
|
||||||
|
* [TeamViewer.com](https://teamviewer.com) - "TeamViewer users OpenFaaS across several clusters"
|
||||||
|
|
||||||
|
* [T-Mobile](https://www.t-mobile.com/) - T-Mobile is a global mobile network that provides mobile data, voice and text services to consumers and businesses.
|
||||||
|
|
||||||
* [Transmute Industries](https://www.transmute.industries/) - "At Transmute we use OpenFaaS to develop identity and access integrations leveraging decentralized identities that integrate with legacy IAM systems. OpenFaaS helps Transmute and our customers avoid vendor lock in, encourages modularity, and helps us rapidly develop and release integrations for customers."
|
* [Transmute Industries](https://www.transmute.industries/) - "At Transmute we use OpenFaaS to develop identity and access integrations leveraging decentralized identities that integrate with legacy IAM systems. OpenFaaS helps Transmute and our customers avoid vendor lock in, encourages modularity, and helps us rapidly develop and release integrations for customers."
|
||||||
|
|
||||||
* [Traversals](https://traversals.com/) - At Traversals, we use OpenFaaS for processing of incoming data. We take benefit from various programming languages available in OpenFaaS.
|
* [Traversals](https://traversals.com/) - At Traversals, we use OpenFaaS for processing of incoming data. We take benefit from various programming languages available in OpenFaaS.
|
||||||
|
|
||||||
* [T-Mobile](https://www.t-mobile.com/) - T-Mobile is a global mobile network that provides mobile data, voice and text services to consumers and businesses.
|
|
||||||
|
|
||||||
* [UStore](http://ustore.com.br/) - "We're using OpenFaaS in production"
|
* [UStore](http://ustore.com.br/) - "We're using OpenFaaS in production"
|
||||||
|
|
||||||
* [Very Good Security](https://www.verygoodsecurity.com) - VGS uses OpenFaaS to build a solid foundation for the development, deployment, and execution of custom logic on customer payloads as part of their secure compute platform.
|
* [Very Good Security](https://www.verygoodsecurity.com) - VGS uses OpenFaaS to build a solid foundation for the development, deployment, and execution of custom logic on customer payloads as part of their secure compute platform.
|
||||||
|
|
||||||
* [Vision Banco SAECA](https://www.visionbanco.com) - self-service home banking portal and asynchronous report/PDF generation. See: [KubeCon Video](https://www.youtube.com/watch?v=mPjI34qj5vU&t=1417s)
|
|
||||||
|
|
||||||
* [Virality](https://www.virality.de/)
|
* [Virality](https://www.virality.de/)
|
||||||
|
|
||||||
|
* [Vision Banco SAECA](https://www.visionbanco.com) - self-service home banking portal and asynchronous report/PDF generation. See: [KubeCon Video](https://www.youtube.com/watch?v=mPjI34qj5vU&t=1417s)
|
||||||
|
|
||||||
* [VMware](https://vmware.com)
|
* [VMware](https://vmware.com)
|
||||||
* Used in "veba" VMware Event Broker Appliance to extend vSphere by adding event functionality. OpenFaaS functions and the vcenter-connector are used as an appliance.
|
* Used in "veba" VMware Event Broker Appliance to extend vSphere by adding event functionality. OpenFaaS functions and the vcenter-connector are used as an appliance.
|
||||||
* CAS / vRA8 - The Cloud Automation Services product has an option to deploy "FaaS on-premises", this actually deploys OpenFaaS white-boxed / white-labelled. [CAS Write-up from Swisscom](https://ict.swisscom.ch/2019/08/cloud-automation-services-on-prem-faas-provider-for-vsphere/)
|
* CAS / vRA8 - The Cloud Automation Services product has an option to deploy "FaaS on-premises", this actually deploys OpenFaaS white-boxed / white-labelled. [CAS Write-up from Swisscom](https://ict.swisscom.ch/2019/08/cloud-automation-services-on-prem-faas-provider-for-vsphere/)
|
||||||
* OpenFaaS is also repackaged as "Automation Extensibility" in the ["vRO" product](https://vnuggets.com/2019/08/16/cloud-assembly-extensibility-with-abx-faas-part1/). [See an example](https://vnuggets.com/2019/08/19/cloud-assembly-extensibility-with-abx-faas-part3/)
|
* OpenFaaS is also repackaged as "Automation Extensibility" in the ["vRO" product](https://vnuggets.com/2019/08/16/cloud-assembly-extensibility-with-abx-faas-part1/). [See an example](https://vnuggets.com/2019/08/19/cloud-assembly-extensibility-with-abx-faas-part3/)
|
||||||
|
|
||||||
|
* [VNourdin](https://www.vnourdin.dev) - I am a French web developer working with the Jamstack, using 11ty and faasd. I started with faasd as I wanted to make it work on my small VPS, but as I do more and more projects relying on OpenFaaS, I'll probably switch to a K8s cluster to gain scalability.
|
||||||
|
|
||||||
* [Waylay](https://www.waylay.io) - We use OpenFaaS to deploy small snippets of code that can be combined in a low-code manner by our clients to do data orchestration and automation. Users of the platform also are able to deploy their own plugins (written in multiple languages), which also get deployed on OpenFaas.
|
* [Waylay](https://www.waylay.io) - We use OpenFaaS to deploy small snippets of code that can be combined in a low-code manner by our clients to do data orchestration and automation. Users of the platform also are able to deploy their own plugins (written in multiple languages), which also get deployed on OpenFaas.
|
||||||
|
|
||||||
* [Wireline.io](https://wireline.io) - portable functions that can run on any hardware, indexed through blockchain.
|
* [Wireline.io](https://wireline.io) - portable functions that can run on any hardware, indexed through blockchain.
|
||||||
|
|
||||||
|
* [WorldQuant](https://worldquant.com) - Using OpenFaaS as part of WorldQuant's solutions.
|
||||||
|
|
||||||
|
* [Yokogawa Electric](https://en.wikipedia.org/wiki/Yokogawa_Electric)
|
||||||
|
|
||||||
* [Ytel](https://www.ytel.com) - Ytel are a Google Cloud customer and deployed OpenFaaS vs. the vendor alternative due to its wide range of templates, Dockerfile support and easier access to services within the VPC. The Dockerfile template allowed for easy migration of existing code. The latency of transactions for customers during purchase process was reduced by offloading synchronous code to NATS which is built into OpenFaaS. OpenFaaS also allowed "hot path" code to be refactored from large services into multiple functions, to take advantage of horizontal scaling.
|
* [Ytel](https://www.ytel.com) - Ytel are a Google Cloud customer and deployed OpenFaaS vs. the vendor alternative due to its wide range of templates, Dockerfile support and easier access to services within the VPC. The Dockerfile template allowed for easy migration of existing code. The latency of transactions for customers during purchase process was reduced by offloading synchronous code to NATS which is built into OpenFaaS. OpenFaaS also allowed "hot path" code to be refactored from large services into multiple functions, to take advantage of horizontal scaling.
|
||||||
|
|
||||||
* [smashHit](https://smashhit.eu) - smashHit is a project funded by the European Union's Horizon 2020 research and innovation programme under grant agreement No. 871477. The objective of smashHit is to assure trusted and secure sharing of data streams from both personal and industrial platforms, needed to build sectorial and cross-sectorial services, by establishing a Framework for processing of data owner consent and legal rules (GDPR) and effective contracting, as well as joint security and privacy-preserving mechanisms. We are utilising OpenFaaS to support the need for scalable processing through the use of functions.
|
|
||||||
|
|
||||||
See the top of the file for how to participate.
|
See the top of the file for how to participate.
|
||||||
|
|
||||||
|
## Appendix
|
||||||
|
|
||||||
|
### Sorting sections
|
||||||
|
|
||||||
|
Adopeters list should be sorted after it's been updated, here's how you can do that with bash.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat | sort --ignore-case
|
||||||
|
# Copy / paste
|
||||||
|
|
||||||
|
# Control + D
|
||||||
|
```
|
||||||
|
|
||||||
|
Please note, for few vendors multiple use case has been listed under same vendor. Hence, the output need to be compared with content in document before updating the document.
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
# Contributing
|
# Contributing guidelines
|
||||||
|
|
||||||
## Guidelines
|
These are the guidelines for contributing to OpenFaaS Community Edition (CE) and faasd components.
|
||||||
|
|
||||||
Guidelines for contributing.
|
OpenFaaS Standard and OpenFaaS For Enterprises are commercial software, and maintained solely by employees of OpenFaaS Ltd.
|
||||||
|
|
||||||
### First impressions - introducing yourself and your use-case
|
Customers can provide feedback via the [openfaas/customers](https://github.com/openfaas/customers) repository
|
||||||
|
|
||||||
One of the best ways to participate within a new open source communities is to introduce yourself and your use-case. This builds goodwill, but also means the community can start to understand your needs and how best to help you.
|
## First impressions - introducing yourself and your use-case
|
||||||
|
|
||||||
|
One of the best ways to participate within a new open source community is to introduce yourself and your use-case. This builds goodwill, but also means the community can start to understand your needs and how best to help you.
|
||||||
|
|
||||||
Given that the community is made up of volunteers, making a good first impression is important to getting their ear and attention.
|
Given that the community is made up of volunteers, making a good first impression is important to getting their ear and attention.
|
||||||
|
|
||||||
@ -31,7 +33,7 @@ The primary ways to engage with the community are via GitHub Issues and [Enterpr
|
|||||||
|
|
||||||
See also: [The no-excuses guide to introducing yourself to a new open source project](https://opensource.com/education/13/7/introduce-yourself-open-source-project)
|
See also: [The no-excuses guide to introducing yourself to a new open source project](https://opensource.com/education/13/7/introduce-yourself-open-source-project)
|
||||||
|
|
||||||
### How can I get involved?
|
## How can I get involved?
|
||||||
|
|
||||||
There are a number of areas where contributions can be accepted:
|
There are a number of areas where contributions can be accepted:
|
||||||
|
|
||||||
@ -49,17 +51,19 @@ There are a number of areas where contributions can be accepted:
|
|||||||
|
|
||||||
This is just a short list of ideas, if you have other ideas for contributing please make a suggestion.
|
This is just a short list of ideas, if you have other ideas for contributing please make a suggestion.
|
||||||
|
|
||||||
### I want to contribute on GitHub
|
If you'd like help getting involved, [join our weekly community call on Zoom](https://docs.openfaas.com/community).
|
||||||
|
|
||||||
#### I've found a security issue
|
## I want to contribute on GitHub
|
||||||
|
|
||||||
Please follow [responsible disclosure practices](https://en.wikipedia.org/wiki/Responsible_disclosure) and send an email to support@openfaas.com. Bear in mind that instructions on how to reproduce the issue are key to proving an issue exists, and getting it resolved. Suggested solutions are also weclome.
|
### I've found a security issue
|
||||||
|
|
||||||
#### I've found a typo
|
Please follow [responsible disclosure practices](https://en.wikipedia.org/wiki/Responsible_disclosure) and send an email to support@openfaas.com. Bear in mind that instructions on how to reproduce the issue are key to proving an issue exists, and getting it resolved.
|
||||||
|
|
||||||
|
### I've found a typo
|
||||||
|
|
||||||
* A Pull Request is not necessary. Raise an [Issue](https://github.com/openfaas/faas/issues) and we'll fix it as soon as we can.
|
* A Pull Request is not necessary. Raise an [Issue](https://github.com/openfaas/faas/issues) and we'll fix it as soon as we can.
|
||||||
|
|
||||||
#### I have a (great) idea
|
### I have a (great) idea
|
||||||
|
|
||||||
The OpenFaaS maintainers would like to make OpenFaaS the best it can be and welcome new contributions that align with the project's goals. Our time is limited so we'd like to make sure we agree on the proposed work before you spend time doing it. Saying "no" is hard which is why we'd rather say "yes" ahead of time. You need to raise a proposal.
|
The OpenFaaS maintainers would like to make OpenFaaS the best it can be and welcome new contributions that align with the project's goals. Our time is limited so we'd like to make sure we agree on the proposed work before you spend time doing it. Saying "no" is hard which is why we'd rather say "yes" ahead of time. You need to raise a proposal.
|
||||||
|
|
||||||
@ -84,7 +88,7 @@ If you are proposing a new tool or service please do due diligence. Does this to
|
|||||||
|
|
||||||
Every effort will be made to work with contributors who do not follow the process. Your PR may be closed or marked as `invalid` if it is left inactive, or the proposal cannot move into a `design/approved` status.
|
Every effort will be made to work with contributors who do not follow the process. Your PR may be closed or marked as `invalid` if it is left inactive, or the proposal cannot move into a `design/approved` status.
|
||||||
|
|
||||||
#### Paperwork for Pull Requests
|
### Paperwork for Pull Requests
|
||||||
|
|
||||||
Please read this whole guide and make sure you agree to the Developer Certificate of Origin (DCO) agreement (included below):
|
Please read this whole guide and make sure you agree to the Developer Certificate of Origin (DCO) agreement (included below):
|
||||||
|
|
||||||
@ -95,7 +99,7 @@ Please read this whole guide and make sure you agree to the Developer Certificat
|
|||||||
* Always give instructions for testing
|
* Always give instructions for testing
|
||||||
* Provide us CLI commands and output or screenshots where you can
|
* Provide us CLI commands and output or screenshots where you can
|
||||||
|
|
||||||
##### Commit messages
|
#### Commit messages
|
||||||
|
|
||||||
The first line of the commit message is the *subject*, this should be followed by a blank line and then a message describing the intent and purpose of the commit. These guidelines are based upon a [post by Chris Beams](https://chris.beams.io/posts/git-commit/).
|
The first line of the commit message is the *subject*, this should be followed by a blank line and then a message describing the intent and purpose of the commit. These guidelines are based upon a [post by Chris Beams](https://chris.beams.io/posts/git-commit/).
|
||||||
|
|
||||||
@ -178,47 +182,44 @@ defer goleak.VerifyNoLeaks(t)
|
|||||||
|
|
||||||
at the very beginning of the test, and it will fail the test if it detects goroutines that were opened but never cleaned up at the end of the test.
|
at the very beginning of the test, and it will fail the test if it detects goroutines that were opened but never cleaned up at the end of the test.
|
||||||
|
|
||||||
#### I have a question, a suggestion or need help
|
#### I need to add a dependency
|
||||||
|
|
||||||
|
All projects use [Go modules](https://github.com/golang/go/wiki/Modules) and vendoring. The concept of `vendoring` is still broadly used in projects written in Go. This means that a copy of the source-code of dependencies is stored within each repository in the `vendor` folder. It allows for a repeatable build and isolates change.
|
||||||
|
|
||||||
|
Components must be licensed with an MIT, BSD, or Apache 2.0 license. We may ask you to write your own code when dependencies are trivial, or unmaintained by their authors.
|
||||||
|
|
||||||
|
### I have a question, a suggestion or need help
|
||||||
|
|
||||||
If you have a deeply technical request or need help debugging your application then you should prepare a simple, public GitHub repository with the minimum amount of code required to reproduce the issue.
|
If you have a deeply technical request or need help debugging your application then you should prepare a simple, public GitHub repository with the minimum amount of code required to reproduce the issue.
|
||||||
|
|
||||||
If you feel there is an issue with OpenFaaS or were unable to get the help you needed from the GitHub, [then send us an email](https://openfaas.com/support/)
|
|
||||||
|
|
||||||
#### Setting expectations, support and SLAs
|
#### Setting expectations, support and SLAs
|
||||||
|
|
||||||
* What kind of support can I expect for free?
|
* What kind of support can I expect?
|
||||||
|
|
||||||
OpenFaaS is licensed in a way that enables you to use the source code in or with your project or product.
|
OpenFaaS Standard customers have self-service support, and can directly contact the OpenFaaS Ltd team via the [openfaas/customers](https://github.com/openfaas/customers) repository using Discussions.
|
||||||
|
|
||||||
If you are using one of the Open Source projects within the openfaas or openfaas-incubator repository, then help may be offered on a limited, good-will basis by volunteers, but if you are a commercial user, you will need to purchase support for timely help.
|
Support is only offered to free users to fix bugs and issues in the codebase, where the full Issue Template is filled out with sufficient instructions to reproduce the issue. We will not debug your application, or comment on your architecture on GitHub.
|
||||||
|
|
||||||
Please be respectful of any time given to you and your needs. The person you are requesting help from may not reside in your timezone and contacting them via direct message is inappropriate.
|
|
||||||
|
|
||||||
Enterprise support is the best place to ask questions, suggest features, and to get help. The GitHub issue tracker can be used for suspected issues with the codebase or deployment artifacts. The whole template must be filled out in detail.
|
* Can we talk to you in person?
|
||||||
|
|
||||||
* Doesn't Open Source mean that everything is free?
|
There is a weekly Zoom call for any free user or customer to attend, topics are taken at the beginning of the call, and we will strive to give everyone time to talk.
|
||||||
|
|
||||||
The OpenFaaS projects are licensed as MIT which means that you are free to use, modify and distribute the software within the terms of the license.
|
|
||||||
|
|
||||||
Contributions, suggestions and feedback is welcomed in the appropriate channels as outlined in this guide. The MIT license does not cover support for PRs, Issues, Technical
|
|
||||||
Support questions, feature requests and technical support/professional services which you may require; the preceding are not free and have a cost to those providing the services. Where possible, this time may be volunteered for free, but it is not unlimited.
|
|
||||||
|
|
||||||
* What is the SLA for my Issue?
|
* What is the SLA for my Issue?
|
||||||
|
|
||||||
Issues are examined, triaged and answered on a best effort basis by volunteers and community contributors. This means that you may receive an initial response within any time period such as: 1 minute, 1 hour, 1 day, or 1 week. There is no implicit meaning to the time between you raising an issue and it being answered or resolved.
|
Issues are examined, triaged and answered on a best effort basis by volunteers and community contributors. This means that you may receive an initial response within any time period such as: 1 minute, 1 hour, 1 day, or 1 week. There is no implicit meaning to the time between you raising an issue and it being answered or resolved.
|
||||||
|
|
||||||
If you see an issue which does not have a response or does not have a resolution, it does not mean that it is not important, or that it is being ignored. It simply means it has not been worked on by a volunteer yet.
|
If you see an issue which does not have a response or does not have a resolution, it does not mean that it is not important, or that it is being ignored. It simply means it has not been worked on yet, or may have been missed.
|
||||||
|
|
||||||
Please take responsibility for following up on your Issues if you feel further action is required.
|
Please take responsibility for following up on your Issues if you feel further action is required.
|
||||||
|
|
||||||
If you are a business using OpenFaaS and need timely and attentive responses, then you should purchase Enterprise Support from OpenFaaS Ltd.
|
If you're an OpenFaaS customer, then you will have a direct line of communication with the OpenFaaS Ltd team, feel free to reach out for an update.
|
||||||
|
|
||||||
* What is the SLA for my Pull Request?
|
* What is the SLA for my Pull Request?
|
||||||
|
|
||||||
In a similar way to Issues, Pull Requests are triaged, reviewed, and considered by a team of volunteers - the Core Team, Members Team and the Project Lead. There are dozens of components that make up the OpenFaaS project and a limited amount of people. Sometimes PRs may become blocked or require further action.
|
In a similar way to Issues, Pull Requests are triaged, reviewed, and considered by a team of volunteers - the Core Team, Members Team and the Project Lead. There are dozens of components that make up the OpenFaaS project and a limited amount of people. Sometimes PRs may become blocked or require further action.
|
||||||
|
|
||||||
Please take responsibility for following up on your Pull Requests if you feel further action is required.
|
Please take responsibility for following up on your Pull Requests if you feel further action is required.
|
||||||
|
|
||||||
* Why may your PR be delayed?
|
* Why may your PR be delayed?
|
||||||
|
|
||||||
* The contributing guide was not followed in some way
|
* The contributing guide was not followed in some way
|
||||||
@ -229,25 +230,19 @@ If you feel there is an issue with OpenFaaS or were unable to get the help you n
|
|||||||
|
|
||||||
* Changes have been requested
|
* Changes have been requested
|
||||||
|
|
||||||
More information, a use-case, or context may be required for the change to be accepted.
|
* The PR is low priority or low impact
|
||||||
|
|
||||||
|
In addition, more information, a use-case, or context may be required for the change to be accepted.
|
||||||
|
|
||||||
* What if I am a GitHub Sponsor?
|
* What if I am a GitHub Sponsor?
|
||||||
|
|
||||||
If you [sponsor OpenFaaS on GitHub](https://github.com/sponsors/openfaas), then you will show up as a Sponsor on your issues and PRs which is one way to show your support for the community and project. Whilst the entry-level sponsorship is only 25 USD / mo, you will benefit from access to regular updates on project development via the [Treasure Trove portal](https://faasd.exit.openfaas.pro/function/trove/). Your company can also take up a GitHub Sponsorship using their GitHub organisation's existing billing relationship.
|
If you [sponsor OpenFaaS on GitHub](https://github.com/sponsors/openfaas), then you will show up as a Sponsor on your issues and PRs which is one way to show your support for the community and project. Thank you for your contribution.
|
||||||
|
|
||||||
|
Most sponsors are individuals, not corporations. But if your organisation can also take up a GitHub Sponsorship using their GitHub organisation's existing billing relationship.
|
||||||
|
|
||||||
* What if I need more than that?
|
* What if I need more?
|
||||||
|
|
||||||
If you're a company using any of these projects, you can get the following through an [Enterprise Support agreement with OpenFaaS Ltd](https://openfaas.com/support/) so that the time and resources required to support your business are paid for.
|
[Check out the options for self-service and enterprise support](https://openfaas.com/pricing/).
|
||||||
|
|
||||||
A support agreement can be tailored to your needs, you may benefit from support, if you need any of the following:
|
|
||||||
|
|
||||||
* security issues patched in a timely manner for all 40 +/- open source components
|
|
||||||
* priority responses to issues/PRs
|
|
||||||
* immediate help and access to experts
|
|
||||||
|
|
||||||
#### I need to add a dependency
|
|
||||||
|
|
||||||
All projects use [Go modules](https://github.com/golang/go/wiki/Modules) and vendoring. The concept of `vendoring` is still broadly used in projects written in Go. This means that a copy of the source-code of dependencies is stored within each repository in the `vendor` folder. It allows for a repeatable build and isolates change.
|
|
||||||
|
|
||||||
### How are releases made?
|
### How are releases made?
|
||||||
|
|
||||||
@ -302,8 +297,10 @@ Core Team attend all project meetings and calls. Allowances will be made for tim
|
|||||||
|
|
||||||
The Core Team includes:
|
The Core Team includes:
|
||||||
|
|
||||||
- Alex Ellis (@alexellis) - Lead
|
- Alex Ellis (@alexellis) - Founder, OpenFaaS Ltd
|
||||||
- Lucas Roesler (@LucasRoesler) - SME for logs, provider model and secrets
|
- Han Verstraete (@welteki) - Junior Software Developer, OpenFaaS Ltd
|
||||||
|
- Lucas Roesler (@LucasRoesler) - SME for logs, provider model and secrets. Lead Developer @ Contiamo
|
||||||
|
- Nitishkumar Singh (@nitishkumar71) - Senior Engineer, CTO.ai
|
||||||
|
|
||||||
#### Members Team
|
#### Members Team
|
||||||
|
|
||||||
@ -389,7 +386,9 @@ See also: [OpenFaaS Pro](https://docs.openfaas.com/openfaas-pro/introduction/)
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This project is licensed under the MIT License.
|
All third-party contributions are licensed under the MIT license, all OpenFaaS Ltd contributions are licensed under the [OpenFaaS CE EULA](https://github.com/openfaas/faas/blob/master/EULA.md).
|
||||||
|
|
||||||
|
OpenFaaS Standard and OpenFaaS for Enterprises are proprietary and binaries are licensed under the commercial [OpenFaaS Pro EULA](https://github.com/openfaas/faas/blob/master/pro/EULA.md).
|
||||||
|
|
||||||
### Copyright notice
|
### Copyright notice
|
||||||
|
|
||||||
@ -398,7 +397,7 @@ It is important to state that you retain copyright for your contributions, but a
|
|||||||
Please add a Copyright notice to new files you add where this is not already present.
|
Please add a Copyright notice to new files you add where this is not already present.
|
||||||
|
|
||||||
```
|
```
|
||||||
// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved.
|
// Copyright (c) OpenFaaS Author(s) 2023. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
65
EULA.md
Normal file
65
EULA.md
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
End User License Agreement (EULA) for OpenFaaS Community Edition
|
||||||
|
|
||||||
|
Licensed Software. OpenFaaS Community Edition is provided as free software under this End User License Agreement (EULA). This EULA applies to all source code, tooling, documentation, configuration, binaries, and container images produced by OpenFaaS Ltd 2017, 2019-2024. Any third-party contributions included in OpenFaaS Community Edition (CE) are licensed under the MIT License.
|
||||||
|
|
||||||
|
1.1 Software Ownership. All available artifacts that comprise "OpenFaaS" (gateway, faasd, faas-netes, queue-worker, etc) including code, documentation, configuration, designs, binaries and container images are the sole property and copyright of OpenFaaS Ltd.
|
||||||
|
|
||||||
|
1.2 Use Restrictions. Commercial use of the OpenFaaS Community Edition is limited to one installation per company and to a period not exceeding 60 days. The software cannot be resold, distributed to, or installed for a client for commercial purposes.
|
||||||
|
|
||||||
|
Your Agreement. By accessing, executing, or otherwise using the OpenFaaS Community Edition, you ("Customer") acknowledge that you have read this Agreement, understand it, and agree to be bound by its terms and conditions. If you are not willing to be bound by the terms of this Agreement, do not access or use the OpenFaaS Community Edition.
|
||||||
|
|
||||||
|
2.1 Entity Representation. If you are using the OpenFaaS Community Edition in your capacity as an employee or agent of a company or organization, any references to “you” in this Agreement shall refer to such entity and not to you in your personal capacity. You warrant that you are authorized to legally bind the company or organization on whose behalf you are accessing the OpenFaaS Community Edition.
|
||||||
|
|
||||||
|
2.2 Agreement Parties. This Agreement is between You ("Customer") and OpenFaaS Ltd. ("Supplier").
|
||||||
|
|
||||||
|
2.3 Governing Law. This Agreement shall be governed by, and construed in accordance with, the laws of England and Wales.
|
||||||
|
|
||||||
|
2.4 Entire Agreement and Supersession.
|
||||||
|
|
||||||
|
This Agreement, together with any referenced Order Form, forms the entire agreement between the Customer and OpenFaaS Ltd. regarding the Licensed Software, superseding all prior or existing agreements, including any purchase order (PO) terms submitted by the Customer. Any PO T&Cs are void and replaced by this Agreement unless OpenFaaS Ltd. agrees otherwise in writing.
|
||||||
|
|
||||||
|
License Grant; Ownership.
|
||||||
|
|
||||||
|
3.1 License Grant. Subject to the terms and conditions of this Agreement, OpenFaaS Ltd hereby grants to the Customer a limited, non-exclusive, non-transferable, revocable license to use the OpenFaaS Community Edition solely for internal business purposes and in accordance with the restrictions set forth herein.
|
||||||
|
|
||||||
|
3.2 Ownership and Intellectual Property Rights. OpenFaaS Ltd retains all rights, title, and interest in the OpenFaaS Community Edition, including any and all intellectual property rights.
|
||||||
|
|
||||||
|
Restrictions and Responsibilities.
|
||||||
|
|
||||||
|
4.1 Usage Restrictions. The Customer shall not distribute, sublicense, rent, lease, modify, translate, reverse engineer, decompile, disassemble, create derivative works based on, or copy the OpenFaaS Community Edition, except as expressly permitted by applicable law.
|
||||||
|
|
||||||
|
4.2 Feedback. Customer may provide feedback to OpenFaaS Ltd, which OpenFaaS Ltd may use to improve the software without obligation to the Customer.
|
||||||
|
|
||||||
|
Termination. This Agreement is effective from the first date you install the OpenFaaS Community Edition. You may terminate this Agreement at any time by deleting all copies of the software. OpenFaaS Ltd may terminate this Agreement at any time if you fail to comply with the terms.
|
||||||
|
|
||||||
|
Limitation of Liability.
|
||||||
|
|
||||||
|
6.1 Warranty Disclaimer. The OpenFaaS Community Edition is provided "as is" without warranty of any kind. You use the software at your own risk.
|
||||||
|
|
||||||
|
6.2 Liability Limitations. OpenFaaS Ltd shall not be liable for any indirect, special, incidental, or consequential damages arising out of the use of the OpenFaaS Community Edition.
|
||||||
|
|
||||||
|
General Provisions.
|
||||||
|
|
||||||
|
7. Co-Marketing
|
||||||
|
|
||||||
|
7.1 At the request of Supplier, Customer agrees to participate in other reasonable marketing activities that promote the benefits of the Services to other potential customers, including providing testimonials, case studies, and references.
|
||||||
|
|
||||||
|
7.2 Customer grants use of the Customer's name and logo on the Supplier's websites and in the Supplier's promotional materials.
|
||||||
|
|
||||||
|
7.3 Customer agrees that Supplier may disclose Customer as a customer of the Products.
|
||||||
|
|
||||||
|
8. Installation and Usage Restrictions
|
||||||
|
|
||||||
|
8.1 Single Installation Limit for Commercial Use: The License granted under this Agreement for the OpenFaaS Community Edition permits commercial use of the software for a period not exceeding 60 days. This period is intended to allow for evaluation of the software's capabilities in a commercial environment. Commercial use is strictly limited to one (1) installation per company for the 60-day evaluation period.
|
||||||
|
|
||||||
|
8.2 Prohibition on Circumvention: To ensure fair use of the OpenFaaS Community Edition, the Customer agrees not to engage in any action with the intent to circumvent the 60-day evaluation period limitation. This includes, but is not limited to, uninstalling and reinstalling the software on the same or different systems within the company to restart the evaluation period.
|
||||||
|
|
||||||
|
8.3 Enforcement and Verification: OpenFaaS Ltd reserves the right to implement reasonable measures to verify compliance with the terms of this Agreement, including the installation and usage restrictions set forth herein. The Customer agrees to cooperate with OpenFaaS Ltd in any such compliance verification efforts.
|
||||||
|
|
||||||
|
8.4 Consequences of Violation: Any attempt to bypass or violate the installation and usage restrictions, as described in Sections 8.1 and 8.2, may result in immediate termination of this EULA and the License granted hereunder. Further, the Customer may be subject to legal action and liable for damages resulting from any such violation.
|
||||||
|
|
||||||
|
9.1 Entire Agreement. This EULA constitutes the entire agreement between the parties concerning the subject matter hereof.
|
||||||
|
|
||||||
|
9.2 Sections 1-8 will remain effective after the termination of the Agreement.
|
||||||
|
|
||||||
|
9.3 Contact Information. For questions about these terms, contact OpenFaaS Ltd at: contact@openfaas.com.
|
11
LICENSE
11
LICENSE
@ -1,3 +1,14 @@
|
|||||||
|
All contributions from Alex Ellis & OpenFaaS Ltd are licensed under the
|
||||||
|
OpenFaaS Community Edition (CE) EULA between the years 2017,2019-2024.
|
||||||
|
|
||||||
|
Contributions from third-parties are licensed under the MIT license.
|
||||||
|
|
||||||
|
A license is required for commercial use of OpenFaaS CE:
|
||||||
|
https://github.com/openfaas/faas/blob/master/EULA.md
|
||||||
|
|
||||||
|
A separate commercial license covering all contributions can be purchased
|
||||||
|
from OpenFaaS Ltd, with details available at: https://openfaas.com/pricing
|
||||||
|
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2016-2018 Alex Ellis
|
Copyright (c) 2016-2018 Alex Ellis
|
||||||
|
6
Makefile
6
Makefile
@ -5,6 +5,12 @@ NS?=openfaas
|
|||||||
build-gateway:
|
build-gateway:
|
||||||
(cd gateway; docker buildx build --platform linux/amd64 -t ${NS}/gateway:latest-dev .)
|
(cd gateway; docker buildx build --platform linux/amd64 -t ${NS}/gateway:latest-dev .)
|
||||||
|
|
||||||
|
|
||||||
|
# generate Go models from the OpenAPI spec using https://github.com/contiamo/openapi-generator-go
|
||||||
|
generate:
|
||||||
|
rm gateway/models/model_*.go || true
|
||||||
|
openapi-generator-go generate models -s api-docs/spec.openapi.yml -o gateway/models --package-name models
|
||||||
|
|
||||||
# .PHONY: test-ci
|
# .PHONY: test-ci
|
||||||
# test-ci:
|
# test-ci:
|
||||||
# ./contrib/ci.sh
|
# ./contrib/ci.sh
|
||||||
|
17
README.md
17
README.md
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
[](https://github.com/openfaas/faas/actions/workflows/build.yml)
|
[](https://github.com/openfaas/faas/actions/workflows/build.yml)
|
||||||
[](https://pkg.go.dev/github.com/openfaas/faas)
|
[](https://pkg.go.dev/github.com/openfaas/faas)
|
||||||
[](https://opensource.org/licenses/MIT)
|
|
||||||
[](https://www.openfaas.com)
|
[](https://www.openfaas.com)
|
||||||
[](https://github.com/alexellis/derek/)
|
[](https://github.com/alexellis/derek/)
|
||||||
|
|
||||||
@ -155,7 +154,7 @@ Have you written a blog about OpenFaaS? Do you have a speaking event? Send a Pul
|
|||||||
|
|
||||||
### Contributing
|
### Contributing
|
||||||
|
|
||||||
OpenFaaS Community Edition is written in Golang and is MIT licensed. Various types of contributions are welcomed whether that means providing feedback, testing existing and new feature or hacking on the source code.
|
OpenFaaS Community Edition is written in Golang. All third-party contributions to the source code are made under the MIT license, additional restrictions apply to OpenFaaS CE as a whole, where contributions from OpenFaaS Ltd are licensed under the [OpenFaaS CE EULA](EULA.md). Various types of contributions are welcomed whether that means providing feedback, testing existing and new feature or hacking on the source code.
|
||||||
|
|
||||||
#### How do I become a contributor?
|
#### How do I become a contributor?
|
||||||
|
|
||||||
@ -174,21 +173,13 @@ An alternative community dashboard is [available here](https://grafana.com/dashb
|
|||||||
|
|
||||||
* Individual Sponsorships 🍻
|
* Individual Sponsorships 🍻
|
||||||
|
|
||||||
The source code for OpenFaaS shared in public repositories on GitHub is free to use and open source under the terms of the MIT license.
|
Users and contributors are encouraged to join their peers in supporting the OpenFaaS project through [GitHub Sponsors](https://github.com/sponsors/openfaas).
|
||||||
|
|
||||||
OpenFaaS Ltd offers [commercial support and enterprise add-ons](https://www.openfaas.com/support) for end-users and [training and consulting services for Cloud and Kubernetes](https://www.openfaas.com/consulting).
|
|
||||||
|
|
||||||
Users and contributors are encouraged to join their peers in supporting the project through [GitHub Sponsors](https://github.com/sponsors/openfaas).
|
|
||||||
|
|
||||||
* OpenFaaS Pro for Production
|
* OpenFaaS Pro for Production
|
||||||
|
|
||||||
OpenFaaS Pro is built for production, the Community Edition (CE) is suitable for open-source developers.
|
OpenFaaS Pro (Standard and For Enterprises) is built for production, the [Community Edition (CE)](EULA.md) is suitable for a Proof of Concept (PoC), for experimentation, and some limited internal use.
|
||||||
|
|
||||||
Upgrade to our commercial distribution with finely-tuned auto-scaling, scale to zero and event connectors for Kafka and AWS SQS.
|
[Learn more about OpenFaaS editions](https://openfaas.com/pricing/)
|
||||||
|
|
||||||
We also offer Enterprise Support where you get to work directly with the founders of the project.
|
|
||||||
|
|
||||||
[Contact us about OpenFaaS Pro & Enterprise Support](https://openfaas.com/support/)
|
|
||||||
|
|
||||||
* Website Sponsorship 🌎
|
* Website Sponsorship 🌎
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
## Exploring or editing the Swagger API documentation
|
## Exploring or editing the Swagger API documentation
|
||||||
|
|
||||||
The `swagger.yml` file can be viewed and edited in the Swagger UI.
|
The `spec.openapi.yml` file can be viewed and edited in the Swagger UI.
|
||||||
|
|
||||||
* Head over to the [Swagger editor](http://editor.swagger.io/)
|
* Head over to the [Swagger editor](http://editor.swagger.io/)
|
||||||
|
|
||||||
* Now click File -> Import URL
|
* Now click File -> Import URL
|
||||||
|
|
||||||
* Type in `https://raw.githubusercontent.com/openfaas/faas/master/api-docs/swagger.yml` and click OK
|
* Type in `https://raw.githubusercontent.com/openfaas/faas/master/api-docs/spec.openapi.yml` and click OK
|
||||||
|
|
||||||
You can now view and edit the Swagger, copy back to your fork before pushing changes.
|
You can now view and edit the Swagger, copy back to your fork before pushing changes.
|
||||||
|
996
api-docs/spec.openapi.yml
Normal file
996
api-docs/spec.openapi.yml
Normal file
@ -0,0 +1,996 @@
|
|||||||
|
openapi: 3.0.1
|
||||||
|
info:
|
||||||
|
title: OpenFaaS API Gateway
|
||||||
|
description: OpenFaaS API documentation
|
||||||
|
license:
|
||||||
|
name: MIT
|
||||||
|
version: 0.8.12
|
||||||
|
contact:
|
||||||
|
name: OpenFaaS Ltd
|
||||||
|
url: https://www.openfaas.com/support/
|
||||||
|
servers:
|
||||||
|
- url: "http://localhost:8080"
|
||||||
|
description: Local server
|
||||||
|
tags:
|
||||||
|
- name: internal
|
||||||
|
description: Internal use only
|
||||||
|
- name: system
|
||||||
|
description: System endpoints for managing functions and related objects
|
||||||
|
- name: function
|
||||||
|
description: Endpoints for invoking functions
|
||||||
|
paths:
|
||||||
|
"/healthz":
|
||||||
|
get:
|
||||||
|
summary: Healthcheck
|
||||||
|
operationId: healthcheck
|
||||||
|
description: Healthcheck for the gateway, indicates if the gateway is running and available
|
||||||
|
tags:
|
||||||
|
- internal
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Healthy
|
||||||
|
'500':
|
||||||
|
description: Not healthy
|
||||||
|
"/metrics":
|
||||||
|
get:
|
||||||
|
summary: Prometheus metrics
|
||||||
|
operationId: metrics
|
||||||
|
description: Prometheus metrics for the gateway
|
||||||
|
tags:
|
||||||
|
- internal
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Prometheus metrics in text format
|
||||||
|
"/system/info":
|
||||||
|
get:
|
||||||
|
operationId: GetSystemInfo
|
||||||
|
description: Get system provider information
|
||||||
|
summary: Get info such as provider version number and provider orchestrator
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Info result
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
"$ref": "#/components/schemas/GatewayInfo"
|
||||||
|
'500':
|
||||||
|
description: Internal Server Error
|
||||||
|
"/system/alert":
|
||||||
|
post:
|
||||||
|
operationId: ScaleAlert
|
||||||
|
description: Scale a function based on an alert
|
||||||
|
summary: |
|
||||||
|
Event-sink for AlertManager, for auto-scaling
|
||||||
|
|
||||||
|
Internal use for AlertManager, requires valid AlertManager alert
|
||||||
|
JSON
|
||||||
|
tags:
|
||||||
|
- internal
|
||||||
|
requestBody:
|
||||||
|
description: Incoming alert
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/PrometheusAlert'
|
||||||
|
required: false
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Alert handled successfully
|
||||||
|
'500':
|
||||||
|
description: Internal error with swarm or request JSON invalid
|
||||||
|
"/system/functions":
|
||||||
|
get:
|
||||||
|
operationId: GetFunctions
|
||||||
|
description: Get a list of deployed functions
|
||||||
|
summary: 'Get a list of deployed functions with: stats and image digest'
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: List of deployed functions.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
"$ref": "#/components/schemas/FunctionStatus"
|
||||||
|
put:
|
||||||
|
operationId: UpdateFunction
|
||||||
|
description: update a function spec
|
||||||
|
summary: Update a function.
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
requestBody:
|
||||||
|
description: Function to update
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
"$ref": "#/components/schemas/FunctionDeployment"
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Accepted
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
'404':
|
||||||
|
description: Not Found
|
||||||
|
'500':
|
||||||
|
description: Internal Server Error
|
||||||
|
post:
|
||||||
|
operationId: DeployFunction
|
||||||
|
description: Deploy a new function.
|
||||||
|
summary: Deploy a new function.
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
requestBody:
|
||||||
|
description: Function to deploy
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
"$ref": "#/components/schemas/FunctionDeployment"
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'202':
|
||||||
|
description: Accepted
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
'500':
|
||||||
|
description: Internal Server Error
|
||||||
|
delete:
|
||||||
|
operationId: DeleteFunction
|
||||||
|
description: Remove a deployed function.
|
||||||
|
summary: Remove a deployed function.
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
requestBody:
|
||||||
|
description: Function to delete
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
"$ref": "#/components/schemas/DeleteFunctionRequest"
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: OK
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
'404':
|
||||||
|
description: Not Found
|
||||||
|
'500':
|
||||||
|
description: Internal Server Error
|
||||||
|
"/system/scale-function/{functionName}":
|
||||||
|
post:
|
||||||
|
operationId: ScaleFunction
|
||||||
|
description: Scale a function
|
||||||
|
summary: Scale a function to a specific replica count
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
parameters:
|
||||||
|
- name: functionName
|
||||||
|
in: path
|
||||||
|
description: Function name
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ScaleServiceRequest'
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Scaling OK
|
||||||
|
'202':
|
||||||
|
description: Scaling OK
|
||||||
|
'404':
|
||||||
|
description: Function not found
|
||||||
|
'500':
|
||||||
|
description: Error scaling function
|
||||||
|
|
||||||
|
"/system/function/{functionName}":
|
||||||
|
get:
|
||||||
|
operationId: GetFunctionStatus
|
||||||
|
description: Get the status of a function by name
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
parameters:
|
||||||
|
- name: functionName
|
||||||
|
in: path
|
||||||
|
description: Function name
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: namespace
|
||||||
|
in: query
|
||||||
|
description: Namespace of the function
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Function Summary
|
||||||
|
content:
|
||||||
|
"*/*":
|
||||||
|
schema:
|
||||||
|
"$ref": "#/components/schemas/FunctionStatus"
|
||||||
|
'404':
|
||||||
|
description: Not Found
|
||||||
|
'500':
|
||||||
|
description: Internal Server Error
|
||||||
|
"/system/secrets":
|
||||||
|
get:
|
||||||
|
operationId: ListSecrets
|
||||||
|
description: Get a list of secret names and metadata from the provider
|
||||||
|
summary: Get a list of secret names and metadata from the provider
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: List of submitted secrets.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
"$ref": "#/components/schemas/SecretDescription"
|
||||||
|
put:
|
||||||
|
operationId: UpdateSecret
|
||||||
|
description: Update a secret.
|
||||||
|
summary: Update a secret, the value is replaced.
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
requestBody:
|
||||||
|
description: Secret to update
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
"$ref": "#/components/schemas/Secret"
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Ok
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
'404':
|
||||||
|
description: Not Found
|
||||||
|
'405':
|
||||||
|
description: Method Not Allowed. Secret update is not allowed in faas-swarm.
|
||||||
|
'500':
|
||||||
|
description: Internal Server Error
|
||||||
|
post:
|
||||||
|
operationId: CreateSecret
|
||||||
|
description: Create a new secret.
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
requestBody:
|
||||||
|
description: A new secret to create
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
"$ref": "#/components/schemas/Secret"
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'201':
|
||||||
|
description: Created
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
'500':
|
||||||
|
description: Internal Server Error
|
||||||
|
delete:
|
||||||
|
operationId: DeleteSecret
|
||||||
|
description: Remove a secret.
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
requestBody:
|
||||||
|
description: Secret to delete
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
"$ref": "#/components/schemas/SecretDescription"
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
'204':
|
||||||
|
description: OK
|
||||||
|
'400':
|
||||||
|
description: Bad Request
|
||||||
|
'404':
|
||||||
|
description: Not Found
|
||||||
|
'500':
|
||||||
|
description: Internal Server Error
|
||||||
|
"/system/logs":
|
||||||
|
get:
|
||||||
|
operationId: GetFunctionLogs
|
||||||
|
description: Get a stream of the logs for a specific function
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
parameters:
|
||||||
|
- name: name
|
||||||
|
in: query
|
||||||
|
description: Function name
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: namespace
|
||||||
|
in: query
|
||||||
|
description: Namespace of the function
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: instance
|
||||||
|
in: query
|
||||||
|
description: Instance of the function
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: tail
|
||||||
|
in: query
|
||||||
|
description: Sets the maximum number of log messages to return, <=0 means
|
||||||
|
unlimited
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
- name: follow
|
||||||
|
in: query
|
||||||
|
description: When true, the request will stream logs until the request timeout
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
- name: since
|
||||||
|
in: query
|
||||||
|
description: Only return logs after a specific date (RFC3339)
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Newline delimited stream of log messages
|
||||||
|
content:
|
||||||
|
application/x-ndjson:
|
||||||
|
schema:
|
||||||
|
"$ref": "#/components/schemas/LogEntry"
|
||||||
|
'404':
|
||||||
|
description: Not Found
|
||||||
|
'500':
|
||||||
|
description: Internal Server Error
|
||||||
|
|
||||||
|
"/system/namespaces":
|
||||||
|
get:
|
||||||
|
operationId: ListNamespaces
|
||||||
|
description: Get a list of namespaces
|
||||||
|
tags:
|
||||||
|
- system
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: List of namespaces
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/ListNamespaceResponse'
|
||||||
|
'500':
|
||||||
|
description: Internal Server Error
|
||||||
|
|
||||||
|
"/async-function/{functionName}":
|
||||||
|
post:
|
||||||
|
operationId: InvokeAsync
|
||||||
|
description: Invoke a function asynchronously
|
||||||
|
summary: |
|
||||||
|
Invoke a function asynchronously in the default OpenFaaS namespace
|
||||||
|
|
||||||
|
Any additional path segments and query parameters will be passed to the function as is.
|
||||||
|
|
||||||
|
See https://docs.openfaas.com/reference/async/.
|
||||||
|
tags:
|
||||||
|
- function
|
||||||
|
parameters:
|
||||||
|
- name: functionName
|
||||||
|
in: path
|
||||||
|
description: Function name
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
description: "(Optional) data to pass to function"
|
||||||
|
content:
|
||||||
|
"*/*":
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
example: '{"hello": "world"}'
|
||||||
|
required: false
|
||||||
|
responses:
|
||||||
|
'202':
|
||||||
|
description: Request accepted and queued
|
||||||
|
'404':
|
||||||
|
description: Not Found
|
||||||
|
'500':
|
||||||
|
description: Internal Server Error
|
||||||
|
|
||||||
|
"/async-function/{functionName}.{namespace}":
|
||||||
|
post:
|
||||||
|
operationId: InvokeAsyncNamespaced
|
||||||
|
description: Invoke a function asynchronously in an OpenFaaS namespace.
|
||||||
|
summary: |
|
||||||
|
Invoke a function asynchronously in an OpenFaaS namespace.
|
||||||
|
|
||||||
|
Any additional path segments and query parameters will be passed to the function as is.
|
||||||
|
|
||||||
|
See https://docs.openfaas.com/reference/async/.
|
||||||
|
tags:
|
||||||
|
- function
|
||||||
|
parameters:
|
||||||
|
- name: functionName
|
||||||
|
in: path
|
||||||
|
description: Function name
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: namespace
|
||||||
|
in: path
|
||||||
|
description: Namespace of the function
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
description: "(Optional) data to pass to function"
|
||||||
|
content:
|
||||||
|
"*/*":
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
example: '{"hello": "world"}'
|
||||||
|
required: false
|
||||||
|
responses:
|
||||||
|
'202':
|
||||||
|
description: Request accepted and queued
|
||||||
|
'404':
|
||||||
|
description: Not Found
|
||||||
|
'500':
|
||||||
|
description: Internal Server Error
|
||||||
|
|
||||||
|
"/function/{functionName}":
|
||||||
|
post:
|
||||||
|
operationId: InvokeFunction
|
||||||
|
description: Invoke a function in the default OpenFaaS namespace.
|
||||||
|
summary: |
|
||||||
|
Synchronously invoke a function defined in te default OpenFaaS namespace.
|
||||||
|
|
||||||
|
Any additional path segments and query parameters will be passed to the function as is.
|
||||||
|
tags:
|
||||||
|
- function
|
||||||
|
parameters:
|
||||||
|
- name: functionName
|
||||||
|
in: path
|
||||||
|
description: Function name
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
description: "(Optional) data to pass to function"
|
||||||
|
content:
|
||||||
|
"*/*":
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
example: '{"hello": "world"}'
|
||||||
|
required: false
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Value returned from function
|
||||||
|
'404':
|
||||||
|
description: Not Found
|
||||||
|
'500':
|
||||||
|
description: Internal server error
|
||||||
|
|
||||||
|
"/function/{functionName}.{namespace}":
|
||||||
|
post:
|
||||||
|
operationId: InvokeFunctionNamespaced
|
||||||
|
description: Invoke a function in an OpenFaaS namespace.
|
||||||
|
summary: |
|
||||||
|
Synchronously invoke a function defined in the specified namespace.
|
||||||
|
|
||||||
|
Any additional path segments and query parameters will be passed to the function as is.
|
||||||
|
tags:
|
||||||
|
- function
|
||||||
|
parameters:
|
||||||
|
- name: functionName
|
||||||
|
in: path
|
||||||
|
description: Function name
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: namespace
|
||||||
|
in: path
|
||||||
|
description: Namespace of the function
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
description: "(Optional) data to pass to function"
|
||||||
|
content:
|
||||||
|
"*/*":
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
example: '{"hello": "world"}'
|
||||||
|
required: false
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Value returned from function
|
||||||
|
'404':
|
||||||
|
description: Not Found
|
||||||
|
'500':
|
||||||
|
description: Internal server error
|
||||||
|
components:
|
||||||
|
securitySchemes:
|
||||||
|
basicAuth:
|
||||||
|
type: http
|
||||||
|
scheme: basic
|
||||||
|
|
||||||
|
schemas:
|
||||||
|
GatewayInfo:
|
||||||
|
required:
|
||||||
|
- provider
|
||||||
|
- version
|
||||||
|
- arch
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
provider:
|
||||||
|
nullable: true
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/components/schemas/ProviderInfo"
|
||||||
|
version:
|
||||||
|
nullable: true
|
||||||
|
description: version of the gateway
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/components/schemas/VersionInfo"
|
||||||
|
arch:
|
||||||
|
type: string
|
||||||
|
description: Platform architecture
|
||||||
|
example: x86_64
|
||||||
|
VersionInfo:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- sha
|
||||||
|
- release
|
||||||
|
properties:
|
||||||
|
commit_message:
|
||||||
|
type: string
|
||||||
|
example: Sample Message
|
||||||
|
sha:
|
||||||
|
type: string
|
||||||
|
example: 7108418d9dd6b329ddff40e7393b3166f8160a88
|
||||||
|
release:
|
||||||
|
type: string
|
||||||
|
format: semver
|
||||||
|
example: 0.8.9
|
||||||
|
ProviderInfo:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- provider
|
||||||
|
- orchestration
|
||||||
|
- version
|
||||||
|
properties:
|
||||||
|
provider:
|
||||||
|
type: string
|
||||||
|
description: The orchestration provider / implementation
|
||||||
|
example: faas-netes
|
||||||
|
orchestration:
|
||||||
|
type: string
|
||||||
|
example: kubernetes
|
||||||
|
version:
|
||||||
|
description: The version of the provider
|
||||||
|
nullable: true
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/components/schemas/VersionInfo"
|
||||||
|
|
||||||
|
PrometheusAlert:
|
||||||
|
type: object
|
||||||
|
description: Prometheus alert produced by AlertManager. This is only a subset of the full alert payload.
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
- receiver
|
||||||
|
- alerts
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: The status of the alert
|
||||||
|
example: resolved
|
||||||
|
receiver:
|
||||||
|
type: string
|
||||||
|
description: The name of the receiver
|
||||||
|
example: webhook
|
||||||
|
alerts:
|
||||||
|
type: array
|
||||||
|
description: The list of alerts
|
||||||
|
items:
|
||||||
|
$ref: "#/components/schemas/PrometheusInnerAlert"
|
||||||
|
example:
|
||||||
|
{
|
||||||
|
"receiver": "scale-up",
|
||||||
|
"status": "firing",
|
||||||
|
"alerts": [{
|
||||||
|
"status": "firing",
|
||||||
|
"labels": {
|
||||||
|
"alertname": "APIHighInvocationRate",
|
||||||
|
"code": "200",
|
||||||
|
"function_name": "func_nodeinfo",
|
||||||
|
"instance": "gateway:8080",
|
||||||
|
"job": "gateway",
|
||||||
|
"monitor": "faas-monitor",
|
||||||
|
"service": "gateway",
|
||||||
|
"severity": "major",
|
||||||
|
"value": "8.998200359928017"
|
||||||
|
},
|
||||||
|
"annotations": {
|
||||||
|
"description": "High invocation total on gateway:8080",
|
||||||
|
"summary": "High invocation total on gateway:8080"
|
||||||
|
},
|
||||||
|
"startsAt": "2017-03-15T15:52:57.805Z",
|
||||||
|
"endsAt": "0001-01-01T00:00:00Z",
|
||||||
|
"generatorURL": "http://4156cb797423:9090/graph?g0.expr=rate%28gateway_function_invocation_total%5B10s%5D%29+%3E+5\u0026g0.tab=0"
|
||||||
|
}],
|
||||||
|
"groupLabels": {
|
||||||
|
"alertname": "APIHighInvocationRate",
|
||||||
|
"service": "gateway"
|
||||||
|
},
|
||||||
|
"commonLabels": {
|
||||||
|
"alertname": "APIHighInvocationRate",
|
||||||
|
"code": "200",
|
||||||
|
"function_name": "func_nodeinfo",
|
||||||
|
"instance": "gateway:8080",
|
||||||
|
"job": "gateway",
|
||||||
|
"monitor": "faas-monitor",
|
||||||
|
"service": "gateway",
|
||||||
|
"severity": "major",
|
||||||
|
"value": "8.998200359928017"
|
||||||
|
},
|
||||||
|
"commonAnnotations": {
|
||||||
|
"description": "High invocation total on gateway:8080",
|
||||||
|
"summary": "High invocation total on gateway:8080"
|
||||||
|
},
|
||||||
|
"externalURL": "http://f054879d97db:9093",
|
||||||
|
"version": "3",
|
||||||
|
"groupKey": 18195285354214864953
|
||||||
|
}
|
||||||
|
|
||||||
|
PrometheusInnerAlert:
|
||||||
|
type: object
|
||||||
|
description: A single alert produced by Prometheus
|
||||||
|
required:
|
||||||
|
- status
|
||||||
|
- labels
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description: The status of the alert
|
||||||
|
example: resolved
|
||||||
|
labels:
|
||||||
|
$ref: "#/components/schemas/PrometheusInnerAlertLabel"
|
||||||
|
|
||||||
|
PrometheusInnerAlertLabel:
|
||||||
|
type: object
|
||||||
|
description: A single label of a Prometheus alert
|
||||||
|
required:
|
||||||
|
- alertname
|
||||||
|
- function_name
|
||||||
|
properties:
|
||||||
|
alertname:
|
||||||
|
type: string
|
||||||
|
description: The name of the alert
|
||||||
|
function_name:
|
||||||
|
type: string
|
||||||
|
description: The name of the function
|
||||||
|
example: nodeinfo
|
||||||
|
|
||||||
|
FunctionDeployment:
|
||||||
|
required:
|
||||||
|
- service
|
||||||
|
- image
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
service:
|
||||||
|
type: string
|
||||||
|
description: Name of deployed function
|
||||||
|
example: nodeinfo
|
||||||
|
image:
|
||||||
|
type: string
|
||||||
|
description: Docker image in accessible registry
|
||||||
|
example: functions/nodeinfo:latest
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
description: Namespace to deploy function to. When omitted, the default namespace
|
||||||
|
is used, typically this is `openfaas-fn` but is configured by the provider.
|
||||||
|
example: openfaas-fn
|
||||||
|
envProcess:
|
||||||
|
type: string
|
||||||
|
description: |
|
||||||
|
Process for watchdog to fork, i.e. the command to start the function process.
|
||||||
|
|
||||||
|
This value configures the `fprocess` env variable.
|
||||||
|
example: node main.js
|
||||||
|
constraints:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
description: Constraints are specific to OpenFaaS Provider
|
||||||
|
example: node.platform.os == linux
|
||||||
|
envVars:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
description: Overrides to environmental variables
|
||||||
|
secrets:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
description: An array of names of secrets that are required to be loaded
|
||||||
|
from the Docker Swarm.
|
||||||
|
example: secret-name-1
|
||||||
|
labels:
|
||||||
|
type: object
|
||||||
|
nullable: true
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
description: A map of labels for making scheduling or routing decisions
|
||||||
|
example:
|
||||||
|
foo: bar
|
||||||
|
annotations:
|
||||||
|
type: object
|
||||||
|
nullable: true
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
description: A map of annotations for management, orchestration, events
|
||||||
|
and build tasks
|
||||||
|
example:
|
||||||
|
topics: awesome-kafka-topic
|
||||||
|
foo: bar
|
||||||
|
limits:
|
||||||
|
nullable: true
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/components/schemas/FunctionResources"
|
||||||
|
requests:
|
||||||
|
nullable: true
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/components/schemas/FunctionResources"
|
||||||
|
readOnlyRootFilesystem:
|
||||||
|
type: boolean
|
||||||
|
description: Make the root filesystem of the function read-only
|
||||||
|
|
||||||
|
# DEPRECATED FIELDS, these fields are ignored in all current providers
|
||||||
|
registryAuth:
|
||||||
|
type: string
|
||||||
|
description: |
|
||||||
|
Deprecated: Private registry base64-encoded basic auth (as present in ~/.docker/config.json)
|
||||||
|
|
||||||
|
Use a Kubernetes Secret with registry-auth secret type to provide this value instead.
|
||||||
|
|
||||||
|
This value is completely ignored.
|
||||||
|
example: dXNlcjpwYXNzd29yZA==
|
||||||
|
deprecated: true
|
||||||
|
network:
|
||||||
|
type: string
|
||||||
|
description: |
|
||||||
|
Deprecated: Network, usually func_functions for Swarm.
|
||||||
|
|
||||||
|
This value is completely ignored.
|
||||||
|
deprecated: true
|
||||||
|
example: func_functions
|
||||||
|
|
||||||
|
FunctionStatus:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- image
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: The name of the function
|
||||||
|
example: nodeinfo
|
||||||
|
image:
|
||||||
|
type: string
|
||||||
|
description: The fully qualified docker image name of the function
|
||||||
|
example: functions/nodeinfo:latest
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
description: The namespace of the function
|
||||||
|
example: openfaas-fn
|
||||||
|
envProcess:
|
||||||
|
type: string
|
||||||
|
description: Process for watchdog to fork
|
||||||
|
example: node main.js
|
||||||
|
envVars:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
description: environment variables for the function runtime
|
||||||
|
constraints:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
description: Constraints are specific to OpenFaaS Provider
|
||||||
|
example: node.platform.os == linux
|
||||||
|
secrets:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
description: An array of names of secrets that are made available to the function
|
||||||
|
labels:
|
||||||
|
type: object
|
||||||
|
nullable: true
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
description: A map of labels for making scheduling or routing decisions
|
||||||
|
example:
|
||||||
|
foo: bar
|
||||||
|
annotations:
|
||||||
|
type: object
|
||||||
|
nullable: true
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
description: A map of annotations for management, orchestration, events
|
||||||
|
and build tasks
|
||||||
|
example:
|
||||||
|
topics: awesome-kafka-topic
|
||||||
|
foo: bar
|
||||||
|
limits:
|
||||||
|
nullable: true
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/components/schemas/FunctionResources"
|
||||||
|
requests:
|
||||||
|
nullable: true
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/components/schemas/FunctionResources"
|
||||||
|
readOnlyRootFilesystem:
|
||||||
|
type: boolean
|
||||||
|
description: removes write-access from the root filesystem mount-point.
|
||||||
|
invocationCount:
|
||||||
|
type: number
|
||||||
|
description: The amount of invocations for the specified function
|
||||||
|
format: integer
|
||||||
|
example: 1337
|
||||||
|
replicas:
|
||||||
|
type: number
|
||||||
|
description: Desired amount of replicas
|
||||||
|
format: integer
|
||||||
|
example: 2
|
||||||
|
availableReplicas:
|
||||||
|
type: number
|
||||||
|
description: The current available amount of replicas
|
||||||
|
format: integer
|
||||||
|
example: 2
|
||||||
|
createdAt:
|
||||||
|
type: string
|
||||||
|
description: |
|
||||||
|
is the time read back from the faas backend's
|
||||||
|
data store for when the function or its container was created.
|
||||||
|
format: date-time
|
||||||
|
usage:
|
||||||
|
nullable: true
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/components/schemas/FunctionUsage"
|
||||||
|
|
||||||
|
FunctionResources:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
memory:
|
||||||
|
type: string
|
||||||
|
description: The amount of memory that is allocated for the function
|
||||||
|
example: 128M
|
||||||
|
cpu:
|
||||||
|
type: string
|
||||||
|
description: The amount of cpu that is allocated for the function
|
||||||
|
example: '0.01'
|
||||||
|
|
||||||
|
FunctionUsage:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
cpu:
|
||||||
|
type: number
|
||||||
|
description: |
|
||||||
|
is the increase in CPU usage since the last measurement
|
||||||
|
equivalent to Kubernetes' concept of millicores.
|
||||||
|
format: double
|
||||||
|
example: 0.01
|
||||||
|
totalMemoryBytes:
|
||||||
|
type: number
|
||||||
|
description: is the total memory usage in bytes.
|
||||||
|
format: double
|
||||||
|
example: 1337
|
||||||
|
|
||||||
|
DeleteFunctionRequest:
|
||||||
|
required:
|
||||||
|
- functionName
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
functionName:
|
||||||
|
type: string
|
||||||
|
description: Name of deployed function
|
||||||
|
example: nodeinfo
|
||||||
|
|
||||||
|
ScaleServiceRequest:
|
||||||
|
required:
|
||||||
|
- serviceName
|
||||||
|
- namespace
|
||||||
|
- replicas
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
serviceName:
|
||||||
|
type: string
|
||||||
|
description: Name of deployed function
|
||||||
|
example: nodeinfo
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
description: Namespace the function is deployed to.
|
||||||
|
example: openfaas-fn
|
||||||
|
replicas:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
minimum: 0
|
||||||
|
description: Number of replicas to scale to
|
||||||
|
example: 2
|
||||||
|
|
||||||
|
SecretDescription:
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: Name of secret
|
||||||
|
example: aws-key
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
description: Namespace of secret
|
||||||
|
example: openfaas-fn
|
||||||
|
SecretValues:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
value:
|
||||||
|
type: string
|
||||||
|
description: Value of secret in plain-text
|
||||||
|
example: changeme
|
||||||
|
rawValue:
|
||||||
|
type: string
|
||||||
|
format: byte
|
||||||
|
description: |
|
||||||
|
Value of secret in base64.
|
||||||
|
|
||||||
|
This can be used to provide raw binary data when the `value` field is omitted.
|
||||||
|
example: Y2hhbmdlbWU=
|
||||||
|
|
||||||
|
Secret:
|
||||||
|
type: object
|
||||||
|
allOf:
|
||||||
|
- $ref: "#/components/schemas/SecretDescription"
|
||||||
|
- $ref: "#/components/schemas/SecretValues"
|
||||||
|
|
||||||
|
LogEntry:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- namespace
|
||||||
|
- instance
|
||||||
|
- timestamp
|
||||||
|
- text
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description: the function name
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
description: the namespace of the function
|
||||||
|
instance:
|
||||||
|
type: string
|
||||||
|
description: the name/id of the specific function instance
|
||||||
|
timestamp:
|
||||||
|
type: string
|
||||||
|
description: the timestamp of when the log message was recorded
|
||||||
|
format: date-time
|
||||||
|
text:
|
||||||
|
type: string
|
||||||
|
description: raw log message content
|
||||||
|
|
||||||
|
ListNamespaceResponse:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
description: Namespace name
|
||||||
|
example: openfaas-fn
|
@ -1,628 +0,0 @@
|
|||||||
swagger: '2.0'
|
|
||||||
info:
|
|
||||||
description: OpenFaaS API documentation
|
|
||||||
version: 0.8.12
|
|
||||||
title: OpenFaaS API Gateway
|
|
||||||
license:
|
|
||||||
name: MIT
|
|
||||||
basePath: /
|
|
||||||
schemes:
|
|
||||||
- http
|
|
||||||
paths:
|
|
||||||
'/system/functions':
|
|
||||||
get:
|
|
||||||
summary: 'Get a list of deployed functions with: stats and image digest'
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: List of deployed functions.
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/FunctionListEntry'
|
|
||||||
post:
|
|
||||||
summary: Deploy a new function.
|
|
||||||
description: ''
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
parameters:
|
|
||||||
- in: body
|
|
||||||
name: body
|
|
||||||
description: Function to deploy
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/FunctionDefinition'
|
|
||||||
responses:
|
|
||||||
'202':
|
|
||||||
description: Accepted
|
|
||||||
'400':
|
|
||||||
description: Bad Request
|
|
||||||
'500':
|
|
||||||
description: Internal Server Error
|
|
||||||
put:
|
|
||||||
summary: Update a function.
|
|
||||||
description: ''
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
parameters:
|
|
||||||
- in: body
|
|
||||||
name: body
|
|
||||||
description: Function to update
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/FunctionDefinition'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Accepted
|
|
||||||
'400':
|
|
||||||
description: Bad Request
|
|
||||||
'404':
|
|
||||||
description: Not Found
|
|
||||||
'500':
|
|
||||||
description: Internal Server Error
|
|
||||||
delete:
|
|
||||||
summary: Remove a deployed function.
|
|
||||||
description: ''
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
parameters:
|
|
||||||
- in: body
|
|
||||||
name: body
|
|
||||||
description: Function to delete
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/DeleteFunctionRequest'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: OK
|
|
||||||
'400':
|
|
||||||
description: Bad Request
|
|
||||||
'404':
|
|
||||||
description: Not Found
|
|
||||||
'500':
|
|
||||||
description: Internal Server Error
|
|
||||||
'/system/alert':
|
|
||||||
post:
|
|
||||||
summary: 'Event-sink for AlertManager, for auto-scaling'
|
|
||||||
description: 'Internal use for AlertManager, requires valid AlertManager alert JSON'
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
parameters:
|
|
||||||
- in: body
|
|
||||||
name: body
|
|
||||||
description: Incoming alert
|
|
||||||
schema:
|
|
||||||
type: object
|
|
||||||
example: |-
|
|
||||||
{"receiver": "scale-up",
|
|
||||||
"status": "firing",
|
|
||||||
"alerts": [{
|
|
||||||
"status": "firing",
|
|
||||||
"labels": {
|
|
||||||
"alertname": "APIHighInvocationRate",
|
|
||||||
"code": "200",
|
|
||||||
"function_name": "func_nodeinfo",
|
|
||||||
"instance": "gateway:8080",
|
|
||||||
"job": "gateway",
|
|
||||||
"monitor": "faas-monitor",
|
|
||||||
"service": "gateway",
|
|
||||||
"severity": "major",
|
|
||||||
"value": "8.998200359928017"
|
|
||||||
},
|
|
||||||
"annotations": {
|
|
||||||
"description": "High invocation total on gateway:8080",
|
|
||||||
"summary": "High invocation total on gateway:8080"
|
|
||||||
},
|
|
||||||
"startsAt": "2017-03-15T15:52:57.805Z",
|
|
||||||
"endsAt": "0001-01-01T00:00:00Z",
|
|
||||||
"generatorURL": "http://4156cb797423:9090/graph?g0.expr=rate%28gateway_function_invocation_total%5B10s%5D%29+%3E+5\u0026g0.tab=0"
|
|
||||||
}],
|
|
||||||
"groupLabels": {
|
|
||||||
"alertname": "APIHighInvocationRate",
|
|
||||||
"service": "gateway"
|
|
||||||
},
|
|
||||||
"commonLabels": {
|
|
||||||
"alertname": "APIHighInvocationRate",
|
|
||||||
"code": "200",
|
|
||||||
"function_name": "func_nodeinfo",
|
|
||||||
"instance": "gateway:8080",
|
|
||||||
"job": "gateway",
|
|
||||||
"monitor": "faas-monitor",
|
|
||||||
"service": "gateway",
|
|
||||||
"severity": "major",
|
|
||||||
"value": "8.998200359928017"
|
|
||||||
},
|
|
||||||
"commonAnnotations": {
|
|
||||||
"description": "High invocation total on gateway:8080",
|
|
||||||
"summary": "High invocation total on gateway:8080"
|
|
||||||
},
|
|
||||||
"externalURL": "http://f054879d97db:9093",
|
|
||||||
"version": "3",
|
|
||||||
"groupKey": 18195285354214864953
|
|
||||||
}
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Alert handled successfully
|
|
||||||
'500':
|
|
||||||
description: Internal error with swarm or request JSON invalid
|
|
||||||
'/async-function/{functionName}':
|
|
||||||
post:
|
|
||||||
summary: 'Invoke a function asynchronously in OpenFaaS'
|
|
||||||
description: >-
|
|
||||||
See https://docs.openfaas.com/reference/async/.
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: functionName
|
|
||||||
description: Function name
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
- in: body
|
|
||||||
name: input
|
|
||||||
description: (Optional) data to pass to function
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
format: binary
|
|
||||||
example:
|
|
||||||
'{"hello": "world"}'
|
|
||||||
required: false
|
|
||||||
responses:
|
|
||||||
'202':
|
|
||||||
description: Request accepted and queued
|
|
||||||
'404':
|
|
||||||
description: Not Found
|
|
||||||
'500':
|
|
||||||
description: Internal Server Error
|
|
||||||
'/function/{functionName}':
|
|
||||||
post:
|
|
||||||
summary: Invoke a function defined in OpenFaaS
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: functionName
|
|
||||||
description: Function name
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
- in: body
|
|
||||||
name: input
|
|
||||||
description: (Optional) data to pass to function
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
format: binary
|
|
||||||
example:
|
|
||||||
'{"hello": "world"}'
|
|
||||||
required: false
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Value returned from function
|
|
||||||
'404':
|
|
||||||
description: Not Found
|
|
||||||
'500':
|
|
||||||
description: Internal server error
|
|
||||||
'/system/scale-function/{functionName}':
|
|
||||||
post:
|
|
||||||
summary: Scale a function
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: functionName
|
|
||||||
description: Function name
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
- in: body
|
|
||||||
name: input
|
|
||||||
description: Function to scale plus replica count
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
format: binary
|
|
||||||
example:
|
|
||||||
'{"service": "hello-world", "replicas": 10}'
|
|
||||||
required: false
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Scaling OK
|
|
||||||
'202':
|
|
||||||
description: Scaling OK
|
|
||||||
'404':
|
|
||||||
description: Function not found
|
|
||||||
'500':
|
|
||||||
description: Error scaling function
|
|
||||||
'/system/function/{functionName}':
|
|
||||||
get:
|
|
||||||
summary: Get a summary of an OpenFaaS function
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: functionName
|
|
||||||
description: Function name
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Function Summary
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/FunctionListEntry'
|
|
||||||
'404':
|
|
||||||
description: Not Found
|
|
||||||
'500':
|
|
||||||
description: Internal Server Error
|
|
||||||
'/system/secrets':
|
|
||||||
get:
|
|
||||||
summary: 'Get a list of secret names and metadata from the provider'
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: List of submitted secrets.
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/SecretName'
|
|
||||||
post:
|
|
||||||
summary: Create a new secret.
|
|
||||||
description: ''
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
parameters:
|
|
||||||
- in: body
|
|
||||||
name: body
|
|
||||||
description: A new secret to create
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/Secret'
|
|
||||||
responses:
|
|
||||||
'201':
|
|
||||||
description: Created
|
|
||||||
'400':
|
|
||||||
description: Bad Request
|
|
||||||
'500':
|
|
||||||
description: Internal Server Error
|
|
||||||
put:
|
|
||||||
summary: Update a secret.
|
|
||||||
description: ''
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
parameters:
|
|
||||||
- in: body
|
|
||||||
name: body
|
|
||||||
description: Secret to update
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/Secret'
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Ok
|
|
||||||
'400':
|
|
||||||
description: Bad Request
|
|
||||||
'404':
|
|
||||||
description: Not Found
|
|
||||||
'405':
|
|
||||||
description: Method Not Allowed. Secret update is not allowed in faas-swarm.
|
|
||||||
'500':
|
|
||||||
description: Internal Server Error
|
|
||||||
delete:
|
|
||||||
summary: Remove a secret.
|
|
||||||
description: ''
|
|
||||||
consumes:
|
|
||||||
- application/json
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
parameters:
|
|
||||||
- in: body
|
|
||||||
name: body
|
|
||||||
description: Secret to delete
|
|
||||||
required: true
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/SecretName'
|
|
||||||
responses:
|
|
||||||
'204':
|
|
||||||
description: OK
|
|
||||||
'400':
|
|
||||||
description: Bad Request
|
|
||||||
'404':
|
|
||||||
description: Not Found
|
|
||||||
'500':
|
|
||||||
description: Internal Server Error
|
|
||||||
'/system/logs':
|
|
||||||
get:
|
|
||||||
summary: Get a stream of the logs for a specific function
|
|
||||||
produces:
|
|
||||||
- application/x-ndjson
|
|
||||||
parameters:
|
|
||||||
- in: query
|
|
||||||
name: name
|
|
||||||
description: Function name
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
- in: query
|
|
||||||
name: since
|
|
||||||
description: Only return logs after a specific date (RFC3339)
|
|
||||||
type: string
|
|
||||||
required: false
|
|
||||||
- in: query
|
|
||||||
name: tail
|
|
||||||
description: Sets the maximum number of log messages to return, <=0 means unlimited
|
|
||||||
type: integer
|
|
||||||
required: false
|
|
||||||
- in: query
|
|
||||||
name: follow
|
|
||||||
description: When true, the request will stream logs until the request timeout
|
|
||||||
type: boolean
|
|
||||||
required: false
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Newline delimited stream of log messages
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/LogEntry'
|
|
||||||
'404':
|
|
||||||
description: Not Found
|
|
||||||
'500':
|
|
||||||
description: Internal Server Error
|
|
||||||
'/system/info':
|
|
||||||
get:
|
|
||||||
summary: Get info such as provider version number and provider orchestrator
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Info result
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/Info'
|
|
||||||
'404':
|
|
||||||
description: Provider does not support info endpoint
|
|
||||||
'500':
|
|
||||||
description: Internal Server Error
|
|
||||||
'/healthz':
|
|
||||||
get:
|
|
||||||
summary: Healthcheck
|
|
||||||
responses:
|
|
||||||
'200':
|
|
||||||
description: Healthy
|
|
||||||
'500':
|
|
||||||
description: Not healthy
|
|
||||||
securityDefinitions:
|
|
||||||
basicAuth:
|
|
||||||
type: basic
|
|
||||||
definitions:
|
|
||||||
Info:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
provider:
|
|
||||||
type: object
|
|
||||||
description: The OpenFaaS Provider
|
|
||||||
properties:
|
|
||||||
provider:
|
|
||||||
type: string
|
|
||||||
example: faas-netes
|
|
||||||
orchestration:
|
|
||||||
type: string
|
|
||||||
example: kubernetes
|
|
||||||
version:
|
|
||||||
type: object
|
|
||||||
description: Version of the OpenFaaS Provider
|
|
||||||
properties:
|
|
||||||
commit_message:
|
|
||||||
type: string
|
|
||||||
example: Sample Message
|
|
||||||
sha:
|
|
||||||
type: string
|
|
||||||
example: 7108418d9dd6b329ddff40e7393b3166f8160a88
|
|
||||||
release:
|
|
||||||
type: string
|
|
||||||
format: semver
|
|
||||||
example: 0.2.6
|
|
||||||
version:
|
|
||||||
type: object
|
|
||||||
description: Version of the Gateway
|
|
||||||
properties:
|
|
||||||
commit_message:
|
|
||||||
type: string
|
|
||||||
example: Sample Message
|
|
||||||
sha:
|
|
||||||
type: string
|
|
||||||
example: 7108418d9dd6b329ddff40e7393b3166f8160a88
|
|
||||||
release:
|
|
||||||
type: string
|
|
||||||
format: semver
|
|
||||||
example: 0.8.9
|
|
||||||
arch:
|
|
||||||
type: string
|
|
||||||
description: "Platform architecture"
|
|
||||||
example: "x86_64"
|
|
||||||
required:
|
|
||||||
- provider
|
|
||||||
- version
|
|
||||||
DeleteFunctionRequest:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
functionName:
|
|
||||||
type: string
|
|
||||||
description: Name of deployed function
|
|
||||||
example: nodeinfo
|
|
||||||
required:
|
|
||||||
- functionName
|
|
||||||
FunctionDefinition:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
service:
|
|
||||||
type: string
|
|
||||||
description: Name of deployed function
|
|
||||||
example: nodeinfo
|
|
||||||
network:
|
|
||||||
type: string
|
|
||||||
description: Network, usually func_functions for Swarm (deprecated)
|
|
||||||
example: func_functions
|
|
||||||
image:
|
|
||||||
type: string
|
|
||||||
description: Docker image in accessible registry
|
|
||||||
example: functions/nodeinfo:latest
|
|
||||||
envProcess:
|
|
||||||
type: string
|
|
||||||
description: Process for watchdog to fork
|
|
||||||
example: node main.js
|
|
||||||
envVars:
|
|
||||||
type: object
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
description: Overrides to environmental variables
|
|
||||||
constraints:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
description: Constraints are specific to OpenFaaS Provider
|
|
||||||
example: "node.platform.os == linux"
|
|
||||||
labels:
|
|
||||||
description: A map of labels for making scheduling or routing decisions
|
|
||||||
type: object
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
example:
|
|
||||||
foo: bar
|
|
||||||
annotations:
|
|
||||||
description: A map of annotations for management, orchestration, events and build tasks
|
|
||||||
type: object
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
example:
|
|
||||||
topics: awesome-kafka-topic
|
|
||||||
foo: bar
|
|
||||||
secrets:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
description: An array of names of secrets that are required to be loaded from the Docker Swarm.
|
|
||||||
example: "secret-name-1"
|
|
||||||
registryAuth:
|
|
||||||
type: string
|
|
||||||
description: >-
|
|
||||||
Private registry base64-encoded basic auth (as present in
|
|
||||||
~/.docker/config.json)
|
|
||||||
example: dXNlcjpwYXNzd29yZA==
|
|
||||||
limits:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
memory:
|
|
||||||
type: string
|
|
||||||
example: "128M"
|
|
||||||
cpu:
|
|
||||||
type: string
|
|
||||||
example: "0.01"
|
|
||||||
requests:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
memory:
|
|
||||||
type: string
|
|
||||||
example: "128M"
|
|
||||||
cpu:
|
|
||||||
type: string
|
|
||||||
example: "0.01"
|
|
||||||
readOnlyRootFilesystem:
|
|
||||||
type: boolean
|
|
||||||
description: Make the root filesystem of the function read-only
|
|
||||||
required:
|
|
||||||
- service
|
|
||||||
- image
|
|
||||||
- envProcess
|
|
||||||
FunctionListEntry:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
description: The name of the function
|
|
||||||
type: string
|
|
||||||
example: nodeinfo
|
|
||||||
image:
|
|
||||||
description: The fully qualified docker image name of the function
|
|
||||||
type: string
|
|
||||||
example: functions/nodeinfo:latest
|
|
||||||
invocationCount:
|
|
||||||
description: The amount of invocations for the specified function
|
|
||||||
type: number
|
|
||||||
format: integer
|
|
||||||
example: 1337
|
|
||||||
replicas:
|
|
||||||
description: The current minimal ammount of replicas
|
|
||||||
type: number
|
|
||||||
format: integer
|
|
||||||
example: 2
|
|
||||||
availableReplicas:
|
|
||||||
description: The current available amount of replicas
|
|
||||||
type: number
|
|
||||||
format: integer
|
|
||||||
example: 2
|
|
||||||
envProcess:
|
|
||||||
description: Process for watchdog to fork
|
|
||||||
type: string
|
|
||||||
example: node main.js
|
|
||||||
labels:
|
|
||||||
description: A map of labels for making scheduling or routing decisions
|
|
||||||
type: object
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
example:
|
|
||||||
foo: bar
|
|
||||||
annotations:
|
|
||||||
description: A map of annotations for management, orchestration, events and build tasks
|
|
||||||
type: object
|
|
||||||
additionalProperties:
|
|
||||||
type: string
|
|
||||||
example:
|
|
||||||
topics: awesome-kafka-topic
|
|
||||||
foo: bar
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
- image
|
|
||||||
- invocationCount
|
|
||||||
- replicas
|
|
||||||
- availableReplicas
|
|
||||||
- envProcess
|
|
||||||
- labels
|
|
||||||
Secret:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
description: Name of secret
|
|
||||||
example: aws-key
|
|
||||||
value:
|
|
||||||
type: string
|
|
||||||
description: Value of secret in plain-text
|
|
||||||
example: changeme
|
|
||||||
required:
|
|
||||||
- name
|
|
||||||
LogEntry:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
description: the function name
|
|
||||||
instance:
|
|
||||||
type: string
|
|
||||||
description: the name/id of the specific function instance
|
|
||||||
timestamp:
|
|
||||||
type: string
|
|
||||||
format: date-time
|
|
||||||
description: the timestamp of when the log message was recorded
|
|
||||||
text:
|
|
||||||
type: string
|
|
||||||
description: raw log message content
|
|
||||||
SecretName:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
name:
|
|
||||||
type: string
|
|
||||||
description: Name of secret
|
|
||||||
example: aws-key
|
|
||||||
externalDocs:
|
|
||||||
description: More documentation available on Github
|
|
||||||
url: 'https://github.com/openfaas/faas'
|
|
@ -1,13 +0,0 @@
|
|||||||
auth plugins
|
|
||||||
============
|
|
||||||
|
|
||||||
Auth plugins must implement request checking on a HTTP port and path such as `:8080/validate`.
|
|
||||||
|
|
||||||
* Valid requests: return 2xx
|
|
||||||
* Invalid requests: return non 2xx
|
|
||||||
|
|
||||||
It is up to the developer to pick whether a request body is required for validation. For strategies such as [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication), headers are sufficient.
|
|
||||||
|
|
||||||
Plugins available:
|
|
||||||
|
|
||||||
* [basic-auth](./basic-auth/)
|
|
1
auth/basic-auth/.gitignore
vendored
1
auth/basic-auth/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
basic-auth
|
|
@ -1,45 +0,0 @@
|
|||||||
FROM --platform=${BUILDPLATFORM:-linux/amd64} ghcr.io/openfaas/license-check:0.4.1 as license-check
|
|
||||||
|
|
||||||
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.19 as build
|
|
||||||
|
|
||||||
ENV GO111MODULE=off
|
|
||||||
ENV CGO_ENABLED=0
|
|
||||||
|
|
||||||
ARG TARGETPLATFORM
|
|
||||||
ARG BUILDPLATFORM
|
|
||||||
ARG TARGETOS
|
|
||||||
ARG TARGETARCH
|
|
||||||
|
|
||||||
COPY --from=license-check /license-check /usr/bin/
|
|
||||||
|
|
||||||
WORKDIR /go/src/handler
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
# Run a gofmt and exclude all vendored code.
|
|
||||||
|
|
||||||
RUN license-check -path ./ --verbose=false "OpenFaaS Authors" "OpenFaaS Author(s)"
|
|
||||||
|
|
||||||
RUN test -z "$(gofmt -l $(find . -type f -name '*.go' -not -path "./vendor/*"))"
|
|
||||||
|
|
||||||
RUN CGO_ENABLED=${CGO_ENABLED} GOOS=${TARGETOS} GOARCH=${TARGETARCH} go test -v ./...
|
|
||||||
|
|
||||||
RUN CGO_ENABLED=${CGO_ENABLED} GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build \
|
|
||||||
--ldflags "-s -w" -a -installsuffix cgo -o handler .
|
|
||||||
|
|
||||||
FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:3.17 as ship
|
|
||||||
# Add non-root user
|
|
||||||
RUN addgroup -S app && adduser -S -g app app \
|
|
||||||
&& mkdir -p /home/app \
|
|
||||||
&& chown app /home/app
|
|
||||||
|
|
||||||
WORKDIR /home/app
|
|
||||||
|
|
||||||
COPY --from=build /go/src/handler/handler .
|
|
||||||
|
|
||||||
RUN chown -R app /home/app
|
|
||||||
|
|
||||||
USER app
|
|
||||||
|
|
||||||
WORKDIR /home/app
|
|
||||||
|
|
||||||
CMD ["./handler"]
|
|
@ -1,13 +0,0 @@
|
|||||||
basic-auth
|
|
||||||
============
|
|
||||||
|
|
||||||
This component implements [Basic Authentication](https://en.wikipedia.org/wiki/Basic_access_authentication) as an OpenFaaS authentication plug-in.
|
|
||||||
|
|
||||||
To run this plugin you will need to create and bind a secret named `basic-auth-user` and `basic-auth-password`
|
|
||||||
|
|
||||||
| Option | Usage |
|
|
||||||
|---------------------------------|--------------|
|
|
||||||
| `port` | Set the HTTP port |
|
|
||||||
| `secret_mount_path` | It is recommended that this is set to `/var/openfaas/secrets` |
|
|
||||||
| `user_filename` | File to read from disk for username, default empty |
|
|
||||||
| `pass_filename` | File to read from disk for username, default empty |
|
|
@ -1,8 +0,0 @@
|
|||||||
module github.com/openfaas/faas/auth/basic-auth
|
|
||||||
|
|
||||||
go 1.17
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/openfaas/faas-provider v0.19.0
|
|
||||||
github.com/pkg/errors v0.9.1
|
|
||||||
)
|
|
@ -1,465 +0,0 @@
|
|||||||
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.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/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/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/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/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-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
|
||||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
|
||||||
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/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
|
||||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
|
||||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
|
||||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
|
||||||
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/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
|
||||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
|
||||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
|
||||||
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.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/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.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.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.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.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
|
||||||
github.com/golang/protobuf v1.4.2/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/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 v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
|
||||||
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.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.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.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/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/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/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
|
||||||
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/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
|
||||||
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/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
|
||||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
|
||||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
|
||||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
|
||||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
|
||||||
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/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/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/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 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/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
|
||||||
github.com/openfaas/faas-provider v0.19.0 h1:1dv4HDkWa9/yVkUll23/06y9lf8+tISOxYoHwBXZaJI=
|
|
||||||
github.com/openfaas/faas-provider v0.19.0/go.mod h1:Farrp+9Med8LeK3aoYpqplMP8f5ebTILbCSLg2LPLZk=
|
|
||||||
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.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
|
||||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
|
||||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
|
||||||
github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/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.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
|
||||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
|
||||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
|
||||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
|
||||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
|
||||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
|
||||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
|
||||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
|
||||||
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.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
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.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
|
||||||
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.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/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-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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
|
||||||
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-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-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-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-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/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.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.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.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|
||||||
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-20181114220301-adae6a3d119a/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-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-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-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-20190628185345-da137c7871d7/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-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-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
|
||||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
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-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-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
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-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-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-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-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/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-20181116152217-5ac8a444bdc5/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-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-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-20191001151750-bb3f8db39f24/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-20200106162015-b016eb3dc98e/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-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/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-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
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.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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
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/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-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-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-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-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-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/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-20191012152004-8de300cfc20a/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-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.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
|
||||||
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-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.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/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
|
||||||
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/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-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-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
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-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
|
||||||
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-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/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
|
||||||
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.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
|
||||||
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/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-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.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/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=
|
|
||||||
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 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
|
||||||
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.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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-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.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
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=
|
|
@ -1,81 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/openfaas/faas-provider/auth"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
port := 8080
|
|
||||||
|
|
||||||
if val, ok := os.LookupEnv("port"); ok {
|
|
||||||
intOut, err := strconv.Atoi(val)
|
|
||||||
if err != nil {
|
|
||||||
panic(errors.Wrap(err, fmt.Sprintf("value of `port`: %s, not a valid port", val)))
|
|
||||||
}
|
|
||||||
port = intOut
|
|
||||||
}
|
|
||||||
|
|
||||||
s := &http.Server{
|
|
||||||
Addr: fmt.Sprintf(":%d", port),
|
|
||||||
ReadTimeout: 5 * time.Second,
|
|
||||||
WriteTimeout: 5 * time.Second,
|
|
||||||
MaxHeaderBytes: 1 << 20, // Max header of 1MB
|
|
||||||
}
|
|
||||||
|
|
||||||
credentialsReader := auth.ReadBasicAuthFromDisk{
|
|
||||||
SecretMountPath: os.Getenv("secret_mount_path"),
|
|
||||||
UserFilename: os.Getenv("user_filename"),
|
|
||||||
PasswordFilename: os.Getenv("pass_filename"),
|
|
||||||
}
|
|
||||||
|
|
||||||
credentials, err := credentialsReader.Read()
|
|
||||||
if err != nil {
|
|
||||||
panic(errors.Wrap(err, "unable to read basic auth credentials, check `secret_mount_path`"))
|
|
||||||
}
|
|
||||||
|
|
||||||
authHandler := auth.DecorateWithBasicAuth(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
}, credentials)
|
|
||||||
http.HandleFunc("/validate", makeLogger(authHandler))
|
|
||||||
|
|
||||||
http.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
})
|
|
||||||
|
|
||||||
log.Printf("Listening on: %d\n", port)
|
|
||||||
log.Fatal(s.ListenAndServe())
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeLogger(next http.Handler) func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
|
|
||||||
next.ServeHTTP(rr, r)
|
|
||||||
log.Printf("Validated request %d.\n", rr.Code)
|
|
||||||
|
|
||||||
resHeader := rr.Header()
|
|
||||||
copyHeaders(w.Header(), &resHeader)
|
|
||||||
|
|
||||||
w.WriteHeader(rr.Code)
|
|
||||||
if rr.Body != nil {
|
|
||||||
w.Write(rr.Body.Bytes())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func copyHeaders(destination http.Header, source *http.Header) {
|
|
||||||
for k, v := range *source {
|
|
||||||
vClone := make([]string, len(v))
|
|
||||||
copy(vClone, v)
|
|
||||||
(destination)[k] = vClone
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_makeLogger_CopiesResponseHeaders(t *testing.T) {
|
|
||||||
handler := http.HandlerFunc(makeLogger(http.HandlerFunc(
|
|
||||||
func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("X-Unit-Test", "true")
|
|
||||||
})))
|
|
||||||
|
|
||||||
s := httptest.NewServer(handler)
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodGet, s.URL, nil)
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
|
|
||||||
handler.ServeHTTP(rr, req)
|
|
||||||
|
|
||||||
got := rr.Header().Get("X-Unit-Test")
|
|
||||||
want := "true"
|
|
||||||
if want != got {
|
|
||||||
t.Errorf("Header X-Unit-Test, want: %s, got %s", want, got)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
21
auth/basic-auth/vendor/github.com/openfaas/faas-provider/LICENSE
generated
vendored
21
auth/basic-auth/vendor/github.com/openfaas/faas-provider/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2017 Alex Ellis
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
30
auth/basic-auth/vendor/github.com/openfaas/faas-provider/auth/basic_auth.go
generated
vendored
30
auth/basic-auth/vendor/github.com/openfaas/faas-provider/auth/basic_auth.go
generated
vendored
@ -1,30 +0,0 @@
|
|||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/subtle"
|
|
||||||
"net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// DecorateWithBasicAuth enforces basic auth as a middleware with given credentials
|
|
||||||
func DecorateWithBasicAuth(next http.HandlerFunc, credentials *BasicAuthCredentials) http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
|
|
||||||
user, password, ok := r.BasicAuth()
|
|
||||||
|
|
||||||
const noMatch = 0
|
|
||||||
if !ok ||
|
|
||||||
user != credentials.User ||
|
|
||||||
subtle.ConstantTimeCompare([]byte(credentials.Password), []byte(password)) == noMatch {
|
|
||||||
|
|
||||||
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
|
||||||
w.Write([]byte("invalid credentials"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
next.ServeHTTP(w, r)
|
|
||||||
}
|
|
||||||
}
|
|
66
auth/basic-auth/vendor/github.com/openfaas/faas-provider/auth/credentials.go
generated
vendored
66
auth/basic-auth/vendor/github.com/openfaas/faas-provider/auth/credentials.go
generated
vendored
@ -1,66 +0,0 @@
|
|||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package auth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// BasicAuthCredentials for credentials
|
|
||||||
type BasicAuthCredentials struct {
|
|
||||||
User string
|
|
||||||
Password string
|
|
||||||
}
|
|
||||||
|
|
||||||
type ReadBasicAuth interface {
|
|
||||||
Read() (*BasicAuthCredentials, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ReadBasicAuthFromDisk struct {
|
|
||||||
SecretMountPath string
|
|
||||||
|
|
||||||
UserFilename string
|
|
||||||
|
|
||||||
PasswordFilename string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ReadBasicAuthFromDisk) Read() (*BasicAuthCredentials, error) {
|
|
||||||
var credentials *BasicAuthCredentials
|
|
||||||
|
|
||||||
if len(r.SecretMountPath) == 0 {
|
|
||||||
return nil, fmt.Errorf("invalid SecretMountPath specified for reading secrets")
|
|
||||||
}
|
|
||||||
|
|
||||||
userKey := "basic-auth-user"
|
|
||||||
if len(r.UserFilename) > 0 {
|
|
||||||
userKey = r.UserFilename
|
|
||||||
}
|
|
||||||
|
|
||||||
passwordKey := "basic-auth-password"
|
|
||||||
if len(r.PasswordFilename) > 0 {
|
|
||||||
passwordKey = r.PasswordFilename
|
|
||||||
}
|
|
||||||
|
|
||||||
userPath := path.Join(r.SecretMountPath, userKey)
|
|
||||||
user, userErr := ioutil.ReadFile(userPath)
|
|
||||||
if userErr != nil {
|
|
||||||
return nil, fmt.Errorf("unable to load %s", userPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
userPassword := path.Join(r.SecretMountPath, passwordKey)
|
|
||||||
password, passErr := ioutil.ReadFile(userPassword)
|
|
||||||
if passErr != nil {
|
|
||||||
return nil, fmt.Errorf("Unable to load %s", userPassword)
|
|
||||||
}
|
|
||||||
|
|
||||||
credentials = &BasicAuthCredentials{
|
|
||||||
User: strings.TrimSpace(string(user)),
|
|
||||||
Password: strings.TrimSpace(string(password)),
|
|
||||||
}
|
|
||||||
|
|
||||||
return credentials, nil
|
|
||||||
}
|
|
10
auth/basic-auth/vendor/github.com/pkg/errors/.travis.yml
generated
vendored
10
auth/basic-auth/vendor/github.com/pkg/errors/.travis.yml
generated
vendored
@ -1,10 +0,0 @@
|
|||||||
language: go
|
|
||||||
go_import_path: github.com/pkg/errors
|
|
||||||
go:
|
|
||||||
- 1.11.x
|
|
||||||
- 1.12.x
|
|
||||||
- 1.13.x
|
|
||||||
- tip
|
|
||||||
|
|
||||||
script:
|
|
||||||
- make check
|
|
23
auth/basic-auth/vendor/github.com/pkg/errors/LICENSE
generated
vendored
23
auth/basic-auth/vendor/github.com/pkg/errors/LICENSE
generated
vendored
@ -1,23 +0,0 @@
|
|||||||
Copyright (c) 2015, Dave Cheney <dave@cheney.net>
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright notice, this
|
|
||||||
list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer in the documentation
|
|
||||||
and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
||||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
||||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
||||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
||||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
44
auth/basic-auth/vendor/github.com/pkg/errors/Makefile
generated
vendored
44
auth/basic-auth/vendor/github.com/pkg/errors/Makefile
generated
vendored
@ -1,44 +0,0 @@
|
|||||||
PKGS := github.com/pkg/errors
|
|
||||||
SRCDIRS := $(shell go list -f '{{.Dir}}' $(PKGS))
|
|
||||||
GO := go
|
|
||||||
|
|
||||||
check: test vet gofmt misspell unconvert staticcheck ineffassign unparam
|
|
||||||
|
|
||||||
test:
|
|
||||||
$(GO) test $(PKGS)
|
|
||||||
|
|
||||||
vet: | test
|
|
||||||
$(GO) vet $(PKGS)
|
|
||||||
|
|
||||||
staticcheck:
|
|
||||||
$(GO) get honnef.co/go/tools/cmd/staticcheck
|
|
||||||
staticcheck -checks all $(PKGS)
|
|
||||||
|
|
||||||
misspell:
|
|
||||||
$(GO) get github.com/client9/misspell/cmd/misspell
|
|
||||||
misspell \
|
|
||||||
-locale GB \
|
|
||||||
-error \
|
|
||||||
*.md *.go
|
|
||||||
|
|
||||||
unconvert:
|
|
||||||
$(GO) get github.com/mdempsky/unconvert
|
|
||||||
unconvert -v $(PKGS)
|
|
||||||
|
|
||||||
ineffassign:
|
|
||||||
$(GO) get github.com/gordonklaus/ineffassign
|
|
||||||
find $(SRCDIRS) -name '*.go' | xargs ineffassign
|
|
||||||
|
|
||||||
pedantic: check errcheck
|
|
||||||
|
|
||||||
unparam:
|
|
||||||
$(GO) get mvdan.cc/unparam
|
|
||||||
unparam ./...
|
|
||||||
|
|
||||||
errcheck:
|
|
||||||
$(GO) get github.com/kisielk/errcheck
|
|
||||||
errcheck $(PKGS)
|
|
||||||
|
|
||||||
gofmt:
|
|
||||||
@echo Checking code is gofmted
|
|
||||||
@test -z "$(shell gofmt -s -l -d -e $(SRCDIRS) | tee /dev/stderr)"
|
|
59
auth/basic-auth/vendor/github.com/pkg/errors/README.md
generated
vendored
59
auth/basic-auth/vendor/github.com/pkg/errors/README.md
generated
vendored
@ -1,59 +0,0 @@
|
|||||||
# errors [](https://travis-ci.org/pkg/errors) [](https://ci.appveyor.com/project/davecheney/errors/branch/master) [](http://godoc.org/github.com/pkg/errors) [](https://goreportcard.com/report/github.com/pkg/errors) [](https://sourcegraph.com/github.com/pkg/errors?badge)
|
|
||||||
|
|
||||||
Package errors provides simple error handling primitives.
|
|
||||||
|
|
||||||
`go get github.com/pkg/errors`
|
|
||||||
|
|
||||||
The traditional error handling idiom in Go is roughly akin to
|
|
||||||
```go
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
```
|
|
||||||
which applied recursively up the call stack results in error reports without context or debugging information. The errors package allows programmers to add context to the failure path in their code in a way that does not destroy the original value of the error.
|
|
||||||
|
|
||||||
## Adding context to an error
|
|
||||||
|
|
||||||
The errors.Wrap function returns a new error that adds context to the original error. For example
|
|
||||||
```go
|
|
||||||
_, err := ioutil.ReadAll(r)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "read failed")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
## Retrieving the cause of an error
|
|
||||||
|
|
||||||
Using `errors.Wrap` constructs a stack of errors, adding context to the preceding error. Depending on the nature of the error it may be necessary to reverse the operation of errors.Wrap to retrieve the original error for inspection. Any error value which implements this interface can be inspected by `errors.Cause`.
|
|
||||||
```go
|
|
||||||
type causer interface {
|
|
||||||
Cause() error
|
|
||||||
}
|
|
||||||
```
|
|
||||||
`errors.Cause` will recursively retrieve the topmost error which does not implement `causer`, which is assumed to be the original cause. For example:
|
|
||||||
```go
|
|
||||||
switch err := errors.Cause(err).(type) {
|
|
||||||
case *MyError:
|
|
||||||
// handle specifically
|
|
||||||
default:
|
|
||||||
// unknown error
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
[Read the package documentation for more information](https://godoc.org/github.com/pkg/errors).
|
|
||||||
|
|
||||||
## Roadmap
|
|
||||||
|
|
||||||
With the upcoming [Go2 error proposals](https://go.googlesource.com/proposal/+/master/design/go2draft.md) this package is moving into maintenance mode. The roadmap for a 1.0 release is as follows:
|
|
||||||
|
|
||||||
- 0.9. Remove pre Go 1.9 and Go 1.10 support, address outstanding pull requests (if possible)
|
|
||||||
- 1.0. Final release.
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Because of the Go2 errors changes, this package is not accepting proposals for new functionality. With that said, we welcome pull requests, bug fixes and issue reports.
|
|
||||||
|
|
||||||
Before sending a PR, please discuss your change by raising an issue.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
BSD-2-Clause
|
|
32
auth/basic-auth/vendor/github.com/pkg/errors/appveyor.yml
generated
vendored
32
auth/basic-auth/vendor/github.com/pkg/errors/appveyor.yml
generated
vendored
@ -1,32 +0,0 @@
|
|||||||
version: build-{build}.{branch}
|
|
||||||
|
|
||||||
clone_folder: C:\gopath\src\github.com\pkg\errors
|
|
||||||
shallow_clone: true # for startup speed
|
|
||||||
|
|
||||||
environment:
|
|
||||||
GOPATH: C:\gopath
|
|
||||||
|
|
||||||
platform:
|
|
||||||
- x64
|
|
||||||
|
|
||||||
# http://www.appveyor.com/docs/installed-software
|
|
||||||
install:
|
|
||||||
# some helpful output for debugging builds
|
|
||||||
- go version
|
|
||||||
- go env
|
|
||||||
# pre-installed MinGW at C:\MinGW is 32bit only
|
|
||||||
# but MSYS2 at C:\msys64 has mingw64
|
|
||||||
- set PATH=C:\msys64\mingw64\bin;%PATH%
|
|
||||||
- gcc --version
|
|
||||||
- g++ --version
|
|
||||||
|
|
||||||
build_script:
|
|
||||||
- go install -v ./...
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- set PATH=C:\gopath\bin;%PATH%
|
|
||||||
- go test -v ./...
|
|
||||||
|
|
||||||
#artifacts:
|
|
||||||
# - path: '%GOPATH%\bin\*.exe'
|
|
||||||
deploy: off
|
|
288
auth/basic-auth/vendor/github.com/pkg/errors/errors.go
generated
vendored
288
auth/basic-auth/vendor/github.com/pkg/errors/errors.go
generated
vendored
@ -1,288 +0,0 @@
|
|||||||
// Package errors provides simple error handling primitives.
|
|
||||||
//
|
|
||||||
// The traditional error handling idiom in Go is roughly akin to
|
|
||||||
//
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// which when applied recursively up the call stack results in error reports
|
|
||||||
// without context or debugging information. The errors package allows
|
|
||||||
// programmers to add context to the failure path in their code in a way
|
|
||||||
// that does not destroy the original value of the error.
|
|
||||||
//
|
|
||||||
// # Adding context to an error
|
|
||||||
//
|
|
||||||
// The errors.Wrap function returns a new error that adds context to the
|
|
||||||
// original error by recording a stack trace at the point Wrap is called,
|
|
||||||
// together with the supplied message. For example
|
|
||||||
//
|
|
||||||
// _, err := ioutil.ReadAll(r)
|
|
||||||
// if err != nil {
|
|
||||||
// return errors.Wrap(err, "read failed")
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// If additional control is required, the errors.WithStack and
|
|
||||||
// errors.WithMessage functions destructure errors.Wrap into its component
|
|
||||||
// operations: annotating an error with a stack trace and with a message,
|
|
||||||
// respectively.
|
|
||||||
//
|
|
||||||
// # Retrieving the cause of an error
|
|
||||||
//
|
|
||||||
// Using errors.Wrap constructs a stack of errors, adding context to the
|
|
||||||
// preceding error. Depending on the nature of the error it may be necessary
|
|
||||||
// to reverse the operation of errors.Wrap to retrieve the original error
|
|
||||||
// for inspection. Any error value which implements this interface
|
|
||||||
//
|
|
||||||
// type causer interface {
|
|
||||||
// Cause() error
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// can be inspected by errors.Cause. errors.Cause will recursively retrieve
|
|
||||||
// the topmost error that does not implement causer, which is assumed to be
|
|
||||||
// the original cause. For example:
|
|
||||||
//
|
|
||||||
// switch err := errors.Cause(err).(type) {
|
|
||||||
// case *MyError:
|
|
||||||
// // handle specifically
|
|
||||||
// default:
|
|
||||||
// // unknown error
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Although the causer interface is not exported by this package, it is
|
|
||||||
// considered a part of its stable public interface.
|
|
||||||
//
|
|
||||||
// # Formatted printing of errors
|
|
||||||
//
|
|
||||||
// All error values returned from this package implement fmt.Formatter and can
|
|
||||||
// be formatted by the fmt package. The following verbs are supported:
|
|
||||||
//
|
|
||||||
// %s print the error. If the error has a Cause it will be
|
|
||||||
// printed recursively.
|
|
||||||
// %v see %s
|
|
||||||
// %+v extended format. Each Frame of the error's StackTrace will
|
|
||||||
// be printed in detail.
|
|
||||||
//
|
|
||||||
// # Retrieving the stack trace of an error or wrapper
|
|
||||||
//
|
|
||||||
// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are
|
|
||||||
// invoked. This information can be retrieved with the following interface:
|
|
||||||
//
|
|
||||||
// type stackTracer interface {
|
|
||||||
// StackTrace() errors.StackTrace
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// The returned errors.StackTrace type is defined as
|
|
||||||
//
|
|
||||||
// type StackTrace []Frame
|
|
||||||
//
|
|
||||||
// The Frame type represents a call site in the stack trace. Frame supports
|
|
||||||
// the fmt.Formatter interface that can be used for printing information about
|
|
||||||
// the stack trace of this error. For example:
|
|
||||||
//
|
|
||||||
// if err, ok := err.(stackTracer); ok {
|
|
||||||
// for _, f := range err.StackTrace() {
|
|
||||||
// fmt.Printf("%+s:%d\n", f, f)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Although the stackTracer interface is not exported by this package, it is
|
|
||||||
// considered a part of its stable public interface.
|
|
||||||
//
|
|
||||||
// See the documentation for Frame.Format for more details.
|
|
||||||
package errors
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
)
|
|
||||||
|
|
||||||
// New returns an error with the supplied message.
|
|
||||||
// New also records the stack trace at the point it was called.
|
|
||||||
func New(message string) error {
|
|
||||||
return &fundamental{
|
|
||||||
msg: message,
|
|
||||||
stack: callers(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Errorf formats according to a format specifier and returns the string
|
|
||||||
// as a value that satisfies error.
|
|
||||||
// Errorf also records the stack trace at the point it was called.
|
|
||||||
func Errorf(format string, args ...interface{}) error {
|
|
||||||
return &fundamental{
|
|
||||||
msg: fmt.Sprintf(format, args...),
|
|
||||||
stack: callers(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// fundamental is an error that has a message and a stack, but no caller.
|
|
||||||
type fundamental struct {
|
|
||||||
msg string
|
|
||||||
*stack
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fundamental) Error() string { return f.msg }
|
|
||||||
|
|
||||||
func (f *fundamental) Format(s fmt.State, verb rune) {
|
|
||||||
switch verb {
|
|
||||||
case 'v':
|
|
||||||
if s.Flag('+') {
|
|
||||||
io.WriteString(s, f.msg)
|
|
||||||
f.stack.Format(s, verb)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fallthrough
|
|
||||||
case 's':
|
|
||||||
io.WriteString(s, f.msg)
|
|
||||||
case 'q':
|
|
||||||
fmt.Fprintf(s, "%q", f.msg)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithStack annotates err with a stack trace at the point WithStack was called.
|
|
||||||
// If err is nil, WithStack returns nil.
|
|
||||||
func WithStack(err error) error {
|
|
||||||
if err == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &withStack{
|
|
||||||
err,
|
|
||||||
callers(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type withStack struct {
|
|
||||||
error
|
|
||||||
*stack
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *withStack) Cause() error { return w.error }
|
|
||||||
|
|
||||||
// Unwrap provides compatibility for Go 1.13 error chains.
|
|
||||||
func (w *withStack) Unwrap() error { return w.error }
|
|
||||||
|
|
||||||
func (w *withStack) Format(s fmt.State, verb rune) {
|
|
||||||
switch verb {
|
|
||||||
case 'v':
|
|
||||||
if s.Flag('+') {
|
|
||||||
fmt.Fprintf(s, "%+v", w.Cause())
|
|
||||||
w.stack.Format(s, verb)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fallthrough
|
|
||||||
case 's':
|
|
||||||
io.WriteString(s, w.Error())
|
|
||||||
case 'q':
|
|
||||||
fmt.Fprintf(s, "%q", w.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap returns an error annotating err with a stack trace
|
|
||||||
// at the point Wrap is called, and the supplied message.
|
|
||||||
// If err is nil, Wrap returns nil.
|
|
||||||
func Wrap(err error, message string) error {
|
|
||||||
if err == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
err = &withMessage{
|
|
||||||
cause: err,
|
|
||||||
msg: message,
|
|
||||||
}
|
|
||||||
return &withStack{
|
|
||||||
err,
|
|
||||||
callers(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrapf returns an error annotating err with a stack trace
|
|
||||||
// at the point Wrapf is called, and the format specifier.
|
|
||||||
// If err is nil, Wrapf returns nil.
|
|
||||||
func Wrapf(err error, format string, args ...interface{}) error {
|
|
||||||
if err == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
err = &withMessage{
|
|
||||||
cause: err,
|
|
||||||
msg: fmt.Sprintf(format, args...),
|
|
||||||
}
|
|
||||||
return &withStack{
|
|
||||||
err,
|
|
||||||
callers(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithMessage annotates err with a new message.
|
|
||||||
// If err is nil, WithMessage returns nil.
|
|
||||||
func WithMessage(err error, message string) error {
|
|
||||||
if err == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &withMessage{
|
|
||||||
cause: err,
|
|
||||||
msg: message,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithMessagef annotates err with the format specifier.
|
|
||||||
// If err is nil, WithMessagef returns nil.
|
|
||||||
func WithMessagef(err error, format string, args ...interface{}) error {
|
|
||||||
if err == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &withMessage{
|
|
||||||
cause: err,
|
|
||||||
msg: fmt.Sprintf(format, args...),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type withMessage struct {
|
|
||||||
cause error
|
|
||||||
msg string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *withMessage) Error() string { return w.msg + ": " + w.cause.Error() }
|
|
||||||
func (w *withMessage) Cause() error { return w.cause }
|
|
||||||
|
|
||||||
// Unwrap provides compatibility for Go 1.13 error chains.
|
|
||||||
func (w *withMessage) Unwrap() error { return w.cause }
|
|
||||||
|
|
||||||
func (w *withMessage) Format(s fmt.State, verb rune) {
|
|
||||||
switch verb {
|
|
||||||
case 'v':
|
|
||||||
if s.Flag('+') {
|
|
||||||
fmt.Fprintf(s, "%+v\n", w.Cause())
|
|
||||||
io.WriteString(s, w.msg)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
fallthrough
|
|
||||||
case 's', 'q':
|
|
||||||
io.WriteString(s, w.Error())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cause returns the underlying cause of the error, if possible.
|
|
||||||
// An error value has a cause if it implements the following
|
|
||||||
// interface:
|
|
||||||
//
|
|
||||||
// type causer interface {
|
|
||||||
// Cause() error
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// If the error does not implement Cause, the original error will
|
|
||||||
// be returned. If the error is nil, nil will be returned without further
|
|
||||||
// investigation.
|
|
||||||
func Cause(err error) error {
|
|
||||||
type causer interface {
|
|
||||||
Cause() error
|
|
||||||
}
|
|
||||||
|
|
||||||
for err != nil {
|
|
||||||
cause, ok := err.(causer)
|
|
||||||
if !ok {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
err = cause.Cause()
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
39
auth/basic-auth/vendor/github.com/pkg/errors/go113.go
generated
vendored
39
auth/basic-auth/vendor/github.com/pkg/errors/go113.go
generated
vendored
@ -1,39 +0,0 @@
|
|||||||
//go:build go1.13
|
|
||||||
// +build go1.13
|
|
||||||
|
|
||||||
package errors
|
|
||||||
|
|
||||||
import (
|
|
||||||
stderrors "errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Is reports whether any error in err's chain matches target.
|
|
||||||
//
|
|
||||||
// The chain consists of err itself followed by the sequence of errors obtained by
|
|
||||||
// repeatedly calling Unwrap.
|
|
||||||
//
|
|
||||||
// An error is considered to match a target if it is equal to that target or if
|
|
||||||
// it implements a method Is(error) bool such that Is(target) returns true.
|
|
||||||
func Is(err, target error) bool { return stderrors.Is(err, target) }
|
|
||||||
|
|
||||||
// As finds the first error in err's chain that matches target, and if so, sets
|
|
||||||
// target to that error value and returns true.
|
|
||||||
//
|
|
||||||
// The chain consists of err itself followed by the sequence of errors obtained by
|
|
||||||
// repeatedly calling Unwrap.
|
|
||||||
//
|
|
||||||
// An error matches target if the error's concrete value is assignable to the value
|
|
||||||
// pointed to by target, or if the error has a method As(interface{}) bool such that
|
|
||||||
// As(target) returns true. In the latter case, the As method is responsible for
|
|
||||||
// setting target.
|
|
||||||
//
|
|
||||||
// As will panic if target is not a non-nil pointer to either a type that implements
|
|
||||||
// error, or to any interface type. As returns false if err is nil.
|
|
||||||
func As(err error, target interface{}) bool { return stderrors.As(err, target) }
|
|
||||||
|
|
||||||
// Unwrap returns the result of calling the Unwrap method on err, if err's
|
|
||||||
// type contains an Unwrap method returning error.
|
|
||||||
// Otherwise, Unwrap returns nil.
|
|
||||||
func Unwrap(err error) error {
|
|
||||||
return stderrors.Unwrap(err)
|
|
||||||
}
|
|
177
auth/basic-auth/vendor/github.com/pkg/errors/stack.go
generated
vendored
177
auth/basic-auth/vendor/github.com/pkg/errors/stack.go
generated
vendored
@ -1,177 +0,0 @@
|
|||||||
package errors
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"path"
|
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Frame represents a program counter inside a stack frame.
|
|
||||||
// For historical reasons if Frame is interpreted as a uintptr
|
|
||||||
// its value represents the program counter + 1.
|
|
||||||
type Frame uintptr
|
|
||||||
|
|
||||||
// pc returns the program counter for this frame;
|
|
||||||
// multiple frames may have the same PC value.
|
|
||||||
func (f Frame) pc() uintptr { return uintptr(f) - 1 }
|
|
||||||
|
|
||||||
// file returns the full path to the file that contains the
|
|
||||||
// function for this Frame's pc.
|
|
||||||
func (f Frame) file() string {
|
|
||||||
fn := runtime.FuncForPC(f.pc())
|
|
||||||
if fn == nil {
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
file, _ := fn.FileLine(f.pc())
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
|
|
||||||
// line returns the line number of source code of the
|
|
||||||
// function for this Frame's pc.
|
|
||||||
func (f Frame) line() int {
|
|
||||||
fn := runtime.FuncForPC(f.pc())
|
|
||||||
if fn == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
_, line := fn.FileLine(f.pc())
|
|
||||||
return line
|
|
||||||
}
|
|
||||||
|
|
||||||
// name returns the name of this function, if known.
|
|
||||||
func (f Frame) name() string {
|
|
||||||
fn := runtime.FuncForPC(f.pc())
|
|
||||||
if fn == nil {
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
return fn.Name()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Format formats the frame according to the fmt.Formatter interface.
|
|
||||||
//
|
|
||||||
// %s source file
|
|
||||||
// %d source line
|
|
||||||
// %n function name
|
|
||||||
// %v equivalent to %s:%d
|
|
||||||
//
|
|
||||||
// Format accepts flags that alter the printing of some verbs, as follows:
|
|
||||||
//
|
|
||||||
// %+s function name and path of source file relative to the compile time
|
|
||||||
// GOPATH separated by \n\t (<funcname>\n\t<path>)
|
|
||||||
// %+v equivalent to %+s:%d
|
|
||||||
func (f Frame) Format(s fmt.State, verb rune) {
|
|
||||||
switch verb {
|
|
||||||
case 's':
|
|
||||||
switch {
|
|
||||||
case s.Flag('+'):
|
|
||||||
io.WriteString(s, f.name())
|
|
||||||
io.WriteString(s, "\n\t")
|
|
||||||
io.WriteString(s, f.file())
|
|
||||||
default:
|
|
||||||
io.WriteString(s, path.Base(f.file()))
|
|
||||||
}
|
|
||||||
case 'd':
|
|
||||||
io.WriteString(s, strconv.Itoa(f.line()))
|
|
||||||
case 'n':
|
|
||||||
io.WriteString(s, funcname(f.name()))
|
|
||||||
case 'v':
|
|
||||||
f.Format(s, 's')
|
|
||||||
io.WriteString(s, ":")
|
|
||||||
f.Format(s, 'd')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalText formats a stacktrace Frame as a text string. The output is the
|
|
||||||
// same as that of fmt.Sprintf("%+v", f), but without newlines or tabs.
|
|
||||||
func (f Frame) MarshalText() ([]byte, error) {
|
|
||||||
name := f.name()
|
|
||||||
if name == "unknown" {
|
|
||||||
return []byte(name), nil
|
|
||||||
}
|
|
||||||
return []byte(fmt.Sprintf("%s %s:%d", name, f.file(), f.line())), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
|
|
||||||
type StackTrace []Frame
|
|
||||||
|
|
||||||
// Format formats the stack of Frames according to the fmt.Formatter interface.
|
|
||||||
//
|
|
||||||
// %s lists source files for each Frame in the stack
|
|
||||||
// %v lists the source file and line number for each Frame in the stack
|
|
||||||
//
|
|
||||||
// Format accepts flags that alter the printing of some verbs, as follows:
|
|
||||||
//
|
|
||||||
// %+v Prints filename, function, and line number for each Frame in the stack.
|
|
||||||
func (st StackTrace) Format(s fmt.State, verb rune) {
|
|
||||||
switch verb {
|
|
||||||
case 'v':
|
|
||||||
switch {
|
|
||||||
case s.Flag('+'):
|
|
||||||
for _, f := range st {
|
|
||||||
io.WriteString(s, "\n")
|
|
||||||
f.Format(s, verb)
|
|
||||||
}
|
|
||||||
case s.Flag('#'):
|
|
||||||
fmt.Fprintf(s, "%#v", []Frame(st))
|
|
||||||
default:
|
|
||||||
st.formatSlice(s, verb)
|
|
||||||
}
|
|
||||||
case 's':
|
|
||||||
st.formatSlice(s, verb)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// formatSlice will format this StackTrace into the given buffer as a slice of
|
|
||||||
// Frame, only valid when called with '%s' or '%v'.
|
|
||||||
func (st StackTrace) formatSlice(s fmt.State, verb rune) {
|
|
||||||
io.WriteString(s, "[")
|
|
||||||
for i, f := range st {
|
|
||||||
if i > 0 {
|
|
||||||
io.WriteString(s, " ")
|
|
||||||
}
|
|
||||||
f.Format(s, verb)
|
|
||||||
}
|
|
||||||
io.WriteString(s, "]")
|
|
||||||
}
|
|
||||||
|
|
||||||
// stack represents a stack of program counters.
|
|
||||||
type stack []uintptr
|
|
||||||
|
|
||||||
func (s *stack) Format(st fmt.State, verb rune) {
|
|
||||||
switch verb {
|
|
||||||
case 'v':
|
|
||||||
switch {
|
|
||||||
case st.Flag('+'):
|
|
||||||
for _, pc := range *s {
|
|
||||||
f := Frame(pc)
|
|
||||||
fmt.Fprintf(st, "\n%+v", f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stack) StackTrace() StackTrace {
|
|
||||||
f := make([]Frame, len(*s))
|
|
||||||
for i := 0; i < len(f); i++ {
|
|
||||||
f[i] = Frame((*s)[i])
|
|
||||||
}
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
|
|
||||||
func callers() *stack {
|
|
||||||
const depth = 32
|
|
||||||
var pcs [depth]uintptr
|
|
||||||
n := runtime.Callers(3, pcs[:])
|
|
||||||
var st stack = pcs[0:n]
|
|
||||||
return &st
|
|
||||||
}
|
|
||||||
|
|
||||||
// funcname removes the path prefix component of a function's name reported by func.Name().
|
|
||||||
func funcname(name string) string {
|
|
||||||
i := strings.LastIndex(name, "/")
|
|
||||||
name = name[i+1:]
|
|
||||||
i = strings.Index(name, ".")
|
|
||||||
return name[i+1:]
|
|
||||||
}
|
|
6
auth/basic-auth/vendor/modules.txt
vendored
6
auth/basic-auth/vendor/modules.txt
vendored
@ -1,6 +0,0 @@
|
|||||||
# github.com/openfaas/faas-provider v0.19.0
|
|
||||||
## explicit; go 1.17
|
|
||||||
github.com/openfaas/faas-provider/auth
|
|
||||||
# github.com/pkg/errors v0.9.1
|
|
||||||
## explicit
|
|
||||||
github.com/pkg/errors
|
|
49
community.md
49
community.md
@ -84,20 +84,55 @@ It would be great to hear from you especially if you have any of the above and w
|
|||||||
| [Digital Transformation of Vision Banco Paraguay with Serverless Functions @ KubeCon](https://kccna18.sched.com/event/GraO/digital-transformation-of-vision-banco-paraguay-with-serverless-functions-alex-ellis-vmware-patricio-diaz-vision-banco-saeca) | Alex Ellis & Patricio Diaz | 13-Dec-2018 |
|
| [Digital Transformation of Vision Banco Paraguay with Serverless Functions @ KubeCon](https://kccna18.sched.com/event/GraO/digital-transformation-of-vision-banco-paraguay-with-serverless-functions-alex-ellis-vmware-patricio-diaz-vision-banco-saeca) | Alex Ellis & Patricio Diaz | 13-Dec-2018 |
|
||||||
| [Introducing "faas" - Cool Hacks Keynote at Dockercon 2017](https://blog.docker.com/2017/04/dockercon-2017-mobys-cool-hack-sessions/) | Alex Ellis | 04-April-2017 |
|
| [Introducing "faas" - Cool Hacks Keynote at Dockercon 2017](https://blog.docker.com/2017/04/dockercon-2017-mobys-cool-hack-sessions/) | Alex Ellis | 04-April-2017 |
|
||||||
|
|
||||||
### 2022
|
### 2023
|
||||||
|
|
||||||
#### Blog posts and write-ups 2022
|
#### Blog posts, write-ups and videos 2023
|
||||||
|
|
||||||
[Back to top](#openfaas-community)
|
[Back to top](#openfaas-community)
|
||||||
|
|
||||||
| Blog/repo name and description | Author | Site | Date |
|
| Blog/video/repo name and description | Author | Site | Date |
|
||||||
|-------------------------------------------------------------------------|--------------|----------|-------------|
|
|-------------------------------------------------------------------------|--------------|----------|-------------|
|
||||||
| [The Event-Driven Edge with OpenFaaS](https://www.openfaas.com/blog/eventdriven-edge/) | Han Verstraete | openfaas.com | 01-June-2022 |
|
| [Building OpenFaaS Serverless function to detect weather using OpenWeatherMap and Python](https://www.faizanbashir.me/building-openfaas-serverless-function-to-detect-weather-using-openweathermap-and-python) | Faizan Bashir | faizanbashir.me | 02-Apr-2023 |
|
||||||
|
| [Fine-tuning the cold-start in OpenFaaS ](https://www.openfaas.com/blog/fine-tuning-the-cold-start/) | Alex Ellis | openfaas.com | 28-Mar-2023 |
|
||||||
|
| [How do changes to the Docker Hub affect OpenFaaS?](https://www.openfaas.com/blog/how-does-docker-hub-affect-openfaas/) | Alex Ellis | openfaas.com | 20-Mar-2023 |
|
||||||
|
| [Cluster auto-scaling with DigitalOcean Kubernetes and OpenFaaS](https://www.openfaas.com/blog/cluster-autoscaling-with-digitalocean/) | Alex Ellis | openfaas.com | 16-Mar-2023 |
|
||||||
|
| [Import leads from Google Forms into your CRM with functions](https://www.openfaas.com/blog/import-leads-from-google-forms-to-crm/) | Alex Ellis | openfaas.com | 02-Mar-2023 |
|
||||||
|
| [Using OpenFaaS on AKS](https://learn.microsoft.com/en-us/azure/aks/openfaas) | Various | learn.microsoft.com | 27-Feb-2023 |
|
||||||
|
| [How to integrate OpenFaaS functions with managed AWS services](https://www.openfaas.com/blog/integrate-openfaas-with-managed-aws-services/) | Han Verstraete | openfaas.com | 19-Jan-2023 |
|
||||||
|
|
||||||
|
### 2022
|
||||||
|
|
||||||
|
#### Blog posts, write-ups and videos 2022
|
||||||
|
|
||||||
|
[Back to top](#openfaas-community)
|
||||||
|
|
||||||
|
| Blog/video/repo name and description | Author | Site | Date |
|
||||||
|
|-------------------------------------------------------------------------|--------------|----------|-------------|
|
||||||
|
| [Trigger OpenFaaS functions from PostgreSQL with AWS Aurora](https://www.openfaas.com/blog/trigger-functions-from-postgres/) | Han Verstraete | openfaas.com | 16-Dec-2022 |
|
||||||
|
| [Introducing our new Python template for production](https://www.openfaas.com/blog/openfaas-pro-python-template/) | Han Verstraete | openfaas.com | 06-Dec-2022 |
|
||||||
|
| [Deploy Serverless Function on k3s/Kubernetes with OpenFaaS (x86/Arm, Linux VM, Go)](https://www.youtube.com/watch?v=-8MrDWg6K6s) | David Hwang | youtube.com | 09-Nov-2022 |
|
||||||
|
| [Rethinking Auto-scaling for OpenFaaS](https://www.openfaas.com/blog/autoscaling-functions/) | Han Verstraete | openfaas.com | 05-Nov-2022 |
|
||||||
|
| [Custom health and readiness checks for your OpenFaaS Functions](https://www.openfaas.com/blog/health-and-readiness-for-functions/) | Alex Ellis | openfaas.com | 26-Oct-2022 |
|
||||||
|
| [Generate PDFs at scale on Kubernetes using OpenFaaS and Puppeteer](https://www.openfaas.com/blog/pdf-generation-at-scale-on-kubernetes/) | Han Verstraete | openfaas.com | 06-Oct-2022 |
|
||||||
|
| [Eliminate vendor locking of Serverless workloads with OpenFaaS](https://awstip.com/eliminate-vendor-lock-in-of-serverless-workloads-with-openfaas-474807383ce1) | Meher Chaitanya | medium.com | 06-Oct-2022 |
|
||||||
|
| [Use the Serverless Function Method to Build a Machine Learning Microservice System](https://blog.infuseai.io/use-serverless-function-method-to-build-a-ml-microservice-system-a108f3f2c1c) | SimonLiu | blog.infuseai.io | 30-Aug-2022 |
|
||||||
|
| [Go Functions as a Service With Kubernetes and OpenFaaS](https://dominikbraun.io/blog/go-functions-as-a-service-with-kubernetes-and-openfaas/) | Dominik Braun | dominikbraun.io | 24-Aug-2022 |
|
||||||
|
| [Exploring the Fan out and Fan in pattern with OpenFaaS](https://www.openfaas.com/blog/fan-out-and-back-in-using-functions/) | Han Verstraete | openfaas.com | 22-Aug-2022 |
|
||||||
|
| [Finding Raspberry Pis with Raspberry Pis](https://www.openfaas.com/blog/searching-for-raspberrypi/) | Alex Ellis | openfaas.com | 08-Aug-2022 |
|
||||||
|
| [The Next Generation of Queuing: JetStream for OpenFaaS](https://www.openfaas.com/blog/jetstream-for-openfaas/) | Han Verstraete | openfaas.com | 21-Jul-2022 |
|
||||||
|
| [How to update your OpenFaaS functions automatically with the Argo CD Image Updater](https://www.openfaas.com/blog/argocd-image-updater-for-functions/) | Han Verstraete | openfaas.com | 04-Jul-2022 |
|
||||||
|
| [How to build functions from source code with the Function Builder API](https://www.openfaas.com/blog/how-to-build-via-api/) | Han Verstraete | openfaas.com | 23-Jun-2022 |
|
||||||
|
| [OpenFaaS First Function](https://rpi4cluster.com/k3s/k3s-openfaas-function/) | Vlado Portos | rpi4cluster.com | 22-Jun-2022 |
|
||||||
|
| [OpenFaaS](https://rpi4cluster.com/k3s/k3s-openfaas/) | Vlado Portos | rpi4cluster.com | 22-Jun-2022 |
|
||||||
|
| [How to package OpenFaaS functions with Helm](https://www.openfaas.com/blog/howto-package-functions-with-helm/) | Han Verstraete | openfaas.com | 09-Jun-2022 |
|
||||||
|
| [The Event-Driven Edge with OpenFaaS](https://www.openfaas.com/blog/eventdriven-edge/) | Han Verstraete | openfaas.com | 01-Jun-2022 |
|
||||||
| [Running faasd on Azure Arm-based Virtual Machines](https://blog.ediri.io/running-faasd-on-azure-arm-based-virtual-machines) | Engin Diri | blog.ediri.io | 27-May-2022 |
|
| [Running faasd on Azure Arm-based Virtual Machines](https://blog.ediri.io/running-faasd-on-azure-arm-based-virtual-machines) | Engin Diri | blog.ediri.io | 27-May-2022 |
|
||||||
| [WebAssembly functions in OpenFaaS using Sat (Part1)](https://www.wasm.builders/suborbital/webassembly-functions-in-openfaas-using-sat-part-1-2omk) | Connor Hicks | wasm.builders | 04-May-2022 |
|
| [WebAssembly functions in OpenFaaS using Sat (Part1)](https://www.wasm.builders/suborbital/webassembly-functions-in-openfaas-using-sat-part-1-2omk) | Connor Hicks | wasm.builders | 04-May-2022 |
|
||||||
| [Building a RESTful API with functions](https://simonemms.com/blog/2022/04/24/building-a-restful-api-with-serverless-functions/) | Simon Emms | simonemms.com | 24-April-2022 |
|
| [Building a RESTful API with functions](https://simonemms.com/blog/2022/04/24/building-a-restful-api-with-serverless-functions/) | Simon Emms | simonemms.com | 24-Apr-2022 |
|
||||||
| [How to process your data the resilient way with back pressure](https://www.openfaas.com/blog/limits-and-backpressure/) | Alex Ellis | openfaas.com | 12-May-2022 |
|
| [How to process your data the resilient way with back pressure](https://www.openfaas.com/blog/limits-and-backpressure/) | Alex Ellis | openfaas.com | 12-May-2022 |
|
||||||
| [A Deep Dive into Golang for OpenFaaS Functions](https://www.openfaas.com/blog/golang-deep-dive/) | Alex Ellis | openfaas.com | 13-April-2022 |
|
| [Open-Faas on Centos 7](https://medium.com/geekculture/open-faas-on-centos-7-c4dc629f28fe) | Heshani Samarasekara | medium.com | 07-May-2022 |
|
||||||
|
| [A Deep Dive into Golang for OpenFaaS Functions](https://www.openfaas.com/blog/golang-deep-dive/) | Alex Ellis | openfaas.com | 13-Apr-2022 |
|
||||||
|
| [Serverless Architecture with OpenFaaS and Java](https://www.xenonstack.com/blog/serverless-open-faas-java) | Navdeep Singh Gill | xenonstack.com | 13-Mar-2022 |
|
||||||
| [My Journey Contributing To OpenFaaS So Far](https://www.openfaas.com/blog/my-journey-contributing-to-openfaas/) | Nitishkumar Singh | openfaas.com | 02-Mar-2022 |
|
| [My Journey Contributing To OpenFaaS So Far](https://www.openfaas.com/blog/my-journey-contributing-to-openfaas/) | Nitishkumar Singh | openfaas.com | 02-Mar-2022 |
|
||||||
| [Your pocket-sized cloud with a Raspberry Pi](https://blog.alexellis.io/your-pocket-sized-cloud/) | Alex Ellis | openfaas.com | 23-Mar-2022 |
|
| [Your pocket-sized cloud with a Raspberry Pi](https://blog.alexellis.io/your-pocket-sized-cloud/) | Alex Ellis | openfaas.com | 23-Mar-2022 |
|
||||||
| [Hosting a React App with OpenFaaS](https://www.openfaas.com/blog/react-app/) | Alex Ellis | openfaas.com | 01-Mar-2022 |
|
| [Hosting a React App with OpenFaaS](https://www.openfaas.com/blog/react-app/) | Alex Ellis | openfaas.com | 01-Mar-2022 |
|
||||||
@ -126,6 +161,7 @@ Mainly virtual due to pandemic.
|
|||||||
|-------------------------------------------------------------------------|--------------|----------|-------------|
|
|-------------------------------------------------------------------------|--------------|----------|-------------|
|
||||||
| [Configure your OpenFaaS functions for staging and production](https://www.openfaas.com/blog/custom-environments/) | Alex Ellis | openfaas.com | 09-Dec-2021 |
|
| [Configure your OpenFaaS functions for staging and production](https://www.openfaas.com/blog/custom-environments/) | Alex Ellis | openfaas.com | 09-Dec-2021 |
|
||||||
| [OpenFaaS - Run Containerized Functions On Your Own Terms](https://iximiuz.com/en/posts/openfaas-case-study/) | Ivan Velichko | iximiuz.com | 02-Dec-2021 |
|
| [OpenFaaS - Run Containerized Functions On Your Own Terms](https://iximiuz.com/en/posts/openfaas-case-study/) | Ivan Velichko | iximiuz.com | 02-Dec-2021 |
|
||||||
|
| [Making a Docker Dev Environment for OpenFaaS](https://www.felipecruz.es/making-a-docker-dev-environment-for-openfaas/) | Felipe Cruz | felipecruz.es | 30-Nov-2021 |
|
||||||
| [Build at the Edge with OpenFaaS and GitHub Actions](https://www.openfaas.com/blog/edge-actions/) | Alex Ellis | openfaas.com | 29-Nov-2021 |
|
| [Build at the Edge with OpenFaaS and GitHub Actions](https://www.openfaas.com/blog/edge-actions/) | Alex Ellis | openfaas.com | 29-Nov-2021 |
|
||||||
| [Improving long-running jobs for OpenFaaS users](https://www.openfaas.com/blog/long-running-jobs/) | Alex Ellis | openfaas.com | 05-Nov-2021 |
|
| [Improving long-running jobs for OpenFaaS users](https://www.openfaas.com/blog/long-running-jobs/) | Alex Ellis | openfaas.com | 05-Nov-2021 |
|
||||||
| [Derek says goodbye to Docker Swarm](https://www.openfaas.com/blog/migrating-derek-from-docker-swarm/) | Alex Ellis | openfaas.com | 05-Oct-2021 |
|
| [Derek says goodbye to Docker Swarm](https://www.openfaas.com/blog/migrating-derek-from-docker-swarm/) | Alex Ellis | openfaas.com | 05-Oct-2021 |
|
||||||
@ -147,6 +183,7 @@ Mainly virtual due to pandemic.
|
|||||||
| [How to integrate with GitHub the right way with GitHub Apps](https://www.openfaas.com/blog/integrate-with-github-apps-and-faasd/) | Batuhan Apaydın | openfaas.com | 26-Jan-2021 |
|
| [How to integrate with GitHub the right way with GitHub Apps](https://www.openfaas.com/blog/integrate-with-github-apps-and-faasd/) | Batuhan Apaydın | openfaas.com | 26-Jan-2021 |
|
||||||
| [Serverless with OpenFaaS and .NET](https://goncalo-a-oliveira.medium.com/serverless-with-openfaas-and-net-6a66b5c30a5f) | Batuhan Apaydın | medium.com | 20-Jan-2021 |
|
| [Serverless with OpenFaaS and .NET](https://goncalo-a-oliveira.medium.com/serverless-with-openfaas-and-net-6a66b5c30a5f) | Batuhan Apaydın | medium.com | 20-Jan-2021 |
|
||||||
| [How I discovered faas and what it changed for me](https://releasecandidate.dev/posts/2021/discovery-faasd-and-openfaas/) | Peter Thaleikis | releasecandidate.dev | 05-Jan-2021 |
|
| [How I discovered faas and what it changed for me](https://releasecandidate.dev/posts/2021/discovery-faasd-and-openfaas/) | Peter Thaleikis | releasecandidate.dev | 05-Jan-2021 |
|
||||||
|
| [Installing OpenFaaS On k3s (Single Node)](https://midnightprogrammer.net/post/installing-openfaas-on-k3s-single-node/) | Pashant Khandelwal | midnightprogrammer.net | 04-Jan-2021 |
|
||||||
|
|
||||||
#### Events in 2021
|
#### Events in 2021
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
FROM --platform=${BUILDPLATFORM:-linux/amd64} ghcr.io/openfaas/license-check:0.4.1 as license-check
|
FROM --platform=${BUILDPLATFORM:-linux/amd64} ghcr.io/openfaas/license-check:0.4.1 AS license-check
|
||||||
|
|
||||||
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.19 as build
|
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.23 AS build
|
||||||
|
|
||||||
ENV GO111MODULE=on
|
ENV GO111MODULE=on
|
||||||
ENV CGO_ENABLED=0
|
ENV CGO_ENABLED=0
|
||||||
@ -29,7 +29,6 @@ COPY types types
|
|||||||
COPY plugin plugin
|
COPY plugin plugin
|
||||||
COPY version version
|
COPY version version
|
||||||
COPY scaling scaling
|
COPY scaling scaling
|
||||||
COPY probing probing
|
|
||||||
COPY pkg pkg
|
COPY pkg pkg
|
||||||
COPY main.go .
|
COPY main.go .
|
||||||
|
|
||||||
@ -43,11 +42,11 @@ RUN CGO_ENABLED=${CGO_ENABLED} GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build --
|
|||||||
-X \"github.com/openfaas/faas/gateway/version.GitCommitSHA=${GIT_COMMIT}\" \
|
-X \"github.com/openfaas/faas/gateway/version.GitCommitSHA=${GIT_COMMIT}\" \
|
||||||
-X \"github.com/openfaas/faas/gateway/version.Version=${VERSION}\" \
|
-X \"github.com/openfaas/faas/gateway/version.Version=${VERSION}\" \
|
||||||
-X github.com/openfaas/faas/gateway/types.Arch=${TARGETARCH}" \
|
-X github.com/openfaas/faas/gateway/types.Arch=${TARGETARCH}" \
|
||||||
-a -installsuffix cgo -o gateway .
|
-o gateway .
|
||||||
|
|
||||||
FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:3.17 as ship
|
FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:3.21.0 AS ship
|
||||||
|
|
||||||
LABEL org.label-schema.license="MIT" \
|
LABEL org.label-schema.license="OpenFaaS CE EULA - non-commercial" \
|
||||||
org.label-schema.vcs-url="https://github.com/openfaas/faas" \
|
org.label-schema.vcs-url="https://github.com/openfaas/faas" \
|
||||||
org.label-schema.vcs-type="Git" \
|
org.label-schema.vcs-type="Git" \
|
||||||
org.label-schema.name="openfaas/faas" \
|
org.label-schema.name="openfaas/faas" \
|
||||||
@ -64,8 +63,8 @@ WORKDIR /home/app
|
|||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
EXPOSE 8082
|
EXPOSE 8082
|
||||||
ENV http_proxy ""
|
ENV http_proxy=""
|
||||||
ENV https_proxy ""
|
ENV https_proxy=""
|
||||||
|
|
||||||
COPY --from=build /go/src/github.com/openfaas/faas/gateway/gateway .
|
COPY --from=build /go/src/github.com/openfaas/faas/gateway/gateway .
|
||||||
COPY assets assets
|
COPY assets assets
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
export DOCKER_CLI_EXPERIMENTAL=enabled
|
export DOCKER_CLI_EXPERIMENTAL=enabled
|
||||||
|
|
||||||
PLATFORM := "linux/amd64,linux/arm/v7,linux/arm64"
|
PLATFORM?="linux/amd64,linux/arm/v7,linux/arm64"
|
||||||
|
|
||||||
TAG?=latest
|
TAG?=dev
|
||||||
SERVER?=docker.io
|
SERVER?=ttl.sh
|
||||||
OWNER?=alexellis2
|
OWNER?=openfaas
|
||||||
NAME=gateway
|
NAME=gateway
|
||||||
|
|
||||||
.PHONY: local-docker
|
.PHONY: buildx-local
|
||||||
build-local:
|
buildx-local:
|
||||||
@echo $(SERVER)/$(OWNER)/$(NAME):$(TAG) \
|
@echo $(SERVER)/$(OWNER)/$(NAME):$(TAG) \
|
||||||
&& docker buildx create --use --name=multiarch --node multiarch \
|
&& docker buildx create --use --name=multiarch --node multiarch \
|
||||||
&& docker buildx build \
|
&& docker buildx build \
|
||||||
@ -17,8 +17,18 @@ build-local:
|
|||||||
--output "type=docker,push=false" \
|
--output "type=docker,push=false" \
|
||||||
--tag $(SERVER)/$(OWNER)/$(NAME):$(TAG) .
|
--tag $(SERVER)/$(OWNER)/$(NAME):$(TAG) .
|
||||||
|
|
||||||
.PHONY: push-docker
|
.PHONY: buildx-push
|
||||||
push-docker:
|
buildx-push:
|
||||||
|
@echo $(SERVER)/$(OWNER)/$(NAME):$(TAG) \
|
||||||
|
&& docker buildx create --use --name=multiarch --node multiarch \
|
||||||
|
&& docker buildx build \
|
||||||
|
--progress=plain \
|
||||||
|
--platform linux/amd64 \
|
||||||
|
--output "type=image,push=true" \
|
||||||
|
--tag $(SERVER)/$(OWNER)/$(NAME):$(TAG) .
|
||||||
|
|
||||||
|
.PHONY: buildx-push-all
|
||||||
|
buildx-push-all:
|
||||||
@echo $(SERVER)/$(OWNER)/$(NAME):$(TAG) \
|
@echo $(SERVER)/$(OWNER)/$(NAME):$(TAG) \
|
||||||
&& docker buildx create --use --name=multiarch --node multiarch \
|
&& docker buildx create --use --name=multiarch --node multiarch \
|
||||||
&& docker buildx build \
|
&& docker buildx build \
|
||||||
|
@ -1,31 +1,40 @@
|
|||||||
module github.com/openfaas/faas/gateway
|
module github.com/openfaas/faas/gateway
|
||||||
|
|
||||||
go 1.18
|
go 1.23
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/docker/distribution v2.8.1+incompatible
|
github.com/docker/distribution v2.8.3+incompatible
|
||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.1
|
||||||
github.com/openfaas/faas-provider v0.19.1
|
github.com/openfaas/faas-provider v0.25.4
|
||||||
github.com/openfaas/nats-queue-worker v0.0.0-20220805080536-d1d72d857b1c
|
github.com/openfaas/nats-queue-worker v0.0.0-20231219105451-b94918cb8a24
|
||||||
github.com/prometheus/client_golang v1.13.0
|
github.com/prometheus/client_golang v1.20.5
|
||||||
github.com/prometheus/client_model v0.2.0
|
github.com/prometheus/client_model v0.6.1
|
||||||
go.uber.org/goleak v1.1.12
|
go.uber.org/goleak v1.3.0
|
||||||
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde
|
golang.org/x/sync v0.10.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// replace github.com/openfaas/faas-provider => ../../faas-provider
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/golang/protobuf v1.5.2 // indirect
|
github.com/hashicorp/go-hclog v1.6.3 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect
|
||||||
github.com/nats-io/nats.go v1.11.1-0.20210623165838-4b75fc59ae30 // indirect
|
github.com/hashicorp/raft v1.7.1 // indirect
|
||||||
github.com/nats-io/nkeys v0.3.0 // indirect
|
github.com/klauspost/compress v1.17.11 // indirect
|
||||||
|
github.com/minio/highwayhash v1.0.3 // indirect
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
|
github.com/nats-io/jwt/v2 v2.7.2 // indirect
|
||||||
|
github.com/nats-io/nats.go v1.37.0 // indirect
|
||||||
|
github.com/nats-io/nkeys v0.4.8 // indirect
|
||||||
github.com/nats-io/nuid v1.0.1 // indirect
|
github.com/nats-io/nuid v1.0.1 // indirect
|
||||||
github.com/nats-io/stan.go v0.9.0 // indirect
|
github.com/nats-io/stan.go v0.10.4 // indirect
|
||||||
github.com/prometheus/common v0.37.0 // indirect
|
github.com/prometheus/common v0.61.0 // indirect
|
||||||
github.com/prometheus/procfs v0.8.0 // indirect
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 // indirect
|
go.etcd.io/bbolt v1.3.11 // indirect
|
||||||
golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24 // indirect
|
golang.org/x/crypto v0.30.0 // indirect
|
||||||
google.golang.org/protobuf v1.28.1 // indirect
|
golang.org/x/sys v0.28.0 // indirect
|
||||||
|
golang.org/x/time v0.8.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.35.2 // indirect
|
||||||
)
|
)
|
||||||
|
633
gateway/go.sum
633
gateway/go.sum
@ -1,594 +1,149 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
|
||||||
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/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/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/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
|
||||||
github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/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-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
|
||||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
|
||||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
|
||||||
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 h1:EFSB7Zo9Eg91v7MJPVsifUysc/wPdN+NOnVe6bWbdBM=
|
|
||||||
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg=
|
|
||||||
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/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/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
|
||||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
|
||||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
|
||||||
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/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
|
||||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
|
||||||
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/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 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/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
|
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||||
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
|
||||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
|
||||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
|
||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
|
||||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
|
||||||
github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
|
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
|
||||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
|
||||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
|
||||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
|
||||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
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/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||||
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/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.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.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.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.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
|
||||||
github.com/golang/protobuf v1.4.2/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/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
|
||||||
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 v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
|
||||||
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.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.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.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.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
|
||||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
|
||||||
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/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/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
|
||||||
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/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
|
||||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
|
||||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
|
||||||
github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
|
||||||
github.com/hashicorp/go-hclog v0.16.1 h1:IVQwpTGNRRIHafnTs2dQLIk4ENtneRIEEJWOVDqz99o=
|
|
||||||
github.com/hashicorp/go-hclog v0.16.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
|
||||||
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
|
github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0=
|
||||||
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=
|
||||||
github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
github.com/hashicorp/go-msgpack/v2 v2.1.2 h1:4Ee8FTp834e+ewB71RDrQ0VKpyFdrKOjvYtnQ/ltVj0=
|
||||||
github.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs=
|
github.com/hashicorp/go-msgpack/v2 v2.1.2/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4=
|
||||||
github.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4=
|
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||||
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
|
|
||||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
|
||||||
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 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
github.com/hashicorp/raft v1.7.1 h1:ytxsNx4baHsRZrhUcbt3+79zc4ly8qm7pi0393pSchY=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/raft v1.7.1/go.mod h1:hUeiEwQQR/Nk2iKDD0dkEhklSsu3jcAcqvPzPoZSAEM=
|
||||||
github.com/hashicorp/raft v1.3.1 h1:zDT8ke8y2aP4wf9zPTB2uSIeavJ3Hx/ceY4jxI2JxuY=
|
|
||||||
github.com/hashicorp/raft v1.3.1/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM=
|
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
|
||||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
|
||||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
|
||||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
|
||||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
|
||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
|
||||||
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.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
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.11.12 h1:famVnQVu7QwryBN4jNseQdUKES71ZAOnB6UQQJPZvqk=
|
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||||
github.com/klauspost/compress v1.11.12/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||||
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD6Q=
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/minio/highwayhash v1.0.3/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ=
|
||||||
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
github.com/nats-io/jwt/v2 v2.7.2 h1:SCRjfDLJ2q8naXp8YlGJJS5/yj3wGSODFYVi4nnwVMw=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/nats-io/jwt/v2 v2.7.2/go.mod h1:kB6QUmqHG6Wdrzj0KP2L+OX4xiTPBeV+NHVstFaATXU=
|
||||||
github.com/minio/highwayhash v1.0.1 h1:dZ6IIu8Z14VlC0VpfKofAhCy74wu/Qb5gcn52yWoz/0=
|
github.com/nats-io/nats-server/v2 v2.10.3 h1:nk2QVLpJUh3/AhZCJlQdTfj2oeLDvWnn1Z6XzGlNFm0=
|
||||||
github.com/minio/highwayhash v1.0.1/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=
|
github.com/nats-io/nats-server/v2 v2.10.3/go.mod h1:lzrskZ/4gyMAh+/66cCd+q74c6v7muBypzfWhP/MAaM=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/nats-io/nats-streaming-server v0.25.5 h1:DX6xaPhKvVLhdpNsuEmmD+O9LfWSnw8cvxQU/H9LRy8=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/nats-io/nats-streaming-server v0.25.5/go.mod h1:dSBVdHGsT/tV91lT4MWFfE6+yjRCNhRIYJpBaTHFdAo=
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/nats-io/nats.go v1.22.1/go.mod h1:tLqubohF7t4z3du1QDPYJIQQyhb4wl6DhjxEajSI7UA=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/nats-io/nats.go v1.37.0 h1:07rauXbVnnJvv1gfIyghFEo6lUcYRY0WXc3x7x0vUxE=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/nats-io/nats.go v1.37.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
|
||||||
github.com/nats-io/jwt v1.2.2 h1:w3GMTO969dFg+UOKTmmyuu7IGdusK+7Ytlt//OYH/uU=
|
|
||||||
github.com/nats-io/jwt v1.2.2/go.mod h1:/xX356yQA6LuXI9xWW7mZNpxgF2mBmGecH+Fj34sP5Q=
|
|
||||||
github.com/nats-io/jwt/v2 v2.0.2 h1:ejVCLO8gu6/4bOKIHQpmB5UhhUJfAQw55yvLWpfmKjI=
|
|
||||||
github.com/nats-io/jwt/v2 v2.0.2/go.mod h1:VRP+deawSXyhNjXmxPCHskrR6Mq50BqpEI5SEcNiGlY=
|
|
||||||
github.com/nats-io/nats-server/v2 v2.2.6/go.mod h1:sEnFaxqe09cDmfMgACxZbziXnhQFhwk+aKkZjBBRYrI=
|
|
||||||
github.com/nats-io/nats-server/v2 v2.3.2 h1:SGJLWrjBHsl0DsdY8PeTR3YKEfiUEYVVq2STw9d8MSY=
|
|
||||||
github.com/nats-io/nats-server/v2 v2.3.2/go.mod h1:dUf7Cm5z5LbciFVwWx54owyCKm8x4/hL6p7rrljhLFY=
|
|
||||||
github.com/nats-io/nats-streaming-server v0.22.0 h1:2egnq86o9roTqUfELlqykf7ZZkNvRsXjVf4EbaLysHo=
|
|
||||||
github.com/nats-io/nats-streaming-server v0.22.0/go.mod h1:Jyu3eUQaUAjwd5TiBuLagKdQRofPrHoIXt1kL0U/e5o=
|
|
||||||
github.com/nats-io/nats.go v1.11.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w=
|
|
||||||
github.com/nats-io/nats.go v1.11.1-0.20210623165838-4b75fc59ae30 h1:9GqilBhZaR3xYis0JgMlJjNw933WIobdjKhilXm+Vls=
|
|
||||||
github.com/nats-io/nats.go v1.11.1-0.20210623165838-4b75fc59ae30/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w=
|
|
||||||
github.com/nats-io/nkeys v0.2.0/go.mod h1:XdZpAbhgyyODYqjTawOnIOI7VlbKSarI9Gfy1tqEu/s=
|
|
||||||
github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8=
|
|
||||||
github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=
|
github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=
|
||||||
|
github.com/nats-io/nkeys v0.4.8 h1:+wee30071y3vCZAYRsnrmIPaOe47A/SkK/UBDPdIV70=
|
||||||
|
github.com/nats-io/nkeys v0.4.8/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc=
|
||||||
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
|
||||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||||
github.com/nats-io/stan.go v0.9.0 h1:TB73Y31au++0sU0VmnBy2pYkSrwH0zUFNRB9YePHqC4=
|
github.com/nats-io/stan.go v0.10.4 h1:19GS/eD1SeQJaVkeM9EkvEYattnvnWrZ3wkSWSw4uXw=
|
||||||
github.com/nats-io/stan.go v0.9.0/go.mod h1:0jEuBXKauB1HHJswHM/lx05K48TJ1Yxj6VIfM4k+aB4=
|
github.com/nats-io/stan.go v0.10.4/go.mod h1:3XJXH8GagrGqajoO/9+HgPyKV5MWsv7S5ccdda+pc6k=
|
||||||
github.com/openfaas/faas-provider v0.18.6/go.mod h1:fq1JL0mX4rNvVVvRLaLRJ3H6o667sHuyP5p/7SZEe98=
|
github.com/openfaas/faas-provider v0.25.4 h1:Cly/M8/Q+OOn8qFxxeaZGyC5B2x4f+RSU28hej+1WcM=
|
||||||
github.com/openfaas/faas-provider v0.19.1 h1:xH8lTWabfDZwzIvC0u1AO48ghD3BNw6Vo231DLqTeI0=
|
github.com/openfaas/faas-provider v0.25.4/go.mod h1:t6RSPCvNfiqYEzf/CtdIj+0OItdyK6IzrOca1EOLNSg=
|
||||||
github.com/openfaas/faas-provider v0.19.1/go.mod h1:Farrp+9Med8LeK3aoYpqplMP8f5ebTILbCSLg2LPLZk=
|
github.com/openfaas/nats-queue-worker v0.0.0-20231219105451-b94918cb8a24 h1:IeFWHV+vpviPvmAVrh6SsW19PkU+7+Pu/CLrFIe1gtc=
|
||||||
github.com/openfaas/nats-queue-worker v0.0.0-20220805080536-d1d72d857b1c h1:ZVpAJIpDdHkX5NGdz49kCzyvG+H+S/KvMAVVfZAN8EI=
|
github.com/openfaas/nats-queue-worker v0.0.0-20231219105451-b94918cb8a24/go.mod h1:SR1bzVXQaZoZS+wWmvO7bXZE6V9S9bukR9J5Kynr/vc=
|
||||||
github.com/openfaas/nats-queue-worker v0.0.0-20220805080536-d1d72d857b1c/go.mod h1:ajlN2z+D8JPBq3kWNv4WLT6mtKPqlgeE3dYEx39d1tk=
|
|
||||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
|
||||||
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.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||||
github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
|
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ=
|
||||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s=
|
||||||
github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||||
github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU=
|
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||||
github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/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.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
|
||||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
|
||||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
|
||||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
|
||||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
|
||||||
github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
|
|
||||||
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
|
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
|
||||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
|
||||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
|
||||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
|
||||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
|
||||||
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
|
|
||||||
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
|
|
||||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
|
||||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
|
||||||
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.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
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/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
|
||||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
|
||||||
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.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.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.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
go.etcd.io/bbolt v1.3.5 h1:XAzx9gjCb0Rxj7EoqcClPD1d5ZBxZJk0jbuoPHenBt0=
|
go.etcd.io/bbolt v1.3.11 h1:yGEzV1wPz2yVCLsD8ZAiGHhHVlczyC9d1rP43/VCRJ0=
|
||||||
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
|
go.etcd.io/bbolt v1.3.11/go.mod h1:dksAq7YMXoljX0xu6VF5DMZGbhYYoLUalEiSySYAS4I=
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
|
||||||
go.uber.org/goleak v1.1.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
|
||||||
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
|
|
||||||
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/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-20190605123033-f99c8df09eb5/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-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
|
||||||
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/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||||
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 h1:GIAS/yBem/gq2MUqgNIzUHW7cJMmx3TGZOrnyYaNQ6c=
|
golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY=
|
||||||
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
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-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-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-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 h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
|
|
||||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/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.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.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
|
||||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
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.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
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-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-20190108225652-1e06a53dbb7e/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-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-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-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-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-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-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
|
||||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
|
||||||
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-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-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
|
||||||
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-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-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-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-20220722155255-886fb9371eb4/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.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde h1:ejfdSekXMDxDLbRrJMwUk6KnSLZ2McaUCVcIKM+N6jc=
|
|
||||||
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
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-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
|
||||||
golang.org/x/sys v0.0.0-20190130150945-aca44879d564/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-20190222072716-a9d3bda3a223/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-20200116001909-b77594299b42/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-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/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-20200106162015-b016eb3dc98e/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-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-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/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-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/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-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24 h1:TyKJRhyo17yWxOMCTHKWrc5rddHORMlnZ/j57umaUd8=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220823224334-20c2bfdbfe24/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||||
|
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
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.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
|
||||||
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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 h1:NusfzzA6yGQ+ua51ck7E3omNUX/JuqbFSaRGqU8CcLI=
|
|
||||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
|
||||||
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-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-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-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
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-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-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
|
||||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/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-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
|
||||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/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-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-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-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
|
||||||
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=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
|
||||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
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/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
|
||||||
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/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-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-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
|
||||||
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-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
|
||||||
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-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/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
|
||||||
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.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
|
||||||
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/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-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.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/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.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
|
||||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
|
||||||
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/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
|
||||||
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.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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-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.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
|
||||||
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=
|
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -27,7 +29,7 @@ func MakeAlertHandler(service scaling.ServiceQuery, defaultNamespace string) htt
|
|||||||
|
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(r.Body)
|
body, err := io.ReadAll(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
w.Write([]byte("Unable to read alert."))
|
w.Write([]byte("Unable to read alert."))
|
||||||
@ -44,7 +46,7 @@ func MakeAlertHandler(service scaling.ServiceQuery, defaultNamespace string) htt
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
errors := handleAlerts(&req, service, defaultNamespace)
|
errors := handleAlerts(req, service, defaultNamespace)
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
log.Println(errors)
|
log.Println(errors)
|
||||||
var errorOutput string
|
var errorOutput string
|
||||||
@ -60,7 +62,7 @@ func MakeAlertHandler(service scaling.ServiceQuery, defaultNamespace string) htt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleAlerts(req *requests.PrometheusAlert, service scaling.ServiceQuery, defaultNamespace string) []error {
|
func handleAlerts(req requests.PrometheusAlert, service scaling.ServiceQuery, defaultNamespace string) []error {
|
||||||
var errors []error
|
var errors []error
|
||||||
for _, alert := range req.Alerts {
|
for _, alert := range req.Alerts {
|
||||||
if err := scaleService(alert, service, defaultNamespace); err != nil {
|
if err := scaleService(alert, service, defaultNamespace); err != nil {
|
||||||
@ -102,6 +104,7 @@ func scaleService(alert requests.PrometheusInnerAlert, service scaling.ServiceQu
|
|||||||
func CalculateReplicas(status string, currentReplicas uint64, maxReplicas uint64, minReplicas uint64, scalingFactor uint64) uint64 {
|
func CalculateReplicas(status string, currentReplicas uint64, maxReplicas uint64, minReplicas uint64, scalingFactor uint64) uint64 {
|
||||||
var newReplicas uint64
|
var newReplicas uint64
|
||||||
|
|
||||||
|
maxReplicas = uint64(math.Min(float64(maxReplicas), float64(scaling.DefaultMaxReplicas)))
|
||||||
step := uint64(math.Ceil(float64(maxReplicas) / 100 * float64(scalingFactor)))
|
step := uint64(math.Ceil(float64(maxReplicas) / 100 * float64(scalingFactor)))
|
||||||
|
|
||||||
if status == "firing" && step > 0 {
|
if status == "firing" && step > 0 {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
@ -12,9 +14,9 @@ import (
|
|||||||
func TestDisabledScale(t *testing.T) {
|
func TestDisabledScale(t *testing.T) {
|
||||||
minReplicas := uint64(1)
|
minReplicas := uint64(1)
|
||||||
scalingFactor := uint64(0)
|
scalingFactor := uint64(0)
|
||||||
newReplicas := CalculateReplicas("firing", scaling.DefaultMinReplicas, scaling.DefaultMaxReplicas, minReplicas, scalingFactor)
|
got := CalculateReplicas("firing", scaling.DefaultMinReplicas, scaling.DefaultMaxReplicas, minReplicas, scalingFactor)
|
||||||
if newReplicas != minReplicas {
|
if got != minReplicas {
|
||||||
t.Logf("Expected not to scale, but replicas were: %d", newReplicas)
|
t.Logf("Expected not to scale, but replicas were: %d", got)
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -22,20 +24,23 @@ func TestDisabledScale(t *testing.T) {
|
|||||||
func TestParameterEdge(t *testing.T) {
|
func TestParameterEdge(t *testing.T) {
|
||||||
minReplicas := uint64(0)
|
minReplicas := uint64(0)
|
||||||
scalingFactor := uint64(0)
|
scalingFactor := uint64(0)
|
||||||
newReplicas := CalculateReplicas("firing", scaling.DefaultMinReplicas, scaling.DefaultMaxReplicas, minReplicas, scalingFactor)
|
got := CalculateReplicas("firing", scaling.DefaultMinReplicas, scaling.DefaultMaxReplicas, minReplicas, scalingFactor)
|
||||||
if newReplicas != 0 {
|
if got != 0 {
|
||||||
t.Log("Expected not to scale")
|
t.Log("Expected not to scale")
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScalingWithSameUpperLowerLimit(t *testing.T) {
|
func TestScaling_SameUpperLowerLimit(t *testing.T) {
|
||||||
minReplicas := uint64(1)
|
minReplicas := uint64(5)
|
||||||
scalingFactor := uint64(20)
|
maxReplicas := uint64(5)
|
||||||
// status string, currentReplicas uint64, maxReplicas uint64, minReplicas uint64, scalingFactor uint64)
|
scalingFactor := uint64(10)
|
||||||
newReplicas := CalculateReplicas("firing", minReplicas, minReplicas, minReplicas, scalingFactor)
|
|
||||||
if newReplicas != 1 {
|
got := CalculateReplicas("firing", minReplicas, minReplicas, maxReplicas, scalingFactor)
|
||||||
t.Logf("Replicas - want: %d, got: %d", minReplicas, newReplicas)
|
|
||||||
|
want := minReplicas
|
||||||
|
if want != got {
|
||||||
|
t.Logf("Replicas - want: %d, got: %d", want, got)
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,58 +48,62 @@ func TestScalingWithSameUpperLowerLimit(t *testing.T) {
|
|||||||
func TestMaxScale(t *testing.T) {
|
func TestMaxScale(t *testing.T) {
|
||||||
minReplicas := uint64(1)
|
minReplicas := uint64(1)
|
||||||
scalingFactor := uint64(100)
|
scalingFactor := uint64(100)
|
||||||
newReplicas := CalculateReplicas("firing", scaling.DefaultMinReplicas, scaling.DefaultMaxReplicas, minReplicas, scalingFactor)
|
got := CalculateReplicas("firing", scaling.DefaultMinReplicas, scaling.DefaultMaxReplicas*2, minReplicas, scalingFactor)
|
||||||
if newReplicas != 20 {
|
if got != scaling.DefaultMaxReplicas {
|
||||||
t.Log("Expected ceiling of 20 replicas")
|
t.Fatalf("want ceiling: %d, but got: %d", scaling.DefaultMaxReplicas, got)
|
||||||
t.Fail()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInitialScale(t *testing.T) {
|
func TestInitialScale_From1_Factor10(t *testing.T) {
|
||||||
minReplicas := uint64(1)
|
minReplicas := uint64(1)
|
||||||
scalingFactor := uint64(20)
|
scalingFactor := uint64(10)
|
||||||
newReplicas := CalculateReplicas("firing", scaling.DefaultMinReplicas, scaling.DefaultMaxReplicas, minReplicas, scalingFactor)
|
got := CalculateReplicas("firing", scaling.DefaultMinReplicas, scaling.DefaultMaxReplicas, minReplicas, scalingFactor)
|
||||||
if newReplicas != 5 {
|
want := uint64(2)
|
||||||
t.Log("Expected the increment to equal 5")
|
|
||||||
t.Fail()
|
if got != want {
|
||||||
|
t.Fatalf("want: %d, but got: %d", want, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScale(t *testing.T) {
|
func TestScale_midrange_factor25(t *testing.T) {
|
||||||
minReplicas := uint64(1)
|
minReplicas := uint64(1)
|
||||||
scalingFactor := uint64(20)
|
scalingFactor := uint64(25)
|
||||||
newReplicas := CalculateReplicas("firing", 4, scaling.DefaultMaxReplicas, minReplicas, scalingFactor)
|
current := uint64(4)
|
||||||
if newReplicas != 8 {
|
maxReplicas := uint64(scaling.DefaultMaxReplicas)
|
||||||
t.Log("Expected newReplicas to equal 8")
|
|
||||||
t.Fail()
|
got := CalculateReplicas("firing", current, maxReplicas, minReplicas, scalingFactor)
|
||||||
|
want := uint64(5)
|
||||||
|
if want != got {
|
||||||
|
t.Fatalf("want: %d, but got: %d", want, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScaleCeiling(t *testing.T) {
|
func TestScale_Ceiling_IsDefaultMaxReplicas(t *testing.T) {
|
||||||
minReplicas := uint64(1)
|
minReplicas := uint64(1)
|
||||||
scalingFactor := uint64(20)
|
scalingFactor := uint64(10)
|
||||||
newReplicas := CalculateReplicas("firing", 20, scaling.DefaultMaxReplicas, minReplicas, scalingFactor)
|
current := uint64(scaling.DefaultMaxReplicas)
|
||||||
if newReplicas != 20 {
|
|
||||||
t.Log("Expected ceiling of 20 replicas")
|
got := CalculateReplicas("firing", current, scaling.DefaultMaxReplicas, minReplicas, scalingFactor)
|
||||||
t.Fail()
|
if got != scaling.DefaultMaxReplicas {
|
||||||
|
t.Fatalf("want: %d, but got: %d", scaling.DefaultMaxReplicas, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestScaleCeilingEdge(t *testing.T) {
|
func TestScaleCeilingReplicasOver(t *testing.T) {
|
||||||
minReplicas := uint64(1)
|
minReplicas := uint64(1)
|
||||||
scalingFactor := uint64(20)
|
scalingFactor := uint64(10)
|
||||||
newReplicas := CalculateReplicas("firing", 19, scaling.DefaultMaxReplicas, minReplicas, scalingFactor)
|
got := CalculateReplicas("firing", 19, scaling.DefaultMaxReplicas, minReplicas, scalingFactor)
|
||||||
if newReplicas != 20 {
|
|
||||||
t.Log("Expected ceiling of 20 replicas")
|
if got != scaling.DefaultMaxReplicas {
|
||||||
t.Fail()
|
t.Fatalf("want: %d, but got: %d", scaling.DefaultMaxReplicas, got)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBackingOff(t *testing.T) {
|
func TestBackingOff(t *testing.T) {
|
||||||
minReplicas := uint64(1)
|
minReplicas := uint64(1)
|
||||||
scalingFactor := uint64(20)
|
scalingFactor := uint64(10)
|
||||||
newReplicas := CalculateReplicas("resolved", 8, scaling.DefaultMaxReplicas, minReplicas, scalingFactor)
|
got := CalculateReplicas("resolved", 8, scaling.DefaultMaxReplicas, minReplicas, scalingFactor)
|
||||||
if newReplicas != 1 {
|
if got != 1 {
|
||||||
t.Log("Expected backing off to 1 replica")
|
t.Log("Expected backing off to 1 replica")
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
@ -104,9 +113,9 @@ func TestScaledUpFrom1(t *testing.T) {
|
|||||||
currentReplicas := uint64(1)
|
currentReplicas := uint64(1)
|
||||||
maxReplicas := uint64(5)
|
maxReplicas := uint64(5)
|
||||||
scalingFactor := uint64(30)
|
scalingFactor := uint64(30)
|
||||||
newReplicas := CalculateReplicas("firing", currentReplicas, maxReplicas, scaling.DefaultMinReplicas, scalingFactor)
|
got := CalculateReplicas("firing", currentReplicas, maxReplicas, scaling.DefaultMinReplicas, scalingFactor)
|
||||||
if newReplicas <= currentReplicas {
|
if got <= currentReplicas {
|
||||||
t.Log("Expected newReplicas > currentReplica")
|
t.Log("Expected got > currentReplica")
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,9 +124,9 @@ func TestScaledUpWithSmallParam(t *testing.T) {
|
|||||||
currentReplicas := uint64(1)
|
currentReplicas := uint64(1)
|
||||||
maxReplicas := uint64(4)
|
maxReplicas := uint64(4)
|
||||||
scalingFactor := uint64(1)
|
scalingFactor := uint64(1)
|
||||||
newReplicas := CalculateReplicas("firing", currentReplicas, maxReplicas, scaling.DefaultMinReplicas, scalingFactor)
|
got := CalculateReplicas("firing", currentReplicas, maxReplicas, scaling.DefaultMinReplicas, scalingFactor)
|
||||||
if newReplicas <= currentReplicas {
|
if got <= currentReplicas {
|
||||||
t.Log("Expected newReplicas > currentReplica")
|
t.Log("Expected got > currentReplica")
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
@ -9,10 +11,14 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/distribution/uuid"
|
"github.com/docker/distribution/uuid"
|
||||||
|
"github.com/openfaas/faas/gateway/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MakeCallIDMiddleware middleware tags a request with a uid
|
// MakeCallIDMiddleware middleware tags a request with a uid
|
||||||
func MakeCallIDMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
func MakeCallIDMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
||||||
|
|
||||||
|
version := version.Version
|
||||||
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
if len(r.Header.Get("X-Call-Id")) == 0 {
|
if len(r.Header.Get("X-Call-Id")) == 0 {
|
||||||
@ -24,6 +30,8 @@ func MakeCallIDMiddleware(next http.HandlerFunc) http.HandlerFunc {
|
|||||||
r.Header.Add("X-Start-Time", fmt.Sprintf("%d", start.UTC().UnixNano()))
|
r.Header.Add("X-Start-Time", fmt.Sprintf("%d", start.UTC().UnixNano()))
|
||||||
w.Header().Add("X-Start-Time", fmt.Sprintf("%d", start.UTC().UnixNano()))
|
w.Header().Add("X-Start-Time", fmt.Sprintf("%d", start.UTC().UnixNano()))
|
||||||
|
|
||||||
|
w.Header().Add("X-Served-By", fmt.Sprintf("openfaas-ce/%s", version))
|
||||||
|
|
||||||
next(w, r)
|
next(w, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
package handlers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MakeExternalAuthHandler make an authentication proxy handler
|
|
||||||
func MakeExternalAuthHandler(next http.HandlerFunc, upstreamTimeout time.Duration, upstreamURL string, passBody bool) http.HandlerFunc {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
req, _ := http.NewRequest(http.MethodGet, upstreamURL, nil)
|
|
||||||
|
|
||||||
copyHeaders(req.Header, &r.Header)
|
|
||||||
|
|
||||||
deadlineContext, cancel := context.WithTimeout(
|
|
||||||
context.Background(),
|
|
||||||
upstreamTimeout)
|
|
||||||
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
res, err := http.DefaultClient.Do(req.WithContext(deadlineContext))
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
log.Printf("ExternalAuthHandler: %s", err.Error())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if res.Body != nil {
|
|
||||||
defer res.Body.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
if res.StatusCode == http.StatusOK {
|
|
||||||
next.ServeHTTP(w, r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
copyHeaders(w.Header(), &res.Header)
|
|
||||||
w.WriteHeader(res.StatusCode)
|
|
||||||
|
|
||||||
if res.Body != nil {
|
|
||||||
io.Copy(w, res.Body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,239 +0,0 @@
|
|||||||
package handlers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_External_Auth_Wrapper_FailsInvalidAuth(t *testing.T) {
|
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusForbidden)
|
|
||||||
}))
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
next := func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusNotImplemented)
|
|
||||||
}
|
|
||||||
|
|
||||||
passBody := false
|
|
||||||
handler := MakeExternalAuthHandler(next, time.Second*5, s.URL, passBody)
|
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodGet, s.URL, nil)
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
handler(rr, req)
|
|
||||||
|
|
||||||
if rr.Code == http.StatusOK {
|
|
||||||
t.Errorf("Status incorrect, did not want: %d, but got %d", http.StatusOK, rr.Code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_External_Auth_Wrapper_FailsInvalidAuth_WritesBody(t *testing.T) {
|
|
||||||
|
|
||||||
wantBody := []byte(`invalid credentials`)
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusForbidden)
|
|
||||||
w.Write(wantBody)
|
|
||||||
}))
|
|
||||||
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
next := func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusNotImplemented)
|
|
||||||
}
|
|
||||||
|
|
||||||
passBody := false
|
|
||||||
handler := MakeExternalAuthHandler(next, time.Second*5, s.URL, passBody)
|
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodGet, s.URL, nil)
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
handler(rr, req)
|
|
||||||
|
|
||||||
if rr.Code == http.StatusOK {
|
|
||||||
t.Errorf("Status incorrect, did not want: %d, but got %d", http.StatusOK, rr.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
if bytes.Compare(rr.Body.Bytes(), wantBody) != 0 {
|
|
||||||
t.Errorf("Body incorrect, want: %s, but got %s", []byte(wantBody), rr.Body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_External_Auth_Wrapper_PassesValidAuth(t *testing.T) {
|
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
}))
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
next := func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusNotImplemented)
|
|
||||||
}
|
|
||||||
|
|
||||||
passBody := false
|
|
||||||
handler := MakeExternalAuthHandler(next, time.Second*5, s.URL, passBody)
|
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodGet, s.URL, nil)
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
handler(rr, req)
|
|
||||||
want := http.StatusNotImplemented
|
|
||||||
if rr.Code != want {
|
|
||||||
t.Errorf("Status incorrect, want: %d, but got %d", want, rr.Code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_External_Auth_Wrapper_WithoutRequiredHeaderFailsAuth(t *testing.T) {
|
|
||||||
wantToken := "secret-key"
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Header.Get("X-Token") == wantToken {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
|
||||||
}))
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
next := func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusNotImplemented)
|
|
||||||
}
|
|
||||||
|
|
||||||
passBody := false
|
|
||||||
handler := MakeExternalAuthHandler(next, time.Second*5, s.URL, passBody)
|
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodGet, s.URL, nil)
|
|
||||||
|
|
||||||
// use an invalid token
|
|
||||||
req.Header.Set("X-Token", "invalid-key")
|
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
handler(rr, req)
|
|
||||||
want := http.StatusUnauthorized
|
|
||||||
if rr.Code != want {
|
|
||||||
t.Errorf("Status incorrect, want: %d, but got %d", want, rr.Code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_External_Auth_Wrapper_WithoutRequiredHeaderFailsAuth_ProxiesServerHeaders(t *testing.T) {
|
|
||||||
wantToken := "secret-key"
|
|
||||||
wantRealm := `Basic realm="Restricted"`
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Header.Get("X-Token") == wantToken {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Header().Set("Www-Authenticate", wantRealm)
|
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
|
||||||
}))
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
next := func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusNotImplemented)
|
|
||||||
}
|
|
||||||
|
|
||||||
passBody := false
|
|
||||||
handler := MakeExternalAuthHandler(next, time.Second*5, s.URL, passBody)
|
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodGet, s.URL, nil)
|
|
||||||
|
|
||||||
// use an invalid token
|
|
||||||
req.Header.Set("X-Token", "invalid-key")
|
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
handler(rr, req)
|
|
||||||
want := http.StatusUnauthorized
|
|
||||||
if rr.Code != want {
|
|
||||||
t.Errorf("Status incorrect, want: %d, but got %d", want, rr.Code)
|
|
||||||
}
|
|
||||||
|
|
||||||
got := rr.Header().Get("Www-Authenticate")
|
|
||||||
if got != wantRealm {
|
|
||||||
t.Errorf("Www-Authenticate header, want: %s, but got %s, %q", wantRealm, got, rr.Header())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_External_Auth_Wrapper_WithRequiredHeaderPassesValidAuth(t *testing.T) {
|
|
||||||
wantToken := "secret-key"
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Header.Get("X-Token") == wantToken {
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
|
||||||
}))
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
next := func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusNotImplemented)
|
|
||||||
}
|
|
||||||
|
|
||||||
passBody := false
|
|
||||||
handler := MakeExternalAuthHandler(next, time.Second*5, s.URL, passBody)
|
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodGet, s.URL, nil)
|
|
||||||
req.Header.Set("X-Token", wantToken)
|
|
||||||
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
handler(rr, req)
|
|
||||||
want := http.StatusNotImplemented
|
|
||||||
if rr.Code != want {
|
|
||||||
t.Errorf("Status incorrect, want: %d, but got %d", want, rr.Code)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Test_External_Auth_Wrapper_TimeoutGivesInternalServerError(t *testing.T) {
|
|
||||||
|
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
time.Sleep(50 * time.Millisecond)
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
}))
|
|
||||||
defer s.Close()
|
|
||||||
|
|
||||||
next := func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.WriteHeader(http.StatusNotImplemented)
|
|
||||||
}
|
|
||||||
|
|
||||||
passBody := false
|
|
||||||
handler := MakeExternalAuthHandler(next, time.Millisecond*10, s.URL, passBody)
|
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodGet, s.URL, nil)
|
|
||||||
rr := httptest.NewRecorder()
|
|
||||||
handler(rr, req)
|
|
||||||
|
|
||||||
want := http.StatusInternalServerError
|
|
||||||
if rr.Code != want {
|
|
||||||
t.Errorf("Status incorrect, want: %d, but got %d", want, rr.Code)
|
|
||||||
}
|
|
||||||
wantSubstring := "context deadline exceeded\n"
|
|
||||||
if !strings.HasSuffix(string(rr.Body.Bytes()), wantSubstring) {
|
|
||||||
t.Errorf("Body incorrect, want to have suffix: %q, but got %q", []byte(wantSubstring), rr.Body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// // Test_External_Auth_Wrapper_PassesValidAuthButOnly200IsValid this test exists
|
|
||||||
// // to document the TODO action to consider all "2xx" statuses as valid.
|
|
||||||
// func Test_External_Auth_Wrapper_PassesValidAuthButOnly200IsValid(t *testing.T) {
|
|
||||||
|
|
||||||
// s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// w.WriteHeader(http.StatusAccepted)
|
|
||||||
// }))
|
|
||||||
// defer s.Close()
|
|
||||||
|
|
||||||
// next := func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// w.WriteHeader(http.StatusNotImplemented)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// passBody := false
|
|
||||||
// handler := MakeExternalAuthHandler(next, time.Second*5, s.URL, passBody)
|
|
||||||
|
|
||||||
// req := httptest.NewRequest(http.MethodGet, s.URL, nil)
|
|
||||||
// rr := httptest.NewRecorder()
|
|
||||||
// handler(rr, req)
|
|
||||||
// want := http.StatusUnauthorized
|
|
||||||
// if rr.Code != want {
|
|
||||||
// t.Errorf("Status incorrect, want: %d, but got %d", want, rr.Code)
|
|
||||||
// }
|
|
||||||
// }
|
|
@ -1,17 +1,24 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/http/httputil"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
fhttputil "github.com/openfaas/faas-provider/httputil"
|
||||||
"github.com/openfaas/faas/gateway/pkg/middleware"
|
"github.com/openfaas/faas/gateway/pkg/middleware"
|
||||||
"github.com/openfaas/faas/gateway/types"
|
"github.com/openfaas/faas/gateway/types"
|
||||||
)
|
)
|
||||||
@ -28,7 +35,10 @@ func MakeForwardingProxyHandler(proxy *types.HTTPClientReverseProxy,
|
|||||||
writeRequestURI = exists
|
writeRequestURI = exists
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reverseProxy := makeRewriteProxy(baseURLResolver, urlPathTransformer)
|
||||||
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
baseURL := baseURLResolver.Resolve(r)
|
baseURL := baseURLResolver.Resolve(r)
|
||||||
originalURL := r.URL.String()
|
originalURL := r.URL.String()
|
||||||
requestURL := urlPathTransformer.Transform(r)
|
requestURL := urlPathTransformer.Transform(r)
|
||||||
@ -39,13 +49,13 @@ func MakeForwardingProxyHandler(proxy *types.HTTPClientReverseProxy,
|
|||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|
||||||
statusCode, err := forwardRequest(w, r, proxy.Client, baseURL, requestURL, proxy.Timeout, writeRequestURI, serviceAuthInjector)
|
statusCode, err := forwardRequest(w, r, proxy.Client, baseURL, requestURL, proxy.Timeout, writeRequestURI, serviceAuthInjector, reverseProxy)
|
||||||
|
|
||||||
seconds := time.Since(start)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error with upstream request to: %s, %s\n", requestURL, err.Error())
|
log.Printf("error with upstream request to: %s, %s\n", requestURL, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
seconds := time.Since(start)
|
||||||
|
|
||||||
for _, notifier := range notifiers {
|
for _, notifier := range notifiers {
|
||||||
notifier.Notify(r.Method, requestURL, originalURL, statusCode, "completed", seconds)
|
notifier.Notify(r.Method, requestURL, originalURL, statusCode, "completed", seconds)
|
||||||
}
|
}
|
||||||
@ -86,12 +96,14 @@ func forwardRequest(w http.ResponseWriter,
|
|||||||
requestURL string,
|
requestURL string,
|
||||||
timeout time.Duration,
|
timeout time.Duration,
|
||||||
writeRequestURI bool,
|
writeRequestURI bool,
|
||||||
serviceAuthInjector middleware.AuthInjector) (int, error) {
|
serviceAuthInjector middleware.AuthInjector,
|
||||||
|
reverseProxy *httputil.ReverseProxy) (int, error) {
|
||||||
|
|
||||||
|
if r.Body != nil {
|
||||||
|
defer r.Body.Close()
|
||||||
|
}
|
||||||
|
|
||||||
upstreamReq := buildUpstreamRequest(r, baseURL, requestURL)
|
upstreamReq := buildUpstreamRequest(r, baseURL, requestURL)
|
||||||
if upstreamReq.Body != nil {
|
|
||||||
defer upstreamReq.Body.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
if serviceAuthInjector != nil {
|
if serviceAuthInjector != nil {
|
||||||
serviceAuthInjector.Inject(upstreamReq)
|
serviceAuthInjector.Inject(upstreamReq)
|
||||||
@ -101,14 +113,19 @@ func forwardRequest(w http.ResponseWriter,
|
|||||||
log.Printf("forwardRequest: %s %s\n", upstreamReq.Host, upstreamReq.URL.String())
|
log.Printf("forwardRequest: %s %s\n", upstreamReq.Host, upstreamReq.URL.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(r.Header.Get("Accept"), "text/event-stream") {
|
||||||
|
|
||||||
|
return handleEventStream(w, r, reverseProxy, upstreamReq, timeout)
|
||||||
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(r.Context(), timeout)
|
ctx, cancel := context.WithTimeout(r.Context(), timeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
res, resErr := proxyClient.Do(upstreamReq.WithContext(ctx))
|
res, err := proxyClient.Do(upstreamReq.WithContext(ctx))
|
||||||
if resErr != nil {
|
if err != nil {
|
||||||
badStatus := http.StatusBadGateway
|
badStatus := http.StatusBadGateway
|
||||||
w.WriteHeader(badStatus)
|
w.WriteHeader(badStatus)
|
||||||
return badStatus, resErr
|
return badStatus, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.Body != nil {
|
if res.Body != nil {
|
||||||
@ -117,17 +134,45 @@ func forwardRequest(w http.ResponseWriter,
|
|||||||
|
|
||||||
copyHeaders(w.Header(), &res.Header)
|
copyHeaders(w.Header(), &res.Header)
|
||||||
|
|
||||||
// Write status code
|
|
||||||
w.WriteHeader(res.StatusCode)
|
w.WriteHeader(res.StatusCode)
|
||||||
|
|
||||||
if res.Body != nil {
|
if res.Body != nil {
|
||||||
// Copy the body over
|
io.Copy(w, res.Body)
|
||||||
io.CopyBuffer(w, res.Body, nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res.StatusCode, nil
|
return res.StatusCode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleEventStream(w http.ResponseWriter, r *http.Request, reverseProxy *httputil.ReverseProxy, upstreamReq *http.Request, timeout time.Duration) (int, error) {
|
||||||
|
ww := fhttputil.NewHttpWriteInterceptor(w)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeoutCause(r.Context(), timeout, http.ErrHandlerTimeout)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
r = r.WithContext(ctx)
|
||||||
|
wg := &sync.WaitGroup{}
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
wg.Done()
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
if errors.Is(r.(error), http.ErrAbortHandler) {
|
||||||
|
log.Printf("Aborted [%s] for: %s", upstreamReq.Method, upstreamReq.URL.Path)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
log.Printf("Recovered from panic in reverseproxy: %v", r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
reverseProxy.ServeHTTP(ww, r)
|
||||||
|
}()
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return ww.Status(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func copyHeaders(destination http.Header, source *http.Header) {
|
func copyHeaders(destination http.Header, source *http.Header) {
|
||||||
for k, v := range *source {
|
for k, v := range *source {
|
||||||
vClone := make([]string, len(v))
|
vClone := make([]string, len(v))
|
||||||
@ -159,3 +204,24 @@ var hopHeaders = []string{
|
|||||||
"Transfer-Encoding",
|
"Transfer-Encoding",
|
||||||
"Upgrade",
|
"Upgrade",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeRewriteProxy(baseURLResolver middleware.BaseURLResolver, urlPathTransformer middleware.URLPathTransformer) *httputil.ReverseProxy {
|
||||||
|
|
||||||
|
return &httputil.ReverseProxy{
|
||||||
|
|
||||||
|
ErrorLog: log.New(io.Discard, "proxy:", 0),
|
||||||
|
ErrorHandler: func(w http.ResponseWriter, r *http.Request, err error) {
|
||||||
|
},
|
||||||
|
Director: func(r *http.Request) {
|
||||||
|
|
||||||
|
baseURL := baseURLResolver.Resolve(r)
|
||||||
|
baseURLu, _ := r.URL.Parse(baseURL)
|
||||||
|
|
||||||
|
requestURL := urlPathTransformer.Transform(r)
|
||||||
|
|
||||||
|
r.URL.Scheme = "http"
|
||||||
|
r.URL.Path = requestURL
|
||||||
|
r.URL.Host = baseURLu.Host
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
@ -33,7 +35,7 @@ func Test_buildUpstreamRequest_Body_Method_Query(t *testing.T) {
|
|||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
upstreamBytes, _ := ioutil.ReadAll(upstream.Body)
|
upstreamBytes, _ := io.ReadAll(upstream.Body)
|
||||||
|
|
||||||
if string(upstreamBytes) != string(srcBytes) {
|
if string(upstreamBytes) != string(srcBytes) {
|
||||||
t.Errorf("Body - want: %s, got: %s", string(upstreamBytes), string(srcBytes))
|
t.Errorf("Body - want: %s, got: %s", string(upstreamBytes), string(srcBytes))
|
||||||
@ -212,7 +214,7 @@ func Test_buildUpstreamRequest_WithPathNoQuery(t *testing.T) {
|
|||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
upstreamBytes, _ := ioutil.ReadAll(upstream.Body)
|
upstreamBytes, _ := io.ReadAll(upstream.Body)
|
||||||
|
|
||||||
if string(upstreamBytes) != string(srcBytes) {
|
if string(upstreamBytes) != string(srcBytes) {
|
||||||
t.Errorf("Body - want: %s, got: %s", string(upstreamBytes), string(srcBytes))
|
t.Errorf("Body - want: %s, got: %s", string(upstreamBytes), string(srcBytes))
|
||||||
@ -268,7 +270,7 @@ func Test_buildUpstreamRequest_WithNoPathNoQuery(t *testing.T) {
|
|||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
upstreamBytes, _ := ioutil.ReadAll(upstream.Body)
|
upstreamBytes, _ := io.ReadAll(upstream.Body)
|
||||||
|
|
||||||
if string(upstreamBytes) != string(srcBytes) {
|
if string(upstreamBytes) != string(srcBytes) {
|
||||||
t.Errorf("Body - want: %s, got: %s", string(upstreamBytes), string(srcBytes))
|
t.Errorf("Body - want: %s, got: %s", string(upstreamBytes), string(srcBytes))
|
||||||
@ -322,7 +324,7 @@ func Test_buildUpstreamRequest_WithPathAndQuery(t *testing.T) {
|
|||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
upstreamBytes, _ := ioutil.ReadAll(upstream.Body)
|
upstreamBytes, _ := io.ReadAll(upstream.Body)
|
||||||
|
|
||||||
if string(upstreamBytes) != string(srcBytes) {
|
if string(upstreamBytes) != string(srcBytes) {
|
||||||
t.Errorf("Body - want: %s, got: %s", string(upstreamBytes), string(srcBytes))
|
t.Errorf("Body - want: %s, got: %s", string(upstreamBytes), string(srcBytes))
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s) 2019. All rights reserved.
|
// Copyright (c) OpenFaaS Author(s) 2019. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
|
||||||
providerTypes "github.com/openfaas/faas-provider/types"
|
providerTypes "github.com/openfaas/faas-provider/types"
|
||||||
@ -27,7 +28,7 @@ func MakeInfoHandler(h http.Handler) http.HandlerFunc {
|
|||||||
|
|
||||||
var provider *providerTypes.ProviderInfo
|
var provider *providerTypes.ProviderInfo
|
||||||
|
|
||||||
upstreamBody, _ := ioutil.ReadAll(upstreamCall.Body)
|
upstreamBody, _ := io.ReadAll(upstreamCall.Body)
|
||||||
err := json.Unmarshal(upstreamBody, &provider)
|
err := json.Unmarshal(upstreamBody, &provider)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error unmarshalling provider json from body %s. Error %s\n", upstreamBody, err.Error())
|
log.Printf("Error unmarshalling provider json from body %s. Error %s\n", upstreamBody, err.Error())
|
||||||
|
@ -3,7 +3,7 @@ package handlers
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -52,7 +52,7 @@ func Test_logsProxyDoesNotLeakGoroutinesWhenProviderClosesConnection(t *testing.
|
|||||||
t.Fatalf("unexpected error sending log request: %s", err)
|
t.Fatalf("unexpected error sending log request: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error reading the response body: %s", err)
|
t.Fatalf("unexpected error reading the response body: %s", err)
|
||||||
}
|
}
|
||||||
@ -126,7 +126,7 @@ func Test_logsProxyDoesNotLeakGoroutinesWhenClientClosesConnection(t *testing.T)
|
|||||||
go func() {
|
go func() {
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
defer close(errCh)
|
defer close(errCh)
|
||||||
_, err := ioutil.ReadAll(resp.Body)
|
_, err := io.ReadAll(resp.Body)
|
||||||
errCh <- err
|
errCh <- err
|
||||||
}()
|
}()
|
||||||
cancel()
|
cancel()
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/openfaas/faas/gateway/pkg/middleware"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/openfaas/faas/gateway/pkg/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_getNamespace_Default(t *testing.T) {
|
func Test_getNamespace_Default(t *testing.T) {
|
||||||
|
@ -1,5 +1,10 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved.
|
// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved.
|
// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
|
@ -17,20 +17,6 @@ type HTTPNotifier interface {
|
|||||||
Notify(method string, URL string, originalURL string, statusCode int, event string, duration time.Duration)
|
Notify(method string, URL string, originalURL string, statusCode int, event string, duration time.Duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrometheusServiceNotifier notifier for core service endpoints
|
|
||||||
type PrometheusServiceNotifier struct {
|
|
||||||
ServiceMetrics *metrics.ServiceMetricOptions
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify about service metrics
|
|
||||||
func (psn PrometheusServiceNotifier) Notify(method string, URL string, originalURL string, statusCode int, event string, duration time.Duration) {
|
|
||||||
code := fmt.Sprintf("%d", statusCode)
|
|
||||||
path := urlToLabel(URL)
|
|
||||||
|
|
||||||
psn.ServiceMetrics.Counter.WithLabelValues(method, path, code).Inc()
|
|
||||||
psn.ServiceMetrics.Histogram.WithLabelValues(method, path, code).Observe(duration.Seconds())
|
|
||||||
}
|
|
||||||
|
|
||||||
func urlToLabel(path string) string {
|
func urlToLabel(path string) string {
|
||||||
if len(path) > 0 {
|
if len(path) > 0 {
|
||||||
path = strings.TrimRight(path, "/")
|
path = strings.TrimRight(path, "/")
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
package handlers
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"golang.org/x/sync/singleflight"
|
|
||||||
|
|
||||||
"github.com/openfaas/faas/gateway/pkg/middleware"
|
|
||||||
"github.com/openfaas/faas/gateway/probing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func MakeProbeHandler(prober probing.FunctionProber, cache probing.ProbeCacher, resolver middleware.BaseURLResolver, next http.HandlerFunc, defaultNamespace string) http.HandlerFunc {
|
|
||||||
|
|
||||||
group := singleflight.Group{}
|
|
||||||
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
functionName, namespace := middleware.GetNamespace(defaultNamespace, middleware.GetServiceName(r.URL.String()))
|
|
||||||
|
|
||||||
key := fmt.Sprintf("Probe-%s.%s", functionName, namespace)
|
|
||||||
res, _, _ := group.Do(key, func() (interface{}, error) {
|
|
||||||
|
|
||||||
cached, hit := cache.Get(functionName, namespace)
|
|
||||||
var probeResult probing.FunctionProbeResult
|
|
||||||
if hit && cached != nil && cached.Available {
|
|
||||||
probeResult = *cached
|
|
||||||
} else {
|
|
||||||
probeResult = prober.Probe(functionName, namespace)
|
|
||||||
cache.Set(functionName, namespace, &probeResult)
|
|
||||||
}
|
|
||||||
|
|
||||||
return probeResult, nil
|
|
||||||
})
|
|
||||||
|
|
||||||
fnRes := res.(probing.FunctionProbeResult)
|
|
||||||
|
|
||||||
if !fnRes.Available {
|
|
||||||
http.Error(w, fmt.Sprintf("unable to probe function endpoint %s", fnRes.Error),
|
|
||||||
http.StatusServiceUnavailable)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
next(w, r)
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +1,14 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
@ -21,15 +24,16 @@ import (
|
|||||||
// MakeQueuedProxy accepts work onto a queue
|
// MakeQueuedProxy accepts work onto a queue
|
||||||
func MakeQueuedProxy(metrics metrics.MetricOptions, queuer ftypes.RequestQueuer, pathTransformer middleware.URLPathTransformer, defaultNS string, functionQuery scaling.FunctionQuery) http.HandlerFunc {
|
func MakeQueuedProxy(metrics metrics.MetricOptions, queuer ftypes.RequestQueuer, pathTransformer middleware.URLPathTransformer, defaultNS string, functionQuery scaling.FunctionQuery) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var body []byte
|
||||||
if r.Body != nil {
|
if r.Body != nil {
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
}
|
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(r.Body)
|
var err error
|
||||||
|
body, err = io.ReadAll(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
callbackURL, err := getCallbackURLHeader(r.Header)
|
callbackURL, err := getCallbackURLHeader(r.Header)
|
||||||
@ -53,8 +57,9 @@ func MakeQueuedProxy(metrics metrics.MetricOptions, queuer ftypes.RequestQueuer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err = queuer.Queue(req); err != nil {
|
if err = queuer.Queue(req); err != nil {
|
||||||
fmt.Printf("Queue error: %v\n", err)
|
log.Printf("Error queuing request: %v", err)
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
http.Error(w, fmt.Sprintf("Error queuing request: %s", err.Error()),
|
||||||
|
http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@ -15,7 +17,6 @@ import (
|
|||||||
"github.com/openfaas/faas/gateway/metrics"
|
"github.com/openfaas/faas/gateway/metrics"
|
||||||
"github.com/openfaas/faas/gateway/pkg/middleware"
|
"github.com/openfaas/faas/gateway/pkg/middleware"
|
||||||
"github.com/openfaas/faas/gateway/plugin"
|
"github.com/openfaas/faas/gateway/plugin"
|
||||||
"github.com/openfaas/faas/gateway/probing"
|
|
||||||
"github.com/openfaas/faas/gateway/scaling"
|
"github.com/openfaas/faas/gateway/scaling"
|
||||||
"github.com/openfaas/faas/gateway/types"
|
"github.com/openfaas/faas/gateway/types"
|
||||||
"github.com/openfaas/faas/gateway/version"
|
"github.com/openfaas/faas/gateway/version"
|
||||||
@ -83,13 +84,9 @@ func main() {
|
|||||||
FunctionNamespace: config.Namespace,
|
FunctionNamespace: config.Namespace,
|
||||||
}
|
}
|
||||||
|
|
||||||
prometheusServiceNotifier := handlers.PrometheusServiceNotifier{
|
|
||||||
ServiceMetrics: metricsOptions.ServiceMetrics,
|
|
||||||
}
|
|
||||||
|
|
||||||
functionNotifiers := []handlers.HTTPNotifier{loggingNotifier, prometheusNotifier}
|
functionNotifiers := []handlers.HTTPNotifier{loggingNotifier, prometheusNotifier}
|
||||||
forwardingNotifiers := []handlers.HTTPNotifier{loggingNotifier, prometheusServiceNotifier}
|
forwardingNotifiers := []handlers.HTTPNotifier{loggingNotifier}
|
||||||
quietNotifier := []handlers.HTTPNotifier{prometheusServiceNotifier}
|
quietNotifier := []handlers.HTTPNotifier{}
|
||||||
|
|
||||||
urlResolver := middleware.SingleHostBaseURLResolver{BaseURL: config.FunctionsProviderURL.String()}
|
urlResolver := middleware.SingleHostBaseURLResolver{BaseURL: config.FunctionsProviderURL.String()}
|
||||||
var functionURLResolver middleware.BaseURLResolver
|
var functionURLResolver middleware.BaseURLResolver
|
||||||
@ -97,16 +94,8 @@ func main() {
|
|||||||
nilURLTransformer := middleware.TransparentURLPathTransformer{}
|
nilURLTransformer := middleware.TransparentURLPathTransformer{}
|
||||||
trimURLTransformer := middleware.FunctionPrefixTrimmingURLPathTransformer{}
|
trimURLTransformer := middleware.FunctionPrefixTrimmingURLPathTransformer{}
|
||||||
|
|
||||||
if config.DirectFunctions {
|
functionURLResolver = urlResolver
|
||||||
functionURLResolver = middleware.FunctionAsHostBaseURLResolver{
|
functionURLTransformer = nilURLTransformer
|
||||||
FunctionSuffix: config.DirectFunctionsSuffix,
|
|
||||||
FunctionNamespace: config.Namespace,
|
|
||||||
}
|
|
||||||
functionURLTransformer = trimURLTransformer
|
|
||||||
} else {
|
|
||||||
functionURLResolver = urlResolver
|
|
||||||
functionURLTransformer = nilURLTransformer
|
|
||||||
}
|
|
||||||
|
|
||||||
var serviceAuthInjector middleware.AuthInjector
|
var serviceAuthInjector middleware.AuthInjector
|
||||||
|
|
||||||
@ -114,8 +103,6 @@ func main() {
|
|||||||
serviceAuthInjector = &middleware.BasicAuthInjector{Credentials: credentials}
|
serviceAuthInjector = &middleware.BasicAuthInjector{Credentials: credentials}
|
||||||
}
|
}
|
||||||
|
|
||||||
decorateExternalAuth := handlers.MakeExternalAuthHandler
|
|
||||||
|
|
||||||
// externalServiceQuery is used to query metadata from the provider about a function
|
// externalServiceQuery is used to query metadata from the provider about a function
|
||||||
externalServiceQuery := plugin.NewExternalServiceQuery(*config.FunctionsProviderURL, serviceAuthInjector)
|
externalServiceQuery := plugin.NewExternalServiceQuery(*config.FunctionsProviderURL, serviceAuthInjector)
|
||||||
|
|
||||||
@ -142,9 +129,12 @@ func main() {
|
|||||||
faasHandlers.FunctionStatus = handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer, serviceAuthInjector)
|
faasHandlers.FunctionStatus = handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer, serviceAuthInjector)
|
||||||
|
|
||||||
faasHandlers.InfoHandler = handlers.MakeInfoHandler(handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer, serviceAuthInjector))
|
faasHandlers.InfoHandler = handlers.MakeInfoHandler(handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer, serviceAuthInjector))
|
||||||
|
faasHandlers.TelemetryHandler = handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer, nil)
|
||||||
|
|
||||||
faasHandlers.SecretHandler = handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer, serviceAuthInjector)
|
faasHandlers.SecretHandler = handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer, serviceAuthInjector)
|
||||||
|
|
||||||
faasHandlers.NamespaceListerHandler = handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer, serviceAuthInjector)
|
faasHandlers.NamespaceListerHandler = handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer, serviceAuthInjector)
|
||||||
|
faasHandlers.NamespaceMutatorHandler = handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer, serviceAuthInjector)
|
||||||
|
|
||||||
faasHandlers.Alert = handlers.MakeNotifierWrapper(
|
faasHandlers.Alert = handlers.MakeNotifierWrapper(
|
||||||
handlers.MakeAlertHandler(externalServiceQuery, config.Namespace),
|
handlers.MakeAlertHandler(externalServiceQuery, config.Namespace),
|
||||||
@ -155,13 +145,6 @@ func main() {
|
|||||||
|
|
||||||
functionProxy := faasHandlers.Proxy
|
functionProxy := faasHandlers.Proxy
|
||||||
|
|
||||||
if config.ProbeFunctions {
|
|
||||||
prober := probing.NewFunctionProber(cachedFunctionQuery, functionURLResolver)
|
|
||||||
// Default of 5 seconds between refreshing probes for function invocations
|
|
||||||
probeCache := probing.NewProbeCache(time.Second * 5)
|
|
||||||
functionProxy = handlers.MakeProbeHandler(prober, probeCache, functionURLResolver, functionProxy, config.Namespace)
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.ScaleFromZero {
|
if config.ScaleFromZero {
|
||||||
scalingFunctionCache := scaling.NewFunctionCache(scalingConfig.CacheExpiry)
|
scalingFunctionCache := scaling.NewFunctionCache(scalingConfig.CacheExpiry)
|
||||||
scaler := scaling.NewFunctionScaler(scalingConfig, scalingFunctionCache)
|
scaler := scaling.NewFunctionScaler(scalingConfig, scalingFunctionCache)
|
||||||
@ -169,7 +152,9 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if config.UseNATS() {
|
if config.UseNATS() {
|
||||||
log.Println("Async enabled: Using NATS Streaming.")
|
log.Println("Async enabled: Using NATS Streaming")
|
||||||
|
log.Println("Deprecation Notice: NATS Streaming is no longer maintained and won't receive updates from June 2023")
|
||||||
|
|
||||||
maxReconnect := 60
|
maxReconnect := 60
|
||||||
interval := time.Second * 2
|
interval := time.Second * 2
|
||||||
|
|
||||||
@ -186,33 +171,35 @@ func main() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
prometheusQuery := metrics.NewPrometheusQuery(config.PrometheusHost, config.PrometheusPort, &http.Client{})
|
prometheusQuery := metrics.NewPrometheusQuery(config.PrometheusHost, config.PrometheusPort, http.DefaultClient, version.BuildVersion())
|
||||||
faasHandlers.ListFunctions = metrics.AddMetricsHandler(faasHandlers.ListFunctions, prometheusQuery)
|
faasHandlers.ListFunctions = metrics.AddMetricsHandler(faasHandlers.ListFunctions, prometheusQuery)
|
||||||
faasHandlers.ScaleFunction = handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer, serviceAuthInjector)
|
faasHandlers.ScaleFunction = scaling.MakeHorizontalScalingHandler(handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer, serviceAuthInjector))
|
||||||
|
|
||||||
if credentials != nil {
|
if credentials != nil {
|
||||||
faasHandlers.Alert =
|
faasHandlers.Alert =
|
||||||
decorateExternalAuth(faasHandlers.Alert, config.UpstreamTimeout, config.AuthProxyURL, config.AuthProxyPassBody)
|
auth.DecorateWithBasicAuth(faasHandlers.Alert, credentials)
|
||||||
faasHandlers.UpdateFunction =
|
faasHandlers.UpdateFunction =
|
||||||
decorateExternalAuth(faasHandlers.UpdateFunction, config.UpstreamTimeout, config.AuthProxyURL, config.AuthProxyPassBody)
|
auth.DecorateWithBasicAuth(faasHandlers.UpdateFunction, credentials)
|
||||||
faasHandlers.DeleteFunction =
|
faasHandlers.DeleteFunction =
|
||||||
decorateExternalAuth(faasHandlers.DeleteFunction, config.UpstreamTimeout, config.AuthProxyURL, config.AuthProxyPassBody)
|
auth.DecorateWithBasicAuth(faasHandlers.DeleteFunction, credentials)
|
||||||
faasHandlers.DeployFunction =
|
faasHandlers.DeployFunction =
|
||||||
decorateExternalAuth(faasHandlers.DeployFunction, config.UpstreamTimeout, config.AuthProxyURL, config.AuthProxyPassBody)
|
auth.DecorateWithBasicAuth(faasHandlers.DeployFunction, credentials)
|
||||||
faasHandlers.ListFunctions =
|
faasHandlers.ListFunctions =
|
||||||
decorateExternalAuth(faasHandlers.ListFunctions, config.UpstreamTimeout, config.AuthProxyURL, config.AuthProxyPassBody)
|
auth.DecorateWithBasicAuth(faasHandlers.ListFunctions, credentials)
|
||||||
faasHandlers.ScaleFunction =
|
faasHandlers.ScaleFunction =
|
||||||
decorateExternalAuth(faasHandlers.ScaleFunction, config.UpstreamTimeout, config.AuthProxyURL, config.AuthProxyPassBody)
|
auth.DecorateWithBasicAuth(faasHandlers.ScaleFunction, credentials)
|
||||||
faasHandlers.FunctionStatus =
|
faasHandlers.FunctionStatus =
|
||||||
decorateExternalAuth(faasHandlers.FunctionStatus, config.UpstreamTimeout, config.AuthProxyURL, config.AuthProxyPassBody)
|
auth.DecorateWithBasicAuth(faasHandlers.FunctionStatus, credentials)
|
||||||
faasHandlers.InfoHandler =
|
faasHandlers.InfoHandler =
|
||||||
decorateExternalAuth(faasHandlers.InfoHandler, config.UpstreamTimeout, config.AuthProxyURL, config.AuthProxyPassBody)
|
auth.DecorateWithBasicAuth(faasHandlers.InfoHandler, credentials)
|
||||||
faasHandlers.SecretHandler =
|
faasHandlers.SecretHandler =
|
||||||
decorateExternalAuth(faasHandlers.SecretHandler, config.UpstreamTimeout, config.AuthProxyURL, config.AuthProxyPassBody)
|
auth.DecorateWithBasicAuth(faasHandlers.SecretHandler, credentials)
|
||||||
faasHandlers.LogProxyHandler =
|
faasHandlers.LogProxyHandler =
|
||||||
decorateExternalAuth(faasHandlers.LogProxyHandler, config.UpstreamTimeout, config.AuthProxyURL, config.AuthProxyPassBody)
|
auth.DecorateWithBasicAuth(faasHandlers.LogProxyHandler, credentials)
|
||||||
faasHandlers.NamespaceListerHandler =
|
faasHandlers.NamespaceListerHandler =
|
||||||
decorateExternalAuth(faasHandlers.NamespaceListerHandler, config.UpstreamTimeout, config.AuthProxyURL, config.AuthProxyPassBody)
|
auth.DecorateWithBasicAuth(faasHandlers.NamespaceListerHandler, credentials)
|
||||||
|
faasHandlers.NamespaceMutatorHandler =
|
||||||
|
auth.DecorateWithBasicAuth(faasHandlers.NamespaceMutatorHandler, credentials)
|
||||||
}
|
}
|
||||||
|
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
@ -223,6 +210,8 @@ func main() {
|
|||||||
r.HandleFunc("/function/{name:["+NameExpression+"]+}/{params:.*}", functionProxy)
|
r.HandleFunc("/function/{name:["+NameExpression+"]+}/{params:.*}", functionProxy)
|
||||||
|
|
||||||
r.HandleFunc("/system/info", faasHandlers.InfoHandler).Methods(http.MethodGet)
|
r.HandleFunc("/system/info", faasHandlers.InfoHandler).Methods(http.MethodGet)
|
||||||
|
r.HandleFunc("/system/telemetry", faasHandlers.TelemetryHandler).Methods(http.MethodGet)
|
||||||
|
|
||||||
r.HandleFunc("/system/alert", faasHandlers.Alert).Methods(http.MethodPost)
|
r.HandleFunc("/system/alert", faasHandlers.Alert).Methods(http.MethodPost)
|
||||||
|
|
||||||
r.HandleFunc("/system/function/{name:["+NameExpression+"]+}", faasHandlers.FunctionStatus).Methods(http.MethodGet)
|
r.HandleFunc("/system/function/{name:["+NameExpression+"]+}", faasHandlers.FunctionStatus).Methods(http.MethodGet)
|
||||||
@ -236,6 +225,8 @@ func main() {
|
|||||||
r.HandleFunc("/system/logs", faasHandlers.LogProxyHandler).Methods(http.MethodGet)
|
r.HandleFunc("/system/logs", faasHandlers.LogProxyHandler).Methods(http.MethodGet)
|
||||||
|
|
||||||
r.HandleFunc("/system/namespaces", faasHandlers.NamespaceListerHandler).Methods(http.MethodGet)
|
r.HandleFunc("/system/namespaces", faasHandlers.NamespaceListerHandler).Methods(http.MethodGet)
|
||||||
|
r.HandleFunc("/system/namespace/{namespace:["+NameExpression+"]*}", faasHandlers.NamespaceMutatorHandler).
|
||||||
|
Methods(http.MethodPost, http.MethodDelete, http.MethodPut, http.MethodGet)
|
||||||
|
|
||||||
if faasHandlers.QueuedProxy != nil {
|
if faasHandlers.QueuedProxy != nil {
|
||||||
r.HandleFunc("/async-function/{name:["+NameExpression+"]+}/", faasHandlers.QueuedProxy).Methods(http.MethodPost)
|
r.HandleFunc("/async-function/{name:["+NameExpression+"]+}/", faasHandlers.QueuedProxy).Methods(http.MethodPost)
|
||||||
@ -252,9 +243,11 @@ func main() {
|
|||||||
uiHandler := http.StripPrefix("/ui", fsCORS)
|
uiHandler := http.StripPrefix("/ui", fsCORS)
|
||||||
if credentials != nil {
|
if credentials != nil {
|
||||||
r.PathPrefix("/ui/").Handler(
|
r.PathPrefix("/ui/").Handler(
|
||||||
decorateExternalAuth(uiHandler.ServeHTTP, config.UpstreamTimeout, config.AuthProxyURL, config.AuthProxyPassBody)).Methods(http.MethodGet)
|
auth.DecorateWithBasicAuth(uiHandler.ServeHTTP, credentials)).
|
||||||
|
Methods(http.MethodGet)
|
||||||
} else {
|
} else {
|
||||||
r.PathPrefix("/ui/").Handler(uiHandler).Methods(http.MethodGet)
|
r.PathPrefix("/ui/").Handler(uiHandler).
|
||||||
|
Methods(http.MethodGet)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Start metrics server in a goroutine
|
//Start metrics server in a goroutine
|
||||||
@ -263,7 +256,7 @@ func main() {
|
|||||||
r.HandleFunc("/healthz",
|
r.HandleFunc("/healthz",
|
||||||
handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer, serviceAuthInjector)).Methods(http.MethodGet)
|
handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver, nilURLTransformer, serviceAuthInjector)).Methods(http.MethodGet)
|
||||||
|
|
||||||
r.Handle("/", http.RedirectHandler("/ui/", http.StatusMovedPermanently)).Methods(http.MethodGet)
|
r.Handle("/", http.RedirectHandler("/ui/", http.StatusTemporaryRedirect)).Methods(http.MethodGet)
|
||||||
|
|
||||||
tcpPort := 8080
|
tcpPort := 8080
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package metrics
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
@ -28,7 +28,7 @@ func AddMetricsHandler(handler http.HandlerFunc, prometheusQuery PrometheusQuery
|
|||||||
}
|
}
|
||||||
|
|
||||||
defer upstreamCall.Body.Close()
|
defer upstreamCall.Body.Close()
|
||||||
upstreamBody, _ := ioutil.ReadAll(upstreamCall.Body)
|
upstreamBody, _ := io.ReadAll(upstreamCall.Body)
|
||||||
|
|
||||||
if recorder.Code != http.StatusOK {
|
if recorder.Code != http.StatusOK {
|
||||||
log.Printf("List functions responded with code %d, body: %s",
|
log.Printf("List functions responded with code %d, body: %s",
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) Alex Ellis 2017
|
// Copyright (c) Alex Ellis 2017
|
||||||
// Copyright (c) 2018 OpenFaaS Author(s)
|
// Copyright (c) 2018 OpenFaaS Author(s)
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package metrics
|
package metrics
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@ -46,9 +48,6 @@ func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
|
|||||||
e.metricOptions.GatewayFunctionsHistogram.Describe(ch)
|
e.metricOptions.GatewayFunctionsHistogram.Describe(ch)
|
||||||
e.metricOptions.ServiceReplicasGauge.Describe(ch)
|
e.metricOptions.ServiceReplicasGauge.Describe(ch)
|
||||||
e.metricOptions.GatewayFunctionInvocationStarted.Describe(ch)
|
e.metricOptions.GatewayFunctionInvocationStarted.Describe(ch)
|
||||||
|
|
||||||
e.metricOptions.ServiceMetrics.Counter.Describe(ch)
|
|
||||||
e.metricOptions.ServiceMetrics.Histogram.Describe(ch)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect collects data to be consumed by prometheus
|
// Collect collects data to be consumed by prometheus
|
||||||
@ -75,9 +74,6 @@ func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
e.metricOptions.ServiceReplicasGauge.Collect(ch)
|
e.metricOptions.ServiceReplicasGauge.Collect(ch)
|
||||||
|
|
||||||
e.metricOptions.ServiceMetrics.Counter.Collect(ch)
|
|
||||||
e.metricOptions.ServiceMetrics.Histogram.Collect(ch)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartServiceWatcher starts a ticker and collects service replica counts to expose to prometheus
|
// StartServiceWatcher starts a ticker and collects service replica counts to expose to prometheus
|
||||||
@ -92,7 +88,7 @@ func (e *Exporter) StartServiceWatcher(endpointURL url.URL, metricsOptions Metri
|
|||||||
|
|
||||||
namespaces, err := e.getNamespaces(endpointURL)
|
namespaces, err := e.getNamespaces(endpointURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Printf("Error listing namespaces: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
services := []types.FunctionStatus{}
|
services := []types.FunctionStatus{}
|
||||||
@ -101,7 +97,7 @@ func (e *Exporter) StartServiceWatcher(endpointURL url.URL, metricsOptions Metri
|
|||||||
if len(namespaces) == 0 {
|
if len(namespaces) == 0 {
|
||||||
services, err = e.getFunctions(endpointURL, e.FunctionNamespace)
|
services, err = e.getFunctions(endpointURL, e.FunctionNamespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Printf("Error getting functions from: %s, error: %s", e.FunctionNamespace, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
e.services = services
|
e.services = services
|
||||||
@ -109,7 +105,7 @@ func (e *Exporter) StartServiceWatcher(endpointURL url.URL, metricsOptions Metri
|
|||||||
for _, namespace := range namespaces {
|
for _, namespace := range namespaces {
|
||||||
nsServices, err := e.getFunctions(endpointURL, namespace)
|
nsServices, err := e.getFunctions(endpointURL, namespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Printf("Error getting functions from: %s, error: %s", e.FunctionNamespace, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
services = append(services, nsServices...)
|
services = append(services, nsServices...)
|
||||||
@ -118,7 +114,6 @@ func (e *Exporter) StartServiceWatcher(endpointURL url.URL, metricsOptions Metri
|
|||||||
|
|
||||||
e.services = services
|
e.services = services
|
||||||
|
|
||||||
break
|
|
||||||
case <-quit:
|
case <-quit:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -165,14 +160,24 @@ func (e *Exporter) getFunctions(endpointURL url.URL, namespace string) ([]types.
|
|||||||
return services, err
|
return services, err
|
||||||
}
|
}
|
||||||
|
|
||||||
bytesOut, readErr := ioutil.ReadAll(res.Body)
|
var body []byte
|
||||||
if readErr != nil {
|
if res.Body != nil {
|
||||||
return services, readErr
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
if b, err := io.ReadAll(res.Body); err != nil {
|
||||||
|
return services, err
|
||||||
|
} else {
|
||||||
|
body = b
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.Unmarshal(bytesOut, &services); err != nil {
|
if len(body) == 0 {
|
||||||
|
return services, fmt.Errorf("no response body from /system/functions")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(body, &services); err != nil {
|
||||||
return services, fmt.Errorf("error unmarshalling response: %s, error: %s",
|
return services, fmt.Errorf("error unmarshalling response: %s, error: %s",
|
||||||
string(bytesOut), err)
|
string(body), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return services, nil
|
return services, nil
|
||||||
@ -199,13 +204,24 @@ func (e *Exporter) getNamespaces(endpointURL url.URL) ([]string, error) {
|
|||||||
return namespaces, nil
|
return namespaces, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
bytesOut, readErr := ioutil.ReadAll(res.Body)
|
var body []byte
|
||||||
if readErr != nil {
|
if res.Body != nil {
|
||||||
return namespaces, readErr
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
if b, err := io.ReadAll(res.Body); err != nil {
|
||||||
|
return namespaces, err
|
||||||
|
} else {
|
||||||
|
body = b
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.Unmarshal(bytesOut, &namespaces); err != nil {
|
if len(body) == 0 {
|
||||||
return namespaces, fmt.Errorf("error unmarshalling response: %s, error: %s", string(bytesOut), err)
|
return namespaces, fmt.Errorf("no response body from /system/namespaces")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(body, &namespaces); err != nil {
|
||||||
|
return namespaces, fmt.Errorf("error unmarshalling response: %s, error: %s", string(body), err)
|
||||||
|
}
|
||||||
|
|
||||||
return namespaces, nil
|
return namespaces, nil
|
||||||
}
|
}
|
||||||
|
@ -41,21 +41,21 @@ func Test_Describe_DescribesThePrometheusMetrics(t *testing.T) {
|
|||||||
go exporter.Describe(ch)
|
go exporter.Describe(ch)
|
||||||
|
|
||||||
d := <-ch
|
d := <-ch
|
||||||
expectedGatewayFunctionInvocationDesc := `Desc{fqName: "gateway_function_invocation_total", help: "Function metrics", constLabels: {}, variableLabels: [function_name code]}`
|
expectedGatewayFunctionInvocationDesc := `Desc{fqName: "gateway_function_invocation_total", help: "Function metrics", constLabels: {}, variableLabels: {function_name,code}}`
|
||||||
actualGatewayFunctionInvocationDesc := d.String()
|
actualGatewayFunctionInvocationDesc := d.String()
|
||||||
if expectedGatewayFunctionInvocationDesc != actualGatewayFunctionInvocationDesc {
|
if expectedGatewayFunctionInvocationDesc != actualGatewayFunctionInvocationDesc {
|
||||||
t.Errorf("Want\n%s\ngot\n%s", expectedGatewayFunctionInvocationDesc, actualGatewayFunctionInvocationDesc)
|
t.Errorf("Want\n%s\ngot\n%s", expectedGatewayFunctionInvocationDesc, actualGatewayFunctionInvocationDesc)
|
||||||
}
|
}
|
||||||
|
|
||||||
d = <-ch
|
d = <-ch
|
||||||
expectedGatewayFunctionsHistogramDesc := `Desc{fqName: "gateway_functions_seconds", help: "Function time taken", constLabels: {}, variableLabels: [function_name code]}`
|
expectedGatewayFunctionsHistogramDesc := `Desc{fqName: "gateway_functions_seconds", help: "Function time taken", constLabels: {}, variableLabels: {function_name,code}}`
|
||||||
actualGatewayFunctionsHistogramDesc := d.String()
|
actualGatewayFunctionsHistogramDesc := d.String()
|
||||||
if expectedGatewayFunctionsHistogramDesc != actualGatewayFunctionsHistogramDesc {
|
if expectedGatewayFunctionsHistogramDesc != actualGatewayFunctionsHistogramDesc {
|
||||||
t.Errorf("Want\n%s\ngot\n%s", expectedGatewayFunctionsHistogramDesc, actualGatewayFunctionsHistogramDesc)
|
t.Errorf("Want\n%s\ngot\n%s", expectedGatewayFunctionsHistogramDesc, actualGatewayFunctionsHistogramDesc)
|
||||||
}
|
}
|
||||||
|
|
||||||
d = <-ch
|
d = <-ch
|
||||||
expectedServiceReplicasGaugeDesc := `Desc{fqName: "gateway_service_count", help: "Current count of replicas for function", constLabels: {}, variableLabels: [function_name]}`
|
expectedServiceReplicasGaugeDesc := `Desc{fqName: "gateway_service_count", help: "Current count of replicas for function", constLabels: {}, variableLabels: {function_name}}`
|
||||||
actualServiceReplicasGaugeDesc := d.String()
|
actualServiceReplicasGaugeDesc := d.String()
|
||||||
if expectedServiceReplicasGaugeDesc != actualServiceReplicasGaugeDesc {
|
if expectedServiceReplicasGaugeDesc != actualServiceReplicasGaugeDesc {
|
||||||
t.Errorf("Want\n%s\ngot\n%s", expectedServiceReplicasGaugeDesc, actualServiceReplicasGaugeDesc)
|
t.Errorf("Want\n%s\ngot\n%s", expectedServiceReplicasGaugeDesc, actualServiceReplicasGaugeDesc)
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package metrics
|
package metrics
|
||||||
|
|
||||||
@ -18,8 +20,6 @@ type MetricOptions struct {
|
|||||||
GatewayFunctionInvocationStarted *prometheus.CounterVec
|
GatewayFunctionInvocationStarted *prometheus.CounterVec
|
||||||
|
|
||||||
ServiceReplicasGauge *prometheus.GaugeVec
|
ServiceReplicasGauge *prometheus.GaugeVec
|
||||||
|
|
||||||
ServiceMetrics *ServiceMetricOptions
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServiceMetricOptions provides RED metrics
|
// ServiceMetricOptions provides RED metrics
|
||||||
@ -69,24 +69,6 @@ func BuildMetricsOptions() MetricOptions {
|
|||||||
[]string{"function_name"},
|
[]string{"function_name"},
|
||||||
)
|
)
|
||||||
|
|
||||||
// For automatic monitoring and alerting (RED method)
|
|
||||||
histogram := prometheus.NewHistogramVec(prometheus.HistogramOpts{
|
|
||||||
Subsystem: "http",
|
|
||||||
Name: "request_duration_seconds",
|
|
||||||
Help: "Seconds spent serving HTTP requests.",
|
|
||||||
Buckets: prometheus.DefBuckets,
|
|
||||||
}, []string{"method", "path", "status"})
|
|
||||||
|
|
||||||
// Can be used Kubernetes HPA v2
|
|
||||||
counter := prometheus.NewCounterVec(
|
|
||||||
prometheus.CounterOpts{
|
|
||||||
Subsystem: "http",
|
|
||||||
Name: "requests_total",
|
|
||||||
Help: "The total number of HTTP requests.",
|
|
||||||
},
|
|
||||||
[]string{"method", "path", "status"},
|
|
||||||
)
|
|
||||||
|
|
||||||
gatewayFunctionInvocationStarted := prometheus.NewCounterVec(
|
gatewayFunctionInvocationStarted := prometheus.NewCounterVec(
|
||||||
prometheus.CounterOpts{
|
prometheus.CounterOpts{
|
||||||
Namespace: "gateway",
|
Namespace: "gateway",
|
||||||
@ -97,16 +79,10 @@ func BuildMetricsOptions() MetricOptions {
|
|||||||
[]string{"function_name"},
|
[]string{"function_name"},
|
||||||
)
|
)
|
||||||
|
|
||||||
serviceMetricOptions := &ServiceMetricOptions{
|
|
||||||
Counter: counter,
|
|
||||||
Histogram: histogram,
|
|
||||||
}
|
|
||||||
|
|
||||||
metricsOptions := MetricOptions{
|
metricsOptions := MetricOptions{
|
||||||
GatewayFunctionsHistogram: gatewayFunctionsHistogram,
|
GatewayFunctionsHistogram: gatewayFunctionsHistogram,
|
||||||
GatewayFunctionInvocation: gatewayFunctionInvocation,
|
GatewayFunctionInvocation: gatewayFunctionInvocation,
|
||||||
ServiceReplicasGauge: serviceReplicas,
|
ServiceReplicasGauge: serviceReplicas,
|
||||||
ServiceMetrics: serviceMetricOptions,
|
|
||||||
GatewayFunctionInvocationStarted: gatewayFunctionInvocationStarted,
|
GatewayFunctionInvocationStarted: gatewayFunctionInvocationStarted,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,15 +3,16 @@ package metrics
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PrometheusQuery represents parameters for querying Prometheus
|
// PrometheusQuery represents parameters for querying Prometheus
|
||||||
type PrometheusQuery struct {
|
type PrometheusQuery struct {
|
||||||
Port int
|
host string
|
||||||
Host string
|
port int
|
||||||
Client *http.Client
|
client *http.Client
|
||||||
|
userAgentVersion string
|
||||||
}
|
}
|
||||||
|
|
||||||
type PrometheusQueryFetcher interface {
|
type PrometheusQueryFetcher interface {
|
||||||
@ -19,45 +20,47 @@ type PrometheusQueryFetcher interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewPrometheusQuery create a NewPrometheusQuery
|
// NewPrometheusQuery create a NewPrometheusQuery
|
||||||
func NewPrometheusQuery(host string, port int, client *http.Client) PrometheusQuery {
|
func NewPrometheusQuery(host string, port int, client *http.Client, userAgentVersion string) PrometheusQuery {
|
||||||
return PrometheusQuery{
|
return PrometheusQuery{
|
||||||
Client: client,
|
client: client,
|
||||||
Host: host,
|
host: host,
|
||||||
Port: port,
|
port: port,
|
||||||
|
userAgentVersion: userAgentVersion,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch queries aggregated stats
|
// Fetch queries aggregated stats
|
||||||
func (q PrometheusQuery) Fetch(query string) (*VectorQueryResponse, error) {
|
func (q PrometheusQuery) Fetch(query string) (*VectorQueryResponse, error) {
|
||||||
|
|
||||||
req, reqErr := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s:%d/api/v1/query?query=%s", q.Host, q.Port, query), nil)
|
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://%s:%d/api/v1/query?query=%s", q.host, q.port, query), nil)
|
||||||
if reqErr != nil {
|
if err != nil {
|
||||||
return nil, reqErr
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
res, getErr := q.Client.Do(req)
|
req.Header.Set("User-Agent", fmt.Sprintf("openfaas-gateway/%s (Prometheus query)", q.userAgentVersion))
|
||||||
if getErr != nil {
|
|
||||||
return nil, getErr
|
res, err := q.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.Body != nil {
|
if res.Body != nil {
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
bytesOut, readErr := ioutil.ReadAll(res.Body)
|
bytesOut, err := io.ReadAll(res.Body)
|
||||||
if readErr != nil {
|
if err != nil {
|
||||||
return nil, readErr
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if res.StatusCode != http.StatusOK {
|
if res.StatusCode != http.StatusOK {
|
||||||
return nil, fmt.Errorf("Unexpected status code from Prometheus want: %d, got: %d, body: %s", http.StatusOK, res.StatusCode, string(bytesOut))
|
return nil, fmt.Errorf("unexpected status code from Prometheus want: %d, got: %d, body: %s", http.StatusOK, res.StatusCode, string(bytesOut))
|
||||||
}
|
}
|
||||||
|
|
||||||
var values VectorQueryResponse
|
var values VectorQueryResponse
|
||||||
|
|
||||||
unmarshalErr := json.Unmarshal(bytesOut, &values)
|
if err := json.Unmarshal(bytesOut, &values); err != nil {
|
||||||
if unmarshalErr != nil {
|
return nil, fmt.Errorf("error unmarshaling result: %s, '%s'", err, string(bytesOut))
|
||||||
return nil, fmt.Errorf("Error unmarshaling result: %s, '%s'", unmarshalErr, string(bytesOut))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &values, nil
|
return &values, nil
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@ package middleware
|
|||||||
|
|
||||||
import "net/http"
|
import "net/http"
|
||||||
|
|
||||||
|
// AuthInjector is an interface for injecting authentication information into a request
|
||||||
|
// which will be proxied or made to a remote/upstream service.
|
||||||
type AuthInjector interface {
|
type AuthInjector interface {
|
||||||
Inject(r *http.Request)
|
Inject(r *http.Request)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package plugin
|
package plugin
|
||||||
|
|
||||||
@ -7,7 +9,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -89,7 +91,7 @@ func (s ExternalServiceQuery) GetReplicas(serviceName, serviceNamespace string)
|
|||||||
|
|
||||||
var bytesOut []byte
|
var bytesOut []byte
|
||||||
if res.Body != nil {
|
if res.Body != nil {
|
||||||
bytesOut, _ = ioutil.ReadAll(res.Body)
|
bytesOut, _ = io.ReadAll(res.Body)
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,20 +113,17 @@ func (s ExternalServiceQuery) GetReplicas(serviceName, serviceNamespace string)
|
|||||||
scalingFactor := uint64(scaling.DefaultScalingFactor)
|
scalingFactor := uint64(scaling.DefaultScalingFactor)
|
||||||
availableReplicas := function.AvailableReplicas
|
availableReplicas := function.AvailableReplicas
|
||||||
|
|
||||||
targetLoad := uint64(scaling.DefaultTargetLoad)
|
|
||||||
|
|
||||||
if function.Labels != nil {
|
if function.Labels != nil {
|
||||||
labels := *function.Labels
|
labels := *function.Labels
|
||||||
|
|
||||||
minReplicas = extractLabelValue(labels[scaling.MinScaleLabel], minReplicas)
|
minReplicas = extractLabelValue(labels[scaling.MinScaleLabel], minReplicas)
|
||||||
maxReplicas = extractLabelValue(labels[scaling.MaxScaleLabel], maxReplicas)
|
maxReplicas = extractLabelValue(labels[scaling.MaxScaleLabel], maxReplicas)
|
||||||
extractedScalingFactor := extractLabelValue(labels[scaling.ScalingFactorLabel], scalingFactor)
|
extractedScalingFactor := extractLabelValue(labels[scaling.ScalingFactorLabel], scalingFactor)
|
||||||
targetLoad = extractLabelValue(labels[scaling.TargetLoadLabel], targetLoad)
|
|
||||||
|
|
||||||
if extractedScalingFactor >= 0 && extractedScalingFactor <= 100 {
|
if extractedScalingFactor > 0 && extractedScalingFactor <= 100 {
|
||||||
scalingFactor = extractedScalingFactor
|
scalingFactor = extractedScalingFactor
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Bad Scaling Factor: %d, is not in range of [0 - 100]. Will fallback to %d", extractedScalingFactor, scalingFactor)
|
return scaling.ServiceQueryResponse{}, fmt.Errorf("bad scaling factor: %d, is not in range of [0 - 100]", extractedScalingFactor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +134,6 @@ func (s ExternalServiceQuery) GetReplicas(serviceName, serviceNamespace string)
|
|||||||
ScalingFactor: scalingFactor,
|
ScalingFactor: scalingFactor,
|
||||||
AvailableReplicas: availableReplicas,
|
AvailableReplicas: availableReplicas,
|
||||||
Annotations: function.Annotations,
|
Annotations: function.Annotations,
|
||||||
TargetLoad: targetLoad,
|
|
||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,6 @@ func TestGetReplicasExistentFn(t *testing.T) {
|
|||||||
MinReplicas: uint64(scaling.DefaultMinReplicas),
|
MinReplicas: uint64(scaling.DefaultMinReplicas),
|
||||||
ScalingFactor: uint64(scaling.DefaultScalingFactor),
|
ScalingFactor: uint64(scaling.DefaultScalingFactor),
|
||||||
AvailableReplicas: 0,
|
AvailableReplicas: 0,
|
||||||
TargetLoad: 10,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var injector middleware.AuthInjector
|
var injector middleware.AuthInjector
|
||||||
|
@ -1,58 +0,0 @@
|
|||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package probing
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ProbeCacher queries functions and caches the results
|
|
||||||
type ProbeCacher interface {
|
|
||||||
Set(functionName, namespace string, result *FunctionProbeResult)
|
|
||||||
Get(functionName, namespace string) (result *FunctionProbeResult, hit bool)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ProbeCache provides a cache of Probe replica counts
|
|
||||||
type ProbeCache struct {
|
|
||||||
Cache map[string]*FunctionProbeResult
|
|
||||||
Expiry time.Duration
|
|
||||||
Sync sync.RWMutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewProbeCache creates a function cache to query function metadata
|
|
||||||
func NewProbeCache(cacheExpiry time.Duration) ProbeCacher {
|
|
||||||
return &ProbeCache{
|
|
||||||
Cache: make(map[string]*FunctionProbeResult),
|
|
||||||
Expiry: cacheExpiry,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set replica count for functionName
|
|
||||||
func (fc *ProbeCache) Set(functionName, namespace string, result *FunctionProbeResult) {
|
|
||||||
fc.Sync.Lock()
|
|
||||||
defer fc.Sync.Unlock()
|
|
||||||
|
|
||||||
fc.Cache[functionName+"."+namespace] = result
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fc *ProbeCache) Get(functionName, namespace string) (*FunctionProbeResult, bool) {
|
|
||||||
|
|
||||||
result := &FunctionProbeResult{
|
|
||||||
Available: false,
|
|
||||||
Error: fmt.Errorf("unavailable in cache"),
|
|
||||||
}
|
|
||||||
|
|
||||||
hit := false
|
|
||||||
fc.Sync.RLock()
|
|
||||||
defer fc.Sync.RUnlock()
|
|
||||||
|
|
||||||
if val, exists := fc.Cache[functionName+"."+namespace]; exists {
|
|
||||||
hit = val.Expired(fc.Expiry) == false
|
|
||||||
result = val
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, hit
|
|
||||||
}
|
|
@ -1,116 +0,0 @@
|
|||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package probing
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/openfaas/faas/gateway/pkg/middleware"
|
|
||||||
"github.com/openfaas/faas/gateway/scaling"
|
|
||||||
"github.com/openfaas/faas/gateway/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
// NewFunctionProber create a new scaler with the specified
|
|
||||||
// ScalingConfig
|
|
||||||
func NewFunctionProber(functionQuery scaling.FunctionQuery, resolver middleware.BaseURLResolver) FunctionProber {
|
|
||||||
// if directFunctions {
|
|
||||||
return &FunctionHTTPProber{
|
|
||||||
Query: functionQuery,
|
|
||||||
Resolver: resolver,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// FunctionHTTPProber probes a function's health endpoint
|
|
||||||
type FunctionHTTPProber struct {
|
|
||||||
Query scaling.FunctionQuery
|
|
||||||
Resolver middleware.BaseURLResolver
|
|
||||||
DirectFunctions bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type FunctionNonProber struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FunctionNonProber) Probe(functionName, namespace string) FunctionProbeResult {
|
|
||||||
return FunctionProbeResult{
|
|
||||||
Found: true,
|
|
||||||
Available: true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type FunctionProber interface {
|
|
||||||
Probe(functionName, namespace string) FunctionProbeResult
|
|
||||||
}
|
|
||||||
|
|
||||||
// FunctionProbeResult holds the result of scaling from zero
|
|
||||||
type FunctionProbeResult struct {
|
|
||||||
Available bool
|
|
||||||
Error error
|
|
||||||
Found bool
|
|
||||||
Duration time.Duration
|
|
||||||
Updated time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
// Expired find out whether the cache item has expired with
|
|
||||||
// the given expiry duration from when it was stored.
|
|
||||||
func (res *FunctionProbeResult) Expired(expiry time.Duration) bool {
|
|
||||||
return time.Now().After(res.Updated.Add(expiry))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scale scales a function from zero replicas to 1 or the value set in
|
|
||||||
// the minimum replicas metadata
|
|
||||||
func (f *FunctionHTTPProber) Probe(functionName, namespace string) FunctionProbeResult {
|
|
||||||
start := time.Now()
|
|
||||||
|
|
||||||
cachedResponse, _ := f.Query.Get(functionName, namespace)
|
|
||||||
probePath := "/_/health"
|
|
||||||
|
|
||||||
if cachedResponse.Annotations != nil {
|
|
||||||
if v, ok := (*cachedResponse.Annotations)["com.openfaas.http.path"]; ok && len(v) > 0 {
|
|
||||||
probePath = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
maxCount := 10
|
|
||||||
pollInterval := time.Millisecond * 50
|
|
||||||
|
|
||||||
err := types.Retry(func(attempt int) error {
|
|
||||||
u := f.Resolver.BuildURL(functionName, namespace, probePath, true)
|
|
||||||
|
|
||||||
r, _ := http.NewRequest(http.MethodGet, u, nil)
|
|
||||||
r.Header.Set("User-Agent", "com.openfaas.gateway/probe")
|
|
||||||
|
|
||||||
resp, err := http.DefaultClient.Do(r)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Printf("[Probe] %s => %d", u, resp.StatusCode)
|
|
||||||
|
|
||||||
if resp.StatusCode == http.StatusOK {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf("failed with status: %s", resp.Status)
|
|
||||||
}, "Probe", maxCount, pollInterval)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return FunctionProbeResult{
|
|
||||||
Error: err,
|
|
||||||
Available: false,
|
|
||||||
Found: true,
|
|
||||||
Duration: time.Since(start),
|
|
||||||
Updated: time.Now(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return FunctionProbeResult{
|
|
||||||
Error: nil,
|
|
||||||
Available: true,
|
|
||||||
Found: true,
|
|
||||||
Duration: time.Since(start),
|
|
||||||
Updated: time.Now(),
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package requests
|
package requests
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package requests
|
package requests
|
||||||
|
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
// Package requests package provides a client SDK or library for
|
|
||||||
// the OpenFaaS gateway REST API
|
|
||||||
package requests
|
|
||||||
|
|
||||||
// DeleteFunctionRequest delete a deployed function
|
|
||||||
type DeleteFunctionRequest struct {
|
|
||||||
FunctionName string `json:"functionName"`
|
|
||||||
}
|
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package scaling
|
package scaling
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package scaling
|
package scaling
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package scaling
|
package scaling
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package scaling
|
package scaling
|
||||||
|
|
||||||
|
@ -1,17 +1,23 @@
|
|||||||
package scaling
|
package scaling
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/openfaas/faas-provider/types"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// DefaultMinReplicas is the minimal amount of replicas for a service.
|
// DefaultMinReplicas is the minimal amount of replicas for a service.
|
||||||
DefaultMinReplicas = 1
|
DefaultMinReplicas = 1
|
||||||
|
|
||||||
// DefaultMaxReplicas is the amount of replicas a service will auto-scale up to.
|
// DefaultMaxReplicas is the amount of replicas a service will auto-scale up to.
|
||||||
DefaultMaxReplicas = 20
|
DefaultMaxReplicas = 5
|
||||||
|
|
||||||
// DefaultScalingFactor is the defining proportion for the scaling increments.
|
// DefaultScalingFactor is the defining proportion for the scaling increments.
|
||||||
DefaultScalingFactor = 20
|
DefaultScalingFactor = 10
|
||||||
|
|
||||||
// DefaultTargetLoad
|
|
||||||
DefaultTargetLoad = 10
|
|
||||||
|
|
||||||
DefaultTypeScale = "rps"
|
DefaultTypeScale = "rps"
|
||||||
|
|
||||||
@ -23,10 +29,44 @@ const (
|
|||||||
|
|
||||||
// ScalingFactorLabel label indicates the scaling factor for a function
|
// ScalingFactorLabel label indicates the scaling factor for a function
|
||||||
ScalingFactorLabel = "com.openfaas.scale.factor"
|
ScalingFactorLabel = "com.openfaas.scale.factor"
|
||||||
|
|
||||||
// TargetLoadLabel see also DefaultTargetScale
|
|
||||||
TargetLoadLabel = "com.openfaas.scale.target"
|
|
||||||
|
|
||||||
// ScaleTypeLabel see also DefaultScaleType
|
|
||||||
ScaleTypeLabel = "com.openfaas.scale.type"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func MakeHorizontalScalingHandler(next http.HandlerFunc) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != http.MethodPost {
|
||||||
|
http.Error(w, "Only POST is allowed", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.Body == nil {
|
||||||
|
http.Error(w, "Error reading request body", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Error reading request body", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
scaleRequest := types.ScaleServiceRequest{}
|
||||||
|
if err := json.Unmarshal(body, &scaleRequest); err != nil {
|
||||||
|
http.Error(w, "Error unmarshalling request body", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if scaleRequest.Replicas < 1 {
|
||||||
|
scaleRequest.Replicas = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if scaleRequest.Replicas > DefaultMaxReplicas {
|
||||||
|
scaleRequest.Replicas = DefaultMaxReplicas
|
||||||
|
}
|
||||||
|
|
||||||
|
upstreamReq, _ := json.Marshal(scaleRequest)
|
||||||
|
// Restore the io.ReadCloser to its original state
|
||||||
|
r.Body = io.NopCloser(bytes.NewBuffer(upstreamReq))
|
||||||
|
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
// Copyright (c) OpenFaaS Author(s). All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package scaling
|
package scaling
|
||||||
|
|
||||||
@ -17,5 +19,4 @@ type ServiceQueryResponse struct {
|
|||||||
ScalingFactor uint64
|
ScalingFactor uint64
|
||||||
AvailableReplicas uint64
|
AvailableReplicas uint64
|
||||||
Annotations *map[string]string
|
Annotations *map[string]string
|
||||||
TargetLoad uint64
|
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,8 @@ type HandlerSet struct {
|
|||||||
// InfoHandler provides version and build info
|
// InfoHandler provides version and build info
|
||||||
InfoHandler http.HandlerFunc
|
InfoHandler http.HandlerFunc
|
||||||
|
|
||||||
|
TelemetryHandler http.HandlerFunc
|
||||||
|
|
||||||
// SecretHandler enables secrets to be managed
|
// SecretHandler enables secrets to be managed
|
||||||
SecretHandler http.HandlerFunc
|
SecretHandler http.HandlerFunc
|
||||||
|
|
||||||
@ -42,4 +44,6 @@ type HandlerSet struct {
|
|||||||
|
|
||||||
// NamespaceListerHandler lists namespaces
|
// NamespaceListerHandler lists namespaces
|
||||||
NamespaceListerHandler http.HandlerFunc
|
NamespaceListerHandler http.HandlerFunc
|
||||||
|
|
||||||
|
NamespaceMutatorHandler http.HandlerFunc
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved.
|
// Copyright (c) OpenFaaS Author(s) 2018. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/openfaas/faas/gateway/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewHTTPClientReverseProxy proxies to an upstream host through the use of a http.Client
|
// NewHTTPClientReverseProxy proxies to an upstream host through the use of a http.Client
|
||||||
@ -31,18 +36,20 @@ func NewHTTPClientReverseProxy(baseURL *url.URL, timeout time.Duration, maxIdleC
|
|||||||
// https://github.com/minio/minio/pull/5860
|
// https://github.com/minio/minio/pull/5860
|
||||||
|
|
||||||
// Taken from http.DefaultTransport in Go 1.11
|
// Taken from http.DefaultTransport in Go 1.11
|
||||||
h.Client.Transport = &http.Transport{
|
h.Client.Transport = &proxyTransport{
|
||||||
Proxy: http.ProxyFromEnvironment,
|
Transport: &http.Transport{
|
||||||
DialContext: (&net.Dialer{
|
Proxy: http.ProxyFromEnvironment,
|
||||||
Timeout: timeout,
|
DialContext: (&net.Dialer{
|
||||||
KeepAlive: timeout,
|
Timeout: timeout,
|
||||||
DualStack: true,
|
KeepAlive: timeout,
|
||||||
}).DialContext,
|
DualStack: true,
|
||||||
MaxIdleConns: maxIdleConns,
|
}).DialContext,
|
||||||
MaxIdleConnsPerHost: maxIdleConnsPerHost,
|
MaxIdleConns: maxIdleConns,
|
||||||
IdleConnTimeout: 90 * time.Second,
|
MaxIdleConnsPerHost: maxIdleConnsPerHost,
|
||||||
TLSHandshakeTimeout: 10 * time.Second,
|
IdleConnTimeout: 90 * time.Second,
|
||||||
ExpectContinueTimeout: 1 * time.Second,
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
|
ExpectContinueTimeout: 1 * time.Second,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return &h
|
return &h
|
||||||
@ -54,3 +61,19 @@ type HTTPClientReverseProxy struct {
|
|||||||
Client *http.Client
|
Client *http.Client
|
||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// proxyTransport is an http.RoundTripper for the reverse proxy client.
|
||||||
|
// It ensures default headers like the `User-Agent` are set on requests.
|
||||||
|
type proxyTransport struct {
|
||||||
|
// Transport is the underlying HTTP transport to use when making requests.
|
||||||
|
Transport http.RoundTripper
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoundTrip implements the RoundTripper interface.
|
||||||
|
func (t *proxyTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||||
|
if _, ok := req.Header["User-Agent"]; !ok {
|
||||||
|
req.Header.Set("User-Agent", fmt.Sprintf("openfaas-ce-gateway/%s", version.BuildVersion()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.Transport.RoundTrip(req)
|
||||||
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package types
|
package types
|
||||||
|
|
||||||
@ -8,7 +10,6 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -129,9 +130,6 @@ func (ReadConfig) Read(hasEnv HasEnv) (*GatewayConfig, error) {
|
|||||||
cfg.PrometheusHost = prometheusHost
|
cfg.PrometheusHost = prometheusHost
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.DirectFunctions = parseBoolValue(hasEnv.Getenv("direct_functions"))
|
|
||||||
cfg.DirectFunctionsSuffix = hasEnv.Getenv("direct_functions_suffix")
|
|
||||||
|
|
||||||
cfg.UseBasicAuth = parseBoolValue(hasEnv.Getenv("basic_auth"))
|
cfg.UseBasicAuth = parseBoolValue(hasEnv.Getenv("basic_auth"))
|
||||||
|
|
||||||
secretPath := hasEnv.Getenv("secret_mount_path")
|
secretPath := hasEnv.Getenv("secret_mount_path")
|
||||||
@ -169,14 +167,6 @@ func (ReadConfig) Read(hasEnv HasEnv) (*GatewayConfig, error) {
|
|||||||
|
|
||||||
cfg.Namespace = hasEnv.Getenv("function_namespace")
|
cfg.Namespace = hasEnv.Getenv("function_namespace")
|
||||||
|
|
||||||
if len(cfg.DirectFunctionsSuffix) > 0 && len(cfg.Namespace) > 0 {
|
|
||||||
if strings.HasPrefix(cfg.DirectFunctionsSuffix, cfg.Namespace) == false {
|
|
||||||
return nil, fmt.Errorf("function_namespace must be a sub-string of direct_functions_suffix")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.ProbeFunctions = parseBoolValue(hasEnv.Getenv("probe_functions"))
|
|
||||||
|
|
||||||
return &cfg, nil
|
return &cfg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,12 +206,6 @@ type GatewayConfig struct {
|
|||||||
// Port to connect to Prometheus.
|
// Port to connect to Prometheus.
|
||||||
PrometheusPort int
|
PrometheusPort int
|
||||||
|
|
||||||
// If set to true we will access upstream functions directly rather than through the upstream provider
|
|
||||||
DirectFunctions bool
|
|
||||||
|
|
||||||
// If set this will be used to resolve functions directly
|
|
||||||
DirectFunctionsSuffix string
|
|
||||||
|
|
||||||
// If set, reads secrets from file-system for enabling basic auth.
|
// If set, reads secrets from file-system for enabling basic auth.
|
||||||
UseBasicAuth bool
|
UseBasicAuth bool
|
||||||
|
|
||||||
@ -245,9 +229,6 @@ type GatewayConfig struct {
|
|||||||
|
|
||||||
// Namespace for endpoints
|
// Namespace for endpoints
|
||||||
Namespace string
|
Namespace string
|
||||||
|
|
||||||
// ProbeFunctions requires the gateway to probe the health endpoint of a function before invoking it
|
|
||||||
ProbeFunctions bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UseNATS Use NATSor not
|
// UseNATS Use NATSor not
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
// License: OpenFaaS Community Edition (CE) EULA
|
||||||
|
// Copyright (c) 2017,2019-2024 OpenFaaS Author(s)
|
||||||
|
|
||||||
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
||||||
|
|
||||||
package types
|
package types
|
||||||
|
|
||||||
@ -38,16 +40,6 @@ func TestRead_UseExternalProvider_Defaults(t *testing.T) {
|
|||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.DirectFunctions != false {
|
|
||||||
t.Log("Default for DirectFunctions should be false")
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(config.DirectFunctionsSuffix) > 0 {
|
|
||||||
t.Log("Default for DirectFunctionsSuffix should be empty")
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(config.Namespace) > 0 {
|
if len(config.Namespace) > 0 {
|
||||||
t.Log("Default for Namespace should be empty")
|
t.Log("Default for Namespace should be empty")
|
||||||
t.Fail()
|
t.Fail()
|
||||||
@ -89,86 +81,6 @@ func TestRead_NamespaceOverrideAgressWithFunctionSuffix_Valid(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRead_NamespaceOverrideAgressWithFunctionSuffix_Invalid(t *testing.T) {
|
|
||||||
|
|
||||||
defaults := NewEnvBucket()
|
|
||||||
readConfig := ReadConfig{}
|
|
||||||
|
|
||||||
defaults.Setenv("direct_functions", "true")
|
|
||||||
wantSuffix := "openfaas-fn.cluster.local.svc."
|
|
||||||
|
|
||||||
defaults.Setenv("direct_functions_suffix", wantSuffix)
|
|
||||||
defaults.Setenv("function_namespace", "fn")
|
|
||||||
|
|
||||||
_, err := readConfig.Read(defaults)
|
|
||||||
|
|
||||||
if err == nil {
|
|
||||||
t.Logf("Expected an error because function_namespace should be a sub-string of direct_functions_suffix")
|
|
||||||
t.Fail()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
want := "function_namespace must be a sub-string of direct_functions_suffix"
|
|
||||||
|
|
||||||
if want != err.Error() {
|
|
||||||
t.Logf("Error want: %s, got: %s", want, err.Error())
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRead_DirectFunctionsOverride(t *testing.T) {
|
|
||||||
defaults := NewEnvBucket()
|
|
||||||
readConfig := ReadConfig{}
|
|
||||||
defaults.Setenv("direct_functions", "true")
|
|
||||||
wantSuffix := "openfaas-fn.cluster.local.svc."
|
|
||||||
defaults.Setenv("direct_functions_suffix", wantSuffix)
|
|
||||||
|
|
||||||
config, _ := readConfig.Read(defaults)
|
|
||||||
|
|
||||||
if config.DirectFunctions != true {
|
|
||||||
t.Logf("DirectFunctions should be true, got: %v", config.DirectFunctions)
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.DirectFunctionsSuffix != wantSuffix {
|
|
||||||
t.Logf("DirectFunctionsSuffix want: %s, got: %s", wantSuffix, config.DirectFunctionsSuffix)
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRead_ProbeFunctions_Default(t *testing.T) {
|
|
||||||
defaults := NewEnvBucket()
|
|
||||||
readConfig := ReadConfig{}
|
|
||||||
defaults.Setenv("probe_functions", "")
|
|
||||||
|
|
||||||
want := false
|
|
||||||
|
|
||||||
config, _ := readConfig.Read(defaults)
|
|
||||||
|
|
||||||
got := config.ProbeFunctions
|
|
||||||
if want != got {
|
|
||||||
t.Logf("ProbeFunctions want %v, but got %v", want, got)
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRead_ProbeFunctions_Enabled(t *testing.T) {
|
|
||||||
defaults := NewEnvBucket()
|
|
||||||
readConfig := ReadConfig{}
|
|
||||||
defaults.Setenv("probe_functions", "true")
|
|
||||||
|
|
||||||
want := true
|
|
||||||
|
|
||||||
config, _ := readConfig.Read(defaults)
|
|
||||||
|
|
||||||
got := config.ProbeFunctions
|
|
||||||
if want != got {
|
|
||||||
t.Logf("ProbeFunctions want %v, but got %v", want, got)
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRead_ScaleZeroDefaultAndOverride(t *testing.T) {
|
func TestRead_ScaleZeroDefaultAndOverride(t *testing.T) {
|
||||||
defaults := NewEnvBucket()
|
defaults := NewEnvBucket()
|
||||||
readConfig := ReadConfig{}
|
readConfig := ReadConfig{}
|
||||||
@ -186,7 +98,7 @@ func TestRead_ScaleZeroDefaultAndOverride(t *testing.T) {
|
|||||||
want = true
|
want = true
|
||||||
|
|
||||||
if config.ScaleFromZero != want {
|
if config.ScaleFromZero != want {
|
||||||
t.Logf("ScaleFromZero was overriden - should be %v, got: %v", want, config.ScaleFromZero)
|
t.Logf("ScaleFromZero was overridden - should be %v, got: %v", want, config.ScaleFromZero)
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
33
gateway/vendor/github.com/cespare/xxhash/v2/README.md
generated
vendored
33
gateway/vendor/github.com/cespare/xxhash/v2/README.md
generated
vendored
@ -3,8 +3,7 @@
|
|||||||
[](https://pkg.go.dev/github.com/cespare/xxhash/v2)
|
[](https://pkg.go.dev/github.com/cespare/xxhash/v2)
|
||||||
[](https://github.com/cespare/xxhash/actions/workflows/test.yml)
|
[](https://github.com/cespare/xxhash/actions/workflows/test.yml)
|
||||||
|
|
||||||
xxhash is a Go implementation of the 64-bit
|
xxhash is a Go implementation of the 64-bit [xxHash] algorithm, XXH64. This is a
|
||||||
[xxHash](http://cyan4973.github.io/xxHash/) algorithm, XXH64. This is a
|
|
||||||
high-quality hashing algorithm that is much faster than anything in the Go
|
high-quality hashing algorithm that is much faster than anything in the Go
|
||||||
standard library.
|
standard library.
|
||||||
|
|
||||||
@ -25,8 +24,11 @@ func (*Digest) WriteString(string) (int, error)
|
|||||||
func (*Digest) Sum64() uint64
|
func (*Digest) Sum64() uint64
|
||||||
```
|
```
|
||||||
|
|
||||||
This implementation provides a fast pure-Go implementation and an even faster
|
The package is written with optimized pure Go and also contains even faster
|
||||||
assembly implementation for amd64.
|
assembly implementations for amd64 and arm64. If desired, the `purego` build tag
|
||||||
|
opts into using the Go code even on those architectures.
|
||||||
|
|
||||||
|
[xxHash]: http://cyan4973.github.io/xxHash/
|
||||||
|
|
||||||
## Compatibility
|
## Compatibility
|
||||||
|
|
||||||
@ -45,19 +47,20 @@ I recommend using the latest release of Go.
|
|||||||
Here are some quick benchmarks comparing the pure-Go and assembly
|
Here are some quick benchmarks comparing the pure-Go and assembly
|
||||||
implementations of Sum64.
|
implementations of Sum64.
|
||||||
|
|
||||||
| input size | purego | asm |
|
| input size | purego | asm |
|
||||||
| --- | --- | --- |
|
| ---------- | --------- | --------- |
|
||||||
| 5 B | 979.66 MB/s | 1291.17 MB/s |
|
| 4 B | 1.3 GB/s | 1.2 GB/s |
|
||||||
| 100 B | 7475.26 MB/s | 7973.40 MB/s |
|
| 16 B | 2.9 GB/s | 3.5 GB/s |
|
||||||
| 4 KB | 17573.46 MB/s | 17602.65 MB/s |
|
| 100 B | 6.9 GB/s | 8.1 GB/s |
|
||||||
| 10 MB | 17131.46 MB/s | 17142.16 MB/s |
|
| 4 KB | 11.7 GB/s | 16.7 GB/s |
|
||||||
|
| 10 MB | 12.0 GB/s | 17.3 GB/s |
|
||||||
|
|
||||||
These numbers were generated on Ubuntu 18.04 with an Intel i7-8700K CPU using
|
These numbers were generated on Ubuntu 20.04 with an Intel Xeon Platinum 8252C
|
||||||
the following commands under Go 1.11.2:
|
CPU using the following commands under Go 1.19.2:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ go test -tags purego -benchtime 10s -bench '/xxhash,direct,bytes'
|
benchstat <(go test -tags purego -benchtime 500ms -count 15 -bench 'Sum64$')
|
||||||
$ go test -benchtime 10s -bench '/xxhash,direct,bytes'
|
benchstat <(go test -benchtime 500ms -count 15 -bench 'Sum64$')
|
||||||
```
|
```
|
||||||
|
|
||||||
## Projects using this package
|
## Projects using this package
|
||||||
@ -67,3 +70,5 @@ $ go test -benchtime 10s -bench '/xxhash,direct,bytes'
|
|||||||
- [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics)
|
- [VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics)
|
||||||
- [FreeCache](https://github.com/coocood/freecache)
|
- [FreeCache](https://github.com/coocood/freecache)
|
||||||
- [FastCache](https://github.com/VictoriaMetrics/fastcache)
|
- [FastCache](https://github.com/VictoriaMetrics/fastcache)
|
||||||
|
- [Ristretto](https://github.com/dgraph-io/ristretto)
|
||||||
|
- [Badger](https://github.com/dgraph-io/badger)
|
||||||
|
10
gateway/vendor/github.com/cespare/xxhash/v2/testall.sh
generated
vendored
Normal file
10
gateway/vendor/github.com/cespare/xxhash/v2/testall.sh
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -eu -o pipefail
|
||||||
|
|
||||||
|
# Small convenience script for running the tests with various combinations of
|
||||||
|
# arch/tags. This assumes we're running on amd64 and have qemu available.
|
||||||
|
|
||||||
|
go test ./...
|
||||||
|
go test -tags purego ./...
|
||||||
|
GOARCH=arm64 go test
|
||||||
|
GOARCH=arm64 go test -tags purego
|
70
gateway/vendor/github.com/cespare/xxhash/v2/xxhash.go
generated
vendored
70
gateway/vendor/github.com/cespare/xxhash/v2/xxhash.go
generated
vendored
@ -16,21 +16,16 @@ const (
|
|||||||
prime5 uint64 = 2870177450012600261
|
prime5 uint64 = 2870177450012600261
|
||||||
)
|
)
|
||||||
|
|
||||||
// NOTE(caleb): I'm using both consts and vars of the primes. Using consts where
|
// Store the primes in an array as well.
|
||||||
// possible in the Go code is worth a small (but measurable) performance boost
|
//
|
||||||
// by avoiding some MOVQs. Vars are needed for the asm and also are useful for
|
// The consts are used when possible in Go code to avoid MOVs but we need a
|
||||||
// convenience in the Go code in a few places where we need to intentionally
|
// contiguous array for the assembly code.
|
||||||
// avoid constant arithmetic (e.g., v1 := prime1 + prime2 fails because the
|
var primes = [...]uint64{prime1, prime2, prime3, prime4, prime5}
|
||||||
// result overflows a uint64).
|
|
||||||
var (
|
|
||||||
prime1v = prime1
|
|
||||||
prime2v = prime2
|
|
||||||
prime3v = prime3
|
|
||||||
prime4v = prime4
|
|
||||||
prime5v = prime5
|
|
||||||
)
|
|
||||||
|
|
||||||
// Digest implements hash.Hash64.
|
// Digest implements hash.Hash64.
|
||||||
|
//
|
||||||
|
// Note that a zero-valued Digest is not ready to receive writes.
|
||||||
|
// Call Reset or create a Digest using New before calling other methods.
|
||||||
type Digest struct {
|
type Digest struct {
|
||||||
v1 uint64
|
v1 uint64
|
||||||
v2 uint64
|
v2 uint64
|
||||||
@ -41,19 +36,31 @@ type Digest struct {
|
|||||||
n int // how much of mem is used
|
n int // how much of mem is used
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new Digest that computes the 64-bit xxHash algorithm.
|
// New creates a new Digest with a zero seed.
|
||||||
func New() *Digest {
|
func New() *Digest {
|
||||||
|
return NewWithSeed(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewWithSeed creates a new Digest with the given seed.
|
||||||
|
func NewWithSeed(seed uint64) *Digest {
|
||||||
var d Digest
|
var d Digest
|
||||||
d.Reset()
|
d.ResetWithSeed(seed)
|
||||||
return &d
|
return &d
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset clears the Digest's state so that it can be reused.
|
// Reset clears the Digest's state so that it can be reused.
|
||||||
|
// It uses a seed value of zero.
|
||||||
func (d *Digest) Reset() {
|
func (d *Digest) Reset() {
|
||||||
d.v1 = prime1v + prime2
|
d.ResetWithSeed(0)
|
||||||
d.v2 = prime2
|
}
|
||||||
d.v3 = 0
|
|
||||||
d.v4 = -prime1v
|
// ResetWithSeed clears the Digest's state so that it can be reused.
|
||||||
|
// It uses the given seed to initialize the state.
|
||||||
|
func (d *Digest) ResetWithSeed(seed uint64) {
|
||||||
|
d.v1 = seed + prime1 + prime2
|
||||||
|
d.v2 = seed + prime2
|
||||||
|
d.v3 = seed
|
||||||
|
d.v4 = seed - prime1
|
||||||
d.total = 0
|
d.total = 0
|
||||||
d.n = 0
|
d.n = 0
|
||||||
}
|
}
|
||||||
@ -69,21 +76,23 @@ func (d *Digest) Write(b []byte) (n int, err error) {
|
|||||||
n = len(b)
|
n = len(b)
|
||||||
d.total += uint64(n)
|
d.total += uint64(n)
|
||||||
|
|
||||||
|
memleft := d.mem[d.n&(len(d.mem)-1):]
|
||||||
|
|
||||||
if d.n+n < 32 {
|
if d.n+n < 32 {
|
||||||
// This new data doesn't even fill the current block.
|
// This new data doesn't even fill the current block.
|
||||||
copy(d.mem[d.n:], b)
|
copy(memleft, b)
|
||||||
d.n += n
|
d.n += n
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if d.n > 0 {
|
if d.n > 0 {
|
||||||
// Finish off the partial block.
|
// Finish off the partial block.
|
||||||
copy(d.mem[d.n:], b)
|
c := copy(memleft, b)
|
||||||
d.v1 = round(d.v1, u64(d.mem[0:8]))
|
d.v1 = round(d.v1, u64(d.mem[0:8]))
|
||||||
d.v2 = round(d.v2, u64(d.mem[8:16]))
|
d.v2 = round(d.v2, u64(d.mem[8:16]))
|
||||||
d.v3 = round(d.v3, u64(d.mem[16:24]))
|
d.v3 = round(d.v3, u64(d.mem[16:24]))
|
||||||
d.v4 = round(d.v4, u64(d.mem[24:32]))
|
d.v4 = round(d.v4, u64(d.mem[24:32]))
|
||||||
b = b[32-d.n:]
|
b = b[c:]
|
||||||
d.n = 0
|
d.n = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,21 +142,20 @@ func (d *Digest) Sum64() uint64 {
|
|||||||
|
|
||||||
h += d.total
|
h += d.total
|
||||||
|
|
||||||
i, end := 0, d.n
|
b := d.mem[:d.n&(len(d.mem)-1)]
|
||||||
for ; i+8 <= end; i += 8 {
|
for ; len(b) >= 8; b = b[8:] {
|
||||||
k1 := round(0, u64(d.mem[i:i+8]))
|
k1 := round(0, u64(b[:8]))
|
||||||
h ^= k1
|
h ^= k1
|
||||||
h = rol27(h)*prime1 + prime4
|
h = rol27(h)*prime1 + prime4
|
||||||
}
|
}
|
||||||
if i+4 <= end {
|
if len(b) >= 4 {
|
||||||
h ^= uint64(u32(d.mem[i:i+4])) * prime1
|
h ^= uint64(u32(b[:4])) * prime1
|
||||||
h = rol23(h)*prime2 + prime3
|
h = rol23(h)*prime2 + prime3
|
||||||
i += 4
|
b = b[4:]
|
||||||
}
|
}
|
||||||
for i < end {
|
for ; len(b) > 0; b = b[1:] {
|
||||||
h ^= uint64(d.mem[i]) * prime5
|
h ^= uint64(b[0]) * prime5
|
||||||
h = rol11(h) * prime1
|
h = rol11(h) * prime1
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h ^= h >> 33
|
h ^= h >> 33
|
||||||
|
308
gateway/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s
generated
vendored
308
gateway/vendor/github.com/cespare/xxhash/v2/xxhash_amd64.s
generated
vendored
@ -1,215 +1,209 @@
|
|||||||
|
//go:build !appengine && gc && !purego
|
||||||
// +build !appengine
|
// +build !appengine
|
||||||
// +build gc
|
// +build gc
|
||||||
// +build !purego
|
// +build !purego
|
||||||
|
|
||||||
#include "textflag.h"
|
#include "textflag.h"
|
||||||
|
|
||||||
// Register allocation:
|
// Registers:
|
||||||
// AX h
|
#define h AX
|
||||||
// SI pointer to advance through b
|
#define d AX
|
||||||
// DX n
|
#define p SI // pointer to advance through b
|
||||||
// BX loop end
|
#define n DX
|
||||||
// R8 v1, k1
|
#define end BX // loop end
|
||||||
// R9 v2
|
#define v1 R8
|
||||||
// R10 v3
|
#define v2 R9
|
||||||
// R11 v4
|
#define v3 R10
|
||||||
// R12 tmp
|
#define v4 R11
|
||||||
// R13 prime1v
|
#define x R12
|
||||||
// R14 prime2v
|
#define prime1 R13
|
||||||
// DI prime4v
|
#define prime2 R14
|
||||||
|
#define prime4 DI
|
||||||
|
|
||||||
// round reads from and advances the buffer pointer in SI.
|
#define round(acc, x) \
|
||||||
// It assumes that R13 has prime1v and R14 has prime2v.
|
IMULQ prime2, x \
|
||||||
#define round(r) \
|
ADDQ x, acc \
|
||||||
MOVQ (SI), R12 \
|
ROLQ $31, acc \
|
||||||
ADDQ $8, SI \
|
IMULQ prime1, acc
|
||||||
IMULQ R14, R12 \
|
|
||||||
ADDQ R12, r \
|
|
||||||
ROLQ $31, r \
|
|
||||||
IMULQ R13, r
|
|
||||||
|
|
||||||
// mergeRound applies a merge round on the two registers acc and val.
|
// round0 performs the operation x = round(0, x).
|
||||||
// It assumes that R13 has prime1v, R14 has prime2v, and DI has prime4v.
|
#define round0(x) \
|
||||||
#define mergeRound(acc, val) \
|
IMULQ prime2, x \
|
||||||
IMULQ R14, val \
|
ROLQ $31, x \
|
||||||
ROLQ $31, val \
|
IMULQ prime1, x
|
||||||
IMULQ R13, val \
|
|
||||||
XORQ val, acc \
|
// mergeRound applies a merge round on the two registers acc and x.
|
||||||
IMULQ R13, acc \
|
// It assumes that prime1, prime2, and prime4 have been loaded.
|
||||||
ADDQ DI, acc
|
#define mergeRound(acc, x) \
|
||||||
|
round0(x) \
|
||||||
|
XORQ x, acc \
|
||||||
|
IMULQ prime1, acc \
|
||||||
|
ADDQ prime4, acc
|
||||||
|
|
||||||
|
// blockLoop processes as many 32-byte blocks as possible,
|
||||||
|
// updating v1, v2, v3, and v4. It assumes that there is at least one block
|
||||||
|
// to process.
|
||||||
|
#define blockLoop() \
|
||||||
|
loop: \
|
||||||
|
MOVQ +0(p), x \
|
||||||
|
round(v1, x) \
|
||||||
|
MOVQ +8(p), x \
|
||||||
|
round(v2, x) \
|
||||||
|
MOVQ +16(p), x \
|
||||||
|
round(v3, x) \
|
||||||
|
MOVQ +24(p), x \
|
||||||
|
round(v4, x) \
|
||||||
|
ADDQ $32, p \
|
||||||
|
CMPQ p, end \
|
||||||
|
JLE loop
|
||||||
|
|
||||||
// func Sum64(b []byte) uint64
|
// func Sum64(b []byte) uint64
|
||||||
TEXT ·Sum64(SB), NOSPLIT, $0-32
|
TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32
|
||||||
// Load fixed primes.
|
// Load fixed primes.
|
||||||
MOVQ ·prime1v(SB), R13
|
MOVQ ·primes+0(SB), prime1
|
||||||
MOVQ ·prime2v(SB), R14
|
MOVQ ·primes+8(SB), prime2
|
||||||
MOVQ ·prime4v(SB), DI
|
MOVQ ·primes+24(SB), prime4
|
||||||
|
|
||||||
// Load slice.
|
// Load slice.
|
||||||
MOVQ b_base+0(FP), SI
|
MOVQ b_base+0(FP), p
|
||||||
MOVQ b_len+8(FP), DX
|
MOVQ b_len+8(FP), n
|
||||||
LEAQ (SI)(DX*1), BX
|
LEAQ (p)(n*1), end
|
||||||
|
|
||||||
// The first loop limit will be len(b)-32.
|
// The first loop limit will be len(b)-32.
|
||||||
SUBQ $32, BX
|
SUBQ $32, end
|
||||||
|
|
||||||
// Check whether we have at least one block.
|
// Check whether we have at least one block.
|
||||||
CMPQ DX, $32
|
CMPQ n, $32
|
||||||
JLT noBlocks
|
JLT noBlocks
|
||||||
|
|
||||||
// Set up initial state (v1, v2, v3, v4).
|
// Set up initial state (v1, v2, v3, v4).
|
||||||
MOVQ R13, R8
|
MOVQ prime1, v1
|
||||||
ADDQ R14, R8
|
ADDQ prime2, v1
|
||||||
MOVQ R14, R9
|
MOVQ prime2, v2
|
||||||
XORQ R10, R10
|
XORQ v3, v3
|
||||||
XORQ R11, R11
|
XORQ v4, v4
|
||||||
SUBQ R13, R11
|
SUBQ prime1, v4
|
||||||
|
|
||||||
// Loop until SI > BX.
|
blockLoop()
|
||||||
blockLoop:
|
|
||||||
round(R8)
|
|
||||||
round(R9)
|
|
||||||
round(R10)
|
|
||||||
round(R11)
|
|
||||||
|
|
||||||
CMPQ SI, BX
|
MOVQ v1, h
|
||||||
JLE blockLoop
|
ROLQ $1, h
|
||||||
|
MOVQ v2, x
|
||||||
|
ROLQ $7, x
|
||||||
|
ADDQ x, h
|
||||||
|
MOVQ v3, x
|
||||||
|
ROLQ $12, x
|
||||||
|
ADDQ x, h
|
||||||
|
MOVQ v4, x
|
||||||
|
ROLQ $18, x
|
||||||
|
ADDQ x, h
|
||||||
|
|
||||||
MOVQ R8, AX
|
mergeRound(h, v1)
|
||||||
ROLQ $1, AX
|
mergeRound(h, v2)
|
||||||
MOVQ R9, R12
|
mergeRound(h, v3)
|
||||||
ROLQ $7, R12
|
mergeRound(h, v4)
|
||||||
ADDQ R12, AX
|
|
||||||
MOVQ R10, R12
|
|
||||||
ROLQ $12, R12
|
|
||||||
ADDQ R12, AX
|
|
||||||
MOVQ R11, R12
|
|
||||||
ROLQ $18, R12
|
|
||||||
ADDQ R12, AX
|
|
||||||
|
|
||||||
mergeRound(AX, R8)
|
|
||||||
mergeRound(AX, R9)
|
|
||||||
mergeRound(AX, R10)
|
|
||||||
mergeRound(AX, R11)
|
|
||||||
|
|
||||||
JMP afterBlocks
|
JMP afterBlocks
|
||||||
|
|
||||||
noBlocks:
|
noBlocks:
|
||||||
MOVQ ·prime5v(SB), AX
|
MOVQ ·primes+32(SB), h
|
||||||
|
|
||||||
afterBlocks:
|
afterBlocks:
|
||||||
ADDQ DX, AX
|
ADDQ n, h
|
||||||
|
|
||||||
// Right now BX has len(b)-32, and we want to loop until SI > len(b)-8.
|
ADDQ $24, end
|
||||||
ADDQ $24, BX
|
CMPQ p, end
|
||||||
|
JG try4
|
||||||
|
|
||||||
CMPQ SI, BX
|
loop8:
|
||||||
JG fourByte
|
MOVQ (p), x
|
||||||
|
ADDQ $8, p
|
||||||
|
round0(x)
|
||||||
|
XORQ x, h
|
||||||
|
ROLQ $27, h
|
||||||
|
IMULQ prime1, h
|
||||||
|
ADDQ prime4, h
|
||||||
|
|
||||||
wordLoop:
|
CMPQ p, end
|
||||||
// Calculate k1.
|
JLE loop8
|
||||||
MOVQ (SI), R8
|
|
||||||
ADDQ $8, SI
|
|
||||||
IMULQ R14, R8
|
|
||||||
ROLQ $31, R8
|
|
||||||
IMULQ R13, R8
|
|
||||||
|
|
||||||
XORQ R8, AX
|
try4:
|
||||||
ROLQ $27, AX
|
ADDQ $4, end
|
||||||
IMULQ R13, AX
|
CMPQ p, end
|
||||||
ADDQ DI, AX
|
JG try1
|
||||||
|
|
||||||
CMPQ SI, BX
|
MOVL (p), x
|
||||||
JLE wordLoop
|
ADDQ $4, p
|
||||||
|
IMULQ prime1, x
|
||||||
|
XORQ x, h
|
||||||
|
|
||||||
fourByte:
|
ROLQ $23, h
|
||||||
ADDQ $4, BX
|
IMULQ prime2, h
|
||||||
CMPQ SI, BX
|
ADDQ ·primes+16(SB), h
|
||||||
JG singles
|
|
||||||
|
|
||||||
MOVL (SI), R8
|
try1:
|
||||||
ADDQ $4, SI
|
ADDQ $4, end
|
||||||
IMULQ R13, R8
|
CMPQ p, end
|
||||||
XORQ R8, AX
|
|
||||||
|
|
||||||
ROLQ $23, AX
|
|
||||||
IMULQ R14, AX
|
|
||||||
ADDQ ·prime3v(SB), AX
|
|
||||||
|
|
||||||
singles:
|
|
||||||
ADDQ $4, BX
|
|
||||||
CMPQ SI, BX
|
|
||||||
JGE finalize
|
JGE finalize
|
||||||
|
|
||||||
singlesLoop:
|
loop1:
|
||||||
MOVBQZX (SI), R12
|
MOVBQZX (p), x
|
||||||
ADDQ $1, SI
|
ADDQ $1, p
|
||||||
IMULQ ·prime5v(SB), R12
|
IMULQ ·primes+32(SB), x
|
||||||
XORQ R12, AX
|
XORQ x, h
|
||||||
|
ROLQ $11, h
|
||||||
|
IMULQ prime1, h
|
||||||
|
|
||||||
ROLQ $11, AX
|
CMPQ p, end
|
||||||
IMULQ R13, AX
|
JL loop1
|
||||||
|
|
||||||
CMPQ SI, BX
|
|
||||||
JL singlesLoop
|
|
||||||
|
|
||||||
finalize:
|
finalize:
|
||||||
MOVQ AX, R12
|
MOVQ h, x
|
||||||
SHRQ $33, R12
|
SHRQ $33, x
|
||||||
XORQ R12, AX
|
XORQ x, h
|
||||||
IMULQ R14, AX
|
IMULQ prime2, h
|
||||||
MOVQ AX, R12
|
MOVQ h, x
|
||||||
SHRQ $29, R12
|
SHRQ $29, x
|
||||||
XORQ R12, AX
|
XORQ x, h
|
||||||
IMULQ ·prime3v(SB), AX
|
IMULQ ·primes+16(SB), h
|
||||||
MOVQ AX, R12
|
MOVQ h, x
|
||||||
SHRQ $32, R12
|
SHRQ $32, x
|
||||||
XORQ R12, AX
|
XORQ x, h
|
||||||
|
|
||||||
MOVQ AX, ret+24(FP)
|
MOVQ h, ret+24(FP)
|
||||||
RET
|
RET
|
||||||
|
|
||||||
// writeBlocks uses the same registers as above except that it uses AX to store
|
|
||||||
// the d pointer.
|
|
||||||
|
|
||||||
// func writeBlocks(d *Digest, b []byte) int
|
// func writeBlocks(d *Digest, b []byte) int
|
||||||
TEXT ·writeBlocks(SB), NOSPLIT, $0-40
|
TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40
|
||||||
// Load fixed primes needed for round.
|
// Load fixed primes needed for round.
|
||||||
MOVQ ·prime1v(SB), R13
|
MOVQ ·primes+0(SB), prime1
|
||||||
MOVQ ·prime2v(SB), R14
|
MOVQ ·primes+8(SB), prime2
|
||||||
|
|
||||||
// Load slice.
|
// Load slice.
|
||||||
MOVQ b_base+8(FP), SI
|
MOVQ b_base+8(FP), p
|
||||||
MOVQ b_len+16(FP), DX
|
MOVQ b_len+16(FP), n
|
||||||
LEAQ (SI)(DX*1), BX
|
LEAQ (p)(n*1), end
|
||||||
SUBQ $32, BX
|
SUBQ $32, end
|
||||||
|
|
||||||
// Load vN from d.
|
// Load vN from d.
|
||||||
MOVQ d+0(FP), AX
|
MOVQ s+0(FP), d
|
||||||
MOVQ 0(AX), R8 // v1
|
MOVQ 0(d), v1
|
||||||
MOVQ 8(AX), R9 // v2
|
MOVQ 8(d), v2
|
||||||
MOVQ 16(AX), R10 // v3
|
MOVQ 16(d), v3
|
||||||
MOVQ 24(AX), R11 // v4
|
MOVQ 24(d), v4
|
||||||
|
|
||||||
// We don't need to check the loop condition here; this function is
|
// We don't need to check the loop condition here; this function is
|
||||||
// always called with at least one block of data to process.
|
// always called with at least one block of data to process.
|
||||||
blockLoop:
|
blockLoop()
|
||||||
round(R8)
|
|
||||||
round(R9)
|
|
||||||
round(R10)
|
|
||||||
round(R11)
|
|
||||||
|
|
||||||
CMPQ SI, BX
|
|
||||||
JLE blockLoop
|
|
||||||
|
|
||||||
// Copy vN back to d.
|
// Copy vN back to d.
|
||||||
MOVQ R8, 0(AX)
|
MOVQ v1, 0(d)
|
||||||
MOVQ R9, 8(AX)
|
MOVQ v2, 8(d)
|
||||||
MOVQ R10, 16(AX)
|
MOVQ v3, 16(d)
|
||||||
MOVQ R11, 24(AX)
|
MOVQ v4, 24(d)
|
||||||
|
|
||||||
// The number of bytes written is SI minus the old base pointer.
|
// The number of bytes written is p minus the old base pointer.
|
||||||
SUBQ b_base+8(FP), SI
|
SUBQ b_base+8(FP), p
|
||||||
MOVQ SI, ret+32(FP)
|
MOVQ p, ret+32(FP)
|
||||||
|
|
||||||
RET
|
RET
|
||||||
|
183
gateway/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s
generated
vendored
Normal file
183
gateway/vendor/github.com/cespare/xxhash/v2/xxhash_arm64.s
generated
vendored
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
//go:build !appengine && gc && !purego
|
||||||
|
// +build !appengine
|
||||||
|
// +build gc
|
||||||
|
// +build !purego
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
// Registers:
|
||||||
|
#define digest R1
|
||||||
|
#define h R2 // return value
|
||||||
|
#define p R3 // input pointer
|
||||||
|
#define n R4 // input length
|
||||||
|
#define nblocks R5 // n / 32
|
||||||
|
#define prime1 R7
|
||||||
|
#define prime2 R8
|
||||||
|
#define prime3 R9
|
||||||
|
#define prime4 R10
|
||||||
|
#define prime5 R11
|
||||||
|
#define v1 R12
|
||||||
|
#define v2 R13
|
||||||
|
#define v3 R14
|
||||||
|
#define v4 R15
|
||||||
|
#define x1 R20
|
||||||
|
#define x2 R21
|
||||||
|
#define x3 R22
|
||||||
|
#define x4 R23
|
||||||
|
|
||||||
|
#define round(acc, x) \
|
||||||
|
MADD prime2, acc, x, acc \
|
||||||
|
ROR $64-31, acc \
|
||||||
|
MUL prime1, acc
|
||||||
|
|
||||||
|
// round0 performs the operation x = round(0, x).
|
||||||
|
#define round0(x) \
|
||||||
|
MUL prime2, x \
|
||||||
|
ROR $64-31, x \
|
||||||
|
MUL prime1, x
|
||||||
|
|
||||||
|
#define mergeRound(acc, x) \
|
||||||
|
round0(x) \
|
||||||
|
EOR x, acc \
|
||||||
|
MADD acc, prime4, prime1, acc
|
||||||
|
|
||||||
|
// blockLoop processes as many 32-byte blocks as possible,
|
||||||
|
// updating v1, v2, v3, and v4. It assumes that n >= 32.
|
||||||
|
#define blockLoop() \
|
||||||
|
LSR $5, n, nblocks \
|
||||||
|
PCALIGN $16 \
|
||||||
|
loop: \
|
||||||
|
LDP.P 16(p), (x1, x2) \
|
||||||
|
LDP.P 16(p), (x3, x4) \
|
||||||
|
round(v1, x1) \
|
||||||
|
round(v2, x2) \
|
||||||
|
round(v3, x3) \
|
||||||
|
round(v4, x4) \
|
||||||
|
SUB $1, nblocks \
|
||||||
|
CBNZ nblocks, loop
|
||||||
|
|
||||||
|
// func Sum64(b []byte) uint64
|
||||||
|
TEXT ·Sum64(SB), NOSPLIT|NOFRAME, $0-32
|
||||||
|
LDP b_base+0(FP), (p, n)
|
||||||
|
|
||||||
|
LDP ·primes+0(SB), (prime1, prime2)
|
||||||
|
LDP ·primes+16(SB), (prime3, prime4)
|
||||||
|
MOVD ·primes+32(SB), prime5
|
||||||
|
|
||||||
|
CMP $32, n
|
||||||
|
CSEL LT, prime5, ZR, h // if n < 32 { h = prime5 } else { h = 0 }
|
||||||
|
BLT afterLoop
|
||||||
|
|
||||||
|
ADD prime1, prime2, v1
|
||||||
|
MOVD prime2, v2
|
||||||
|
MOVD $0, v3
|
||||||
|
NEG prime1, v4
|
||||||
|
|
||||||
|
blockLoop()
|
||||||
|
|
||||||
|
ROR $64-1, v1, x1
|
||||||
|
ROR $64-7, v2, x2
|
||||||
|
ADD x1, x2
|
||||||
|
ROR $64-12, v3, x3
|
||||||
|
ROR $64-18, v4, x4
|
||||||
|
ADD x3, x4
|
||||||
|
ADD x2, x4, h
|
||||||
|
|
||||||
|
mergeRound(h, v1)
|
||||||
|
mergeRound(h, v2)
|
||||||
|
mergeRound(h, v3)
|
||||||
|
mergeRound(h, v4)
|
||||||
|
|
||||||
|
afterLoop:
|
||||||
|
ADD n, h
|
||||||
|
|
||||||
|
TBZ $4, n, try8
|
||||||
|
LDP.P 16(p), (x1, x2)
|
||||||
|
|
||||||
|
round0(x1)
|
||||||
|
|
||||||
|
// NOTE: here and below, sequencing the EOR after the ROR (using a
|
||||||
|
// rotated register) is worth a small but measurable speedup for small
|
||||||
|
// inputs.
|
||||||
|
ROR $64-27, h
|
||||||
|
EOR x1 @> 64-27, h, h
|
||||||
|
MADD h, prime4, prime1, h
|
||||||
|
|
||||||
|
round0(x2)
|
||||||
|
ROR $64-27, h
|
||||||
|
EOR x2 @> 64-27, h, h
|
||||||
|
MADD h, prime4, prime1, h
|
||||||
|
|
||||||
|
try8:
|
||||||
|
TBZ $3, n, try4
|
||||||
|
MOVD.P 8(p), x1
|
||||||
|
|
||||||
|
round0(x1)
|
||||||
|
ROR $64-27, h
|
||||||
|
EOR x1 @> 64-27, h, h
|
||||||
|
MADD h, prime4, prime1, h
|
||||||
|
|
||||||
|
try4:
|
||||||
|
TBZ $2, n, try2
|
||||||
|
MOVWU.P 4(p), x2
|
||||||
|
|
||||||
|
MUL prime1, x2
|
||||||
|
ROR $64-23, h
|
||||||
|
EOR x2 @> 64-23, h, h
|
||||||
|
MADD h, prime3, prime2, h
|
||||||
|
|
||||||
|
try2:
|
||||||
|
TBZ $1, n, try1
|
||||||
|
MOVHU.P 2(p), x3
|
||||||
|
AND $255, x3, x1
|
||||||
|
LSR $8, x3, x2
|
||||||
|
|
||||||
|
MUL prime5, x1
|
||||||
|
ROR $64-11, h
|
||||||
|
EOR x1 @> 64-11, h, h
|
||||||
|
MUL prime1, h
|
||||||
|
|
||||||
|
MUL prime5, x2
|
||||||
|
ROR $64-11, h
|
||||||
|
EOR x2 @> 64-11, h, h
|
||||||
|
MUL prime1, h
|
||||||
|
|
||||||
|
try1:
|
||||||
|
TBZ $0, n, finalize
|
||||||
|
MOVBU (p), x4
|
||||||
|
|
||||||
|
MUL prime5, x4
|
||||||
|
ROR $64-11, h
|
||||||
|
EOR x4 @> 64-11, h, h
|
||||||
|
MUL prime1, h
|
||||||
|
|
||||||
|
finalize:
|
||||||
|
EOR h >> 33, h
|
||||||
|
MUL prime2, h
|
||||||
|
EOR h >> 29, h
|
||||||
|
MUL prime3, h
|
||||||
|
EOR h >> 32, h
|
||||||
|
|
||||||
|
MOVD h, ret+24(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
// func writeBlocks(d *Digest, b []byte) int
|
||||||
|
TEXT ·writeBlocks(SB), NOSPLIT|NOFRAME, $0-40
|
||||||
|
LDP ·primes+0(SB), (prime1, prime2)
|
||||||
|
|
||||||
|
// Load state. Assume v[1-4] are stored contiguously.
|
||||||
|
MOVD d+0(FP), digest
|
||||||
|
LDP 0(digest), (v1, v2)
|
||||||
|
LDP 16(digest), (v3, v4)
|
||||||
|
|
||||||
|
LDP b_base+8(FP), (p, n)
|
||||||
|
|
||||||
|
blockLoop()
|
||||||
|
|
||||||
|
// Store updated state.
|
||||||
|
STP (v1, v2), 0(digest)
|
||||||
|
STP (v3, v4), 16(digest)
|
||||||
|
|
||||||
|
BIC $31, n
|
||||||
|
MOVD n, ret+32(FP)
|
||||||
|
RET
|
15
gateway/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go
generated
vendored
Normal file
15
gateway/vendor/github.com/cespare/xxhash/v2/xxhash_asm.go
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//go:build (amd64 || arm64) && !appengine && gc && !purego
|
||||||
|
// +build amd64 arm64
|
||||||
|
// +build !appengine
|
||||||
|
// +build gc
|
||||||
|
// +build !purego
|
||||||
|
|
||||||
|
package xxhash
|
||||||
|
|
||||||
|
// Sum64 computes the 64-bit xxHash digest of b with a zero seed.
|
||||||
|
//
|
||||||
|
//go:noescape
|
||||||
|
func Sum64(b []byte) uint64
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func writeBlocks(d *Digest, b []byte) int
|
24
gateway/vendor/github.com/cespare/xxhash/v2/xxhash_other.go
generated
vendored
24
gateway/vendor/github.com/cespare/xxhash/v2/xxhash_other.go
generated
vendored
@ -1,8 +1,9 @@
|
|||||||
// +build !amd64 appengine !gc purego
|
//go:build (!amd64 && !arm64) || appengine || !gc || purego
|
||||||
|
// +build !amd64,!arm64 appengine !gc purego
|
||||||
|
|
||||||
package xxhash
|
package xxhash
|
||||||
|
|
||||||
// Sum64 computes the 64-bit xxHash digest of b.
|
// Sum64 computes the 64-bit xxHash digest of b with a zero seed.
|
||||||
func Sum64(b []byte) uint64 {
|
func Sum64(b []byte) uint64 {
|
||||||
// A simpler version would be
|
// A simpler version would be
|
||||||
// d := New()
|
// d := New()
|
||||||
@ -14,10 +15,10 @@ func Sum64(b []byte) uint64 {
|
|||||||
var h uint64
|
var h uint64
|
||||||
|
|
||||||
if n >= 32 {
|
if n >= 32 {
|
||||||
v1 := prime1v + prime2
|
v1 := primes[0] + prime2
|
||||||
v2 := prime2
|
v2 := prime2
|
||||||
v3 := uint64(0)
|
v3 := uint64(0)
|
||||||
v4 := -prime1v
|
v4 := -primes[0]
|
||||||
for len(b) >= 32 {
|
for len(b) >= 32 {
|
||||||
v1 = round(v1, u64(b[0:8:len(b)]))
|
v1 = round(v1, u64(b[0:8:len(b)]))
|
||||||
v2 = round(v2, u64(b[8:16:len(b)]))
|
v2 = round(v2, u64(b[8:16:len(b)]))
|
||||||
@ -36,19 +37,18 @@ func Sum64(b []byte) uint64 {
|
|||||||
|
|
||||||
h += uint64(n)
|
h += uint64(n)
|
||||||
|
|
||||||
i, end := 0, len(b)
|
for ; len(b) >= 8; b = b[8:] {
|
||||||
for ; i+8 <= end; i += 8 {
|
k1 := round(0, u64(b[:8]))
|
||||||
k1 := round(0, u64(b[i:i+8:len(b)]))
|
|
||||||
h ^= k1
|
h ^= k1
|
||||||
h = rol27(h)*prime1 + prime4
|
h = rol27(h)*prime1 + prime4
|
||||||
}
|
}
|
||||||
if i+4 <= end {
|
if len(b) >= 4 {
|
||||||
h ^= uint64(u32(b[i:i+4:len(b)])) * prime1
|
h ^= uint64(u32(b[:4])) * prime1
|
||||||
h = rol23(h)*prime2 + prime3
|
h = rol23(h)*prime2 + prime3
|
||||||
i += 4
|
b = b[4:]
|
||||||
}
|
}
|
||||||
for ; i < end; i++ {
|
for ; len(b) > 0; b = b[1:] {
|
||||||
h ^= uint64(b[i]) * prime5
|
h ^= uint64(b[0]) * prime5
|
||||||
h = rol11(h) * prime1
|
h = rol11(h) * prime1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
gateway/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go
generated
vendored
3
gateway/vendor/github.com/cespare/xxhash/v2/xxhash_safe.go
generated
vendored
@ -1,10 +1,11 @@
|
|||||||
|
//go:build appengine
|
||||||
// +build appengine
|
// +build appengine
|
||||||
|
|
||||||
// This file contains the safe implementations of otherwise unsafe-using code.
|
// This file contains the safe implementations of otherwise unsafe-using code.
|
||||||
|
|
||||||
package xxhash
|
package xxhash
|
||||||
|
|
||||||
// Sum64String computes the 64-bit xxHash digest of s.
|
// Sum64String computes the 64-bit xxHash digest of s with a zero seed.
|
||||||
func Sum64String(s string) uint64 {
|
func Sum64String(s string) uint64 {
|
||||||
return Sum64([]byte(s))
|
return Sum64([]byte(s))
|
||||||
}
|
}
|
||||||
|
5
gateway/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go
generated
vendored
5
gateway/vendor/github.com/cespare/xxhash/v2/xxhash_unsafe.go
generated
vendored
@ -1,3 +1,4 @@
|
|||||||
|
//go:build !appengine
|
||||||
// +build !appengine
|
// +build !appengine
|
||||||
|
|
||||||
// This file encapsulates usage of unsafe.
|
// This file encapsulates usage of unsafe.
|
||||||
@ -11,7 +12,7 @@ import (
|
|||||||
|
|
||||||
// In the future it's possible that compiler optimizations will make these
|
// In the future it's possible that compiler optimizations will make these
|
||||||
// XxxString functions unnecessary by realizing that calls such as
|
// XxxString functions unnecessary by realizing that calls such as
|
||||||
// Sum64([]byte(s)) don't need to copy s. See https://golang.org/issue/2205.
|
// Sum64([]byte(s)) don't need to copy s. See https://go.dev/issue/2205.
|
||||||
// If that happens, even if we keep these functions they can be replaced with
|
// If that happens, even if we keep these functions they can be replaced with
|
||||||
// the trivial safe code.
|
// the trivial safe code.
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ import (
|
|||||||
//
|
//
|
||||||
// See https://github.com/golang/go/issues/42739 for discussion.
|
// See https://github.com/golang/go/issues/42739 for discussion.
|
||||||
|
|
||||||
// Sum64String computes the 64-bit xxHash digest of s.
|
// Sum64String computes the 64-bit xxHash digest of s with a zero seed.
|
||||||
// It may be faster than Sum64([]byte(s)) by avoiding a copy.
|
// It may be faster than Sum64([]byte(s)) by avoiding a copy.
|
||||||
func Sum64String(s string) uint64 {
|
func Sum64String(s string) uint64 {
|
||||||
b := *(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)}))
|
b := *(*[]byte)(unsafe.Pointer(&sliceHeader{s, len(s)}))
|
||||||
|
3
gateway/vendor/github.com/golang/protobuf/AUTHORS
generated
vendored
3
gateway/vendor/github.com/golang/protobuf/AUTHORS
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
# This source code refers to The Go Authors for copyright purposes.
|
|
||||||
# The master list of authors is in the main Go distribution,
|
|
||||||
# visible at http://tip.golang.org/AUTHORS.
|
|
3
gateway/vendor/github.com/golang/protobuf/CONTRIBUTORS
generated
vendored
3
gateway/vendor/github.com/golang/protobuf/CONTRIBUTORS
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
# This source code was written by the Go contributors.
|
|
||||||
# The master list of contributors is in the main Go distribution,
|
|
||||||
# visible at http://tip.golang.org/CONTRIBUTORS.
|
|
324
gateway/vendor/github.com/golang/protobuf/proto/buffer.go
generated
vendored
324
gateway/vendor/github.com/golang/protobuf/proto/buffer.go
generated
vendored
@ -1,324 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"google.golang.org/protobuf/encoding/prototext"
|
|
||||||
"google.golang.org/protobuf/encoding/protowire"
|
|
||||||
"google.golang.org/protobuf/runtime/protoimpl"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
WireVarint = 0
|
|
||||||
WireFixed32 = 5
|
|
||||||
WireFixed64 = 1
|
|
||||||
WireBytes = 2
|
|
||||||
WireStartGroup = 3
|
|
||||||
WireEndGroup = 4
|
|
||||||
)
|
|
||||||
|
|
||||||
// EncodeVarint returns the varint encoded bytes of v.
|
|
||||||
func EncodeVarint(v uint64) []byte {
|
|
||||||
return protowire.AppendVarint(nil, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SizeVarint returns the length of the varint encoded bytes of v.
|
|
||||||
// This is equal to len(EncodeVarint(v)).
|
|
||||||
func SizeVarint(v uint64) int {
|
|
||||||
return protowire.SizeVarint(v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeVarint parses a varint encoded integer from b,
|
|
||||||
// returning the integer value and the length of the varint.
|
|
||||||
// It returns (0, 0) if there is a parse error.
|
|
||||||
func DecodeVarint(b []byte) (uint64, int) {
|
|
||||||
v, n := protowire.ConsumeVarint(b)
|
|
||||||
if n < 0 {
|
|
||||||
return 0, 0
|
|
||||||
}
|
|
||||||
return v, n
|
|
||||||
}
|
|
||||||
|
|
||||||
// Buffer is a buffer for encoding and decoding the protobuf wire format.
|
|
||||||
// It may be reused between invocations to reduce memory usage.
|
|
||||||
type Buffer struct {
|
|
||||||
buf []byte
|
|
||||||
idx int
|
|
||||||
deterministic bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBuffer allocates a new Buffer initialized with buf,
|
|
||||||
// where the contents of buf are considered the unread portion of the buffer.
|
|
||||||
func NewBuffer(buf []byte) *Buffer {
|
|
||||||
return &Buffer{buf: buf}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDeterministic specifies whether to use deterministic serialization.
|
|
||||||
//
|
|
||||||
// Deterministic serialization guarantees that for a given binary, equal
|
|
||||||
// messages will always be serialized to the same bytes. This implies:
|
|
||||||
//
|
|
||||||
// - Repeated serialization of a message will return the same bytes.
|
|
||||||
// - Different processes of the same binary (which may be executing on
|
|
||||||
// different machines) will serialize equal messages to the same bytes.
|
|
||||||
//
|
|
||||||
// Note that the deterministic serialization is NOT canonical across
|
|
||||||
// languages. It is not guaranteed to remain stable over time. It is unstable
|
|
||||||
// across different builds with schema changes due to unknown fields.
|
|
||||||
// Users who need canonical serialization (e.g., persistent storage in a
|
|
||||||
// canonical form, fingerprinting, etc.) should define their own
|
|
||||||
// canonicalization specification and implement their own serializer rather
|
|
||||||
// than relying on this API.
|
|
||||||
//
|
|
||||||
// If deterministic serialization is requested, map entries will be sorted
|
|
||||||
// by keys in lexographical order. This is an implementation detail and
|
|
||||||
// subject to change.
|
|
||||||
func (b *Buffer) SetDeterministic(deterministic bool) {
|
|
||||||
b.deterministic = deterministic
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetBuf sets buf as the internal buffer,
|
|
||||||
// where the contents of buf are considered the unread portion of the buffer.
|
|
||||||
func (b *Buffer) SetBuf(buf []byte) {
|
|
||||||
b.buf = buf
|
|
||||||
b.idx = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset clears the internal buffer of all written and unread data.
|
|
||||||
func (b *Buffer) Reset() {
|
|
||||||
b.buf = b.buf[:0]
|
|
||||||
b.idx = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bytes returns the internal buffer.
|
|
||||||
func (b *Buffer) Bytes() []byte {
|
|
||||||
return b.buf
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unread returns the unread portion of the buffer.
|
|
||||||
func (b *Buffer) Unread() []byte {
|
|
||||||
return b.buf[b.idx:]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Marshal appends the wire-format encoding of m to the buffer.
|
|
||||||
func (b *Buffer) Marshal(m Message) error {
|
|
||||||
var err error
|
|
||||||
b.buf, err = marshalAppend(b.buf, m, b.deterministic)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unmarshal parses the wire-format message in the buffer and
|
|
||||||
// places the decoded results in m.
|
|
||||||
// It does not reset m before unmarshaling.
|
|
||||||
func (b *Buffer) Unmarshal(m Message) error {
|
|
||||||
err := UnmarshalMerge(b.Unread(), m)
|
|
||||||
b.idx = len(b.buf)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
type unknownFields struct{ XXX_unrecognized protoimpl.UnknownFields }
|
|
||||||
|
|
||||||
func (m *unknownFields) String() string { panic("not implemented") }
|
|
||||||
func (m *unknownFields) Reset() { panic("not implemented") }
|
|
||||||
func (m *unknownFields) ProtoMessage() { panic("not implemented") }
|
|
||||||
|
|
||||||
// DebugPrint dumps the encoded bytes of b with a header and footer including s
|
|
||||||
// to stdout. This is only intended for debugging.
|
|
||||||
func (*Buffer) DebugPrint(s string, b []byte) {
|
|
||||||
m := MessageReflect(new(unknownFields))
|
|
||||||
m.SetUnknown(b)
|
|
||||||
b, _ = prototext.MarshalOptions{AllowPartial: true, Indent: "\t"}.Marshal(m.Interface())
|
|
||||||
fmt.Printf("==== %s ====\n%s==== %s ====\n", s, b, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeVarint appends an unsigned varint encoding to the buffer.
|
|
||||||
func (b *Buffer) EncodeVarint(v uint64) error {
|
|
||||||
b.buf = protowire.AppendVarint(b.buf, v)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeZigzag32 appends a 32-bit zig-zag varint encoding to the buffer.
|
|
||||||
func (b *Buffer) EncodeZigzag32(v uint64) error {
|
|
||||||
return b.EncodeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31))))
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeZigzag64 appends a 64-bit zig-zag varint encoding to the buffer.
|
|
||||||
func (b *Buffer) EncodeZigzag64(v uint64) error {
|
|
||||||
return b.EncodeVarint(uint64((uint64(v) << 1) ^ uint64((int64(v) >> 63))))
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeFixed32 appends a 32-bit little-endian integer to the buffer.
|
|
||||||
func (b *Buffer) EncodeFixed32(v uint64) error {
|
|
||||||
b.buf = protowire.AppendFixed32(b.buf, uint32(v))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeFixed64 appends a 64-bit little-endian integer to the buffer.
|
|
||||||
func (b *Buffer) EncodeFixed64(v uint64) error {
|
|
||||||
b.buf = protowire.AppendFixed64(b.buf, uint64(v))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeRawBytes appends a length-prefixed raw bytes to the buffer.
|
|
||||||
func (b *Buffer) EncodeRawBytes(v []byte) error {
|
|
||||||
b.buf = protowire.AppendBytes(b.buf, v)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeStringBytes appends a length-prefixed raw bytes to the buffer.
|
|
||||||
// It does not validate whether v contains valid UTF-8.
|
|
||||||
func (b *Buffer) EncodeStringBytes(v string) error {
|
|
||||||
b.buf = protowire.AppendString(b.buf, v)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeMessage appends a length-prefixed encoded message to the buffer.
|
|
||||||
func (b *Buffer) EncodeMessage(m Message) error {
|
|
||||||
var err error
|
|
||||||
b.buf = protowire.AppendVarint(b.buf, uint64(Size(m)))
|
|
||||||
b.buf, err = marshalAppend(b.buf, m, b.deterministic)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeVarint consumes an encoded unsigned varint from the buffer.
|
|
||||||
func (b *Buffer) DecodeVarint() (uint64, error) {
|
|
||||||
v, n := protowire.ConsumeVarint(b.buf[b.idx:])
|
|
||||||
if n < 0 {
|
|
||||||
return 0, protowire.ParseError(n)
|
|
||||||
}
|
|
||||||
b.idx += n
|
|
||||||
return uint64(v), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeZigzag32 consumes an encoded 32-bit zig-zag varint from the buffer.
|
|
||||||
func (b *Buffer) DecodeZigzag32() (uint64, error) {
|
|
||||||
v, err := b.DecodeVarint()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return uint64((uint32(v) >> 1) ^ uint32((int32(v&1)<<31)>>31)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeZigzag64 consumes an encoded 64-bit zig-zag varint from the buffer.
|
|
||||||
func (b *Buffer) DecodeZigzag64() (uint64, error) {
|
|
||||||
v, err := b.DecodeVarint()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
return uint64((uint64(v) >> 1) ^ uint64((int64(v&1)<<63)>>63)), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeFixed32 consumes a 32-bit little-endian integer from the buffer.
|
|
||||||
func (b *Buffer) DecodeFixed32() (uint64, error) {
|
|
||||||
v, n := protowire.ConsumeFixed32(b.buf[b.idx:])
|
|
||||||
if n < 0 {
|
|
||||||
return 0, protowire.ParseError(n)
|
|
||||||
}
|
|
||||||
b.idx += n
|
|
||||||
return uint64(v), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeFixed64 consumes a 64-bit little-endian integer from the buffer.
|
|
||||||
func (b *Buffer) DecodeFixed64() (uint64, error) {
|
|
||||||
v, n := protowire.ConsumeFixed64(b.buf[b.idx:])
|
|
||||||
if n < 0 {
|
|
||||||
return 0, protowire.ParseError(n)
|
|
||||||
}
|
|
||||||
b.idx += n
|
|
||||||
return uint64(v), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeRawBytes consumes a length-prefixed raw bytes from the buffer.
|
|
||||||
// If alloc is specified, it returns a copy the raw bytes
|
|
||||||
// rather than a sub-slice of the buffer.
|
|
||||||
func (b *Buffer) DecodeRawBytes(alloc bool) ([]byte, error) {
|
|
||||||
v, n := protowire.ConsumeBytes(b.buf[b.idx:])
|
|
||||||
if n < 0 {
|
|
||||||
return nil, protowire.ParseError(n)
|
|
||||||
}
|
|
||||||
b.idx += n
|
|
||||||
if alloc {
|
|
||||||
v = append([]byte(nil), v...)
|
|
||||||
}
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeStringBytes consumes a length-prefixed raw bytes from the buffer.
|
|
||||||
// It does not validate whether the raw bytes contain valid UTF-8.
|
|
||||||
func (b *Buffer) DecodeStringBytes() (string, error) {
|
|
||||||
v, n := protowire.ConsumeString(b.buf[b.idx:])
|
|
||||||
if n < 0 {
|
|
||||||
return "", protowire.ParseError(n)
|
|
||||||
}
|
|
||||||
b.idx += n
|
|
||||||
return v, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeMessage consumes a length-prefixed message from the buffer.
|
|
||||||
// It does not reset m before unmarshaling.
|
|
||||||
func (b *Buffer) DecodeMessage(m Message) error {
|
|
||||||
v, err := b.DecodeRawBytes(false)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return UnmarshalMerge(v, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeGroup consumes a message group from the buffer.
|
|
||||||
// It assumes that the start group marker has already been consumed and
|
|
||||||
// consumes all bytes until (and including the end group marker).
|
|
||||||
// It does not reset m before unmarshaling.
|
|
||||||
func (b *Buffer) DecodeGroup(m Message) error {
|
|
||||||
v, n, err := consumeGroup(b.buf[b.idx:])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b.idx += n
|
|
||||||
return UnmarshalMerge(v, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// consumeGroup parses b until it finds an end group marker, returning
|
|
||||||
// the raw bytes of the message (excluding the end group marker) and the
|
|
||||||
// the total length of the message (including the end group marker).
|
|
||||||
func consumeGroup(b []byte) ([]byte, int, error) {
|
|
||||||
b0 := b
|
|
||||||
depth := 1 // assume this follows a start group marker
|
|
||||||
for {
|
|
||||||
_, wtyp, tagLen := protowire.ConsumeTag(b)
|
|
||||||
if tagLen < 0 {
|
|
||||||
return nil, 0, protowire.ParseError(tagLen)
|
|
||||||
}
|
|
||||||
b = b[tagLen:]
|
|
||||||
|
|
||||||
var valLen int
|
|
||||||
switch wtyp {
|
|
||||||
case protowire.VarintType:
|
|
||||||
_, valLen = protowire.ConsumeVarint(b)
|
|
||||||
case protowire.Fixed32Type:
|
|
||||||
_, valLen = protowire.ConsumeFixed32(b)
|
|
||||||
case protowire.Fixed64Type:
|
|
||||||
_, valLen = protowire.ConsumeFixed64(b)
|
|
||||||
case protowire.BytesType:
|
|
||||||
_, valLen = protowire.ConsumeBytes(b)
|
|
||||||
case protowire.StartGroupType:
|
|
||||||
depth++
|
|
||||||
case protowire.EndGroupType:
|
|
||||||
depth--
|
|
||||||
default:
|
|
||||||
return nil, 0, errors.New("proto: cannot parse reserved wire type")
|
|
||||||
}
|
|
||||||
if valLen < 0 {
|
|
||||||
return nil, 0, protowire.ParseError(valLen)
|
|
||||||
}
|
|
||||||
b = b[valLen:]
|
|
||||||
|
|
||||||
if depth == 0 {
|
|
||||||
return b0[:len(b0)-len(b)-tagLen], len(b0) - len(b), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
63
gateway/vendor/github.com/golang/protobuf/proto/defaults.go
generated
vendored
63
gateway/vendor/github.com/golang/protobuf/proto/defaults.go
generated
vendored
@ -1,63 +0,0 @@
|
|||||||
// Copyright 2019 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"google.golang.org/protobuf/reflect/protoreflect"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetDefaults sets unpopulated scalar fields to their default values.
|
|
||||||
// Fields within a oneof are not set even if they have a default value.
|
|
||||||
// SetDefaults is recursively called upon any populated message fields.
|
|
||||||
func SetDefaults(m Message) {
|
|
||||||
if m != nil {
|
|
||||||
setDefaults(MessageReflect(m))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setDefaults(m protoreflect.Message) {
|
|
||||||
fds := m.Descriptor().Fields()
|
|
||||||
for i := 0; i < fds.Len(); i++ {
|
|
||||||
fd := fds.Get(i)
|
|
||||||
if !m.Has(fd) {
|
|
||||||
if fd.HasDefault() && fd.ContainingOneof() == nil {
|
|
||||||
v := fd.Default()
|
|
||||||
if fd.Kind() == protoreflect.BytesKind {
|
|
||||||
v = protoreflect.ValueOf(append([]byte(nil), v.Bytes()...)) // copy the default bytes
|
|
||||||
}
|
|
||||||
m.Set(fd, v)
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
|
|
||||||
switch {
|
|
||||||
// Handle singular message.
|
|
||||||
case fd.Cardinality() != protoreflect.Repeated:
|
|
||||||
if fd.Message() != nil {
|
|
||||||
setDefaults(m.Get(fd).Message())
|
|
||||||
}
|
|
||||||
// Handle list of messages.
|
|
||||||
case fd.IsList():
|
|
||||||
if fd.Message() != nil {
|
|
||||||
ls := m.Get(fd).List()
|
|
||||||
for i := 0; i < ls.Len(); i++ {
|
|
||||||
setDefaults(ls.Get(i).Message())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Handle map of messages.
|
|
||||||
case fd.IsMap():
|
|
||||||
if fd.MapValue().Message() != nil {
|
|
||||||
ms := m.Get(fd).Map()
|
|
||||||
ms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool {
|
|
||||||
setDefaults(v.Message())
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
113
gateway/vendor/github.com/golang/protobuf/proto/deprecated.go
generated
vendored
113
gateway/vendor/github.com/golang/protobuf/proto/deprecated.go
generated
vendored
@ -1,113 +0,0 @@
|
|||||||
// Copyright 2018 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
package proto
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
protoV2 "google.golang.org/protobuf/proto"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// Deprecated: No longer returned.
|
|
||||||
ErrNil = errors.New("proto: Marshal called with nil")
|
|
||||||
|
|
||||||
// Deprecated: No longer returned.
|
|
||||||
ErrTooLarge = errors.New("proto: message encodes to over 2 GB")
|
|
||||||
|
|
||||||
// Deprecated: No longer returned.
|
|
||||||
ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof")
|
|
||||||
)
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 }
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func GetStats() Stats { return Stats{} }
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func MarshalMessageSet(interface{}) ([]byte, error) {
|
|
||||||
return nil, errors.New("proto: not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func UnmarshalMessageSet([]byte, interface{}) error {
|
|
||||||
return errors.New("proto: not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func MarshalMessageSetJSON(interface{}) ([]byte, error) {
|
|
||||||
return nil, errors.New("proto: not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func UnmarshalMessageSetJSON([]byte, interface{}) error {
|
|
||||||
return errors.New("proto: not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func RegisterMessageSetType(Message, int32, string) {}
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func EnumName(m map[int32]string, v int32) string {
|
|
||||||
s, ok := m[v]
|
|
||||||
if ok {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
return strconv.Itoa(int(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use.
|
|
||||||
func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {
|
|
||||||
if data[0] == '"' {
|
|
||||||
// New style: enums are strings.
|
|
||||||
var repr string
|
|
||||||
if err := json.Unmarshal(data, &repr); err != nil {
|
|
||||||
return -1, err
|
|
||||||
}
|
|
||||||
val, ok := m[repr]
|
|
||||||
if !ok {
|
|
||||||
return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr)
|
|
||||||
}
|
|
||||||
return val, nil
|
|
||||||
}
|
|
||||||
// Old style: enums are ints.
|
|
||||||
var val int32
|
|
||||||
if err := json.Unmarshal(data, &val); err != nil {
|
|
||||||
return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName)
|
|
||||||
}
|
|
||||||
return val, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use; this type existed for intenal-use only.
|
|
||||||
type InternalMessageInfo struct{}
|
|
||||||
|
|
||||||
// Deprecated: Do not use; this method existed for intenal-use only.
|
|
||||||
func (*InternalMessageInfo) DiscardUnknown(m Message) {
|
|
||||||
DiscardUnknown(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use; this method existed for intenal-use only.
|
|
||||||
func (*InternalMessageInfo) Marshal(b []byte, m Message, deterministic bool) ([]byte, error) {
|
|
||||||
return protoV2.MarshalOptions{Deterministic: deterministic}.MarshalAppend(b, MessageV2(m))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use; this method existed for intenal-use only.
|
|
||||||
func (*InternalMessageInfo) Merge(dst, src Message) {
|
|
||||||
protoV2.Merge(MessageV2(dst), MessageV2(src))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use; this method existed for intenal-use only.
|
|
||||||
func (*InternalMessageInfo) Size(m Message) int {
|
|
||||||
return protoV2.Size(MessageV2(m))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deprecated: Do not use; this method existed for intenal-use only.
|
|
||||||
func (*InternalMessageInfo) Unmarshal(m Message, b []byte) error {
|
|
||||||
return protoV2.UnmarshalOptions{Merge: true}.Unmarshal(b, MessageV2(m))
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user